Leaflet: How to display markers behind polygons? - leaflet

I need icons (PNG) and polygons on my map. So I create icons as markers and polygons as polygons. Unfortunately regardless of creation order polygons are displayed "below" markers. I need is vice-versa. Is there a way, how to do it?

EDIT:
Correct default panes order in Leaflet 0.x: (from top-most to bottom-most)
objectsPane
popupPane
markerPane <= all markers icon (other than L.CircleMarker)
shadowPane <= all markers icon shadow
overlayPane <= all vectors (including L.CircleMarker)
tilePane
So just using the marker's icon shadow is not enough. You have to manually change the z-index of those panes in CSS (or through JS).
See also Leaflet: Polyline above Marker.
Original answer:
The stack order of vectors (like your polygons) and Markers is fixed in Leaflet 0.x. They are inserted into "panes" which order is (from top-most to bottom-most):
popupPane
markerPane <= all markers icon (other than L.CircleMarker)
overlayPane <= all vectors (including L.CircleMarker)
shadowPane <= all markers icon shadow
tilePane
So you should be able to easily workaround this fixed order by using the Marker's Icon shadow. If you still want the user to be able to click on your marker, simply use a transparent image for the normal icon, with the same size as your shadow image.
The situation is different in Leaflet 1.0. You can create your own panes (map.createPane), set their order by specifying their zIndex (possibly through CSS), and specify where your vectors and markers go by using their pane (and shadowPane for markers) option(s).

Related

Is there a way to check for markers whos icons intersect / overlap visibly?

I am building a map and want to use the leaflet markercluster plugin to cluster any markers that intersect visibly (the icons overlap each other). I can't seem to figure out a way to check whether the markers icons intersect though.
I've examined the documentation and the Marker objects. The marker object has no "bounds" object and has no function to return the bounds of the icon.
Yes, it's possible.
This is implemented in some Leaflet plugins, like Leaflet.LayerGroup.Collision - the technique involves fetching the computed style of each icon's HTML element to get the actual size in CSS pixels, offset those numbers by the relative pixel position of the marker's LatLng, and using a rtree data structure to speed up the calculation of the overlaps. Do have a look at the complete source for LayerGroup.Collision plugin.
Note that this technique only takes into account the rectangular bounding boxes of the icons; while it would be possible to check for the individual transparent pixels, that would involve more complex data structures and a different technique to fetch the opacity of each pixel.

polygon label displying duplicate in mapbox studio style editor

I have uploaded polygon shape zip file in mapbox tileset and created layer name as polygon_label but layer labels are showing duplicate inside polygon area.
So there is any way to centroid the polygon geometry or restrict to display duplicate label.
How to get label centroid of the polygon and remove duplication of the label from polygon area?
You need to create point geometries and use that as your source.
I have the same issue with a shapefile with land sections I imported. To get the outline of the land sections I added a fill type layer since the tileset contains polygon features. Then I add another layer of type symbol to be able to show the section address text field from the tileset features. I set the placement as "Point". But, the text field shows multiple places inside the polygons.
The only solution I have found is to make the labels appear along the boundries of the polygons by setting the placement as "Line". This still shows multiple labels. But, it is a bit more friendly for the user.

Getting the div screen location in Leaflet

I am working on a project using Leaflet. I want to place a label for objects on the map. I don’t want the label to appear on the map. I want the label placed above the map, but at the screen or div Left location from a latLng point.
I can’t seem to get the correct position using the functions available. Is there some example I can look at to give me insight? I would think Leaflet could do this.
The key here is to leverage the latLngToContainerPoint() method of L.Map - it will give you the pixel coordinates relative to the map container of the L.LatLng passed.
So create a container for a tick...
<div id="topbar"><span id="toptick">↓</span></div>
<div id="leaflet"></div>
...and use CSS to ensure it's on top of the map container, and has the same width. Then, run a function to translate the map point you want into an offset relative to the top-left corner of the map container...
function repositionEdges(){
var offset = map.latLngToContainerPoint(geopoint);
}
...run that after map initialization, and after every movement of the map...
repositionEdges();
map.on('move zoom', repositionEdges);
...and finally, inside that function, shift the tick horizontally tweaking its style...
function repositionEdges(){
var offset = map.latLngToContainerPoint(geopoint);
document.getElementById('toptick').style.left = offset.x + 'px';
}
You can see a working example at https://next.plnkr.co/edit/60qrWND50mCOQ11T?preview .
This is just one approach. The specific implementation will be different if you're using more than one point, or if you want to use <canvas> for drawing the ticks.
See also the graticule, edge scale bar and edge markers plugins from the Leaflet plugins list. Those plugins contain implementations of similar concepts.

Leaflet: How to deal with overlapping lines?

How can I deal with overlapping lines in the Leaflet map library?
I download geoJSON from the server sid and draw it right onto the map. If there are two identical entries, Leaflet draws them twice. This could be fixed by finding exact duplicated on the server side.
That however doesn't work for different datasets sharing some of the same space. As a result parts of both are drawn onto the same spot.
It appears that the lines are being rendered with the default Leaflet Polyline opacity of 0.5. If you were instantiating the Polylines yourself in code, you could override the opacity to make the lines opaque in this manner:
var myPolyLine = new L.Polyline( myPoints, { opacity: 1 } );
The line that would appear on top would then be the line that you added to the map last (one or the other is going to be on top, unless you make them both opaque and the same color). But this may be moot if you are loading in geoJSON directly and don't have control over how Leaflet renders it.

Select area by dragging mouse in gwt

I am using gwt with gwt-dnd and I want to do the following:
1. Select rectangle area by dragging the mouse
2. Select all the elements that are in this area
3. drag all selected elements.
Is there any idea?
On MouseDownEvent record the coordinates of the pointer (event.getClientX() and eventGetClientY()).
On MouseUpEvent do the same. If coordinates are different, you have a selected rectangular.
Get the widget which contains all the widgets or elements that are selectable. Loop through its children.
Compare coordinates of each widget with your rectangular (use getAbsoluteTop(), getAbdoluteLeft(), getOffsetHeight(), and getOffsetWidth()). Select widgets that are totally or partially inside the selected area.
I would add to Andrei's answer that if you to provide feedback by displaying the rectangle during selection that what we do is display the rectangle as an instance of com.google.gwt.user.client.ui.HTML with a style that displays the borders. This is updated using onMouseMove using setPixelSize and setWidgetPosition.
The library gwtquery-plugins offers a MultiSelect feature, so I will give it a try.
gwtquery-plugins