Geographic Information Systems Asked by Devdatta Tengshe on January 7, 2021
I have a simple Leaflet map, where The user can draw a Circle, using Leaflet.Draw.
When you use the following code to get the geometry,
map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
console.log(layer.toGeoJSON());
drawnItems.addLayer(layer);
});
You get only the center Point. This issue on Github says that it is expected behavior.
The issue says that you can also get the Radius, and build the Geometry yourself.
I tried to do that using Turf, using
TurfBuffer(t.circle_layer.toGeoJSON(), t.circleBounds.radius, {
units: 'meters',
});
The problem is that the circle created, is different from the Geometry shown on the Leaflet Map. (note the Road intersection on the South-East Side of the circle)
Circle on Screen where user is drawing:
Circle, which is result of Turf buffer:
I guess this is due to the radius being in Web Mercator in leaflt-draw.
I would like to get the circle coordinates that the user has actually drawn. How can I get those?
Here is a complete page, showing Turf Circle and Turf Buffer, the buffer shows an issue. Note the circle has steps (Vertices). I'm guessing as there isn't a real GeoJSON circle in the standard.
<!DOCTYPE html>
<html>
<head>
<title>Turf Circle Example</title>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@turf/turf@5/turf.min.js"></script>
<style>
html, body, #map {
width : 100%;
height : 100%;
}
</style>
</head>
<body>
<div id="map" ></div>
<script>
var map = L.map('map').setView([42.736424, -73.762713], 10);
var osm=new L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png',{
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'});
osm.addTo(map);
var editableLayers = new L.FeatureGroup();
map.addLayer(editableLayers);
var options = {
position: 'topleft',
collapsed: false,
edit: {
featureGroup: editableLayers,
poly: {
allowIntersection: false
}
},
draw: {
polygon: {
allowIntersection: false,
showArea: true
}
}
};
var drawControl = new L.Control.Draw(options);
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function (e) {
var layer = e.layer;
var type = e.layerType;
if (type === 'circle') {
var theCenterPt = layer.getLatLng();
var center = [theCenterPt.lng,theCenterPt.lat];
console.log(center);
var theRadius = layer.getRadius();
editableLayers.addLayer(layer);
// Turf Circle
var turfCircle;
var options = {steps: 64, units: 'meters'}; //Change steps to 4 to see what it does.
var turfCircle = turf.circle(center, theRadius, options);
var NewTurfCircle = new L.GeoJSON(turfCircle, {color:"black"}).addTo(map);
//Turf Buffer
var thepoint = turf.point(center);
var buffered = turf.buffer(thepoint, theRadius, {units: 'meters'});
var NewTurfBuffer = new L.GeoJSON(buffered, {color:"red"}).addTo(map);
}
});
</script>
</body>
</html>
Correct answer by Bill Chappell on January 7, 2021
I get the code a little different as GeoJSON standard does not include circles.
map.on('draw:created', function (e) {
var type = e.layerType,
layer = e.layer;
drawfeatureGroup.addLayer(layer);
if (type === 'circle') {
var theCenterPt = layer.getLatLng();
var theRadius = layer.getRadius();
Now I have the center point and radius to draw a circle in leaflet or using Turf.
If you going to use the circle to see if points from another layer are inside it, this may help, it does not use turf.
var test = [];
var counter_points_in_circle = 0;
// Loop through each point in GeoJSON file //var allPoints = L.geoJson(data);
allPoints.eachLayer(function (layer) {
// Lat, long of current point
layer_lat_long = layer.getLatLng();
// Distance from our circle marker To current point in meters
distance_from_centerPoint = layer_lat_long.distanceTo(theCenterPt);
// See if meters is within radius
if (distance_from_centerPoint <= theRadius) {
counter_points_in_circle += 1;
test.push(layer.feature);
}
});
// alert(counter_points_in_circle); //Works.
alert(test.length);
alert("results "+JSON.stringify(test));
Example from a click & distance instead of a draw, same concept.
http://www.gistechsolutions.com/leaflet/DEMO/Select/SelectPoints4.html
Answered by Bill Chappell on January 7, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP