简体   繁体   中英

MongoDB Geospatial - searching to point items AND geoIntersects

I'm working on an application that searches for business near a certain point:

Document structure currently looks like:

{
        "_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
                ]
        }

}

This represents a business.

The 'geo' represents it's lat / lon

I can then search for businesses with x miles of a point using $near

However, some businesses offer a "mobile" service.
- ie, cover an area x miles from a given point. In this instance, I've thought about adding another element to the doc:

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

How could I change my query to cover both the 'geo' items, and any that intersect from my 'mobileGeo' element?

For example:

在此处输入图片说明

A and B are “fixed” points C represents an area of 10 miles from a given point. Since this radius overlaps the 'search' area, it is returned in the results.

I've seen `$geoIntersects', but am unsure if this is correct?

$geoIntersects is an operator that will include both fully covered points (your A and B) and also everything that intersects (C). You can however only use one operator, so if you want to use a $geoIntersects , you need to make sure that your search geometries are part of the same field. I would therefore suggest to store your search field (point or polygon) different from your display field (point, I suppose). And then only set the index on the search field. If the search field contains a point then you can of course choose not to store the display field as it would be duplicated information.

Your second question involves calculating the polygon for your point C + radius. I don't think you can do that directly with GeoJSON, so you need to calculate appropriate points to make up your circle. In PHP, you could do that with something like:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM