Posted in September 2012

Leaflet and Vicgrid (EPSG:3111) projection

While Leaflet is a fantastic mapping library, there’s not a lot of info out there on how to use it with different projections. I thought I’d share some tips I discovered while trying to get Leaflet working with a WMS server that only supports the projected VICGRID94 (EPSG:3111) CRS. Leaflet’s documentation is generally OK, but there’s a few potential roadblocks which took me a while to understand.

First you’ll need Leaflet, proj4js and Proj4Leaflet all installed on your server and linked to your page.

Before you initialise the map instance you’ll need to set up the CRS transform, which goes along the lines of:

// Coordinate to grid transformation matrix
var transformation = new L.Transformation(1, 0, -1, 0);
// Official Spatial Reference from
var crs = L.CRS.proj4js('EPSG:3111',
'+proj=lcc +lat_1=-36 +lat_2=-38 +lat_0=-37 +lon_0=145 +x_0=2500000 +y_0=2500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs',

You’ll also need to set up scale function, and assign it to your crs object.

// Scale for each level
var res = [2116.670900008467, 1058.3354500042335, 529.1677250021168, 264.5838625010584, 132.2919312505292, 66.1459656252646, 26.458386250105836, 13.229193125052918, 6.614596562526459, 2.6458386250105836, 1.3229193125052918, 0.6614596562526459, 0.33072982812632296, 0.21166709000084669];

var scale = function(zoom) {
 return 1 / res[zoom];
crs.scale = scale;

It took me a while to track this one down, but when you’re creating your layers, make sure you set “continuousWord: true” . Failing to set this will result in no tiles being loaded. Here’s an example WMS layer:

var cartolayer = L.tileLayer.wms("http://x.x.x.x/map/wms", {
 layers: 'basemap',
 format: 'image/png',
 continuousWorld: true,

Lastly, when initialising the map:

  • You must again set the option continuousWorld: true
  • You must set “worldCopyJump: false”, or you’ll have problems with the map jumping to a random location when you attempt to drag it (see Leaflet issue #1003)
  • Set the crs to the one created earlier
var map = new L.Map('map', {
 crs: crs,
 continuousWorld: true,
 center: new L.LatLng(-37.8, 144.9),
 zoom: 5,
 minZoom: 0,
 maxZoom: 13,
 worldCopyJump: false

Now you should be right to go and take advantage VICGRID with all that Leaflet goodness!

Some information which might be useful is available at:

Tagged , , , , ,

Investigating MapInfo’s Geocode Routine

After doing a bit of work using MapInfo’s built-in Geocode routine I started getting curious about how the routine handles various special cases. After a bit of experimenting I thought I’d document what I found out.

Starting with the simplest case, a street with odd numbers (1-9) on the left, and even numbers (2-10) on the right. The red stars show where MapInfo geocodes house numbers 3 and 4:

So far so good – we can see that MapInfo has correctly determined that one side of our street corresponds to odd numbers and one to even, and it has correctly matched the address points to the corresponding side of the road. Let’s try a one sided road next:

MapInfo treats -9999 values in an address ranges table as “no address points”. This road segment is correctly handled by MapInfo, and house number 4 gets geocoded to the correct side of the road. Nothing unexpected so far, but now let’s split the street into two lanes, with odd numbers on one side and even on the other:

More or less what we want to see. I should point out that in all these tests I’ve left the default setting of insetting addresses 15% from the ends of the street, which explains why points 2/10 and 1/9 don’t fall right on the beginning and end of the road segments. I’m not sure why the points curve out and fall at varying distances to the road — but it’s close enough and I can live with that.

Just to see what happens, lets go back to one road segment with valid even numbers (2-10) on only one side, and try geocoding an odd number house (9):

MapInfo has geocoded the point right in the centre of the road segment. Not what we’d like, but at least the Find command returns a result of 11 (exact match, side of street undetermined) for this case and it’s possible to find and avoid these types of errors. What happens now if we mix odd and even numbers on the same road side?

Here we’ve set one side of the road to range from 1 to 10, and the other to contain no addresses (-9999). Unfortunately none of the house numbers, either odd or even, match correctly in this case. All numbers from 1-10 are placed at the centroid, with a result code of 11. I guess mixing odd and even numbers in a street segment like this should be avoided.  If you have a street segment which does contain a range of odd and even numbers in reality, it looks like the only way to get this to work correctly is to duplicate the road segment, once with an odd number range and once with an even range. Hmmm… I wonder what happens if we have two matching street segments, one with this mix of odd and even numbers, and the second with just odd numbers?

Good – that’s encouraging to see. MapInfo can match the odd numbered houses to the segment with an odd address range of 1-9, even when we have a bad segment which covers the same number range. The even numbers don’t return a match, with a result code of -411 (multiple matches, side of street undetermined, exact match). Let’s take a step back and try a different type of conflict, where the address numbers on either side of the road overlap:

After a bit more testing (which I won’t go into here), it looks like when there’s an overlapping range like this and an address point could fall on either side of the road, MapInfo places it on the right hand side. For reference, overlapping ranges across two different road segments will geocode points which unambiguously fall on one road segment, and return a code of -401 (multiple matches, exact match) for the others:

(Address points 2 and 10 geocode, whereas 4, 6 and 8 don’t). One last thing to try – let’s see what happens when the address ranges table contains a point object. In this case we’ll add a point object with a left range of 1-9 and a right range of 2-10.

I wasn’t expecting this to work, but it appears to correctly geocode any numbers between 1 and 10 directly to the same location as the address ranges point. This is great news (for reasons I’ll possibly go into in a later blog post).

Quick Summary:

  • Don’t have an address range on the one side of a segment which consists of both odd and even numbers. If you do need to have a segment like this, you’ll need to duplicate the segment with one row having and odd range and the other having an even range.
  • Make sure to correctly handle any matches with a result code of side of street undetermined, since these may have just matched to the centre of the road
  • It’s OK to have point objects in an address ranges table
Tagged , , ,