使用sebm-angular2-google-map实现OverlappingMarkerSpidifier

时间:2016-10-27 20:57:52

标签: google-maps angular typescript webpack

我正在尝试在angular2 2.0.0上使用OverlappingMarkerSpidifier实现SebM Angular 2 Google Maps

我已经使用从sebm模块导入的GoogleMapsAPIWrapper成功加载了Google Maps API。一旦加载,我正在执行我从存储库下载的OMW脚本,我添加了一个module.exports语句。但是,我收到以下错误消息:

Uncaught TypeError: this.constructor.ProjHelper is not a constructor

以下是OMW代码:

/** @preserve OverlappingMarkerSpiderfier
https://github.com/jawj/OverlappingMarkerSpiderfier
Copyright (c) 2011 - 2013 George MacKerron
Released under the MIT licence: http://opensource.org/licenses/mit-license
Note: The Google Maps API v3 must be included *before* this code
 */

module.exports = function () {

  var __hasProp = {}.hasOwnProperty, __slice = [].slice;
  var ge, gm, lcH, lcU, mt, p, twoPi, x, _i, _len, _ref;

  p = _Class.prototype;

  _ref = [_Class, p];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    x = _ref[_i];
    x['VERSION'] = '0.3.3';
  }

  gm = google.maps;

  ge = gm.event;

  mt = gm.MapTypeId;

  twoPi = Math.PI * 2;

  p['keepSpiderfied'] = false;

  p['markersWontHide'] = false;

  p['markersWontMove'] = false;

  p['nearbyDistance'] = 20;

  p['circleSpiralSwitchover'] = 9;

  p['circleFootSeparation'] = 23;

  p['circleStartAngle'] = twoPi / 12;

  p['spiralFootSeparation'] = 26;

  p['spiralLengthStart'] = 11;

  p['spiralLengthFactor'] = 4;

  p['spiderfiedZIndex'] = 1000;

  p['usualLegZIndex'] = 10;

  p['highlightedLegZIndex'] = 20;

  p['event'] = 'click';

  p['minZoomLevel'] = false;

  p['legWeight'] = 1.5;

  p['legColors'] = {
    'usual': {},
    'highlighted': {}
  };

  lcU = p['legColors']['usual'];

  lcH = p['legColors']['highlighted'];

  lcU[mt.HYBRID] = lcU[mt.SATELLITE] = '#fff';

  lcH[mt.HYBRID] = lcH[mt.SATELLITE] = '#f00';

  lcU[mt.TERRAIN] = lcU[mt.ROADMAP] = '#444';

  lcH[mt.TERRAIN] = lcH[mt.ROADMAP] = '#f00';

  function _Class(map, opts) {
    var e, k, v, _j, _len1, _ref1;
    this.map = map;
    if (opts == null) {
      opts = {};
    }
    for (k in opts) {
      if (!__hasProp.call(opts, k)) continue;
      v = opts[k];
      this[k] = v;
    }
    this.projHelper = new this.constructor.ProjHelper(this.map);
    this.initMarkerArrays();
    this.listeners = {};
    _ref1 = ['click', 'zoom_changed', 'maptypeid_changed'];
    for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
      e = _ref1[_j];
      ge.addListener(this.map, e, (function(_this) {
        return function() {
          return _this['unspiderfy']();
        };
      })(this));
    }
  }

  p.initMarkerArrays = function() {
    this.markers = [];
    return this.markerListenerRefs = [];
  };

  p['addMarker'] = function(marker) {
    var listenerRefs;
    if (marker['_oms'] != null) {
      return this;
    }
    marker['_oms'] = true;
    listenerRefs = [
      ge.addListener(marker, this['event'], (function(_this) {
        return function(event) {
          return _this.spiderListener(marker, event);
        };
      })(this))
    ];
    if (!this['markersWontHide']) {
      listenerRefs.push(ge.addListener(marker, 'visible_changed', (function(_this) {
        return function() {
          return _this.markerChangeListener(marker, false);
        };
      })(this)));
    }
    if (!this['markersWontMove']) {
      listenerRefs.push(ge.addListener(marker, 'position_changed', (function(_this) {
        return function() {
          return _this.markerChangeListener(marker, true);
        };
      })(this)));
    }
    this.markerListenerRefs.push(listenerRefs);
    this.markers.push(marker);
    return this;
  };

  p.markerChangeListener = function(marker, positionChanged) {
    if ((marker['_omsData'] != null) && (positionChanged || !marker.getVisible()) && !((this.spiderfying != null) || (this.unspiderfying != null))) {
      return this['unspiderfy'](positionChanged ? marker : null);
    }
  };

  p['getMarkers'] = function() {
    return this.markers.slice(0);
  };

  p['removeMarker'] = function(marker) {
    var i, listenerRef, listenerRefs, _j, _len1;
    if (marker['_omsData'] != null) {
      this['unspiderfy']();
    }
    i = this.arrIndexOf(this.markers, marker);
    if (i < 0) {
      return this;
    }
    listenerRefs = this.markerListenerRefs.splice(i, 1)[0];
    for (_j = 0, _len1 = listenerRefs.length; _j < _len1; _j++) {
      listenerRef = listenerRefs[_j];
      ge.removeListener(listenerRef);
    }
    delete marker['_oms'];
    this.markers.splice(i, 1);
    return this;
  };

  p['clearMarkers'] = function() {
    var i, listenerRef, listenerRefs, marker, _j, _k, _len1, _len2, _ref1;
    this['unspiderfy']();
    _ref1 = this.markers;
    for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
      marker = _ref1[i];
      listenerRefs = this.markerListenerRefs[i];
      for (_k = 0, _len2 = listenerRefs.length; _k < _len2; _k++) {
        listenerRef = listenerRefs[_k];
        ge.removeListener(listenerRef);
      }
      delete marker['_oms'];
    }
    this.initMarkerArrays();
    return this;
  };

  p['addListener'] = function(event, func) {
    var _base;
    ((_base = this.listeners)[event] != null ? _base[event] : _base[event] = []).push(func);
    return this;
  };

  p['removeListener'] = function(event, func) {
    var i;
    i = this.arrIndexOf(this.listeners[event], func);
    if (!(i < 0)) {
      this.listeners[event].splice(i, 1);
    }
    return this;
  };

  p['clearListeners'] = function(event) {
    this.listeners[event] = [];
    return this;
  };

  p.trigger = function() {
    var args, event, func, _j, _len1, _ref1, _ref2, _results;
    event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
    _ref2 = (_ref1 = this.listeners[event]) != null ? _ref1 : [];
    _results = [];
    for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
      func = _ref2[_j];
      _results.push(func.apply(null, args));
    }
    return _results;
  };

  p.generatePtsCircle = function(count, centerPt) {
    var angle, angleStep, circumference, i, legLength, _j, _results;
    circumference = this['circleFootSeparation'] * (2 + count);
    legLength = circumference / twoPi;
    angleStep = twoPi / count;
    _results = [];
    for (i = _j = 0; 0 <= count ? _j < count : _j > count; i = 0 <= count ? ++_j : --_j) {
      angle = this['circleStartAngle'] + i * angleStep;
      _results.push(new gm.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle)));
    }
    return _results;
  };

  p.generatePtsSpiral = function(count, centerPt) {
    var angle, i, legLength, pt, _j, _results;
    legLength = this['spiralLengthStart'];
    angle = 0;
    _results = [];
    for (i = _j = 0; 0 <= count ? _j < count : _j > count; i = 0 <= count ? ++_j : --_j) {
      angle += this['spiralFootSeparation'] / legLength + i * 0.0005;
      pt = new gm.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle));
      legLength += twoPi * this['spiralLengthFactor'] / angle;
      _results.push(pt);
    }
    return _results;
  };

  p.spiderListener = function(marker, event) {
    var $this, clear, m, mPt, markerPt, markerSpiderfied, nDist, nearbyMarkerData, nonNearbyMarkers, pxSq, _j, _len1, _ref1;
    markerSpiderfied = marker['_omsData'] != null;
    if (!(markerSpiderfied && this['keepSpiderfied'])) {
      if (this['event'] === 'mouseover') {
        $this = this;
        clear = function() {
          return $this['unspiderfy']();
        };
        window.clearTimeout(p.timeout);
        p.timeout = setTimeout(clear, 3000);
      } else {
        this['unspiderfy']();
      }
    }
    if (markerSpiderfied || this.map.getStreetView().getVisible() || this.map.getMapTypeId() === 'GoogleEarthAPI') {
      return this.trigger('click', marker, event);
    } else {
      nearbyMarkerData = [];
      nonNearbyMarkers = [];
      nDist = this['nearbyDistance'];
      pxSq = nDist * nDist;
      markerPt = this.llToPt(marker.position);
      _ref1 = this.markers;
      for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
        m = _ref1[_j];
        if (!((m.map != null) && m.getVisible())) {
          continue;
        }
        mPt = this.llToPt(m.position);
        if (this.ptDistanceSq(mPt, markerPt) < pxSq) {
          nearbyMarkerData.push({
            marker: m,
            markerPt: mPt
          });
        } else {
          nonNearbyMarkers.push(m);
        }
      }
      if (nearbyMarkerData.length === 1) {
        return this.trigger('click', marker, event);
      } else {
        return this.spiderfy(nearbyMarkerData, nonNearbyMarkers);
      }
    }
  };

  p['markersNearMarker'] = function(marker, firstOnly) {
    var m, mPt, markerPt, markers, nDist, pxSq, _j, _len1, _ref1, _ref2, _ref3;
    if (firstOnly == null) {
      firstOnly = false;
    }
    if (this.projHelper.getProjection() == null) {
      throw "Must wait for 'idle' event on map before calling markersNearMarker";
    }
    nDist = this['nearbyDistance'];
    pxSq = nDist * nDist;
    markerPt = this.llToPt(marker.position);
    markers = [];
    _ref1 = this.markers;
    for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
      m = _ref1[_j];
      if (m === marker || (m.map == null) || !m.getVisible()) {
        continue;
      }
      mPt = this.llToPt((_ref2 = (_ref3 = m['_omsData']) != null ? _ref3.usualPosition : void 0) != null ? _ref2 : m.position);
      if (this.ptDistanceSq(mPt, markerPt) < pxSq) {
        markers.push(m);
        if (firstOnly) {
          break;
        }
      }
    }
    return markers;
  };

  p['markersNearAnyOtherMarker'] = function() {
    var i, i1, i2, m, m1, m1Data, m2, m2Data, mData, nDist, pxSq, _j, _k, _l, _len1, _len2, _len3, _ref1, _ref2, _ref3, _results;
    if (this.projHelper.getProjection() == null) {
      throw "Must wait for 'idle' event on map before calling markersNearAnyOtherMarker";
    }
    nDist = this['nearbyDistance'];
    pxSq = nDist * nDist;
    mData = (function() {
      var _j, _len1, _ref1, _ref2, _ref3, _results;
      _ref1 = this.markers;
      _results = [];
      for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
        m = _ref1[_j];
        _results.push({
          pt: this.llToPt((_ref2 = (_ref3 = m['_omsData']) != null ? _ref3.usualPosition : void 0) != null ? _ref2 : m.position),
          willSpiderfy: false
        });
      }
      return _results;
    }).call(this);
    _ref1 = this.markers;
    for (i1 = _j = 0, _len1 = _ref1.length; _j < _len1; i1 = ++_j) {
      m1 = _ref1[i1];
      if (!((m1.map != null) && m1.getVisible())) {
        continue;
      }
      m1Data = mData[i1];
      if (m1Data.willSpiderfy) {
        continue;
      }
      _ref2 = this.markers;
      for (i2 = _k = 0, _len2 = _ref2.length; _k < _len2; i2 = ++_k) {
        m2 = _ref2[i2];
        if (i2 === i1) {
          continue;
        }
        if (!((m2.map != null) && m2.getVisible())) {
          continue;
        }
        m2Data = mData[i2];
        if (i2 < i1 && !m2Data.willSpiderfy) {
          continue;
        }
        if (this.ptDistanceSq(m1Data.pt, m2Data.pt) < pxSq) {
          m1Data.willSpiderfy = m2Data.willSpiderfy = true;
          break;
        }
      }
    }
    _ref3 = this.markers;
    _results = [];
    for (i = _l = 0, _len3 = _ref3.length; _l < _len3; i = ++_l) {
      m = _ref3[i];
      if (mData[i].willSpiderfy) {
        _results.push(m);
      }
    }
    return _results;
  };

  p.makeHighlightListenerFuncs = function(marker) {
    return {
      highlight: (function(_this) {
        return function() {
          return marker['_omsData'].leg.setOptions({
            strokeColor: _this['legColors']['highlighted'][_this.map.mapTypeId],
            zIndex: _this['highlightedLegZIndex']
          });
        };
      })(this),
      unhighlight: (function(_this) {
        return function() {
          return marker['_omsData'].leg.setOptions({
            strokeColor: _this['legColors']['usual'][_this.map.mapTypeId],
            zIndex: _this['usualLegZIndex']
          });
        };
      })(this)
    };
  };

  p.spiderfy = function(markerData, nonNearbyMarkers) {
    var bodyPt, footLl, footPt, footPts, highlightListenerFuncs, leg, marker, md, nearestMarkerDatum, numFeet, spiderfiedMarkers;
    if (this['minZoomLevel'] && this.map.getZoom() < this['minZoomLevel']) {
      return false;
    }
    this.spiderfying = true;
    numFeet = markerData.length;
    bodyPt = this.ptAverage((function() {
      var _j, _len1, _results;
      _results = [];
      for (_j = 0, _len1 = markerData.length; _j < _len1; _j++) {
        md = markerData[_j];
        _results.push(md.markerPt);
      }
      return _results;
    })());
    footPts = numFeet >= this['circleSpiralSwitchover'] ? this.generatePtsSpiral(numFeet, bodyPt).reverse() : this.generatePtsCircle(numFeet, bodyPt);
    spiderfiedMarkers = (function() {
      var _j, _len1, _results;
      _results = [];
      for (_j = 0, _len1 = footPts.length; _j < _len1; _j++) {
        footPt = footPts[_j];
        footLl = this.ptToLl(footPt);
        nearestMarkerDatum = this.minExtract(markerData, (function(_this) {
          return function(md) {
            return _this.ptDistanceSq(md.markerPt, footPt);
          };
        })(this));
        marker = nearestMarkerDatum.marker;
        leg = new gm.Polyline({
          map: this.map,
          path: [marker.position, footLl],
          strokeColor: this['legColors']['usual'][this.map.mapTypeId],
          strokeWeight: this['legWeight'],
          zIndex: this['usualLegZIndex']
        });
        marker['_omsData'] = {
          usualPosition: marker.position,
          leg: leg
        };
        if (this['legColors']['highlighted'][this.map.mapTypeId] !== this['legColors']['usual'][this.map.mapTypeId]) {
          highlightListenerFuncs = this.makeHighlightListenerFuncs(marker);
          marker['_omsData'].hightlightListeners = {
            highlight: ge.addListener(marker, 'mouseover', highlightListenerFuncs.highlight),
            unhighlight: ge.addListener(marker, 'mouseout', highlightListenerFuncs.unhighlight)
          };
        }
        marker.setPosition(footLl);
        marker.setZIndex(Math.round(this['spiderfiedZIndex'] + footPt.y));
        _results.push(marker);
      }
      return _results;
    }).call(this);
    delete this.spiderfying;
    this.spiderfied = true;
    return this.trigger('spiderfy', spiderfiedMarkers, nonNearbyMarkers);
  };

  p['unspiderfy'] = function(markerNotToMove) {
    var listeners, marker, nonNearbyMarkers, unspiderfiedMarkers, _j, _len1, _ref1;
    if (markerNotToMove == null) {
      markerNotToMove = null;
    }
    if (this.spiderfied == null) {
      return this;
    }
    this.unspiderfying = true;
    unspiderfiedMarkers = [];
    nonNearbyMarkers = [];
    _ref1 = this.markers;
    for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
      marker = _ref1[_j];
      if (marker['_omsData'] != null) {
        marker['_omsData'].leg.setMap(null);
        if (marker !== markerNotToMove) {
          marker.setPosition(marker['_omsData'].usualPosition);
        }
        marker.setZIndex(null);
        listeners = marker['_omsData'].hightlightListeners;
        if (listeners != null) {
          ge.removeListener(listeners.highlight);
          ge.removeListener(listeners.unhighlight);
        }
        delete marker['_omsData'];
        unspiderfiedMarkers.push(marker);
      } else {
        nonNearbyMarkers.push(marker);
      }
    }
    delete this.unspiderfying;
    delete this.spiderfied;
    this.trigger('unspiderfy', unspiderfiedMarkers, nonNearbyMarkers);
    return this;
  };

  p.ptDistanceSq = function(pt1, pt2) {
    var dx, dy;
    dx = pt1.x - pt2.x;
    dy = pt1.y - pt2.y;
    return dx * dx + dy * dy;
  };

  p.ptAverage = function(pts) {
    var numPts, pt, sumX, sumY, _j, _len1;
    sumX = sumY = 0;
    for (_j = 0, _len1 = pts.length; _j < _len1; _j++) {
      pt = pts[_j];
      sumX += pt.x;
      sumY += pt.y;
    }
    numPts = pts.length;
    return new gm.Point(sumX / numPts, sumY / numPts);
  };

  p.llToPt = function(ll) {
    return this.projHelper.getProjection().fromLatLngToDivPixel(ll);
  };

  p.ptToLl = function(pt) {
    return this.projHelper.getProjection().fromDivPixelToLatLng(pt);
  };

  p.minExtract = function(set, func) {
    var bestIndex, bestVal, index, item, val, _j, _len1;
    for (index = _j = 0, _len1 = set.length; _j < _len1; index = ++_j) {
      item = set[index];
      val = func(item);
      if ((typeof bestIndex === "undefined" || bestIndex === null) || val < bestVal) {
        bestVal = val;
        bestIndex = index;
      }
    }
    return set.splice(bestIndex, 1)[0];
  };

  p.arrIndexOf = function(arr, obj) {
    var i, o, _j, _len1;
    if (arr.indexOf != null) {
      return arr.indexOf(obj);
    }
    for (i = _j = 0, _len1 = arr.length; _j < _len1; i = ++_j) {
      o = arr[i];
      if (o === obj) {
        return i;
      }
    }
    return -1;
  };

  _Class.ProjHelper = function(map) {
    return this.setMap(map);
  };

  _Class.ProjHelper.prototype = new gm.OverlayView();

  _Class.ProjHelper.prototype['draw'] = function() {};

  return _Class;

};

