How do I get a Leaflet shape's layer type when

2019-08-16 17:35发布

问题:

My Leaflet project allows the users to draw shapes (lines, rectangles and polygons). The user can click on the shapes to get their statistics (area, perimeter, etc).

I tried a click event on my FeatureGroup(), where all the shapes I have drawn is added. I am not sure if this is the best approach. Then upon click, a function taking an event is called. The layer type is inferred from the event object.


 //Handlers for when drawn shapes are clicked
        editableLayers.on('click', onLayerClick);

        function onLayerClick(e)
        {
            let type = e.layerType,
                layer = e.layer;
            if (type === 'polygon') {
                polygons.push(e.layer);
                let area = L.GeometryUtil.geodesicArea(layer.getLatLngs()[0]);
                console.log("New polygon area: " + area);
            }

            if (type === 'rectangle') {
                rectangles.push(e.layer);
                let area = L.GeometryUtil.geodesicArea(layer.getLatLngs()[0]);
                console.log("New rectangle area: " + area);
            }     
        }

The type object returns an undefined, and the layer object returns a bunch of parameters making no reference to the shape type. Because of that, I cannot infer the shape type and perform the correct calculations to get their stats.

回答1:

I would leverage the instanceof operator for this task, e.g.:

function onLayerClick(ev) {
  var targetLayer = ev.sourceTarget;
  if (targetLayer instanceof L.Rectangle) {
     // Do something
  } else if (targetLayer instanceof L.Polygon) {
     // Do something
  } else if (targetLayer instanceof L.Polyline) {
     // Do something
  } else {
     // Do something
  }
}

Note that due to how inheritance works, any instance of L.Rectangle is also an instance of L.Polygon, and L.Polyline and L.Path - that's why the code should check first for the most specific subclasses.

Remember to check out the Leaflet reference, specifically for the bits which tell you about the inheritance tree, e.g.:

Rectangle

A class for drawing rectangle overlays on a map. Extends Polygon.

The Leaflet class diagram is also useful for understanding the inheritance tree.



回答2:

The root cause is that event.layerType is a special property added by Leaflet.draw plugin, only when a new feature has been created by a user.

When you attach your click event listener on Leaflet standard Feature Group, the click event object does not have such layerType property, as you can check on the docs.

As for a solution, see IvanSanchez's answer.