2019独角兽企业重金招聘Python工程师标准>>>

附近搜索 geohash.neighbors 生成周边8个geohash(如下图),生成的长方形区域,与我要的搜索附近半径几公里以内肯定不相符。找到老外写的 https://github.com/ashwin711/proximityhash 。

需要 php版本代码 @ 我

<?php
/*** author https://my.oschina.net/jszhang* copy2php  https://github.com/ashwin711/proximityhash */// demo
// ProximityHash::create_geohash($lat, $lng, 1000, 6);class ProximityHash
{public static function in_circle_check($latitude, $longitude, $centre_lat, $centre_lon, $radius){$x_diff = $longitude - $centre_lon;$y_diff = $latitude - $centre_lat;if (pow($x_diff, 2) + pow($y_diff, 2) <= pow($radius, 2)) {return true;}return false;}public static function get_centroid($latitude, $longitude, $height, $width){$y_cen = $latitude + ($height / 2);$x_cen = $longitude + ($width / 2);return [$x_cen, $y_cen];}public static function convert_to_latlon($y, $x, $latitude, $longitude){$pi = 3.14159265359;$r_earth = 6371000;$lat_diff = ($y / $r_earth) * (180 / $pi);$lon_diff = ($x / $r_earth) * (180 / $pi) / cos($latitude * $pi / 180);$final_lat = $latitude + $lat_diff;$final_lon = $longitude + $lon_diff;return [$final_lat, $final_lon];}public static function create_geohash($latitude, $longitude, $radius, $precision, $georaptor_flag = false, $minlevel = 1, $maxlevel = 12){$x = 0.0;$y = 0.0;$points    = [];$geohashes = [];$grid_width  = [5009400.0, 1252300.0, 156500.0, 39100.0, 4900.0, 1200.0, 152.9, 38.2, 4.8, 1.2, 0.149, 0.0370];$grid_height = [4992600.0, 624100.0, 156000.0, 19500.0, 4900.0, 609.4, 152.4, 19.0, 4.8, 0.595, 0.149, 0.0199];$height = ($grid_height[$precision - 1]) / 2;$width  = ($grid_width[$precision - 1]) / 2;$lat_moves = intval(ceil($radius / $height));$lon_moves = intval(ceil($radius / $width));foreach (range(0, $lat_moves) as $i) {$temp_lat = $y + $height * $i;foreach (range(0, $lon_moves) as $j) {$temp_lon = $x + $width * $j;if (self::in_circle_check($temp_lat, $temp_lon, $y, $x, $radius)) {list($x_cen, $y_cen) = self::get_centroid($temp_lat, $temp_lon, $height, $width);$points[] = self::convert_to_latlon($y_cen, $x_cen, $latitude, $longitude);$points[] = self::convert_to_latlon(-$y_cen, $x_cen, $latitude, $longitude);$points[] = self::convert_to_latlon($y_cen, -$x_cen, $latitude, $longitude);$points[] = self::convert_to_latlon(-$y_cen, -$x_cen, $latitude, $longitude);}}}foreach ($points as $point) {$geohashes[] = GeoHash::encode($point[0], $point[1], $precision);}$geohashes = array_unique($geohashes);if ($georaptor_flag) {// GeoRaptor我没copy// return GeoRaptor::compress($geohashes, $minlevel, $maxlevel);return $geohashes;} else {return $geohashes;}}}
<?php// author https://my.oschina.net/jszhangclass GeoHash
{const BASE32_CODES      = "0123456789bcdefghjkmnpqrstuvwxyz";const BASE32_CODES_DICT = ['0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'b' => 10, 'c' => 11, 'd' => 12, 'e' => 13, 'f' => 14, 'g' => 15, 'h' => 16, 'j' => 17, 'k' => 18, 'm' => 19, 'n' => 20, 'p' => 21, 'q' => 22, 'r' => 23, 's' => 24, 't' => 25, 'u' => 26, 'v' => 27, 'w' => 28, 'x' => 29, 'y' => 30, 'z' => 31];// const BASE32_CODES_DICT = array_flip(explode('', self::BASE32_CODES));/*** Significant Figure Hash Length** This is a quick and dirty lookup to figure out how long our hash* should be in order to guarantee a certain amount of trailing* significant figures. This was calculated by determining the error:* 45/2^(n-1) where n is the number of bits for a latitude or* longitude. Key is # of desired sig figs, value is minimum length of* the geohash.* @type Array*///     Desired sig figs:  0  1  2  3  4   5   6   7   8   9  10const SIGFIG_HASH_LENGTH = [0, 5, 7, 8, 11, 12, 13, 15, 16, 17, 18];public static function encode($latitude, $longitude, $numberOfChars = ''){if ($numberOfChars === 'auto') {$decSigFigsLat   = strlen(strstr($latitude, '.')) - 1;$decSigFigsLong  = strlen(strstr($longitude, '.')) - 1;$numberOfSigFigs = max($decSigFigsLat, $decSigFigsLong);$numberOfChars   = self::SIGFIG_HASH_LENGTH[$numberOfSigFigs];} else if (empty($numberOfChars)) {$numberOfChars = 9;}$chars      = [];$bits       = 0;$bitsTotal  = 0;$hash_value = 0;$maxLat     = 90;$minLat     = -90;$maxLon     = 180;$minLon     = -180;$mid        = 0;while (count($chars) < $numberOfChars) {if ($bitsTotal % 2 === 0) {$mid = ($maxLon + $minLon) / 2;if ($longitude > $mid) {$hash_value = ($hash_value << 1) + 1;$minLon     = $mid;} else {$hash_value = ($hash_value << 1) + 0;$maxLon     = $mid;}} else {$mid = ($maxLat + $minLat) / 2;if ($latitude > $mid) {$hash_value = ($hash_value << 1) + 1;$minLat     = $mid;} else {$hash_value = ($hash_value << 1) + 0;$maxLat     = $mid;}}$bits++;$bitsTotal++;if ($bits === 5) {$chars[]    = self::BASE32_CODES[$hash_value];$bits       = 0;$hash_value = 0;}}return implode('', $chars);}public static function decode($hash_string){$bbox   = self::decode_bbox($hash_string);$lat    = ($bbox[0] + $bbox[2]) / 2;$lon    = ($bbox[1] + $bbox[3]) / 2;$latErr = $bbox[2] - $lat;$lonErr = $bbox[3] - $lon;return ['latitude'  => $lat,'longitude' => $lon,'error'     => ['latitude' => $latErr, 'longitude' => $lonErr],];}public static function decode_bbox($hash_string){$isLon  = true;$maxLat = 90;$minLat = -90;$maxLon = 180;$minLon = -180;$mid;$hashValue = 0;for ($i = 0, $l = strlen($hash_string); $i < $l; $i++) {$code      = $hash_string[$i];$hashValue = self::BASE32_CODES_DICT[$code];for ($bits = 4; $bits >= 0; $bits--) {$bit = ($hashValue >> $bits) & 1;if ($isLon) {$mid = ($maxLon + $minLon) / 2;if ($bit === 1) {$minLon = $mid;} else {$maxLon = $mid;}} else {$mid = ($maxLat + $minLat) / 2;if ($bit === 1) {$minLat = $mid;} else {$maxLat = $mid;}}$isLon = !$isLon;}}return [$minLat, $minLon, $maxLat, $maxLon];}/*** Neighbors** Returns all neighbors' hashstrings clockwise from north around to northwest* 7 0 1* 6 x 2* 5 4 3* @param {String} hash_string* @returns {encoded neighborHashList|Array}*/public static function neighbors($hash_string){$hashstringLength = strlen($hash_string);$lonlat = self::decode($hash_string);$lat    = $lonlat['latitude'];$lon    = $lonlat['longitude'];$latErr = $lonlat['error']['latitude'] * 2;$lonErr = $lonlat['error']['longitude'] * 2;$List = [[1, 0],[1, 1],[0, 1],[-1, 1],[-1, 0],[-1, -1],[0, -1],[1, -1],];$neighborHashList = array_map(function ($neighbor) use ($lat, $lon, $latErr, $lonErr, $hashstringLength) {$neighbor_lat = $lat + $neighbor[0] * $latErr;$neighbor_lon = $lon + $neighbor[1] * $lonErr;return self::encode($neighbor_lat, $neighbor_lon, $hashstringLength);}, $List);return $neighborHashList;}public function get_box($arr){$minLat = $arr[0][1];$minLon = $arr[0][0];$maxLat = $arr[0][1];$maxLon = $arr[0][0];foreach ($arr as $point) {$minLat = $point[1] > $minLat ? $minLat : $point[1];$minLon = $point[0] > $minLon ? $minLon : $point[0];$maxLat = $point[1] < $maxLat ? $maxLat : $point[1];$maxLon = $point[0] < $maxLon ? $maxLon : $point[0];}return [$minLat, $minLon, $maxLat, $maxLon];}
}

转载于:https://my.oschina.net/jszhang/blog/1635440

geohash 附近搜索相关推荐

  1. geohash美团附近酒店搜索-技术方案

    美团附近酒店搜索-技术方案 自Redis 3.2开始,Redis基于geohash和zset提供了地理位置相关功能. 什么是Geohash Geohash是一种地址编码,它能把二维的经纬度编码成一维的 ...

  2. Redis核心数据结构ZSET、GeoHash 、 Stream--排行榜、消息Pull推送、附近搜索、布隆过滤器 、IM聊天室

    ZSET.Geo . Stream redis zset数据结构 常用命令 排行榜 步骤一.初始化1个月的历史数据 步骤二:定时刷新数据 步骤3:排行榜查询接口 GeoHash 命令 附近酒店搜索实现 ...

  3. 算法进阶系列1 空间搜索 GeoHash 算法

    1. 背景 我们经常会用到 App 打车和共享单车,App 界面上会显示出自己附近一个范围内可用的出租车或者共享单车: 那如何发现以自己为圆心一定范围内的车呢?最直观的想法就是在数据库里存储每一辆车的 ...

  4. Geohash之范围搜索

    概述 很多时候,我们都会遇到这样的需求:查找某个点周边多少距离的点.从本质来说,是一个缓冲区分析+空间查找,本文结合Geohash来实现类似的功能. 效果 说明: 红色的点和红色的圈是查找的中心点和距 ...

  5. Query理解在美团搜索中的应用

    分享嘉宾:刘亮 美团 资深算法工程师 编辑整理:吴雪松 出品社区:DataFunTalk 导读:在过去的20年中,搜索过程中处理查询的方式以及向用户显示结果的方式已完全改变.该过程已经从仅基于文本匹配 ...

  6. 机器学习在高德搜索建议中的应用优化实践

    来自:高德技术 导读:高德的愿景是:连接真实世界,让出行更美好.为了实现愿景,我们要处理好LBS大数据和用户之间的智能链接.信息检索是其中的关键技术,而搜索建议又是检索服务不可或缺的组成部分. 本文将 ...

  7. GeoHash核心原理解析

    http://www.cnblogs.com/LBSer/p/3310455.html 引子 机机是个好动又好学的孩子,平日里就喜欢拿着手机地图点点按按来查询一些好玩的东西.某一天机机到北海公园游玩, ...

  8. 数据挖据之GeoHash核心原理解析

    引子 机机是个好动又好学的孩子,平日里就喜欢拿着手机地图点点按按来查询一些好玩的东西.某一天机机到北海公园游玩,肚肚饿了,于是乎打开手机地图,搜索北海公园附近的餐馆,并选了其中一家用餐. 饭饱之后机机 ...

  9. 基于LBS功能应用的Geohash方案

    随着移动终端的普及,很多应用都基于LBS功能,附近的某某(餐馆.银行.妹纸等等). 基础数据中,一般保存了目标位置的经纬度:利用用户提供的经纬度,进行对比,从而获得是否在附近. 目标: 查找附近的某某 ...

最新文章

  1. Linux多台服务器共用密钥ssh自动登陆
  2. note for git
  3. Java 技术之垃圾回收机制
  4. NYOJ 1067 Compress String(区间dp)
  5. 【技术解决方案】GitHub本地仓库管理与远程仓库管理
  6. laravel 如何 new php 类,PHP实例:laravel通过创建自定义artisan make命令来新建类文件详解...
  7. 如何写标题摘要关键字
  8. Java多线程:生命周期,实现与调度
  9. linux中date使用方法,linux命令详解date使用方法(计算母亲节和父亲节日期脚本示例)...
  10. 2015年创业中遇到的技术问题:21-30
  11. windows本地运行sentinel
  12. (转)log4j(二)——如何控制日志信息的输出?
  13. python word 英语音标_(完整word版)英语音标大全
  14. 大数据和云计算有什么关系?
  15. bat文件如何调用另一个bat文件
  16. 安装Ubuntu系统卡在载入界面,显示正在安装open vm tools
  17. Chrome 设置主页无效一直是2345
  18. 使用matplotlib在图片上画框框
  19. wordpress配置SSL证书
  20. [生而为人-思考] Knowledge Cooking 分享会记录 -1

热门文章

  1. oauth2 增加token 返回参数_RingCentral Tech | OAuth2.0面面观
  2. python外星人入侵游戏图片_跪求一个问题@关于外星人入侵游戏(《python编程基础从入门到实...
  3. Activity启动过程剖析
  4. (014)java后台开发之用tomcat发布自己的javaWeb项目
  5. swift_042(Swift的typealias(别名)的用法)
  6. (001) RN开发之Mac搭建开发环境
  7. 语言中knitr_R语言软件包的批量引用
  8. 二分图带权最大匹配费用流_你真的会写二分检索吗?
  9. linux执行class文件_「大数据干货」Windows系统和Linux系统中打jar包与导入语句剖析...
  10. 解决Warning: Ignoring InnerClasses attribute for an anonymous inner class