Leaflet: How to deal with overlapping lines? - leaflet

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.

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.

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.

Hidden points with different markers

How can I draw points and line which are not visible (they are hidden from certain point of view) - actually they are visible due to alpha, with different markers and line styles.
I can set all of the markers and lines, but I need them different in the background.

Leaflet: How to display markers behind polygons?

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

hide and show a polyline in leaflet?

I'm using leaflet for show raw itinerary to go to some markers.
I'm showing my itinerary with a leaflet polyline.
But I would like to be able to
How to hide and show a polyline in leaflet ?
I can do this :
$('.leaflet-overlay-pane').hide();
and
$('.leaflet-overlay-pane').show();
But this will show and hide all my polyline.
I would like to be able to hide and show them separately.
Thanks.
If you have a reference to the polyline
var polyline = L.polyline(...);
Then you can use
map.addLayer(polyline);//For show
map.removeLayer(polyline);// For hide
at the moment I think there is no native method to only hide/show, maybe in the 0.7 version
Other solution is to access to the object container, in a old commet from the maintainer
I don't think there's an easy solution, for tile layers at least. :( I'll try to handle this sooner.
For vectors, you can change path._container.style.display, and for markers - marker._image.style.display and marker._shadow.style.display.
Removing and adding objects on the map will also change the order of the layers (if you have more than one in your legend). The added objects will always be on top and not in the original order. I use setLatLng (markers) and setLatLngs (polylines and polygons) to do a quick trick without changing the order. Just change the latLngs to e.g.(1000,1000) outside your view.
var myLatLng0 = L.latLng(1000,1000);
var myObject = L.marker(myLatLng,{....});
myObject.latlng = myLatLng;
or
var myObject = L.polygon(myPath,{....});
myObject.path = myPath;
Hide / Show marker:
myObject.setLatLng(myLatLng0);
myObject.setLatLng(myObject.latlng);
Hide / Show polyline or polygon:
myObject.setLatLngs(myLatLng0);
myObject.setLatLngs(myObject.path);
Note: hiding polylines and polygons will also work with setLatLngs(false). setLatLng(false) for markers will give an error.