Using Turf with Leaflet - leaflet

I've made a leaflet map and was trying to implement turf.
As a quick test, I just wanted to put a buffer around one of my markers. But somehow I can still only see the two markers on my map. I basically followed the steps from this document. https://lib.dr.iastate.edu/gis_tasksheets/3/
I'm not sure where I made a mistake, I hope someone can tell me.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Leaflet Map"</title>
<!-- leaflet.css, leaflet.js, turf.js von externer Quelle einbinden -->
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.4.0/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.4.0/dist/leaflet.js"></script> <!-- Load Leaflet code library-->
<script src='https://cdnjs.cloudflare.com/ajax/libs/leaflet-omnivore/0.3.4/leaflet-omnivore.min.js'></script> <!-- Load Omnivore to convert CSV to GeoJSON format -->
<script src="http://code.jquery.com/jquery-3.5.1.min.js"></script><!-- Load jQuery and PapaParse to read data from a CSV file -->
<script src="https://cdn.jsdelivr.net/npm/papaparse#5.3.0/papaparse.min.js"></script>
<script src='https://unpkg.com/#turf/turf/turf.min.js'></script>
<script>
var buffered = turf.buffer(point);
</script>
</head>
<body>
<div id='Karte' style='height: 800px; width: 100%;'></div>
<script type='text/javascript'>
var Karte = L.map('Karte').setView([48.896465, 10.996526], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
'attribution': 'Kartendaten © OpenStreetMap Mitwirkende',
'useCache': true
}).addTo(Karte);
var marker1 = L.marker([48.896465, 10.996526]).addTo(Karte);
var marker2 = L.marker([48.892750, 10.990300]).addTo(Karte);
var point = turf.point([48.896465, 10.996526]);
var buffered = turf.buffer(point, 50, {units: 'meter'});
buffer = L.geoJSON(buffered);
buffer.addTo(Karte);
</script>
</body>
</html>

Turf use geojson and geojson has the coordinate format lnglat, leaflet has latlng.
You have to swap your coords in the turf.point function:
var point = turf.point([10.996526,48.896465]);
Update
Remove also following:
<script>
var buffered = turf.buffer(point);
</script>
And change meter to meters
{units: 'meters'}
Demo

Be careful, leaflet works with [lat, lon] coordinates while geoJSON (and turf) is [lon, lat].
var coords1 = [48.896465, 10.996526];
var coords2 = [48.892750, 10.990300];
var marker1 = L.marker(coords1).addTo(Karte);
var marker2 = L.marker(coords2).addTo(Karte);
//add buffers
var point1 = turf.point([coords1[1], coords1[0]]);
var buffered1 = turf.buffer(point1, 50, {units: 'meters'})
L.geoJSON(buffered1).addTo(Karte);
var point2 = turf.point([coords2[1], coords2[0]]);
var buffered2 = turf.buffer(point2, 50, {units: 'meters'})
L.geoJSON(buffered2).addTo(Karte);
Check fiddle: https://jsfiddle.net/rp1320mf/
I would also like to add a note. Working with buffers or doing other distance-related tasks may be very inaccurate in Geographic Coordinate Systems. You should use it only if you dont really care about accuracy.

Related

geojson coordinates to line

I would like to show geojson point coordinates as a line on a leaflet map.
A simplified code with some test data looks like this:
<html>
<head>
<!-- Load leaflet library and use its styling css -->
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"> </script>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<link rel="stylesheet" href="style.css" type="text/css" /> //not included
</head>
<body>
<div class="pagewrapper">
<div id="map"></div>
<button onclick="myFunction()">Click me</button>
</div>
<script type="text/javascript">
//add map and set view
var map = L.map('map').setView([48.8,13.03],6);
// add background layer "opentopomap"
var backgroundlayer = L.tileLayer ('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png');
map.addLayer(backgroundlayer);
//get geojson data
function myFunction() {
$.ajax({
type: 'GET',
dataType:"json",
url: "https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_populated_places.geojson",
method: 'GET',
success: function(response) {
visualizer.sendDataToMap(response);
},
error:function(error) {
}
});
var visualizer = {};
//make geojson object and add to map
visualizer.sendDataToMap = function(jsonData) {
L.geoJson(jsonData).addTo(map);;
};
};
</script>
</body>
</html>
The part "visualizer.sendDataToMap(..)" might seem strange but is needed for some reason.
I managed to show the points on the map. But what I need is to show them as line (connect the first point with the second, connect the second point with the third ..).
I thought about writing the coordinates into an array which I then can use further in L.polyline() and use for some other calculations. I tried with response.geometry.coordinates and fiddled around with "coordsToLatLng" and some other suggestions I found in the forum. Maybe I need to loop through the coordinates, but I dont know how to do that. Could not get anything to work with my example.
Any hints would be appreciated.Thanks.
You can extract the coordinates from the geojson features by looping over geojson features array and mapping latitude and longitude. Then you will end up with an array of latLngs which is what you want to create the lines between the marker coordinates.
//make geojson object and add to map
visualizer.sendDataToMap = function(jsonData) {
console.log(jsonData)
L.geoJson(jsonData).addTo(map);
const latlngs = jsonData.features.map(feature => [feature.properties.LATITUDE, feature.properties.LONGITUDE]);
L.polyline(latlngs, {
color: 'red'
}).addTo(map);
};
};
Demo

