Leaflet issue related to svg layer ordering - javascript

In my leaflet application I am using both canvas and svg renderers.
Canvas renderer is used for markers and svg for polygon.
But because of this i am unable to order the svg rendered polygon layers using layer.bringToBack() method.
Reason why I want polygon layer to back is shown in below image.
Polygon above markers
Polygon covers my markers making them unclickable I want polygon below my markers as foll image.
Polygon below marker
In html this is how the layers are arranged, all canvas and html elements.
HTML code
Please suggest me a suitable solution for my issue

You can create a new map pane and add the markers to that pane: https://leafletjs.com/reference.html#map-pane
map.createPane('canvasMarkers'); //https://leafletjs.com/reference.html#map-createpane
var canvas = L.canvas({
pane: 'canvasMarkers'
})
L.circleMarker(map.getCenter(), {renderer: canvas}).addTo(map);
.leaflet-canvasMarkers-pane{
z-index: 600;
}
or just use the image marker pane:
var canvas = L.canvas({
pane: 'markerPane'
})
L.circleMarker(map.getCenter(), {renderer: canvas}).addTo(map);
https://plnkr.co/edit/gVuJvUw7mCVNa6Xj

Related

How to draw the circle in the mapbox

I've searched how to draw the circle in the mapbox using Javascript but couldn't find out the correct solution.
var myCircle = new MapboxCircle({lat: data.lat, lng: data.lng}, data.radius, {
editable: true,
minRadius: data.minRadius,
fillColor: data.color
}).addTo(map);
The above code is provided by Mapbox but it allows just add the circle Layer in fixed radius on the map.
But what I wanted is to draw the circle in dynamic radius by dragging.
You can pass these radii in meters using the latest version of Leaflet. The radius will change relative to zoom levels.
Here's some more information via Leaflet's documentation
L.circle([lat,lng], radius).addTo(map);
More documentation here: https://www.mapbox.com/mapbox.js/api/v2.1.9/l-circlemarker/

LeafletJS L.DivIcon HTML marker text - scale relative to map zoom

So I'm using the latest version of leaflet (v1.0.2), and am trying to dynamically apply text labels to specific lat lng points on a custom (geo aligned) map.
My issue is that I need the text on the map to maintain it's the size (as though the text is actually part of the tile image) when zooming. Using a Marker of any kind results in the text staying at its correct size. If I use something like an image overlay and add an SVG with text in, it scales with the map zoom.
I've noticed that the image overlay has a CSS3 scale added to its transform property when zooming whereas the marker does not.
Can I extend the marker to scale as the image overlay does?
I've already written code that listens to the zoom event and adjusts the font size of markers but this is CPU intensive (especially for mobile browsers) and I don't really want to render the text dynamically within svgs either!
I've provided a demo so that this makes more sense. You can see that example_1 (the marker) maintains it's size however far you zoom in or out. Example_2 (the svg image) scales relative to the map when zooming. This (Example_2) is what I'm trying to get an L.DivIcon with html text content to do!
Any help or suggestions are appreciated!
https://jsfiddle.net/z96L7hdu/
Example Code
HTML
<div id="map" style="width:500px; height:600px;"></div>
JavaScript
var map = L.map('map', {
zoomSnap: 0
}).setView([0, 0], 3);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
var img = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciICAgICB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgNTAwIDQwIj4gIDx0ZXh0IHg9IjAiIHk9IjAiIGZvbnQtZmFtaWx5PSJWZXJkYW5hIiBmb250LXNpemU9IjM1Ij4gICAgRXhhbXBsZV8yICA8L3RleHQ+PC9zdmc+";
imageBounds = [[-8.636810901898114, -12.135975261193327], [-18.28136415046407, 17.181122017133486]];
L.imageOverlay(img, imageBounds).addTo(map);
var myIcon = L.divIcon({className: 'my-div-icon', html:"Example_1"});
L.marker({lat: 0.7800052024755708, lng: 0.010986328125}, {icon: myIcon}).addTo(map);
Apologies for the late answer, but I thought it was an interesting question. You can indeed extend the L.Marker class, to create markers that resize the font of their DivIcon to match the zoom level:
L.FixedSizeMarker = L.Marker.extend({
options: {
fontSize: 12, // starting size of icon in pixels
zoomBase: 3 // Zoom level where fontSize is the correct size
},
update: function () {
if (this._icon && this._icon.tagName === 'DIV' && this._map) {
let size = this.options.fontSize * Math.pow(2, (this._map.getZoom() - this.options.zoomBase));
this._icon.style.fontSize = size + 'px';
}
return L.Marker.prototype.update.call(this);
}
});
L.fixedSizeMarker = (latlng, options) => new L.FixedSizeMarker(latlng, options);
The code above defines a new FixedSizeMarker, which behaves just like a normal Marker, but if you add a DivIcon to it, it will resize the font. It takes two options, to specify the font size in pixels, and the zoom level that you want that font size to be correct for. In the example in the OP's JSFiddle, you would use it like this:
var myIcon3 = L.divIcon({className: 'my-div-icon', html:"Example_3"});
L.fixedSizeMarker({lat: 0.7800052024755708, lng: -12.135975261193327},
{icon: myIcon3, fontSize: 24, zoomBase: 3}).addTo(map);
When using these markers, it may look better to set {markerZoomAnimation: false} in the map options. The marker size change is otherwise quite obvious when you zoom the map.
const element = marker.getElement();
element.style[L.DomUtil.TRANSFORM] = `scale(3)`;
You can use this to modify the css of a marker

