【问题标题】:How to create custom control in leaflet draw for Angular?如何在 Angular 的传单绘制中创建自定义控件?
【发布时间】:2018-08-15 08:53:09
【问题描述】:

我是传单绘制插件和打字稿的新手,所以我正在寻找扩展传单绘制的方法,以创建一个绘制圆圈的自定义控件。看到一个用JS写的例子,但是不知道如何正确创建基于leaflet draw插件的控件。

我正在创建基于 Angular 的网络应用程序。 帮助扩展打字稿中的控制。我正在使用 ars 库。

"leaflet": "^1.3.3",
"leaflet-draw": "^1.0.2",
"@types/leaflet": "^1.2.9",

它的代码sn-p在JS中是如何实现的

 }
/*Class for new polygon shape */
L.Draw.CustomCircle = L.Draw.Circle.extend({
    options: {
        repeatMode: true
    },
    initialize: function (map, options) {
        this.type = 'customCircle';
        L.Draw.Feature.prototype.initialize.call(this, map, options);
    }
});


/*Changes some of the default text for the toolbar buttons*/
L.drawLocal = {
    draw: {
        toolbar: {
            buttons: {
                circle: 'Draw a include circle',
                customCircle: 'Draw a exnclude circle',
            }
        },
        handlers: {
            circle: {
                tooltip: {
                    start: 'Click and drag to include circle.'
                },
                radius: 'Radius'
            },
          customCircle: {
                tooltip: {
                    start: 'Click and drag to exclude circle.'
                },
                radius: 'Radius'
            }
        }
    },
    edit: {        }
};

/*Adds new shape types to the options */
L.DrawToolbar.include({

options: {
        circle: {},
        customCircle: {}
    },
        initialize: function (options) {
    // Ensure that the options are merged correctly since L.extend is only shallow
    for (var type in this.options) {
        if (this.options.hasOwnProperty(type)) {
            if (options[type]) {
                options[type] = L.extend({}, this.options[type], options[type]);
            }
        }
    }

    this._toolbarClass = 'leaflet-draw-draw';
    L.Toolbar.prototype.initialize.call(this, options);
},
    getModeHandlers: function (map) {
        return [
             {
                enabled: this.options.customCircle,
                handler: new L.Draw.CustomCircle(map, this.options.customCircle),
                title: L.drawLocal.draw.toolbar.buttons.customCircle
            },
                             {
                enabled: this.options.circle,
                handler: new l.draw.circle(map, this.options.circle),
                title: l.drawlocal.draw.toolbar.buttons.circle
            },
        ];
    },

    // Get the actions part of the toolbar
    getActions: function (handler) {
        return [
            {
                enabled: handler.completeShape,
                title: L.drawLocal.draw.toolbar.finish.title,
                text: L.drawLocal.draw.toolbar.finish.text,
                callback: handler.completeShape,
                context: handler
            },
        ];
    },

    setOptions: function (options) {
        L.setOptions(this, options);

        for (var type in this._modes) {
            if (this._modes.hasOwnProperty(type) && options.hasOwnProperty(type)) {
                this._modes[type].handler.setOptions(options[type]);
            }
        }
    }
});


var drawControl = new L.Control.Draw();
map.addControl(drawControl);