Leaflet show multiple markers and setView

I have sample code that uses Leaflet and open street map. Nevertheless, i am not sure how could i add more markers. Besides i don't really understand the sense of setView function i read that it's for centering map, but what is the sense to have it since there is only one marker which should be automaticly as map center point, and from the other hand if there will be more markers what is a sense of setView?
Additional question: Is Leaflet and open street map free for commercial use?
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet.js" integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" crossorigin=""></script>
</head>
<body>
<div id="mapDiv" style="width: 800px; height: 500px"></div>
<script>
// position we will use later
var lat = 40.73;
var lon = -74.00;
// initialize map
map = L.map('mapDiv').setView([lat, lon], 13);
// set map tiles source
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © OpenStreetMap contributors',
maxZoom: 18,
}).addTo(map);
// add marker to the map
marker = L.marker([lat, lon]).addTo(map);
// add popup to the marker
marker.bindPopup("<b>ACME CO.</b><br />This st. 48<br />New York").openPopup();
</script>
</body>
</html>
</pre>
there is only one marker which should be automaticly as map center point
There is nothing in Leaflet itself that would automatically center a map view on your only Marker.
On the other hand, the sample code you show does achieve this, using setView on the same coordinates as your only Marker.
if there will be more markers what is a sense of setView?
setView gives you the ability to define which part of the map you want to initially display in your viewport, independently from your map content / layers (in your case: your markers). Obviously you can define a view that shows all your Markers at once as well.
i am not sure how could i add more markers.
Do L.marker([lat, lon]).addTo(map); as many times as needed, with lat and lon different each time as needed.
Is Leaflet and open street map free for commercial use?
Leaflet is distributed under a BSD 2-clause license, commercial use is permitted.
OpenStreetMap data is free, but not the tiles generated by OSM servers. There are many services generating similar tiles from OSM data or other sources that you can check out. E.g. you can search for "leaflet providers".
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet.js" integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" crossorigin=""></script>
</head>
<body>
<div id="mapDiv" style="width: 800px; height: 500px"></div>
<script>
// position we will use later
var lat = 40.73;
var lon = -74.00;
// initialize map
map = L.map('mapDiv');
// set map tiles source
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © OpenStreetMap contributors',
maxZoom: 18,
}).addTo(map);
/*
L.tileLayer('http://{s}.google.com/vt?lyrs=s&x={x}&y={y}&z={z}', {
maxZoom: 13,
subdomains:['mt0','mt1','mt2','mt3']
}).addTo(map);
*/
map.locate({setView: false, maxZoom: 8});
// add marker to the map
map.setView(new L.LatLng(lat, lon), 18);
marker = L.marker([lat, lon]).addTo(map);
// add popup to the marker
marker.bindPopup("<b>ACME CO.</b><br />This st. 48<br />New York").openPopup();
</script>
</body>
</html>
</pre>
Map Tiles

How to get the nearest Feature of an leaflet WMS Map?

