Avatar of smetterd
smetterdFlag for United States of America

asked on 

Check valid or invalid address with Google Maps API

Our Student Management System feeds a third party bus routing system (Versatrans RP). Versatrans then takes the addresses and builds bus routes using geocoding. Campus clerks continually messup or misspell addresses (e.g. "18=9 Vic. Crclke" instead of the correct "189 Victory Circle") which of course causes the auto-build of routes to fail.

Can anyone point me in the direction of how to use Google Maps API or other webservice to grab addresses, assess them, and return TRUE if they're OK and FALSE if they're not?

Many thanks....
SoftwareGIS/GPS ProgrammingWeb Languages and Standards

Avatar of undefined
Last Comment
Ray Paseur
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

The US Postal Service offers a data verification API.  Google it if you want to learn more.  In my experience it was difficult to use and their "tech support" was nothing better than surly.  But that was a few years ago, and now that they are living in the fear of going out of business they may have gotten a better customer-service ethic.  

The geocoders from Google and Yahoo can also provide data verification.  You might want to check the terms of use carefully.  IIRC the Google geocoder must be used in conjunction with a Google Map, or you have to pay a fee for its commercial use.  Here is demonstration script showing how I have used the Google and Yahoo geocoders.  These technologies are changing under the covers of the services that provide them, so you may find new APIs or new data returned from the API.  It appears at this moment that the Yahoo service is down.  However it may be disabled since the V1 interface has been deprecated.  The new Yahoo service is called PlaceFinder and it is not integrated into my example here.

Testing this address which does not exist, you will see that Google tries to give a geocode and returns a precision of "6"
http://www.laprbass.com/RAY_geocoder.php?a=7520+Colleen+Lane&c=McLean&s=VA&z=22101

Testing this address which does exist, you get a precision of "8"
http://www.laprbass.com/RAY_geocoder.php?a=1446+Colleen+Lane&c=McLean&s=VA&z=22101

Using the new Yahoo PlaceFinder, you can see the results here:
Valid http://where.yahooapis.com/geocode?q=1446+Colleen+Lane,McLean,VA,22101
Bogus http://where.yahooapis.com/geocode?q=7520+Colleen+Lane,McLean,VA,22101

More info: http://developer.yahoo.com/geo/placefinder/

These services try to be helpful by guessing at what you mean if the address is not completely valid, so you may need to do some additional programming to compare your input to their response and see if the results make sense.  Note the address returned by the bogus call to the PlaceFinder!

HTH, ~Ray
<?php // RAY_geocoder.php
error_reporting(E_ALL);


// DEMONSTRATE HOW TO CALL THE YAHOO! AND GOOGLE GEOCODERS


// A NOMINAL DATA CLEAN-UP FUNCTION
function get_clean_text_string($s)
{
    return preg_replace('/[^A-Z 0-9_\.,\-#]/i', NULL, $s);
}


// API KEYS MAY BE REQUIRED
require_once('RAY_live_data.php');


// A FREEFORM LOCATION STATEMENT IS OPTIONAL (BUT NOT USED HERE)
$location = $a = $c = $s = $z = NULL;

// THESE ARE THE GET-FORM VARIABLES
$vars = array( 'a', 'c', 's', 'z' );

// FILTER THE ARGUMENTS
if (!empty($_GET))
{
    foreach ($_GET as $k => $v)
    {
        if (!in_array($k, $vars)) continue;
        $$k = get_clean_text_string($v);
    }
    if ($a != NULL) { $location .= $a . ' '; }
    if ($c != NULL) { $location .= $c . ' '; }
    if ($s != NULL) { $location .= $s . ' '; }
    if ($z != NULL) { $location .= $z . ' '; }
    $location = trim($location);
}

// PREPARE THE FORM
$form = <<<ENDFORM
<doctype html>
<head>
<title>$a $c $s $z Yahoo/Google Geocoder Query</title>
</head>
<body>
<form method="get">
Addr: <input type="text" name="a" autocomplete="off" value="$a" />
City: <input type="text" name="c" autocomplete="off" value="$c" />
ST:   <input type="text" name="s" autocomplete="off" value="$s" size="2" />
Zip:  <input type="text" name="z" autocomplete="off" value="$z" size="8" />
<input type="submit" value="Go" />
</form>
</body>
</html>
ENDFORM;

if (!$location)
{
    echo $form;
    die();
}


// PREPARE THE GEOCODER
$y_demo       = new SimpleGeoCoder;
$y_demo->address = $a;
$y_demo->city    = $c;
$y_demo->state   = $s;
$y_demo->zip     = $z;

// TEST THE YAHOO! GEOCODER
$y_demo->geocodeYahoo();
echo "<pre>";
echo PHP_EOL;
echo "YAHOO! DATA FOR <strong>$location</strong>";
echo PHP_EOL;
print_r($y_demo);
echo "</pre>";



// PREPARE THE GEOCODER
$g_demo        = new SimpleGeoCoder;
$g_demo->address  = $a;
$g_demo->city     = $c;
$g_demo->state    = $s;
$g_demo->zip      = $z;

// TEST THE GOOGLE GEOCODER
$g_demo->geocodeGoogle();
echo "<pre>";
echo PHP_EOL;
echo "GOOGLE DATA FOR <strong>$location</strong>";
echo PHP_EOL;
print_r($g_demo);
echo "</pre>";


// ALL DONE
echo $form;
die();



// SIMPLE GEOCODER CLASS
class SimpleGeoCoder
{

    // DECLARE THE INPUT DATA
    public $location; // USE THIS FOR A FREEFORM QUERY, OR USE THESE PARTS
    public $address;
    public $city;
    public $state;
    public $zip;

