Im using leaflet to create a photo map, with my own tiles, which works as expected.
Im trying to work out how I can prevent the zoom from following this Quadtree type pattern:
I would like to be able to zoom in say increments of 25% or 100px.
An example of 100px increments:
Question: What is the logic for doing this? If it is at all possible?
My reason for wanting to do this is so that my photo map (which doesnt wrap like a normal map) can be more responsive and fit the users screen size nicely.
I made a demonstration of my issue which can be seen here
A leaflet map has several ways to control the zoom level shown, but the most obvious one is setZoom() . For example, map. setZoom(0); will set the zoom level of map to 0 .
Zoom Level+Maximum/Minimum Zoom. Google Maps has an integer 'zoom level' which is the resolution of the current view. Zoom levels are between 0 (the entire world can be seen on one map) and 21+. You can also set the minimum and maximum values for the zoom parameter.
A zoom level or scale is a number that defines how large or small the contents of a map appear in a map view . Scale is a ratio between measurements on a map view and measurements in the real-world.
Leaflet is open source and free. However the examples on leaflet site use Mapbox to render map. Mapbox is more expensive than Google map (Mapbox pricing).
The short answer is that you can only show zoom levels for which you have pre-rendered tiles. Leaflet won't create intermediary zoom levels for you.
The long answer is that in order to use do this, you need to define your own CRS scale method and pass it to your map, for example:
L.CRS.CustomZoom = L.extend({}, L.CRS.Simple, {
scale: function (zoom) {
// This method should return the tile grid size
// (which is always square) for a specific zoom
// We want 0 = 200px = 2 tiles @ 100x100px,
// 1 = 300px = 3 tiles @ 100x100px, etc.
// Ie.: (200 + zoom*100)/100 => 2 + zoom
return 2 + zoom;
}
});
var map = L.map('map', { crs: L.CRS.CustomZoom }).setView([0, 0], 0);
In this example, I've extended L.CRS.Simple
, but you can of course extend any CRS from the API you'd like, or even create your own from scratch.
Using a zoom factor which results in a map pixel size that is not a multiple of your tilesize, means your right/bottom edge tiles will only be partially filled with map data. This can be fixed by making the non-map part of such tiles 100% transparent (or same the colour as your background).
However, it is, in my opinion, a much better idea to set the tilesize to match the lowest common denominator, in this case 100px. Remember to reflect this by using the tileSize
option in your tile layer. And, of course, you will need to re-render your image into 100x100 pixels tiles instead of the 256x256 tiles you are using currently.
One caveat, the current version of LeafletJS (0.5) has a bug that prevents a custom scale() method from working, due to the TileLayer class being hardcoded to use power-of-2 zoom scaling. However, the change you need to do is minor and hopefully this will be addressed in a future release of Leaflet. Simply change TileLayer._getWrapTileNum()
from:
_getWrapTileNum: function () {
// TODO refactor, limit is not valid for non-standard projections
return Math.pow(2, this._getZoomForUrl());
},
To:
_getWrapTileNum: function () {
return this._map.options.crs.scale(this._getZoomForUrl());
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With