About This Code
Brief Description:
Geocoding class in Lotusscript
Contributor:
Karl-Henry Martinsson
Last Modified:
13 Jul 2009
OpenNTF Disclaimer
All of the program code and information presented in the OpenNTF.org Code Bin are provided "as-is", and should be used at your own risk. OpenNTF.org make no express or implied warranty about anything in the Code Bin, and OpenNTF.org will not be responsible or liable for any damage caused by the use or misuse of anything from this site. OpenNTF.org makes no guarantees about anything. Please thoroughly test all of the knowledge and code you find here before you attempt to use them in your production environment.
Code / Description
This Lotusscript class is using the Google REST API for geocoding an address.
You simply instantiate the class by passing the address broken down into four arguments (street, city, state, zip). If you lack data, pass an empty string.
Note: The code is currently written for US addresses.
The class will submit the address to Google and get information back. The class exposes the same information you sent (street, city, state and zip) as well as latitude and longitude and "accuracy", a number describing how accurate the latitude/longitude is (street level, intersection, city, etc).
The class can be used not only to retrieve the latitude and longitude for a location, but also to verify that a particular address exists, or look up the zip code based on the street, city and state.
Simply take the code in GeoCode.txt and paste it into a (new) script library. I call it Class.GeoCode. Then you can use it everywhere you like.
I am working on an updated/expanded version that will let you generate KML data for Google Maps/Google Earth as well.
Usage / Example
Example 1.
This will simply display the data returned in a message box.
Dim geodata As GeoData
Set geodata = New GeoData("6363 North State Highway 161", "Irving", "tx", "")
If geodata.IsValid Then
Msgbox geodata.Street & Chr$(13) & geodata.City & ", " & geodata.State & " " & geodata.ZIP,, _ "Accuracy = " & geodata.Accuracy
Msgbox "Lat: " & geodata.Latitude & " Longitude: " & geodata.Longitude
End If
Example 2.
This is code you can put in a button on a form. It reads a number of fields containing address info, call the GeoCode class, and then update the address fields with the data return by the class.
Dim ws As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim geodata As GeoData
Dim streetStr As String
Dim cityStr As String
Dim stateStr As String
Dim zipStr As String
Dim ret As Integer
Set uidoc = ws.CurrentDocument
streetStr = uidoc.FieldGetText("Address")
cityStr = uidoc.FieldGetText("City")
stateStr = uidoc.FieldGetText("State")
zipStr = uidoc.FieldGetText("ZIP")
Set geodata = New GeoData(streetStr, cityStr, stateStr, zipStr)
If geodata.HasAddInfo(streetStr) Then
ret = Msgbox("Possible apartment/suit detected. Value may get overwritten." & Chr$(13) & Chr$(13) & _
"Original address:" & Chr$(13) & StreetStr & Chr$(13) & CityStr & ", " & StateStr & " " & ZipStr & _
Chr$(13) & Chr$(13) & "Address returned by Google:" & Chr$(13) & geodata.Street & Chr$(13) & _
geodata.City & ", " & geodata.State & " " & geodata.ZIP & Chr$(13) & Chr$(13) & _
"Do you want to use this new address?",4+16,"Verify Address")
If ret = 7 Then
Exit Sub
End If
Else
If streetStr<>geodata.Street Or cityStr<>geodata.City Or stateStr<>geodata.State Or zipStr<>geodata.ZIP Then
ret = Msgbox("Original address:" & Chr$(13) & StreetStr & Chr$(13) & CityStr & ", " & StateStr & " " & ZipStr & _
Chr$(13) & Chr$(13) & "Address returned by Google:" & Chr$(13) & geodata.Street & Chr$(13) & geodata.City & _
", " & geodata.State & " " & geodata.ZIP & Chr$(13) & Chr$(13) &
"Do you want to use this new address?",4+32,"Verify Address")
If ret = 7 Then
Exit Sub
End If
End If
End If
Call uidoc.FieldSetText("Address", geodata.Street)
Call uidoc.FieldSetText("City", geodata.City)
Call uidoc.FieldSetText("State", geodata.State)
Call uidoc.FieldSetText("ZIP", geodata.ZIP)
Call uidoc.FieldSetText("Latitude", geodata.Latitude)
Call uidoc.FieldSetText("Longitude", geodata.Longitude)
Code Attachments
Comments
Posted by Dwight Wilbanks on 07/13/2009 04:08:08 PMNice work
I built a similar one a while back that was less polished than your,
I didn't know that Deloitte & Touche has an office there.
Posted by Karl-Henry Martinsson on 07/13/2009 04:26:47 PMThanks!
I enjoy building these kind of small classes than I can then share with the community. :-)
I notice however that there are 4 copies of this code, due to me doing some editing and cleaning up. Will ask someone to remove the duplicates.
Posted by Joseph LeMay on 08/20/2009 09:43:28 AMReplace word
it wouldn't compile for me at first; it choked on the line.
Private Function R5strReplace(mystring As String, search As String, replace As String) As String
it had a problem with the word "replace" which is a lotusscript function. I changed it to "replaceMe" both there and in the function below, and it compiled.
Posted by Joseph LeMay on 08/20/2009 12:24:29 PMbut it works great
it probably saved me close to one man-day of coding. we probably just wouldn't have bothered using google maps if not for this readily-available class.
here's a button to load a static map.
Dim w As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim geodata As GeoData
Dim officeStreetAddress As String
Dim fullStreetAddress As String
Dim officeCity As String
Dim officeState As String
Dim officeZip As String
Dim mapsURL As String
Dim encodedStreetAddress As String
Dim i As Integer
Set uidoc = w.CurrentDocument
officeStreetAddress = uidoc.FieldGetText("OfficeStreetAddress")
officeCity = uidoc.FieldGetText("OfficeCity")
officeState = Left(uidoc.FieldGetText("OfficeState"),2)
officeZip = uidoc.FieldGetText("OfficeZip")
Set geodata = New GeoData(officeStreetAddress,officeCity, officeState, officeZip)
If geodata.IsValid Then
mapsURL = "http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q="
fullStreetAddress = officeStreetAddress + " " + officeCity + " " + officeState + " " + officeZip
encodedStreetAddress = ""
For i = 1 To Len(fullStreetAddress)
If Mid$(fullStreetAddress, i,1) = " " Then
encodedStreetAddress = encodedStreetAddress + "+"
Else
encodedStreetAddress = encodedStreetAddress + Mid$(fullStreetAddress, i,1)
End If
Next
mapsURL = mapsURL + encodedStreetAddress + "&sll=" + geodata.Latitude + "," + geodata.Longitude + "ie=UTF8&z=16&iwloc=A"
Call w.URLOpen(mapsURL)
Else
Messagebox "Google maps API did not return valid GeoData.",0,"Sorry"
End If
Posted by Tim Nolan on 10/16/2009 10:57:24 AMAPI Key
What did you enter for the URL when generating an API key to use the code from the Notes Client?
Posted by Karl-Henry Martinsson on 10/16/2009 11:44:07 AMAPI key
I used the main URL/domain for the company website. Worked for me. YMMV.
Posted by Dwight Wilbanks on 10/16/2009 12:45:09 PMAbout the API Key
When I was playing around with this, (some time ago), the Key was only needed when you sent a referer (like if it was comming from a web page directly) When you use the ServerXMLHTTP, your sending an initial request without a corrosponding web page (home) so it did not need that parameter at all. When you use the functions from javascript withing a web page you do need a key and you can request it from google.
Posted by Joseph LeMay on 10/16/2009 04:40:38 PMI just got a maps key from google
sign up here
http://code.google.com/apis/maps/signup.html to get a key from google.
then paste the key you get into the class like I did below.
mapsKey = "ABQIAAAArI_h1z3RSwiFp1Jyg42CNBTE_U-ZX0WZyUy1yxJZ4bxm576ybRQSNcehTs65H8VKbb6-Q"
don' t use the key pasted above because I changed some letters.
Posted by Tim Nolan on 10/16/2009 05:45:54 PMI got it to work.
I changed the code to use "MSXML2.XMLHTTP" instead of "MSXML2.ServerXMLHTTP" and it worked fine.
Thanks for all of the responses.