leaflet layer interrupting interactivity of base layer - javascript

I am working on a project based on the Leaflet Choropleth Tutorial.
In my map, I have three base layers that the user switches between
var basemaps= {
"layer1": layer1,
"layer2": layer 2,
"layer3": layer 3
};
Each of these layers highlights and displays popup information just like in the Choropleth template.
I also have layers that display labels(values) for each region, depending which one is active.
var activelabel = L.layerGroup();
var showlabels = {
"labels": activelabel
};
map.on('baselayerchange', function (event) {
activelabel.clearLayers();
switch (event.layer) {
case layer1:
label1.addTo(activelabel);
break;
case layer2:
label2.addTo(activelabel);
break;
case layer3:
label3.addTo(activelabel);
break;
}
});
My problem, is that when the labels are active, if the user hovers over the part of the region where the label is, the highlight feature and info box do not display any information.
I am trying to find a way to make the activelabel layer invisible, so that the hover still works.
I found the tutorial on Map Panes, which seems like the solution to my problem, but it doesn't seem to do anything.
I'm not sure if i'm putting the pane information in the wrong spot, or if this doesn't actually work like I think it should? I've tried changing the xIndex everywhere from 0 to 700 and it doesn't seem to make a difference?
map.createPane('labels');
map.getPane('labels').style.zIndex = 700;
map.getPane('labels').style.pointerevents = 'none';
I've tried putting the pane: 'labels' code here, where I format my labels
var createLabelIcon = function(labelClass,labelText){
return L.divIcon({
className: labelClass,
html: labelText
})
};
as well as here, where I create the layer group.
var label1 = new L.layerGroup();
makelabel1();
Any help would be appreciated. Thank you.

I figured out a solution to this. I have three separate .js files where I add all the layers containing labels to my layergroups.
If I add {interactive: false} to each instance of .addLayer in each file, the labels to not interrupt the mouse hover.
I'm not sure why this doesnt work when I add interactive:false to the layer group as opposed to each addLayer line, but it seems to be working.

Related

Using a polygon as a marker with leaflet

I currently have a map for a game with item locations, i'm wanting to add animals to the side bar/legend but as a polygon instead of a marker, i get how to draw a polygon but i cannot figure out how to make it only show when selected from the legend (or even how to add one to the legend). Sorry for this very basic question.
I'm really very new to this, I only started learning about leaflet to make a map for a game, so i'm not really sure how to explain what i've done.. so i'll try my best:
I have a list of markers like:
var marker_combulbrsh2 = L.marker([-1474, 2661.5])
.bindPopup('Common Bullbrush');
and then i have the layer groups that have lines this like:
var lg_combulbrsh = L.layerGroup([
marker_combulbrsh1, marker_combulbrsh2
]);
and then an overlay list with the layer groups like:
"<i>Common Bullbrush" : lg_combulbrsh,
and then i have them display on the map with:
L.control.layers(null, overlays, {collapsed:true, position: 'topleft'}).addTo(map);
I am wanting to add a series of polygons that are selectable from the side panel/legend in the same way that the above L.marker is, so that I don't have to add individual locations that are close together for adding animal locations to the map.
`var polygonPoints = [
[-2263, 432],
[-2361, 435],
[-2337, 674],
[-2263, 432]];
var poly = L.polygon(polygonPoints).addTo(map);`
The code above draws the polygon i want to draw, but it's permanently there and I haven't been able to figure out how to make it a selectable item like the L.markers are. I figure i have to add the polygon as a marker some how and then have that marker added to the layer group and create an entry for them on the overlay list and then have them display through L.control.layers - I just cannot wrap my head around how though.
again, sorry for this very basic question and thank you to anyone who reads. if you are able to help with this and would like credit added to the website with a link to your work or social media or something i'm more than happy to do so.

How to change polygon pane in Leaflet (custom pane)

I figured out how to create a polygon in a custom pane using the Working with Map Panes tutorial and this Stack Overflow question with its associated Fiddle.
Can I switch the polygon to a different (custom) pane after it has been created?
I create a polygon in a custom pane like so:
// create custom pane
mymap.createPane('polygonView');
var polygonViewPane = mymap.getPane('polygonView');
polygonViewPane.style.zIndex = 300;
// with custom renderer
var myrenderer = L.svg({
pane: polygonViewPane
});
// create polygon in a custom pane (note the `renderer:myrenderer` or `pane:polygonViewPane` both work)
var myPoly = L.polygon([
[51.509, -0.08],
[51.503, -0.06],
[51.51, -0.047]
], {
fillOpacity: 1,
pane: polygonViewPane
}).addTo(mymap);
It would seem like I should be able to switch the pane with something like:
// changes pane in options.pane, but appearance on the map is same
myPoly.setStyle({pane: polygonViewPaneTop});
// also does not work (command fails without output in console?)
myPoly.setStyle({renderer: myrenderer2});
but neither of these are working. I can switch the zIndex of the whole pane with polygonViewPane.style.zIndex = 800;, but I will usually have multiple polygons on that main pane, and I only want to bring one to the front of all of my layers.
https://jsfiddle.net/kbkxf220/
EDIT:
Updated Fiddle incorporating IvanSanchez's answer:
https://jsfiddle.net/kbkxf220/3/
// THIS WORKS; polygon switches pane and `myPoly.options.pane` shows new pane.
myPoly.removeFrom(mymap);
myPoly.setStyle({pane: polygonViewPaneTop, renderer: myrenderer2});
myPoly.addTo(mymap);
Note that you need to switch renderer for the polygon to switch panes on the map view (see inspect element) and switch pane for myPoly.options.pane to properly display the new pane.
No, Leaflet doesn't allow to change panes on the fly.
Remove the layer from the map, change its options, then re-add it.
If your problem is bringing lines/polygons on top of each other, remember that you can call bringToFront() on them.

