Wie speichere ich Linien und Polygone in JSON-Dokumenten?

24

Angesichts der zunehmenden NoSQL- Bewegung und der Tatsache , dass Datenbanken wie MongoDB eine neue Perspektive für die flexible Speicherung von Daten für GIS bieten. Wie lassen sich Linien und Polygone am besten in JSON-Dokumenten speichern, um 2D-Indizes und räumliche Funktionen zu nutzen?

Pablo
quelle
6
MongoDB unterstützt derzeit nur die Indizierung von Punkten, und seine räumlichen Funktionen beschränken sich auf das Finden innerhalb von Grenzen.
scw

Antworten:

16

GeoJSON hier sind die SPECs .

Hier ist ein Beispiel für eine Linie und ein Polygon:

{ "type": "FeatureCollection",
  "features": [
    { "type": "Feature",
      "geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
      "properties": {"prop0": "value0"}
      },
    { "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
          ]
        },
      "properties": {
        "prop0": "value0",
        "prop1": 0.0
        }
      },
    { "type": "Feature",
       "geometry": {
         "type": "Polygon",
         "coordinates": [
           [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
             [100.0, 1.0], [100.0, 0.0] ]
           ]
       },
       "properties": {
         "prop0": "value0",
         "prop1": {"this": "that"}
         }
       }
     ]
   }
CaptDragon
quelle
9

Eine Sache, die zu beachten ist, ist, dass MongoDBs Unterstützung für räumliche Datentypen für jede ernsthafte räumliche Suche entsetzlich schlecht ist, und dies gilt allgemein für NoSQL, als ich das letzte Mal nachgesehen habe. Ich mag GeoCouch nicht so sehr, aber es hat noch viel zu tun.

GeoJSON ist ein fantastisches Format, aber um die begrenzten (NUR PUNKT) räumlichen Indizes in Mongo zu nutzen, benötigen Sie eine räumlich indizierte Sammlung, die nur einen Datensatz für jeden Punkt des Polygons mit einem zusätzlichen Wert für die Datensatz-ID Ihres Polygons enthält In einer anderen Sammlung lebender räumlicher Datensatz. Verwenden Sie dann eine Bounding-Box-Abfrage, um Datensatz-IDs von einer abzurufen und von der anderen auszuwählen, und emulieren Sie so effektiv einen Join.

Sie könnten hacky werden und nur die Ecken des Begrenzungsrahmens als Punkte für Ihre Datensätze verwenden, aber dann kann die Suche nach Begrenzungsrahmen fehlschlagen und insgesamt werden einige ziemlich ineffiziente Entwurfsmuster erzwungen und alle Arten von Verantwortlichkeiten werden dem Entwickler unangemessen auferlegt.

Als Referenzimplementierung können Sie auf diesen Code verweisen, der auf dem diesjährigen Esri Developer Summit vorgestellt wurde.

Ich war überhaupt nicht zufrieden mit der räumlichen Unterstützung der verschiedenen NoSQL-Datenbanken. Sie reichen nur für die Suche nach dummen Punktwolken aus. Dies ist sinnvoll, wenn man bedenkt, dass die meisten Apps, die diese Funktion verwenden, nur Pins auf einer Google-Karte in einem Browser ablegen. PostGIS wird auf absehbare Zeit immer noch das beste Open-Source-Arbeitspferd für die Verwaltung von Geodaten sein.

Jason Scheirer
quelle
9

Das ist einfach nicht wahr,

"Um räumliche Indizes in Mongo nutzen zu können, benötigen Sie eine räumlich indizierte Sammlung, die nur einen Datensatz für jeden der Punkte des Polygons enthält. Ein zusätzlicher Wert für die Datensatz-ID Ihres räumlichen Datensatzes, der in einer anderen Sammlung lebt, lautet dann a Bounding-Box-Abfrage zum Abrufen von Datensatz-IDs aus einer [Sammlung] und Auswählen von [Datensatzdaten] aus der anderen [Sammlung], um einen Join effektiv zu emulieren. "

Ich habe USGS-Punktdaten in einer einzelnen Mongo-Sammlung mit Datensätzen gespeichert, die wie folgt aussehen:

