My leaflet map with custom tiles is working properly until I try to set the max bounds for my map.
var SWCorner = new L.LatLng(-312, -180);
var NECorner = new L.LatLng(180, 312);
var MaxBounds = new L.LatLngBounds(southWest, northEast);
var map = L.map('map', { crs: L.CRS.EPSG4326, draggable: true }).setView([-63, 65], 1);
map.setMaxBounds(MaxBounds);
L.tileLayer('http://localhost:9000/CustomIcons/tile_{z}_{x}-{y}.png', {
boxZoom: false,
minZoom: 1,
maxZoom: 5,
tms: true,
noMoveStart: true,
keyboardPanOffset: 10,
noWrap: true,
tileSize: 350
}).addTo(map);
Things I have tried are:
var SOMmap = L.map('SOMmap', { crs: L.CRS.EPSG4326 maxBounds: new L.LatLngBounds([-312,-180],[180,312]}).setView([-63, 65], 1);
var SOMmap = L.map('SOMmap', { crs: L.CRS.EPSG4326,
draggable: true, maxBounds: MaxBounds }).setView([-63, 65], 1);
var SOMmap = L.map('SOMmap', { crs: L.CRS.EPSG4326,
draggable: true
}).setView([-63, 65], 1).setMaxBounds(MaxBounds);
Whenever I try to set the max bounds, the tiles always vanish. How do I need to call the setMaxBounds?
From http://spatialreference.org/ref/epsg/4326/
EPSG:4326
WGS 84
WGS84 Bounds: -180.0000, -90.0000, 180.0000, 90.0000
Projected Bounds: -180.0000, -90.0000, 180.0000, 90.0000
Scope: Horizontal component of 3D system. Used by the GPS satellite navigation system and for NATO military geodetic surveying.
Last Revised: Aug. 27, 2007
Area: World
So your values for the LatLngBounds are not valid in this projection lat should be between -180 and 180 , lng between -90 and 90
Related
I have a codepen demonstrating the issue at https://codepen.io/ericg_off/pen/KKoJvbK
I am using leaflet 1.8.0.
I have adjusted the map's maxBounds (const maxBounds = [[-90, -480], [90, -120]];) so the left and right edges of the map are
Left Edge ----- Right Edge
To accomplish this, I needed to allow the tileLayer to wrap around the antemeridian...so noWrap retains the default value of true.
So, when I zoom out, I get:
But, I would like to have similar behavior to what would happen if I left the maxBounds set to const maxBounds = [[-90, -180], [90, 180]]; and set noWrap: true which would look like:
i.e. the gray background outside of the maxBounds.
How can I do this?
HTML:
<div id="map"></div>
CSS:
#map {
height: 100vh;
}
JS:
const maxBounds = [
[-90, -480],
[90, -120]
];
// const maxBounds = [
// [-90, -180],
// [90, 180]
// ];
var map = L.map("map", {
center: [38.89, -77.03],
zoom: 3,
maxBounds
});
var tiles = new L.tileLayer(
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
{
minZoom: 0,
maxZoom: 8,
// noWrap: true
}
).addTo(map);
Leaflet has a nice heatmap layer, but which I am finding difficulties to handle when zooming into the map.
I can set the data to have a radius of 0.1 and they look very nice when I have a zoom level of 8.
If a user zooms in to a level of, say 10, the map becomes entirely covered by the heatmap.
Also, if the user zooms out to level 6 the heatmap becomes invisible.
Can anyone, please, let me know how to scale the radius of data points of the heatmap, so as to obtain a similar effect to that of Google Maps Heatmap?
Thank you!
EDITED:
I used the heatmap from Patrick Wield heatmap.js
The code I used is as follows:
<script>
window.onload = function() {
var myData = {
max: 1000,
data: [
{lat: 50.32638, lng: 9.81727, count: 1},
{lat: 50.31009, lng: 9.57019, count: 1},
{lat: 50.31257, lng: 9.44102, count: 1},
]
};
var baseLayer = L.tileLayer(
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © CloudMade',
maxZoom: 18,
minZoom: 7
}
);
var cfg = {
"radius": .1,
"maxOpacity": 1,
"scaleRadius": true,
"useLocalExtrema": true,
latField: 'lat',
lngField: 'lng',
valueField: 'count'
};
var heatmapLayer = new HeatmapOverlay(cfg);
var map = new L.Map('map', {
center: new L.LatLng(50.339247, 9.902947),
zoom: 8,
layers: [baseLayer, heatmapLayer]
});
heatmapLayer.setData(myData);
layer = heatmapLayer;
};
</script>
I have a standard leaflet map, for various reasons (high resolution data) I need to zoom in further than the default settings allow, to centimetres.
how do I override this max zoom setting?
My code is currently:
<script>
// Set the projection system using proj4js and proj4leafletjs(not sure this works yet)
var crs = new L.Proj.CRS('EPSG:32365',
'+proj=utm +zone=35 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs',
{
resolutions: [
8192, 4096, 2048, 1024, 512, 256, 128
],
origin: [0, 0]
})
// Creating map options
var mapOptions = {
center: [38.623162,27.9282893],
zoom: 10,
zoomSnap: 0.25
}
// Creating a map object
var map = new L.map('map', mapOptions);
// Creating a Layer object
var layer = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
// Adding layer to the map
map.addLayer(layer);
</script>
I have used the first code to display a Bergfex layer in OpenLayers and this works up to high zoom layers whereas I cannot get a Leaflet layer to work above zoom 12.
Does anybody know if this is a limitation or are other elements needed? I have tried it both as a base layer or overlay. Both sets of code are below.
OpenLayers:
bergfex = new OpenLayers.Layer.XYZ("Bergfex Topo Austria",
"http://static7.bergfex.at/images/amap/${z}$folder/${z}_${x}_${y}.png", {
sphericalMercator: true,
buffer: 0,
opacity: 0.5,
isBaseLayer: false,
visibility: false,
attribution: "© 2008, 2013 BEV,<a href='http://www.bergfex.at'>bergfex GmbH</a>",
getURL: function(bounds) {
var path = OpenLayers.Layer.XYZ.prototype.getURL.apply(this, arguments);
var parts = path.split("$folder/");
var z = parseInt(parts[0].substr(-2));
path = path.replace("$folder", z >= 14 ?
"/" + parts[1].substr(3, 2 + z - 14) : "");
return path;
}
});
Leaflet:
bf = L.tileLayer('http://static7.bergfex.at/images/amap/{z}/{z}_{x}_{y}.png', {
maxZoom: 18,
attribution: bergfexAttribution,
detectRetina: true
})
The URL template used in your Leaflet code ('http://static7.bergfex.at/images/amap/{z}/{z}_{x}_{y}.png') has tiles available only above Austria, and from zoom levels 8 to 13 (included). There are no tiles (404 error) from zoom 0 to 7 (included), and zoom 14 and above.
To avoid unnecessary network request, you might be interested in using minZoom and bounds Tile Layer options:
bf = L.tileLayer('http://static7.bergfex.at/images/amap/{z}/{z}_{x}_{y}.png', {
maxZoom: 13,
minZoom: 8,
bounds: [
[45, 10], // I just used arbitrary bounds, you should adjust them.
[50, 15]
],
attribution: bergfexAttribution,
detectRetina: true
});
Now to go beyond zoom level 13, your OpenLayers code changes that URL template dynamically (see the getURL options), so it looks like 'http://static7.bergfex.at/images/amap/{z}/{x2}/{z}_{x}_{y}.png' with x2 being the first 2 digits of x at zoom 14 and the first 3 at zoom 15 (maybe and so on).
You will need to do a similar "URL template dynamic adjustment" for Leaflet. Unfortunately, Leaflet does not expose a similar getURL option as OpenLayers. Nevertheless, you could modify the getTileUrl method of your bf Tile Layer instance so that it does that adjustment (you would have to adapt your OpenLayers code):
var bf2 = L.tileLayer('http://static7.bergfex.at/images/amap/{z}/{x2}/{z}_{x}_{y}.png', {
maxZoom: 18, // Looks like tiles are available only up to 15 included, or the URL template changes again?
minZoom: 14,
bounds: [
[45, 10], // I just used arbitrary bounds, you should adjust them.
[50, 15]
],
attribution: bergfexAttribution,
detectRetina: true
});
bf2.getTileUrl = function (tilePoint) {
var x2 = Math.floor(tilePoint.x / 100);
return L.Util.template(this._url, L.extend({
s: this._getSubdomain(tilePoint),
z: tilePoint.z,
x: tilePoint.x,
y: tilePoint.y,
x2: x2
}, this.options));
};
bf2.addTo(map);
Demo: http://jsfiddle.net/ve2huzxw/217/
I am using mapbox/leaflet to display a picture of a human body rather than a regular map.
I am using leaflet draw and I need to be able to create a circle and move it around while maintaining its radius. However, when I move it towards the bottom of the map/screen, the size increases exponentialy. I want it to stay the same size.
I assume it's something to do with projection or CRS but I'm not sure what to do to stop it.
My code is :
var mapMinZoom = 0;
var mapMaxZoom = 4;
var map = L.map('map', {
maxZoom: mapMaxZoom,
minZoom: mapMinZoom,
crs: L.CRS.Simple,
noWrap: true,
continuousWorld: true
}).setView([0, 0], mapMaxZoom);
var mapBounds = new L.LatLngBounds(
map.unproject([0, 3840], mapMaxZoom),
map.unproject([4096, 0], mapMaxZoom));
map.fitBounds(mapBounds);
L.tileLayer('/tiles/{z}/{x}/{y}.png', {
minZoom: mapMinZoom, maxZoom: mapMaxZoom,
bounds: mapBounds,
attribution: 'Rendered with MapTiler',
noWrap: true,
continuousWorld: true
}).addTo(map);
var touches;
var featureGroup = L.featureGroup().addTo(map);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: featureGroup
}
}).addTo(map);
map.on('draw:created', function (e) {
featureGroup.addLayer(e.layer);
});
Any ideas? I don't need to use leaflet draw, just the L.circle would do, but it has the same issue.
Gif of issue here :
Turns out there are a load of todos in the leaflet 0.7 code... including this little gem :
// TODO Earth hardcoded, move into projection code!
_getLatRadius: function () {
return (this._mRadius / 40075017) * 360;
},
_getLngRadius: function () {
return this._getLatRadius() / Math.cos(L.LatLng.DEG_TO_RAD * this._latlng.lat);
},
Updated to 0.8Dev and it has all been fixed!