这是我的代码:

let omw = require('../../scripts/overlapping-marker-spidifier.js');
this.overlappingMarkerSpidifier = omw()(this.map); 

我原本以为我目前所拥有的会延迟执行脚本直到需要,然后手动调用,暴露OverlappingMarkerSpiderfier函数。

有人知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:3)

好的,我终于设法实现了这一点。涉及几个步骤。

首先,导入并调整重叠标记spidifier脚本

使用修改后的OMS脚本在项目中创建一个文件,绑定在下面。

如果要手动构建项目,请执行以下操作:

  • git clone https://github.com/jawj/OverlappingMarkerSpiderfier.git
  • cd OverlappingMarkerSpiderfier
  • 打开bower.json并将devDependency closure-compiler的url更改为//dl.google.com/closure-compiler/compiler-20131014.zip
  • 运行npm run dist
  • 打开lib / oms.js并修改文件以导出函数,如下面的代码所示:

```     / ** @preserve OverlappingMarkerSpiderfier     https://github.com/jawj/OverlappingMarkerSpiderfier     版权所有(c)2011 - 2013 George MacKerron     根据MIT许可证发布:http://opensource.org/licenses/mit-license     注意:在此代码之前,必须包含 Google Maps API v3      * /

module.exports = function () {

  var __hasProp = {}.hasOwnProperty, __slice = [].slice;
  var ge, gm, lcH, lcU, mt, p, twoPi, x, _i, _len, _ref;

  p = _Class.prototype;

  _ref = [_Class, p];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    x = _ref[_i];
    x['VERSION'] = '0.3.3';
  }

  gm = google.maps;

  ge = gm.event;

  mt = gm.MapTypeId;

  twoPi = Math.PI * 2;

  p['keepSpiderfied'] = false;

  p['markersWontHide'] = false;

  p['markersWontMove'] = false;

  p['nearbyDistance'] = 20;

  p['circleSpiralSwitchover'] = 9;

  p['circleFootSeparation'] = 23;

  p['circleStartAngle'] = twoPi / 12;

  p['spiralFootSeparation'] = 26;

  p['spiralLengthStart'] = 11;

  p['spiralLengthFactor'] = 4;

  p['spiderfiedZIndex'] = 1000;

  p['usualLegZIndex'] = 10;

  p['highlightedLegZIndex'] = 20;

  p['event'] = 'click';

  p['minZoomLevel'] = false;

  p['legWeight'] = 1.5;

  p['legColors'] = {
    'usual': {},
    'highlighted': {}
  };

  lcU = p['legColors']['usual'];

  lcH = p['legColors']['highlighted'];

  lcU[mt.HYBRID] = lcU[mt.SATELLITE] = '#fff';

  lcH[mt.HYBRID] = lcH[mt.SATELLITE] = '#f00';

  lcU[mt.TERRAIN] = lcU[mt.ROADMAP] = '#444';

  lcH[mt.TERRAIN] = lcH[mt.ROADMAP] = '#f00';

  function _Class(map, opts) {
    var e, k, v, _j, _len1, _ref1;
    this.map = map;
    if (opts == null) {
      opts = {};
    }
    for (k in opts) {
      if (!__hasProp.call(opts, k)) continue;
      v = opts[k];
      this[k] = v;
    }
    this.projHelper = new this.constructor.ProjHelper(this.map);
    this.initMarkerArrays();
    this.listeners = {};
    _ref1 = ['click', 'zoom_changed', 'maptypeid_changed'];
    for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
      e = _ref1[_j];
      ge.addListener(this.map, e, (function(_this) {
        return function() {
          return _this['unspiderfy']();
        };
      })(this));
    }
    return this;
  }

  p.initMarkerArrays = function() {
    this.markers = [];
    return this.markerListenerRefs = [];
  };

  p['addMarker'] = function(marker) {
    var listenerRefs;
    if (marker['_oms'] != null) {
      return this;
    }
    marker['_oms'] = true;
    listenerRefs = [
      ge.addListener(marker, this['event'], (function(_this) {
        return function(event) {
          return _this.spiderListener(marker, event);
        };
      })(this))
    ];
    if (!this['markersWontHide']) {
      listenerRefs.push(ge.addListener(marker, 'visible_changed', (function(_this) {
        return function() {
          return _this.markerChangeListener(marker, false);
        };
      })(this)));
    }
    if (!this['markersWontMove']) {
      listenerRefs.push(ge.addListener(marker, 'position_changed', (function(_this) {
        return function() {
          return _this.markerChangeListener(marker, true);
        };
      })(this)));
    }
    this.markerListenerRefs.push(listenerRefs);
    this.markers.push(marker);
    return this;
  };

  p.markerChangeListener = function(marker, positionChanged) {
    if ((marker['_omsData'] != null) && (positionChanged || !marker.getVisible()) && !((this.spiderfying != null) || (this.unspiderfying != null))) {
      return this['unspiderfy'](positionChanged ? marker : null);
    }
  };

  p['getMarkers'] = function() {
    return this.markers.slice(0);
  };

  p['removeMarker'] = function(marker) {
    var i, listenerRef, listenerRefs, _j, _len1;
    if (marker['_omsData'] != null) {
      this['unspiderfy']();
    }
    i = this.arrIndexOf(this.markers, marker);
    if (i < 0) {
      return this;
    }
    listenerRefs = this.markerListenerRefs.splice(i, 1)[0];
    for (_j = 0, _len1 = listenerRefs.length; _j < _len1; _j++) {
      listenerRef = listenerRefs[_j];
      ge.removeListener(listenerRef);
    }
    delete marker['_oms'];
    this.markers.splice(i, 1);
    return this;
  };

  p['clearMarkers'] = function() {
    var i, listenerRef, listenerRefs, marker, _j, _k, _len1, _len2, _ref1;
    this['unspiderfy']();
    _ref1 = this.markers;
    for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
      marker = _ref1[i];
      listenerRefs = this.markerListenerRefs[i];
      for (_k = 0, _len2 = listenerRefs.length; _k < _len2; _k++) {
        listenerRef = listenerRefs[_k];
        ge.removeListener(listenerRef);
      }
      delete marker['_oms'];
    }
    this.initMarkerArrays();
    return this;
  };

  p['addListener'] = function(event, func) {
    var _base;
    ((_base = this.listeners)[event] != null ? _base[event] : _base[event] = []).push(func);
    return this;
  };

  p['removeListener'] = function(event, func) {
    var i;
    i = this.arrIndexOf(this.listeners[event], func);
    if (!(i < 0)) {
      this.listeners[event].splice(i, 1);
    }
    return this;
  };

  p['clearListeners'] = function(event) {
    this.listeners[event] = [];
    return this;
  };

  p.trigger = function() {
    var args, event, func, _j, _len1, _ref1, _ref2, _results;
    event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
    _ref2 = (_ref1 = this.listeners[event]) != null ? _ref1 : [];
    _results = [];
    for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
      func = _ref2[_j];
      _results.push(func.apply(null, args));
    }
    return _results;
  };

  p.generatePtsCircle = function(count, centerPt) {
    var angle, angleStep, circumference, i, legLength, _j, _results;
    circumference = this['circleFootSeparation'] * (2 + count);
    legLength = circumference / twoPi;
    angleStep = twoPi / count;
    _results = [];
    for (i = _j = 0; 0 <= count ? _j < count : _j > count; i = 0 <= count ? ++_j : --_j) {
      angle = this['circleStartAngle'] + i * angleStep;
      _results.push(new gm.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle)));
    }
    return _results;
  };

  p.generatePtsSpiral = function(count, centerPt) {
    var angle, i, legLength, pt, _j, _results;
    legLength = this['spiralLengthStart'];
    angle = 0;
    _results = [];
    for (i = _j = 0; 0 <= count ? _j < count : _j > count; i = 0 <= count ? ++_j : --_j) {
      angle += this['spiralFootSeparation'] / legLength + i * 0.0005;
      pt = new gm.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle));
      legLength += twoPi * this['spiralLengthFactor'] / angle;
      _results.push(pt);
    }
    return _results;
  };

  p.spiderListener = function(marker, event) {
    var $this, clear, m, mPt, markerPt, markerSpiderfied, nDist, nearbyMarkerData, nonNearbyMarkers, pxSq, _j, _len1, _ref1;
    markerSpiderfied = marker['_omsData'] != null;
    if (!(markerSpiderfied && this['keepSpiderfied'])) {
      if (this['event'] === 'mouseover') {
        $this = this;
        clear = function() {
          return $this['unspiderfy']();
        };
        window.clearTimeout(p.timeout);
        p.timeout = setTimeout(clear, 3000);
      } else {
        this['unspiderfy']();
      }
    }
    if (markerSpiderfied || this.map.getStreetView().getVisible() || this.map.getMapTypeId() === 'GoogleEarthAPI') {
      return this.trigger('click', marker, event);
    } else {
      nearbyMarkerData = [];
      nonNearbyMarkers = [];
      nDist = this['nearbyDistance'];
      pxSq = nDist * nDist;
      markerPt = this.llToPt(marker.position);
      _ref1 = this.markers;
      for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
        m = _ref1[_j];
        if (!((m.map != null) && m.getVisible())) {
          continue;
        }
        mPt = this.llToPt(m.position);
        if (this.ptDistanceSq(mPt, markerPt) < pxSq) {
          nearbyMarkerData.push({
            marker: m,
            markerPt: mPt
          });
        } else {
          nonNearbyMarkers.push(m);
        }
      }
      if (nearbyMarkerData.length === 1) {
        return this.trigger('click', marker, event);
      } else {
        return this.spiderfy(nearbyMarkerData, nonNearbyMarkers);
      }
    }
  };

  p['markersNearMarker'] = function(marker, firstOnly) {
    var m, mPt, markerPt, markers, nDist, pxSq, _j, _len1, _ref1, _ref2, _ref3;
    if (firstOnly == null) {
      firstOnly = false;
    }
    if (this.projHelper.getProjection() == null) {
      throw "Must wait for 'idle' event on map before calling markersNearMarker";
    }
    nDist = this['nearbyDistance'];
    pxSq = nDist * nDist;
    markerPt = this.llToPt(marker.position);
    markers = [];
    _ref1 = this.markers;
    for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
      m = _ref1[_j];
      if (m === marker || (m.map == null) || !m.getVisible()) {
        continue;
      }
      mPt = this.llToPt((_ref2 = (_ref3 = m['_omsData']) != null ? _ref3.usualPosition : void 0) != null ? _ref2 : m.position);
      if (this.ptDistanceSq(mPt, markerPt) < pxSq) {
        markers.push(m);
        if (firstOnly) {
          break;
        }
      }
    }
    return markers;
  };

  p['markersNearAnyOtherMarker'] = function() {
    var i, i1, i2, m, m1, m1Data, m2, m2Data, mData, nDist, pxSq, _j, _k, _l, _len1, _len2, _len3, _ref1, _ref2, _ref3, _results;
    if (this.projHelper.getProjection() == null) {
      throw "Must wait for 'idle' event on map before calling markersNearAnyOtherMarker";
    }
    nDist = this['nearbyDistance'];
    pxSq = nDist * nDist;
    mData = (function() {
      var _j, _len1, _ref1, _ref2, _ref3, _results;
      _ref1 = this.markers;
      _results = [];
      for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
        m = _ref1[_j];
        _results.push({
          pt: this.llToPt((_ref2 = (_ref3 = m['_omsData']) != null ? _ref3.usualPosition : void 0) != null ? _ref2 : m.position),
          willSpiderfy: false
        });
      }
      return _results;
    }).call(this);
    _ref1 = this.markers;
    for (i1 = _j = 0, _len1 = _ref1.length; _j < _len1; i1 = ++_j) {
      m1 = _ref1[i1];
      if (!((m1.map != null) && m1.getVisible())) {
        continue;
      }
      m1Data = mData[i1];
      if (m1Data.willSpiderfy) {
        continue;
      }
      _ref2 = this.markers;
      for (i2 = _k = 0, _len2 = _ref2.length; _k < _len2; i2 = ++_k) {
        m2 = _ref2[i2];
        if (i2 === i1) {
          continue;
        }
        if (!((m2.map != null) && m2.getVisible())) {
          continue;
        }
        m2Data = mData[i2];
        if (i2 < i1 && !m2Data.willSpiderfy) {
          continue;
        }
        if (this.ptDistanceSq(m1Data.pt, m2Data.pt) < pxSq) {
          m1Data.willSpiderfy = m2Data.willSpiderfy = true;
          break;
        }
      }
    }
    _ref3 = this.markers;
    _results = [];
    for (i = _l = 0, _len3 = _ref3.length; _l < _len3; i = ++_l) {
      m = _ref3[i];
      if (mData[i].willSpiderfy) {
        _results.push(m);
      }
    }
    return _results;
  };

  p.makeHighlightListenerFuncs = function(marker) {
    return {
      highlight: (function(_this) {
        return function() {
          return marker['_omsData'].leg.setOptions({
            strokeColor: _this['legColors']['highlighted'][_this.map.mapTypeId],
            zIndex: _this['highlightedLegZIndex']
          });
        };
      })(this),
      unhighlight: (function(_this) {
        return function() {
          return marker['_omsData'].leg.setOptions({
            strokeColor: _this['legColors']['usual'][_this.map.mapTypeId],
            zIndex: _this['usualLegZIndex']
          });
        };
      })(this)
    };
  };

  p.spiderfy = function(markerData, nonNearbyMarkers) {
    var bodyPt, footLl, footPt, footPts, highlightListenerFuncs, leg, marker, md, nearestMarkerDatum, numFeet, spiderfiedMarkers;
    if (this['minZoomLevel'] && this.map.getZoom() < this['minZoomLevel']) {
      return false;
    }
    this.spiderfying = true;
    numFeet = markerData.length;
    bodyPt = this.ptAverage((function() {
      var _j, _len1, _results;
      _results = [];
      for (_j = 0, _len1 = markerData.length; _j < _len1; _j++) {
        md = markerData[_j];
        _results.push(md.markerPt);
      }
      return _results;
    })());
    footPts = numFeet >= this['circleSpiralSwitchover'] ? this.generatePtsSpiral(numFeet, bodyPt).reverse() : this.generatePtsCircle(numFeet, bodyPt);
    spiderfiedMarkers = (function() {
      var _j, _len1, _results;
      _results = [];
      for (_j = 0, _len1 = footPts.length; _j < _len1; _j++) {
        footPt = footPts[_j];
        footLl = this.ptToLl(footPt);
        nearestMarkerDatum = this.minExtract(markerData, (function(_this) {
          return function(md) {
            return _this.ptDistanceSq(md.markerPt, footPt);
          };
        })(this));
        marker = nearestMarkerDatum.marker;
        leg = new gm.Polyline({
          map: this.map,
          path: [marker.position, footLl],
          strokeColor: this['legColors']['usual'][this.map.mapTypeId],
          strokeWeight: this['legWeight'],
          zIndex: this['usualLegZIndex']
        });
        marker['_omsData'] = {
          usualPosition: marker.position,
          leg: leg
        };
        if (this['legColors']['highlighted'][this.map.mapTypeId] !== this['legColors']['usual'][this.map.mapTypeId]) {
          highlightListenerFuncs = this.makeHighlightListenerFuncs(marker);
          marker['_omsData'].hightlightListeners = {
            highlight: ge.addListener(marker, 'mouseover', highlightListenerFuncs.highlight),
            unhighlight: ge.addListener(marker, 'mouseout', highlightListenerFuncs.unhighlight)
          };
        }
        marker.setPosition(footLl);
        marker.setZIndex(Math.round(this['spiderfiedZIndex'] + footPt.y));
        _results.push(marker);
      }
      return _results;
    }).call(this);
    delete this.spiderfying;
    this.spiderfied = true;
    return this.trigger('spiderfy', spiderfiedMarkers, nonNearbyMarkers);
  };

  p['unspiderfy'] = function(markerNotToMove) {
    var listeners, marker, nonNearbyMarkers, unspiderfiedMarkers, _j, _len1, _ref1;
    if (markerNotToMove == null) {
      markerNotToMove = null;
    }
    if (this.spiderfied == null) {
      return this;
    }
    this.unspiderfying = true;
    unspiderfiedMarkers = [];
    nonNearbyMarkers = [];
    _ref1 = this.markers;
    for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
      marker = _ref1[_j];
      if (marker['_omsData'] != null) {
        marker['_omsData'].leg.setMap(null);
        if (marker !== markerNotToMove) {
          marker.setPosition(marker['_omsData'].usualPosition);
        }
        marker.setZIndex(null);
        listeners = marker['_omsData'].hightlightListeners;
        if (listeners != null) {
          ge.removeListener(listeners.highlight);
          ge.removeListener(listeners.unhighlight);
        }
        delete marker['_omsData'];
        unspiderfiedMarkers.push(marker);
      } else {
        nonNearbyMarkers.push(marker);
      }
    }
    delete this.unspiderfying;
    delete this.spiderfied;
    this.trigger('unspiderfy', unspiderfiedMarkers, nonNearbyMarkers);
    return this;
  };

  p.ptDistanceSq = function(pt1, pt2) {
    var dx, dy;
    dx = pt1.x - pt2.x;
    dy = pt1.y - pt2.y;
    return dx * dx + dy * dy;
  };

  p.ptAverage = function(pts) {
    var numPts, pt, sumX, sumY, _j, _len1;
    sumX = sumY = 0;
    for (_j = 0, _len1 = pts.length; _j < _len1; _j++) {
      pt = pts[_j];
      sumX += pt.x;
      sumY += pt.y;
    }
    numPts = pts.length;
    return new gm.Point(sumX / numPts, sumY / numPts);
  };

  p.llToPt = function(ll) {
    return this.projHelper.getProjection().fromLatLngToDivPixel(ll);
  };

  p.ptToLl = function(pt) {
    return this.projHelper.getProjection().fromDivPixelToLatLng(pt);
  };

  p.minExtract = function(set, func) {
    var bestIndex, bestVal, index, item, val, _j, _len1;
    for (index = _j = 0, _len1 = set.length; _j < _len1; index = ++_j) {
      item = set[index];
      val = func(item);
      if ((typeof bestIndex === "undefined" || bestIndex === null) || val < bestVal) {
        bestVal = val;
        bestIndex = index;
      }
    }
    return set.splice(bestIndex, 1)[0];
  };

  p.arrIndexOf = function(arr, obj) {
    var i, o, _j, _len1;
    if (arr.indexOf != null) {
      return arr.indexOf(obj);
    }
    for (i = _j = 0, _len1 = arr.length; _j < _len1; i = ++_j) {
      o = arr[i];
      if (o === obj) {
        return i;
      }
    }
    return -1;
  };

  _Class.ProjHelper = function(map) {
    return this.setMap(map);
  };

  _Class.ProjHelper.prototype = new gm.OverlayView();

  _Class.ProjHelper.prototype['draw'] = function() {};

  return _Class;

};

```

