Reputation: 38499
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?
Upvotes: 0
Views: 537
Reputation: 36764
$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;
Upvotes: 1