geojson coordinates to line - leaflet

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

Related

Using Turf with 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.

ArcGis layers on mapbox gl

I'm trying to add a layer from an api on ArcGis:
https://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Facility_and_Structure/MapServer/1
In leaflet it is posible with:
L.esri.featureLayer({
url:"https://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Facility_and_Structure/MapServer/1",
style: function () {
return { color: "#70ca49", weight: 2 };
}
}).addTo(map);
Is there a way to do this on mapboxgl?
Hi Jorge Monroy - Mapbox GL JS expects the data sources as such. In your case where you're wanting to load building footprints from an ArcGIS REST Service, your best bet is to load them as a geojson.
It looks like you're publishing the services from ArcServer 10.31. In that case, the way that I've loaded ArcGIS REST services is by exposing them through AGOL as explained there. If you have that option, that seems easiest. Otherwise, there are other (work-arounds)[https://gis.stackexchange.com/questions/13029/converting-arcgis-server-json-to-geojson] that I've no experience with.
Using Washington D.C. as an example, if you navigate to: http://opendata.dc.gov/datasets/building-footprints and then click on APIs, you can copy the link to the geojson service.
You can then load into MapboxGL JS through the data property of the geojson source shown there.
You can use leaflet-mapbox-gl.js to integrate leaflet and mapbox. Get token from mapbox and add it to below example to make it work.
References: https://github.com/mapbox/mapbox-gl-leaflet
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.5.0/mapbox-gl.css' rel='stylesheet' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.5.0/mapbox-gl.js'></script>
<script src="https://unpkg.com/mapbox-gl-leaflet/leaflet-mapbox-gl.js"></script>
<script src="https://unpkg.com/esri-leaflet/dist/esri-leaflet.js"></script>
<style>
html, body, #map {
margin:0; padding:0; width : 100%; height : 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var token = "";//add token before running this example
const INITIAL_VIEW_STATE = {
latitude: 45.528,
longitude: -122.680,
zoom: 13
};
var map = L.map('map').setView([45.528, -122.680], 13);
L.esri.basemapLayer("NationalGeographic").addTo(map);
var parks = L.esri.featureLayer({
url: "https://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/services/Portland_Parks/FeatureServer/0",
style: function () {
return { color: "#70ca49", weight: 2 };
}
}).addTo(map);
var gl = L.mapboxGL({
accessToken: token,
style: 'mapbox://styles/mapbox/dark-v10'
}).addTo(map);
//To add anything on mapbox, first access the mapbox using getMapboxMap()
gl.getMapboxMap().on('load', () => {
//To load any layer on mapbox
//gl.getMapboxMap().addLayer();
});
var popupTemplate = "<h3>{NAME}</h3>{ACRES} Acres<br><small>Property ID: {PROPERTYID}<small>";
parks.bindPopup(function(e){
return L.Util.template(popupTemplate, e.feature.properties)
});
</script>
</body>
</html>

unable to dispaly polygon on the map using Leaflet draw plugin

I am trying to use draw plugin from here http://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#l-draw
and tried using it locally as shown below
<html>
<head>
<title>A Leaflet map!</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css"/>
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.2/leaflet.draw.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.2/leaflet.draw.js"></script>
<style>
#map{ height: 100% }
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
var drawControl = new L.Control.Draw({
draw : {
position : 'topleft',
polygon : true,
polyline : false,
rectangle : true,
circle : false
},
edit : false
});
map.addControl(drawControl);
</script>
</body>
</html>
I am getting the drawing control and map but the polygon draw is not shown up after drawing is completed not sure how to do it
Please help in getting the polygon drawn on the map as shown in this demo
http://leaflet.github.io/Leaflet.draw/docs/examples/full.html
You must create a feature group and add the layers when they are created ...
var drawnItems = L.featureGroup().addTo(map);
map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
drawnItems.addLayer(layer);
});
see the source of http://leaflet.github.io/Leaflet.draw/docs/examples/full.html

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();

How to specify accessToken for Mapbox with Leaflet

From Mapbox site I tested this code and success:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title></title>
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.cs
<style>
body { margin:0; padding:0; }
.map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map' class='map'> </div>
<script>
var map = new L.Map('map', {
center: new L.LatLng(51.505, -0.09),
zoom: 8,
layers: new L.TileLayer('https://a.tiles.mapbox.com/v3/mapbox.world-bright/{z}
});
</script>
</body>
</html>
How can I access my own map with markers and features? I suppose the "mapbox.world-bright" would be replaced by my own map.id, but how can I set the accessToken?
For some reasons I need to stick with Leaflet, and don't want to switch to mapbox.js.
It's just a matter of using the right url in L.TileLayer. You'll need to add your mapId and token and use the correct attribution. It's also much better if you load the tiles from multiple subdomains because your browser can handle up to four connection as once. Code example:
L.tileLayer('https://{s}.tiles.mapbox.com/v4/{mapId}/{z}/{x}/{y}.png?access_token={token}', {
attribution: '© Mapbox © OpenStreetMap',
subdomains: ['a','b','c','d'],
mapId: 'myMapId',
token: 'myUserToken'
});
To add the features of your map you'll need to query those in a separate request. Here's an example using jQuery. You'll need to swap the MAPID and TOKEN for your mapid and token ofcourse:
$.getJSON('http://a.tiles.mapbox.com/v4/MAPID/features.json?access_token=TOKEN', function (data) {
// Assuming the variable map contains your mapinstance
var geojson = L.geoJson(data).addTo(map);
map.fitBounds(geojson.getBounds());
});
Here's a working example on Plunker: http://plnkr.co/edit/h8F3kC?p=preview