Ja, es gibt einen besseren Weg. Sie müssen einen räumlichen Index verwenden . Diese Indizes organisieren Metadaten zu Geometrien, um weit entfernte Geometrien sehr schnell herauszufiltern. Dadurch werden viele CPU-Zyklen gespart, indem die von Ihnen beschriebenen Berechnungen vermieden werden. Sie sollten sich nicht die Mühe machen, eine selbst zu implementieren, da alle wichtigen relationalen Datenbanken einen räumlichen Geometrietyp und dazugehörige Indizes bereitstellen.
Was Sie untersuchen möchten, sind Abfragen "innerhalb der Entfernung" (Abfragen für Geometrien innerhalb einer bestimmten Entfernung von einer anderen Geometrie). Dies sind sehr standardmäßige und weitgehend gelöste Probleme, die in allen oben genannten Datenbanken (und in mehreren integriert) möglich sind:
- PostGIS:
ST_DWithin
- SQL Server:
STDistance
(Es ist nicht klar, ob die Indexverwendung in der 3D-Geografie-Version dieser Funktion unterstützt wird.)
- Oracle:
SDO_WITHIN_DISTANCE
(Dies bedeutet nicht explizit, dass die Verwendung des Index ausgelöst wird. Ich würde den Abfrageplan noch einmal überprüfen. Möglicherweise müssen Sie einen anwenden SDO_FILTER
, damit er den Index verwendet.)
- MySQL: Ich finde das immer noch heraus.
Problemumgehung zum Auslösen der Indexverwendung
Im schlimmsten Fall, wenn Sie Probleme haben, das System dazu zu bringen, den räumlichen Index mit diesen Abfragen zu verwenden, können Sie einen zusätzlichen Filter hinzufügen. Sie erstellen einen quadratischen Begrenzungsrahmen mit Seiten der Länge 2 * (Suchabstand), der an Ihrem Suchpunkt zentriert ist, und vergleichen die Begrenzungsrahmen der Tabellengeometrien damit , bevor Sie den tatsächlichen Abstand überprüfen. Das macht PostGIS ' ST_DWithin
oben sowieso intern.
Entfernung in GIS
Während räumliche Indizes fantastisch und absolut die richtige Lösung für Ihr Problem sind, kann die Entfernungsberechnung logisch kompliziert werden. Insbesondere müssen Sie sich Gedanken darüber machen, in welcher Projektion (im Grunde alle Parameter für das Koordinatensystem) Ihre Daten gespeichert sind. Die meisten 2D-Projektionen (andere als Winkelkoordinatensysteme wie die verschiedenen Lat / Long-Projektionen) verzerren die Länge erheblich. Beispielsweise erweitert die Web Mercator-Projektion (die von Google, Bing und allen anderen großen Anbietern von Basiskarten verwendet wird) Bereiche und Entfernungen zunehmend, je weiter der Standort vom Äquator entfernt ist . Ich kann mich irren, da ich nicht offiziell in GIS ausgebildet bin, aber das Beste, was ich für 2D-Projektionen gesehen habe, sind einige spezifische, die korrekte Abstände von a versprecheneinzelner, konstanter Punkt in der ganzen Welt. (Nein, es ist nicht praktisch, für jede Abfrage eine andere Projektion zu verwenden. Dadurch werden Ihre Indizes unbrauchbar.)
Die Quintessenz ist, dass Sie sicherstellen müssen, dass Ihre Mathematik korrekt ist. Aus Sicht der Entwicklung ist dies am einfachsten, wenn Sie Winkelprojektionen (diese werden häufig als "geografisch" bezeichnet) und Funktionen verwenden, die das Berechnen mit einem Sphäroidmodell unterstützen. Diese Berechnungen sind jedoch etwas teurer als die 2D-Berechnungen und einige DBs unterstützen die Indizierung möglicherweise nicht. Wenn Sie mit ihnen jedoch eine akzeptable Leistung erzielen können, ist dies wahrscheinlich der richtige Weg. Eine weitere häufig verwendete Option sind regionale Projektionen (wie UTM-Zonen), mit denen Entfernungen und Bereiche nahezu korrigiert werden, wenn Ihre Daten auf einen bestimmten Teil der Welt beschränkt sind. Was für Ihre App am besten ist, hängt von Ihren spezifischen Anforderungen ab.
Dies gilt auch dann, wenn Sie keine integrierten räumlichen Indizes verwenden. Ihre Daten haben eine gewisse Projektion, unabhängig davon, welche Technologie oder Technik Sie derzeit verwenden oder in Zukunft verwenden. Sie wirken sich bereits auf alle Abfragen und Berechnungen aus, die Sie durchführen.