GEOG5870/1M: Web-based GIS A course on web-based mapping

Geo-coding

There are a number of services available to handle geocoding (and, conversion between spatial reference systems). Some useful starting points include:

A rather friendlier system is available online, at Nearby.org.uk, which we will look at in this practical. Following that, we'll look at jscoord, a geocoding library.


Task


This is very useful, as it gives us the lat/long references that we need to use for the Blue Plaques data. You could convert the whole data set this way, recording the lat/long output in your copy of the data set. With a little co-operation with other students, the whole data set could be geocoded fairly quickly. However, this approach (while workable for this practical) would not be sufficient if your data set was considerably larger. Fortunately, there are services which allow automated processing of geocoding and co-ordinate conversion. However to use these, you have to sign up for an API key. This doesn't cost anything and is there to stop abuse of the site from commercial companies. There more info on this on the API site.

There is also a geocoding service available from Google Maps – again, if you wish to use it, you will need to register for a key. The full description of Google's Geocoder is on their geocoding page. However, the Google geocoder does not do what we want for this task, which is to convert from traditional Ordnance Survey grid references to latitude-longitude co-ordinates.

Note that geocoding is a resource intensive and relatively slow process. Whilst the Google Maps geocoder could be used directly to determine marker locations given addresses, you would not want to do this each time the map is loaded. In practice, you would have a seperate system to maintain your own database of coordinates, updating only for new addresses.


Task (optional)

If you are confident with using APIs in this way, try using the nearby.org.uk conversion api to convert some points.


JSCoord

A final approach that is of interest to us is to use a Javascript library for co-ordinate conversion. JScoord is an open source library that includes routines for converting between a number of reference systems.

This can be use to convert from OS National Grid references to the appropriate latitude / longitude reference.


Task

Copy the JScoord library, extracting the files into the same directory as your other Javascript files.

The code listing below shows a skeleton version of a number of files that can be used to draw the blue plaques data. Firstly, plaques_map.html is the HTML document that will present our map. There is one important change to note – there is a new SCRIPT tag in the header part of the file, which loads the JScoord library. It is important to load this before the script that will use the library.

The code for the HTML file plaques_map.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript"
   src="http://maps.google.com/maps/api/js"></script>
<script type="text/javascript" src="jscoord-1.1.1.js"></script>
<script type="text/javascript" src="test_plaques_data.js"></script>
<script type="text/javascript" src="map_setup_plaques.js"></script>
<link rel="stylesheet" media="all" href="map_style.css" type="text/css">
<title>Blue plaques example</title>
</head>

<body onload="initialize()">
<h1>Blue plaques map</h1>
<div class="gmap" id="map_canvas" style="height: 400px; width: 600px"></div>
</body>
</html>

The plaques_map.html file also makes reference to a test data file test_plaques_data.js, which includes the first two points we want to add. This has been put into an array called os_markers, to remind us that the co-ordinates are currently OS grid references.

The code for the data file test_plaques_data.js
var os_markers = [
{
'id':1,
'title':'Burley Bar Stone',
'location':'Inside main entrance of Leeds Building Society, The Headrow Leeds 1',
'unveiler':'Lord Marshall of Leeds, President of Leeds Civic Trust, former Leader of Leeds City Council',
'date':'27 Nov 1987',
'sponser':'Leeds & Holbeck Building Society',
'easting':430055,
'northing':433766,
'caption':'This stone, now housed inside the main entrance of Leeds Building society marked the medieval boundary between the manorial borough, or town, of Leeds and Leeds Main Riding, the surrounding agricultural land. First recorded 1726.'
},
{
'id':2,
'title':'Louis Le Prince (1st Plaque)',
'location':'British Waterways, Leeds Bridge, Lower Briggate, Leeds 1',
'unveiler':'Mr. William Le Prince Huettle, great-grandson of Louis Le Prince',
'date':'13 Oct 1988',
'sponser':'British Waterways Board',
'easting':430296,
'northing':433148,
'caption':'Louis Aime August Le Prince came to Leeds in 1866 where he experimented in cinematography. In 1888 he patented a one-lens camera which he filmed Leeds Bridge from the British Waterways building. These were probably the world’s first successful moving pictures.'
}];

Notice that the longer entries are word-wrapped: long entries have to be on one continuous line in JSON; they can't contain line breaks.

Finally, we have a new map_setup_plaques.js version of our map_setup code, adapted for this task.

The code for the main JavaScript file map_setup_plaques.js
var map; // The map object
var myCentreLat = 53.8;
var myCentreLng = -1.6;
var initialZoom = 12;

function infoCallback(infowindow, marker) {
   return function() {
      infowindow.open(map, marker);
   };
}

function addMarker(myPos,myTitle,myInfo) {
   var marker = new google.maps.Marker({
      position: myPos,
      map: map,
      title: myTitle
   });
   var infowindow = new google.maps.InfoWindow({content: myInfo});
   google.maps.event.addListener(marker,
      'click', infoCallback(infowindow, marker));
}

function initialize() {
   var latlng = new google.maps.LatLng(myCentreLat,myCentreLng);
   var myOptions = {
      zoom: initialZoom,
      center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
   };
   map = new google.maps.Map(
      document.getElementById("map_canvas"),myOptions);

   for (id in os_markers) {
      var info = "<div class=infowindow><h1>" +
         os_markers[id].title + "</h1><p>Caption: "
         + os_markers[id].caption +
         "</p></div>";

      // Convert co-ords
      var osPt = new OSRef(
         os_markers[id].easting,os_markers[id].northing);
      var llPt = osPt.toLatLng(osPt);
      llPt.OSGB36ToWGS84();

      addMarker(
         new google.maps.LatLng(llPt.lat,llPt.lng),
         os_markers[id].title,info);
   }
}

The main change is the addition of these lines to the loop which iterates through the array of marker data:

      var osPt = new OSRef(
         os_markers[id].easting,os_markers[id].northing);
      var llPt = osPt.toLatLng(osPt);
      llPt.OSGB36ToWGS84();

These lines make use of features of the JScoord library that we have loaded. Firstly, we create a new object of the type OSRef (this object is made available through the JScoord library), and initialise it using the easting and northing values stored in our marker data. We then make use of a method provided by the library for OS points: toLatLng().

This converts the point to a latlng point (the conversion maths is contained within the library). However, not all latitude and longitude references are the same! These coordinates assume that we are still using the OSGB36 datum that is used for normal OS maps. As the OS National Grid uses a different datum to Google Maps, it is necessary to convert between datums as well.

This is done, above, by the OSGB36ToWGS84() method of the lat-long object. Since we have not specified a new variable, the statement 'llPt.OSGB36ToWGS84();' causes the llPt object to act on itself.

Finally, we use the addMarker() to add a marker to our map in the same way as before, except that instead of using the co-ordinates from the original data, we use the lat and lng properties of the object llPt.


Task - part of portfolio submission

Add markers to the map from the blue plaques data. Use whichever method of co-ordinate conversion you prefer (i.e. JSCoord, manual conversion using nearby.org.uk, or direct use of a geocoding or conversion API).



[Course Index]