Kürzlich gab es ein Geschäftsszenario, bei dem Personen in der Nähe gefunden wurden. Daher habe ich die relevanten Informationen überprüft und eine technische Zusammenfassung der verschiedenen Möglichkeiten und spezifischen Implementierungen zur Verwendung von PHP zur Implementierung verwandter Funktionen erstellt Lesen Sie es. Bringen Sie Kommentare und Korrekturen mit und kommen wir zur Sache:
LBS (Location-Based Service)
Das Finden von Menschen in der Nähe hat einen größeren Begriff namens LBS (Location-Based Service), LBS bezieht sich auf Es ist Ein Mehrwertdienst, der die Standortinformationen von Benutzern mobiler Endgeräte über das Funkkommunikationsnetz von Telekommunikations-Mobilfunkbetreibern oder externe Positionierungsmethoden erhält und Benutzern mit Unterstützung der GIS-Plattform entsprechende Dienste bereitstellt. Daher muss zuerst der Standort des Benutzers ermittelt werden. Der Standort des Benutzers kann über GPS, Basisstation des Betreibers, WLAN usw. ermittelt werden. Im Allgemeinen erhält der Client die Längen- und Breitenkoordinaten des Standorts des Benutzers und lädt diese auf den Anwendungsserver hoch Der Anwendungsserver speichert die Benutzerkoordinaten und den Client. Beim Abrufen der Daten von Personen in der Nähe greift der Anwendungsserver auf die Datenbank zu, um sie basierend auf dem geografischen Standort des Anforderers und bestimmten Bedingungen (Entfernung, Geschlecht, aktive Zeit usw.) zu filtern und zu sortieren.
Wie finde ich den Abstand zwischen zwei Punkten basierend auf Längen- und Breitengrad?
Wir alle wissen, dass die Koordinaten zweier Punkte in ebenen Koordinaten mit der Formel für den Abstand der ebenen Koordinaten berechnet werden können, aber Längen- und Breitengrad sind sphärische Koordinatensysteme, die die sphärische Oberfläche des dreidimensionalen Raums verwenden, um den Raum auf der Erde zu definieren . Unter der Annahme, dass die Erde in Bezug auf den Kugelabstand eine perfekte Kugel ist, lautet die Berechnungsformel wie folgt:
Wenn Sie sich für den spezifischen Inferenzprozess interessieren, empfehle ich diesen Artikel: [Mathematische Formel und Ableitung] Berechnen Sie den Abstand zwischen zwei Punkten auf dem Boden basierend auf Längen- und Breitengrad
Der PHP-Funktionscode lautet wie folgt:
/** * 根据两点间的经纬度计算距离 * @param $lat1 * @param $lng1 * @param $lat2 * @param $lng2 * @return float */ public static function getDistance($lat1, $lng1, $lat2, $lng2){ $earthRadius = 6367000; //approximate radius of earth in meters $lat1 = ($lat1 * pi() ) / 180; $lng1 = ($lng1 * pi() ) / 180; $lat2 = ($lat2 * pi() ) / 180; $lng2 = ($lng2 * pi() ) / 180; $calcLongitude = $lng2 - $lng1; $calcLatitude = $lat2 - $lat1; $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2); $stepTwo = 2 * asin(min(1, sqrt($stepOne))); $calculatedDistance = $earthRadius * $stepTwo; return round($calculatedDistance); }
Der MySQL-Code lautet wie folgt:
SELECT id, ( 3959 * acos ( cos ( radians(78.3232) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(65.3234) ) + sin ( radians(78.3232) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 30 ORDER BY distance LIMIT 0 , 20;
Zusätzlich zur Berechnung der sphärischen Abstandsformel oben können wir ihn erhalten Verwenden Sie bestimmte Datenbankdienste wie Redis und MongoDB:
Redis 3.2 bietet eine GEO-Funktion für geografische Standorte, mit der nicht nur die Entfernung zwischen zwei Standorten, sondern auch eine Sammlung geografischer Standorte innerhalb eines Standortbereichs ermittelt werden kann. Redis-Befehlsdokumentation
1. Einen geografischen Standort hinzufügen
GEOADD key longitude latitude member [longitude latitude member ...]
3. Ermitteln Sie die Entfernung zwischen zwei geografischen Standorten
GEOPOS key member [member ...]
4 Breitengrad
GEODIST key member1 member2 [unit]
5. Holen Sie sich die Standortsammlung mit geografischen Informationen des angegebenen Mitglieds
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
MongoDB hat einen Geodatenindex speziell für diese Art von Abfrage erstellt. Die Indizes 2d und 2dsphere gelten für Ebenen bzw. Kugeln.
MongoDB-DokumentGEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
3. Finden Sie die maximale Entfernung und die maximale Anzahl von Elementen
db.location.insert( {uin : 1 , loc : { lon : 50 , lat : 50 } } )
5 Ergebnisse Der Abstand zwischen einem Punkt und dem Abfragepunkt
db.location.ensureIndex( { loc : "2d" } )
6. Verwenden Sie geoNear mit Abfragebedingungen und einer Rückgabenummer. GeoNear verwendet den runCommand-Befehl und unterstützt nicht die Funktion zum Begrenzen und Überspringen von Parametern im Zusammenhang mit Paging in der Suchabfrage
Mehrere PHP-Methoden und spezifische Implementierungen1. Basierend auf MySql
Methode zum Hinzufügen von Mitgliedern:
db.location.find( { loc :{ $near : [50, 50] } )
Abfrage von Personen in der Nähe (unterstützt Abfragebedingungen und Paging): db.location.find( { loc : { $near : [50, 50] , $maxDistance : 5 } } ).limit(20)
PHP kann die
redis-Erweiterung mit Redis installieren oder die
predis-Klassenbibliothek über Composer installieren. In diesem Artikel wird die Redis-Erweiterung verwendet, um sie zu implementieren.
Methode zum Hinzufügen von Mitgliedern:
db.runCommand( { geoNear : "location" , near : [ 50 , 50 ], num : 10, query : { type : "museum" } } )
Personen in der Nähe abfragen (Abfragebedingungen und Paging werden nicht unterstützt): db.runCommand( { geoNear : "location" , near : [ 50 , 50 ], num : 10, query : { uin : 1 } })
(
Document) und
mongodb(
Dokumentation) Um eine gute Erweiterung auszuwählen, müssen Sie die entsprechende Dokumentation überprüfen. Da es sich bei der Mongodb-Erweiterung um eine neue Version handelt, wird in diesem Artikel die Mongodb-Erweiterung ausgewählt. Angenommen, wir erstellen die Datenbankbibliothek und die Standortsammlung. Legen Sie den Index fest: public function geoAdd($uin, $lon, $lat)
{
$pdo = $this->getPdo();
$sql = 'INSERT INTO `markers`(`uin`, `lon`, `lat`) VALUES (?, ?, ?)';
$stmt = $pdo->prepare($sql);
return $stmt->execute(array($uin, $lon, $lat));
}
public function geoNearFind($lon, $lat, $maxDistance = 0, $where = array(), $page = 0)
{
$pdo = $this->getPdo();
$sql = "SELECT
id, (
3959 * acos (
cos ( radians(:lat) )
* cos( radians( lat ) )
* cos( radians( lon ) - radians(:lon) )
+ sin ( radians(:lat) )
* sin( radians( lat ) )
)
) AS distance
FROM markers";
$input[':lat'] = $lat;
$input[':lon'] = $lon;
if ($where) {
$sqlWhere = ' WHERE ';
foreach ($where as $key => $value) {
$sqlWhere .= "`{$key}` = :{$key} ,";
$input[":{$key}"] = $value;
}
$sql .= rtrim($sqlWhere, ',');
}
if ($maxDistance) {
$sqlHaving = " HAVING distance < :maxDistance";
$sql .= $sqlHaving;
$input[':maxDistance'] = $maxDistance;
}
$sql .= ' ORDER BY distance';
if ($page) {
$page > 1 ? $offset = ($page - 1) * $this->pageCount : $offset = 0;
$sqlLimit = " LIMIT {$offset} , {$this->pageCount}";
$sql .= $sqlLimit;
}
$stmt = $pdo->prepare($sql);
$stmt->execute($input);
$list = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $list;
}
public function geoAdd($uin, $lon, $lat) { $redis = $this->getRedis(); $redis->geoAdd('markers', $lon, $lat, $uin); return true; }
Fragen Sie Personen in der Nähe ab (Ergebnisse mit Entfernung zurückgeben, Abfragebedingungen unterstützen, Anzahl der Zahlungsrückgaben, Paging nicht unterstützen):
public function geoNearFind($uin, $maxDistance = 0, $unit = 'km') { $redis = $this->getRedis(); $options = ['WITHDIST']; //显示距离 $list = $redis->geoRadiusByMember('markers', $uin, $maxDistance, $unit, $options); return $list; }
Hinweise:
1 Wählen Sie eine gute Erweiterung, die Schreibmethoden von Mongo- und Mongodb-Erweiterungen sind sehr unterschiedlich
2. Wenn beim Schreiben von Daten keine Antwort angezeigt wird, überprüfen Sie bitte die Schreibbestätigungsebene.
3 Die mit „find“ abgefragten Daten müssen die Entfernung selbst berechnen, und die mit „geoNear“ abgefragten Daten unterstützen kein Paging.
Die abgefragte Entfernung Die Verwendung von geoNear muss mithilfe der sphärischen und distanceMultiplier-Parameter in km umgewandelt werden. Die obige Demo kann hier angeklickt werden: Demo. Zusammenfassung: Das Obige stellt drei Möglichkeiten vor, die Funktion zum Abfragen von Personen in der Nähe zu implementieren B. relativ wenige Datenzeilen, reicht MySQL aus, um die Entfernung zwischen einem Benutzer und mehreren Städten abzufragen. Wenn Sie jedoch eine schnelle Antwort in Echtzeit und einen allgemeinen Suchbereich benötigen Da die Datenmenge groß ist und es mehrere Attributfilterbedingungen gibt, ist die Verwendung von Mongo praktischerweise nur Vorschläge. Der spezifische Implementierungsplan muss auf der Grundlage des jeweiligen Unternehmens überprüft werden.
Das obige ist der detaillierte Inhalt vonBringen Sie Ihnen bei, wie Sie PHP verwenden, um Personen in der Nähe zu finden, die Sie suchen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!