Friday, July 25, 2008

Using mapstraction and Yahoo maps to determine lat/lon of a location

(View demo).

During this week, I started experimenting with maps in my web applications. As a good developer, you should always google and see what is out there. Why invent the wheel again. One the first things I encountered was a javascript framework called mapstraction. It really does a nice job on working with maps (independent of the maps provider).

Having a look at the demos provided by mapstraction it was quite easy and fast to create mapping functionality. My biggest problem was the choice of the mapping provider. Having a look at the various api's and providers, there are actually 2 mapping api's which look good: Yahoo and Google. Being stubborn and not being a sheep in a flock, I have chosen for yahoo. I think yahoo is doing a very good job with their services.

Creating the map


The first thing we need to do is to get an app key from Yahoo. After we have this we can start coding. We start off by including the javascript files to our page. Then we create a div element which will hold our map. (Keep in mind that thesize of the div element needs to be specified, either directly or in the css).

Basically we are now set for coding.


<script type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=3.0&appid={yourappkey}"></script>
<script type="text/javascript" src="js/mapstraction.js"></script>
<!-- the size must be specified here, or in the CSS -->
<div id="mapcontainer" style="width:300px;height:200px;"></div>

As always for javascript coding, I use jQuery. When the dom is ready, we will start
creating the mapstraction object and then initialize it.



$(document).ready(
function() {
var bw = $('body').width();
// we want the map to be as width as the browser window
$('#mapcontainer').css( 'width', bw);
// initialise the map with yahoo API
mapstraction = new Mapstraction('mapstraction','yahoo');
// add some controls for it (for zooming and panning)
mapstraction.addControls({
pan: true,
zoom: 'large',
map_type: true
});
// this function we will use to put some markers on the map,
// eg coming from a database
fillmap(true);
}
);

Almost done... Just need to fill the map with markers. In my example I will have 1 marker which is predefined, but you can easily get this from your database (eg, by using an ajax call)

Markers on the map

In order to be able to add markers on the map, we need to define a point based on latitude and longitude. Once we have this point, we can add the marker to the given position.

function fillmap() {
// check if we have a mapstraction defined
if (mapstraction) {
// set the lat/lon value of the location we would like to mark
// in this example, it is Rotterdam (centrum of the world :))
var lat=51.92434043666618;
var lon=4.47817325592041;
// get rid of existing markers (if they are)
mapstraction.removeAllMarkers();
// create a point with lat/lon coordinates defined
var myPoint = new LatLonPoint(lat,lon);
// create a marker positioned at a lat/lon
var my_marker = new Marker(myPoint);
// add the marker to the map
mapstraction.addMarker(my_marker);
// center map on the location and zoom (level 9)
mapstraction.setCenterAndZoom(myPoint, 9);
}
}
It is possible to add text to a marker, however this is not my goal. If you want to do that, you can use the my_marker.setInfoBubble() method.

The goal is to get the latitude and longitude values of a location the user selects on the map. In order to do this we need to add and onclick event to the map. This can easily be done by using the addEventListener of the mapstraction object.



// capture the mouse click event
mapstraction.addEventListener( 'click', onClickMap);

// on each mouse click this function will be called with the point
// object of mapstraction
function onClickMap( point) {
// the yahoo map returns 0 for lat and 180 for lon when user
// clicks on a control on the map (for example on the pan-left arrow)
if (point.lat != 0) {
// we will remove existing markers on the map (resetting the map)
mapstraction.removeAllMarkers();
// we add a marker at the clicked location
mapstraction.addMarker( new Marker( new LatLonPoint(point.lat,point.lon)));
}
}

Now we are finished. To conclude: it is very quick and easy to geo-enable your application by using mapstraction.

Demo

For a demonstration of the code, have a look at my lat/lon finder. Please look at the source to see the full implementation.

In order to accomplish the search functionality and removing of markers in the demo, I have modified/extended the mapstration.js with 2 functions (for Yahoo):

Mapstraction.findCenterAndZoom(findtxt, zoom)

Marker.setClick(onMarkerClick)

The first function allows to search on a text and then centers the found location with a zoom. The second function allows a callback function when the marker is clicked. This was a function I really missed in mapstraction.

While I was busy working on the demo, I also found it interesting to be able to retrieve the location name of clicked/entered location. This is done by using the geonames.org JSON webservices.

Finally, I also implemented the parsin of the URL with lat and lon parameters, allowing a permalink. All in all, I think it is a usefull demo ;)

Feedback/Comments

If you have any questions or remarks about this code, as always you can always contact me.