geohash,php扩展

geohash简介:

geohash是一种地址编码,它能把二维的经纬度编码成一维的字符串。

geohash有以下几个特点:

首先,geohash用一个字符串表示经度和纬度两个坐标。某些情况下无法在两列上同时应用索引 (例如MySQL 4之前的版本,Google App Engine的数据层等),利用geohash,只需在一列上应用索引即可。

其次,geohash表示的并不是一个点,而是一个矩形区域。比如编码wx4g0ec19,它表示的是一个矩形区域。 使用者可以发布地址编码,既能表明自己位于北海公园附近,又不至于暴露自己的精确坐标,有助于隐私保护。

第三,编码的前缀可以表示更大的区域。例如wx4g0ec1,它的前缀wx4g0e表示包含编码wx4g0ec1在内的更大范围。
这个特性可以用于附近地点搜索。首先根据用户当前坐标计算geohash(例如wx4g0ec1)然后取其前缀进行查询 (SELECT * FROM
place WHERE geohash LIKE ‘wx4g0e%’),即可查询附近的所有地点。Geohash比直接用经纬度的高效很多。

用途

移动互联网,lbs可以说是一个基础应用,geohash对于解决附近地点搜索提供了一个有效的解决方案。

扩展:

这个php扩展,提供了三个函数:

/**
    *  $latitude    //纬度
    *  $longitude   //经度
    *  $precision   //精密度, 默认是12
    *  返回 $precision 长度的 string
    */
   geohash_encode($latitude, $longitude, $precision=12);  



   /**
    *  $hash    //geohash_encode后的值
    *  返回 array // Array
    *                    (
    *                        [latitude] => 39.416916975752
    *                        [longitude] => 100.92223992571
    *                        [north] => 39.416917059571
    *                        [east] => 100.92224009335
    *                        [south] => 100.92223992571
    *                        [west] => 100.92223975807
    *                    )
    */
   geohash_decode($hash);

   /**
    *  $hash    //geohash_encode后的值
    *  返回 在$hash 8个 (东南西北各二个)附近的hash值
    */
   geohash_neighbors($hash);

github地址:http://github.com/shenzhe/geohash

 

另外一种算法:

geo = encode_geohash(30.63578, 104.031601, 12); //神马时候做成个php扩展把!
  echo $geo ;
  print_r(decode_geohash( $geo ));
function encode_geohash( $latitude , $longitude , $deep )
{
     $BASE32 = '0123456789bcdefghjkmnpqrstuvwxyz' ;
     $bits = array (16,8,4,2,1);
     $lat = array (-90.0, 90.0);
     $lon = array (-180.0, 180.0);
     
     $bit = $ch = $i = 0;
     $is_even = 1;
     $i = 0;
     $mid ;
     $geohash = '' ;
     while ( $i < $deep )
     {
         if ( $is_even )
         {
             $mid = ( $lon [0] + $lon [1]) / 2;
             if ( $longitude > $mid )
             {
                 $ch |= $bits [ $bit ];
                 $lon [0] = $mid ;
             } else {
                 $lon [1] = $mid ;
             }
         } else {
             $mid = ( $lat [0] + $lat [1]) / 2;
             if ( $latitude > $mid )
             {
                 $ch |= $bits [ $bit ];
                 $lat [0] = $mid ;
             } else {
                 $lat [1] = $mid ;
             }
         }
         
         $is_even = ! $is_even ;
         if ( $bit < 4)
             $bit ++;
         else {
             $i ++;
             $geohash .= $BASE32 [ $ch ];
             $bit = 0;
             $ch = 0;
         }
     }
     return $geohash ;
}
 
function decode_geohash( $geohash )
{
     $geohash = strtolower ( $geohash );
     $BASE32 = '0123456789bcdefghjkmnpqrstuvwxyz' ;
     $bits = array (16,8,4,2,1);
     $lat = array (-90.0, 90.0);
     $lon = array (-180.0, 180.0);
     $hashlen = strlen ( $geohash );
     $is_even = 1;
     
     for ( $i = 0; $i < $hashlen ; $i ++ )
     {
         $of = strpos ( $BASE32 , $geohash [ $i ]);
         for ( $j =0; $j <5; $j ++) {
             $mask = $bits [ $j ];
             if ( $is_even ) {
                 $lon [!( $of & $mask )] = ( $lon [0] + $lon [1])/2;
             } else {
                 $lat [!( $of & $mask )] = ( $lat [0] + $lat [1])/2;
             }
             $is_even = ! $is_even ;
         }
     }
     $point = array ( 0 => ( $lat [0] + $lat [1]) / 2, 1 => ( $lon [0] + $lon [1]) / 2);
     return $point ;
}

转载于:https://www.cnblogs.com/mylele/articles/4316016.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值