如何在Angular传单绘制中创建自定义控件?

时间:2018-08-15 08:53:09

标签: angular typescript leaflet leaflet.draw

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

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

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

其代码段如何在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);

3 个答案:

答案 0 :(得分:2)

我也有同样的需求,很显然,我的搜索结束了这个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);

希望有帮助!

答案 1 :(得分:1)

我不确定过去是如何做到的,无论它是否是正确的方法,我都不确定。有用。它不遵循“角度”的处理方式,但是您使用的外部库不遵循角度,因此只能随其角度而变化。

当然,我只为您做了一点,但这应该可以帮助您入门。确实与在JS中执行此操作相同,只是这次您周围有一个打字稿类。

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),它将当前角度范围绑定到回调,然后您可以从传单中安全地调用回调,但将其保持在角度范围内(希望如此)。

答案 2 :(得分:0)

我设法实现了它。基本上在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]);
                }
            }
        }
    });
}

}