Geo!Suggest
Geo!Suggest = Yahoo Geocoding API + AJAXSource Code::./yahoo.geocode.php
<?php
/**
* Geo!Suggest
*
* @package Geo!Suggest
* @version 1.0
*
* This is a main Geo!Suggest script - it used to render user interface.
* The main responsibility for this script is communication with service.yahoo.geocode.php through the AJAX calls
* fetching geocoding results and dynamical user interface creating.
*
* History
* 11/12/2005 A. Bidochko
* - Created.
*/
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<meta name="title" content="Geo!Suggest" />
<meta name="description" content="Geo!Suggest - Yahoo Geocoder's AJAX Interface" />
<meta name="keywords" content="Yahoo, Geocoding, MapBuilder.net" />
<meta name="author" content="Andrew Bidochko" />
<title>Geo!Suggest</title>
<style type="text/css">
#MapBuilderIW { width: 200px; height: 200px;}
</style>
<script type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=2.0&appid=mapbuilder.net"></script>
<script type="text/javascript">
// Global storage for Location objects
var MBLocations = new Array();
// Storage for map object
var map;
// MapBuilder.net: Location Definition Class
function MBLocation (Latitude, Longitude, Address, City, State, Zip, Country) {
this.Latitude = Latitude;
this.Longitude = Longitude;
this.Address = Address;
this.City = City;
this.State = State;
this.Zip = Zip;
this.Country = Country;
// Create well formatted location address
this.GetAddress = function() {
var addressItem = '';
if (this.Address != '') {
addressItem = this.Address;
}
if (this.City != '') {
addressItem = (addressItem=='') ? this.City : addressItem + ", " + this.City;
}
if (this != '') {
addressItem = (addressItem=='') ? this.State : addressItem + ", " + this.State;
}
if (this.Zip != '') {
addressItem = (addressItem=='') ? this.Zip : addressItem + ", " + this.Zip;
}
if (this.Country != '') {
addressItem = (addressItem=='') ? this.Country : addressItem + ", " + this.Country;
}
return addressItem;
}
}
// global flag
var isIE = false;
// global request and XML document objects
var req;
// retrieve XML document (reusable generic function);
// parameter is URL string (relative or complete) to
// an .xml file whose Content-Type is a valid XML
// type, such as text/xml; XML source must be from
// same domain as HTML file
function loadXMLDoc(url) {
// branch for native XMLHttpRequest object
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send(null);
// branch for IE/Windows ActiveX version
}
else if (window.ActiveXObject) {
isIE = true;
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send();
}
}
}
// handle onreadystatechange event of req object
function processReqChange() {
// only if req shows "loaded"
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200) {
clearAll();
buildGeoSuggestList();
// Enable address
document.LocationSearchForm.LocationSearch.removeAttribute("readonly");
}
else {
alert("There was a problem retrieving the XML data:\n" +
req.statusText);
// Enable address
document.LocationSearchForm.LocationSearch.removeAttribute("readonly");
}
}
}
// Retrieve text of an XML document element, including elements using namespaces
function getElementTextNS(prefix, local, parentElem, index) {
var result = "";
if (prefix && isIE) {
// IE/Windows way of handling namespaces
result = parentElem.getElementsByTagName(prefix + ":" + local)[index];
}
else {
// the namespace versions of this method
// (getElementsByTagNameNS()) operate
// differently in Safari and Mozilla, but both
// return value with just local name, provided
// there aren't conflicts with non-namespace element
// names
result = parentElem.getElementsByTagName(local)[index];
}
if (result) {
// get text, accounting for possible
// whitespace (carriage return) text nodes
if (result.childNodes.length > 1) {
return result.childNodes[1].nodeValue;
} else {
if (result.firstChild == null) return '';
return result.firstChild.nodeValue;
}
}
else {
return "n/a";
}
}
// Remove all previuos results from the screen
function clearAll() {
clearSelect("GeoSuggestList");
document.getElementById('searchInfo').innerHTML = '';
}
// Empty select list content
function clearSelect(select_name) {
var select = document.getElementById(select_name);
while (select.length > 0) {
select.remove(0);
}
}
// Add item to select element
function appendToSelect(select, value, content) {
var opt;
opt = document.createElement("option");
opt.value = value;
opt.appendChild(content);
select.appendChild(opt);
}
// Fill Loactions select list with items from the XML document
function buildGeoSuggestList() {
//Remove all markers from map
map.removeMarkersAll();
document.getElementById('searchInfo').style.display = 'block';
//document.getElementById("searchInfo").style.visibility = 'visible';
var select = document.getElementById("GeoSuggestList");
var errors = req.responseXML.getElementsByTagName("Error");
// Do we have Error in xml?
if (errors.length > 0) {
document.getElementById('searchInfo').innerHTML = "<span style=\"color:red\">Yahoo returned the following error: " +
getElementTextNS("", "Message", errors[0], 0) +
"</span>";
document.getElementById('GeoResults').style.display = 'none';
document.getElementById("GeoSuggest").style.display = 'none';
return;
}
var items = req.responseXML.getElementsByTagName("Result");
/* Get precision attibutes.
* Looks like yahoo return the same 'precision' attribute for multiple "Result" element
*/
var precision = items[0].getAttribute('precision');
// loop through <Result > elements, and add each nested to the "Suggest" drop down
for (var i = 0; i < items.length; i++) {
// Craete location object and store it in the array
MBLocations[i] = new MBLocation
(
getElementTextNS("", "Latitude", items[i], 0),
getElementTextNS("", "Longitude", items[i], 0),
getElementTextNS("", "Address", items[i], 0),
getElementTextNS("", "City", items[i], 0),
getElementTextNS("", "State", items[i], 0),
getElementTextNS("", "Zip", items[i], 0),
getElementTextNS("", "Country", items[i], 0)
);
//Add node to the drop down
appendToSelect(select, i, document.createTextNode(MBLocations[i].GetAddress()));
}
// Dump geocoding results
// Show first available result
DumpGeoInfo('0');
// Do we have some suggestions from Yahoo?
if (items.length > 1) {
document.getElementById('searchInfo').innerHTML = 'Yahoo suggest you to select the most suitable geocoding result:';
document.getElementById("GeoSuggest").style.display = 'block';
}
else {
document.getElementById('searchInfo').style.display = 'none';
document.getElementById("GeoSuggest").style.display = 'none';
}
}
// AJAX call to make geocoding
function GeoCode(address) {
if (trim(address)=='') {
alert ("Please, specify address for geocoding.")
return;
}
document.LocationSearchForm.LocationSearch.setAttribute("readonly","readonly");
document.getElementById('searchInfo').innerHTML = 'Searching...';
loadXMLDoc("service.yahoo.geocode.php?address=" + encode(address));
}
// Show geo information received from Yahoo for the given ID of MBLocation object
function DumpGeoInfo(id) {
document.getElementById("GeoResults").innerHTML =
"<b>Geocode Result</b><br \>" +
"Latitude: " + MBLocations[id].Latitude + "<br \>" +
"Longitude: " + MBLocations[id].Longitude + "<br \>" +
"Address: " + MBLocations[id].Address + "<br \>" +
"City: " + MBLocations[id].City + "<br \>" +
"State: " + MBLocations[id].State + "<br \>" +
"Zip: " + MBLocations[id].Zip + "<br \>" +
"Country: " + MBLocations[id].Country;
document.getElementById("GeoResults").style.visibility = 'visible';
// Center Map and show marker
showMarker(MBLocations[id].Latitude, MBLocations[id].Longitude, '3', "x", document.getElementById("GeoResults").innerHTML);
}
// Get address, put it on the form and geocode
function ForceGeoCode(address) {
document.LocationSearchForm.LocationSearch.value = address;
GeoCode(address);
}
// encode the things to pass back and forth
// the escape() method in Javascript is deprecated -- should use encodeURIComponent if available
function encode( uri ) {
if (encodeURIComponent) {
return encodeURIComponent(uri);
}
if (escape) {
return escape(uri);
}
}
function onLoad() {
// Create a map object
map = new YMap(document.getElementById('mapContainer'));
// Add a slider zoom control
map.addZoomShort();
var Text = "First Test";
// Create a lat/lon object
var myPoint = new YGeoPoint(30.244047, -97.747175);
// Display the map centered on a latitude and longitude
map.drawZoomAndCenter(myPoint, 3);
}
function trim(str)
{
return str.replace(/^\s*|\s*$/g,"");
}
// Show marker with label and text for mouse click event
function showMarker(Latitude, Longitude, Zoom, Label, Text) {
// Create a lat/lon object
var myPoint = new YGeoPoint(parseFloat(Latitude), parseFloat(Longitude));
// Display the map centered on a latitude and longitude
map.drawZoomAndCenter(myPoint, Zoom);
// Create a marker positioned at a lat/lon
var marker = new YMarker(myPoint);
// Add a label to the marker
marker.addLabel("<blink>"+Label+"</blink>");
// Call onSmartWinEvent when the user clicks on the marker
YEvent.Capture(marker, EventsList.MouseClick,
function onSmartWinEvent() {
marker.openSmartWindow("<div id=\"MapBuilderIW\">"+Text+"</div>");
}
);
// Display the marker
map.addOverlay(marker);
}
</script>
</head>
<body onload="onLoad();">
<h1>Geo!Suggest - Yahoo Geocoder's AJAX Interface</h1>
<div style="margin-right:15px;">
<form id="LocationSearchForm" name="LocationSearchForm" method="post" onsubmit="GeoCode(document.LocationSearchForm.LocationSearch.value); return false;">
<input class="text" id="LocationSearch" name="LocationSearch" size="40" value="Sunnyvale" type="text">
 
<input value="Search" type="button" class="frmButton" onclick="GeoCode(document.LocationSearchForm.LocationSearch.value);">
</form>
<div id="searchInfo"></div>
<div id="GeoSuggest" style="display:none">
<select id="GeoSuggestList" size="1" onchange="DumpGeoInfo(this.options[this.selectedIndex].value)">
<option value="">Yahoo Suggest</option>
</select>
</div>
<div id="GeoResults" style="visibility:hidden"> </div>
<div id="mapContainer" style="width: 350px; height: 300px; margin-top:20px;"></div>
<div id="devinfo">
Developmet: <br />
<a href="http://www.mapbuilder.net">Andrew Bidochko</a>
</div>
</div>
</body>
</html>