Archive | October, 2014

ESRI Geocoding Widget Using the REST API and JavaScript

20 Oct
Geocoder Widget with the result dislpayed.

Geocoder Widget with the result dislpayed.

I need to geocode in my web apps and I decided to try writing my own geocoder using my ArcServer geocoding service and the ESRI REST API. I have made two version: one that only requires including the css and js files and one that requires a line of code to initialize. The second one allows me to switch the geocoder I want to use. The geocoder requres a Leaflet.js map – only to add the marker. If you want to use a different mapping library, just change the code in the JavaScript file after the line if(http.readyState == 4 && http.status == 200) {. The http.responseText will contain a JSON string of the results. Do whatever you want with them.

To use the first one, the HTML looks as follows:
<html>
<head><title>DMDVIEW REST Services</title>
<link rel=”stylesheet” href=”geocoder.css” />
<link rel=”stylesheet” href=”http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css&#8221; />
<style>
html, body, #map {
padding: 0;
margin: 0;
height: 100%;
}

</style>
</head>
<body>
<div id=”map”></div>
<script src=”http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js”></script&gt;
<script src=”geocoderMap.js”></script>
<script>

var map = L.map(‘map’, {
center: [35.10418, -106.62987],
zoom: 9
});

L.tileLayer(‘http://{s}.tile.osm.org/{z}/{x}/{y}.png’).addTo(map);

</script>
</body>
</html>

 

The CSS:

#AddressSearchBox{
background-color: rgba(255, 255, 255, 0.5);
border: 1px solid #000;
-moz-border-radius: 15px;
border-radius: 15px;
height:40px;
width:350px;
padding-top:10px;
padding-left:5px;
position: absolute;
left: 40%;
top: 0px;
z-index: 100000;
}
#first{
text-align: center;
}
#second{
text-align: left;
margin: 0 auto;
width: 50%;
}

 

The JavaScript file does all the work. It creates the nested <div>’s to the HTML, formats them and then lets you enter an address and either puch the button or press enter. The result is a point on the map at the first result with the popup open, displaying the result name. Just add your ArcServer geocoding service URL and you can include a geocoder widget with 2 includes.

Here is the JavaScript:

(function() {

var b = document.getElementsByTagName(‘body’)[0];
var first = document.createElement(‘div’);
var second = document.createElement(‘div’);
var addressSearchBox = document.createElement(‘div’);

first.id = “first”;
second.id = “second”;
addressSearchBox.id = “AddressSearchBox”;

b.appendChild(first);
first.appendChild(second);
second.appendChild(addressSearchBox);

var text = “<center><b>Address:</b><input type=’text’ id=’addr’ name=’to’><button id=’search’ >Search</button><center>”
addressSearchBox.innerHTML=text;

var textbox = document.getElementById(“addr”);
var button = document.getElementById(“search”);

function GeocodeAddress(){
addressFromAddressSearchBox=document.getElementById(“addr”).value;
var params = “Street=”+addressFromAddressSearchBox+”&f=json&outSR=4326”;
var url = “http://YourArcServerName/ArcGIS/rest/services/YourGeolocatorServiceName/GeocodeServer/findAddressCandidates&#8221;;
if (window.XMLHttpRequest)
{
http=new XMLHttpRequest();
}
else
{
http=new ActiveXObject(“Msxml2.XMLHTTP”);
}

http.open(“POST”, url, true);
http.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
var thexy= JSON.parse(http.responseText);
var yousearchedfor = L.marker([thexy.candidates[0].location.y,thexy.candidates[0].location.x]).addTo(map).bindPopup(‘<h3>’+addressFromAddressSearchBox+'</h3>’).openPopup();
map.setView([thexy.candidates[0].location.y,thexy.candidates[0].location.x],18);
}//end if
}
http.send(params);
}
button.onclick=function geocode(){
GeocodeAddress();

}

textbox.onkeypress=function handleKeyPress(e){
var key=e.keyCode || e.which;
if (key==13){
GeocodeAddress();

}}

}
());

 

I mentioned that I had a second example that allowed you to switch the service at run time, or just use the default. This example requires a line of code in your HTML:

new geocoder();

or

new geocoder(“http://the service you want to use.com/arcgis/services/rest/….”);

 

the CSS is the same. The only change is in the JavaScript. Here is the code:

( function( window, undefined, url ) {

function geocoder(url) {
this.url=url;
url = typeof url !== ‘undefined’ ? url : “http://YourArcServer/ArcGIS/rest/services/YourServiceName/GeocodeServer/findAddressCandidates&#8221;;
var b = document.getElementsByTagName(‘body’)[0];
var first = document.createElement(‘div’);
var second = document.createElement(‘div’);
var addressSearchBox = document.createElement(‘div’);

first.id = “first”;
second.id = “second”;
addressSearchBox.id = “AddressSearchBox”;

b.appendChild(first);
first.appendChild(second);
second.appendChild(addressSearchBox);

var text = “<center><b>Address:</b><input type=’text’ id=’addr’ name=’to’><button id=’search’ >Search</button><center>”
addressSearchBox.innerHTML=text;

var textbox = document.getElementById(“addr”);
var button = document.getElementById(“search”);
function GeocodeAddress(){
addressFromAddressSearchBox=document.getElementById(“addr”).value;
var params = “Street=”+addressFromAddressSearchBox+”&f=json&outSR=4326”;

if (window.XMLHttpRequest)
{
http=new XMLHttpRequest();
}
else
{
http=new ActiveXObject(“Msxml2.XMLHTTP”);
}

http.open(“POST”, url, true);
http.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
var thexy= JSON.parse(http.responseText);
var yousearchedfor = L.marker([thexy.candidates[0].location.y,thexy.candidates[0].location.x]).addTo(map).bindPopup(‘<h3>’+addressFromAddressSearchBox+'</h3>’).openPopup();
map.setView([thexy.candidates[0].location.y,thexy.candidates[0].location.x],18);
}//end if
}
http.send(params);
}

button.onclick=function geocode(){
GeocodeAddress();
}

textbox.onkeypress=function handleKeyPress(e){
var key=e.keyCode || e.which;
if (key==13){
GeocodeAddress();
}}

}

window.geocoder = geocoder;

} )( window );

Advertisements

Leaflet.js Essentials: My Book is now Available!

1 Oct

4812OS_Leaflet Essentials

My book is available on Amazon.com

or at Packt Publishing