How to get geo coordinates of road? - google-maps

I'm trying to create a corridor along a road. Therefore I need some kind of a coordinate set. Currently I'm requesting a route and using it's coordinates. But with this approach I run into problems if there is a long segment, eg. 200km on a highway. If I only use the position of the instructions when getting onto the highway and when exiting it, the corridor may miss some parts of the road since it may not be a straight one.
So what I'd like to do is, query the "major" road coordinates of a road. For now it does not matter if id needs an ID or the road name or any coordinates.
I'm currently working with HERE maps, but if there is any other service which may fulfill my requirement, I'm open to review and test it. I also reviewed google-maps api, but still not found a service or any similar approach.
Thanks in advance.

If I understand your question correctly you need to obtain the full geometry of the route first, then prune the result down to the coordinates you want.
For both the HERE 7.2 routing API and the 6.2 Enterprise Routing API, If you want to obtain the shape of a route you just need to include the parameter routeattributes=shape.
e.g.
.../calculateroute.json?waypoint0=lat,lng&waypoint1=lat,lng&mode=fastest:car:traffic:Adefault&routeattributes=shape&app_id=YOR_APPID&app_code=YOUR_TOKEN
The full geometry (of routes or manuevers) is not usually returned without the shape enum being set.
This is explained in the API User guide as shown:
routeAttributes
Define which atrributes are included in the response as part of the data representation of the route. Defaults to waypoints, summary,summaryByCountry legs, lines. See also RouteAttributeType.
Enum [waypoints | summary | summaryByCountry | shape | boundingBox | legs | notes ]
The route shape example within the API explorer returns :
[
"52.5160414,13.3782982",
"52.5163436,13.3782148",
"52.5162363,13.3783329",
"52.5162148,13.3786547",
"52.5162792,13.3795774",
"52.5163651,13.3808541",
"52.5165153,13.3807898",
"52.516644,13.3807361",
"52.5169337,13.3806503",
"52.5181997,13.3804357",
"52.5189185,13.380264",
"52.5189829,13.3811975",
"52.5191653,13.3820879",
"52.5197446,13.3840835",
"52.5201201,13.3851671",
"52.5203025,13.3855319",
"52.52056,13.3859825",
"52.5206485,13.3861105"
], ... etc.
within the response.

Related

MapBox ESRI Data Layer

I have a mapbox, and want to display a layer of esri data onto it. The data I'm getting is being pulled in from this json file:
https://gis.usps.com/arcgis/rest/services/EDDM/selectZIP/GPServer/routes/execute?f=json&env%3AoutSR=102100&ZIP=93003&Rte_Box=R&UserName=EDDM
The data['results'][0]['value']['features'] array looks something like this:
[{'attributes': {'key':'value'}},{'geometry':{'paths':[[-13273770,4064608],[-13273762,4064613],....]}},
{'attributes': {'key':'value'}},{'geometry':{'paths':[[-13273770,4064608],[-13273762,4064613],....]}},
{'attributes': {'key':'value'}},{'geometry':{'paths':[[-13273770,4064608],[-13273762,4064613],....]}}}]
My question is about the geometry array. The data there is not Lat/Lng values (which I was hoping for), so I'm not sure how to add these to my map. I'm new to GIS, and the research I've done so far points to SpatialReferences. Any help is obviously much appreciated!
MapBox seems to only accept Latitude and Longitude coordinates (from what I can tell at least). The coordinates you have in your file come from ESRI 102100 (3857) projection system - the clue is near the beginning of your file:
"spatialReference":{"wkid":102100,"latestWkid":3857}..."
Normally, you'd have to convert this yourself, a good link for potential tips in the future is:
https://gis.stackexchange.com/questions/9442/arcgis-coordinate-system
On this occasion however, you can do something far easier. Simply change the "outSR" property of your URL from 102100 to 4326 (WGS84) and let it do it for you.
https://gis.usps.com/arcgis/rest/services/EDDM/selectZIP/GPServer/routes/execute?f=json&env%3AoutSR=4326&ZIP=93003&Rte_Box=R&UserName=EDDM

Draw line from start of road to end given it's latlng

I'd like to highlight all roads around a user in a certain radius.
I've worked out how to get the lat/lng of the roads and even their lengths, but I'm struggling to work out how to draw lines from the start of a road to the end of the same road given only the lat/lng of said road.
countryCode:"GB"
distance:195.450718073417
gid:101823433
isIn:"Portsmouth"
lat:50.79336325
length:58.7727976883358
lng:-1.0940351000000001
name:"Colpoy Street"
oneWay:false
openstreetmapId:12929127
streetType:"RESIDENTIAL"
http://services.gisgraphy.com/street/streetsearch?format=json&lat=50.7913547&lng=-1.0944082&radius=200&streettype=&distance=true
I've seen various solutions of "snapping" to roads, but this requires a start and end lat/lng, I only have the single lat/lng of the road location.
I'm not fussy about the use of mapping API, although I'd prefer to use Leaflet.js/OSM. Is this possible?
You will need a server component that replys your request with the geometry of your desired road. For prototyping, you might use the OverpassAPI and display a geoJSON answer of the desired object in a new Leaflet layer.
Just to clarify: You need to add a new vector layer, as you have to use a seperate datasource with the road network on top of your raster maps.

Get exact geo coordinates along an entire route, Google Maps or OpenStreetMap

Suppose I have a route defined from one town to another. From the Google Maps API I can recover a route between the two. However, the route returned from Google is a driving route that includes geo-coordinates only at places where there is another step in a leg (for example, where I have to turn from one highway to another).
What I need is geo-locations (lat/long) along the entire route, at specific intervals (for example, every 1/4 mile or 100m).
Is there a way to accomplish this via the Google Maps API / web services?
Or would the OpenStreetMap database be the way to do it?
Kind regards,
Madeleine.
OSRM gives you routes with road geometries as they are in the OpenStreetMap database. For example, you can get the route as GPX (and post-process this file if you want). This would look like the following:
GET http://router.project-osrm.org/viaroute?hl=en&loc=47.064970,15.458470&loc=47.071100,15.476760&output=gpx
Read more: OSRM API docs.
Since the accepted answer is outdated and does not work anymore, here is how all nodes along a road can be queried using the route service from Project OSRM.
Given an arbitrary number of lon,lat pairs.
For Instance the following three (in Berlin):
13.388860,52.517037
13.397634,52.529407
13.428555,52.523219
The route-service calculates the fastest route between these points and its possible to return all nodes along the road using the following query:
http://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.397634,52.529407;13.428555,52.523219?alternatives=false&annotations=nodes
This returns a json response containing node IDs of all the nodes along the route. The result should look something like this:
{
"routes": [
{
...
"legs": [
{
"annotation": {
"nodes": [
2264199819,
2045820592,
21487242,
...
]
}
To receive the lat,lon coordinates of the nodes OverpassAPI can be used.
[out:json];
(
node(264199819);
node(...);
node(...);
...
);
(._;>;);
out;
Here is a sample request using overpass-turbo: http://overpass-turbo.eu/s/toe
It's simply google.maps.DirectionsService().route() method. You need to pass the service request and then a callback which executes upon completion of the service request.
https://developers.google.com/maps/documentation/javascript/directions
While not used as API, here: https://www.nmeagen.org/ one can create "Multi-point line", set the distance between points and download route (coordinates) as CSV.
Adding to the Marlio's answer.
You can use Google Maps Directions API itself.
For a given origin and destination, in the JSON output, look for following:
"polyline" : {
"points" : ""
}
You can use a decoder to get the coordinates from the polyline.:
https://github.com/emcconville/google-map-polyline-encoding-tool
Or. you can use the googleway package in R to decode the same.
https://cran.r-project.org/web/packages/googleway/googleway.pdf
I am not sure how to set the resolution to your desired level though.But the resolution in the API output is really good.

Unable to use the table #2 types with Google Places API

I am unable to get any results with the Places API when I use a types=transit_station|neighborhood (or any other type included in the table 2 here: http://code.google.com/apis/maps/documentation/places/supported_types.html#table2
Apparently, this is not related to a specific location (I've tried both Milan, Italy and London, GB), so I'm wondering if I'm doing something wrong or if the API is not currently working as expected.
If the above has no solution, I'd be very happy if there was another way of finding the neighborhood of a building (for instance, in this map: http://g.co/maps/hfdke I'd like to be able to find "Fiera Campionaria", "Il Portello" etc).
What you are looking for are sublocality's, this can be confirmed through a Places Autocomplete API request:
Input "Fiera Campionaria" returns "Fiera Campionaria, Milano, Italia" with types "sublocality", "political", "geocode":
https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Fiera%20Campionaria&sensor=false&key=your_api_key
Input "Il Portello" returns "Il Portello, Milano, Italia" with types "sublocality", "political", "geocode":
https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Il%20Portello&sensor=false&key=your_api_key
Unfortunately a Places API Search request in this area with types specified as "sublocality|political|geocode" does not return these results:
https://maps.googleapis.com/maps/api/place/search/json?location=45.47536640,9.15523110&radius=3000&sensor=false&types=sublocality|political|geocode&key=your_api_key
I have reported this Internally as a bug.
Cheers
Chris
First of all:
Keep in mind that you only can find a place that has been created by somebody.
Also remember that the places-API is experimental.
I also didn't find any place of type neighborhood in Milan or London.
But I find them e.g. in Paris, New York, Washington, so you may test your application there.
What I realized while playing around with the API:
When I define the range to search for by location and radius the results often are very inaccurate.
For example I search for a neighborhood starting by a point in radius of 5km, it will find a neighborhood in 4km but not in 400m.
The results are much more exactly when I search within LatLngBounds

How do I implement a "find nearest" type functionality?

HI,
I was wondering if anyone had any ideas about how to implement functionality where given an array of locations ( for e.g. branches) it will list the nearest one or list all withing a 5 mile radius etc?
When you say "locations", what do you mean exactly? Street addresses? GPS coordinates?
If you have GPS coordinates (or can convert an address to coords), you can always calculate the Euclidean distance or the (more accurate) great-circle distance between two points. Caculate the distance between the current location and each potential destination, then sort the list by shortest distance.
You didn't mention if you were using the Google Maps API, but here's some additional info in case you are. You can store two points as objects of type GLatLng and use object1.distanceFrom(object2) to calculate this. You can also create a GLatLngBounds object representing a rectangular region on the map and use GLatLngBounds.containsLatLng(latlng:GLatLng) to see if a geographical point lies within that region.
Edit: What typically happens in the case you mention below is when a user enters a post code, the "current location" is taken to be the geographic center of that post code (you would probably have to get this info from the authority who assigns post codes in your area). If you are in the UK, this site has a free list of postcodes and their coordinates. Searching for a postal code in Google Maps will take you to the center of that postcode; if you need to build your own list of post codes and coordinates, you can probably create a script that will iterate through all valid post codes and use Google maps to look them up and turn them into GPS coordinates.
To turn an address into coordinates, you want to do what is called geocoding. Google Maps has an API for this, and there are other resources that can provide you this functionality. For some examples, try this page. What resource you use largely depends on where you are, as most of this information is localized. You didn't mention much about your project (platform, language, etc), but at the bottom of that page is a section called "Geocoding Helper Libraries" that may have the functionality you need rolled into a pre-built package. In particular the GeoKit library (Ruby language) has a handful of examples on the front page of their website, including several that look like they do exactly what you are wanting to do.
EDIT: I got the following code from the code generator at WebRPC:
/**
* Copyright WebRPC
* available under the GNU GENERAL PUBLIC LICENSE Version 2, June 1991
* http://www.gnu.org/licenses/gpl.txt
*/
public class Client
{
public static void Main(string[] args)
{
// make the call
XPathDocument doc = new XPathDocument(#"http://maps.google.com/maps/geo?q=New+York&output=xml&key=ABQIAAAAuXdMTY5VIU1FvkgOOP1dNBTsILMTMKRV-aJhd94IQkaJhVJ0YBS2qNSZGm8TaefqbXBT6lUXeMZ6tA");
// print the outputs
XPathNavigator nav = doc.CreateNavigator();
XPathNodeIterator coord = nav.Select( "/kml/Response/Placemark/Point/coordinates" );
while ( coord.MoveNext() )
System.Console.WriteLine( coord.Current );
XPathNodeIterator accuracy = nav.Select( "/kml/Response/Placemark/AddressDetails/#Accuracy" );
while ( accuracy.MoveNext() )
System.Console.WriteLine( accuracy.Current );
}
}
You should be able to modify this C# code to suit your needs. Specifically, in the call to new XPathDocument, change the part of the string that reads ?q=New+York to whatever address or postal code you need (for example, using ?q=1060+West+Addison%2C+Chicago%2C+IL will retrieve information for Wrigley Field in Chicago, or using ?q=LS11+0ES%2C+UK will get info for a postal code in Leeds). To format an address from a regular text string, change spaces to '+' and turn all other non-alphanumeric characters into their ASCII equivalent (such as '%2C' for a comma).
The next few lines retrieve the information from the server and parse it in various ways. Of interest here is the field /kml/Response/Placemark/Point/coordinates in the returned data. This string will contain your latitude and longitude coordinates for the location you specified above.
Now, this should give you enough information to create a C# function that is able to turn an address or post code into a pair of coordinates. The hard part is done, but two steps remain. First, you will want to use this to generate coordinates for each address in your database (store these in the database with the addresses for best results). Now, when a user enters an address, call your C# function again to generate a set of coordinates for her location. Now that you have coordinates for everything, you can find the distance between two coordinates by using one of the two distance-calculating functions I linked to at the top of the post. Run down your list of branches, calculate the distance from the user to each, and sort that list to find the branches with the shortest distance values.