2016-02-28 4 views
1

У меня есть коллекция данных geoJSON в базе данных mongoDB (v2.6.10 ). Данные состоят из тысяч полигонов, в основном квадратов, которые представляют собой заявки на землю размером 500х500 м. Эти данные используются в веб-приложении, которое отображает данные на карте.mongodb geospatial queries polygon inside polygon

Производительность веб-приложения очень медленная из-за огромного количества полигонов. Чтобы повысить производительность, я хочу ограничить запросы границами текущего окна карты. Мы используем API-интерфейс Mapbox, и я могу получить карты из API, которые будут использоваться в гео-запросе mongodb.

До сих пор мне не удалось связаться с монгонговыми запросами.

Вот пример записи данных GeoJSON, которые хранятся в БД:

{ 
    "_id" : ObjectId("56ca94e0336aac299182442f"), 
    "type" : "Feature", 
    "properties" : { 
    "TNRTPCD" : "P", 
    ## some fields ommitted for privacy reasons ## 
    "TRMNTNDT" : null, 
    "RNHCTRS" : 20.3496, 
    "TTLTPCD" : "PCX" 
    }, 
    "geometry" : { 
    "type" : "Polygon", 
    "coordinates" : [ 
     [ 
     [ 
      [ 
      -121.88883540217063, 
      50.97489195799901, 
      0 
      ], 
      [ 
      -121.88883523174192, 
      50.97072525131302, 
      0 
      ], 
      [ 
      -121.8950854466247, 
      50.97072527980969, 
      0 
      ], 
      [ 
      -121.89508560169767, 
      50.97489198254216, 
      0 
      ], 
      [ 
      -121.88883540217063, 
      50.97489195799901, 
      0 
      ] 
     ] 
     ] 
    ] 
    } 
} 

Я попытался следующий запрос и возвращает никаких записей и нет ошибок:

db.docs.find(
    { 
    'geometry.coordinates': { 
     $geoWithin: { 
      $geometry: { 
      type : "Polygon" , 
      coordinates: [[ 
      [ -121.26571655273438, 49.56352444783811 ], 
      [ -121.26571655273438, 52.719152198289635 ], 
      [ -120.97492218017578, 52.719152198289635 ], 
      [ -120.9749221801757, 49.56352444783811 ], 
      [ -121.26571655273438, 49.56352444783811 ] 
       ]] 
      } 
     } 
    } 
    } 
) 

I знайте, что есть данные в пределах определенной границы и все же отмечаются возвращения. Я попытался сыграть с целевым столбцом. Я попытался переключить «geometry.coordinates» на просто координаты, я пробовал с кавычками и без. Я также столкнулся с координатами AOI многоугольника. Когда первая точка не повторяется, я получаю сообщение об ошибке.

Я также попытался переключить $ geoWithin на $ near, $ box и $ geoIntersects. С аналогичными результатами.

Я предполагаю, что проблема связана с географическим индексом, но это просто догадка. Я пытался поставить индекс 2dsphere на колонке геометрии, используя следующую команду:

db.docs.ensureIndex({ "geometry" : "2dsphere" }); 

Это терпит неудачу и дает следующее сообщение об ошибке:

"createdCollectionAutomatically" : false, 
    "numIndexesBefore" : 1, 
    "ok" : 0, 
    "errmsg" : "Can't extract geo keys from object, malformed geometry?: 

Когда я пытаюсь положить индекс на только координаты, кажется, работать. Я использовал эту команду:

db.docs.ensureIndex({ "coordinates" : "2dsphere" }); 

И получил следующий вывод:

"createdCollectionAutomatically" : false, 
    "numIndexesBefore" : 1, 
    "numIndexesAfter" : 2, 
    "ok" : 1 
} 

Чтобы быть честным, я новичок в MongoDB так эта обратная связь не означает, что много для меня. Я не новичок в ГИС и картографировании, но я не могу понять это. Пожалуйста помоги. Подводя итог, я пытаюсь сузить результаты моих запросов, используя функции геофильтрации манго.

+0

Yup это означает, что он говорит. Ваш GeoJSON недействителен, по крайней мере, для MongoDB. Проблема в том, что у вас есть значения «x/y/z», и вы можете иметь только значения «x/y». Итак, падение значений '0' для' z', которые вы бы не использовали в любом случае. –

+0

FYI, даже если исправлено, многоугольник, показанный в качестве примера в вашем вопросе **, не ** лежит в пределах полигона в вашем запросе. Таким образом, еще один вопрос, который вы задаете, заключается в том, чтобы убедиться, что образец, который вы предоставляете, является тем, что вы ожидаете от соответствия любым таким запросам, которые вы можете сделать. Этот документ не соответствует, даже если все z-индексы удалены. –

+0

Привет, Блэйкс, спасибо, что нашли время, чтобы помочь. Координаты Z не нужны. Имеет смысл, что они могут некорректно работать с «2D-сферой». Я восстановил файл geoJSON с удаленными координатами z. Затем импортируется в монго в виде отдельной коллекции. У меня такая же ошибка при попытке добавить индекс 2d: > db.docs4.ensureIndex ({"geometry": "2dsphere"}); { \t "createdCollectionAutomatically": ложь, \t "numIndexesBefore": 1, \t "ОК": 0, \t "ErrMsg": «Невозможно извлечь ключи гео из объекта, искаженной геометрии – ngust

ответ

0

ОК, я получил его сейчас. Проблема с координатами Z. Спасибо Блэйкс Семь за это. Я потратил много часов разочарования, пытаясь понять, почему запросы не будут работать.

Я воссоздал geoJSON на этот раз, удалив значения Z. В противном случае файлы geoJSON идентичны. Затем я импортировал только файл X, Y только в mongo в качестве другой коллекции.

Я все еще не удалось создать индекс 2dsphere на колонке геометрии, но я был в состоянии создать на координат непосредственно с помощью следующей команды:

db.docs.ensureIndex({ "coordinates" : "2dsphere" }); 

Из примеров онлайн, казалось, как индекс должен иметь были в столбце геометрии, но запросы работают с этой настройкой.

я теперь возвращает ожидаемые результаты с этим запросом:

db.docs4.find(
    { 
    "geometry": { 
     $geoWithin: { 
      $geometry: { 
      type : "Polygon" , 
      coordinates: [[ 
      [-121.57814025878906, 49.651181832527826 ], 
      [ -121.57814025878906, 49.80652967700498 ], 
      [ 121.28734588623047, 49.80652967700498 ], 
      [ -121.28734588623047, 49.651181832527826], 
      [ -121.57814025878906, 49.651181832527826 ] 
       ]] 
      } 
     } 
    } 
    } 
) 
0

Причиной этой ошибки вызывается пересекающиеся многоугольники. Это предотвратит создание 2D-индексов сферы.

Вы можете проверить, если у вас есть пересекающиеся загрузив файл GeoJSON на следующий сайт: mapshaper

Если какой-либо сообщается, вы можете исправить их на месте с помощью упрощать функции. Это нормально, чтобы исправить пару файлов, но если вам нужно исправить лот, тогда вам нужно будет использовать ogr2ogr в наборе инструментов GDAL.