Leaflet – Showing WMS with EPSG:3301 Projection

layersleafletwms

I am trying to show wms layer EPSG:3301 using leaflet, but have no succes for a long time.
http://kaart.maaamet.ee/wms/alus?service=WMS&version=1.3.0&request=GetCapabilities
Here is my code:

function initialize() {

var crs = L.CRS.proj4js('EPSG:3301',
     '+proj=lcc +lat_1=59.33333333333334 +lat_2=58 +lat_0=57.51755393055556 +lon_0=24 +x_0=500000 +y_0=6375000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs',
    new L.Transformation(1, -40500, -1, 7017000)
);

var wmsMap= L.tileLayer.wms('http://kaart.maaamet.ee/wms/alus', {
    layers: 'MA-ALUS',
    format: 'image/png',
    maxZoom: 14,
    minZoom: 3,
    continuousWorld: true,
    transparent:true
});

var map = L.map('map', {
        layers:[wmsMap],
        continuousWorld: true,
        center: new L.LatLng(58.66, 25.05),
        zoom: 2,
        maxZoom: 13,
        minZoom: 1,
        maxBounds: new L.LatLngBounds([
            [56.42, 20.87],
            [60.9, 29.23]
        ]),
        crs: crs
    }
);

Please anybody check my code to see what's wrong with it?? I see map area, see attribution and layer switcher if I add them, but not a map.

Best Answer

Here is a working code for your problem: http://jsfiddle.net/GFarkas/rkhzfguz/1/

Some explanations on the wrong lines:

var crs = L.CRS.proj4js('EPSG:3301',
 '+proj=lcc +lat_1=59.33333333333334 +lat_2=58 +lat_0=57.51755393055556 +lon_0=24 +x_0=500000 +y_0=6375000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs',
new L.Transformation(1, -40500, -1, 7017000)
);

First of all, the correct function name as you can see in the Proj4Leaflet project's manual is L.Proj.CRS. Also, you have to call a new instance of the function (there is a great article about constructors and instances here).

The first two arguments the L.Proj.CRS constructor takes are the projection name and definition. So far so good. However, the third and last argument is an object of options. More clearly, you have to put the option parameters in braces and call them on their respective names (like transformation: new L.Transformation(1, -40500, -1, 7017000)). This calling method with the colon is called KVP (key-value pairs).

The last problem is, that you have to define the resolutions on every zoom level. You have defined 12 zoom levels (3-14), so you have to define 12 resolution or scale values. At zoom level 0, the usual resolution is 8192m, and it halves at every zoom level.

The final code of this part will look like something like this:

var crs = new L.Proj.CRS('EPSG:3301',
 '+proj=lcc +lat_1=59.33333333333334 +lat_2=58 +lat_0=57.51755393055556 +lon_0=24 +x_0=500000 +y_0=6375000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs',
{
    resolutions: [
        1024, 512, 256, 128,
        64, 32, 16, 8, 4, 2, 1, 0.5
    ],
    transformation: new L.Transformation(1, -40500, -1, 7017000)
});

The rest of the code is functional, however I have two observations you should consider:

It is easier and less code to set the view of the map individually with map.setView()

Original code:

center: new L.LatLng(58.66, 25.05),
zoom: 2,

map.setView() method:

map.setView([58.66, 25.05], 2);

You shouldn't call a zoom level your layer doesn't have, because it will result in a grey background. So if you don't have other layers in your inventory, then you should call zoom level 3 instead of zoom level 2. Then your map will render normally and you won't be confused if your code is working or not.

Related Question