How to get nearby location in a specific range? - geolocation

I have a array of latitude and longitude and a center point.
{
center: {
lat: 10.002,
lng: 20.003
},
all: [
{
lat: 20,
lng: 50
},
{
lat: 10,
lng: 20.000001
},
// ...
]
}
I would like to know how do I get nearby locations in 10km or other specific range. Does there any keyword or library can help me do this?

you can use geohash.
standard geohash can give you a good starting point, since the hash represents the location so you can group by the hash on certain mask based on your precision.
refer to: https://en.wikipedia.org/wiki/Geohash
this method is simple and there are lots of libraries out there.
but it also suffers from pole distortion and edge cases.
however I have implemented an alternative algorithm to solve those problems: https://github.com/linehrr/geohash
the drawback is that precision is pre-determined, so masking won't work since it's not linear.
hope this helps.

Related

How to calculate total distance between points covered by a Cab when my pickup and drop location are same?

I am working on some Cab related app. But I have a problem that if my pick up location and drop location are same then how can I calculate the distance covered by the cab that time.
Currently I am calculating distance from one coordinates to another coordinates using the below mentioned code.
func calculateDistance(pickLat: String, pickLong: String, dropLat: String, dropLong: String) {
let coordinate0 = CLLocation(latitude: Double(pickLat)!, longitude: Double(pickLong)!)
let coordinate1 = CLLocation(latitude: Double(dropLat)!, longitude: Double(dropLong)!)
let distanceInMeters = coordinate0.distance(from: coordinate1) // result is in meters
print(distanceInMeters)
}
This is normal process I am doing. Please help me out.
For this you need to work on specific event. You need to start capturing the location from your taxi app when the taxi arrived at pickup and the ride is started. You must have events like ArrivedOnPickup , RideStarted,OnWay, Completed.
Just like #Lu_ Suggested start capturing the coordinates in an array till the ride is completed. On ride completion you get the distance by implementing
http://findnerd.com/list/view/How-to-calculate-distance-from-array-of-coordinates-in-iOS/17529/
Note: You can also use Google Direction api to draw path and get the distance but this will not ensure that you route taken by the driver and route provided by the google will be same

Get documents in the order same as given array

Consider a scenario, where user wants deals which are sorted by nearest distance from his current location.
I have defined 2 documents, one is locations and other is deals. Deals can have many locations, locations have a 2dsphere index, and deals have array of location ids.
Now, I am getting locations in order of nearest to farthest from a specified point.
db.locations.aggregate([ { "$geoNear": { near: { coordinates: [73, 18]}, maxDistance: 1, distanceField : "distance", spherical: true } } ])
The real problem I'm facing is to get the deals in the order of locations that I've retrived.
Is there a way by which I can get deals based on the order of location ids given ?

how to get the distance or radian between two point on the earth with lng and lat?

how to get the distance or radian between two point on the earth with lng and lat?
You probably don't want mapReduce in this case but actually the aggregation framework. Apart from the general first stage query you can run via $geoNear which is more efficient in your purpose.
db.places.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -88 , 30 ]
},
"distanceField": "dist"
}},
{ "$match": {
"loc": {
"$centerSphere": [ [ -88 , 30 ] , 0.1 ]
}
}}
])
Or frankly, because the initial $geoNear stage will "project" an additional field into the document containing the "distance" from the queried "point of origin", then you can just "filter" on that element in a subsequent stage:
db.places.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -88 , 30 ]
},
"distanceField": "dist"
}},
{ "$match": {
"dist": { "$lte": 0.1 }
}}
])
Since this is one option that can "produce/project" a value representing the distance in the result then that satisfies your first criteria. The "chaining" nature of the "aggregation framework" allows "additional filtering" or any other operation you need to perform after the filtering of the initial query.
So $geoWithin works just as well in the aggregation framework under a $match stage as it would in any standard query since it is not "dependant" on an "index" of geospatial origin to be present. It performs better in an initial query with one, but it does not need it.
Since your requirement is the "distance" from the point of origin, then the most logical thing to do is to perform an operation that will return such information. Such as this does.
Would love to include all of the relevant links in this response, but as a new responder then two links is all I am allowed for now.
One more relevant note:
The measurement of "distance" or "radius" in any operation is dependant on how your data is stored. If it is in a "legacy" or "key/pair or plain array" format then the value will be expressed in "radians", otherwise where the data is expressed in GeoJSON format on the "location" then the "distance data" is expressed in "meters" instead.
That is an important consideration given the libraries implemented by the MongoDB service and how this interacts with the data as you have it stored. There is of course documentation on this in the official resources should you care to look at that properly. And again, I cannot add those links at this time, unless this response sees some much needed love.
https://github.com/mongodb/mongo/blob/master/src/third_party/s2/s2latlng.cc#L37
GetDistance() return a S1Angle, S1Angle::radians() will return the radians.
This belong to s2-geometry-library(google code will close,i export it to my github. Java).

