The MapAPI 1.0 is deprecated. Please use the new MapAPI 1.1.
« Previous chapter 1: Mapping Back to Index Next chapter 3: Mapping and Geocoding »
This chapter gives you a short introduction in geocoding and reverse-geocoding. Geocoding is important, if you want to get the coordinate for a specified address. After the address is geocoded, the coordinate can be used for map positioning. The map requires meter coordinates for correct positioning. Further, the geocoder client supports reverse geocoding which can be used to find possible addresses for a specified coordinate.
Fig. 2.1: UML class diagram: Geocoder Client
Lets start with our first geocoding example. Fill out the input fields below and press the geocode button. After receiving the response from the geocoder server, the example displays a list of possible coordinates for the entered address.
Geocoding example 2a (view example) or
Source code example 2a:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>Chapter 2: Geocoding example 2a</title> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <link type="text/css" rel="stylesheet" href="http://iw.mapandroute.de/MapAPI-1.0/css/screen.css"> <script type="text/javascript" src="http://iw.mapandroute.de/MapAPI-1.0/js/mapping.js"></script> </head> <body class="tutorial" onload="initFields()"> <script type="text/javascript"> var geocoder = new IWGeocoderClient(); IWEventManager.addListener(geocoder, 'ongeocode', function(event) { return showGeocodingResults(event); }); /** * Calls the geocode method. * @private * @param {String} inputAddress the address string * @param {String} countryCode the country code * @param {Number} maximumHits the maximum hits returned by the geocoder * @return {void} */ function doGeocoding(inputAddress, countryCode, maximumHits) { geocoder.geocodeAddressString(inputAddress, countryCode, maximumHits); } /** * Callback method for geocode events. * @private * @param {IWGeocodingEvent} event the geocoding event * @return {void} */ function showGeocodingResults(event) { var results = event.results; var table = document.getElementById('resultTable'); for (var i = table.rows.length-1; i > 0; i--) { table.deleteRow(i); } if (results.length > 0) { var rows = results.length; for(var i = 0; i < rows; i++) { var result = results[i]; var tr = table.insertRow(i+1); tr.className = (i % 2 ? 'even' : 'odd'); tr.insertCell(0).innerHTML = i+1; var text = ''; var address = result.getAddress(); if (address.getStreet()) { text = address.getStreet() } if (address.getHouseNumber()) { text += ' ' + address.getHouseNumber(); } if (address.getZipCode()) { text += ' ' + address.getZipCode(); } if (address.getCity()) { text += ' ' + address.getCity(); } if (address.getCountry()) { text += ' ' + address.getCountry(); } if (address.getCountryCode()) { text += ' ' + address.getCountryCode(); } var wgs84 = address.getCoordinate().toWGS84(); tr.insertCell(1).innerHTML = text; tr.insertCell(2).innerHTML = address.getCoordinate().getX() + ', ' + address.getCoordinate().getY(); tr.insertCell(3).innerHTML = wgs84.getX() + ', ' + wgs84.getY(); tr.insertCell(4).innerHTML = result.getHitProbability(); tr.insertCell(5).innerHTML = (typeof result.getQuality() == 'undefined' ? '????' : result.getQuality()); } } } /** * Fills out the input fields with default values. * @private * @return {void} */ function initFields() { var form = document.forms['geocodeForm']; form.inputAddress.value = 'Riemenschneiderstr. 11, 53175 Bonn'; } </script> <form id="geocodeForm" action=""> <table> <tr> <td width="150">Address phrase</td> <td><input type="text" size="35" name="inputAddress"></td> </tr> <tr> <td width="150">Country code</td> <td><input type="text" size="35" name="countryCode" value="D"></td> </tr> <tr> <td width="150">Maximum hits</td> <td><input type="text" size="35" name="maximumHits" value="30"></td> </tr> </table> <input type="reset" value="reset form"> <input type="button" value="geocode" onClick="doGeocoding(this.form.inputAddress.value, this.form.countryCode.value, this.form.maximumHits.value)"> </form> <br> <div style="position: relative; left: -1px; width: 100%; height: 145px; overflow: auto; padding: 1px;"> <table id="resultTable"> <tr> <th>No.</th> <th>Address</th> <th>meter coordinate</th> <th>degree coordinate</th> <th>Hit probability</th> <th>Quality</th> </tr> </table> </div> </body> </html>
The previous example looks a little bit more complex than our first mapping example. The reason is, that we have to handle the server response by ourselves. But a closer look at the code will show, that using the API for geocoding is also very easy. Let us take the code apart and have a look what it does.
At first we need a new geocoder client, so we instantiate the IWGeocoderClient class. Then we add a new listener to
the IWEventManager object. With the IWEventManager we can add so called "event listeners".
Listeners can be used to determine when a request comes in. In this
case, we catch the geocoding event and call the showGeocodingResults()
method to display the result after the geocoder server has sent an
answer.
var geocoder = new IWGeocoderClient(); IWEventManager.addListener(geocoder, 'ongeocode', function(event) { return showGeocodingResults(event); });
geocodeAddressString
methodWe define two javascript methods, doGeocoding()
and
showGeocodingResults()
. In doGeocoding()
we
just forward the values from the HTML form to the geocoder server by
calling the geocodeAddressString method. The second parameter has
to be a country code. This is necessary, because the address search
would by to complex without localizing it to a country. In our example
we want to search in Germany.
function doGeocoding(inputAddress, countryCode, maximumHits) { geocoder.geocodeAddressString(inputAddress, countryCode, maximumHits); }
The complete list of supported country codes is specified in the configration file of your geocoder server. The following table shows only some example codes.
Code | Country | Code | Country |
---|---|---|---|
D |
Deutschland | A |
Österreich |
CH |
Schweiz | B |
Belgien |
NL |
Niederlande | F |
Frankreich |
E |
Spanien | L |
Luxemburg |
I |
Italien | GB |
Großbritannien |
N |
Norwegen | DK |
Dänemark |
S |
Schweden | P |
Portugal |
AND |
Andorra | RSM |
San Marino |
FIN |
Finnland | PL |
Polen |
CZ |
Tschechien | IRL |
Irland |
GRC |
Griechenland | HUN |
Ungarn |
SVK |
Slowakei | ALB |
Albanien |
BIH |
Bosnien-Herzegowina | HRV |
Kroatien |
MDA |
Moldawien | ROU |
Rumänien |
SRB |
Serbien | SVN |
Slowenien |
MNE |
Montenegro | BGR |
Bulgarien |
BLR |
Weißrussland | EST |
Estland |
LTU |
Litauen | LVA |
Lettland |
MKD |
Makedonien | MLT |
Malta |
RUS |
Russland | TUR |
Türkei |
UKR |
Ukraine | UAE |
Vereinigte Arabische Emirate |
The server will now process our geocoding request and will send
an answer back to the geocoder client. The answer will then be caught by
our event listener and delegated to the showGeocodingResults()
method. The method writes the result from the geocoder server into the resultTable
that we defined at the bottom of our HTML code. For this, the method
gets as parameter the event
object from the geocoder
client. We know that this event is an instance of IWGeocodingEvent, so we grab the geocoding results from
the results
attribute. The results
attribute
contains an array of IWGeocodingResult objects. We can now iterate over all
results and print them in our table. The geocoded address can be access
by calling the getAddress() method. We use the getter methods from the
address object to create a formatted address string.
function showGeocodingResults(event) { var results = event.results; for (var i = table.rows.length-1; i > 0; i--) { table.deleteRow(i); } if (results.length > 0) { var rows = results.length; for(var i = 0; i < rows; i++) { var result = results[i]; tr = table.insertRow(i+1); tr.className = (i % 2 ? 'even' : 'odd'); tr.insertCell(0).innerHTML = i+1; var text = ''; var address = result.getAddress(); if (address.getStreet()) { text = address.getStreet() } if (address.getHouseNumber()) { text += ' ' + address.getHouseNumber(); } if (address.getZipCode()) { text += ' ' + address.getZipCode(); } if (address.getCity()) { text += ' ' + address.getCity(); } if (address.getCountry()) { text += ' ' + address.getCountry(); } if (address.getCountryCode()) { text += ' ' + address.getCountryCode(); } var wgs84 = address.getCoordinate().toWGS84(); tr.insertCell(1).innerHTML = text; tr.insertCell(2).innerHTML = address.getCoordinate().getX() + ', ' + address.getCoordinate.getY(); tr.insertCell(3).innerHTML = wgs84.getX() + ', ' + wgs84.getY(); tr.insertCell(4).innerHTML = result.getHitProbability(); } } }
This is a simple HTML form, the only interesting line is the
input tag at the bottom, where we send our form content to the doGeocoding()
method.
<form id="geocodeForm" action=""> <table> <tr> <td width="150">Address phrase</td> <td><input type="text" size="35" name="inputAddress"></td> </tr> <tr> <td width="150">Country code</td> <td><input type="text" size="35" name="countryCode" value="D"></td> </tr> <tr> <td width="150">Maximum hits</td> <td><input type="text" size="35" name="maximumHits" value="30"></td> </tr> </table> <input type="reset" value="reset form"> <input type="button" value="geocode" onClick="doGeocoding(this.form.inputAddress.value, this.form.countryCode.value, this.form.maximumHits.value)"> </form>
In this table we want to present the results. We just define the
"hull" here, the main part is done by the showGeocodingResults()
method. Therefore it is important that the table id here matches with
the id we use in that method.
<div style="position: relative; left: -1px; width: 100%; height: 145px; overflow: auto; padding: 1px;"> <table id="resultTable"> <tr> <th>No.</th> <th>Address</th> <th>meter coordinate</th> <th>degree coordinate</th> <th>Hit probability</th> <th>Quality</th> </tr> </table> <div>
The first example shows you a simple way to geocode a free address search. This is very powerful feature but in some cases it is necessary for you to set the address attributes explicit. The following example uses an IWAddress object for setting this attributes. You can set the street, house number, zipcode, city and countrycode attribute. The structure of the next example is very similar to our first, so we explain only the main different part.
Geocoding example 2b (view example):
Source code example 2b:
geocodeAddress
methodThe doGeocoding()
method gets now all address
attributes from the HTML form separately. The only thing that we must do
is to create an IWAddress object and set its properties. After this, we
can call the geocodeAddress() method which takes the address object
as parameter. The geocoding event is also caught by the event listener
and automatically forwarded to the showGeocodingResult()
method which prints the geocoding result in the table.
function doGeocoding(street, houseNumber, zipCode, city, countryCode, maximumHits) { var address = new IWAddress(); address.setStreet(street); address.setHouseNumber(houseNumber); address.setZipCode(zipCode); address.setCity(city); address.setCountryCode(countryCode); geocoder.geocodeAddress(address, maximumHits); }
The following reverse geocoding examples demonstrates the use of the reverse geocoding methods. The examples are very similar to the previous examples at the top of the page.
Reverse-Geocoding example 2c (view example):
Source code example 2c:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>Chapter 2: Reverse-Geocoding example 2c</title> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <link type="text/css" rel="stylesheet" href="http://iw.mapandroute.de/MapAPI-1.0/css/screen.css"> <script type="text/javascript" src="http://iw.mapandroute.de/MapAPI-1.0/js/mapping.js"></script> </head> <body class="tutorial"> <script type="text/javascript"> var geocoder = new IWGeocoderClient(); IWEventManager.addListener(geocoder, 'onreversegeocode', function(event) { return showReverseGeocodingResults(event); }); /** * Calls the reverse geocode method. * @private * @param {String} projection the name of the projection: 'WGS84' or 'MERCATOR' * @param {Number} x the x coordinate * @param {Number} y the y coordinate * @param {Number} radius * @return {void} */ function doReverseGeocoding(projection, x, y, radius) { geocoder.reverseGeocodeByRadius(new IWCoordinate(x, y, projection), radius); } /** * Callback method for reverse geocode events. * @private * @param {IWReverseGeocodingEvent} event the reverse geocoding event * @return {void} */ function showReverseGeocodingResults(event) { var results = event.results; var table = document.getElementById('resultTable'); for (var i = table.rows.length-1; i > 0; i--) { table.deleteRow(i); } if (results.length > 0) { var rows = results.length; for(var i = 0; i < rows; i++) { var result = results[i]; var address = result.getAddress(); var tr = table.insertRow(i+1); tr.className = (i % 2 ? 'even' : 'odd'); tr.insertCell(0).innerHTML = i+1; tr.insertCell(1).innerHTML = address.getCoordinate().getX() + ', ' + address.getCoordinate().getY(); var wgs84 = address.getCoordinate().toWGS84(); tr.insertCell(2).innerHTML = wgs84.getX() + ', ' + wgs84.getY(); var text = ''; var address = result.getAddress(); if (address.getStreet()) { text = address.getStreet() } if (address.getHouseNumber()) { text += ' ' + address.getHouseNumber(); } if (address.getZipCode()) { text += ' ' + address.getZipCode(); } if (address.getCity()) { text += ' ' + address.getCity(); } if (address.getCountry()) { text += ' ' + address.getCountry(); } if (address.getCountryCode()) { text += ' ' + address.getCountryCode(); } tr.insertCell(3).innerHTML = text; tr.insertCell(4).innerHTML = result.getDistance(); } } } </script> <form action=""> <table> <tr> <td width="150">Projection</td> <td> <select name="projection"> <option value="meter" selected>meter</option> <option value="degree">degree</option> </select> </td> </tr> <tr> <td width="150">X coordinate</td> <td><input type="text" size="35" name="x" value="786332"></td> </tr> <tr> <td width="150">Y coordinate</td> <td><input type="text" size="35" name="y" value="6572310"></td> </tr> <tr> <td width="150">Radius in meter</td> <td> <input type="text" size="35" name="radius" value="1000"> </td> </tr> </table> <input type="button" value="reverse geocode" onClick="doReverseGeocoding(this.form.projection.value, this.form.x.value, this.form.y.value, this.form.radius.value)"> </form> <br> <div style="position: relative; left: -1px; width: 100%; height: 145px; overflow: auto; padding: 1px;"> <table id="resultTable"> <tr> <th>No.</th> <th>meter coordinate</th> <th>degree coordinate</th> <th>Address</th> <th>Distance in meters</th> </tr> </table> </div> </body> </html>
Reverse-Geocoding example 2d (view example) or
The difference between to the first and the second reverse geocoding example is, that we call in the first the reverseGeocodeByRadius method from the geocoder client and in the second the reverseGeocodeByHits method.
« Previous chapter 1: Mapping Back to Index Next chapter 3: Mapping and Geocoding »
Copyright 2007-2009 infoware GmbH, mapsuite Javascript Tutorial