Files
nodeMap/node_modules/overlapping-marker-spiderfier-leaflet/build/oms.js

386 lines
12 KiB
JavaScript

(function () {
'use strict';
/** @preserve OverlappingMarkerSpiderfier
https://github.com/jawj/OverlappingMarkerSpiderfier-Leaflet
Copyright (c) 2011 - 2012 George MacKerron
Released under the MIT licence: http://opensource.org/licenses/mit-license
Note: The Leaflet maps API must be included *before* this code
*/
var hasProp = {}.hasOwnProperty,
slice = [].slice;
(function() {
if (this['L'] == null) {
return;
}
return this['OverlappingMarkerSpiderfier'] = (function() {
var p, twoPi;
p = _Class.prototype;
p['VERSION'] = '0.2.6';
twoPi = Math.PI * 2;
p['keepSpiderfied'] = false;
p['nearbyDistance'] = 20;
p['circleSpiralSwitchover'] = 9;
p['circleFootSeparation'] = 25;
p['circleStartAngle'] = twoPi / 12;
p['spiralFootSeparation'] = 28;
p['spiralLengthStart'] = 11;
p['spiralLengthFactor'] = 5;
p['legWeight'] = 1.5;
p['legColors'] = {
'usual': '#222',
'highlighted': '#f00'
};
function _Class(map, opts) {
var e, j, k, len, ref, v;
this.map = map;
if (opts == null) {
opts = {};
}
for (k in opts) {
if (!hasProp.call(opts, k)) continue;
v = opts[k];
this[k] = v;
}
this.initMarkerArrays();
this.listeners = {};
ref = ['click', 'zoomend'];
for (j = 0, len = ref.length; j < len; j++) {
e = ref[j];
this.map.addEventListener(e, (function(_this) {
return function() {
return _this['unspiderfy']();
};
})(this));
}
}
p.initMarkerArrays = function() {
this.markers = [];
return this.markerListeners = [];
};
p['addMarker'] = function(marker) {
var markerListener;
if (marker['_oms'] != null) {
return this;
}
marker['_oms'] = true;
markerListener = (function(_this) {
return function() {
return _this.spiderListener(marker);
};
})(this);
marker.addEventListener('click', markerListener);
this.markerListeners.push(markerListener);
this.markers.push(marker);
return this;
};
p['getMarkers'] = function() {
return this.markers.slice(0);
};
p['removeMarker'] = function(marker) {
var i, markerListener;
if (marker['_omsData'] != null) {
this['unspiderfy']();
}
i = this.arrIndexOf(this.markers, marker);
if (i < 0) {
return this;
}
markerListener = this.markerListeners.splice(i, 1)[0];
marker.removeEventListener('click', markerListener);
delete marker['_oms'];
this.markers.splice(i, 1);
return this;
};
p['clearMarkers'] = function() {
var i, j, len, marker, markerListener, ref;
this['unspiderfy']();
ref = this.markers;
for (i = j = 0, len = ref.length; j < len; i = ++j) {
marker = ref[i];
markerListener = this.markerListeners[i];
marker.removeEventListener('click', markerListener);
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, len, ref, ref1, results;
event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
ref1 = (ref = this.listeners[event]) != null ? ref : [];
results = [];
for (j = 0, len = ref1.length; j < len; j++) {
func = ref1[j];
results.push(func.apply(null, args));
}
return results;
};
p.generatePtsCircle = function(count, centerPt) {
var angle, angleStep, circumference, i, j, legLength, ref, results;
circumference = this['circleFootSeparation'] * (2 + count);
legLength = circumference / twoPi;
angleStep = twoPi / count;
results = [];
for (i = j = 0, ref = count; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
angle = this['circleStartAngle'] + i * angleStep;
results.push(new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle)));
}
return results;
};
p.generatePtsSpiral = function(count, centerPt) {
var angle, i, j, legLength, pt, ref, results;
legLength = this['spiralLengthStart'];
angle = 0;
results = [];
for (i = j = 0, ref = count; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
angle += this['spiralFootSeparation'] / legLength + i * 0.0005;
pt = new L.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) {
var j, len, m, mPt, markerPt, markerSpiderfied, nearbyMarkerData, nonNearbyMarkers, pxSq, ref;
markerSpiderfied = marker['_omsData'] != null;
if (!(markerSpiderfied && this['keepSpiderfied'])) {
this['unspiderfy']();
}
if (markerSpiderfied) {
return this.trigger('click', marker);
} else {
nearbyMarkerData = [];
nonNearbyMarkers = [];
pxSq = this['nearbyDistance'] * this['nearbyDistance'];
markerPt = this.map.latLngToLayerPoint(marker.getLatLng());
ref = this.markers;
for (j = 0, len = ref.length; j < len; j++) {
m = ref[j];
if (!this.map.hasLayer(m)) {
continue;
}
mPt = this.map.latLngToLayerPoint(m.getLatLng());
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);
} else {
return this.spiderfy(nearbyMarkerData, nonNearbyMarkers);
}
}
};
p.makeHighlightListeners = function(marker) {
return {
highlight: (function(_this) {
return function() {
return marker['_omsData'].leg.setStyle({
color: _this['legColors']['highlighted']
});
};
})(this),
unhighlight: (function(_this) {
return function() {
return marker['_omsData'].leg.setStyle({
color: _this['legColors']['usual']
});
};
})(this)
};
};
p.spiderfy = function(markerData, nonNearbyMarkers) {
var bodyPt, footLl, footPt, footPts, leg, marker, md, mhl, nearestMarkerDatum, numFeet, spiderfiedMarkers;
this.spiderfying = true;
numFeet = markerData.length;
bodyPt = this.ptAverage((function() {
var j, len, results;
results = [];
for (j = 0, len = markerData.length; j < len; 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, len, results;
results = [];
for (j = 0, len = footPts.length; j < len; j++) {
footPt = footPts[j];
footLl = this.map.layerPointToLatLng(footPt);
nearestMarkerDatum = this.minExtract(markerData, (function(_this) {
return function(md) {
return _this.ptDistanceSq(md.markerPt, footPt);
};
})(this));
marker = nearestMarkerDatum.marker;
leg = new L.Polyline([marker.getLatLng(), footLl], {
color: this['legColors']['usual'],
weight: this['legWeight'],
clickable: false
});
this.map.addLayer(leg);
marker['_omsData'] = {
usualPosition: marker.getLatLng(),
leg: leg
};
if (this['legColors']['highlighted'] !== this['legColors']['usual']) {
mhl = this.makeHighlightListeners(marker);
marker['_omsData'].highlightListeners = mhl;
marker.addEventListener('mouseover', mhl.highlight);
marker.addEventListener('mouseout', mhl.unhighlight);
}
marker.setLatLng(footLl);
marker.setZIndexOffset(marker.options.zIndexOffset + 1000000);
results.push(marker);
}
return results;
}).call(this);
delete this.spiderfying;
this.spiderfied = true;
return this.trigger('spiderfy', spiderfiedMarkers, nonNearbyMarkers);
};
p['unspiderfy'] = function(markerNotToMove) {
var j, len, marker, mhl, nonNearbyMarkers, ref, unspiderfiedMarkers;
if (markerNotToMove == null) {
markerNotToMove = null;
}
if (this.spiderfied == null) {
return this;
}
this.unspiderfying = true;
unspiderfiedMarkers = [];
nonNearbyMarkers = [];
ref = this.markers;
for (j = 0, len = ref.length; j < len; j++) {
marker = ref[j];
if (marker['_omsData'] != null) {
this.map.removeLayer(marker['_omsData'].leg);
if (marker !== markerNotToMove) {
marker.setLatLng(marker['_omsData'].usualPosition);
}
marker.setZIndexOffset(marker.options.zIndexOffset - 1000000);
mhl = marker['_omsData'].highlightListeners;
if (mhl != null) {
marker.removeEventListener('mouseover', mhl.highlight);
marker.removeEventListener('mouseout', mhl.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 j, len, numPts, pt, sumX, sumY;
sumX = sumY = 0;
for (j = 0, len = pts.length; j < len; j++) {
pt = pts[j];
sumX += pt.x;
sumY += pt.y;
}
numPts = pts.length;
return new L.Point(sumX / numPts, sumY / numPts);
};
p.minExtract = function(set, func) {
var bestIndex, bestVal, index, item, j, len, val;
for (index = j = 0, len = set.length; j < len; 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, j, len, o;
if (arr.indexOf != null) {
return arr.indexOf(obj);
}
for (i = j = 0, len = arr.length; j < len; i = ++j) {
o = arr[i];
if (o === obj) {
return i;
}
}
return -1;
};
return _Class;
})();
}).call(window);
}());