There's nothing that makes you so aware of the improvisation of human existence as a song unfinished. Or an old address book. - Carson McCullers
In Part 1 I showed you how to get started with the MapQuest Advantage API by getting a developer key. In Part 2 I put that key to use by providing access to a basic map in the Map It! widget. Part 3 showed you how to incorporate basic geocoding. In Part 4 I discussed more advanced geocoding topics - including handling multiple matches and specifying geocode search options. Part 5 discussed adding widget options including the default zoom level, specifying point of interest icons, and the default map type. Part 6 discussed how to add direction capabilities to the widget. In this final installment I'll talk about how easy it is to integrate address searching with the Mac OS X Address Book application.
Address Book Searching
The Mac OS X Address Book application is bundled with the OS X operating system, providing a way for users to organize their contacts and associated information including their addresses. Also included with Mac OS X is an Address Book widget, which provides access to the Address Book database from a widget. I've explored the Address Book widget code, and extracted the AddressBookPlugIn. Plug-ins are native code that can be used to access operating system levels features from a widget's JavaScript interface.
Listing 1 demonstrates how I've modified the address parsing method. If an address is entered that does not match one of the pre-defined formats I will assume that it's a name to retrieve from the Address Book. The address book is searched for the name with the best match. Then the street, city, state, and zip code are retrieved from the best match. The retrieved address is then parsed as discussed in Part 3!
Listing 1 - Retrieving From the Address Book
function onAddressSearch(event)
{
// user hit a return?
if(event.keyCode == 13) {
if(!$(address).value.blank()) {
var street = "";
var city = "";
var state = "";
var zip = "";
var country = "";
$(lblErrorMsg).innerText = "";
$(multMatches).style.visibility = "hidden";
$(lblMultMatch).style.visibility = "hidden";
var splitAddr = $(address).value.split(',');
// if we only get 2 elements assume address, zip
if(splitAddr.length == 2) {
street = splitAddr[0];
zip = splitAddr[1];
// for three elements assume address, city, state
} else if(splitAddr.length == 3) {
street = splitAddr[0];
city = splitAddr[1];
state = splitAddr[2];
// for 4 elements assume address, city, state, zip
} else if(splitAddr.length == 4) {
street = splitAddr[0];
city = splitAddr[1];
state = splitAddr[2];
zip = splitAddr[3];
// for 5 elements assume address, city, state, zip, country
} else if(splitAddr.length == 5) {
street = splitAddr[0];
city = splitAddr[1];
state = splitAddr[2];
zip = splitAddr[3];
country = splitAddr[4];
} else {
// otherwise assume it's a name to look up in the Address Book
AddressBookPlugin.searchForStringWithBestMatch($(address).value);
// retrieve the values from the address book
street = AddressBookPlugin.displayedValueAtIndex(7);
city = AddressBookPlugin.displayedValueAtIndex(8)
state = AddressBookPlugin.displayedValueAtIndex(9);
zip = AddressBookPlugin.displayedValueAtIndex(10);
}
var result = widget.system('java -classpath .:mq.jar GetLocations
-street "' + street + '" -city "' + city + '" -state "' + state +
'" -zip "' + zip + '" -country "' +country + '"',null).outputString;
// any errors?
if(result == "ERROR") {
$(lblErrorMsg).innerText = "Error! Unknown Address Format!";
// address not found?
} else if (result == "NOT FOUND") {
$(lblErrorMsg).innerText = "Address Was Not Found!";
} else {
// split on return - a line is printed for each individual result
var eachresult = result.split('\n');
// just one result returned? - then just plot the point -
// there are two extra returns so 3 really means 1 item
if(eachresult.length == 3) {
// get the coordinates from the returned string
var coords = eachresult[0].split('|');
// create a new point based on the coordinates
newCenter = new MQLatLng(parseFloat(coords[0]),parseFloat(coords[1]));
//create a new icon object
myIcon = new MQMapIcon();
// set the icon image: icon file location, width, height, recalc infowindow offset,
// is it a PNG image?
if(defIcon == "pin") {
myIcon.setImage("images/pinpoint_red.gif",32,32,true,false);
} else if(defIcon == "star") {
myIcon.setImage("images/starsmall_red",18,18,true,false);
} else if(defIcon == "x") {
myIcon.setImage("images/xspot.gif",17,17,true,false);
}
// create a point
myPoint = new MQPoi(newCenter);
// set the custom icon
myPoint.setIcon(myIcon);
// recenter the map on the point,
// the second parameter specifies the zoom level
myMap.setCenter(newCenter,defZoom);
// add the point as a Point of Interest
myMap.addPoi(myPoint);
} else {
// clear out existing items
$(multMatches).options.length = 0;
for(var i=0; i < eachresult.length; i++) {
// parse each returned location
var location = eachresult[i].split('|');
// 7 items on the result line?
if(location.length == 7) {
var locationtext = location[2] + "," + location[3] + "," + location[4] + "," + location[5] + "," + location[6];
var objNewOption = document.createElement("OPTION");
$(multMatches).options.add(objNewOption);
// add the location text
objNewOption.text = locationtext;
// add the coordinates as a | separate string to the value...
objNewOption.value = location[0] + '|' + location[1];
}
}
// show the label and combo box...
$(multMatches).style.visibility = "visible";
$(lblMultMatch).style.visibility = "visible";
}
}
}
}
}
Conclusion
For your reference, here are some references for the MapQuest Platform:
