Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decoding the Google Maps embedded parameters

The context

I would like to be able to extract the location of Google Maps embedded in a website (random example found at the bottom of this website).

<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3128.340699934565!2d-0.46482818466529047!3d38.3642391796565!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0xd62377123a70817%3A0x85e89b65fcf7c648!2sCalle+Cruz+de+Piedra%2C+4%2C+03015+Alicante!5e0!3m2!1ses!2ses!4v1476192292052" width="100%" height="350" frameborder="0" style="border:0" allowfullscreen=""></iframe>

So, basically I want to extract the pinpoint location from the Maps URL:

https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3128.340699934565!2d-0.46482818466529047!3d38.3642391796565!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0xd62377123a70817%3A0x85e89b65fcf7c648!2sCalle+Cruz+de+Piedra%2C+4%2C+03015+Alicante!5e0!3m2!1ses!2ses!4v1476192292052 

The URL design

Google seems to use a proprietary parameter design here. This blog entry and this Stackoverflow post did a good job summarizing how these parameters can be understood. The parameters are structured like (![id][type][value]), with types:

m: matrix f: float d: double i: integer b: boolean e: enum (as integer) s: string u: unsigned int 

Matrices can encapsulate multiple data entries, e. g. !1m3!1i2!1i4!1i17 means that the matrix with the ID 1 contains the three integer values [2, 4, 17].

With this knowledge, the parameters can be structured like this:

!1m18   !1m12     !1m3       !1d3128.340699934565       !2d-0.46482818466529047       !3d38.3642391796565     !2m3       !1f0       !2f0       !3f0     !3m2       !1i1024       !2i768       !4f13.1   !3m3     !1m2       !1s0xd62377123a70817:0x85e89b65fcf7c648       !2sCalle Cruz de Piedra, 4, 03015 Alicante   !5e0 !3m2   !1ses   !2ses !4v1476192292052 

Now it seems to be easy, we see coordinates almost in clear-text. But as the blog entry points out, the parameters

!1d3128.340699934565 !2d-0.46482818466529047 !3d38.3642391796565 

are not the position of the pinpoint, but the center of the shown map. They are similar, but at times very different. Changing the coordinates and/or the address will not result in a different map.

Only when changing the parameter !1s0xd62377123a70817:0x85e89b65fcf7c648, the map display will break, meaning this parameter decodes the location of the pinpoint.

Just, in what encoding?

The question

In the blog entry (from August 2016), the Maps link is built up differently. There is another parameter which encodes the longitude and latitude coordinates in base64:

zMzfCsDQ3JzM0LjUiUyAxNDXCsDAwJzU2LjYiRQ ----base64---> 37°47'34.5"S 145°00'56.6"E 

In a similar manner, the coordinates of this new parameter should hopefully decode:

0xd62377123a70817:0x85e89b65fcf7c648 ----????----> 38.364236,-0.462649 

It looks like hexadecimal encoding, but when converting to integer (964394229279688727:9649133063979386440), this does not correspond to geographic coordinates in a system I know.

So, who can crack the code? Any help appreciated.

like image 833
Manu CJ Avatar asked Oct 30 '17 14:10

Manu CJ


People also ask

Can I extract embedded Google maps data from this webpage?

You can access the full google map by clicking the "View Larger Map" icon in the upper right corner of the map embedded on the page you shared. Here is the url. In the google map, if you go to the top of the legend and click the three vertical dots, the menu will display the option "Download KML".


1 Answers

This intermediate is not the final answer, and the sequel follows)), just some thoughts

Undocumented method. (with ftid instead of place_id parameter)
Places API Web Service
No warranty in future:

https://maps.googleapis.com/maps/api/place/details/json?key=YOUR_API_KEY&ftid=0xd62377123a70817:0x85e89b65fcf7c648& 

The documented request is:

https://maps.googleapis.com/maps/api/place/details/json?key=YOUR_API_KEY&placeid=ChIJFwinI3E3Yg0RSMb3_GWb6IU 

Need API KEY for this requests Setting up API keys

Answer from Google: (JSON - light parsing)

{    "html_attributions" : [],    "result" : {       "address_components" : [          {             "long_name" : "4",             "short_name" : "4",             "types" : [ "street_number" ]          },          {             "long_name" : "Calle Cruz de Piedra",             "short_name" : "Calle Cruz de Piedra",             "types" : [ "route" ]          },          {             "long_name" : "Alacant",             "short_name" : "Alacant",             "types" : [ "locality", "political" ]          },          {             "long_name" : "Alicante",             "short_name" : "A",             "types" : [ "administrative_area_level_2", "political" ]          },          {             "long_name" : "Comunidad Valenciana",             "short_name" : "Comunidad Valenciana",             "types" : [ "administrative_area_level_1", "political" ]          },          {             "long_name" : "Spain",             "short_name" : "ES",             "types" : [ "country", "political" ]          },          {             "long_name" : "03015",             "short_name" : "03015",             "types" : [ "postal_code" ]          }       ],       "adr_address" : "\u003cspan class=\"street-address\"\u003eCalle Cruz de Piedra, 4\u003c/span\u003e, \u003cspan class=\"postal-code\"\u003e03015\u003c/span\u003e \u003cspan class=\"locality\"\u003eAlacant\u003c/span\u003e, \u003cspan class=\"region\"\u003eAlicante\u003c/span\u003e, \u003cspan class=\"country-name\"\u003eSpain\u003c/span\u003e",       "formatted_address" : "Calle Cruz de Piedra, 4, 03015 Alacant, Alicante, Spain",       "geometry" : {          "location" : {             "lat" : 38.3642358,             "lng" : -0.4626489          },          "viewport" : {             "northeast" : {                "lat" : 38.3655847802915,                "lng" : -0.4612999197084979             },             "southwest" : {                "lat" : 38.3628868197085,                "lng" : -0.463997880291502             }          }       },       "icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png",       "id" : "ce1aa5a252b86d559268866a6a4858db9bba3dff",       "name" : "Calle Cruz de Piedra, 4",       "place_id" : "ChIJFwinI3E3Yg0RSMb3_GWb6IU",       "reference" : "CmRbAAAAn6NLYXEs-ttLvUlgjnh5aDHt-LR_hXe6JmUN8fzv6MJ7Q50xt_zUU_WlTc3aL_BQc70-1YjEb6Soluro5rA8cIFJG_w08RSr_JWo_SFEFc1Ncme_dKVKsPX6Q0LtO8gWEhACTzabAMLQfM5xt1_BNsywGhSZr0WRGlutqeuRgs-IY41ndk3yoQ",       "scope" : "GOOGLE",       "types" : [ "street_address" ],       "url" : "https://maps.google.com/?q=Calle+Cruz+de+Piedra,+4,+03015+Alacant,+Alicante,+Spain&ftid=0xd62377123a70817:0x85e89b65fcf7c648",       "utc_offset" : 60,       "vicinity" : "Alacant"    },    "status" : "OK" } 