Display popups with leaflet ( large dataset )

Im using Leaflet & Geojson-vt to visualize a large dataset (GeoJSON with 70,000 polylines features)
Is there any way to show smoothly a popup (it contains the polyline data) on click event on one of the multiple polylines ?
I am using geojson-vt and the example from here to add the tiles to the leaflet map.
i tried this
function onEachFeature(feature, layer) {
layer.on('click', function(e) {
layer.bindPopup(feature.properties.NUMERO);
});
}
L.geoJson($scope.dataOfFile.data, {
onEachFeature: onEachFeature
}).addTo(map);
but the map keep freezing.
Not sure I'm understanding... That example draws a canvas layer from vector tiles, this has no interaction method. If it were polygons you could use point in polygon from the original data. Since it's lines you may want to experiment with the almost over plugin using 0 weight (transparent) lines.
I had a similar issue with popups on Markers. If I added the popup before the marker was added to the map then the map would briefly freeze when all the markers were added to the map.
So instead I added the Markers to the map first. I maintained an array of all the markers then added the popups afterwards to each marker and I no longer experienced the map locking up.

Leaflet polygons cut off on map viewport while dragging

I am using mapbox library for one of my fleet_management application and i have created circle & polygon leaflet on map.
Current behavior: When dragging polygons or circles are on map only partly in the viewport, the part of the polygons or circles that were out of the viewport are cut off,
So i used panTO for center map at requested coordinate,but sometimes panTo() does not center map at requested coordinate(leaflets like circle and polygon).
this.map.panTo(this.shape._latlng);
Desired behavior: When dragging the polygon or circle it should come center of the map and it should load properly(Don't cut off).
The problem is present in https://github.com/Leaflet/Leaflet/issues/2814, see this github link.
Start observing 'isDrag'(Dragged or not) property. When latlng changes polygon will be centered.
geofenceDrag: function() {
if (!_.isNull(this.shape))
this.map.panTo(this.shape._latlng);
}
}.observes('isDrag')

Overlay with DrawingManager google map v3

I am using google map v3 and its drawingManager feature, I want to get the pixels of these Shapes either through Lat and Long or directly.
Here is the URL of drawingManager Shapes
https://developers.google.com/maps/documentation/javascript/examples/user-editable-shapes
I want to get the pixels as here with respect to the container of map
http://gmaps-samples-v3.googlecode.com/svn/trunk/latlng-to-coord-control/latlng-to-coord-control.html
like here, buts using overlay class and I want to use it for DrawingManager Shapes, need some help on it.
Thanks
To translate a LatLng to a Point use the method fromLatLngToPoint() of the current projection.
The current projection is returned by mapObject.getProjection()
However, a shape isn't always defined by LatLng's/Points.
For rectangles you must translate the points defined by the bounds, for a circle the center(and/or bounds), and for polylines/polygons the path.

Categories