Leaflet.draw mapping: How to initiate the draw fun

2019-01-16 14:44发布

For anyone experienced with leaflet or leaflet.draw plugin:

I want to initiate drawing a polygon without using the toolbar from leaflet.draw. I've managed to find the property that allows editing without using the toolbar (layer.editing.enable();) by searching online (it's not in the main documentation). I can't seem to find how to begin drawing a polygon without the toolbar button. Any help would be much appreciated!

Thank you :)

3条回答
三岁会撩人
2楼-- · 2019-01-16 14:55

This simple code works for me:

new L.Draw.Polyline(map, drawControl.options.polyline).enable();

Just put it into the onclick handler of your custom button (or wherever you want).

The variables map and drawControl are references to your leaflet map and draw control.

Diving into the source code (leaflet.draw-src.js) you can find the functions to draw the other elements and to edit or delete them.

new L.Draw.Polygon(map, drawControl.options.polygon).enable()
new L.Draw.Rectangle(map, drawControl.options.rectangle).enable()
new L.Draw.Circle(map, drawControl.options.circle).enable()
new L.Draw.Marker(map, drawControl.options.marker).enable()

new L.EditToolbar.Edit(map, {
                featureGroup: drawControl.options.featureGroup,
                selectedPathOptions: drawControl.options.edit.selectedPathOptions
            })
new L.EditToolbar.Delete(map, {
                featureGroup: drawControl.options.featureGroup
            })

I hope this will be useful for you too.

EDIT: The L.EditToolbar.Edit and L.EditToolbar.Delete classes expose the following useful methods:

  • enable(): to start edit/delete mode
  • disable(): to return to standard mode
  • save(): to save changes (it fires draw:edited / draw:deleted events)
  • revertLayers(): to undo changes
查看更多
霸刀☆藐视天下
3楼-- · 2019-01-16 15:13

So I've figured this out for circles, but it should be the same for polygons. It's actually really simple. Hopefully the following code answers your question, but if not let me know and I can post more to a gist or something.

// Creates the circle on the map for the given latLng and Radius
// If the createdWithAddress flag is true, the circle will not update 
// it's address according to its position. 
createCircle: function(latLng, radius, createdWithAddress) {
if (!this.circle) {
  var self = this,
      centerIcon,
      centerMarker;

  centerIcon = new L.Icon({
    iconUrl: '/assets/location_pin_24px.png',
    iconSize: [24, 24],
    iconAnchor: [12, 24],
    shadowUrl: '/assets/marker-shadow.png',
    shadowSize: [20, 20],
    shadowAnchor:[6, 20]
  })

  // Setup the options for the circle -> Override icons, immediately editable
  options = {
    stroke: true,
    color: '#333333',
    opacity: 1.0,
    weight: 4,
    fillColor: '#FFFFFF',
    moveIcon: centerIcon,
    resizeIcon: new L.Icon({
      iconUrl: '/assets/radius_handle_18px.png',
      iconSize: [12, 12],
      iconAnchor: [0,0]
    })
  }

  if (someConfigVarYouDontNeedToKnow) {
    options.editable = false
    centerMarker = new L.Marker(latLng, { icon:centerIcon })
  } else {
    options.editable = true
  }

  // Create our location circle 
  // NOTE: I believe I had to modify Leaflet or Leaflet.draw to allow for passing in
  // options, but you can make it editable with circle.editing.enable()
  this.circle = L.circle([latLng.lat, latLng.lng], radius, options)

  // Add event handlers to update the location
  this.circle.on('add', function() {
    if (!createdWithAddress) {
      self.reverseGeocode(this.getLatLng())
    }
    self.updateCircleLocation(this.getLatLng(), this.getRadius())
    self.updateMapView()
  })            
  this.circle.on('edit', function() {
    if (self.convertLatLngToString(this.getLatLng()) !== self.getLocationLatLng()) {
      self.reverseGeocode(this.getLatLng())
    }
    self.updateCircleLocation(this.getLatLng(), this.getRadius())
    self.updateMapView()
  })

  this.map.addLayer(this.circle)
  if (centerMarker) {
    centerMarker.addTo(this.map)
    this.circle.redraw()
    centerMarker.update()
  }
}
},

Sorry a lot of that is just noise, but it should give you an idea of how to go about this. You can control editing like you said with editing.enable()/.disable().

Make sure to comment with any questions. Good luck man.

查看更多
疯言疯语
4楼-- · 2019-01-16 15:15

I think it's worth mentioning Jacob Toyes answer to this problem. You're always drawing with handlers in leaflet.draw - not directly with layers. If you want to edit a layer, you use the handler saved in a layers editing field like that: layer.editing.enable();. And if you want to create a new layer, you first create a new handler:

// Define you draw handler somewhere where you click handler can access it. N.B. pass any draw options into the handler
var polygonDrawer = new L.Draw.Polyline(map);

// Assumming you have a Leaflet map accessible
map.on('draw:created', function (e) {
    var type = e.layerType,
        layer = e.layer;

    // Do whatever you want with the layer.
    // e.type will be the type of layer that has been draw (polyline, marker, polygon, rectangle, circle)
    // E.g. add it to the map
    layer.addTo(map);
});

// Click handler for you button to start drawing polygons
$('#draw_poly').click(function() {
    polygonDrawer.enable();
});

By now there actually is an example on the leaflet.draw github page: https://github.com/Leaflet/Leaflet.draw/blob/master/examples/edithandlers.html

Nevertheless I think handlers aren't well documented there yet.

Like stated above, L.EditToolbar.Edit and L.EditToolbar.Delete expose interesting methods and events like editstart and editstop. What's not mentioned is that these two classes themselves are derived from L.Handler.

查看更多
登录 后发表回答