Setting up API keys

If your client application does not use OAuth 2.0, then it must include an API key when it calls an API that's enabled within a Google Cloud Platform project. The application passes this key into all API requests as a key=API_key parameter. To create your application's API key:

  1. Go to the API Console.
  2. From the projects list, select a project or create a new one.
  3. If the APIs & services page isn't already open, open the left side menu and select APIs & services.
  4. On the left, choose Credentials.
  5. Click Create credentials and then select API key.

Note: In addition to reading the instructions on this page, be sure to read Best practices for securely using API keys.


(draft) not deleted for history

for test only! temporary solution:

curl "https://www.google.com/maps/place/data=!4m2!3m1!1s0xd62377123a70817:0x85e89b65fcf7c648" -s -b -L -H "user-agent: Googlebot/2.1 (+http://www.google.com/bot.html)" | FIND """0xd62377123a70817:0x85e89b65fcf7c648""," 

Answer in command prompt: ,["0xd62377123a70817:0x85e89b65fcf7c648",null,null,[null,null,38.364235799999996,-0.4626489]

CURL there if needed

search to be continued....


I think, this (0xd62377123a70817:0x85e89b65fcf7c648) is ID of map object in GoogleMap database. When click URL1.

For Example

if you want geographic coordinates then click URL2 please and next if need create link as EMBED no problem, result below:

src="https://www.google.com/maps/embed?pb= !1m18     !1m12         !1m3             !1d782.0856626047412             !2d-0.46311117079625247             !3d38.36419405026406         !2m3             !1f0             !2f0         !3f0         !3m2             !1i1024             !2i768         !4f13.1     !3m3         !1m2             !1s0x0%3A0x0             !2zMzjCsDIxJzUxLjEiTiAwwrAyNyc0NS4yIlc     !5e0 !3m2    !1ses    !2ses !4v1509474812934"  

it is FTID (0xd62377123a70817:0x85e89b65fcf7c648)
The ftid parameter is a unique identifier for certain map objects, just as fid and cid are.
Locations that need to be on the map but are not part of the Local database are identified by the ftid parameter. It is not possible to claim these type of Maps objects through Places.

API Google Places and others work with place-id

for (Calle Cruz de Piedra, 4 03015 Alicante) place-id = ChIJFwinI3E3Yg0RSMb3_GWb6IU

(place -> place-id)
https://developers.google.com/maps/documentation/javascript/examples/places-placeid-finder
and Reverse (place-id->place)
https://developers.google.com/maps/documentation/javascript/examples/geocoding-place-id

NOW:

place-id to location - ok
https://developers.google.com/maps/documentation/geocoding/intro?hl=en#ReverseGeocoding

FTID to location -? question open... for fast and automatic

way over Google:

https://google.com/maps?ftid=0xd62377123a70817:0x85e89b65fcf7c648

https://www.google.com/maps/place/Calle+Cruz+de+Piedra,+4,+03015+Alicante,+%D0%98%D1%81%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F/@38.3642358,-0.4648376,17z/data=!3m1!4b1!4m5!3m4!1s0xd62377123a70817:0x85e89b65fcf7c648!8m2!3d38.3642358!4d-0.4626489

for Atlantic Ocean work too:
https://google.com/maps?ftid=0xadd28c30ec90d79%3A0x44652457c0696504

and two words about Google Maps Embed API:

<iframe  src="https://www.google.com/maps/embed?pb= !1m3 !3m2 !1m1 !1s0xd62377123a70817%3A0x85e89b65fcf7c648" width="400" height="400" frameborder="0" style="border:0" allowfullscreen> </iframe>

m create Block with this syntax: 1 Digital - ID or place in current block? 2 Digital - value = size of new block

!<ID>m<value>

!1m3 !3m2 !1m1 !1s0xd62377123a70817%3A0x85e89b65fcf7c648  {} {,,{}} {,,{{}}} {,,{{1s}}}  !1:{} !1:{!3:{}} !1:{!3:{!1:{}}} !1:{!3:{!1:{1s}}} 

I hope this helps!

like image 199
Akubik Avatar answered Sep 16 '22 17:09

Akubik