Heim Backend-Entwicklung PHP-Tutorial 查找附近网点geohash算法及实现 (PHP版本)

查找附近网点geohash算法及实现 (PHP版本)

Jun 23, 2016 pm 01:43 PM

参考文档:

http://blog.csdn.net/wangxiafghj/article/details/9014363geohash  算法原理及实现方式
http://blog.charlee.li/geohash-intro/  geohash:用字符串实现附近地点搜索
http://blog.sina.com.cn/s/blog_7c05385f0101eofb.html    查找附近点--Geohash方案讨论
http://www.wubiao.info/372        查找附近的xxx 球面距离以及Geohash方案探讨
http://en.wikipedia.org/wiki/Haversine_formula       Haversine formula球面距离公式
http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe   球面距离公式代码实现
http://developer.baidu.com/map/jsdemo.htm#a6_1   球面距离公式验证  
http://www.wubiao.info/470     Mysql or Mongodb LBS快速实现方案


geohash有以下几个特点:

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

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

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

Geohash比直接用经纬度的高效很多。


Geohash算法实现(PHP版本)

<?phpclass Geohash{    private $coding="0123456789bcdefghjkmnpqrstuvwxyz";    private $codingMap=array();      public function Geohash()    {        for($i=0; $i<32; $i++)        {            $this->codingMap[substr($this->coding,$i,1)]=str_pad(decbin($i), 5, "0", STR_PAD_LEFT);        }      }      public function decode($hash)    {        $binary="";        $hl=strlen($hash);        for($i=0; $icodingMap[substr($hash,$i,1)];        }          $bl=strlen($binary);        $blat="";        $blong="";        for ($i=0; $ibinDecode($blat,-90,90);         $long=$this->binDecode($blong,-180,180);        // $lat=$this->binDecode($blat,2,54);        // $long=$this->binDecode($blong,72,136);          $latErr=$this->calcError(strlen($blat),-90,90);        $longErr=$this->calcError(strlen($blong),-180,180);          $latPlaces=max(1, -round(log10($latErr))) - 1;        $longPlaces=max(1, -round(log10($longErr))) - 1;          $lat=round($lat, $latPlaces);        $long=round($long, $longPlaces);          return array($lat,$long);    }      public function encode($lat,$long)    {        $plat=$this->precision($lat);        $latbits=1;        $err=45;        while($err>$plat)        {            $latbits++;            $err/=2;        }          $plong=$this->precision($long);        $longbits=1;        $err=90;        while($err>$plong)        {            $longbits++;            $err/=2;        }          $bits=max($latbits,$longbits);          $longbits=$bits;        $latbits=$bits;        $addlong=1;        while (($longbits+$latbits)%5 != 0)        {            $longbits+=$addlong;            $latbits+=!$addlong;            $addlong=!$addlong;        }          $blat=$this->binEncode($lat,-90,90, $latbits);          $blong=$this->binEncode($long,-180,180,$longbits);          $binary="";        $uselong=1;        while (strlen($blat)+strlen($blong))        {            if ($uselong)            {                $binary=$binary.substr($blong,0,1);                $blong=substr($blong,1);            }            else            {                $binary=$binary.substr($blat,0,1);                $blat=substr($blat,1);            }            $uselong=!$uselong;        }          $hash="";        for ($i=0; $i<strlen>coding[$n];        }          return $hash;    }      private function calcError($bits,$min,$max)    {        $err=($max-$min)/2;        while ($bits--)            $err/=2;        return $err;    }      private function precision($number)    {        $precision=0;        $pt=strpos($number,'.');        if ($pt!==false)        {            $precision=-(strlen($number)-$pt-1);        }          return pow(10,$precision)/2;    }      private function binEncode($number, $min, $max, $bitcount)    {        if ($bitcount==0)            return "";        $mid=($min+$max)/2;        if ($number>$mid)            return "1".$this->binEncode($number, $mid, $max,$bitcount-1);        else            return "0".$this->binEncode($number, $min, $mid,$bitcount-1);    }      private function binDecode($binary, $min, $max)    {        $mid=($min+$max)/2;          if (strlen($binary)==0)            return $mid;          $bit=substr($binary,0,1);        $binary=substr($binary,1);          if ($bit==1)            return $this->binDecode($binary, $mid, $max);        else            return $this->binDecode($binary, $min, $mid);    }}  ?></strlen>
Nach dem Login kopieren

测试实例

<?php require_once("db_config.php");require_once('geohash.class.php');  $geohash=new Geohash;  //经纬度转换成Geohash  //获取附近的信息$n_latitude  =  34.236080797698;$n_longitude = 109.0145193757;echo "当前位置为:经度108.7455,纬度34.3608<br/><br>以下网点离我最近:";  //开始$b_time = microtime(true);  //方案A,直接利用数据库存储函数,遍历排序  //方案B geohash求出附近,然后排序  //当前 geohash值 $n_geohash = $geohash->encode($n_latitude,$n_longitude);  //附近$n = 3;$like_geohash = substr($n_geohash, 0, $n); $sql = 'select * from retailersinfotable where geohash like "'.$like_geohash.'%"';  $query = mysql_query($sql);	if(mysql_num_rows($query))	{		while($row=mysql_fetch_array($query))		{			$data[] = array (							"latitude" =>$row["Latitude"],							"longitude"=>$row["Longitude"],							"name"     =>$row["RetailersName"],					);		}}  //算出实际距离 foreach($data as $key=>$val){    $distance = getDistance($n_latitude,$n_longitude,$val['latitude'],$val['longitude']);    $data[$key]['distance'] = $distance;      //排序列    $sortdistance[$key] = $distance;}    //距离排序array_multisort($sortdistance,SORT_ASC,$data);  //结束$e_time = microtime(true); echo "(计算耗时:" ;echo $e_time - $b_time; echo "秒)<br>";  //var_dump($data);   foreach($data as $key=>$val){	echo "";	echo $val['distance']. " 米-------".$val['name'];}  /***  @desc 根据两点间的经纬度计算距离*  @param float $latitude 纬度值*  @param float $longitude 经度值*/function getDistance($latitude1, $longitude1, $latitude2, $longitude2) {	$earth_radius = 6371000;   //approximate radius of earth in meters		$dLat = deg2rad($latitude2 - $latitude1);	$dLon = deg2rad($longitude2 - $longitude1);     /*       Using the       Haversine formula        http://en.wikipedia.org/wiki/Haversine_formula	   http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe       验证:百度地图  http://developer.baidu.com/map/jsdemo.htm#a6_1       calculate the distance     */		$a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * sin($dLon/2) * sin($dLon/2);	$c = 2 * asin(sqrt($a));	$d = $earth_radius * $c;		return round($d);   //四舍五入}  ?>
Nach dem Login kopieren




Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
2 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Repo: Wie man Teamkollegen wiederbelebt
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Abenteuer: Wie man riesige Samen bekommt
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

11 beste PHP -URL -Shortener -Skripte (kostenlos und Premium) 11 beste PHP -URL -Shortener -Skripte (kostenlos und Premium) Mar 03, 2025 am 10:49 AM

Lange URLs, die oft mit Schlüsselwörtern und Tracking -Parametern überfüllt sind, können Besucher abschrecken. Ein URL -Verkürzungsskript bietet eine Lösung, die präzise Links erstellt, die ideal für soziale Medien und andere Plattformen sind. Diese Skripte sind für einzelne Websites a wertvoll

Einführung in die Instagram -API Einführung in die Instagram -API Mar 02, 2025 am 09:32 AM

Nach seiner hochkarätigen Akquisition durch Facebook im Jahr 2012 nahm Instagram zwei APIs für den Einsatz von Drittanbietern ein. Dies sind die Instagram -Graph -API und die Instagram Basic Display -API. Ein Entwickler, der eine App erstellt, die Informationen von a benötigt

Arbeiten mit Flash -Sitzungsdaten in Laravel Arbeiten mit Flash -Sitzungsdaten in Laravel Mar 12, 2025 pm 05:08 PM

Laravel vereinfacht die Behandlung von temporären Sitzungsdaten mithilfe seiner intuitiven Flash -Methoden. Dies ist perfekt zum Anzeigen von kurzen Nachrichten, Warnungen oder Benachrichtigungen in Ihrer Anwendung. Die Daten bestehen nur für die nachfolgende Anfrage standardmäßig: $ Anfrage-

Erstellen Sie eine React -App mit einem Laravel -Back -Ende: Teil 2, reagieren Erstellen Sie eine React -App mit einem Laravel -Back -Ende: Teil 2, reagieren Mar 04, 2025 am 09:33 AM

Dies ist der zweite und letzte Teil der Serie zum Aufbau einer Reaktionsanwendung mit einem Laravel-Back-End. Im ersten Teil der Serie haben wir eine erholsame API erstellt, die Laravel für eine grundlegende Produktlistenanwendung unter Verwendung von Laravel erstellt hat. In diesem Tutorial werden wir Dev sein

Vereinfachte HTTP -Reaktion verspottet in Laravel -Tests Vereinfachte HTTP -Reaktion verspottet in Laravel -Tests Mar 12, 2025 pm 05:09 PM

Laravel bietet eine kurze HTTP -Antwortsimulationssyntax und vereinfache HTTP -Interaktionstests. Dieser Ansatz reduziert die Code -Redundanz erheblich, während Ihre Testsimulation intuitiver wird. Die grundlegende Implementierung bietet eine Vielzahl von Verknüpfungen zum Antworttyp: Verwenden Sie Illuminate \ Support \ facades \ http; Http :: fake ([ 'Google.com' => 'Hallo Welt',, 'github.com' => ['foo' => 'bar'], 'Forge.laravel.com' =>

Curl in PHP: So verwenden Sie die PHP -Curl -Erweiterung in REST -APIs Curl in PHP: So verwenden Sie die PHP -Curl -Erweiterung in REST -APIs Mar 14, 2025 am 11:42 AM

Die PHP Client -URL -Erweiterung (CURL) ist ein leistungsstarkes Tool für Entwickler, das eine nahtlose Interaktion mit Remote -Servern und REST -APIs ermöglicht. Durch die Nutzung von Libcurl, einer angesehenen Bibliothek mit Multi-Protokoll-Dateien, erleichtert PHP Curl effiziente Execu

12 Beste PHP -Chat -Skripte auf Codecanyon 12 Beste PHP -Chat -Skripte auf Codecanyon Mar 13, 2025 pm 12:08 PM

Möchten Sie den dringlichsten Problemen Ihrer Kunden in Echtzeit und Sofortlösungen anbieten? Mit Live-Chat können Sie Echtzeitgespräche mit Kunden führen und ihre Probleme sofort lösen. Sie ermöglichen es Ihnen, Ihrem Brauch einen schnelleren Service zu bieten

Ankündigung von 2025 PHP Situation Survey Ankündigung von 2025 PHP Situation Survey Mar 03, 2025 pm 04:20 PM

Die 2025 PHP Landscape Survey untersucht die aktuellen PHP -Entwicklungstrends. Es untersucht Framework -Nutzung, Bereitstellungsmethoden und Herausforderungen, die darauf abzielen, Entwicklern und Unternehmen Einblicke zu geben. Die Umfrage erwartet das Wachstum der modernen PHP -Versio

See all articles