【问题讨论】:

    标签: angular typescript leaflet leaflet.draw


    【解决方案1】:

    我也有同样的需求,显然我的搜索以这个 SO 问题结束。我不太喜欢@TheJSWizard 提出的解决方案,因为我们在 TS 中,所以我们应该使用“面向对象”的方法。

    原来解决方案非常简单。从自定义控件的 javascript 传单教程开始,我创建了以下 Typescript 传单自定义控件类:

    import * as L from 'leaflet';
    
    export class Watermark extends L.Control {
    
      onAdd(map: L.Map) {
        let img = L.DomUtil.create('img') as HTMLImageElement;
        img.src = '../../docs/images/logo.png';
        img.style.width = '200px';
        return img;
      }
    
      onRemove(map: L.Map) {
        // Nothing to do here
      }
    
      constructor(options?: L.ControlOptions) {
        super(options);
      }
    }
    

    然后我可以在任何地方使用自定义控件Watermark 通过以下方式创建地图:

    import * as L from 'leaflet';
    import { Watermark } from './leaflet-watermark-control';
    ...
    
    let myMap = L.map("mapId")setView([51.505, -0.09], 13);
    new Watermark({position: 'bottomleft'}).addTo(myMap);
    

    希望对你有帮助!

    【讨论】:

      【解决方案2】:

      我过去是如何做到的,我不确定这样做是否正确。有用。它不遵循“角度”的做事方式,但是您使用的是不遵循角度的外部库,因此您只能尽可能地保持角度。

      当然,我只为你做了一点,但这应该让你开始。真的和在 JS 中做的一样,只是这次你有一个 typescript 类。

      import * as L from 'leaflet';
      @Component({
        selector: 'app-map',
        templateUrl: 'foo.html',
      })
      
      export class MapPage implements OnInit {
        public map: L.Map;
        constructor() { }
      
        public ngOnInit() {
          const config = {};
          this.map = L.map('elementId', config)
          this.addLeafletExtras();
        }
      
        private addLeafletExtras() {
          L.Draw.CustomCircle = L.Draw.Circle.extend({
            options: {
              repeatMode: true
            },
            initialize: function (map, options) {
              this.type = 'customCircle';
              L.Draw.Feature.prototype.initialize.call(this, map, options);
            }
          });
        }
      
      }
      

      需要注意的是,如果你想在传单中添加回调,在你的角度代码中调用一些东西,传递回调并使用 .bind(this) ,这会将当前的角度范围绑定到回调,然后您可以安全地从传单调用您的回调,但将其保持在角度范围内(我希望这是有道理的)。

      【讨论】:

      • 但是我可以像你推荐的那样做,因为 ts 会抛出一个错误:'Property 'CustomCircle' does not exist on type 'typeof Draw'。'
      • 你在导入leaflet-draw吗? import 'leaflet-draw';
      • 如果您在 index.html 中加载依赖项,它们将不起作用,除非您将所有属性声明为 any(我不建议这样做)。为了打字稿,您需要做的是导入您需要使用的所有传单插件,以便打字稿知道它们存在。您也可以创建/查找类型来执行此操作。
      • 你能提供一些工作的例子吗,对我来说很难得到它。 L.Draw 不起作用,因为我必须覆盖许多类。我不知道该怎么做
      • 您要覆盖与 L.Draw 相关的哪些内容?只需将导入添加到 typscript 文件的顶部
      【解决方案3】:

      我设法实现了它。它基本上不完全在 ts 中,但可以工作

      declare var L;
      export class Ovverides {
      addNewTypes() {
          /*change the draw created event to pass in a featureTypeCode.
             This makes it so that when the draw created is triggered, I can fetch the type shape made and
             append that as a property in the generated GeoJSON*/
          L.Draw.Feature.prototype._fireCreatedEvent = function (layer) {
              if (this.featureTypeCode) {
                  this._map.fire('draw:created', { layer: layer, layerType: this.type, featureTypeCode: this.featureTypeCode });
              } else {
                  this._map.fire('draw:created', { layer: layer, layerType: this.type });
              }
          }
      
          /*Class for new circle include */
          L.Draw.CircleInclude = L.Draw.Circle.extend({
              options: {
                  repeatMode: false
              },
              initialize: function (map, options) {
                  this.type = L.Draw.Circle.TYPE;
                  this.featureTypeCode = 'include';
                  this._initialLabelText = L.drawLocal.draw.handlers.circle.include.tooltip.start;
                  this._endLabelText = 'Release mouse to finish drawing.';
                  L.Draw.Feature.prototype.initialize.call(this, map, options);
              }
          });
          /*Class for new circle exclude */
          L.Draw.CircleExclude = L.Draw.Circle.extend({
              options: {
                  repeatMode: false
              },
      
              initialize: function (map, options) {
                  this.type = L.Draw.Circle.TYPE;
                  this.featureTypeCode = 'exclude';
                  this._endLabelText = 'Release mouse to finish drawing.';
                  this._initialLabelText = L.drawLocal.draw.handlers.circle.exclude.tooltip.start;
                  L.Draw.Feature.prototype.initialize.call(this, map, options);
              }
          });
      
          /*Modify this function to catch the featureCodeType.  This needs to append to the
          Css class name generated so that I can color them and do other stuff appropriately
          based on custom class in our css file*/
          L.Toolbar.prototype._initModeHandler = function (handler, container, buttonIndex, classNamePredix, buttonTitle) {
              var type = handler.type;
              var target = type;
              if (typeof handler.featureTypeCode != 'undefined') {
                  target = type + '-' + handler.featureTypeCode;
              }
              this._modes[type] = {};
      
              this._modes[type].handler = handler;
      
              this._modes[type].button = this._createButton({
                  type: type,
                  title: buttonTitle,
                  className: classNamePredix + '-' + target,
                  container: container,
                  callback: this._modes[type].handler.enable,
                  context: this._modes[type].handler
              });
              this._modes[type].buttonIndex = buttonIndex;
      
              this._modes[type].handler
                  .on('enabled', this._handlerActivated, this)
                  .on('disabled', this._handlerDeactivated, this);
          }
      
          /*Changes some of the default text for the toolbar buttons*/
          L.drawLocal = {
              draw: {
                  toolbar: {
                      actions: {
                          title: 'Cancel drawing',
                          text: 'Cancel'
                      },
                      finish: {
                          title: 'Finish drawing',
                          text: 'Finish'
                      },
                      undo: {
                          title: 'Delete last point drawn',
                          text: 'Delete last point'
                      },
                      buttons: {
                          polyline: 'Draw a polyline',
                          polygon: 'Draw a polygon',
                          rectangle: 'Draw a rectangle',
                          circle: {
                              include: 'Create include circle',
                              exclude: 'Create exclude circle',
                          },
                          marker: 'Draw a marker'
                      }
                  },
                  handlers: {
                      circle: {
                          radius: 'Radius',
                          include: {
                              tooltip: {
                                  start: 'Click to start drawing a circle include',
                              },
                          },
                          exclude: {
                              tooltip: {
                                  start: 'Click to start drawing a circle exclude',
                              },
                          },
                      },
                      marker: {
                          tooltip: {
                              start: 'Click map to place a site marker.'
                          }
                      },
                      polygon: {
                          tooltip: {
                              start: 'Click to start drawing a site property',
                              cont: 'Click to continue drawing a site property',
                              end: 'Click first point to close this site property'
                          }
                      },
                      polyline: {
                          error: '<strong>Error:</strong> shape edges cannot cross!',
                          tooltip: {
                              start: 'Click to start drawing line',
                              cont: 'Click to continue drawing line',
                              end: 'Click last point to finish line'
                          }
                      },
                      rectangle: {
                          tooltip: {
                              start: 'Click and drag to create a site boundary'
                          }
                      },
                      simpleshape: {
                          tooltip: {
                              end: 'Release mouse to finish drawing.'
                          }
                      }
                  }
              },
              edit: {
                  toolbar: {
                      actions: {
                          save: {
                              title: 'Save changes',
                              text: 'Save'
                          },
                          cancel: {
                              title: 'Cancel editing, discards all changes',
                              text: 'Cancel'
                          },
                          clearAll: {
                              title: 'Clear all layers',
                              text: 'Clear All'
                          }
                      },
                      buttons: {
                          edit: 'Edit layers',
                          editDisabled: 'No layers to edit',
                          remove: 'Delete layers',
                          removeDisabled: 'No layers to delete'
                      }
                  },
                  handlers: {
                      edit: {
                          tooltip: {
                              text: 'Drag handles or markers to edit features.',
                              subtext: 'Click cancel to undo changes.'
                          }
                      },
                      remove: {
                          tooltip: {
                              text: 'Click on a feature to remove.'
                          }
                      }
                  }
              }
          };
      
          /*Adds new shape types to the options */
          L.DrawToolbar.include({
              options: {
                  polyline: {},
                  polygon: {},
                  rectangle: {},
                  circle: {
                      include: {},
                      exclude: {}
                  },
                  marker: {}
              },
              initialize: function (options) {
                  // Ensure that the options are merged correctly since L.extend is only shallow
                  for (var type in this.options) {
                      if (this.options.hasOwnProperty(type)) {
                          if (options[type]) {
                              options[type] = L.extend({}, this.options[type], options[type]);
                          }
                      }
                  }
      
                  this._toolbarClass = 'leaflet-draw-draw';
                  L.Toolbar.prototype.initialize.call(this, options);
              },
              getModeHandlers: function (map) {
                  return [
                      {
                          enabled: this.options.circle.include,
                          handler: new L.Draw.CircleInclude(map, this.options.circle.include),
                          title: L.drawLocal.draw.toolbar.buttons.circle.include
                      },
                      {
                          enabled: this.options.circle.exclude,
                          handler: new L.Draw.CircleExclude(map, this.options.circle.exclude),
                          title: L.drawLocal.draw.toolbar.buttons.circle.exclude
                      },
                  ];
              },
      
              // Get the actions part of the toolbar
              getActions: function (handler) {
                  return [
                      {
                          enabled: handler.completeShape,
                          title: L.drawLocal.draw.toolbar.finish.title,
                          text: L.drawLocal.draw.toolbar.finish.text,
                          callback: handler.completeShape,
                          context: handler
                      },
                      {
                          enabled: handler.deleteLastVertex,
                          title: L.drawLocal.draw.toolbar.undo.title,
                          text: L.drawLocal.draw.toolbar.undo.text,
                          callback: handler.deleteLastVertex,
                          context: handler
                      },
                      {
                          title: L.drawLocal.draw.toolbar.actions.title,
                          text: L.drawLocal.draw.toolbar.actions.text,
                          callback: this.disable,
                          context: this
                      }
                  ];
              },
      
              setOptions: function (options) {
                  L.setOptions(this, options);
      
                  for (var type in this._modes) {
                      if (this._modes.hasOwnProperty(type) && options.hasOwnProperty(type)) {
                          this._modes[type].handler.setOptions(options[type]);
                      }
                  }
              }
          });
      }
      

      }

      【讨论】:

        猜你喜欢
        • 2017-02-21
        • 1970-01-01
        • 1970-01-01
        • 2019-05-04
        • 1970-01-01
        • 1970-01-01
        • 2017-04-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多