Leaflet Bounds Not Updated - leaflet

I have a problem with a function allowing to change the position of a marker on my leaflet map.
I update the coordinates of my map with a zoom to 17.
However when I call my recupObjectByLatLong function by passing mapRef.current.getBounds (), the map has not yet updated the bounds in relation to the zoom of the new coordinates.
To prevent the problem today, I put a setTimeout, however I don't think this is the cleanest solution ...
function changePositionMarker(e) {
const latitude = e.latlng.lat;
const longitude = e.latlng.lng;
mapRef.current.setView(L.latLng(latitude, longitude), 17);
markerRef.current.setLatLng([latitude, longitude]);
markerRef.current.bindPopup('test').openPopup();
setTimeout(() => {
recupObjectByLatLong(mapRef.current.getBounds().getNorthEast().lat, mapRef.current.getBounds().getNorthEast().lng, mapRef.current.getBounds().getSouthWest().lat, mapRef.current.getBounds().getSouthWest().lng);
}, 1000);
}

Related

Leaflet - custom tile layer - get lat long coordinates

My requirement is be able to call an api which returns me GeoJson - this api requires the bounding box in lat/long coordinates. I would like to be able to have this api called for each tile but am stuck trying to convert the L.Coords x,y,z values to bounds.
I would have thought this would be a common use case - is there another way I should be approaching this problem?
Code demonstrates my approach.
L.TileLayer.Custom = L.TileLayer.extend({
getTileUrl: (coords: L.Coords) => {
const bounds = coords?.getBounds();
const geometry = {
ymin: bounds?.getSouth(),
xmin: bounds?.getWest(),
ymax: bounds?.getNorth(),
xmax: bounds?.getEast()
};
// call api Api.call(geometry).then(...)
},
});
L.tileLayer.custom = function () {
return new L.TileLayer.Custom();
};
L.tileLayer.custom().addTo(map);

Mapbox GL JS: zoom to filtered polygon?

I am using Mapbox GL JS to display a polygon layer. I would to allow the user to choose a name from a dropdown, and then highlight and zoom to the matching polygon.
I already know how to highlight the matching polygon using map.setFilter, but I don't know how to zoom to the bounds of the matching polygon. This is my current code:
map.addLayer({
'id': 'polygon_hover',
'source': 'mysource',
'source-layer': 'mylayer',
'type': 'fill',
'paint': {
'fill-color': 'red',
"fill-opacity": 0.6
},
"filter": ["==", 'CUSTNAME', ""]
});
// Get details from dropdown
custname.on("change", function(e) {
// get details of name from select event
map.setFilter('polygon_hover', ["==", 'CUSTNAME', name]);
// Get bounds of filtered polygon somehow?
// var bounds = ??;
// map.fitBounds(bounds);
});
I have examined the Mapbox example of zooming to bounds, but it assumes that you already know what the bounds are.
Is there any way it's possible to get the bounds of the polygon matching a map filter in Mapbox?
I've the following code to fitBounds to Polygon center coords:
var coordinates = f.geometry.coordinates[0];
var bounds = coordinates.reduce(function (bounds, coord) {
return bounds.extend(coord);
}, new mapboxgl.LngLatBounds(coordinates[0], coordinates[0]));
map.fitBounds(bounds, {
padding: 20
});
Where f is one Feature.
I found a solution to your problem. Leaflet has a polygon Class which takes an Array of polygon coordinates and has a function called getBounds() that returns south west and north east bounds. However, Leaflet doesn't follow the convention of LngLat, its format is LatLng. Therefore, you have to switch it. I took an example out from Mapbox Show drawn polygon area, and added exactly what you're looking for.
var polygon = data.features[0].geometry.coordinates;
var fit = new L.Polygon(polygon).getBounds();
var southWest = new mapboxgl.LngLat(fit['_southWest']['lat'], fit['_southWest']['lng']);
var northEast = new mapboxgl.LngLat(fit['_northEast']['lat'], fit['_northEast']['lng']);
var center = new mapboxgl.LngLatBounds(southWest, northEast).getCenter();
// map.flyTo({center: center, zoom: 10});
map.fitBounds(new mapboxgl.LngLatBounds(southWest, northEast));
I see that the question is still relevant - I solved it making a separate request to the database containing all points of a given polygon and building bounds [[minLng, minLat], [maxLng, maxLat]].
All attempts to address geometry of already rendered or source features didn't work for me - most probably because Mapbox doesn't keep initial geoJSON in the tiles.

