通过geohash找出距离某个经纬度点最近的道路(二维空间查询转换为一维比较查询)...

场景

通过出租车、货车等发出实时轨迹点,这些轨迹点往往出现偏移,需要找出汽车具体在哪条道路上行驶

传统做法

通过对点进行buffer,然后关联空间数据库(oracle、postgis等)找出与buffer相交的link,逐步比较点与关联link的距离,找出距离最近的link

缺点:

1、空间数据库二维的比较

2、buffer半径可能需要多次设置,有可能buffer没有关联出link,需要放到半径重新进行空间比较

新方案思路

1、对所有道路link进行外包框的geohash计算,获取一个最小的和一个最大的,比如

MULTILINESTRING((116.84977 39.93626,116.84975 39.93648,116.8505 39.93661,116.8509 39.93667,116.85148 39.93681,116.85186 39.93689))

        String wkt = "MULTILINESTRING((116.84977 39.93626,116.84975 39.93648,116.8505 39.93661,116.8509 39.93667,116.85148 39.93681,116.85186 39.93689))";
        
        Geometry geom = new WKTReader().read(wkt);
        
        Geometry bundary = geom.getEnvelope();
        
        String minGeohash = "zzzzzzzzzzzz";
        
        String maxGeohash = "0";
        
        for(Coordinate c:bundary.getCoordinates()){
            String hash = GeoHash.withCharacterPrecision(c.y, c.x, 12).toBase32();
            
            if (minGeohash.compareTo(hash)>0)
                minGeohash = hash;
            
            if (maxGeohash.compareTo(hash)<0)
                maxGeohash = hash;
        }
        
        System.out.println(minGeohash+","+maxGeohash);

对应minGeohash和maxGeohash为:wx554ypmsd2w,wx555n2cjxyh

2、创建表结构存储到关系型数据库中

create table link_geohash(start String,end String,int link_pid);

创建索引:

create index idx_link_geohash_start on link_geohash(start);

create index idx_link_geohash_end on link_geohash(end);

3、导入数据到表link_geohash

start对应minGeohash,end对应maxGeohash

4、根据点查找对应道路link

比方说点:Point(116.850829 39.936568)、对应的geohash为:wx555n0pmev5

select link_pid from link_geohash where 'wx555n0pmev5' between start,end;

5、通过上一步查出的link编号,获取对应的geometry,再逐个比较,返回距离最小的那根link即可

 

点到线距离计算公式

 

转载于:https://www.cnblogs.com/lilei2blog/p/8042004.html

Redis Geo命令`GeoRadiusCommandArgs`用于在地理空间范围内执行查询操作,特别是查找指定半径内最近的地理位置。当你想获取距离给定坐标(比如当前用户的经纬度最近的八个时,你可以创建一个`GeoRadiusCommandArgs`实例,并设置相关的参数: 1. **中心坐标**:首先,你需要提供一个经度和纬度作为查询中心,例如`(longitude, latitude)`。 2. **半径**:设置一个范围值,表示你想要找到的与中心的最大距离。 3. **单位**:可以选择使用米(m)或其他常见的距离单位,如公里(km)。 4. **返回结果的数量**:在这个例子中,设置为8,表示你希望得到最接近的8个地。 5. **排序规则**:默认是按照距离递增排序,如果你想按距离递减排序,可以设置`WITHDIST` 6. **包含类型**:`WITHCOORDS`保留地理位置坐标,`WITHHASH`保留哈希字段等。 创建完`GeoRadiusCommandArgs`后,你可以构造SQL-like查询字符串,然后通过Redis客户端调用`ZRANGE`(如果需要从最近到最远)或者`ZREVRANGE`(如果需要从最远到最近)命令,传入这个查询参数。 示例代码(伪代码): ```python args = redis.geo_radius_command_args( center=your_current_location, radius="10km", count=8, unit="km", withcoords=True ) # 如果你想按距离递减排序 sorted_results = redis.zrangebyscore(*args) # 或者按距离递增排序 # sorted_results = redis.zrevrangebyscore(*args) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值