将OMS脚本导入使用sebm-google-map的组件

将以下属性添加到使用sebm-google-map组件的组件中:

let oms = require('../../scripts/overlapping-marker-spidifier.js');

获取原生地图,标记管理器和标记

创建一个新指令,用于获取本机地图对象,标记管理器和标记。它将嵌套在sebm-google-map组件中(请注意get-google-map指令,并确保您的标记嵌套在get-google-map指令中):

<my-parent-component>
    <sebm-google-map>
        <get-google-map (map)="setMap($event)" (markerManager)="setMarkerManager($event)" (markers)="setMarkers($event)">
            <sebm-google-map-marker ... ></sebm-google-map-marker>
        </get-google-map>
    </sebm-google-map>
</my-parent-component>

这是指令的代码:

import { Directive, Output, EventEmitter, AfterViewInit, ContentChildren, QueryList } from '@angular/core';
import { GoogleMapsAPIWrapper, MarkerManager, SebmGoogleMapMarker } from 'angular2-google-maps/core';

@Directive({
  selector: 'get-google-map',
})
export class GetGoogleMapDirective implements AfterViewInit {

  /**
   * Get native map object
   */
  private _map: any = null;
  @Output('map') mapChanged: EventEmitter<any> = new EventEmitter<any>();
  set map(val){
    this._map = val;
    this.mapChanged.emit(val);
  }
  get map(){
    return this._map;
  }

