Search code examples
javascriptphpgoogle-mapsgoogle-maps-api-3geocoding

finding place id or gps coordinates with a google maps url


I've been looking at solutions to retrieve place_id or directly the gps coordinates of a place from a google maps shared url.

I want my users to simple copy paste a location link and I retrieve the coordinates of the place they want, very easily done on the long url of google maps as the coordinates are transparent (ex https://www.google.com/maps/place/Eiffel+Tower/@48.8583701,2.2919064,17z/data=!3m1!4b1!4m6!3m5!1s0x47e66e2964e34e2d:0x8ddca9ee380ef7e0!8m2!3d48.8583701!4d2.2944813!16zL20vMDJqODE?hl=en-FR&entry=ttu ).

But I'm having trouble trying to do the same kind of operation when the users use the much shorter version from the app, or the shared option on maps (ex. https://maps.app.goo.gl/GmCgwbfgzPHq1JeHA ) do you have any idea if this is possible? I've been trying to use Geocoding and place details api... but I can't quite get close to the result I'd like.

In short I would like to get gps lat/lon from a link under this format https://maps.app.goo.gl/GmCgwbfgzPHq1JeHA using PHP HTTP request if possible and store the lat/lon in an array or at least do the same as this website https://wheregoes.com/


My first guess

function unshortenURL($shortURL) { $ch = curl_init($shortURL);

curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
$expandedURL = $shortURL;

if (!curl_errno($ch)) {
    $info = curl_getinfo($ch);
    if ($info['http_code'] == 301 || $info['http_code'] == 302) {
        $expandedURL = $info['url'];
    }
}

curl_close($ch);
return $expandedURL;

}

my second choice

function unshortenURL($mapsUrl) { //mapsUrl is only the code https://maps.app.goo.gl/**GmCgwbfgzPHq1JeHA** in bold $apiURL = " https://places.googleapis.com/v1/places/$mapsUrl?fields=id,displayName&key=API_KEY";

$ch = curl_init($apiURL);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

curl_close($ch);

$data = json_decode($response, true);

if ($data && isset($data['results'][0]['geometry']['location'])) {
    $location = $data['results'][0]['geometry']['location'];
    $latitude = $location['lat'];
    $longitude = $location['lng'];
    return array('latitude' => $latitude, 'longitude' => $longitude);
} else {
    return null; // Invalid or incomplete response
}

}

{ "error": { "code": 400, "message": "Not a valid Place ID: GmCgwbfgzPHq1JeHA\n", "status": "INVALID_ARGUMENT" } }

makes sense as I'm trying to get the id with what I believed was an "id"...

third choice was basically the same but with Geocoding


Solution

  • Here is the answer I made myself and works great for need, hope it helps other.

    so basically I'm looking at a pattern (LAT/LON) in a link provided by a user. If the coordinates are presents within the provided link then we can go to the next step. Otherwise we will try to get the full link from a shortened link (using the checkRedirects function) , if a longer link exist providing us the necessary coordinates then let's keep continue other we try our luck with the extractAddressFromURL() function if any address is found we then proceed with the geocoding api from google to get out LAT/LON coordinates with the found address using the getLocationCoordinates() function.

    $pattern = '/@(-?\d+\.\d+),(-?\d+\.\d+)/';
        if(preg_match($pattern, $activityLink, $matches)){
          $locationX = $matches['1'];
          $locationY = $matches['2'];
        } else{
                    if($_SERVER["REQUEST_METHOD"] == "POST"){
                        $redirects = checkRedirects($activityLink);
                        foreach($redirects as $url){
                            if(preg_match($pattern, $url, $matches)){
                      $locationX = $matches['1'];
                      $locationY = $matches['2'];
                                break;
                    } else{
                                $address = extractAddressFromURL($url);
                                $coordinates = getLocationCoordinates($address);
    
                                if($coordinates){
                                    $locationX = $coordinates['latitude'];
                          $locationY = $coordinates['longitude'];
                                    break;
                                } else{
                                }
                            }
                        }
                    } else{
                    }
        }
    

    and here are the functions I'm calling:

    function checkRedirects($url) {
      $redirects = [];
      $ch = curl_init($url);
    
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_HEADER, true);
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    
      $response = curl_exec($ch);
      $info = curl_getinfo($ch);
      $headers = substr($response, 0, $info['header_size']);
    
      $lines = explode("\n", $headers);
    
      foreach ($lines as $line) {
        if(stripos($line, "Location:") !== false) {
          $redirects[] = trim(str_ireplace("Location:", "", $line));
        }
      }
    
      curl_close($ch);
    
      return $redirects;
    }
    
    function extractAddressFromURL($url){
      $parsedUrl = parse_url($url);
      if(isset($parsedUrl['query'])){
        parse_str($parsedUrl['query'], $queryParameters);
    
        if(isset($queryParameters['q'])){
          $address = urldecode($queryParameters['q']);
        } elseif (isset($queryParameters['continue'])){
          $address = urldecode($queryParameters['continue']);
        } else{
          $address = 0;
        }
      } else{
        $address = 0;
      }
    
      return $address;
    }
    
    function getLocationCoordinates($adress){
      $encodedUrl = urlencode($adress);
      $apiURL = "https://maps.googleapis.com/maps/api/geocode/json?address=".$encodedUrl."&key=API_KEY";
      $ch = curl_init($apiURL);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      $response = curl_exec($ch);
      curl_close($ch);
      $data = json_decode($response, true);
    
      if($data && isset($data['results'][0]['geometry']['location'])){
        $location = $data['results'][0]['geometry']['location'];
        $latitude = $location['lat'];
        $longitude = $location['lng'];
        return array('latitude' => $latitude, 'longitude' => $longitude);
      } else{
        return null;
      }
    }