Comment stocker des lignes et des polygones dans des documents JSON?

24

En regardant le mouvement NoSQL croissant et en considérant que les bases de données comme MongoDB offrent une nouvelle perspective dans le stockage de données flexible pour SIG. Quelle est la meilleure façon de stocker des lignes et des polygones dans des documents JSON pour tirer parti des index 2D et des fonctions spatiales?

Pablo
la source
6
MongoDB ne prend actuellement pas en charge l'indexation sur autre chose que des points, et ses fonctions spatiales sont limitées à la recherche dans des limites.
scw

Réponses:

16

GeoJSON voici les SPECs .

Voici un exemple de ligne et de polygone:

{ "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
la source
9

Une chose à noter est que la prise en charge de MongoDB pour les types de données spatiales est horriblement mauvaise pour toute recherche spatiale sérieuse, et cela s'applique à tous les niveaux avec NoSQL la dernière fois que j'ai vérifié. Je n'aime pas beaucoup GeoCouch un peu moins, mais il reste encore du chemin à parcourir.

GeoJSON est un format fantastique, mais pour profiter des index spatiaux limités (POINT-ONLY) dans Mongo, vous auriez besoin d'une collection indexée spatialement ne contenant rien d'autre qu'un enregistrement pour chacun des points du polygone avec une valeur supplémentaire pour l'ID d'enregistrement de votre enregistrement spatial vivant dans une autre collection, puis utilisez une requête de zone de délimitation pour obtenir les ID d'enregistrement de l'un et sélectionner dans l'autre, en émulant efficacement une jointure.

Vous pouvez aller hacky et juste faire les coins de la boîte englobante comme points pour vos enregistrements, mais les recherches dans la boîte englobante peuvent échouer et dans l'ensemble cela force certains modèles de conception assez inefficaces et pousse de manière inappropriée toutes sortes de responsabilités pour le développeur.

En tant qu'implémentation de référence, vous pouvez vous référer à ce code qui a été présenté au Esri Developer Summit cette année.

Je ne suis pas du tout satisfait du support spatial sur les différentes bases de données NoSQL. Ils ne vont que suffisamment loin pour la recherche de nuages ​​de points stupides, ce qui est logique étant donné que la plupart des applications qui utilisent cela ne font que déposer des punaises sur une carte Google sur un navigateur quelque part. PostGIS sera toujours le meilleur cheval de bataille open source pour gérer les informations spatiales dans un avenir prévisible.

Jason Scheirer
la source
9

Ce n'est tout simplement pas vrai,

"Pour tirer parti des index spatiaux dans Mongo, vous auriez besoin d'une collection indexée spatialement ne contenant qu'un enregistrement pour chacun des points du polygone, avec une valeur supplémentaire pour l'ID d'enregistrement de votre enregistrement spatial vivant dans une autre collection, puis utilisez un "Boîte de délimitation pour obtenir les ID d'enregistrement d'une [collection] et sélectionner [les données d'enregistrement] de l'autre [collection], en émulant efficacement une jointure".

J'ai des données de points USGS stockées dans une seule collection Mongo avec des enregistrements qui ressemblent à ceci:

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

Je suis capable de faire des requêtes de boîte englobante sur ces données qui retournent très bien l'enregistrement entier (sans avoir besoin d'une autre collection).

Question:

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

Réponse:

{ "_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 offre également la possibilité d'effectuer des recherches de voisins les plus proches, ainsi que des recherches de points dans les polygones. Ceci est bien documenté sur mongodb.org

lagerratrobe
la source
Toutes mes excuses, mais je suis confus, MongoDB peut ou ne peut pas créer un index spatial sur des collections d'entités linéaires et polygonales?
Derek Swingley
2
Il ne peut pas créer d'index spatial sur les entités linéaires et surfaciques pour le moment. Cependant, il peut effectuer une recherche point par polygone sur une table contenant des points, si vous fournissez la géométrie du polygone dans le cadre de la requête. mongodb.org/display/DOCS/…
lagerratrobe
1
OK, donc la déclaration: "GeoJSON est un format fantastique mais pour profiter des index spatiaux limités (POINT-ONLY) dans Mongo" est en fait vrai parce que Mongo ne peut indexer que spatialement des points.
Derek Swingley
Je vous accorde qu'une partie de cette phrase est exacte, "index spatiaux limités (POINT-ONLY)". Donc 5 mots sur 71, soit 7%. Cela laisse 93% de celui-ci incorrect. Je soutiens ma déclaration.
lagerratrobe
1
Pouvez-vous modifier votre réponse pour clarifier? En l'état, c'est déroutant et trompeur. En ce qui concerne l'autre partie de l'énoncé, n'est-ce pas simplement une suggestion pour la mise en œuvre d'un index spatial pour les données non ponctuelles? Ce n'est peut-être pas idéal ou optimal, mais ce n'est qu'une suggestion. Il serait également utile d'expliquer pourquoi vous pensez que la majorité de cette affirmation est fausse.
Derek Swingley