Using the Google Place Details API to get the address through an place_id.
You can specify the language=en but for example a hotel in Phuket will still return the city and province in there local language.
This is a sample output of the Google Places API:
[result] => Array
(
[address_components] => Array
(
[0] => Array
(
[long_name] => ภูเก็ต
[short_name] => จ.ภูเก็ต
Long_name and short_name both contain the local version in their own script. My users would like to see the international version of that city name, like "Phuket"
Example place: Phuket Marriott Resort & Spa, Merlin Beach, Pa Tong, Kathu District, Phuket, Thailand
Why would Google not supply the English version? On their Google Maps they display the full address.
They give a full address in the API adr_address but you would have to parse that yourself quite unreliable.
You could also use Google Translate for a translation but would be unreliable as well.
I tested it, the result isn't in "address_components" , you will find the adress here :
"formatted_address" : "99 Muen-Ngoen Road Tri-Trang Beach, Patong Patong Phuket, ตำบลป่าตอง อำเภอกะทู้ ภูเก็ต 83150, Thailand"
The full JSON reuslt :
{
"html_attributions" : [],
"result" : {
"address_components" : [
{
"long_name" : "ภูเก็ต",
"short_name" : "จ.ภูเก็ต",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "ตำบลป่าตอง",
"short_name" : "ตำบลป่าตอง",
"types" : [ "locality", "political" ]
},
{
"long_name" : "อำเภอกะทู้",
"short_name" : "อำเภอกะทู้",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Thailand",
"short_name" : "TH",
"types" : [ "country", "political" ]
},
{
"long_name" : "83150",
"short_name" : "83150",
"types" : [ "postal_code" ]
}
],
"adr_address" : "99 Muen-Ngoen Road Tri-Trang Beach, Patong Patong Phuket, \u003cspan class=\"extended-address\"\u003eตำบลป่าตอง\u003c/span\u003e \u003cspan class=\"locality\"\u003eอำเภอกะทู้\u003c/span\u003e \u003cspan class=\"region\"\u003eภูเก็ต\u003c/span\u003e \u003cspan class=\"postal-code\"\u003e83150\u003c/span\u003e, \u003cspan class=\"country-name\"\u003eThailand\u003c/span\u003e",
"business_status" : "OPERATIONAL",
"formatted_address" : "99 Muen-Ngoen Road Tri-Trang Beach, Patong Patong Phuket, ตำบลป่าตอง อำเภอกะทู้ ภูเก็ต 83150, Thailand",
"formatted_phone_number" : "076 335 300",
"geometry" : {
"location" : {
"lat" : 7.883537999999999,
"lng" : 98.27270779999999
},
"viewport" : {
"northeast" : {
"lat" : 7.884994980291502,
"lng" : 98.27402173029151
},
"southwest" : {
"lat" : 7.882297019708498,
"lng" : 98.27132376970849
}
}
},
"icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/lodging-71.png",
"id" : "47f504a09fb6891f688957af609c39a4064b150e",
"international_phone_number" : "+66 76 335 300",
"name" : "Phuket Marriott Resort & Spa, Merlin Beach",
"opening_hours" : {
"open_now" : true,
"periods" : [
{
"open" : {
"day" : 0,
"time" : "0000"
}
}
],
"weekday_text" : [
"Monday: Open 24 hours",
"Tuesday: Open 24 hours",
"Wednesday: Open 24 hours",
"Thursday: Open 24 hours",
"Friday: Open 24 hours",
"Saturday: Open 24 hours",
"Sunday: Open 24 hours"
]
},
Related
I need to return any (at least one) valid address that exist around a zip code.
The country will always be the same.
How can I achieve this?
Thank you,
You can accomplish this through 2 requests, using the output of the first as input for the second. There are a few caveats outlined at the end.
Request 1
Get data based on Zip Code:
curl --location --request GET 'https://maps.googleapis.com/maps/api/geocode/json?address=90058&key={{YOUR_API_KEY}}'
From your response you will want to take results[0].geometry.location object. You will use the lat and lng values for your next query. The example above provides the following:
// … more above
"formatted_address" : "Los Angeles, CA 90058, USA",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 34.045639,
"lng" : -118.1685449
},
"southwest" : {
"lat" : 33.979672,
"lng" : -118.2435201
}
},
"location" : {
"lat" : 34.00637469999999,
"lng" : -118.2234229
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 34.045639,
"lng" : -118.1685449
},
"southwest" : {
"lat" : 33.979672,
"lng" : -118.2435201
}
}
},
"place_id" : "ChIJDeH8s8TIwoARYQFWkBcCzFk",
// … more below
Request 2
Get data based on Latitude and Longitude
curl --location --request GET 'https://maps.googleapis.com/maps/api/geocode/json?latlng=34.00637469999999,-118.2234229&key={{YOUR_API_KEY}}'
NOTE! The query param has changed from address to latlng
This will likely return many results, you will have to decide which type meets your requirements, but I would recommend looping through the results array and looking for an entry with a types array which includes street_address or premise and using that entry as your target result set.
For the example above, results[1] will have "types" : [ "premise" ]
Its associated formatted_address and the complete parent object will be as follows:
see note at bottom on targeting specific types
"formatted_address" : "2727 E Vernon Ave, Vernon, CA 90058, USA",
// … more above
{
"address_components": [
{
"long_name": "2727",
"short_name": "2727",
"types": [
"street_number"
]
},
{
"long_name": "East Vernon Avenue",
"short_name": "E Vernon Ave",
"types": [
"route"
]
},
{
"long_name": "Vernon",
"short_name": "Vernon",
"types": [
"locality",
"political"
]
},
{
"long_name": "Los Angeles County",
"short_name": "Los Angeles County",
"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": "90058",
"short_name": "90058",
"types": [
"postal_code"
]
},
{
"long_name": "1822",
"short_name": "1822",
"types": [
"postal_code_suffix"
]
}
],
"formatted_address": "2727 E Vernon Ave, Vernon, CA 90058, USA",
"geometry": {
"bounds": {
"northeast": {
"lat": 34.0065676,
"lng": -118.2228652
},
"southwest": {
"lat": 34.0057081,
"lng": -118.2245065
}
},
"location": {
"lat": 34.0061691,
"lng": -118.2236056
},
"location_type": "ROOFTOP",
"viewport": {
"northeast": {
"lat": 34.0074868302915,
"lng": -118.2223368697085
},
"southwest": {
"lat": 34.0047888697085,
"lng": -118.2250348302915
}
}
},
"place_id": "ChIJCQv2_sPIwoARZn8W2bF9a9g",
"types": [
"premise"
]
},
// … more below
Caveats
I assume since you said "Zip Code" you meant the United States. I only tested for the US, if you need other country support, consider adding the country code to your address query params in request 1.
If you use this approach starting with Zip Code, you might encounter results with a route or street_address but no premise if the Zip Code represents a large geographic area with a very low population density. I tested this on "Vernon, California (90058) - population 112" and "Freeport City, Kansas (67049) - population 5". Freeport City returned no result having type of premise.
If you want to query a specific type so you don't have to search through a large result set, you can apply the query param &result_type=premise to request 2. However, if no result exists for the given lat/lng with your specified type(s), you will receive a results.status = ZERO_RESULTS.
Multiple result_type values may be applied, separate with a pipe (|)
Full docs here on Reverse Geocoding: https://developers.google.com/maps/documentation/geocoding/intro#ReverseGeocoding
I am trying to extract formatted address, lat, lon using using google API. The JSON output looks like below:
var inpt = {
"results" : [
{
"address_components" : [
{
"long_name" : "94",
"short_name" : "94",
"types" : [ "street_number" ]
},
{
"long_name" : "Kinghorne Street",
"short_name" : "Kinghorne St",
"types" : [ "route" ]
},
{
"long_name" : "Goulburn",
"short_name" : "Goulburn",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Goulburn Mulwaree Council",
"short_name" : "Goulburn Mulwaree",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "New South Wales",
"short_name" : "NSW",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "Australia",
"short_name" : "AU",
"types" : [ "country", "political" ]
},
{
"long_name" : "2580",
"short_name" : "2580",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "94 Kinghorne St, Goulburn NSW 2580, Australia",
"geometry" : {
"location" : {
"lat" : -34.742658,
"lng" : 149.722802
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : -34.7413090197085,
"lng" : 149.7241509802915
},
"southwest" : {
"lat" : -34.74400698029149,
"lng" : 149.7214530197085
}
}
},
"place_id" : "ChIJ_57nYeiuFmsR0ZLPJl7b2P0",
"plus_code" : {
"compound_code" : "7P4F+W4 Goulburn, New South Wales, Australia",
"global_code" : "4RQF7P4F+W4"
},
"types" : [ "establishment", "food", "point_of_interest", "store" ]
}
],
"status" : "OK"
}
Using Dataweave of MuleSoft 4, I wanted to filter payload by "types" which is an Array. My expected result should be:
location: "New South Wales"
To get the above result I tried expression like below:
%dw 2.0
output application/json
--
{
location: inpt.results.address_components filter ($.type contains "administrative_area_level_1")[0]."long_name"
}
But I am getting null result. Appreciate your help!
Super close, your results is an array. If you have more than one JSON object in the array, you'll need to map them. Here's a solution to the current question:
%dw 2.0
output application/json
---
location: (inpt.results[0].address_components filter ($.types contains "administrative_area_level_1"))[0].long_name
You can use this as well:
%dw 2.0
output application/json
---
{
(flatten (payload.results.address_components) filter ($.types contains "administrative_area_level_1") map {
location : $.long_name
})
}
All "long_name" value for all index of "address_Components" is not display. When using the path: path("results[0].address_components[].long_name")
then test case is failed.
I want to display all "long_name" value given in response. Please suggest me.
{
"results" : [
{
"address_components" : [
{
"long_name" : "Chicago",
"short_name" : "Chicago",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Cook County",
"short_name" : "Cook County",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Illinois",
"short_name" : "IL",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Chicago, IL, USA",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 42.023131,
"lng" : -87.52366099999999
},
"southwest" : {
"lat" : 41.6443349,
"lng" : -87.9402669
}
},
"location" : {
"lat" : 41.8781136,
"lng" : -87.6297982
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 42.023131,
"lng" : -87.52404399999999
},
"southwest" : {
"lat" : 41.6443349,
"lng" : -87.9402669
}
}
},
"place_id" : "ChIJ7cv00DwsDogRAMDACa2m4K8",
"types" : [ "locality", "political" ]
}
],
"status" : "OK"
}
I am using selenium (Maven TestNG):
#Test
public void test_08(){
String[] arrayList = {"chicago"};
for(int i=0; i<arrayList.length; i++){
Response resp = given().
parameter("address", arrayList[i]).
when().
get("http://maps.googleapis.com/maps/api/geocode/json");
Assert.assertEquals(resp.getStatusCode(), 200);
String respReport = resp.
then().
contentType(ContentType.JSON).
extract().
path("results[0].address_components[0].long_name");
System.out.println("Logn Name: "+respReport+);
}
}
OUT PUT:
Logn Name: Chicago
PASSED: test_08
It is because you don't give an index to components as well which is also a json array! So this one passes because you are giving an index to components:
path("results[0].address_components[0].long_name");
Whilst in your bold text at the top of your description you don't.
Now for iterating through the various elements of address_componenents array all you need to do is find the length of the address_components array and then increase the index from zero until < length.of the json array. Something like this:
String jsonObjectAsString = jsonObjectFromYourResponse.toString();
public void retrieveAddressComponenets(String jsonObjectAsString){
JsonElement jelement = new JsonParser().parse(jsonObjectAsString);
JsonObject jobject = jelement.getAsJsonObject();
JsonArray jArray = jobject.getAsJsonArray("address_components");
int i=0;
while(i<jArray.length()){
jelement = new JsonParser().parse(jarray.get(i).toString());
System.out.println("Logn Name: "+respReport);
i++;
}
}
Here is how your json object looks like (currently it has 4 entries you want to retrieve)
Hope this helps to resolve!
Best of luck!
Working in MS Access 2013. Have a ton of locations/addresses which need to be standardized.
Examples include addresses like:
500 W Main St
500 West Main St
500 West Main Street
You get the point.
I've considered running a query that pulls all records where the left(7) or something characters exist more than once in the database, but there are obvious flaws in that logic.
Is there a function or query or anything else that would help me generate a list of records whose addresses may exist multiple times, in slightly different fashions?
This is a tricky business ... equal parts Black Magic and Science. You will be amazed at the variations of Boulevard alone.
This is why I use the Google API. It can be time consuming, for the initial data-set, but only new adds would need to be resolved.
For example
https://maps.googleapis.com/maps/api/geocode/json?address=500 S Main St,Providence RI 02903
returns, in part
"formatted_address" : "500 S Main St, Providence, RI 02903, USA"
and the GOOD News is
https://maps.googleapis.com/maps/api/geocode/json?address=500 South Main Steet,Providence RI 02903
returns the same formatted address as the previous query
"formatted_address" : "500 S Main St, Providence, RI 02903, USA"
VBA Example:
Upon executing the following code ...
' VBA project Reference required:
' Microsoft XML, v3.0
Dim httpReq As New MSXML2.ServerXMLHTTP
httpReq.Open "GET", "https://maps.googleapis.com/maps/api/geocode/json?address=500 South Main Steet,Providence RI 02903", False
httpReq.send
Dim response As String
response = httpReq.responseText
... the string variable response contains the following JSON data:
{
"results" : [
{
"address_components" : [
{
"long_name" : "500",
"short_name" : "500",
"types" : [ "street_number" ]
},
{
"long_name" : "South Main Street",
"short_name" : "S Main St",
"types" : [ "route" ]
},
{
"long_name" : "Fox Point",
"short_name" : "Fox Point",
"types" : [ "neighborhood", "political" ]
},
{
"long_name" : "Providence",
"short_name" : "Providence",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Providence County",
"short_name" : "Providence County",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Rhode Island",
"short_name" : "RI",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "02903",
"short_name" : "02903",
"types" : [ "postal_code" ]
},
{
"long_name" : "2915",
"short_name" : "2915",
"types" : [ "postal_code_suffix" ]
}
],
"formatted_address" : "500 S Main St, Providence, RI 02903, USA",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 41.82055829999999,
"lng" : -71.4028137
},
"southwest" : {
"lat" : 41.8204014,
"lng" : -71.40319219999999
}
},
"location" : {
"lat" : 41.8204799,
"lng" : -71.40300289999999
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : 41.8218288302915,
"lng" : -71.40165396970851
},
"southwest" : {
"lat" : 41.8191308697085,
"lng" : -71.40435193029151
}
}
},
"partial_match" : true,
"place_id" : "ChIJicPQAT9F5IkRfq2njkYqZtE",
"types" : [ "premise" ]
}
],
"status" : "OK"
}
John's answer is completely valid, I wanted to add also that you can achieve the same goal with HERE API. You can do this for free with HERE Maps and you won't need a credit card to get started.
https://geocode.search.hereapi.com/v1/geocode?q=500 West Main Street&apiKey=YOUR_API_KEY
Returns:
{
"items": [
{
"title": "500 W Main St, Alhambra, CA 91801-3308, United States",
"id": "here:af:streetsection:-2rEzgpCkFyX.gMQjWtV1A:CgcIBCCl6q07EAEaAzUwMChk",
"resultType": "houseNumber",
"houseNumberType": "PA",
"address": {
"label": "500 W Main St, Alhambra, CA 91801-3308, United States",
"countryCode": "USA",
"countryName": "United States",
"state": "California",
"county": "Los Angeles",
"city": "Alhambra",
"street": "W Main St",
"postalCode": "91801-3308",
"houseNumber": "500"
},
"position": {
"lat": 34.09193,
"lng": -118.13238
},
"access": [
{
"lat": 34.09241,
"lng": -118.13272
}
],
"mapView": {
"west": -118.13347,
"south": 34.09103,
"east": -118.13129,
"north": 34.09283
},
"scoring": {
"queryScore": 1.0,
"fieldScore": {
"streets": [
1.0
],
"houseNumber": 1.0
}
}
},
additional results...
So you can normalize your data based on the title.
My JSON response is like this:
{
"results" : [
{
"address_components" : [
{
"long_name" : "285",
"short_name" : "285",
"types" : [ "street_number" ]
},
{
"long_name" : "Bedford Ave",
"short_name" : "Bedford Ave",
"types" : [ "route" ]
},
{
"long_name" : "Williamsburg",
"short_name" : "Williamsburg",
"types" : [ "neighborhood", "political" ]
},
{
"long_name" : "Brooklyn",
"short_name" : "Brooklyn",
"types" : [ "sublocality", "political" ]
},
I need to get the last value for the Key long_name:
{
"long_name" : "Brooklyn",//i need to get this "Brooklyn"
"short_name" : "Brooklyn",
"types" : [ "sublocality", "political" ]
},
How can i get that although there is a lot of Values with the same key long_name:
NSArray *resultsArray = [responseDict objectForKey:#"results"];//what to do next?
[[[[[resultsArray objectAtIndex:0] valueForKey:#"address_components"] valueForKey:#"long_name"] lastObject];
Breaking down:
// get array of address components
[[resultsArray objectAtIndex:0] valueForKey:#"address_components"]
// calling this on array will get you long_name values from ALL elements
...] valueForKey:#"long_name"]
// finally grab the last element long_name array
...] lastObject];
Equivalent would be:
[[[[resultsArray objectAtIndex:0] valueForKey:#"address_components"] lastObject] valueForKey:#"long_name"];
Breaking down:
// get array of address components
[[resultsArray objectAtIndex:0] valueForKey:#"address_components"]
// get last dictionary
...] lastObject]
// get long_name from last dictionary
...] valueForKey:#"long_name"]