Ich habe kürzlich eine Übung gemacht, bei der ich versucht habe, eine App zu erstellen, während ich so tat, als wäre ich ein Minimalist. Dies erforderte, dass ich GPS-Punkte filtern konnte, ohne meinen bewährten Freund PostGIS zu verwenden.
Ich habe einen kurzen Überblick über die drei beliebtesten Methoden zur Indizierung räumlicher Daten gegeben: Geohash, H3 und S2.
Alle drei dieser Werkzeuge funktionieren, indem sie den Globus in Formen zerteilen, die sich beim Vergrößern in immer kleinere Einheiten unterteilen.
Eine gute Möglichkeit, die Funktionsweise dieser Indextypen zu erkunden, ist unter https://geohash.softeng.co/. Wenn Sie auf jede Zelle klicken, wird sie vergrößert und zeigt Ihnen eine tiefere Ebene. Einer meiner Lieblingsorte auf der Welt ist GeoHash ddk6p5
Um diese zum „Indexieren“ von GPS-Daten zu verwenden, müssen Sie lediglich eine Textspalte für jede Ebene hinzufügen, an der Sie interessiert sind. Ich könnte beispielsweise eine Tabelle wie diese erstellen:
CREATE TABLE IF NOT EXISTS places ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, latitude REAL, longitude REAL, geohash_level_2 TEXT, geohash_level_4 TEXT ); INSERT INTO places (name,latitude,longitude,geohash_level_2,geohash_level_4) VALUES('mt shavano', 38.618840, -106.239364, '9w', '9wu7'); INSERT INTO places (name,latitude,longitude,geohash_level_2,geohash_level_4) VALUES('blanca peak', 37.578047, -105.485796, '9w', '9wsv'); INSERT INTO places (name,latitude,longitude,geohash_level_2,geohash_level_4) VALUES('mt princeton', 38.749148, -106.242578, '9w', '9wuk'); INSERT INTO places (name,latitude,longitude,geohash_level_2,geohash_level_4) VALUES('la soufriere', 13.336299, -61.177146, 'dd', 'ddk7');
Sqlime ist ein guter Ort, um diese Abfragen auszuprobieren.
Um dann Orte im Süden Colorados zu finden, würde ich herausfinden, welcher Hash den Teil der Karte abdeckt, der „9w“ ist:
SELECT * FROM places WHERE geohash_level_2 = '9w';
Um Orte in der südlichen Karibik zu finden, könnte ich Folgendes verwenden:
SELECT * FROM places WHERE geohash_level_2 = 'dd';
Dieser Ansatz erfordert im Voraus eine gewisse Planung darüber, welche Indexebenen Sie in Ihrer Datenbank behalten müssen. Ansonsten funktioniert es hervorragend für einfache Anwendungen, bei denen Sie schnell herausfinden müssen, welche Objekte in einem bestimmten Bereich oder Kartenansichtsfenster gefunden werden.
Eine Datenbank, die LIKE-Abfragen unterstützt, kann dazu beitragen, die Verwendung mehrerer Spalten zu reduzieren. Beachten Sie außerdem, dass H3-Zellennummern nicht perfekt überlappen, sodass Abfragen vom Typ „beginnt mit“ mit H3 nicht funktionieren.
Schließlich ist ein nettes Merkmal dieser Indizes, dass sich die Zellnummern hervorragend als Echtzeit-Ereignisthemen eignen würden. In meinen obigen Beispielen könnte ich also ein Veranstaltungsthema namens „9w“ für Süd-Colorado erstellen. Wenn dann neue Orte hinzugefügt werden, würde ich für jeden neuen Ort ein Ereignis im Thema „9w“ ausgeben.
Hier finden Sie einige Beispiele für JavaScript-Code (Deno) für jeden dieser Indextypen:
Beachten Sie, dass die GeoJSON-Ausgabe hier angezeigt werden kann: https://geojson.io/
import { geocoordinateToGeohash } from 'npm:geocoordinate-to-geohash' import { geohashToPolygonFeature } from 'npm:geohash-to-geojson' import geohash from 'npm:ngeohash' const lat = 38.618840 const lng = -106.239364 const hash2 = geohash.encode(lat, lng, 2) console.log('mt shavano hash at level 2', hash2) const feat2 = geohashToPolygonFeature(hash2) console.log('mt shavano hash at level 2 bounds', JSON.stringify(feat2)) // About a city block in size in CO (size changes as you head towards poles) const hash7 = geohash.encode(lat, lng, 7) console.log('mt shavano hash at level 4', hash7) const feat7 = geohashToPolygonFeature(hash7) console.log('mt shavano hash at level 4 bounds', JSON.stringify(feat7))
import h3 from 'npm:h3-js' import geojson2h3 from "npm:geojson2h3" const lat = 38.618840 const lng = -106.239364 // Level 2 (~1/3 Colorado Size) const h3IndexL2 = h3.latLngToCell(lat, lng, 2); console.log('mt shavano cell at level 2', h3IndexL2) const featureL2 = geojson2h3.h3ToFeature(h3IndexL2) console.log('mt shavano cell at level 2 bounds', JSON.stringify(featureL2)) // Level 4 (~City of Salida Size) const h3IndexL4 = h3.latLngToCell(lat, lng, 4); console.log('mt shavano cell at level 4', h3IndexL4) const featureL4 = geojson2h3.h3ToFeature(h3IndexL4) console.log('mt shavano cell at level 4 bounds', JSON.stringify(featureL4))
// This might be a better choice : https://www.npmjs.com/package/@radarlabs/s2 import s2 from 'npm:s2-geometry' const S2 = s2.S2 const lat = 38.618840 const lng = -106.239364 const key2 = S2.latLngToKey(lat, lng, 2) const id2 = S2.keyToId(key2) const feature2 = cellCornersToFeatureCollection(lat, lng, 2) console.log('mt shavano key at level 2', key2) console.log('mt shavano cell id at level 2', id2) console.log('mt shavano cell at level 2 corners', JSON.stringify(feature2)) const key4 = S2.latLngToKey(lat, lng, 4) const id4 = S2.keyToId(key4) const feature4 = cellCornersToFeatureCollection(lat, lng, 4) console.log('mt shavano key at level 4', key4) console.log('mt shavano cell id at level 4', id4) console.log('mt shavano cell at level 4 corners', JSON.stringify(feature4)) function cellCornersToFeatureCollection(lat, lng, level) { const ll = S2.L.LatLng(lat, lng) const cell = S2.S2Cell.FromLatLng(ll, level) const corners = cell.getCornerLatLngs() const coordinates = corners.map((pair) => { return [pair.lng, pair.lat] }) return { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [coordinates] }, "properties": {} } ] } }
Das obige ist der detaillierte Inhalt vonGeoindizierungs-Sampler. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!