¿Cómo almacenar líneas y polígonos en documentos JSON?

24

Observando el creciente movimiento NoSQL y considerando que bases de datos como MongoDB ofrecen una nueva perspectiva en el almacenamiento flexible de datos para SIG. ¿Cuál es la mejor manera de almacenar líneas y polígonos en documentos JSON para aprovechar los índices 2D y las funciones espaciales?

Pablo
fuente
66
MongoDB actualmente no admite la indexación en nada más que puntos, y sus funciones espaciales se limitan a encontrar dentro de los límites.
scw

Respuestas:

16

GeoJSON aquí están las especificaciones .

Aquí hay un ejemplo de una línea y un polígono:

{ "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
fuente
9

Una cosa a tener en cuenta es que el soporte de MongoDB para los tipos de datos espaciales es terriblemente malo para cualquier búsqueda espacial seria, y esto se aplica en todos los ámbitos con NoSQL la última vez que lo verifiqué. No me gusta GeoCouch un poco menos, pero todavía tiene mucho camino por recorrer.

GeoJSON es un formato fantástico, pero para aprovechar los índices espaciales limitados (SOLO PUNTO) en Mongo, necesitaría una colección indexada espacialmente que no contenga más que un registro para cada uno de los puntos del polígono con un valor adicional para el ID de registro de su registro espacial que vive en otra colección, luego use una consulta de cuadro delimitador para obtener ID de registro de una y seleccionar de la otra, emulando efectivamente una unión.

Podría volverse loco y simplemente hacer las esquinas del cuadro delimitador como puntos para sus registros, pero luego las búsquedas del cuadro delimitador pueden fallar y, en general, obliga a algunos patrones de diseño bastante ineficientes y empuja inapropiadamente todo tipo de responsabilidades al desarrollador.

Como implementación de referencia, puede consultar este código que se presentó en la Cumbre de desarrolladores de Esri este año.

No estoy contento con el soporte espacial en las diversas bases de datos NoSQL. Solo van lo suficientemente lejos para la búsqueda en la nube de puntos tontos, lo que tiene sentido teniendo en cuenta que la mayoría de las aplicaciones que usan esto solo están colocando marcadores en un mapa de Google en un navegador en algún lugar. PostGIS seguirá siendo el mejor caballo de batalla de código abierto para gestionar la información espacial en el futuro previsible.

Jason Scheirer
fuente
9

Esto simplemente no es verdad,

"para aprovechar los índices espaciales en Mongo, necesitaría una colección indexada espacialmente que no contenga más que un registro para cada uno de los puntos del polígono, con un valor adicional para el ID de registro de su registro espacial que vive en otra colección, luego use un consulta de cuadro delimitador para obtener ID de registro de una [colección] y seleccionar [datos de registro] de la otra [colección], emulando efectivamente una unión ".

Tengo datos de puntos USGS almacenados en una única colección de Mongo con registros que se ven así:

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

Puedo hacer consultas de cuadro delimitador en estos datos que devuelven todo el registro (sin la necesidad de otra colección) muy bien.

Consulta:

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

Respuesta:

{ "_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 también ofrece la posibilidad de realizar búsquedas de vecinos más cercanos, así como de buscar puntos en polígonos. Esto está bien documentado en mongodb.org

lagerratrobe
fuente
Disculpas pero estoy confundido, ¿MongoDB puede o no puede crear un índice espacial en línea y colecciones de entidades poligonales?
Derek Swingley
2
No puede crear un índice espacial en línea y entidades poligonales en este momento. Sin embargo, puede realizar una búsqueda de punto en el polígono en una tabla con puntos, si proporciona la geometría del polígono como parte de la consulta. mongodb.org/display/DOCS/…
lagerratrobe
1
Bien, entonces la afirmación: "GeoJSON es un formato fantástico pero para aprovechar los índices espaciales limitados (SOLO PUNTO) en Mongo" es realmente cierto porque Mongo solo puede indexar puntos espacialmente.
Derek Swingley
Le garantizo que una parte de esa oración es precisa, "índices espaciales limitados (SOLO PARA PUNTOS)". Entonces 5 de 71 palabras, o 7%. Eso deja que el 93% sea incorrecto. Estoy detrás de mi declaración.
lagerratrobe
1
¿Puedes editar tu respuesta para aclarar? Como es, es confuso y engañoso. Con respecto a la otra parte de la declaración, ¿no es eso básicamente una sugerencia para implementar un índice espacial para datos no puntuales? Puede que no sea ideal u óptimo, pero es solo una sugerencia. También sería útil explicar por qué cree que la mayoría de esa afirmación es incorrecta.
Derek Swingley