I am quiet new to Web Services and I am facing a problem.
I have a Map linked with a WMS.
I added a basemap and my WMS Date as a tileLayer and the show up correctly on my map.
Now I want the nearest Feature to PopUp when I click anywhere on the map.
I already searched the Web but could not find a solution I understood. (https://gist.github.com/rclark/6908938)
Can anyone help me with this?
This is my code so far:
<!DOCTYPE html>
<html>
<head>
<title>XXX</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.6.0/dist/leaflet.css"
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.6.0/dist/leaflet.js"
integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
crossorigin=""></script>
<style type="text/css">
#nrwMap { height: 800px; width: 1300px;}
</style>
</head>
<body>
<div id="Map"></div>
<script type="text/javascript">
var mymap = L.map('Map').setView([51.28, 7.33], 8);
var url = 'http://www.xxx.xxx.com/wms/';
var basemap = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
id: 'mapbox/streets-v11'
})
basemap.addTo(mymap);
var featureLayer = L.tileLayer.wms(url, {
layers: 'layerName',
format: 'image/png',
transparent: true
});
featureLayer.addTo(mymap);
</script>
</body>
</html>
Leaflet.GeometryUtil has a function/feature called closestLayer. It might help.
mymap.on('click', onMapClick);
function onMapClick(e) {
nearestLayer = L.GeometryUtil.closestLayer(mymap, layersToSearch, e.latlng)
// It will return the layer, latlng of point on layer nearest to the 'click' and distance from the 'click' }

How to use GeoMet WMS with leaflet

I have been trying to make a WMS service work with leaflet. I just want to use the standard CRS=EPSG:3857 which does seem to be supported by the service. However I just cannot get the WMS layer to line up on the OpenStreetMap base layer.
This picture should line up over Canada. It works in QGIS just fine.
Here is a code pen:https://codepen.io/keenedge/pen/dybWgbM
This is the doc page for the WMS I need to use.
I've tried setting crs: L.CRS.EPS3857 in the map and in the WMS layer but it seems to have no effect.
Anyone now how to get this code pen working?
full code here:
<!DOCTYPE html>
<html>
<head>
<title>Quick Start - Leaflet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.5.1/dist/leaflet.css"
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
crossorigin="" />
<script src="https://unpkg.com/leaflet#1.5.1/dist/leaflet.js"
integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
crossorigin=""></script>
</head>
<body>
<div id="mapid" style="width: 800px; height: 800px;"></div>
<script>
var osmUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib = 'Map data © OpenStreetMap contributors';
var osm = new L.TileLayer(osmUrl, { minZoom: 1, maxZoom: 19, attribution: osmAttrib });
var wmsOptions = {
layers: 'HRDPS.NORTH.PRES_WSPD.275',
transparency: true,
format: 'image/png',
version: '1.3.0'
}
var url = 'https://geo.weather.gc.ca/geomet'
var wmsLayer = L.tileLayer.wms(url, wmsOptions);
var myMap = L.map('mapid').setView([49, -123], 2);
osm.addTo(myMap);
wmsLayer.addTo(myMap);
</script>
</body>
</html>
Thanks for your help
The HRDPS.NORTH.PRES_WSPD.275 layer from that WMS server looks exactly the same in Leaflet than in QGis, when QGis is configured to display EPSG:3857:
You're doing nothing wrong. Note that other layers from the same WMS service do cover continental Canada, or the ocean, or some other area.

How do I delete multiple markers from a Leaflet map?

I am trying to delete all the markers on my map, but code below only the last added marker will be deleted.
Is there a way to get a new a instance of map i mean on click of a button is there a way to reinitialize the map in leaflet?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://npmcdn.com/leaflet#1.0.0-rc.3/dist/leaflet.css" />
</head>
<body>
<script src="https://npmcdn.com/leaflet#1.0.0-rc.3/dist/leaflet.js"></script>
<script src="../leaflet/lib/AnimatedMarker.js"></script>
<style>
#mapid { height: 500px; }
</style>
<div id="mapid"></div>
<script>
var mymap = L.map('mapid').setView([40.68510, -73.94136], 13);
L.tileLayer('http://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', {
attribution: '© Openstreetmap France | © OpenStreetMap'
}).addTo(mymap);
var marker = L.marker([40.68510, -73.94136]).addTo(mymap);
var marker = L.marker([40.68576, -73.94149]).addTo(mymap);
var marker = L.marker([40.68649, -73.94165]).addTo(mymap);
mymap.removeLayer(marker);
</script>
</body>
</html>
Instead of adding markers to the map, add your markers to a layerGroup and add the layerGroup to the map.
You can remove the markers using clearLayers() method.
var markers = L.layerGroup([marker1, marker2]).addTo(map);
markers.clearLayers();