  /**
   * Get marker manager
   */
  private _markerManager: any = null;
  @Output('markerManager') markerManagerChanged: EventEmitter<MarkerManager> = new EventEmitter<MarkerManager>();
  set markerManager(val){
    this._markerManager = val;
    this.markerManagerChanged.emit(val);
  }
  get markerManager(){
    return this._markerManager;
  }

  /**
   * Get sebm markers
   */
  private _markers: any = null;
  @Output('markers') markersChanged: EventEmitter<SebmGoogleMapMarker[]> = new EventEmitter<SebmGoogleMapMarker[]>();
  set markers(val){
    this._markers = val;
    this.markersChanged.emit(val);
  }
  get markers(){
    return this._markers;
  }
  @ContentChildren(SebmGoogleMapMarker) markerChildren: QueryList<SebmGoogleMapMarker>;

  constructor(
    private googleMapsWrapper: GoogleMapsAPIWrapper,
    private googleMarkerManager: MarkerManager
  ) { }

  ngAfterViewInit() {
    // get native map
    this.googleMapsWrapper.getNativeMap().then(map => {
      this.map = map;
    }, error => {
      throw error;
    })

    // get marker manager
    this.markerManager = this.googleMarkerManager;

    // get markers
    this.markerChildren.changes.subscribe(markers => {
      this.markers = markers._results;
    })
  }
}

