Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VBScript

Classic ASP Class for Yahoo! Placefinder

5.00/5 (2 votes)
7 Mar 2012CDDL3 min read 26.1K   312  
A VBScript class for calling Yahoo!'s Placefinder for geocoding

Introduction 

Ever need to make pushpin maps of customers or store locations? Before you even build a map, you need to geocode the address information. Geocoding is the process of converting text address like 123 North Burgundy Street, Chicago, IL into longitude and latitude points that specify the pinpoint on a map grid. For years, this was a costly process involving third party GIS applications, quarterly data updates, and a high degree of IT expertise to keep things running. Thanks to services like Yahoo! Placefinder, you can geocode up to 5,000 addresses each day for free!

Background

Before you get started, you need to apply for an application ID from Yahoo! Placefinder. You can get the AppID here: http://developer.yahoo.com/geo/placefinder/. Paste the app ID you receive from Yahoo! in the Class_Initialize section of the class. The class itself is very simple. The next section shows just how easy it is.

Using the code

Paste the class code below into your application. To call the geocoder, first create an instance of the class, then you make a call to the geocoder.

VBScript
dim ygeo
dim lon
dim lat 

set ygeo = new YGeoCoder
call ygeo.Geocode( address, city, state, zip )
'' now you can get the longitude and latitude from the object
if ygeo.iserror = false then 
   lon = ygeo.longitude
   lat = ygeo.latitude
end if
'' That's it! 

The following properties are populated from the geocoder results after making a call to Geocode:

  • street - The street address passed; it may be corrected by Yahoo! geocoder and expressed in short-hand.
  • city - The city found upon geocoding (if only street address and zip are passed to the geocode request).
  • state- The state found upon geocoding (if only street address and zip are passed to the geocode request).
  • zip - The zip code found (if only street address, city, and state are passed to the geocode request).
  • latitude - the latitude portion of the geocoded address.
  • longitude - the longitude portion of the geocoded address.
  • country - the country of the geocoded address.
  • xml - the XML data returned from Yahoo! placefinder.
  • reason - if the geocode request fails, this will contain the reason.

The Code

