Question

Here is my current code on how I'm getting different components.

function getGeocodeFull($address)
{
    if (empty($address)) return false;

    $_geocode = false; 

    if (($_geocode = $this->getCache($address)) === false) // check if address is has a cache
    {
        if (($results = $this->geoGetCoordsFull($address)) !== false) 
        {
            // sloooooooooopppy.. yes these can all be combined, i know.
            if (!isset($results->results[0]->geometry->location->lat))  return false;
            if (!isset($results->results[0]->geometry->location->lat))  return false;
            if (!isset($results->results[0]->formatted_address))        return false;
            if (!isset($results->results[0]->address_components))       return false;

            $_geocode['lat']     = $results->results[0]->geometry->location->lat;
            $_geocode['lon']     = $results->results[0]->geometry->location->lng;
            $_geocode['address'] = $results->results[0]->formatted_address;

            foreach ($results->results[0]->address_components as $component)
            {
                if (isset($component->types))
                {
                    foreach ($component->types as $type)
                    {
                        switch ($type)
                        {
                            case 'route':
                                $_geocode['street'] = $component->long_name;
                                break;
                            case 'locality':
                                $_geocode['city'] = $component->long_name;
                                break;
                            case 'administrative_area_level_2':
                                $_geocode['county'] = $component->long_name;
                                break;
                            case 'administrative_area_level_3':
                                $_geocode['area'] = $component->long_name;
                                break;
                            case 'postal_code':
                                $_geocode['zip'] = $component->short_name;
                                break;
                        }     
                    }
                }    
            }

            $this->putCacheFull($address, $_geocode['lat'], $_geocode['lon'], $_geocode['address'], $_geocode['street'], $_geocode['city'], $_geocode['county'], $_geocode['area'], $_geocode['zip']);
        }
    }

    return $_geocode;
}

geoGetCoordsFull() simply uses file_get_contents on the google map api geocode page, then decodes the results then returns them.

I'm not too big of a fan of what that looks like. It seems like it can be very inconsistent. Are there any other BETTER solutions to getting all the data from google or any other service?

I'd prefer another service that doesn't limit requests (or is it illegal to use multiple geocode services such as bing/yahoo/etc) ?? (sorry for throwing in another question)

Anyway, much help would be very appreciated!

Was it helpful?

Solution

I went about it another way, I've removed a bit of code for brevity, but basically I had a table with about 16'000 locations (all locations in Australia) and looped through them all to find them on Google Maps, retrieve the lat long info and store back in the table so it never had to be looked up again

$row contains an array of details for the location I'm looking up, like the address, postcode, suburb and state

You'll also need to get an API key from Google Maps for this code, as it uses v2. I don't think you need one anymore for v3

define("MAPS_HOST", "maps.google.com");
define("KEY", "YOU_KEY_HERE");

// Initialize delay in geocode speed
$delay = 0;
$lat = '';
$lng = '';
$base_url = "http://" . MAPS_HOST . "/maps/geo?output=xml" . "&key=" . KEY;

  $geocode_pending = true;
  while ($geocode_pending) {

    flush();

    $address = $row['suburb'] . ' ' . $row['postcode'] . ', ' . $row['state'] . ' Australia';
    $request_url = $base_url . "&q=" . urlencode($address);
    $xml = simplexml_load_file($request_url) or die("url not loading");

    $status = $xml->Response->Status->code;
    if (strcmp($status, "200") == 0) {
      // Successful geocode
      $geocode_pending = false;
      $coordinates = $xml->Response->Placemark->Point->coordinates;
      $coordinatesSplit = split(",", $coordinates);

      // Format: Longitude, Latitude, Altitude
      $lat = $coordinatesSplit[1];
      $lng = $coordinatesSplit[0];

    } else if (strcmp($status, "620") == 0) {
      // sent geocodes too fast, have a breather and try again soon
      echo("Google says no... increase the delay to ".($delay/1000000)." seconds<br />\n");
      $delay += 100000;
    } else {
      // failure to geocode
      $geocode_pending = false;
      echo "Address " . $address . " failed to be geocoded. ";
      echo "Received status " . $status . "<br />
\n";
    }
    usleep($delay);
  }
  echo("Lat long found for " . $address . "<br />\n");
  echo("Lat: " . $lat . "<br />\n");
  echo("Long: " . $lng . "<br />\n");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top