MongoDB Geospatial - 搜索点项和geoIntersects

时间:2014-01-22 22:53:49

标签: mongodb mongoose geospatial

我正在开发一个在某个点附近搜索商家的应用程序:

目前文档结构如下:

{
        "_id" : ObjectId("52dbcf155b67b9f80f000021"),
        "name" : "Some Business Name",
        "town" : "Bournemouth",
        "postcode" : "BH7 4XK",
        "country_code" : "UK",
        "country_name" : "United Kingdom",

        "geo" : {
                "type" : "Point",
                "coordinates" : [
                        -1.8185951,
                        50.7429735
                ]
        }

}

这代表了一项业务。

'geo'代表它的纬度/经度

然后,我可以使用$near

搜索x英里一点的商家

但是,有些企业提供“移动”服务 - 即,覆盖距给定点x英里的区域。 在这个例子中,我考虑过在doc中添加另一个元素:

    "mobileGeo" : {
            "type" : "Polygon", //I'm guessing?
            "coordinates" : [] // not sure how to represent...
    }

如何更改我的查询以涵盖'geo'项目以及与我的'mobileGeo'元素相交的任何项目?

例如:

enter image description here

A和B是“固定”点 C表示距离给定点10英里的区域。 由于此半径与“搜索”区域重叠,因此会在结果中返回。

我见过`$ geoIntersects',但我不确定这是否正确?

1 个答案:

答案 0 :(得分:1)

$ geoIntersects是一个运算符,它将包含两个完全覆盖的点(您的A和B)以及与(C)相交的所有内容。但是,您只能使用一个运算符,因此如果要使用$geoIntersects,则需要确保搜索几何是同一字段的一部分。因此,我建议将搜索字段(点或多边形)存储为与显示字段不同(点,我想)。然后只在搜索字段上设置索引。如果搜索字段包含一个点,那么您当然可以选择不存储显示字段,因为它将是重复的信息。

您的第二个问题涉及计算C +半径的多边形。我不认为你可以直接用GeoJSON做到这一点,所以你需要计算合适的点来构成你的圈子。在PHP中,您可以使用以下内容执行此操作:

<?php
$lat = 51.5;
$lon = -0.5;

$latRad = deg2rad( $lat );
$lonRad = deg2rad( $lon );

$diameter = 6371; // radius of earth
$distance =    5; // 5 km

$radius = $distance / $diameter;

$points = [];

// create 16 points.
for ($i = 0; $i <= M_PI * 2 + 0.1; $i += M_PI / 8)
{
    $latNew = $latRad + ( sin( $i ) * $radius );
    $lonNew = $lonRad + ( ( cos( $i ) * $radius ) / cos( $latNew ) );

    $points[] = [ rad2deg( $lonNew ), rad2deg( $latNew ) ];

}

$json =json_encode( [
    'type' => 'Polygon',
    'coordinates' => [[ $points ]]
], JSON_PRETTY_PRINT );

echo $json;