Leaflet:连接线内可拖动标记的体系结构

时间:2017-12-18 14:52:40

标签: javascript leaflet draggable

我正在开发基于传单的原理图/图表编辑器。基本上,这是由折线连接的任意数量的交互式(即可拖动)标记:

enter image description here

我想开发系统,以便在拖动标记时,重新绘制连接的折线以与它们一起拖动。

目前,标记和折线彼此不知情。 标记是扩展L.marker的自定义类,折线同样延伸L.Polyline。 L.Map已经扩展到提供“添加组件”。 (组件==标记)和' linkComponents'方法

我的第一个想法是在标记本身上保持对每条连接折线的引用。然后我可以覆盖拖动处理程序来重绘每条折线。

这提出了两个问题:

  • 标记如何知道哪个'结束'我需要更改折线的坐标?

  • 在某些时候,我希望能够通过某些用户交互单独删除这些行。如果我这样做,连接 标记现在将持有对不具有的折线的引用 存在!因此,解决这个问题的方法是让每条折线 保持对它们连接的标记的引用。但现在似乎 变得有点脆弱,我可能有多个地方 需要更新信息。

所以我正在寻找有关实现此功能的合理方法/模式的建议

1 个答案:

答案 0 :(得分:1)

答案,或者至少 答案让我不再像企业痴迷于OO的开发人员那样思考并利用传单事件系统。

当我创建折线时,我传入原始标记以计算折线的起点和终点:

const Link = L.Polyline.extend({

  options: {
    fromIcon: null,
    fromPort: null,
    toIcon: null,
    toPort: null
  },

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

    // We will insert the 'from port' coordinate at the start and the
    // 'to' coordinate at the end. 
    // 'getPortLocation' is just a simple function to return the LatLng of where a line should start to be drawn over a 'port'
    const start = this.options.fromIcon.getPortLocation(this.options.fromPort);
    const end = this.options.toIcon.getPortLocation(this.options.toPort);

    // Insert port positions at the start and end af the latlng array.
    latlngs.unshift(start);
    latlngs.push(end);
    this._setLatLngs(latlngs);
  }
}

一个简单的解决方案是简单地听取拖动事件:

    // Make sure the line is updated when the connected markers are moved
    this.options.fromIcon.on('drag', (event) => this.fromDragHandler(event, this.options.fromPort));
    this.options.toIcon.on('drag', (event) => this.toDragHandler(event, this.options.toPort));

重新划线:

fromDragHandler: function(event, portNum) {
  const marker = event.target;
  const latlngs = this.getLatLngs();
  const newPos = marker.getPortLocation(portNum);
  latlngs[0] = newPos;
  this.setLatLngs(latlngs);
}

在我问起之前,我是否想过更加努力并浏览了更多代码......