    // DECLARE THE WORKING DATA
    private $precis; // TEXTUAL PRECISION FROM YAHOO
    private $yfp, $yahooUrl,  $yahooResponse,  $ydata;
    private $gfp, $googleUrl, $googleResponse, $gdata;

    // DECLARE THE OUTPUT DATA
    public $latitude;
    public $longitude;
    public $precision;
    public $warning;
    public $geocoder;

    // DECLARE THE CONSTRUCTOR
    public function __construct()
    {
        $this->latitude  = 0.0;
        $this->longitude = 0.0;
        $this->precision = FALSE; // WANT A VALUE OF 5 OR HIGHER, HIGHER IS BETTER
        $this->warning   = '';
        $this->geocoder  = '';
    }


    // DECLARE THE YAHOO! VERSION OF THE WORKHORSE
    public function geocodeYahoo()
    {
        $this->geocoder = 'Yahoo!';
        $yahooUrl       = "http://local.yahooapis.com/MapsService/V1/geocode?&appid=";
        if (defined("YAHOO_API"))
        {
            $yahooUrl .= YAHOO_API;
        }

        // YOU CAN ASK FOR A FREEFORM QUERY
        if ($this->location != '')
        {
            $yahooUrl .= "&location=" . urlencode($this->location);
        }

        // YOU CAN ASK FOR INDIVIDUAL PIECES OF AN ADDRESS
        else
        {
            $yahooUrl .= "&street=" . urlencode($this->address);
            $yahooUrl .= "&city="   . urlencode($this->city);
            $yahooUrl .= "&state="  . urlencode($this->state);
            $yahooUrl .= "&zip="    . urlencode($this->zip);
        }

        // EXECUTE YAHOO GEOCODER QUERY
        // NOTE - USE ERROR SUPPRESSION OR IT WILL BARK OUT THE YAHOO API KEY - ON FAILURE RETURNS HTTP 400 BAD REQUEST
        if ($yfp = @fopen($yahooUrl, 'r'))
        {
            $yahooResponse = '';
            while (!feof($yfp)) { $yahooResponse .= fgets($yfp); }
            fclose($yfp);
        }
        else
        {
            return FALSE;
        }

        // EXAMINE THE RESULT
        if ($yahooResponse != '') // NOT EMPTY, WE GOT DATA
        {
            $ydata    = new SimpleXMLElement($yahooResponse);

            // CHECK FOR ANY ERROR MESSAGE, IF NONE, EXTRACT THE DATA POINTS
            $y_err    = $ydata->Message;
            if ($y_err == '')
            {
                $this->precis    = $ydata->Result["precision"];
                $this->warning   = $ydata->Result["warning"];
                $this->latitude  = $ydata->Result->Latitude;
                $this->longitude = $ydata->Result->Longitude;
                $this->address   = $ydata->Result->Address;
                $this->city      = $ydata->Result->City;
                $this->state     = $ydata->Result->State;
                $this->zip       = $ydata->Result->Zip;

                // SET PRECISION TO A NUMBER VALUE
                if ($this->precis == 'zip')     { $this->precision = "5"; }
                if ($this->precis == 'street')  { $this->precision = "6"; }
                if ($this->precis == 'address') { $this->precision = "8"; }
            }
            else
            {
                return FALSE;
            }
        }

        // NO RESULT - SOMETHING IS SICK AT YAHOO
        else
        {
            return FALSE;
        }
        return TRUE;
    } // END function geocodeYahoo



    // DECLARE THE GOOGLE VERSION OF THE WORKHORSE
    public function geocodeGoogle()
    {
        $this->geocoder = 'Google';
        $googleUrl      = "http://maps.google.com/maps/geo?output=csv";
        if (defined("GOOGLE_API"))
        {
            $googleUrl .= "&key=" . GOOGLE_API;
        }

        // YOU CAN ASK FOR A FREEFORM QUERY
        if ($this->location != '')
        {
            $googleUrl .= "&q=" . urlencode($this->location);
        }

        // YOU CAN ASK FOR INDIVIDUAL PIECES OF AN ADDRESS
        else
        {
            $googleUrl .= "&q=" . urlencode(trim($this->address .' '. $this->city .' '. $this->state .' '. $this->zip));
        }

        // EXECUTE GOOGLE GEOCODER QUERY
        if ($gfp = @fopen($googleUrl, 'r'))
        {
            $googleResponse = '';
            while (!feof($gfp)) { $googleResponse .= fgets($gfp); }
            fclose($gfp);
        }
        else
        {
            return FALSE;
        }

        // EXTRACT THE DATA
        $gdata    = explode(',',$googleResponse);

        // RESPONSE CODE SHOULD BE '200' -- IF 602 - BAD ZIP CODE OR UNUSABLE ADDRESS
        if ($gdata[0] != '200')
        {
            return FALSE;
        }

        // GEOCODE ACCURACY - ZIP CODE = 5, HIGHER NUMBERS ARE BETTER
        $this->precision = $gdata[1];
        $this->latitude  = $gdata[2];
        $this->longitude = $gdata[3];
        return TRUE;
    } // END function geocodeGoogle

} // END class SimpleGeocoder

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of smetterd
smetterd
Flag of United States of America image

ASKER

Sorry it took so long to respond. My acct was inadvertently held due to credit card expiration. Thank you!
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Thanks for the points - it's a great question, ~Ray
Software
Software

Software is any set of instructions that directs a computer to perform specific tasks or operations. Computer software consists of programs, libraries and related non-executable data (such as documentation). Computer software is non-tangible, contrasted with computer hardware, which is the physical component of computers. Software written in a machine language is known as "machine code". However, in practice, software is usually written in high-level programming languages than machine language. High-level languages are translated into machine language using a compiler or interpreter or a combination of the two.

43K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo