Source: bemap-leaflet/bemap-map-leaflet-polyline.js

/**
 * Add a bemap.Polyline to the layer
 * @public
 * @param {bemap.Polyline} bemap.Polyline.
 * @param {object} options
 * @return {bemap.LeafletMap}
 */
bemap.LeafletMap.prototype.addPolyline = function(polyline, options) {
  if (polyline !== null && bemap.inheritsof(polyline, bemap.Polyline)) {
    var style = polyline.getStyle();
    if (!style) {
      style = new bemap.LineStyle({ color: new bemap.Color(0, 0, 0, 1), width: 2 });
    }
    var color = style.getColor();

    // Resolve the target layer FIRST so we can hand its custom pane to
    // L.polyline at construction (Leaflet honours `pane` only on init).
    var opts = options || {};
    var l = null;
    if (opts.layer !== undefined && (bemap.inheritsof(opts.layer, bemap.VectorLayer))) {
      l = opts.layer;
    } else {
      l = this.getLayerByName(bemap.Map.DEFAULT_LAYER.POLYLINE);
      if (l === null) {
        l = new bemap.VectorLayer({ name: bemap.Map.DEFAULT_LAYER.POLYLINE });
        this.addLayer(l);
      }
    }

    var polylineOpts = {
      color: color.getHex(),
      opacity: color.getAlpha(),
      weight: style.getWidth(),
      bubblingMouseEvents: false,
      dashArray: style.type === "dash" ? "10" : ""
    };
    // User-named VectorLayers have a dedicated path pane (z=400 default,
    // shifted by zIndexLayer). Default layers skip this and inherit
    // Leaflet's native overlayPane — markers (markerPane z=600) win.
    if (l && l._paneNamePath) polylineOpts.pane = l._paneNamePath;
    polyline.native = L.polyline(polyline.getLatLonArrays(), polylineOpts);

    if (polyline.map === null) {
      polyline.map = this;
    }

    if (polyline.layer === null) {
      polyline.layer = l;
    }
    polyline.native.addTo(l.native);
  }

  return this;
};

/**
 * Remove a polyline from his layer.
 * @public
 * @param {bemap.Polyline} polyline the polyline object to remove.
 */
bemap.LeafletMap.prototype.removePolyline = function(polyline) {
  if (polyline !== null && polyline.layer !== null && polyline.layer.native !== null && bemap.inheritsof(polyline, bemap.Polyline)) {
    polyline.map.native.removeLayer(polyline.native);
    polyline.layer = null;
    polyline.map = null;
  }
  return this;
};

/**
 * Set the listner when an specified eventType occur on bemap.Polyline.
 * @public
 * @param {bemap.Polyline} polyline
 * @param {bemap.Map.EventType} eventType Event type.
 * @param {function} callback Function will be called when the specified eventType is occur.
 * @param {object} options options.
 * @return {bemap.Listener} this.
 */
bemap.LeafletMap.prototype.onPolyline = function(polyline, eventType, callback, options) {
  var opts = options ? options : {};

  var nativeListener = polyline.native.on(eventType, function(evt) {
    var mapEvent = new bemap.MapEvent({
      native: evt,
      bemapObject: polyline,
      x: evt.containerPoint ? evt.containerPoint.x : undefined,
      y: evt.containerPoint ? evt.containerPoint.y : undefined,
      coordinate: evt.latlng ? new bemap.Coordinate(evt.latlng.lng, evt.latlng.lat) : undefined,
      properties: options,
      map: this
    });
    callback(mapEvent);
  });
  var listener = new bemap.Listener({
    native: nativeListener,
    callback: callback,
    key: eventType,
    bemapObject: polyline
  });

  return listener;
};

/**
 * Define the draggable capability for bemap.Polyline (Leaflet).
 * @param {bemap.Polyline} polyline
 * @param {function} callback
 * @param {object} options
 * @return {bemap.Listener}
 */
bemap.LeafletMap.prototype.draggablePolyline = function(polyline, callback, options) {
  var _this = this;

  polyline.native.on('mousedown', function(evt) {
    L.DomEvent.stopPropagation(evt);
    _this.native.dragging.disable();
    var mouseStartLat = evt.latlng.lat;
    var mouseStartLng = evt.latlng.lng;

    var onMove = function(e) {
      var dLat = e.latlng.lat - mouseStartLat;
      var dLng = e.latlng.lng - mouseStartLng;
      mouseStartLat = e.latlng.lat;
      mouseStartLng = e.latlng.lng;

      var latlngs = polyline.native.getLatLngs();
      var newLatLngs = [];
      for (var i = 0; i < latlngs.length; i++) {
        newLatLngs.push(L.latLng(latlngs[i].lat + dLat, latlngs[i].lng + dLng));
      }
      polyline.native.setLatLngs(newLatLngs);

      var coords = polyline.getCoordinates();
      for (var j = 0; j < coords.length; j++) {
        coords[j].setLon(coords[j].getLon() + dLng).setLat(coords[j].getLat() + dLat);
      }
    };

    _this.native.on('mousemove', onMove);
    _this.native.once('mouseup', function(e) {
      _this.native.off('mousemove', onMove);
      _this.native.dragging.enable();
      if (callback) {
        callback(new bemap.MapEvent({
          native: e, bemapObject: polyline,
          coordinate: e.latlng ? new bemap.Coordinate(e.latlng.lng, e.latlng.lat) : undefined,
          map: _this
        }));
      }
    });
  });

  return new bemap.Listener({ native: polyline.native, bemapObject: polyline, key: 'dragFeature' });
};