how do i decode/encode the url parameters for the new google maps?
Asked Answered
F

3

15

Im trying to figure out how to extract the lat/long of the start/end in a google maps directions link that looks like this:

https://www.google.com/maps/preview#!data=!1m4!1m3!1d189334!2d-96.03687!3d36.1250439!4m21!3m20!1m4!3m2!3d36.0748342!4d-95.8040972!6e2!1m5!1s1331-1399+E+14th+St%2C+Tulsa%2C+OK+74120!2s0x87b6ec9a1679f9e5%3A0x6e70df70feebbb5e!3m2!3d36.1424613!4d-95.9736986!3m8!1m3!1d189334!2d-96.03687!3d36.1250439!3m2!1i1366!2i705!4f13.1&fid=0

Im guessing the "!" is a separator between variables followed by XY where x is a number and y is a lower case letter, but can not quite figure out how to reliably extract the coordinates as the number/order of variables changes as well as their XY prefixes.

ideas? thanks

Fourcycle answered 23/8, 2013 at 23:12 Comment(0)
T
21

Well, this is old, but hey. I've been working on this a bit myself, so here's what I've figured out:

The data is an encoded javascript array, so the trick when trying to generate your own data string is to ensure that your formatting keeps the structure of the array intact. To do this, let's look at what each step represents.

As you're correctly figured out, each exclamation point defines the start of a value definition. The first character, an int value, is an inner count, and (I believe) acts as an identifier, although I'm not 100% certain on this. It seems to be pretty flexible in terms of what you can have here, as long as it's an int. The second character, however, is much more important. It defines the data type of the value. I don't know if I've found all the data types yet, but the ones I have figured out are:

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

the remaining characters actually hold the value itself, so a string will just hold the string, a boolean will be '1' or '0', and so on. However, there's an important gotcha: the matrix data type.

The value of the matrix will be an integer. This is the length of the matrix, measured in the number of values. That is, for a matrix !1mx, the next x value definitions will belong to the matrix. This includes nested matrix definitions, so a matrix of form [[1,2]] would look like !1m3!1m2!1i1!2i2 (outer matrix has three children, inner matrix has 2). this also means that, in order to remove a value from the list, you must also check it for matrix ancestors and, if they exist, update their values to reflect the now missing member.

The x data type is another anomaly. I'm going to guess it's hexdecimal encoded for most purposes, but in my particular situation (making a call for attribution info), they appear to also use the x data type to store lat/long information, and this is NOT encoded in hex, but is an unsigned long with the value set as value = coordinate<0 ? (430+coordinate)*1e7 : coordinate*1e7

An example (pulled directly from google maps) of the x data type being used in this way: https://www.google.com/maps/vt?pb=!1m8!4m7!2u7!5m2!1x405712614!2x3250870890!6m2!1x485303036!2x3461808386!2m1!1e0!2m20!1e2!2spsm!4m2!1sgid!2sznfCVopRY49wPV6IT72Cvw!4m2!1ssp!2s1!8m11!13m9!2sa!15b1!18m5!2b1!3b0!4b1!5b0!6b0!19b1!19u12!3m1!5e1105!4e5!18m1!1b1

For the context of the question asked, it's important to note that there are no reliable identifiers in the structure. Google reads the values in a specific order, so always keep in mind when building your own encoded data that order matters; you'll need to do some research/testing to determine that order. As for reading, your best hope is to rebuild the matrix structure, then scan it for something that looks like lat/long values (i.e. a matrix containing exactly two children of type double (or x?))

Tourist answered 14/12, 2015 at 19:32 Comment(4)
I created a basic Javascript Gist based on your answer to parse the "data" attribute value into an Array: gist.github.com/jeteon/e71fa21c1feb48fe4b5eeec045229a0cGuest
Decoder on PHP: gist.github.com/mingalevme/04702bb7e5e361448cbe44cb7b3895d5Boeke
There is a "z"-type: "!2z0JfRg9Cx0L7QstGB0LrQuNC5INCxLdGALCA0LCDQnNC-0YHQutCy0LAsIDExOTAzNA!" - looks like base64 encoded binary dataBoeke
x-parameter is not coordinates, it's their own place ID.More info here #47017887.Thereupon
D
6

Looks like the developer tools from current browsers (I am using Chrome for that) can give you a lot of info.

Try the following:

  • Go to Google Maps with Chrome (or adapt the instructions for other browser);
  • Open Developer Tools (Ctrl + Shift + I);
  • Go to Network tab. Clear the current displayed values;
  • Drag the map until some url with encoded data appears;
  • Click on that url, and then go to the Preview sub-tab;

enter image description here

Dinghy answered 26/6, 2017 at 0:46 Comment(2)
doesn't seem to work any more; the Preview tab shows map tilesSerendipity
@JasonS There's several pb=! URLs in the network tab. You are correct the first few of them show map tiles, but one of the later calls also shows the full data as shown in this screenshot.Hieronymus
C
5

Try this.

function URLtoLatLng(url) {
  this.lat = url.replace(/^.+!3d(.+)!4d.+$/, '$1');
  this.lng = url.replace(/^.+!4d(.+)!6e.+$/, '$1');
  return this;
}

var url = new URLtoLatLng('https://www.google.com/maps/preview#!data=!1m4!1m3!1d189334!2d-96.03687!3d36.1250439!4m21!3m20!1m4!3m2!3d36.0748342!4d-95.8040972!6e2!1m5!1s1331-1399+E+14th+St%2C+Tulsa%2C+OK+74120!2s0x87b6ec9a1679f9e5%3A0x6e70df70feebbb5e!3m2!3d36.1424613!4d-95.9736986!3m8!1m3!1d189334!2d-96.03687!3d36.1250439!3m2!1i1366!2i705!4f13.1&fid=0');

console.log(url.lat + ' ' + url.lng);
Chiropractor answered 23/8, 2013 at 23:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.