VBScript
'' YGeoCoder class
'' by Larry Boeldt
'' (C) 2010 Larry Boeldt
'' 
'***************************************************************************
' Copyright 2010 Larry Boeldt 
' Class: YGeoCoder  Version 1.0    11:11 AM Sunday, June 27, 2010
' Author: Larry Boeldt 
' Terms: 
' GPL, commercial license available
'
' Properties(s):
'   
'
' Methods:
'   Geocode( address, city, state, zip )
'
' Description:
' A class that wraps most of the functionality of yahoo geocoder. 
'
' Setup Instructions:
' Get your appid here: <a href="https://developer.apps.yahoo.com/wsregapp/">https://developer.apps.yahoo.com/wsregapp/</a>
' Copy and paste the licence code in the appid="" assignment 
' in class_initialize.
'***************************************************************************
class YGeoCoder
    private appid
    private m_street
    private m_city
    private m_state
    private m_zip
    private m_lon
    private m_lat
    private m_precision
    private m_country
    private m_xml
    private m_reason
    private m_output
    private m_url
    
 '***************************************************************************
 ' Copyright 2010 Larry Boeldt 
 ' Function:  class_initialize Version 1.0    11:11 AM Sunday, June 27, 2010
 ' Author: Larry Boeldt
 ' Terms: 
 ' GPL, commercial license available
 '
 ' Parameter(s):
 '   none
 '
 ' Return Value:
 '   none
 '
 ' Description:
 ' Initialize the class object with default values. 
 ' Remember to sign up for your yahooappid and paste it below
 '***************************************************************************
    sub class_initialize()
       '' Get your appid here: https://developer.apps.yahoo.com/wsregapp/
       '' copy and paste your app id below
        appid=""
        m_output = "xml"
    end sub
    property get output()
        output = m_output
    end property
    
    property get url()
        url = m_url
    end property
    property let output(value)
        if value="php" or value="xml" then 
            m_output=value
        else
            m_output = "xml"
        end if    
    end property    
    
    property get lon()
        lon = m_lon
    end property
    property get lat()
        lat = m_lat
    end property
    
    property get city()
        city = m_city
    end property
    
    property get state()
        state = m_state
    end property
    
    property get zip()
        zip = m_zip
    end property
    
    property get country()
        country = m_country
    end property
    property get precision()
        precision = m_precision
    end property
    
    property get address()
        address=m_street
    end property
    
    property get street()
        street = m_street
    end property
    
    
    property get xml()
        xml = m_xml
    end property
    
    property get reason()
        reason = m_reason
    end property
    
 
 '***************************************************************************
 ' Copyright 2010 Larry Boeldt 
 ' Function:  GetPrecision Version 1.0    11:11 AM Sunday, June 27, 2010
 ' Author: Larry Boeldt
 ' Terms: 
 ' GPL, commercial license available
 '
 ' Parameter(s):
 '   Doc XML Document from Yahoo
 '
 ' Return Value:
 '   Precision value from yahoo
 '
 ' Description:
 ' Get the precision value returned by yahoo
 '
 '***************************************************************************
    function GetPrecision( doc )
        Dim node
        dim value
        set node=doc.documentElement.selectSingleNode( "/ResultSet/Result" )
        if node is nothing then 
            value = "none" 
        else
            value = node.GetAttribute( "precision" )
        end if 
        set node = nothing
        
        GetPrecision = value
    end function
 '***************************************************************************
 ' Copyright 2010 Larry Boeldt 
 ' Function:  GetXMLValue Version 1.0    11:11 AM Sunday, June 27, 2010
 ' Author: Larry Boeldt
 ' Terms: 
 ' GPL, commercial license available
 '
 ' Parameter(s):
 '   Doc  XML Document from Yahoo
 ' name the tag name/value you want to retrieve
 ' Return Value:
 '   Value of specified tag or blank string
 '
 ' Description:
 ' Get one of the address return values from the yahoo XML
 '
 '***************************************************************************    
    function GetXMLValue( doc, name )
        Dim node
        dim value
        if left(name,1) = "/" then 
           '' get a custom node
           set node=doc.documentElement.selectSingleNode( name )
        else 
           '' get by name from default location
           set node=doc.documentElement.selectSingleNode("/ResultSet/Result/" & name )
        end if
        if node is nothing then 
            value = "" 
        else
            value = node.text
        end if 
        set node = nothing
        GetXMLValue = value
    end function
 '***************************************************************************
 ' Copyright 2010 Larry Boeldt 
 ' Function:  Geocode Version 1.0    11:11 AM Sunday, June 27, 2010
 ' Author: Larry Boeldt
 ' Terms: 
 ' GPL, commercial license available
 '
 ' Parameter(s):
 '   street street address to geocode
 ' city   city name to geocode
 ' state   state to geoocde
 ' zip    zip code/postal code to geocode
 '
 ' Return Value:
 '   none
 '
 ' Description:
 ' Call the Yahoo geocoder with the given address information.
 '
 '***************************************************************************
    function geocode( street, city, state, zip )
        dim url
        Dim doc
        output = m_output
        
        Set doc=CreateObject("Microsoft.XMLDOM") 
        doc.async=false 
        call doc.setProperty("ServerHTTPRequest",true)
        url="http://local.yahooapis.com/MapsService/V1/geocode" & _
            "?appid=" & appid & _
            "&street=" & street & _
            "&city=" & city & _
            "&state=" & state & _
            "&zip=" & zip & _
            "&output=" & output 
        m_url = url
        doc.load( url )
        '' Blank out the property values to defaults before continuing
        m_lat = 0.0
        m_lon = 0.0
        m_street = ""
        m_city = ""
        m_state = ""
        m_zip = ""
        m_country = ""
        m_xml = "not loaded"
        m_precision = "failed"
        
        '' Check if there was an error getting the document from yahoo

        if doc.parseError.errorcode=0 then
            '' Now check if we have a YAHOO error
            if isError( doc ) = true then
                m_reason = GetXMLValue( doc, "/Error/Message" )
            else
                ' proceed
                m_precision = GetPrecision( doc )
                m_lat = GetXMLValue( doc, "Latitude" )
                m_lon = GetXMLValue( doc, "Longitude" )
                m_street = GetXMLValue( doc, "Address" )
                m_city = GetXMLValue( doc, "City" )
                m_state = GetXMLValue( doc, "State" )
                m_zip = GetXMLValue( doc, "Zip" )
                m_country = GetXMLValue( doc, "Country" )
                m_reason = ""
            end if
            m_xml = doc.xml
        else 
            m_reason = doc.parseError.reason & " line: " & doc.parseError.line
            m_xml = doc.text
            '' Error code here
        end if
        set doc = nothing
    end function
 '***************************************************************************
 ' Copyright 2010 Larry Boeldt 
 ' Function:  isError Version 1.0    11:11 AM Sunday, June 27, 2010
 ' Author: Larry Boeldt
 ' Terms: 
 ' GPL, commercial license available
 '
 ' Parameter(s):
 '   Doc XML Document from Yahoo
 '
 ' Return Value:
 '   True if document is a Yahoo! Error document
 ' False if document is a valid data packet from yahoo
 '
 ' Description:
 ' Determine if returned documen is a Yahoo error document
 '
 '***************************************************************************
    function isError( doc )
        dim bResult
        
        if GetXMLValue( doc, "/Error/Message" ) = "" then 
            bResult = false
        else
            bResult = true
        end if
        
    end function
