I want to get a more accurate address (from coordinates) than the address range from the function
geoCoder.reverseGeocodeLocation(location, completionHandler: {} )
In the google maps API guide (https://developers.google.com/maps/documentation/geocoding/intro#Results) they specify that I can change location_type in order to get a more accurate address. How do I specify these parameters? This is my code:
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: center.latitude, longitude: center.longitude)
geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in ...
})
If you want to use the Google Maps API, as you linked, you need to be forming an HTTP request to the API (with an API Key you've acquired from Google). The reverseGeocodeLocation uses Apple's Map API, and is definitely not going to be able to accept Google's location_type parameter. The core HTTP request you're going to want to make is therefore of the form:
let url:String = "https://maps.googleapis.com/maps/api/geocode/json?latlng=\(center.latitude),\(center.longitude)&location_type=\(DESIRED_LOCATION_TYPE)&key=\(YOUR_API_KEY)"
From the link you specified, the DESIRED_LOCATION_TYPE can be one of:
"ROOFTOP" restricts the results to addresses for which we have
location information accurate down to street address precision.
"RANGE_INTERPOLATED" restricts the results to those that reflect an
approximation (usually on a road) interpolated between two precise
points (such as intersections). An interpolated range generally
indicates that rooftop geocodes are unavailable for a street address.
"GEOMETRIC_CENTER" restricts the results to geometric centers of a
location such as a polyline (for example, a street) or polygon
(region).
"APPROXIMATE" restricts the results to those that are
characterized as approximate.
Related
I am currently working on a project that involves calculating Duration matrices from a collection of thousands of addresses using NEO4J and Bing Maps API. Since the data is sensitive, we're going to use the mock address (which actually produces the same issue I'm describing) '72ND & DODGE, OMAHA, NE 68132' to represent the format intersection addresses are being sent to Bing Maps API using their keys and basic url requests.
To preface this: the issue isn't with my code (which is also sensitive data), as all my code is doing is sending one url string of the above format plus the authorization key to Bing Maps and awaiting a response that contains the duration data of the trip. My issue is Bing Maps being seemingly unable to handle or work with intersections of streets to calculate distances/durations from other locations. When I throw these addresses into Bing/Google Maps in the web browser, they are able to be found and calculated in the exact same format as the above example.
I start off my program checking if an address exists/is valid by having it find the latitude and longitude of each address, so for the example '72ND & DODGE, OMAHA, NE 68132' it found: Lat: '41.259690' and Long: '-96.023770'. If it is unable to find the Lat/Long of an addresses, then it throws the 'Invalid Geocode' error, but in this initialization context it means the address does not exist, or is poorly formatted, which makes sense and is why I did this for the initialization phase.
However, if I go to use '72ND & DODGE, OMAHA, NE 68132' for any duration calculations between other addresses, it throws the 'Invalid Geocode' for '72ND & DODGE, OMAHA, NE 68132' over and over again with no explanation on why even though it passed the Lat/Long check. I'd also like to mention that this issue isn't consistent, as some intersections do not work while others do, but there is no consistency in knowing which ones will or will not work. Thus, I am ultimately wondering if Bing Maps is unable to calculate certain addresses no matter their formatting or whatnot.
Be sure to encode your query before putting it into the URL. Especially when you have & in your query since it would then break your query up, thinking you were asking just for 72ND and the rest of your query is query string parameter name. This is documented in the best practices section here.
In Java you can encode the query parameter like this:
String baseURL = "https://dev.virtualearth.net/REST/v1/Locations?key={BingMapsKey}&query=";
// query string
String query = "72ND & DODGE, OMAHA, NE 68132";
// URL encode query string
String encodeStr = URLEncoder.encode(query, StandardCharsets.UTF_8.name());
// final url
String url = baseURL + encodeStr;
Here is an example of how your query URL should look:
https://dev.virtualearth.net/REST/v1/Locations?key={BingMapsKey}&query= 72ND%20%26%20DODGE%2C%20OMAHA%2C%20NE%2068132
What is the difference between OSRM route service and match service?
According to OSRM documentation, route and match are 2 endpoints with different objectives:
Route: It will return the fastest route between the coordinated in the supplied order. For example:
https://router.project-osrm.org/route/v1/driving/-77.0969009399414,38.89397221118197;-77.08866119384766,38.88154580068335;-77.0745849609375,38.88515369217454;-77.05432891845703,38.90586211685612?overview=false&alternatives=true&steps=true
A call to this endpoint will return the shortest path from lat: -77.0969009399414, lon: 38.89397221118197 to lat -77.08866119384766, lon: 38.88154580068335 and then to lat: -77.05432891845703, lon: 38.90586211685612
Match: This endpoint works in a complete different way. Given a GPS dataset, the match service will try to match those points to the road network in the most pausible way.
So, if you have few GPS points and want to get the best route to visit them, you will use the route service. If you have a lot of GPS points and want to re-construct the most probable followed path, you will use the match service
I am finding the latitude and longitude of a Address 4760 matric Drive, winter park, FL, 32792 and bing map giving lat long 28.604771, -81.292976. This same i am doing with my request from URL and the url is http://dev.virtualearth.net/REST/v1/Locations?countryRegion=USA&adminDistrict=FL&locality=&postalCode=32792&addressLine=4760%20matric%20Drive&key=Mykey&output=xml
This is response me the lat long
<Latitude>28.610404968261719</Latitude>
<Longitude>-81.2994155883789</Longitude>
Why the same address are different Lat Long from bing map. Please give me advice.
Trying both forms of the address in the REST services I'm getting the exact same result which is the second set of coordinates you provided. The reason for this is that the geocoder matched the postal code and not the road.
The Bing Maps website returns the first result you mentioned but the website is using a completely new geocoder that is currently being tested before being used on the backend of the developer API's.
Hi I am using mapquest api to show the distance from source to destination in app
Problem:
I am sending below request to mapquest to get the distance
{ "locations":[ "40.2336,-111.6475", "33.621227,-111.917229","30.688181,76.706238"],
"options":{ "allToAll":true, "unit":"k", "doReverseGeocode":false,"manyToOne":true } }
Now in this case distance can be calculated from first lat long to second lat long as both are US based address but distance cannot be calculated between first and third location as third one is Indian location .
Now the response I am getting is
{"route":{"routeError":{"message":"","errorCode":0}},"info":{"copyright":
{"text":"© 2015 MapQuest, Inc.","imageUrl":"http://api.mqcdn.com/res/mqlogo.gif",
"imageAltText":"© 2015 MapQuest, Inc."},"statuscode":400,
"messages":["We are unable to route with the given locations."]}}
Which I suppose is wrong as distance between first two places should be returned .
Please suggest what can be done for this ?
Currently the matrix fails if any of the legs fails. Making this return any successful legs is on the team's backlog.
The reason for the error is that your locations are invalid. I ran it with the exact POST body you had, and got error 402. Looking at the MapQuest Directions API Status Codes, this is an invalid location. This makes sense, considering the coordinates include two in the US and one in India. This, AFAIK, is only a driving API, hence why overseas locations are invalid.
Another point unrelated to the main problem: your request is semantically invalid. You specify both allToAll and manyToOne as true, which is invalid. The API will ignore your manyToOne as a result, so make sure you are requesting exactly what you want.
The documentation for
- (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;
The documentation clearly states:
In the case of forward-geocoding requests, multiple placemark objects
may be returned if the provided information yielded multiple possible
locations.
states that it returns an array of placemarks. However, even if I search for objects I know for certain have multiple entries (Hollywood, washington, Denmark, main street, ect.) i always only get one entry.
Some people just shrug and say use the google API instead, but i fear for the request limit.
Is there some setting or hack to fix this, or is the CLGeocoder simply broken ?
I would definitely suggest using Google Geocoding API - it is simply superior. I also argue, that you should not fear the usage limit for Google Geocoding APIs requests.
If you are developing mobile application, I suggest implementing client-side geocoding - that means, that every device queries directly Google API. As it is directly stated in Google's own documentation
geocoding limits are per user session, there is no risk that your application will reach a global limit as your userbase grows.
More info in geocoding strategies docs and geocoding docs.
MKLocalSearch is the answer here:
let request = MKLocalSearch.Request()
request.naturalLanguageQuery = "addressToBeSearched"
request.region = MKCoordinateRegion(center: span: )
let localSearch = MKLocalSearch(request: request)
localSearch.start { response, error in
// returns (MKLocalSearch.Response?, Error?) -> Void
// which ultimately has an array of MKMapItem from which you can extract a placemark.
}
This returns the nearby and not only, points of interest, places, etc.
The only drawback I can think of is that you have to provide the current location in the initializer for MKCoordinateRegion and the span.