Google Maps API data in new response format

When passing Google Maps API an address, it used to return a HTML formatted response. Given the new format of the response, is there something better than tagdata( to pull the lat & lng of “location”?

     "formatted_address" : "3040 SE 143rd Ave, Portland, OR 97236, USA",
     "geometry" : {
        "bounds" : {
           "northeast" : {
              "lat" : 45.5001223,
              "lng" : -122.5160117
           },
           "southwest" : {
              "lat" : 45.5000205,
              "lng" : -122.5162573
           }
        },
        "location" : {
           "lat" : 45.50007009999999,
           "lng" : -122.5161041
        },
        "location_type" : "ROOFTOP",
        "viewport" : {
           "northeast" : {
              "lat" : 45.5014203802915,
              "lng" : -122.5147855197085
           },
           "southwest" : {
              "lat" : 45.4987224197085,
              "lng" : -122.5174834802915
           }
        }
     },

Or is it time to drop back to standard text funnelling and parsing?

1 Like

That’s JSON, so if you were using Panorama X, you could use the new JSON functions :slight_smile:

However, you filed this under Panorama “Classic”, so those new functions aren’t available. Parsing JSON can be tricky, especially when the data structure is nested as in this case. However, this wouldn’t be too bad to parse with tagdata(, and that’s probably how I would do it. I’d start with

tagdata(htmlContent,|||"location" : {|||,"}",1)

Then I would probably use another tagdata( to extract the lat, and possibly the after( function to extract the longitude, or tagdata( could be used for that also.

Are you sure that format isn’t still supported?

According to the documentation at

A Geocoding API request takes the following form:

https://maps.googleapis.com/maps/api/geocode/outputFormat?parameters
where outputFormat may be either of the following values:

json (recommended) indicates output in JavaScript Object Notation (JSON); or
xml indicates output in XML

XML is the “old” format, that plays nice with tagdata(.

You are correct Dave. When I attempted to update my query to include the recently required ‘key’, when it did not work at first, I overlooked that the problem was not the XML but rather the new format of the URL. I’ll wait to do the JSON until I convert this db over to Panorama X.

This is the data I receive from the Google Maps API:

{
   "results" : [
  {
     "address_components" : [
        {
           "long_name" : "1111",
           "short_name" : "1111",
           "types" : [ "street_number" ]
        },
        {
           "long_name" : "Maple Drive",
           "short_name" : "Maple Dr",
           "types" : [ "route" ]
        },
        {
           "long_name" : "Uptown",
           "short_name" : "Uptown",
           "types" : [ "locality", "political" ]
        },
        {
           "long_name" : "Harrison Township",
           "short_name" : "Harrison Township",
           "types" : [ "administrative_area_level_3", "political" ]
        },
        {
           "long_name" : "Smith County",
           "short_name" : "Smith County",
           "types" : [ "administrative_area_level_2", "political" ]
        },
        {
           "long_name" : "Georgia",
           "short_name" : "GA",
           "types" : [ "administrative_area_level_1", "political" ]
        },
        {
           "long_name" : "United States",
           "short_name" : "US",
           "types" : [ "country", "political" ]
        },
        {
           "long_name" : "33333",
           "short_name" : "33333",
           "types" : [ "postal_code" ]
        },
        {
           "long_name" : "2222",
           "short_name" : "2222",
           "types" : [ "postal_code_suffix" ]
        }
     ],
     "formatted_address" : "1111 Maple Dr, Uptown, GA 33333, USA",
     "geometry" : {
        "bounds" : {
           "northeast" : {
              "lat" : 11.8,
              "lng" : -12.7
           },
           "southwest" : {
              "lat" : 11.7,
              "lng" : -12.8
           }
        },
        "location" : {
           "lat" : 11.75,
           "lng" : -12.75
        },
        "location_type" : "ROOFTOP",
        "viewport" : {
           "northeast" : {
              "lat" : 11.75,
              "lng" : -12.75
           },
           "southwest" : {
              "lat" : 11.76,
              "lng" : -12.74
           }
        }
     },
     "place_id" : "RandomCharacters254RFDSA",
     "types" : [ "premise" ]
  }
   ],
   "status" : "OK"
}

When using jsonimport I get a dictionary with two keys: “results” and “status”. The value for the key “results” isn’t an array or a dictionary. How do I further parse this nested JSON statement? I’d appreciate any help using the JSON commands or others, as needed.

I’m not sure what information you need to extract from the JSON text but here is a starting point and my best guess. The above JSON text is in a variable I have named theJSON and I used this formula:

tagdata(theJSON,|||"formatted_address" : "|||,{",},1)+
    tagdata(theJSON,|||"location" : {|||,|||},|||,1)

Which will produce this result:

1111 Maple Dr, Uptown, GA 33333, USA
           "lat" : 11.75,
           "lng" : -12.75

I used the triple vertical lines for the quotes in the function parameters because the quoted header and trailer already use the normal quotes and curly brackets.

A JSON structure is like an onion, you have to peel it apart layer by layer. Each layer could be a dictionary or an array. Eric, you only peeled the first layer. Here is an example that extracts the formatted address from your data.

let jsource = ... json code from Eric Werner's example above ...
let jdata = jsonimport(jsource)
// message listdictionarykeys(jdata) rtn
let results = getdictionaryvalue(jdata,"results")
// message arraysize(results) rtn
let resultdictionary = array(results,1)
// message listdictionarykeys(resultdictionary) rtn
let formattedAddress = getdictionaryvalue(resultdictionary,"formatted_address")
message formattedAddress

When I run this code it displays 1111 Maple Dr, Uptown, GA 33333, USA

Using these techniques you can extract any value from the JSON structure.

Note: I have left the intermediate message statements in the code that I used to figure out how to peel apart the structure, for your edification (but commented out).

Since this subject is listed under the Panorama “Classic” category, you would need to substitute listdictionarynames( in place of listdictionarykeys(. Just thought I’d mention that in case it is actually being coded in Classic.

Classic Panorama doesn’t have anything remotely equivalent to jsonimport(. In Panorama 6, you would want to use the XML format, and the tagparameter( and tagparameterarray( functions.

Robert’s original question was about Panorama 6, but Eric switched it to Panorama X (by using the jsonimport statement). I’ve just now switched the thread topic to Panorama X, though it is really mixed between both versions.

Jim and Gary, thank you for your answers … I wanted to be able to use either the XML or JSON technique. XML is very straightforward and the JSON appeared to me that it be just as easy. I just couldn’t figure out what the array delimiter was for that second onion layer … of course I didn’t think about a data array which doesn’t need one. I haven’t coded much with data arrays.

My apologies for semi-hijacking a Classic discussion.