MongoDB如何检查点是否在多边形内部?

30

mongo 2.6

我有一些存储的多边形,还有一个点。我想知道这个点是否适合任何存储的多边形。

文档示例

{ ..., "polygons" : [ [ 17.60083012593064, 78.18557739257812 ], [ 17.16834652544664, 78.19381713867188 ], [ 17.17490690610013, 78.739013671875 ], [ 17.613919673106714, 78.73489379882812 ] ], ... }

已经有一个几乎相同的问题了 Mongodb : Check if a point is inside a stored polygon。 但是对于我来说它不起作用 - 这个查询至少要给出一个结果(例如中的那个),但它没有。

db.areas.find( { polygons : { $geoIntersects : { $geometry : {type:"Point",coordinates:[17.3734, 78.4738]} } } } )

实际上,如果我选择多边形边界上的一个点-它确实有效。

$geoWithin 方法必须按照 mondodb 文档所述执行工作。

但是任何这些查询都不起作用。

db.areas.find( { polygons : { $geoWithin : { $geometry : {type:"Point",coordinates:[17.3734, 78.4738]} } } } ) - not supported with provided geometry

db.tradeareas.find( { polygons : { $geoWithin : { $geometry : {type:"Polygon",coordinates: inside_polygon} } } } ) - BadValue bad geo query

看起来我错过了什么,但不明白是什么和在哪里。

如果能得到帮助将不胜感激。


你正在使用2D还是2DSphere索引? - John Powell
我已经发布了一个解决方案。似乎对于点/多边形相交查询,顺序很重要。 - John Powell
3个回答

50
似乎与顺序有关。如果您使用$geoWithin并尝试查找多边形内的点,则在其中的是您正在搜索的字段。但是,$geoIntersects可以双向工作,因此您可以搜索多边形内的点或包含点的多边形,例如:
似乎与顺序有关。如果您使用$geoWithin并尝试查找多边形内的点,则在其中的是您正在搜索的字段。但是,$geoIntersects可以双向工作,因此您可以搜索多边形内的点或包含点的多边形,例如:
db.geom.insert({
  "polygons": {
    "type":"Polygon",
    "coordinates": [[
      [ 17.60083012593064, 78.18557739257812],
      [ 17.16834652544664, 78.19381713867188],
      [ 17.17490690610013, 78.739013671875],
      [ 17.613919673106714, 78.73489379882812],
      [ 17.60083012593064, 78.18557739257812]
    ]]
  }
});

db.geom.find({
  polygons: {
    $geoIntersects: {
      $geometry: {
        "type": "Point",
        "coordinates": [17.3734, 78.4738]
      }
    }
  }
});

还要注意,在多边形末尾需要重复第一个点。如果删除了最后一对点,你将会得到一个$err

无法规范化查询:BadValue坏地理查询错误。

看来MongoDB允许您插入无效的几何图形,并且只在尝试添加2dsphere索引或执行相交/包含/靠近查询时进行投诉,这我想是合理的,因为GeoJSON可以是有效的JSON而不是有效的几何图形。


谢谢您的回复。 我按照您建议的方式进行了测试 - 它确实可以正常工作 - 就像在Mongo文档示例中一样。 但是我没有多边形。 我只有一个点作为参数。 要获取多边形,我需要向数据库发出请求。 因此,在拥有一百万条记录的情况下,我需要进行200万次请求才能找到包含我的点的所有多边形。 - user3806072
@user3806072 我遇到了你之前遇到的同样问题。我认为这是保存的多边形的GEOJSON结构引起的。你把结构改成了什么样子?你的模式是什么样子的?非常感谢! - rmg.n3t
“这句话中的‘似乎与顺序有关’是什么意思?” - Chris
如果我们的数据库中有多个多边形和点,是否有可能实现相同的功能?我们能否在MongoDB中隐式地进行点对多边形分析? - banbar
1
@banbar。抱歉,我不再使用MongoDB了。我相信你可以实现它,但我认为你可能需要将其作为一个单独的问题来询问。 - John Powell
显示剩余2条评论

1

感谢John Powell,这里提供了相同查询的C#驱动程序版本。

 var geometry = new BsonDocument
                            {
                                     { "type", "Point" },
                                     { "coordinates",
                                        new BsonArray(new double[]{ Longitude,
                                        Latitude} ) }
                            };
                    var geometryOperator = new BsonDocument { { "$geometry", geometry } };
                    var geoIntersectsOperator = new BsonDocument { { "$geoIntersects", geometryOperator } };

                    var findField = new BsonDocument { { "geometry", geoIntersectsOperator } };


                    var results = MyCollection.Find(findField).ToList();

0

在Java中可以这样做

@Autowired
private MongoOperations mongoOpertions;
    
public void pointIntersect(GeoJsonPoint gp){
    Query query = new Query();
    query.addCriteria(Criteria.where("geometry").intersects(gp));
    List<ResultDtoType> result = mongoOpertions.find(query, ResultDtoType.class);
    //perform any action with result 
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接