Leaflet plus Turf.js - dynamically set bounds based on data points - leaflet

I'm new to Turf.js but have used leaflet before. Looking to move my Google maps over to leafet/turf.js
I'm trying to dynamically set the initial map view by using getBounds as per leaflet, but when using Turf.js, I get an error 'line.getBounds' is not a function.
I've also tried using bbox, to get the bounding box of my datapoints, and whilst I can draw the box on the screen, I can't seem set the initial view to it. I can set the initial view as a static point.
//Some Points
var somePoints = [
[-3.535,55.62],
[-3.54,55.61],
[-3.547,55.6],
[-3.55,55.59],
[-3.57,55.58]
];
var features = turf.points(somePoints);
var center = turf.center(features);
var map = L.map('map').setView([55.6, -3.55], 12);
L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://openstreetmap.org" target=blank>OpenStreetMap</a> Contributors',
maxZoom: 18,
}).addTo(map);
var line = turf.lineString(somePoints);
var options = {units: 'miles'};
L.geoJSON(line).addTo(map);
var along = turf.along(line, 1.25, options);
L.geoJSON(along).addTo(map).bindTooltip("my tooltip text");
along = turf.along(line, 2.123, options);
L.geoJSON(along).addTo(map).bindTooltip("12345");
var bbox = turf.bbox(line);
var bboxPolygon = turf.bboxPolygon(bbox);
L.geoJSON(bboxPolygon ).addTo(map)
var features = turf.points(somePoints);
var center = turf.center(features);

Updated code - I needed to find the bounds of the turf.js object
//path coords
var coords = [
[-3.535,55.62],
[-3.54,55.61],
[-3.547,55.6],
[-3.55,55.59],
[-3.57,55.58]
];
var features = turf.points(coords );
var center = turf.center(features);
var map = L.map('map');
L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://openstreetmap.org" target=blank>OpenStreetMap</a> Contributors',
maxZoom: 18,
}).addTo(map);
var line = turf.lineString(coords);
var options = {units: 'miles'};
L.geoJSON(line).addTo(map);
var along = turf.along(line, 1.25, options);
L.geoJSON(along).addTo(map).bindTooltip("my tooltip text");
along = turf.along(line, 2.123, options);
L.geoJSON(along).addTo(map).bindTooltip("12345");
// get center x/y
var features = turf.points(coords);
var center = turf.center(features);
var centroid_xy = center.geometry.coordinates;
var x = centroid_xy[0];
var y = centroid_xy[1];
// get bounds
var bbox = turf.bbox(line);
var b0 = bbox[0];
var b1 = bbox[1];
var b2 = bbox[2];
var b3 = bbox[3];
L.marker([55.62, -3.535]).bindPopup("Test marker").addTo(map);
var mapMarker2 = L.icon({
iconSize: [16, 16],
iconAnchor: [8, 8],
});
map.setView([y, x], 13);
map.fitBounds([[b1, b0],[b3, b2]]);

Related

Leaflet plus turf.js - color of line before & after point

I have a basic leaflet plus turf.js polyline - i'd like to be able to style the line before and after a given point. So for example - from the start to the point marker (along) (color : red). Basically, showing the portion of the route(line) that has been completed.
//path coords
var coords = [
[-3.535,55.62],
[-3.54,55.61],
[-3.547,55.6],
[-3.55,55.59],
[-3.57,55.58]
];
var features = turf.points(coords );
var center = turf.center(features);
var map = L.map('map');
L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://openstreetmap.org" target=blank>OpenStreetMap</a> Contributors',
maxZoom: 18,
}).addTo(map);
var line = turf.lineString(coords);
var options = {units: 'miles'};
L.geoJSON(line).addTo(map);
var along = turf.along(line, 1.25, options);
L.geoJSON(along).addTo(map).bindTooltip("my tooltip text");
// get center x/y
var features = turf.points(coords);
var center = turf.center(features);
var centroid_xy = center.geometry.coordinates;
var x = centroid_xy[0];
var y = centroid_xy[1];
// get bounds
var bbox = turf.bbox(line);
var b0 = bbox[0];
var b1 = bbox[1];
var b2 = bbox[2];
var b3 = bbox[3];
L.marker([55.62, -3.535]).bindPopup("Test marker").addTo(map);
var mapMarker2 = L.icon({
iconSize: [16, 16],
iconAnchor: [8, 8],
});
map.setView([y, x], 13);
map.fitBounds([[b1, b0],[b3, b2]]);
You can use your along point to split the line with TurfJS:
split = turf.lineSplit(line, along)
This gives you a FeatureCollection of 2 features, which you can use to show the two segments on the map.
https://observablehq.com/d/f379582399e8089d

Leaflet: impossible to remove specific image layer

Below are three functions that I use to respectively create a map, add an IMG-layer and remove an IMG-layer. Problem is that when I add an IMG-layer and then want to remove it before adding a new (different) IMG-layer......the removal is not taking place.
The IMG-layers that I use are simple URLs to png's.
So subsequently:
loadMap();
SetLayer("2018_10_13_16_15.png");
RemoveLayer("2018_10_13_16_15.png");
SetLayer("2018_10_13_16_30.png");
Then "2018_10_13_16_15.png" is not removed.
What am I doing wrong??
var map = L.map('map');
var imageBounds = [[50.520, 0.813], [54.295, 10.996]];
function loadMap(){
map.createPane('labels');
var positron = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png', {
attribution: cartodbAttribution
}).addTo(map);
var positronLabels = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png', {
attribution: cartodbAttribution,
pane: 'labels'
}).addTo(map);
map.setView({lat: 52.5, lng: 5.2}, 6.5);
isMap = true; //map is loaded
}
function SetLayer(url) {
IMGLayer = L.imageOverlay(url, imageBounds);
IMGLayer.addTo(map);
}
function RemoveLayer(url) {
IMGLayer = L.imageOverlay(url, imageBounds);
IMGLayer.removeFrom(map);
}

