My app crashes when trying to get a String containing special characters - objective-c
when i try to display a String, my application crashes:
NSLog(#"The start point is: %#",startPt);
This is the startPt value: 39-49%20Avenue%20d'Ivry,%2075013%20Paris,%20France. Actually it's returned from the Google Maps web service.
Sometimes, the application didn't crashes, but i got something weird in the Log:
The start point is: text/javascript
Why i am not able to assign the String 39-49%20Avenue%20d'Ivry,%2075013%20Paris,%20France to a NSString variable?
EDIT:
Here is the JSON response parsing:
NSString *responseString=[request responseString];
NSDictionary *responseDict=[responseString JSONValue];
NSArray *resultsArray = [responseDict objectForKey:#"results"];
location=[[resultsArray valueForKey:#"formatted_address"] objectAtIndex:0];
location=[location stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSLog(#"The location is : %#",location);//39-49%20Avenue%20d'Ivry,%2075013%20Paris,%20France
And this is the JSON response returned from the Google maps API:
{
"results" : [
{
"address_components" : [
{
"long_name" : "39-49",
"short_name" : "39-49",
"types" : [ "street_number" ]
},
{
"long_name" : "Avenue d'Ivry",
"short_name" : "Avenue d'Ivry",
"types" : [ "route" ]
},
{
"long_name" : "Quartier de la Gare",
"short_name" : "Quartier de la Gare",
"types" : [ "neighborhood", "political" ]
},
{
"long_name" : "13th arrondissement of Paris",
"short_name" : "13th arrondissement of Paris",
"types" : [ "sublocality", "political" ]
},
{
"long_name" : "Paris",
"short_name" : "Paris",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Paris",
"short_name" : "75",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Île-de-France",
"short_name" : "IdF",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "France",
"short_name" : "FR",
"types" : [ "country", "political" ]
},
{
"long_name" : "75013",
"short_name" : "75013",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "39-49 Avenue d'Ivry, 75013 Paris, France",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 48.82332110,
"lng" : 2.36638740
},
"southwest" : {
"lat" : 48.82296810,
"lng" : 2.36571090
}
},
"location" : {
"lat" : 48.82313960,
"lng" : 2.36602210
},
"location_type" : "RANGE_INTERPOLATED",
"viewport" : {
"northeast" : {
"lat" : 48.82449358029150,
"lng" : 2.367398130291502
},
"southwest" : {
"lat" : 48.82179561970850,
"lng" : 2.364700169708498
}
}
},
"types" : [ "street_address" ]
},
{
"address_components" : [
{
"long_name" : "Quartier de la Gare",
"short_name" : "Quartier de la Gare",
"types" : [ "neighborhood", "political" ]
},
{
"long_name" : "13th arrondissement of Paris",
"short_name" : "13th arrondissement of Paris",
"types" : [ "sublocality", "political" ]
},
{
"long_name" : "Paris",
"short_name" : "Paris",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Paris",
"short_name" : "75",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Île-de-France",
"short_name" : "IdF",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "France",
"short_name" : "FR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Quartier de la Gare, Paris, France",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 48.83810700000001,
"lng" : 2.3869610
},
"southwest" : {
"lat" : 48.8189240,
"lng" : 2.3556050
}
},
"location" : {
"lat" : 48.82807520,
"lng" : 2.36740680
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 48.83810700000001,
"lng" : 2.3869610
},
"southwest" : {
"lat" : 48.8189240,
"lng" : 2.3556050
}
}
},
"types" : [ "neighborhood", "political" ]
},
{
"address_components" : [
{
"long_name" : "13th arrondissement of Paris",
"short_name" : "13th arrondissement of Paris",
"types" : [ "sublocality", "political" ]
},
{
"long_name" : "Paris",
"short_name" : "Paris",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Paris",
"short_name" : "75",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Île-de-France",
"short_name" : "IdF",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "France",
"short_name" : "FR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "13th arrondissement of Paris, Paris, France",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 48.84496499999999,
"lng" : 2.3900530
},
"southwest" : {
"lat" : 48.8155730,
"lng" : 2.3411080
}
},
"location" : {
"lat" : 48.83222220,
"lng" : 2.35555560
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 48.84496499999999,
"lng" : 2.3900530
},
"southwest" : {
"lat" : 48.8155730,
"lng" : 2.3411080
}
}
},
"types" : [ "sublocality", "political" ]
},
{
"address_components" : [
{
"long_name" : "75013",
"short_name" : "75013",
"types" : [ "postal_code" ]
},
{
"long_name" : "Paris",
"short_name" : "Paris",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Paris",
"short_name" : "75",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Île-de-France",
"short_name" : "IdF",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "France",
"short_name" : "FR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "75013 Paris, France",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 48.84493089999999,
"lng" : 2.39026440
},
"southwest" : {
"lat" : 48.81587960,
"lng" : 2.34112720
}
},
"location" : {
"lat" : 48.8307590,
"lng" : 2.3592040
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 48.84493089999999,
"lng" : 2.39026440
},
"southwest" : {
"lat" : 48.81587960,
"lng" : 2.34112720
}
}
},
"types" : [ "postal_code" ]
},
{
"address_components" : [
{
"long_name" : "Paris",
"short_name" : "Paris",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Paris",
"short_name" : "75",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Île-de-France",
"short_name" : "IdF",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "France",
"short_name" : "FR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Paris, France",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 48.9021450,
"lng" : 2.46992090
},
"southwest" : {
"lat" : 48.8155730,
"lng" : 2.2241990
}
},
"location" : {
"lat" : 48.8566140,
"lng" : 2.35222190
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 48.9021450,
"lng" : 2.46992090
},
"southwest" : {
"lat" : 48.8155730,
"lng" : 2.2241990
}
}
},
"types" : [ "locality", "political" ]
},
{
"address_components" : [
{
"long_name" : "Paris",
"short_name" : "75",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Île-de-France",
"short_name" : "IdF",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "France",
"short_name" : "FR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Paris, France",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 48.9021450,
"lng" : 2.46992090
},
"southwest" : {
"lat" : 48.8155730,
"lng" : 2.2241990
}
},
"location" : {
"lat" : 48.87633370,
"lng" : 2.34612070
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 48.9021450,
"lng" : 2.46992090
},
"southwest" : {
"lat" : 48.8155730,
"lng" : 2.2241990
}
}
},
"types" : [ "administrative_area_level_2", "political" ]
},
{
"address_components" : [
{
"long_name" : "Île-de-France",
"short_name" : "IdF",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "France",
"short_name" : "FR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Île-de-France, France",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 49.2415040,
"lng" : 3.5590070
},
"southwest" : {
"lat" : 48.1200810,
"lng" : 1.446170
}
},
"location" : {
"lat" : 48.84991980,
"lng" : 2.63704110
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 49.2415040,
"lng" : 3.5590070
},
"southwest" : {
"lat" : 48.1200810,
"lng" : 1.446170
}
}
},
"types" : [ "administrative_area_level_1", "political" ]
},
{
"address_components" : [
{
"long_name" : "France",
"short_name" : "FR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "France",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 51.08896180,
"lng" : 9.559956999999999
},
"southwest" : {
"lat" : 41.34232760,
"lng" : -5.1412280
}
},
"location" : {
"lat" : 46.2276380,
"lng" : 2.2137490
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 51.08896180,
"lng" : 9.559956999999999
},
"southwest" : {
"lat" : 41.34232760,
"lng" : -5.1412280
}
}
},
"types" : [ "country", "political" ]
}
],
"status" : "OK"
}
I can think of two possibilities :
(1) Why do you assume the string is ASCII? Try a different encoding :
location = [location stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
Perhaps Google are using a unicode ' instead of one within the ASCII set? And if you're looking at address data then you can be fairly sure that odd characters are going to get put in there!
and (2) (this one is more unlikely given you have posted the JSON in your question but worth thinking about)
When you first get location you aren't checking that it's actually a string (you aren't checking that 'formatted_address' is an array either!)
What if the JSON returned was this (say there is a bug in the server?) :
{
...
"formatted_address" : [ { } ]
...
}
Here, [[resultsArray valueForKey:#"formatted_address"] objectAtIndex:0]; would work, but it wouldn't return an NSString.
Try adding in this kind of check :
location=[[resultsArray valueForKey:#"formatted_address"] objectAtIndex:0];
if (NO == [location isKindOfClass:[NSString class]]) {
NSLog(#"Location wasn't a string (%#) : %#", [location class], location);
} else {
location=[location stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSLog(#"The location is : %#",location);//39-49%20Avenue%20d'Ivry,%2075013%20Paris,%20France
}
My guess is that startPt isn't an NSString, but rather a char*. If that's the case, the simplest way to create an NSString from it is with [NSString stringWithFormat:#"%s", startPt].
Related
geocoding google maps api return different place_id
Geocoding: http://maps.googleapis.com/maps/api/geocode/json?address=%D0%A0%D0%BE%D1%81%D1%81%D0%B8%D1%8F%2C+%D0%B3%D0%BE%D1%80%D0%BE%D0%B4+%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0%2C+%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0%2C+%D0%9B%D1%83%D0%B1%D1%8F%D0%BD%D1%81%D0%BA%D0%B8%D0%B9+%D0%BF%D1%80%D0%BE%D0%B5%D0%B7%D0%B4+3&sensor=false Return { "results" : [ { "address_components" : [ { "long_name" : "3", "short_name" : "3", "types" : [ "street_number" ] }, { "long_name" : "Lubyanskiy proyezd", "short_name" : "Lubyanskiy pr-d", "types" : [ "route" ] }, { "long_name" : "Tsentralnyy administrativnyy okrug", "short_name" : "Tsentralnyy administrativnyy okrug", "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "long_name" : "Moskva", "short_name" : "Moskva", "types" : [ "locality", "political" ] }, { "long_name" : "gorod Moskva", "short_name" : "g. Moskva", "types" : [ "administrative_area_level_2", "political" ] }, { "long_name" : "Moscow", "short_name" : "Moscow", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "Russia", "short_name" : "RU", "types" : [ "country", "political" ] }, { "long_name" : "101000", "short_name" : "101000", "types" : [ "postal_code" ] } ], "formatted_address" : "Lubyanskiy proyezd, 3, Moskva, Russia, 101000", "geometry" : { "bounds" : { "northeast" : { "lat" : 55.7587676, "lng" : 37.6290579 }, "southwest" : { "lat" : 55.7587612, "lng" : 37.6290433 } }, "location" : { "lat" : 55.7587676, "lng" : 37.6290579 }, "location_type" : "RANGE_INTERPOLATED", "viewport" : { "northeast" : { "lat" : 55.76011338029149, "lng" : 37.6303995802915 }, "southwest" : { "lat" : 55.75741541970849, "lng" : 37.6277016197085 } } }, "place_id" : "EkbQm9GD0LHRj9C90YHQutC40Lkg0L_RgNC-0LXQt9C0LCAzLCDQnNC-0YHQutCy0LAsINCg0L7RgdGB0LjRjywgMTAxMDAw", "types" : [ "street_address" ] }, { "address_components" : [ { "long_name" : "3", "short_name" : "3", "types" : [ "street_number" ] }, { "long_name" : "Lubyanskiy proyezd", "short_name" : "Lubyanskiy pr-d", "types" : [ "route" ] }, { "long_name" : "Tsentralnyy administrativnyy okrug", "short_name" : "Tsentralnyy administrativnyy okrug", "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "long_name" : "Moskva", "short_name" : "Moskva", "types" : [ "locality", "political" ] }, { "long_name" : "gorod Moskva", "short_name" : "g. Moskva", "types" : [ "administrative_area_level_2", "political" ] }, { "long_name" : "Moscow", "short_name" : "Moscow", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "Russia", "short_name" : "RU", "types" : [ "country", "political" ] }, { "long_name" : "109074", "short_name" : "109074", "types" : [ "postal_code" ] } ], "formatted_address" : "Lubyanskiy proyezd, 3, Moskva, Russia, 109074", "geometry" : { "bounds" : { "northeast" : { "lat" : 55.7539059, "lng" : 37.6355031 }, "southwest" : { "lat" : 55.7538962, "lng" : 37.6354968 } }, "location" : { "lat" : 55.7539059, "lng" : 37.6354968 }, "location_type" : "RANGE_INTERPOLATED", "viewport" : { "northeast" : { "lat" : 55.7552500302915, "lng" : 37.6368489302915 }, "southwest" : { "lat" : 55.7525520697085, "lng" : 37.6341509697085 } } }, "partial_match" : true, "place_id" : "EkbQm9GD0LHRj9C90YHQutC40Lkg0L_RgNC-0LXQt9C0LCAzLCDQnNC-0YHQutCy0LAsINCg0L7RgdGB0LjRjywgMTA5MDc0", "types" : [ "street_address" ] } ], "status" : "OK" } But I get incorrect result, when I try find place info by place_id from previos results. For example: Find place by place_id https://maps.googleapis.com/maps/api/place/details/json?placeid=EkbQm9GD0LHRj9C90YHQutC40Lkg0L_RgNC-0LXQt9C0LCAzLCDQnNC-0YHQutCy0LAsINCg0L7RgdGB0LjRjywgMTAxMDAw&key=YOUR_GOOGLE_GEO_API_KEY Result: > { "html_attributions" : [], "result" : { > "address_components" : [ > { > "long_name" : "3", > "short_name" : "3", > "types" : [ "street_number" ] > }, > { > "long_name" : "Lubyanskiy proyezd", > "short_name" : "Lubyanskiy pr-d", > "types" : [ "route" ] > }, > { > "long_name" : "Tsentralnyy administrativnyy okrug", > "short_name" : "Tsentralnyy administrativnyy okrug", > "types" : [ "sublocality_level_1", "sublocality", "political" ] > }, > { > "long_name" : "Moskva", > "short_name" : "Moskva", > "types" : [ "locality", "political" ] > }, > { > "long_name" : "gorod Moskva", > "short_name" : "g. Moskva", > "types" : [ "administrative_area_level_2", "political" ] > }, > { > "long_name" : "Moscow", > "short_name" : "Moscow", > "types" : [ "administrative_area_level_1", "political" ] > }, > { > "long_name" : "Russia", > "short_name" : "RU", > "types" : [ "country", "political" ] > }, > { > "long_name" : "101000", > "short_name" : "101000", > "types" : [ "postal_code" ] > } > ], > "adr_address" : "\u003cspan class=\"street-address\"\u003eLubyanskiy proyezd, 3\u003c/span\u003e, > \u003cspan class=\"locality\"\u003eMoskva\u003c/span\u003e, \u003cspan > class=\"country-name\"\u003eRussia\u003c/span\u003e, \u003cspan > class=\"postal-code\"\u003e101000\u003c/span\u003e", > "formatted_address" : "Lubyanskiy proyezd, 3, Moskva, Russia, 101000", > "geometry" : { > "location" : { > "lat" : 55.7587676, > "lng" : 37.6290579 > } > }, > "icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png", > "id" : "38efff77618f372a66fe6aaadde36e46a8d9b0a8", > "name" : "Lubyanskiy pr-d, 3", > "place_id" : "Ej_Qm9GD0LHRj9C90YHQutC40Lkg0L_RgC4sIDMsINCc0L7RgdC60LLQsCwg0KDQvtGB0YHQuNGPLCAxMDEwMDA", > "reference" : "CpQBiwAAAA6ClEFYu1E3xM-8kRNGEf0s6sLJTMfqfroDVdaujzEMomzMTJ7HB80Bb8X5JLNrChwXlcFyKs4Hxn1vwgBm4LBfyCgMLty6WewWGKg7MbJb7ZDBhK0kQMRTcbnPGQ7hAG5MNo9t8LIMfDu0kZmsoCosW1MDEHbiXIHC9uygPYplHN6VzNP71rjh8V0AbiaZ9BIQohpY3YsUs0bWEwDUr74NqRoUttzPvs4Mlv_1nLCiPb_yHz5hW5M", > "scope" : "GOOGLE", > "types" : [ "street_address" ], > "url" : "https://maps.google.com/maps/place?q=Lubyanskiy+proyezd,+3,+Moskva,+Russia,+101000&ftid=0x46b54a5c1e406657:0xd25bbb02ec771347", > "vicinity" : "Tsentralnyy administrativnyy okrug" }, "status" : "OK" } How can you see, the place_id is different in request and response. In request (last link): EkbQ......AxMDAw In response: Ej_Qm9.....MDEwMDA EkbQ......AxMDAw != Ej_Qm9.....MDEwMDA The same place have two different place_id. How can I solve this problemm? I need help!
The place_id is not unique. The place is unique. There is nothing in the documentation that says there is a one-to-one mapping of place to place_id, only from place_id to place. In fact the documentation specifically states that a place can have multiple place IDs. From the documentation Note: Place IDs are also available through the Places API. A single place ID refers to only one place, but a place can have multiple place IDs. For more information, see the place ID overview.
To answer your question, there is no problem to solve. As #geocodezip says, a single location may have multiple place ID's. Both of your place IDs are valid and stable and you can use either. There are more details here: https://developers.google.com/places/place-id#multiple-ids When you request place details for a specific place ID, you receive the details for the requested place. Note however that the place ID may be different, if the place has received a new ID since your previous request. You can safely continue to use the original place ID to access the place, but it's recommended that you swap to using the most recently-returned place ID whenever possible.
How to draw Google map neighborhood boundaries?
I want to draw Google defined neighborhood boundaries over JavaScript V3 Map Api. I have found it but couldn't get a better solution for this. If you explorer Google map and search for any location Google highlights the boundary in "Red" color. So I want the same but to draw a poly lines.
The closest I can think of is using google geocoding and get a bounding box from it. For example, if you query http://maps.googleapis.com/maps/api/geocode/json?address=southwark , the google geocode gives the following, { "results" : [ { "address_components" : [ { "long_name" : "Southwark", "short_name" : "Southwark", "types" : [ "locality", "political" ] }, { "long_name" : "Greater London", "short_name" : "Gt Lon", "types" : [ "administrative_area_level_2", "political" ] }, { "long_name" : "United Kingdom", "short_name" : "GB", "types" : [ "country", "political" ] }, { "long_name" : "SE1", "short_name" : "SE1", "types" : [ "postal_code_prefix", "postal_code" ] }, { "long_name" : "London", "short_name" : "London", "types" : [ "postal_town" ] } ], "formatted_address" : "Southwark, London, Greater London SE1, UK", "geometry" : { "location" : { "lat" : 51.502781, "lng" : -0.087738 }, "location_type" : "APPROXIMATE", "viewport" : { "northeast" : { "lat" : 51.50972609999999, "lng" : -0.07173059999999999 }, "southwest" : { "lat" : 51.4958349, "lng" : -0.1037454 } } }, "types" : [ "locality", "political" ] } ], "status" : "OK" } Here you can use the "geometry" object to get a bounding box for the result.
Trying to parse a Json with Open Refine GREL
I'm trying to parse this JSON but really can't find the way to extract the data I want. { "results" : [ { "address_components" : [ { "long_name" : "44", "short_name" : "44", "types" : [ "street_number" ] }, { "long_name" : "Rue Montaigne", "short_name" : "Rue Montaigne", "types" : [ "route" ] }, { "long_name" : "Agen", "short_name" : "Agen", "types" : [ "locality", "political" ] }, { "long_name" : "Lot-et-Garonne", "short_name" : "Lot-et-Garonne", "types" : [ "administrative_area_level_2", "political" ] }, { "long_name" : "Aquitaine", "short_name" : "Aquitaine", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "France", "short_name" : "FR", "types" : [ "country", "political" ] }, { "long_name" : "47000", "short_name" : "47000", "types" : [ "postal_code" ] } ], "formatted_address" : "44 Rue Montaigne, 47000 Agen, France", "geometry" : { "bounds" : { "northeast" : { "lat" : 44.1994907, "lng" : 0.6172573 }, "southwest" : { "lat" : 44.19949039999999, "lng" : 0.6172388999999999 } }, "location" : { "lat" : 44.19949039999999, "lng" : 0.6172573 }, "location_type" : "RANGE_INTERPOLATED", "viewport" : { "northeast" : { "lat" : 44.20083953029149, "lng" : 0.618597080291502 }, "southwest" : { "lat" : 44.1981415697085, "lng" : 0.6158991197084979 } } }, "partial_match" : true, "types" : [ "street_address" ] } ], "status" : "OK" } I'm trying to isolate the lat and the lng from the point I geolocalized with Google Refine GREL ("location" : { "lat" : 44.19949039999999, "lng" : 0.6172573 }). Can you give me a hint of what I should do to succeed?
Try this: with(value.parseJson().results[0].geometry.location, pair, pair.lat +", " + pair.lng)
Looking for a good and free reverse geocoding API [closed]
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers. We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations. Closed 8 years ago. Improve this question I am familiar with two reverse geocoding APIs - Google Maps and foursquare. Both have problems. Consider lat,lng = 35.699,139.707 (Tokyo). Foursquare: GET https://api.foursquare.com/v2/venues/search?ll=35.699,139.707&oauth_token=5TJR4WQZSOW0ZWTE4ENMXKO3Y415252GITEMRPQIVPMEGCYK&v=20120723&limit=1 yields the following result: { "meta": { "code": 200 }, "notifications": [ { "type": "notificationTray", "item": { "unreadCount": 0 } } ], "response": { "venues": [ { "id": "4b64ebedf964a520e3d92ae3", "name": "まいどおおきに食堂 東新宿食堂", "contact": { "phone": "0352911870", "formattedPhone": "03-5291-1870" }, "location": { "address": "大久保1-1-45", "crossStreet": "新宿セントラルハイツプラザ 1F", "lat": 35.698492646211, "lng": 139.707271456718, "distance": 61, "postalCode": "169-0072", "city": "新宿区", "state": "東京都", "country": "Japan", "cc": "JP" }, "categories": [ { "id": "4bf58dd8d48988d111941735", "name": "Restaurant japonais", "pluralName": "Restaurants japonais", "shortName": "Japonaise", "icon": { "prefix": "https://foursquare.com/img/categories_v2/food/japanese_", "suffix": ".png" }, "primary": true } ], "verified": false, "stats": { "checkinsCount": 191, "usersCount": 100, "tipCount": 1 }, "url": "http://www.shokudo.jp/", "likes": { "count": 0, "groups": [] }, "specials": { "count": 0, "items": [] }, "hereNow": { "count": 0, "groups": [] } } ] } } I am only interested in the response.venues[0].location.city entry. Unfortunately, I do not know Japanese, so I cannot tell what it is. Well, google says it is Shinjuku - one of the special wards of Tokyo. Google Maps: GET http://maps.googleapis.com/maps/api/geocode/json?sensor=false&language=en&latlng=35.699,139.707 yields: { "results" : [ { "address_components" : [ { "long_name" : "41", "short_name" : "41", "types" : [ "sublocality_level_4", "sublocality", "political" ] }, { "long_name" : "1", "short_name" : "1", "types" : [ "sublocality_level_3", "sublocality", "political" ] }, { "long_name" : "1丁目", "short_name" : "1丁目", "types" : [ "sublocality_level_2", "sublocality", "political" ] }, { "long_name" : "Okubo", "short_name" : "Okubo", "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "locality", "political" ] }, { "long_name" : "Tokyo", "short_name" : "Tokyo", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "Japan", "short_name" : "JP", "types" : [ "country", "political" ] } ], "formatted_address" : "Japan, Tokyo, Shinjuku, Okubo, 1丁目1−41", "geometry" : { "location" : { "lat" : 35.69893960, "lng" : 139.7069460 }, "location_type" : "APPROXIMATE", "viewport" : { "northeast" : { "lat" : 35.70028858029149, "lng" : 139.7082949802915 }, "southwest" : { "lat" : 35.69759061970850, "lng" : 139.7055970197085 } } }, "types" : [ "sublocality_level_4", "sublocality", "political" ] }, { "address_components" : [ { "long_name" : "169-8540", "short_name" : "169-8540", "types" : [ "postal_code" ] }, { "long_name" : "2", "short_name" : "2", "types" : [ "sublocality_level_3", "sublocality", "political" ] }, { "long_name" : "1丁目", "short_name" : "1丁目", "types" : [ "sublocality_level_2", "sublocality", "political" ] }, { "long_name" : "Okubo", "short_name" : "Okubo", "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "locality", "political" ] }, { "long_name" : "Tokyo", "short_name" : "Tokyo", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "Japan", "short_name" : "JP", "types" : [ "country", "political" ] } ], "formatted_address" : "1丁目-2 Okubo, Shinjuku, Tokyo 169-8540, Japan", "geometry" : { "location" : { "lat" : 35.69946460, "lng" : 139.70746810 }, "location_type" : "APPROXIMATE", "viewport" : { "northeast" : { "lat" : 35.70081358029149, "lng" : 139.7088170802915 }, "southwest" : { "lat" : 35.69811561970850, "lng" : 139.7061191197085 } } }, "types" : [ "postal_code" ] }, { "address_components" : [ { "long_name" : "1", "short_name" : "1", "types" : [ "sublocality_level_3", "sublocality", "political" ] }, { "long_name" : "1丁目", "short_name" : "1丁目", "types" : [ "sublocality_level_2", "sublocality", "political" ] }, { "long_name" : "Okubo", "short_name" : "Okubo", "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "locality", "political" ] }, { "long_name" : "Tokyo", "short_name" : "Tokyo", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "Japan", "short_name" : "JP", "types" : [ "country", "political" ] } ], "formatted_address" : "Japan, Tokyo, Shinjuku, Okubo, 1丁目1", "geometry" : { "bounds" : { "northeast" : { "lat" : 35.69984490, "lng" : 139.70749510 }, "southwest" : { "lat" : 35.69787060, "lng" : 139.70506090 } }, "location" : { "lat" : 35.69880630, "lng" : 139.70610160 }, "location_type" : "APPROXIMATE", "viewport" : { "northeast" : { "lat" : 35.70020673029150, "lng" : 139.7076269802915 }, "southwest" : { "lat" : 35.69750876970850, "lng" : 139.7049290197085 } } }, "types" : [ "sublocality_level_3", "sublocality", "political" ] }, { "address_components" : [ { "long_name" : "1丁目", "short_name" : "1丁目", "types" : [ "sublocality_level_2", "sublocality", "political" ] }, { "long_name" : "Okubo", "short_name" : "Okubo", "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "locality", "political" ] }, { "long_name" : "Tokyo", "short_name" : "Tokyo", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "Japan", "short_name" : "JP", "types" : [ "country", "political" ] } ], "formatted_address" : "Japan, Tokyo, Shinjuku, Okubo, 1丁目", "geometry" : { "bounds" : { "northeast" : { "lat" : 35.70128920, "lng" : 139.70796940 }, "southwest" : { "lat" : 35.69787060, "lng" : 139.7019760 } }, "location" : { "lat" : 35.69868950, "lng" : 139.70306310 }, "location_type" : "APPROXIMATE", "viewport" : { "northeast" : { "lat" : 35.70128920, "lng" : 139.70796940 }, "southwest" : { "lat" : 35.69787060, "lng" : 139.7019760 } } }, "types" : [ "sublocality_level_2", "sublocality", "political" ] }, { "address_components" : [ { "long_name" : "Okubo", "short_name" : "Okubo", "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "locality", "political" ] }, { "long_name" : "Tokyo", "short_name" : "Tokyo", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "Japan", "short_name" : "JP", "types" : [ "country", "political" ] } ], "formatted_address" : "Okubo, Shinjuku, Tokyo, Japan", "geometry" : { "bounds" : { "northeast" : { "lat" : 35.70956610, "lng" : 139.7091340 }, "southwest" : { "lat" : 35.69787310, "lng" : 139.70060080 } }, "location" : { "lat" : 35.70418340, "lng" : 139.70558750 }, "location_type" : "APPROXIMATE", "viewport" : { "northeast" : { "lat" : 35.70956610, "lng" : 139.7091340 }, "southwest" : { "lat" : 35.69787310, "lng" : 139.70060080 } } }, "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "address_components" : [ { "long_name" : "Higashishinjuku Station", "short_name" : "Higashishinjuku Station", "types" : [ "train_station", "transit_station", "establishment" ] }, { "long_name" : "27", "short_name" : "27", "types" : [ "sublocality_level_3", "sublocality", "political" ] }, { "long_name" : "7丁目", "short_name" : "7丁目", "types" : [ "sublocality_level_2", "sublocality", "political" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "locality", "political" ] }, { "long_name" : "Tokyo", "short_name" : "Tokyo", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "Japan", "short_name" : "JP", "types" : [ "country", "political" ] } ], "formatted_address" : "Higashishinjuku Station, 7丁目-27 Shinjuku, Tokyo, Japan", "geometry" : { "bounds" : { "northeast" : { "lat" : 35.7050830, "lng" : 139.7144590 }, "southwest" : { "lat" : 35.6926030, "lng" : 139.7000410 } }, "location" : { "lat" : 35.697920, "lng" : 139.7075490 }, "location_type" : "APPROXIMATE", "viewport" : { "northeast" : { "lat" : 35.7050830, "lng" : 139.7144590 }, "southwest" : { "lat" : 35.6926030, "lng" : 139.7000410 } } }, "types" : [ "train_station", "transit_station", "establishment" ] }, { "address_components" : [ { "long_name" : "169-0072", "short_name" : "169-0072", "types" : [ "postal_code" ] }, { "long_name" : "Okubo", "short_name" : "Okubo", "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "locality", "political" ] }, { "long_name" : "Tokyo", "short_name" : "Tokyo", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "Japan", "short_name" : "JP", "types" : [ "country", "political" ] } ], "formatted_address" : "Okubo, Shinjuku, Tokyo 169-0072, Japan", "geometry" : { "bounds" : { "northeast" : { "lat" : 35.70972520, "lng" : 139.71028470 }, "southwest" : { "lat" : 35.69710930, "lng" : 139.69624280 } }, "location" : { "lat" : 35.70418340, "lng" : 139.70558750 }, "location_type" : "APPROXIMATE", "viewport" : { "northeast" : { "lat" : 35.70972520, "lng" : 139.71028470 }, "southwest" : { "lat" : 35.69710930, "lng" : 139.69624280 } } }, "types" : [ "postal_code" ] }, { "address_components" : [ { "long_name" : "Shinokubo Station", "short_name" : "Shinokubo Station", "types" : [ "train_station", "transit_station", "establishment" ] }, { "long_name" : "10", "short_name" : "10", "types" : [ "sublocality_level_3", "sublocality", "political" ] }, { "long_name" : "1丁目", "short_name" : "1丁目", "types" : [ "sublocality_level_2", "sublocality", "political" ] }, { "long_name" : "Hyakunincho", "short_name" : "Hyakunincho", "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "locality", "political" ] }, { "long_name" : "Tokyo", "short_name" : "Tokyo", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "Japan", "short_name" : "JP", "types" : [ "country", "political" ] } ], "formatted_address" : "Shinokubo Station, 1丁目-10 Hyakunincho, Shinjuku, Tokyo, Japan", "geometry" : { "bounds" : { "northeast" : { "lat" : 35.7078270, "lng" : 139.708840 }, "southwest" : { "lat" : 35.6953970, "lng" : 139.6937970 } }, "location" : { "lat" : 35.7013060, "lng" : 139.7000440 }, "location_type" : "APPROXIMATE", "viewport" : { "northeast" : { "lat" : 35.7078270, "lng" : 139.708840 }, "southwest" : { "lat" : 35.6953970, "lng" : 139.6937970 } } }, "types" : [ "train_station", "transit_station", "establishment" ] }, { "address_components" : [ { "long_name" : "Shinjuku Station", "short_name" : "Shinjuku Station", "types" : [ "train_station", "transit_station", "establishment" ] }, { "long_name" : "38", "short_name" : "38", "types" : [ "sublocality_level_3", "sublocality", "political" ] }, { "long_name" : "3丁目", "short_name" : "3丁目", "types" : [ "sublocality_level_2", "sublocality", "political" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "locality", "political" ] }, { "long_name" : "Tokyo", "short_name" : "Tokyo", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "Japan", "short_name" : "JP", "types" : [ "country", "political" ] } ], "formatted_address" : "Shinjuku Station, 3丁目-38 Shinjuku, Tokyo, Japan", "geometry" : { "bounds" : { "northeast" : { "lat" : 35.7005790, "lng" : 139.7124960 }, "southwest" : { "lat" : 35.6812220, "lng" : 139.6878250 } }, "location" : { "lat" : 35.6909210, "lng" : 139.7002580 }, "location_type" : "APPROXIMATE", "viewport" : { "northeast" : { "lat" : 35.7005790, "lng" : 139.7124960 }, "southwest" : { "lat" : 35.6812220, "lng" : 139.6878250 } } }, "types" : [ "train_station", "transit_station", "establishment" ] }, { "address_components" : [ { "long_name" : "160-0022", "short_name" : "160-0022", "types" : [ "postal_code" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "sublocality_level_1", "sublocality", "political" ] }, { "long_name" : "Shinjuku", "short_name" : "Shinjuku", "types" : [ "locality", "political" ] }, { "long_name" : "Tokyo", "short_name" : "Tokyo", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "Japan", "short_name" : "JP", "types" : [ "country", "political" ] } ], "formatted_address" : "Shinjuku, Tokyo 160-0022, Japan", "geometry" : { "bounds" : { "northeast" : { "lat" : 35.70311470, "lng" : 139.71922230 }, "southwest" : { "lat" : 35.68222330, "lng" : 139.69241360 } }, "location" : { "lat" : 35.69110170, "lng" : 139.7067630 }, "location_type" : "APPROXIMATE", "viewport" : { "northeast" : { "lat" : 35.70311470, "lng" : 139.71922230 }, "southwest" : { "lat" : 35.68222330, "lng" : 139.69241360 } } }, "types" : [ "postal_code" ] }, /* REMOVED FOR BREVITY */ ], "status" : "OK" } Google Maps API is in English, but its results are too low level. For instance, cities and towns are normally identified with the locality type. Here the locality is Shinjuku, which is one of the special wards of Tokyo, but it is an implementation detail of the administration system of Tokyo. I want to get Tokyo as the city. Of course, I could search for the administrative_area_level_1 type token instead of the locality, knowing that Tokyo is actually one of the Japan prefectures. The foursquare API has the same problem, it reports the city as Shinjuku and the state as Tokyo, only both as in Japanese! Are there any simple high level reverse geocoding API which returns common sense results? I mean, no one outside Japan says "I am going to Shinjuku". People say "I am going to Tokyo". Thanks.
OpenStreeMap has a reverse lookup tool too: http://wiki.openstreetmap.org/wiki/Nominatim#Reverse_Geocoding_.2F_Address_lookup Example from link: Query: http://nominatim.openstreetmap.org/reverse?format=xml&lat=52.5487429714954&lon=-1.81602098644987&zoom=18&addressdetails=1 Result: <reversegeocode timestamp="Fri, 06 Nov 09 16:33:54 +0000" querystring="..."> <result place_id="1620612" osm_type="node" osm_id="452010817"> 135, Pilkington Avenue, Wylde Green, City of Birmingham, West Midlands (county), B72, United Kingdom </result> <addressparts> <house>135</house> <road>Pilkington Avenue</road> <village>Wylde Green</village> <town>Sutton Coldfield</town> <city>City of Birmingham</city> <county>West Midlands (county)</county> <postcode>B72</postcode> <country>United Kingdom</country> <country_code>gb</country_code> </addressparts> </reversegeocode>
The Yahoo Maps API may be able to help you out, because it offers the ability to set the precision.
Try GeocodeFarm. 250 free queries daily per IP based but the web service is free for unlimited and the cheap $25 gives you 25,000 queries daily (which is what I use for my apps). Results are easy to understand, thorough documentation, forward and reverse, etc.
You can try Bing Maps I don't know how accurate it is, but you can try it http://dev.virtualearth.net/services/v1/geocodeservice/geocodeservice.asmx/ReverseGeocode?latitude=[NUMBER]&longitude=[NUMBER]&key=[MAPS_KEY]&culture=%22en-us%22&format=json
What other pieces of my address can Google Maps take out like the city, state and country?
I'm using this gem called Geocoder that's part of Ruby on rails. You can choose which geocoding service to use and I chose Google Maps. Now it states in the Advanced Geocoding section that if I'm familiar with the geocoding service I can actually parse and get more data for my columns in my database such as, city, state, country, etc. My question is, where can I see the list of all the things Google can parse for me? I want to add to my database more info such as the province, prefecture, etc. Where do I look?
https://developers.google.com/maps/documentation/geocoding/ Check out some of the sample JSON/XML output on this page. As you can see, you can get street address, postal code, locality, city, country, region and any other available information. { "results" : [ { "address_components" : [ { "long_name" : "1600", "short_name" : "1600", "types" : [ "street_number" ] }, { "long_name" : "Amphitheatre Pkwy", "short_name" : "Amphitheatre Pkwy", "types" : [ "route" ] }, { "long_name" : "Mountain View", "short_name" : "Mountain View", "types" : [ "locality", "political" ] }, { "long_name" : "Santa Clara", "short_name" : "Santa Clara", "types" : [ "administrative_area_level_2", "political" ] }, { "long_name" : "California", "short_name" : "CA", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "United States", "short_name" : "US", "types" : [ "country", "political" ] }, { "long_name" : "94043", "short_name" : "94043", "types" : [ "postal_code" ] } ], "formatted_address" : "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA", "geometry" : { "location" : { "lat" : 37.42291810, "lng" : -122.08542120 }, "location_type" : "ROOFTOP", "viewport" : { "northeast" : { "lat" : 37.42426708029149, "lng" : -122.0840722197085 }, "southwest" : { "lat" : 37.42156911970850, "lng" : -122.0867701802915 } } }, "types" : [ "street_address" ] } ], "status" : "OK" }