Classic ASP Class for Yahoo! Placefinder





5.00/5 (2 votes)
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.
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
'' 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:
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...
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:
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:
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