当该指令被引入时会发生三件事:

  • 它获取对本机地图对象的引用,并使用事件发射器
  • 输出它
  • 它获取对标记管理器的引用并使用事件发射器
  • 输出它
  • 它引用了所有SebmGoogleMapMarkers

在父组件中使用标记管理器,标记和本机地图对象

注意markerManager,map和markers的get-google-map输出上的事件绑定。我们需要在父对象中为这些对象设置函数,以便在输出这些对象时捕获它们:

  /**
   * Sets up google map spidifier
   */
  setupSpidifier(){
    let getOms = oms();
    this.overlappingMarkerSpidifier = getOms.call(getOms.prototype, this.map); 
  }

  /**
   * Sets a reference to the google map object created by sebm - uses GetGoogleMapComponent
   */
  setMap(map: any){
    this.map = map;
    this.setupSpidifier();
  }

  /**
   * Gets the google marker manager from get-google-map
   */
  setMarkerManager(markerManager: MarkerManager){
    this.markerManager = markerManager;
  }

  /**
   * Sets the markers, used by spidifier
   */
  setMarkers(markers: SebmGoogleMapMarker[]){
    this.markers = markers;
    for(let marker of markers){
      this.markerManager.getNativeMarker(marker).then(marker => {
        this.overlappingMarkerSpidifier.addMarker(marker);
      });
    }
  }

以上代码捕获从我们的指令输出的地图,标记管理器和标记。当我们得到地图时,我们保存它,然后调用setup spidifier,它在我们的sebm-map上初始化OMS。

接下来,我们缓存标记管理器,每次输出标记时,我们将它们添加到OMS。

那就是它!如果答案不清楚,请道歉,如果我需要澄清任何内容,请写一下,所以请发表评论。