How to remove markers when use Leaflet Slider to show changes over time

I am using Leaflet Slider, of Dennis Wilhelm, to try to show changes in data over a period of five years in a Leaflet map.
I am trying to get that when the user move the cursor over the slider, some marker disappear and some other appear. So far, I only get that the new marker appear on top of the old marker.
So, my question is:
How can I remove markers when use Leaflet Slider to show changes over time? What changes I have to do in the original SliderControl.js?
Thanks in advance!
Below is the link to Dennis Wilhelm's Leaflet Slider code:
https://github.com/dwilhelm89/LeafletSlider/blob/master/SliderControl.js
It might be late, but for anyone who is looking for it now. If you want to show changes over time and want to show specific points at a time, pass the parameter follow as true, so the slider would show only one point at a time.
var sliderControl = L.control.sliderControl({
position: "topleft",
layer: layername,
follow: true
});
When I need to update markers in Leaflet I add my markers to a layergroup. I then add that layer group to the map once, and clear it before adding new markers. Below is a code snippet of what it might look like. That way all markers are cleared out before adding new ones. I hope that helps you.
var map = L.map('map').setView([0, 0], 2);
var markerLayerGroup = new L.LayerGroup();
map.addLayer(markerLayerGroup);
function addMarkers() {
markerLayerGroup.clearLayers();
markerLayerGroup.addLayer(markerVariable);
}
I have used the range: true property to overcome this issue in a project i'm working on.
It is suboptimal however given that you need to move 2 sliders, both a Left and right slider, which represent the limits of the period you're interested in viewing, rather than just one for say a month end snapshot.
Also one increment of the slider will add 1 point to the map rather than adding a whole lot at once.
I expect there are solutions to these problems by extending the class but i've not had the time to do that yet.
here's my code:
var sliderControl = L.control.sliderControl({
position: "topleft",
layer: membMarksCurrent,
range: true
});
map.addControl(sliderControl);
sliderControl.startSlider();

How can I use a leaflet layer control to toggle a d3 svg overlay?

I have 3 d3 svgs I want to put on the same leaflet map. I would like to be able to control them with the same ease as leaflet layers.
Here is code that works, but is janky.
The relevant part is lines 75 to the end, where I create a custom layer control tied specifically to my d3 svg group, instantiate it, and pop it in the overlays hash before addTo(map).
var lineLayer = L.Class.extend({
initialize: function () {
return;
},
onAdd: function (map) {
railLineGroup.style("display", "block");
},
onRemove: function (map) {
railLineGroup.style("display", "none");
},
});
var railLineLayer = new lineLayer();
overlays["Rail Lines"] = railLineLayer;
L.control.layers(baseLayers, overlays).addTo(map);
There's got to be a better way to do this. For instance, because this is a hack, the layer control does not know that the layer has already been activated, so the checkbox is unchecked.
Any help would be greatly appreciated!
I really would recommend you to have a look at Vector OSM, specially at tilejson.js. There you see a proper implementation which makes layer control work with SVG overlay.

How to add square tiles to leaflet map with hovering effect?

I want to split my map into tiles/territories. So i've prepared another layer showing squares. But this layer is full of .png image files so there is no data/object for this squares.
I've also tried to draw squares with leaflet's geometry objects. But it causing performance issues, there is times to show 500+ squares.
If you develop something like that what method would you prefer? UTFGrid? GeoJSON/Geometry? Or maybe any other better solution?
UPDATE:
Actually i don't want to get data belongs to square's territory i just want to change the square's color somehow i mean somehow i want to highlight that area maybe i can create a rectangle on the fly when user mouseover.
And im trying avoid to use UTFGrid for just highlighting. But I want to ensure the UTFGrid is the only way or not.
This sounds like the exact reason that UTFGrid was created! This site links to the tutorial that I used when learning UTFGrid, and it is solid.
Updated after your update:
MarkerCluster might have the look/feel you are going after, they basically paint a polygon onto the map layer. You can check the source here, and here's a relevant snippet:
_showCoverage: function (e) {
var map = this._map;
if (this._inZoomAnimation) {
return;
}
if (this._shownPolygon) {
map.removeLayer(this._shownPolygon);
}
if (e.layer.getChildCount() > 2 && e.layer !== this._spiderfied) {
this._shownPolygon = new L.Polygon(e.layer.getConvexHull(), this.options.polygonOptions);
map.addLayer(this._shownPolygon);
}
},

Categories

Resources