0

After several attempts, some tinkering and a lot of asking here, I got my fictional map running with tiles by setting up a simple custom CRS. Alas, the map is slightly off center. I got the feelig that fitToBounds does not really work and if I add setView it does not change anything either.

My map size is 1024x1024 so the map should fit nicely at zoom level 2, but look for yourself.

The code looks like this:

 ////////////////////////////////////////////////////////////////////////////
    // Conversion from (x, y) raster image coordinates to equivalent of latLng
    // Taken from Leaflet tutorial "Non-geographical maps"
    // http://leafletjs.com/examples/crs-simple/crs-simple.html
    ////////////////////////////////////////////////////////////////////////////
    var yx = L.latLng;

    var xy = function(x, y) {
      if (L.Util.isArray(x)) { // When doing xy([x, y]);
        return yx(x[1], x[0]);
      }
      return yx(y, x); // When doing xy(x, y);
    };


    var minZoom = 2;
    var maxZoom = 12;
    var img = [
      16384, // original width of image `karta.jpg` => x / ~longitude (0 is left)
      16384 // original height of image => y / ~ reverse of latitude (0 is top)
    ];

    /**
     * See https://stackoverflow.com/questions/34638887/leaflet-custom-coordinates-on-image
     * http://leafletjs.com/reference-1.0.3.html#transformation
     * 256 px * 2^4 = 4096 px
     */

    L.CRS.MySimple = L.extend({}, L.CRS.Simple, {
      //                      coefficients: a      b    c     d
      transformation: new L.Transformation(1 / 48, 0, 1 / 48, 0) // Compute a and c coefficients so that  tile 0/0/0 is from [0, 0] to [img]
    });

    var bounds = [xy(0, 0), xy(img)];

    var map = L.map("map", {
      crs: L.CRS.MySimple, // http://leafletjs.com/reference-1.0.3.html#map-crs
      maxBounds: bounds, // http://leafletjs.com/reference-1.0.3.html#map-maxbounds
      minZoom: minZoom,
      maxZoom: maxZoom
    });

    map.fitBounds(bounds);  //this makes the map fit the bounds we defined

    L.tileLayer('tiles/{z}/{x}/{y}.png', {
      bounds: bounds, // http://leafletjs.com/reference-1.0.3.html#gridlayer-bounds
      noWrap: true,
      attribution: 'Your Map',
      minZoom: minZoom,
      maxZoom: maxZoom,
      maxNativeZoom: 6  //how deep the actual map tiles go
    }).addTo(map);

//Experimental Zoom Viewer

    var ZoomViewer = L.Control.extend({
        onAdd: function(){
            var gauge = L.DomUtil.create('div');
            gauge.style.width = '200px';
            gauge.style.background = 'rgba(255,255,255,0.5)';
            gauge.style.textAlign = 'left';
            map.on('zoomstart zoom zoomend', function(ev){
                gauge.innerHTML = 'Zoom level: ' + map.getZoom();
            })
            return gauge;
        }
    });
(new ZoomViewer).addTo(map);
  • 1
    I'd try adding github.com/ardhi/Leaflet.MousePosition and seeing if the coordinates from your custom CRS make sense (check that the tiles and the bbox coincide). Maybe you have an off-by-one error, maybe you wanted to use 1/64 instead of 1/48. – IvanSanchez May 1 at 15:05
2

@IvanSanchez is right (tested), CRS transform should be

transformation: new L.Transformation(1 / 64, 0, 1 / 64, 0)

because you have 6 zoom levels and 2^6 = 64.

| improve this answer | |
  • Always the little things... The 48 were from another test with lesser resolution and zoom level. I hate it when I have to come here with stuff I should have found myself. But after staring too long at the same code, I kind of turn blind apparently... – Merion May 1 at 20:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.