0

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: enter image description here

Circle, which is result of Turf buffer: enter image description here

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?

2

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/leaflet@1.0.3/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@1.0.3/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: '&copy; <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>
| improve this answer | |
  • This is what I went with. using 64 steps was more than enough for my use case. – Devdatta Tengshe Jun 12 '18 at 8:34
1

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

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.