0
votes

I have made simple leaflet example. It renders procedural tiles with position and zoom displayed on each one. Projection and CRS are configured to map lat and lng directly to x and y without any transformation at zoom=20. You can easily check this by clicking on the map and viewing popup with coordinates.

var naturalZoom = 20;

L.Projection.Direct = {
    project: function (latlng) {
        return new L.Point(latlng.lat, -latlng.lng);
    },

    unproject: function (point) {
        return new L.LatLng(point.x, -point.y);
    }
};

L.CRS.Wall = L.extend({}, L.CRS, {
    projection: L.Projection.Direct,
    transformation: new L.Transformation(1, 0, -1, 0),

    scale: function (zoom) {
        return Math.pow(2, zoom-naturalZoom);
    }
});

var map = L.map('map', {
    crs: L.CRS.Wall,
    maxBounds: new L.LatLngBounds([0,0], [4096, 4096])
});
map.setView([0,0], naturalZoom);

I am trying to restrict the bounds of the map (uncomment line #26 of the code in jsfiddle example) but this breaks the dragging of the whole layer. Does anyone have similar problem with custom crs and maxBounds? Can this be a bug in the leaflet library?

Thank you for any help.

1
Leaflet animates dragging, when you let go of the mouse, it still moves a little further. You're setting the bounds very tight. Therefore you hit the wall a lot when dragging. I don't see anything else out of the ordinary happening. Can you explain what makes you say the dragging breaks?flup
Bounds are not tight, they are set to rect(0,0,4096,4096). Please take a look at the example jsfiddle.net/cMjZa/4 Just try dragging and zooming, to see what i am talking about.Viktor Nikolaiev
Aha! Yes, now I see it! Am I right to think that one screen pixel is one map pixel, though? Then it's somewhat tight.flup
Yes at zoom=20, which is default in my case, pixels are identical to map points. What i'm need is to restrict the world size. By default world size is -180..180 and -90..90. I didn't find a function which can change this, so tried to use maxBounds option. But it the bug.Viktor Nikolaiev

1 Answers

2
votes

I think the problem is that your project/unproject is broken? Anyway, you don't have to do any of this manually, Leaflet.js provides a CRS to convert between px and latlng, set your map up like this:

var map = L.map('map', {
  maxZoom: 20,
  minZoom: 20,
  crs: L.CRS.Simple
}).setView([0, 0], 20);

and then set the map bounds (where my image is 1024x6145):

var southWest = map.unproject([0, 6145], map.getMaxZoom());
var northEast = map.unproject([1024, 0], map.getMaxZoom());
map.setMaxBounds(new L.LatLngBounds(southWest, northEast));

You can then add markers by:

var m = {
  x: 102, // px coordinates on full sized image
  y: 404
}
var marker = L.marker(map.unproject([m.x, m.y], map.getMaxZoom())).addTo(map);

Note we are using map.unproject to go from px to latlng.

I wrote how to do this in more detail, including how to split up your image but the above gives you the basic gist.