How to enable dragging of map in leaflet.js

I am using leaflet.js to visualize the map. I updating the markers on the map using the following code
map.dragging.enable();
data.forEach(function(d)
{
lat=d.lat;
lon=d.lon;
road=d.road;
detector=d.detector;
markers.push((new L.circle([lat, lon], 200, {
color: 'yellow',
fillColor: '#f0f',
fillOpacity: 0.5
})).bindPopup("Road Name:"+road+"<br>Detector ID: "+detector))
});
for (var i = 0; i < markers.length; i++) {
map.addLayer(markers[i]);
}
map.setView([lat, lon],13);
map.dragging.enable();
I am enabling the dragging of the map both before and after the loop. But the map is still not draggable after the update operation. But initially when i have not updated the map markers its draggable. But when the marker locations are updated it becomes non draggable. How can i solve this problem?
Don't you have to show us where you are declaring lat, lon? Is it outside of scope? You could be calling a setView with invalid parameters which might cause Leaflet to throw an error.

Leaflet: Removing markers from map

I load some lat / lon info, then use it to build a polyline.
I then want to add a marker at each of the polyline vertices that will show when the polyline is clicked.
The vertices should disappear if a different (or the same) polyline is clicked.
The code below creates the polyline and the vertex markers.
But the vertex markers do not ever disappear.
I've tried to do this several ways with the same result. I've tried storing the vertex markers in an array and adding them directly to the map, then map.removeLayer'ing them. That doesn't work either. Nor does it work if I use an L.featureGroup instead of a layerGroup.
Clearly I've missed the point somewhere as to how markers can be removed. Could someone point me at the error in my methodology?
// trackMarkersVisible is a global L.layerGroup
// success is a callback from an ajax that fetches trackData, an array f lat/lon pairs
success: function (trackData) {
// build an array of latLng's
points = buildTrackPointSet(trackData, marker.deviceID);
var newTrack = L.polyline(
points, {
color: colors[colorIndex],
weight: 6,
clickable: true
}
);
$(newTrack).on("click", function () {
trackMarkersVisible.clearLayers();
$.each(points, function(idx, val) {
var tm = new L.Marker(val);
trackMarkersVisible.addLayer(tm);
});
map.addLayer(trackMarkersVisible);
});
}
Without a JSFiddle or Plunker it's hard to say because i'm not sure what behaviour your getting but using the clearLayers() method of L.LayerGroup should remove all layers from that group. I would check in the onclick handler if the group already has layers: group.getLayers().length === 0 If the group is empty, add the markers, if the group has layers use clearLayers. Example in code:
polyline.on('click', function (e) {
if (group.getLayers().length === 0) {
e.target._latlngs.forEach(function (latlng) {
group.addLayer(L.marker(latlng));
});
} else {
group.clearLayers();
}
});
This works for me, see the example on Plunker: http://plnkr.co/edit/7IPHrO?p=preview
FYI: an instance of L.Polyline is always clickable by default so you can leave out the clickable: true

Start-Marker from geojson polyline

i have a map with some walking- and bike-routes and popups with a few details an a pic. Now i want to set a marker on the first vertex of a geojson polyline, but i cant find out how. Btw. i´m new to leaflet/mapbox, and i put my map togehter from code snippets.
Here is the map now:
This is how i create the polylines now. I call them via layercontrol.
var mtb = L.geoJson(radjs, {
filter: function (feature, layer) {
if (feature.properties) {
// If the property "underConstruction" exists and is true, return false (don't render features under construction)
return feature.properties.typ === 'mtb';
}
return true;
},
style: {
"color": '#6699cc',
dashArray: '',
"weight": 4,
"opacity": 0.6
}, onEachFeature: onEachFeature2}).addTo(rad);
Thank you for your help,
Marc
You could just add a Feature to your geojson with the latitude and longitude like the do it in the Leaflet GeoJSON Example.
Probably it will be more convenient to read the geometry.coordinates from geojson features and define a new marker.
Beside you have an error on line 569. You should change:
var map = L.mapbox.map('map','',{
to:
var map = L.mapbox.map('map',null,{
Create a simple marker object and add it to the map.
marker = L.marker([0, 0], {
icon: L.mapbox.marker.icon()
}).addTo(map)
Then set the latitude and longitude to the first coordinates of your geoJSON. Assuming your geoJSON is set to the var geojson, you can access the coordinates by indexing into the array.
marker.setLatLng(L.latLng(
geojson.coordinates[0][1],
geojson.coordinates[0][0]))