Putting random latitude and longitude in google maps geolocation?

I have latitude and longitude of some cities and I want to input it the geocoder randomly. Can anyone please tell me how do I do that. The values are both negative and float. for an instance mexico lat/long 23.634501,-102.552784
myLatlng = new google.maps.LatLng(1.352083,103.819836);
I want to put values randomly from a set of values in Latlng function. Thanks
You don't specify your programming language, so I'll answer language agnostic.
I'll assume you have a Point type that can take two double values, e.g.
class Point
{
double Latitude;
double Longitude;
}
and that you have a list or set of instances of Point representing the set of latitude/longitude pairs you want to select from.
List<Point> points;
Just generate a random integer between 0 and (set size -1). Use that random integer as an index into the list.
int index = Random(0, points.Length-1);
Point myRandomPoint = points[index];
Now use that Point in your call to Google
myLatlng = new google.maps.LatLng(myRandomPoint.Latitude, myRandomPoint.Longitude);

freebase get buildings and geolocation

I need to get all the buildings with "church" function that are far 100km from a specified point (lat, lng). I made in this way:
[{
"id": null,
"name": null,
"type": "/architecture/building",
"building_function" : [{"name" : 'church'}],
"/location/location/geolocation" : {"latitude" : 45.1603653, "longitude" : 10.7976976}
"/location/location/area" : 100
}]​
but I alway get an empty response
code: "/api/status/ok"
result: []
status: "200 OK"
transaction_id: "cache;cache03.p01.sjc1:8101;2011-04-16T12:32:45Z;0035"
What am I missing?
Thanks
An area isn't a distance and you probably don't want an exact match to the value "100" anyway. You've asked for things which are precisely at that long/lat and have exactly that area.
Are you looking for churches which are less than a certain distance, more than a certain distance, or exactly the given distance? You probably want to look at the Geosearch API http://api.freebase.com/api/service/geosearch?help (although it's not a long term solution since it's been deprecated)
The /location/location/area property is used to query locations which cover a certain amount of area. So your query looks for buildings centered at (45.1603653, 10.7976976) which cover an area of 100km. Naturally there are no results that match.
Searching for topics within 100km of a those coordinates takes a little more work. You'll need to use the Geosearch service which is still in alpha. The following query should give you the results that you're looking for:
http://www.freebase.com/api/service/geosearch?location={%22type%22:%22Point%22,%22coordinates%22:[10.7976976,45.1603653]}&type=/architecture/building&within=100&indent=1
Once you have that list of buildings, you can query the MQL Read API to find out which ones are churches like this:
[{
"id": null,
"name": null,
"type": "/architecture/building",
"building_function" : [{"name" : 'church'}],
"filter:id|=":[
"/en/verona_arena",
"/en/basilica_palladiana",
"/en/teatro_olimpico",
"/en/palazzo_del_te",
"/en/villa_capra_la_rotonda",
"/en/villa_badoer",
"/en/san_petronio_basilica",
"/en/palazzo_schifanoia",
"/en/palazzo_chiericati",
"/en/basilica_di_santandrea_di_mantova",
"/en/basilica_of_san_domenico",
"/en/castello_estense",
"/en/palazzo_dei_diamanti",
"/en/villa_verdi",
"/en/cathedral_of_cremona",
"/en/monte_berico",
"/en/villa_pojana",
"/en/san_sebastiano",
"/en/cremona_baptistery",
"/en/palazzo_della_pilotta"
]
}]​
Right now its only matching 2 results so you'll probably need to edit some of those topics to mark them as churches.

Resources