How to extract coordinates from google maps short url?

Viewed 669

I have a list of google maps short urls like :

https://goo.gl/maps/4hHGt2147ijXHkpC8

and I was wondering how to extract location latitude and longitude from each short url with an api or client library ?

NOTE: The URL Shortener API to get the long url doesn't work anymore.

https://www.googleapis.com/urlshortener/v1/url?key=[my_api_key]&shortUrl=[my_short_url]

UPDATE: all the answers I have found so far was for the long url which I don't have, and to obtain it I have to put the link in the browser, and I have like 10000 link, so is there's any other solution than developing a scraping tool to open the short url in the browser to obtain the long url and then extract coordinates from the long url ?

EDIT:

i tried the following code :

public class Test {

    public static void main(String[] args) throws Exception {
        String url = "https://goo.gl/maps/chcK1sV1BtpYirAP9";
        String urlLong = getRedirectURL(url);
        System.out.println(urlLong);
        System.out.println("maps final url: " + buildMapURL(urlLong));
    }

    public static String buildMapURL(String url) {
        Pattern pattern = Pattern.compile("!3d\\d+\\.\\d+!4d\\d+\\.\\d+");
        Matcher matcher = pattern.matcher(url);
        if (matcher.find()) {
            String result = matcher.group(0).replace("!3d", "").replace("!4d", ",");
            return "https://maps.google.com/maps?q=" + result;
        }
        return "";
    }

    public static String getRedirectURL(String strURL) throws Exception {
        InputStream is = null;
        try {

            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            URL url = new URL(strURL);
            HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
            https.setInstanceFollowRedirects(true);
            HttpsURLConnection.setFollowRedirects(true);
            https.connect();
            int responseCode = https.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                is = https.getInputStream();
                return https.getURL().toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (is != null)
                is.close();
        }
        return null;

    }

}

Issue: After i get the long url as follows

https://www.google.com.sa/maps/place/%D8%B3%D8%A7%D9%86%D8%AC+%D9%8A%D9%88%D9%86%D8%AC+%D8%A7%D9%84%D8%A8%D8%A7%D8%B2%D8%B9%D9%8A+SSANGYONG+Bazie%E2%80%AD/@24.695477,46.7345518,18z/data=!4m5!3m4!1s0x3e2f03f1077c5fbf:0x9003e7394e3408f8!8m2!3d24.6968319!4d46.7353356?hl=ar&shorturl=1

the captured coordinates is not 100% accurate since when I open it in browser after couple of seconds it redirects to a new url which I am not able to capture, so i tried to get the redirect url for it and it produces same result.

Is there's a solution for this issue or another suggestion for API to extract exact coordinates ?

1 Answers

The coordinates after the @ 24.695477,46.7345518 are the center of the map, not the location, that is in the your URL: https://www.google.com.sa/maps/place/%D8%B3%D8%A7%D9%86%D8%AC+%D9%8A%D9%88%D9%86%D8%AC+%D8%A7%D9%84%D8%A8%D8%A7%D8%B2%D8%B9%D9%8A+SSANGYONG+Bazie%E2%80%AD/@24.695477,46.7345518,18z/data=!4m5!3m4!1s0x3e2f03f1077c5fbf:0x9003e7394e3408f8!8m2!3d24.6968319!4d46.7353356?hl=ar&shorturl=1

Google uses the web-standard key1=value1&key=value2 style in the map queries. These are the meaning of the chars in the Google Maps queries:

d - double-precision floating-point

f - single-precision floating-point

i - integer

s - string

z - encoded data or an id or some kind

b - byte or boolean (?)

v - timestamp, Unix epoch in milliseconds

These are parameter groups of your link at the "data=" part:

!4m5

!3m4

!1s0x3e2f03f1077c5fbf:0x9003e7394e3408f8

!8m2

!3d24.6968319

!4d46.7353356

?hl=ar&shorturl=1

There are lots of parameter groups for creating google maps queries according to the XML hierarchy.

For example :

"https://www.google.com/maps/embed?pb=" +
    "!1m18" +
        "!1m12" +
            "!1m3" +
                "!1d3152.8774048836685" +
                "!2d145.01352231578036" +
                "!3d-37.792912740624445" +
            "!2m3" +
                "!1f0" +
                "!2f0" +
                "!3f0" +
            "!3m2" +
                "!1i1024" +
                "!2i768" +
            "!4f13.1" +
        "!3m3" +
            "!1m2" +
                "!1s0x0%3A0x0" +
                "!2zMzfCsDQ3JzM0LjUiUyAxNDXCsDAwJzU2LjYiRQ" +
        "!5e0" +
    "!3m2" +
        "!1sen" +
        "!2sau" +
    "!4v1471218824160"

Actually, every parameters represents a tag in XML schema like this example :

<kml>
  <Response>
    <name>London</name>
    <Status>
          <code>200</code>
      <request>geocode</request>
    </Status>
    <Placemark id="p1">
      <address>London, Greater London, UK</address>
      <AddressDetails Accuracy="4">
        <Country>
        <CountryNameCode>GB</CountryNameCode>
          <AdministrativeArea>
           <AdministrativeAreaName>England</AdministrativeAreaName>
            <SubAdministrativeArea>
              <SubAdministrativeAreaName>Greater London</SubAdministrativeAreaName>
              <Locality>
                <LocalityName>London</LocalityName>
              </Locality>
            </SubAdministrativeArea>
          </AdministrativeArea>
        </Country>
      </AddressDetails>
      <Point>
        <coordinates>0.126236,51.500152,0</coordinates>
      </Point>
    </Placemark>
  </Response>
</kml>

So Finally, in your Java code, you have a pattern that checks the 3d and 4d but it will just get to the center of the map again.

NOTE: Actually, you can also use the !1s parameter(Yours is that !1s0x3e2f03f1077c5fbf:0x9003e7394e3408f8).But it also redirects the same long url. It has hexadecimal code as param1:param2. Convert param2 from hexadecimal to decimal and pass it in cid ( CustomerId ) parameter like this : https://google.com/maps?cid=10377392199702939896

You need !2z parameter to find real coordinates with base64 encoded data like that :

  • !2zMzfCsDQ3JzM0LjUiUyAxNDXCsDAwJzU2LjYiRQ

and then decode it for getting the real coordinates but you don't have a "z" field in your long URL. Maybe Google changed query standards after stopped supporting "goo.gl" short links on March 30, 2019.

Please check these links for more information:

Andrew Whitby

Pete Watson-Wailes

Blog

Thanks.

Related