> db.names.find({FEATURE_NAME: 'Mount Saint Helens', STATE_ALPHA: 'WA'})       
{ "_id" : ObjectId("4e262106d7a99b7db41a4919"), 
"_ID" : 1525360, 
"FEATURE_NAME" : "Mount Saint Helens", 
"FEATURE_CLASS" : "Summit", 
"STATE_ALPHA" : "WA", 
"STATE_FIPS" : 53, 
"COUNTY_NAME" : "Skamania", 
"COUNTY_FIPS" : "059", 
"COORDS" : [ -122.1944, 46.1912 ], 
"ELEV_IN_FT" : "8356" }

Ich bin in der Lage, Bounding-Box-Abfragen für diese Daten durchzuführen, die den gesamten Datensatz zurückgeben (ohne dass eine weitere Sammlung erforderlich ist).

Abfrage:

> box = [[-126.562500,45.089036], [-123.750000,47.040182]]
[ [ -126.5625, 45.089036 ], [ -123.75, 47.040182 ] ]
> db.names.find({"COORDS" : {"$within" : {"$box" : box}}, FEATURE_CLASS: "Summit"}, {FEATURE_NAME: true, COUNTY_NAME: true, STATE_ALPHA: true, ELEV_IN_FEET: true}).limit(5);

Antwort:

{ "_id" : ObjectId("4e2620f8d7a99b7db4146cec"), "FEATURE_NAME" : "Harlocker Hill", "STATE_ALPHA" : "OR", "COUNTY_NAME" : "Coos" }
{ "_id" : ObjectId("4e2620f8d7a99b7db414a349"), "FEATURE_NAME" : "Neskowin Crest", "STATE_ALPHA" : "OR", "COUNTY_NAME" : "Tillamook" }
{ "_id" : ObjectId("4e2620f8d7a99b7db414a105"), "FEATURE_NAME" : "Miles Mountain", "STATE_ALPHA" : "OR", "COUNTY_NAME" : "Tillamook" }
{ "_id" : ObjectId("4e2620f8d7a99b7db414934a"), "FEATURE_NAME" : "Mount Gauldy", "STATE_ALPHA" : "OR", "COUNTY_NAME" : "Tillamook" }
{ "_id" : ObjectId("4e2620f8d7a99b7db4149d06"), "FEATURE_NAME" : "Little Hebo", "STATE_ALPHA" : "OR", "COUNTY_NAME" : "Yamhill" }

Mongo bietet auch die Möglichkeit, Suchen nach nächsten Nachbarn sowie nach Punkten in Polygonen durchzuführen. Dies ist auf mongodb.org gut dokumentiert

lagerratrobe
quelle
Entschuldigung, aber ich bin verwirrt, MongoDB kann oder kann keinen räumlichen Index für Linien- und Polygon-Feature-Sammlungen erstellen.
Derek Swingley
2
Derzeit kann kein räumlicher Index für Linien- und Polygon-Features erstellt werden. Es kann jedoch eine Point-in-Polygon-Suche in einer Tabelle mit Punkten durchgeführt werden, wenn Sie die Polygongeometrie als Teil der Abfrage angeben. mongodb.org/display/DOCS/…
lagerratrobe
1
OK, also die Aussage: "GeoJSON ist ein fantastisches Format, aber die begrenzten (NUR PUNKT) räumlichen Indizes in Mongo auszunutzen" ist tatsächlich wahr, weil Mongo Punkte nur räumlich indizieren kann.
Derek Swingley
Ich gebe Ihnen zu, dass ein Teil dieses Satzes genau ist, "begrenzte (NUR-PUNKT) räumliche Indizes". Also 5 von 71 Wörtern oder 7%. Das lässt 93% davon falsch. Ich stehe hinter meiner Aussage.
Lagerratrobe
1
Können Sie Ihre Antwort bearbeiten, um dies zu klären? So wie es ist, ist es verwirrend und irreführend. Ist dies im Übrigen nicht nur ein Vorschlag zur Implementierung eines räumlichen Index für Nicht-Punkt-Daten? Es ist vielleicht nicht ideal oder optimal, aber es ist nur ein Vorschlag. Es würde auch helfen, herauszufinden, warum Sie den größten Teil dieser Aussage für falsch halten.
Derek Swingley