Как получить все круги, в которых содержится точка?

Есть ли способ узнать, в каких многоугольниках (в частности, кругах) находится конкретная точка?

В этом случае я бы сохранил документы, содержащие круги, как показано ниже, я бы передал широту и долготу для точки и хотел бы получить все документы, в которых точка находится в пределах заданного круга.

{
  "_id" : ObjectId("53e3e85ce4b0c2e8227a1dad"),
  "name" : "Menlo College",
  "location" : [-122.1928, 37.45632],
  "radius" : NumberLong(215),
},
{
  "_id" : ObjectId("53e43d19e4b0aeabcb3d3f9d"),
  "name" : "West Valley College",
  "location" : [-122.01021194458008, 37.263226547586207],
  "radius" : NumberLong(604),
}

Если это невозможно, то возможно ли это, по крайней мере, с другими формами GeoJSON? Все, что я нашел до сих пор, указывает на то, что обратное возможно (найти все точки, которые находятся внутри круга), но ничего для этого сценария.

Спасибо


person Jorge Pozas    schedule 20.08.2014    source источник


Ответы (1)


Это возможно с помощью оператора запросов MongoDB $geoIntersects Geospatial.

Итак, если у вас есть коллекция полигонов GeoJson и вы хотите узнать все полигоны, которые пересекаются с заданной вами точкой, вам нужно выполнить следующее:

db.places.find( { <locationFieldOfYourDocuments> :
                  { $geoIntersects :
                    { $geometry :
                      { type : "Point" ,
                        coordinates: [long, lat]
                } } } } )

В приведенной выше команде loc — это атрибут каждого документа, который содержит координаты полигона GeoJson. Кроме того, убедитесь, что у вас есть индекс 2dsphere над <locationFieldOfYourDocuments>.

Теперь, чтобы решить вашу первоначальную проблему, я использую немного javascript. Возможно, есть лучшие решения, но я не знаю.

Допустим, все ваши круги хранятся в коллекции Circles. Я бы запрашивал эту коллекцию и извлекал каждый круг один за другим, а затем выполнял пересечение с другой коллекцией, которая содержала бы одну точку, которую вы хотели бы запросить, пересекается ли она с кругами или нет. Итак, пусть точка хранится в коллекции SinglePoint.

Скрипт будет выглядеть...

db.Intersections.remove({}); // emptying the output collection
var circleCursor = db.Circles.find();
while (circleCursor.hasNext()) {
    var circle = circleCursor.next();
    var coord = circle.location;
    var radiusInRadians = circle.radius * conversionFactorForRadius;
    var intersect = db.SinglePoint.find({loc :
                                         { $geoWithin :
                                           {$centerSphere : [coord], radiusInRadians}
                                         }});
    if (intersect.hasNext()) {db.Intersections.add(circle)} // this will add all intersecting circles to Intersections collection
}

Все, что вам нужно сделать, это сохранить этот скрипт в файле (myScript.js) и сделать вызов:

mongo DBName pathTomyScript.js

Это сохранит все круги, которые пересекаются с вашей точкой ввода, в коллекции Intersects. Все вышеперечисленные коллекции должны находиться в базе данных DBName.

person displayName    schedule 21.08.2014
comment
Это интересное решение. Хотя я думаю, что хочу попытаться избежать необходимости получать все круги, потому что, хотя сейчас их всего несколько, необходимо масштабировать, чтобы иметь десятки тысяч кругов, и это будет выполняться тысячи раз в день для разных точек. .. Думаю, если бы я знал максимальный радиус круга, я мог бы получить все круги на заданном расстоянии от точки. - person Jorge Pozas; 21.08.2014
comment
Я знаю, что это не умный ответ. Это лучшее, что я мог придумать сейчас. Подождите несколько дней. Кто-то, вероятно, поставит лучшее решение или, может быть, 10gen добавит некоторые функции в MongoDB в более новых версиях. - person displayName; 21.08.2014
comment
Оцените ответ. Я собираюсь использовать вариант этого, пока у меня не будет лучшего решения для него. - person Jorge Pozas; 08.09.2014
comment
@displayName .. я думаю, что mongo shud предоставляет функцию для хранения концентраторов (кругов) и функцию для их извлечения. а также предоставить варианты поиска, если точка находится внутри круга.. - person shivadarshan; 28.01.2015
comment
@shivadarshan: это, вероятно, начнется в более поздних версиях. SQL Server предоставляет эту функциональность на данный момент. - person displayName; 28.01.2015
comment
@displayName.. не могли бы вы объяснить мне, как использовать эту функцию в sql - person shivadarshan; 29.01.2015
comment
@shivadarshan: используйте STIntersects() в типах данных SqlGeography или SqlGeometry, чтобы сделать это в одной команде. Погугли это. - person displayName; 29.01.2015