How can I shift leaflet map bounds without repeating the tiles? - leaflet

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);

Related

How can I control the zindex of a leaflet layer?

I have a codepen at https://codepen.io/ericg_off/pen/qBoPQGX which demonstrates the issue.
I would like the marker to be drawn underneath the line.
How can I change the z-index of the layers to accomplish this?
Searching has suggested several potential solutions, but nothing appears to work.
HTML
<div id="map"></div>
CSS
#map {
height: 100vh;
}
#map >>> .my-icons {
background-color: rgba(0, 255, 0, 0);
}
JS
var map = L.map("map", {
// Set latitude and longitude of the map center (required)
center: [38, -77],
// Set the initial zoom level, values 0-18, where 0 is most zoomed-out (required)
zoom: 5
});
// Create a Tile Layer and add it to the map
var tiles = new L.tileLayer(
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
{
attribution:
'© OpenStreetMap contributors',
minZoom: 3,
maxZoom: 8
}
).addTo(map);
divIcon = L.divIcon({
//html: '<i class="fa fa-map-marker fa-1x"></i>',
html: '<i class="fa fa-star fa-1x"></i>',
className: 'my-icons'
})
const markerLayer = L.layerGroup().addTo(map);
const lineLayer = L.layerGroup().addTo(map);
// markerLayer.setZIndex(-1000)
// markerLayer.bringToBack();
const from = [38, -77];
const to = [38, -100];
const fromMarker = L.marker(from, { icon: divIcon } ).addTo(lineLayer);
const line = L.polyline([from, to], { color: "green", weight: 1 }).addTo(markerLayer);
The tutorial on panes explains how to change the zIndex of a pane.
After reading the documentation on Panes and learning that the marker pane has a zindex of 600 and the overlay pane (where the lines are drawn) has a index of 400, I just needed to change the marker pane to a index of 300.
map.getPane('markerPane').style.zIndex = 300;
Updated the codepen with the answer.

Leafletjs heatmap

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>

Fit map to bounds exactly

Is there a way to fit the map exactly to bounds? (or as close a possible).
For example, in this jsfiddle, even without padding the map leaves a lot of padding above and below the points:
http://jsfiddle.net/BC7q4/444/
map.fitBounds(bounds);
$('#fit1').click(function(){ map.fitBounds(bounds); });
$('#fit2').click(function(){ map.fitBounds(bounds, {padding: [50, 50]}); });
I'm trying to fit a map as precisely as possible to a set of bounds that closely match the map shape without all the extra padding.
Setting a map's ne corner and sw corner would work as well, but I don't think that functionality exists.
You are very probably looking for the map zoomSnap option:
Forces the map's zoom level to always be a multiple of this, particularly right after a fitBounds() or a pinch-zoom. By default, the zoom level snaps to the nearest integer; lower values (e.g. 0.5 or 0.1) allow for greater granularity. A value of 0 means the zoom level will not be snapped after fitBounds or a pinch-zoom.
Because its default value is 1, after your fitBounds the map will floor down the zoom value to the closest available integer value, hence possibly introducing more padding around your bounds.
By specifiying zoomSnap: 0, you ask the map not to snap the zoom value:
var map = L.map('map', {
zoomSnap: 0 // http://leafletjs.com/reference.html#map-zoomsnap
}).setView([51.505, -0.09], 5);
// add an OpenStreetMap tile layer
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
var southWest = new L.LatLng(40.712, -74.227),
northEast = new L.LatLng(40.774, -74.125),
bounds = new L.LatLngBounds(southWest, northEast);
L.marker([40.712, -74.227]).addTo(map);
L.marker([40.774, -74.125]).addTo(map);
map.fitBounds(bounds);
$('#fit1').click(function() {
map.fitBounds(bounds);
});
$('#fit2').click(function() {
map.fitBounds(bounds, {
padding: [50, 50]
});
});
body {
padding: 0;
margin: 0;
}
#map {
height: 300px;
margin-top: 10px;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.2.0/dist/leaflet.css">
<script src="https://unpkg.com/leaflet#1.2.0/dist/leaflet-src.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<button id="fit1">fit without bounds</button>
<button id="fit2">fit with bounds</button>
<div id="map"></div>

Leaflet Circle radius changing dependant on y/lng coords

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!

Leaflet setMaxBonds causing error

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