首先看用法,代码来自github,修改了,习惯lat在前,lng在后。
$geohash = new GeoHash();
$geohash->encode(‘39.9232111’,‘116.3906111’);
$geohash->decode(‘wx4g0ec19cc’);
//下面是展示获取周围8个的
$geohash->expand(‘wx4g0ec19cc’);
<?php
class GeoHash
{
private static $table = “0123456789bcdefghjkmnpqrstuvwxyz”;
private static $bits = array(
0b10000, 0b01000, 0b00100, 0b00010, 0b00001
);
public static function encode($lat, $lng, $prec = 0.00001)
{
$minlng = -180;
$maxlng = 180;
$minlat = -90;
$maxlat = 90;
$hash = array();
$error = 180;
$isEven = true;
$chr = 0b00000;
$b = 0;
while ($error >= $prec) {
if ($isEven) {
$next = ($minlng + $maxlng) / 2;
if ($lng > $next) {
$chr |= self::$bits[$b];
$minlng = $next;
} else {
$maxlng = $next;
}
} else {
$next = ($minlat + $maxlat) / 2;
if ($lat > $next) {
$chr |= self::$bits[$b];
$minlat = $next;
} else {
$maxlat = $next;
}
}
$isEven = !$isEven;
if ($b < 4) {
$b++;
} else {
$hash[] = self::$table[$chr];
$error = max($maxlng – $minlng, $maxlat – $minlat);
$b = 0;
$chr = 0b00000;
}
}
return join(”, $hash);
}
public static function expand($hash, $prec = 0.00001)
{
list($minlng, $maxlng, $minlat, $maxlat) = self::decode($hash);
$dlng = ($maxlng – $minlng) / 2;
$dlat = ($maxlat – $minlat) / 2;
return array(
self::encode($minlng – $dlng, $maxlat + $dlat, $prec),
self::encode($minlng + $dlng, $maxlat + $dlat, $prec),
self::encode($maxlng + $dlng, $maxlat + $dlat, $prec),
self::encode($minlng – $dlng, $maxlat – $dlat, $prec),
self::encode($maxlng + $dlng, $maxlat – $dlat, $prec),
self::encode($minlng – $dlng, $minlat – $dlat, $prec),
self::encode($minlng + $dlng, $minlat – $dlat, $prec),
self::encode($maxlng + $dlng, $minlat – $dlat, $prec),
);
}
public static function getRect($hash)
{
list($minlng, $maxlng, $minlat, $maxlat) = self::decode($hash);
return array(
array($minlng, $minlat),
array($minlng, $maxlat),
array($maxlng, $maxlat),
array($maxlng, $minlat),
);
}
/**
* decode a geohash string to a geographical area
*
* @var $hash string geohash
* @return array array($minlng, $maxlng, $minlat, $maxlat);
*/
public static function decode($hash)
{
$minlng = -180;
$maxlng = 180;
$minlat = -90;
$maxlat = 90;
for ($i=0,$c=strlen($hash); $i<$c; $i++) {
$v = strpos(self::$table, $hash[$i]);
if (1&$i) {
if (16&$v) {
$minlat = ($minlat + $maxlat) / 2;
} else {
$maxlat = ($minlat + $maxlat) / 2;
}
if (8&$v) {
$minlng = ($minlng + $maxlng) / 2;
} else {
$maxlng = ($minlng + $maxlng) / 2;
}
if (4&$v) {
$minlat = ($minlat + $maxlat) / 2;
} else {
$maxlat = ($minlat + $maxlat) / 2;
}
if (2&$v) {
$minlng = ($minlng + $maxlng) / 2;
} else {
$maxlng = ($minlng + $maxlng) / 2;
}
if (1&$v) {
$minlat = ($minlat + $maxlat) / 2;
} else {
$maxlat = ($minlat + $maxlat) / 2;
}
} else {
if (16&$v) {
$minlng = ($minlng + $maxlng) / 2;
} else {
$maxlng = ($minlng + $maxlng) / 2;
}
if (8&$v) {
$minlat = ($minlat + $maxlat) / 2;
} else {
$maxlat = ($minlat + $maxlat) / 2;
}
if (4&$v) {
$minlng = ($minlng + $maxlng) / 2;
} else {
$maxlng = ($minlng + $maxlng) / 2;
}
if (2&$v) {
$minlat = ($minlat + $maxlat) / 2;
} else {
$maxlat = ($minlat + $maxlat) / 2;
}
if (1&$v) {
$minlng = ($minlng + $maxlng) / 2;
} else {
$maxlng = ($minlng + $maxlng) / 2;
}
}
}
return array($minlat, $maxlat, $minlng, $maxlng);
}
}
未经允许不得转载:互联网骚操作 » php版本的geohash类库,包括查询周边8个格子的hash编码
评论前必须登录!