Jak przechowywać linie i wielokąty w dokumentach JSON?

24

Patrząc na rosnący ruch NoSQL i biorąc pod uwagę, że bazy danych takie jak MongoDB oferują nową perspektywę elastycznego przechowywania danych dla GIS. Jaki jest najlepszy sposób przechowywania linii i wielokątów w dokumentach JSON, aby skorzystać z indeksów 2d i funkcji przestrzennych?

Pablo
źródło
6
MongoDB nie obsługuje obecnie indeksowania niczego poza punktami, a jego funkcje przestrzenne ograniczają się do wyszukiwania w granicach.
scw

Odpowiedzi:

16

GeoJSON tutaj są specyfikacjami .

Oto przykład linii i wielokąta:

{ "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
źródło
9

Należy zauważyć, że wsparcie MongoDB dla typów danych przestrzennych jest strasznie złe dla każdego poważnego wyszukiwania przestrzennego, i dotyczy to całej tablicy NoSQL przy ostatnim sprawdzeniu. GeoCouch trochę mi się nie podoba, ale wciąż jest jeszcze wiele do zrobienia.

GeoJSON to fantastyczny format, ale aby skorzystać z ograniczonych (TYLKO PUNKTOWYCH) indeksów przestrzennych w Mongo, potrzebujesz indeksowanej przestrzennie kolekcji zawierającej tylko rekord dla każdego z punktów wielokąta z dodatkową wartością dla identyfikatora rekordu twojego rekord przestrzenny żyjący w innej kolekcji, a następnie użyj kwerendy obwiedni, aby uzyskać identyfikatory rekordów z jednej i wybrać drugą, skutecznie emulując sprzężenie.

Możesz się zhakować i po prostu zrobić rogi ramki granicznej jako punkty dla swoich rekordów, ale wtedy wyszukiwania ramki granicznej mogą się nie powieść, a w sumie wymusza to dość nieefektywne wzorce projektowe i niewłaściwie spycha wszelkie obowiązki na programistę.

Jako implementację referencyjną możesz odnieść się do tego kodu, który został zaprezentowany na tegorocznym szczycie programistów Esri.

W ogóle nie byłem zadowolony ze wsparcia przestrzennego w różnych bazach danych NoSQL. Przechodzą tylko wystarczająco daleko, by wyszukać głupie chmury punktów, co ma sens, biorąc pod uwagę, że większość aplikacji używających tego typu upuszcza pinezki na mapie Google w przeglądarce. PostGIS nadal będzie najlepszym koniem roboczym typu open source do zarządzania informacjami przestrzennymi w dającej się przewidzieć przyszłości.

Jason Scheirer
źródło
9

To po prostu nieprawda,

„aby skorzystać z indeksów przestrzennych w Mongo, potrzebujesz kolekcji indeksowanej przestrzennie zawierającej tylko zapis dla każdego punktu wielokąta, z dodatkową wartością identyfikatora rekordu rekordu przestrzennego mieszkającego w innej kolekcji, a następnie użyj zapytanie pola ograniczającego, aby uzyskać identyfikatory rekordów z jednej [kolekcji] i wybrać [nagrać dane] z drugiej [kolekcji], skutecznie emulując sprzężenie. ”

Mam dane punktów USGS przechowywane w jednej kolekcji Mongo z rekordami, które wyglądają tak:

> 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" }

Jestem w stanie wykonać zapytania o pola ograniczające na tych danych, które zwracają cały rekord (bez potrzeby kolejnej kolekcji).

Pytanie:

> 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);

Odpowiedź:

{ "_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 zapewnia także możliwość wyszukiwania najbliższych sąsiadów, a także wyszukiwania wielokątów. Jest to dobrze udokumentowane na mongodb.org

lagerratrobe
źródło
Przepraszam, ale jestem zdezorientowany, że MongoDB może, ale nie może utworzyć indeksu przestrzennego w kolekcjach obiektów liniowych i wielokątnych?
Derek Swingley,
2
W tej chwili nie można utworzyć indeksu przestrzennego dla obiektów liniowych i wielokątnych. Może jednak przeprowadzić wyszukiwanie typu punkt-w-wielokącie na tabeli z punktami, jeśli podasz geometrię wielokąta jako część zapytania. mongodb.org/display/DOCS/…
lagerratrobe
1
OK, więc stwierdzenie: „GeoJSON jest fantastycznym formatem, ale aby skorzystać z ograniczonych (TYLKO POINT) indeksów przestrzennych w Mongo” jest w rzeczywistości prawdziwe, ponieważ Mongo może tylko indeksować przestrzennie punkty.
Derek Swingley
Przyznaję, że część tego zdania jest dokładna, „ograniczona (TYLKO POINT) indeksami przestrzennymi”. A więc 5 z 71 słów, czyli 7%. To sprawia, że ​​93% z nich jest niepoprawnych. Stoję za moim oświadczeniem.
lagerratrobe
1
Czy możesz edytować swoją odpowiedź, aby wyjaśnić? Jest to mylące i mylące. Czy w odniesieniu do drugiej części stwierdzenia nie jest to po prostu sugestia dotycząca wdrożenia indeksu przestrzennego dla danych niepunktowych? To może nie być idealne ani optymalne, ale to tylko sugestia. Pomocne byłoby również wyjaśnienie, dlaczego uważasz, że większość tego stwierdzenia jest błędna.
Derek Swingley,