end class '' YGeocoder

How It Works

The Geocode function is the main workhorse in the class; it does the work of assembling a URL and making an HTTP GET call to the Yahoo! Placefinder service. Here is the code segment that does the job; I've added comments to each line describing what it does:

VBScript
Set doc=CreateObject("Microsoft.XMLDOM")  '' Create a XML Dom object
doc.async=false '' we will make a syncronus call meaning the object will wait for a response

'' This part is important if you want to call within an ASP page
call doc.setProperty("ServerHTTPRequest",true) 

'' Assemble the URL with the parameters passed in the geocode call
url="<a href="http://local.yahooapis.com/MapsService/V1/geocode">http://local.yahooapis.com/MapsService/V1/geocode</a>" & _
    "?appid=" & appid & _
    "&street=" & street & _
    "&city=" & city & _
    "&state=" & state & _
    "&zip=" & zip & _
    "&output=" & output 
'' Set a global property m_url with the url string (for debugging purposes)
m_url = url
'' Now make the call to yahoo geocoder service using the assembled URL

doc.load( url )

The doc object will now contain the XML response from Yahoo!'s Web Service. To populate the object properties, I parse the XML document, looking for each desired property value. To make this an easy task, I use a utility function GetXMLValue that takes as parameters the document object and the name of the return tag whose value I want to capture. You'll see this as a series of calls that look like this...

VBScript
m_lat = GetXMLValue( doc, "Latitude" )

In the example above, I get the latitude value and assign it to m_lat. This is exposed to your calling code as the property .lat in your ygeo object. This practice might seem redundant, but it is the proper object oriented technique for dealing with classes. The following code segment illustrates how the property is created:

VBScript
property get lat()
    lat = m_lat
end property 

The GetXMLValue function is a shortcut way to get the desired properties. Below you will find the full function, with line by line comments that describe what each line is doing:

VBScript
function GetXMLValue( doc, name )

    Dim node   '' Placeholder for an XML Node object
    dim value  '' The value as parsed from the XML node, this is the return value

    '' To facilitate "shortcuts" for the specific yahoo code values the following
    '' If then statement is used
    if left(name,1) = "/" then '' Check if a custom node request is made
       '' get a custom node
       set node=doc.documentElement.selectSingleNode( name )
    else 
       '' Custom node request was not found, get by name from default location
       set node=doc.documentElement.selectSingleNode("/ResultSet/Result/" & name )
    end if

    '' If the node is nothing (not found) then return a blank value
    if node is nothing then 
        value = "" 
    else
        '' Then node has been found, return the text within the tags of the node
        value = node.text
    end if 
    '' Clean up by setting the node to nothing

    set node = nothing

    '' Return the value of the node (or blank if not found)
    GetXMLValue = value
end function

That covers the main set of functions that make this class work. There are two more functions worth noting: isError and GetPrecision. Each takes the XML document object as a parameter and returns a value based on what is found in the XML. isError returns true if Yahoo! Place Finder could not geocode the address for some reason (for example, if you passed all blank values). The GetPrecision function returns Yahoo's precision value which indicates whether the longitude and latitude values are from the 'address', 'zip', or 'city' depending on how accurately your address information could be matched. In the case of zip and city, the "centroid" value is provided. The centroid in most cases is the geographic center of the city or the zip code's tabulated area.

History

  • 2010/09/06 - Initial article post
  • 2012/03/06 - Updated code for revised API

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)