Redis GEO | 操作方法 |
---|---|
geoadd | 添加地理位置的坐标 |
geopos | 获取地理位置的坐标 |
geodist | 计算两个位置之间的距离 |
georadius | 根据用户给定的经纬度坐标来获取指定范围内的地理位置集合 |
georadiusbymember | 根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合 |
geohash | 返回一个或多个位置对象的 geohash 值 |
最后一个距离单位参数说明:
m:米,默认单位。
km:千米。
mi:英里。
ft:英尺。
m:米,默认单位。
km:千米。
mi:英里。
ft:英尺。
WITHDIST:在返回位置元素的同时,将位置元素与中心之间的距离也一并返回。
WITHCOORD:将位置元素的经度和维度也一并返回。
WITHHASH:以52位有符号整数的形式,返回位置元素经过原始geohash编码的有序集合分值。这个选项主要用于底层应用或者调试,实际中的作用并不大。
COUNT限定返回的记录数。
ASC:查找结果根据距离从近到远排序。
DESC:查找结果根据从远到近排序。
如果之前创建店铺的时候保存了经纬度,这个数据可以在数据库中读取,id是门店的id,longitude 经度,latitude纬度
如果仔细的读者应该发现了,在这里用的语法是上文介绍过的,在这里只是把名称换成了店铺id,后面比较好和门店进行绑定
可以看到redis库中已经有我们填写的测试数据了,接下来我们结合上文所说到的georadius方法进行取值
这里使用的是asc升序排序,还有desc降序排序,一般附近门店第一个显示的是最近门店,所以用asc升序排序,单位是km 比较好查询
显示的是km单位,把数据拿到后可以 *1000 改成m单位,更具自己的项目需求进行改变
在这里遍历用店铺id做为数组的key
在这将门店距离数据和门店信息数据组合
最后组合成的数据,已经可以在前端小程序中渲染附近门店距离啦,这只是测试数据哦,真实数据要更具自己项目数据进行结合 对读者有帮助的话 帮我点个赞哦 期待留言~~
成品效果哦~~
(ps: 最后可以设防,读取数据库门店信息条数和redis 储存的门店经纬度数据总数 进行对比,如果一致,则直接读取redis数据,否则重新查询数据库,将数据重新赋值给redis,可以减少数据库io查询)
//模拟门店 id 经度 纬度
$store_location=array(
0=>array(
'id'=>1,
'longitude'=>'113.956843',
'latitude'=>'22.575094',
),
1=>array(
'id'=>2,
'longitude'=>'113.957746',
'latitude'=>'22.574877',
),
2=>array(
'id'=>3,
'longitude'=>'113.957036',
'latitude'=>'22.575545',
),
);
//遍历测试数据 循环在redis 插入 经纬度
foreach($store_locationas$K=>$item){
Redis::GeoAdd('store_location',$item['longitude'],$item['latitude'],$item['id']);
}
//在这里经纬度是写死的,在实际项目中这里传进来的经纬度是更具用户授权定位信息之后拿到的经纬度
$positions=Redis::GeoRadius('store_location',113.955964,22.574741,1000,'km','WITHDIST','asc');
//在这里遍历用店铺id做为数组key
$positions_container=[];
foreach($positionsas$k=>$v){
$positions_container[$v[0]]=$v;
}
//这里是门店信息测试数据,读者可以更具项目数据进行读取
$stores=array(
0=>array(
'id'=>1,
'name'=>'ck',
),
1=>array(
'id'=>2,
'name'=>'myj',
),
2=>array(
'id'=>3,
'name'=>'tyb',
),
);
//门店信息容器
$store_info=[];
foreach($storesas$k=>$v){//遍历门店信息数据
foreach($positions_containeras$kk=>$vv){//遍历相对距离位置
//如果数组key等于门店信息id 则把数据重新赋值给门店信息容器 store_info
if($kk=$v['id']){
$store_info[$kk]['id']=$v['id'];
$store_info[$kk]['name']=$v['name'];
$store_info[$kk]['apart']=($positions_container[$kk][1]*1)*1000;
}
}
}
//取出门店距离数组列
$column=array_column($store_info,'apart');
//更具距离进行升序排序
array_multisort($column,SORT_ASC,$store_info);
dd($store_info);