I'm trying to get the distances between one source point and one or more destination points, I'm using the OSRM API to accomplish this. However, the distances being returned are way off.
Source coordinates:
-2.2314725 | 53.4832925
Destination
-2.2315072 | 53.483238
Performing the following request:
http://router.project-osrm.org/table/v1/driving/-2.2314725,53.4832925;-2.2315072,53.483238?sources=0
The distance between the two points should be around 41km, but the result doesn't match at all.
Am I missing something blatantly obvious?
Below is the output from the above request:
{
"durations": [
[
0,
1.3
]
],
"destinations": [
{
"hint": "DBhtiw0YbYteAAAASwAAAAwAAAARAAAAQMh8QZccSEFqRAFARVYzQF4AAABLAAAADAAAABEAAABqpgAAg_Pd_0MXMANP893_HRcwAwEAXxOHnFES",
"distance": 5.459720867300434,
"name": "",
"location": [
-2.231421,
53.483331
]
},
{
"hint": "DBhtiw0YbYtRAAAAWAAAAAwAAAARAAAA27FaQUMzakFqRAFARVYzQFEAAABYAAAADAAAABEAAABqpgAAnPPd_zcXMAMt893_5hYwAwEAXxOHnFES",
"distance": 11.644459328154321,
"name": "",
"location": [
-2.231396,
53.483319
]
}
],
"sources": [
{
"hint": "DBhtiw0YbYteAAAASwAAAAwAAAARAAAAQMh8QZccSEFqRAFARVYzQF4AAABLAAAADAAAABEAAABqpgAAg_Pd_0MXMANP893_HRcwAwEAXxOHnFES",
"distance": 5.459720867300434,
"name": "",
"location": [
-2.231421,
53.483331
]
}
],
"code": "Ok"
}
There are two issues:
You probably mixed latitude and longitude. -2.2314725, 53.4832925 is somewhere in the ocean whereas 53.4832925,-2.2314725 is in Manchester. Sorry, I was wrong. OSRM expects lon,lat.
The two locations are almost identical. They are only 7 meters apart.
Related
I have a database with about 6 million documents where each looks like the following:
{
"_id": ObjectId("5d2327409ac8bc0085f3e733"),
"type": "Feature",
"properties": {
"osm_id": "2956281",
"code": 1500,
"fclass": "building",
"name": null,
"type": "tower"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-0.0154288,
51.4539007
],
[
-0.0153606,
51.4540789
],
[
-0.0150739,
51.4540339
],
[
-0.0151478,
51.4538517
],
[
-0.0154288,
51.4539007
]
]
]
}
}
The values in the coordinates array are pairs of lat/longs, but they're in the wrong order for my requirements so I need to switch them. I have written a script in JavaScript which iterates through the array and switches them but it's very slow as it operates on one document at a time.
Is there any way to do this with a more traditional bulk update call, which presumably would be much faster?
I am GeoJSON unfortunately still a bloody beginner. Now I have to solve a problem and understand, unfortunately, no piece of systematics.
Can you please help me and explain how I can use MongoDB to evaluate GEO data for the following case.
We have three areas (for example, countries), these have a value (say base area) now I have a catchment area that covers all three countries in part. How do I get the percentage of each country?
Here is a graphic to visualize the problem:
It is needed here e.g. the areas of A (n), B (n) and C (n).
In the database (mongodb#3.2) I have corresponding document with GEO data. Example:
{
"type": "FeatureCollecton",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
13.6868862,
51.063946
],
[
13.6873401,
51.063999
],
[
13.6883277,
51.0640888
],
...
]
]
},
"properties": {
"name": "Land A",
"qkm": 65.866862
}
},
]
}, ...
I am trying to use Mapbox to calculate the duration between two locations however the examples here are incomplete (at least with my limited experience). I would like to connect to this API using server-side Java, however I can't even get a basic example working in javaScript, Python or simply in the address bar in my browser.
I can get an example working in my browser using this url and substituting in my API key:
https://api.mapbox.com/geocoding/v5/mapbox.places/Chester.json?country=us&access_token=pk.my-token-value
However I can't get a similar example working with the distance API. The best I can manage is something like this:
https://api.mapbox.com/distances/v1/driving/[13.41894,52.50055],[14.10293,52.50055]&access_token=pk.my-token-value.
But I have no idea how to format my coordinates as I can't find a single example.
Has anyone been able to get this working. Ideally in Java, but client-side JavaScript or a valid url would be a great start.
I should also add that I can't get the JavaScript or Python ones working as they rely on external librarys that aren't referenced anywhere in the documentation!.
Thanks in advance.
Looks like you can provide a list of 2 or more semi-colon separated coordinates:
https://api.mapbox.com/optimized-trips/v1/mapbox/driving/13.41894,52.50055;14.10293,52.50055?access_token=pk.your_token
returns:
{
"code":"Ok",
"waypoints":[
{"distance":9.0352511932471,"name":"","location":[13.418991,52.500625],"waypoint_index":0,"trips_index":0},
{"distance":91.0575241567836,"name":"Berliner Chaussee","location":[14.103096,52.499738],"waypoint_index":1,"trips_index":0}
],
"trips":
[
{"geometry":"}_m_Iu{{pA}ZuQ}Iad#}cAk^jr#etOdE_iGtTqoAxBkoGnOkiCjR_s#wJ_v#b#}aN|aBogRyVucBiEw_C~r#_eB`Fc`NtP_bAshBorHa#}dCkOe~AmPmrGlPlrGjOd~A`#|dCrhBnrHuP~aAaFb`N_s#~dBhEv_CxVtcBkbBbeRo#l`NzJ`z#mRpr#qOpjCwBpnGoT~lAeEdkGsr#jtOtp#dQ~UjTtDfZf]jS",
"legs":[
{"summary":"","weight":4198.3,"duration":3426.4,"steps":[],"distance":49487},
{"summary":"","weight":7577.8,"duration":3501.3,"steps":[],"distance":49479.7}
],
"weight_name":"routability",
"weight":11776.1,
"duration":6927.700000000001,
"distance":98966.7}
]
}
I don't know if this is better now, but I had to work through it right now and can give you this example
curl "https://api.mapbox.com/directions-matrix/v1/mapbox/driving/9.51416,54.47004;13.5096410,50.0716190;6.8614070,48.5206360;14.1304840,51.0856060?sources=0&access_token={token}"`
This will return the following json for driving durations. I made use of the sources attribute, which is my search lng/lat and all other points are places in my database.
{
"code": "Ok",
"durations": [
[0.0, 29407.9, 34504.7, 24163.5]
],
"destinations": [{
"distance": 131.946157371,
"name": "",
"location": [9.514914, 54.468939]
}, {
"distance": 34.636975593,
"name": "",
"location": [13.509868, 50.071344]
}, {
"distance": 295.206928933,
"name": "",
"location": [6.863566, 48.52287]
}, {
"distance": 1186.975749670,
"name": "",
"location": [14.115694, 51.080408]
}],
"sources": [{
"distance": 131.946157371,
"name": "",
"location": [9.514914, 54.468939]
}]
}
Adding the annotations=distance parameter to the url will return the distances instead of the durations if you need that.
{
"code": "Ok",
"distances": [
[0.0, 738127.3, 902547.6, 616060.8] // distances in meters
],
"destinations": [{ // destinations including the source
"distance": 131.946157371, // result 0
"name": "",
"location": [9.514914, 54.468939]
}, {
"distance": 34.636975593, // result 1
"name": "",
"location": [13.509868, 50.071344]
}, {
"distance": 295.206928933, // result 2
"name": "",
"location": [6.863566, 48.52287]
}, {
"distance": 1186.975749670, // result 3
"name": "",
"location": [14.115694, 51.080408]
}],
"sources": [{ // source where we start from
"distance": 131.946157371,
"name": "",
"location": [9.514914, 54.468939]
}]
}
I'm new to using SQL server Geo-spatial functionality and I seem to have a formatting problem when I'm trying convert text to polygon. I have all the county ploygons from the US Census and when I do a geojson validation check they are displaying correctly. I tried to take those values and create tsql polyons but for some reason they are not valid. Here is what I have:
select geography::STPolyFromText('POLYGON((-95.388 42.909, -95.388 43.255, -94.913 43.255, -94.913 42.909, -95.388 42.909))', 4326);
The above should be a county in Iowa. I have the following example from MS that is working:
select geography::STPolyFromText('POLYGON((-122.358 47.653, -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))', 4326);
Can anyone see what I'm doing wrong?
For reference here is the geojson for the Iowa county:
{ "type": "Feature", "properties": { "GEO_ID": "0500000US19041", "STATE": "19", "COUNTY": "041", "NAME": "Clay", "LSAD": "County", "CENSUSAREA": 567.238000 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -95.388182, 42.909897 ], [ -95.388078, 43.255221 ], [ -94.913723, 43.255054 ], [ -94.913890, 42.909700 ], [ -95.388182, 42.909897 ] ] ] } }
The documents in my mongodb collection look like this:
{
"_id" : ObjectId("5562d6831683523f449e7d85")
"geometry" : {
"type" : "Polygon",
"coordinates" :
[[
[-122.4,37.81],
[-132.9, 39.9],
[-122.28, 37.80],
[-124.18, 39.81]
]]
}}
I have a point (lat long pair), which I'll call x and y. I need to see if the coordinates of the document create a polygon such that these coordinates are inside that polygon.
So, of course I need to compute the line describing each edge of the polygon, etc., and then see if the coordinates of the point are within that. However, for now, let's just assume we want to query documents that have x and y within the maximum and minimum lat long values of the entire array.
Here is how I tried to query this:
db.<collection-name>.find(
{'geometry.coordinates':
{$elemMatch:
{
[{$gt:-122.1}, {$lt:-122.0 }], [{$gt: 37.89 },{$lt: 37.91}]
}
}
}
)
however, the result is: Unexpected token [. I tried to follow the example here.
How do I query an array like this, where there are conditions on each element of the array in the document? thanks.
What you seem to be trying to do by matching array elements is actually "Finding a Polygon that contains a Point", which is why I changed your question title.
To accomplish this you are better off using the geoSpatail features of MongoDB rather than trying to work out the bounds yourself. With valid GeoJSON data the query is quite simple using the $geoIntersects operator.
To demonstrate, I'll first set up a collection, with some Polygon data:
db.areas.insert([
{
"name": "San Jose",
"geometry": {
"type": "Polygon",
"coordinates": [[
[ -122.20916748046876, 37.13404537126446 ],
[ -122.20916748046876, 37.496652341233364 ],
[ -121.65710449218749, 37.496652341233364 ],
[ -121.65710449218749, 37.13404537126446 ],
[ -122.20916748046876, 37.13404537126446 ]
]]
}
},
{
"name": "San Franciso",
"geometry": {
"type": "Polygon",
"coordinates": [[
[ -122.73651123046874, 37.58811876638322 ],
[ -122.73651123046874, 37.89219554724437 ],
[ -122.28332519531249, 37.89219554724437 ],
[ -122.28332519531249, 37.58811876638322 ],
[ -122.73651123046874, 37.58811876638322 ]
]]
}
}
])
Then ( though not required for $geoIntersects specifically ) when working with geoSpatial data it is best to have an "index" defined. The one that makes sense for real GeoJSON locations is "2dsphere". The index is created on the field that contains the "root" of the GeoJSON data, which is in this case called "geometry":
db.areas.createIndex({ "geometry": "2dsphere" })
Then all you need to do is supply a .find() query. I'm using the coordinates for "San Francisco city" here:
db.areas.find({
"geometry": {
"$geoIntersects": {
"$geometry": {
"type": "Point",
"coordinates": [
-122.45361328124999,
37.76420119453823
]
}
}
}
})
Which of course returns the "Polyon" defining the "San Franciso" area since that "Point" lies within that object.
{
"name": "San Franciso",
"geometry": {
"type": "Polygon",
"coordinates": [[
[ -122.73651123046874, 37.58811876638322 ],
[ -122.73651123046874, 37.89219554724437 ],
[ -122.28332519531249, 37.89219554724437 ],
[ -122.28332519531249, 37.58811876638322 ],
[ -122.73651123046874, 37.58811876638322 ]
]]
}
}
That is all there is to finding whether your "Point" lies within a "Polygon" you have stored in your collection.
Also look at tools such as geojsonlint.com and geojson.io (examples, not endorsements) in order to validate and visualise your data, which from your example does not provide a well formed Polygon.