leaflet snap polyline to rout

I'm try to convert polyline to rout but I have a problem
You see in the picture below that the road is different from the polyline:
Here is my code:
var mymap = L.map('map').setView([32.661343, 51.680374], 6);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(mymap);
var markers = new L.MarkerClusterGroup();
var markerList = [];
var a = [];
var myTrip = [];
var myTrip2 = [];
for (var i = 1; i < locations.length ; i++) {
myTrip.push(new L.LatLng(parseFloat(locations[i]['Received']['lat']),parseFloat(locations[i]['Received']['lng'])));
a[0] = parseFloat(locations[i]['Received']['lat']);
a[1] = parseFloat(locations[i]['Received']['lng']);
var marker = new L.Marker(new L.LatLng(a[0], a[1]));
marker.bindPopup((locations[i]['Received']['id']).toString());
markerList.push(marker);
var polyline =L.polyline(myTrip, {color: 'blue'}).addTo(mymap);
}
var markerPatterns = L.polylineDecorator(myTrip, {
patterns: [
{offset: 25, repeat: 50, symbol: L.Symbol.arrowHead({pixelSize: 15, pathOptions: {fillOpacity: 1, weight: 0}})}
]
}).addTo(mymap);
var control = L.Routing.control({
waypoints: myTrip,
show: false,
waypointMode: 'snap',
showAlternatives: true,
useZoomParameter: true,
createMarker: function() {}
}).addTo(mymap);
1) So are the lines drawn using the raw coordinates? In other words, are the lines drawn like you do not use a routing service?
2) Leaflet Routing Machine is a plug-in that supports several routing engines, with OSRM as a default.
http://www.liedman.net/leaflet-routing-machine/
Have you tried inserting your DB coordinates to the OSRM-demo? Is it giving you the expected results?
http://map.project-osrm.org/
The high and low streets are routes because 1 of your waypoints are hitting that street and to get back on track again it have to turn around the block. It would have routed correcly if your waypoints where more accurate.

Markercluster toggle ON / OFF

They asked me for a 'toggle button' to switch the clustering on and off Can someone help me to achieve clustering on/off?
Note: loading more than 30,000 points
Create two layers, one with and one without the marker clustering and add them to the leaflet control. For example:
var littleton = L.marker([39.61, -105.02]).bindPopup('This is Littleton, CO.'),
denver = L.marker([39.74, -104.99]).bindPopup('This is Denver, CO.'),
aurora = L.marker([39.73, -104.8]).bindPopup('This is Aurora, CO.'),
golden = L.marker([39.77, -105.23]).bindPopup('This is Golden, CO.');
var cities = L.layerGroup([littleton, denver, aurora, golden]);
var citiesClustered = new L.MarkerClusterGroup();
markers.addLayer(littleton);
markers.addLayer(denver);
markers.addLayer(aurora);
markers.addLayer(golden);
var streets = L.tileLayer(mapboxUrl, {id: 'examples.map-i86knfo3', attribution: mapboxAttribution});
var map = L.map('map', {
center: [39.73, -104.99],
zoom: 10,
layers: [streets, cities]
});
var baseMaps = {
"Streets": streets
};
var overlayMaps = {
"Cities": cities,
"Clustered cities": citiesClustered
};
L.control.layers(baseMaps, overlayMaps).addTo(map);
You can also create a custom control that will de-cluster the markers but this control already exists and it's easy to implement.

Leaflet Circle radius changing dependant on y/lng coords

I am using mapbox/leaflet to display a picture of a human body rather than a regular map.
I am using leaflet draw and I need to be able to create a circle and move it around while maintaining its radius. However, when I move it towards the bottom of the map/screen, the size increases exponentialy. I want it to stay the same size.
I assume it's something to do with projection or CRS but I'm not sure what to do to stop it.
My code is :
var mapMinZoom = 0;
var mapMaxZoom = 4;
var map = L.map('map', {
maxZoom: mapMaxZoom,
minZoom: mapMinZoom,
crs: L.CRS.Simple,
noWrap: true,
continuousWorld: true
}).setView([0, 0], mapMaxZoom);
var mapBounds = new L.LatLngBounds(
map.unproject([0, 3840], mapMaxZoom),
map.unproject([4096, 0], mapMaxZoom));
map.fitBounds(mapBounds);
L.tileLayer('/tiles/{z}/{x}/{y}.png', {
minZoom: mapMinZoom, maxZoom: mapMaxZoom,
bounds: mapBounds,
attribution: 'Rendered with MapTiler',
noWrap: true,
continuousWorld: true
}).addTo(map);
var touches;
var featureGroup = L.featureGroup().addTo(map);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: featureGroup
}
}).addTo(map);
map.on('draw:created', function (e) {
featureGroup.addLayer(e.layer);
});
Any ideas? I don't need to use leaflet draw, just the L.circle would do, but it has the same issue.
Gif of issue here :
Turns out there are a load of todos in the leaflet 0.7 code... including this little gem :
// TODO Earth hardcoded, move into projection code!
_getLatRadius: function () {
return (this._mRadius / 40075017) * 360;
},
_getLngRadius: function () {
return this._getLatRadius() / Math.cos(L.LatLng.DEG_TO_RAD * this._latlng.lat);
},
Updated to 0.8Dev and it has all been fixed!