aboutsummaryrefslogtreecommitdiffstats
path: root/extlib/leaflet/src/layer/vector
diff options
context:
space:
mode:
Diffstat (limited to 'extlib/leaflet/src/layer/vector')
-rw-r--r--extlib/leaflet/src/layer/vector/Circle.js51
-rw-r--r--extlib/leaflet/src/layer/vector/CircleMarker.js25
-rw-r--r--extlib/leaflet/src/layer/vector/MultiPoly.js27
-rw-r--r--extlib/leaflet/src/layer/vector/Path.Popup.js24
-rw-r--r--extlib/leaflet/src/layer/vector/Path.VML.js91
-rw-r--r--extlib/leaflet/src/layer/vector/Path.js207
-rw-r--r--extlib/leaflet/src/layer/vector/Polygon.js58
-rw-r--r--extlib/leaflet/src/layer/vector/Polyline.js112
8 files changed, 595 insertions, 0 deletions
diff --git a/extlib/leaflet/src/layer/vector/Circle.js b/extlib/leaflet/src/layer/vector/Circle.js
new file mode 100644
index 00000000..c737c191
--- /dev/null
+++ b/extlib/leaflet/src/layer/vector/Circle.js
@@ -0,0 +1,51 @@
+/*
+ * L.Circle is a circle overlay (with a certain radius in meters).
+ */
+
+L.Circle = L.Path.extend({
+ initialize: function(latlng, radius, options) {
+ L.Path.prototype.initialize.call(this, options);
+
+ this._latlng = latlng;
+ this._mRadius = radius;
+ },
+
+ options: {
+ fill: true
+ },
+
+ setLatLng: function(latlng) {
+ this._latlng = latlng;
+ this._redraw();
+ return this;
+ },
+
+ setRadius: function(radius) {
+ this._mRadius = radius;
+ this._redraw();
+ return this;
+ },
+
+ projectLatlngs: function() {
+ var equatorLength = 40075017,
+ scale = this._map.options.scale(this._map._zoom);
+
+ this._point = this._map.latLngToLayerPoint(this._latlng);
+ this._radius = (this._mRadius / equatorLength) * scale;
+ },
+
+ getPathString: function() {
+ var p = this._point,
+ r = this._radius;
+
+ if (L.Path.SVG) {
+ return "M" + p.x + "," + (p.y - r) +
+ "A" + r + "," + r + ",0,1,1," +
+ (p.x - 0.1) + "," + (p.y - r) + " z";
+ } else {
+ p._round();
+ r = Math.round(r);
+ return "AL " + p.x + "," + p.y + " " + r + "," + r + " 0," + (65535 * 360);
+ }
+ }
+}); \ No newline at end of file
diff --git a/extlib/leaflet/src/layer/vector/CircleMarker.js b/extlib/leaflet/src/layer/vector/CircleMarker.js
new file mode 100644
index 00000000..fa4bacf0
--- /dev/null
+++ b/extlib/leaflet/src/layer/vector/CircleMarker.js
@@ -0,0 +1,25 @@
+/*
+ * L.CircleMarker is a circle overlay with a permanent pixel radius.
+ */
+
+L.CircleMarker = L.Circle.extend({
+ options: {
+ radius: 10,
+ weight: 2
+ },
+
+ initialize: function(latlng, options) {
+ L.Circle.prototype.initialize.call(this, latlng, null, options);
+ this._radius = this.options.radius;
+ },
+
+ projectLatlngs: function() {
+ this._point = this._map.latLngToLayerPoint(this._latlng);
+ },
+
+ setRadius: function(radius) {
+ this._radius = radius;
+ this._redraw();
+ return this;
+ }
+}); \ No newline at end of file
diff --git a/extlib/leaflet/src/layer/vector/MultiPoly.js b/extlib/leaflet/src/layer/vector/MultiPoly.js
new file mode 100644
index 00000000..60d6de68
--- /dev/null
+++ b/extlib/leaflet/src/layer/vector/MultiPoly.js
@@ -0,0 +1,27 @@
+/*
+ * Contains L.MultiPolyline and L.MultiPolygon layers.
+ */
+
+(function() {
+ function createMulti(klass) {
+ return L.FeatureGroup.extend({
+ initialize: function(latlngs, options) {
+ this._layers = {};
+ for (var i = 0, len = latlngs.length; i < len; i++) {
+ this.addLayer(new klass(latlngs[i], options));
+ }
+ },
+
+ setStyle: function(style) {
+ for (var i in this._layers) {
+ if (this._layers.hasOwnProperty(i) && this._layers[i].setStyle) {
+ this._layers[i].setStyle(style);
+ }
+ }
+ }
+ });
+ }
+
+ L.MultiPolyline = createMulti(L.Polyline);
+ L.MultiPolygon = createMulti(L.Polygon);
+}());
diff --git a/extlib/leaflet/src/layer/vector/Path.Popup.js b/extlib/leaflet/src/layer/vector/Path.Popup.js
new file mode 100644
index 00000000..b82a4920
--- /dev/null
+++ b/extlib/leaflet/src/layer/vector/Path.Popup.js
@@ -0,0 +1,24 @@
+/*
+ * Popup extension to L.Path (polylines, polygons, circles), adding bindPopup method.
+ */
+
+L.Path.include({
+ bindPopup: function(content, options) {
+ if (!this._popup || this._popup.options !== options) {
+ this._popup = new L.Popup(options);
+ }
+ this._popup.setContent(content);
+
+ if (!this._openPopupAdded) {
+ this.on('click', this._openPopup, this);
+ this._openPopupAdded = true;
+ }
+
+ return this;
+ },
+
+ _openPopup: function(e) {
+ this._popup.setLatLng(e.latlng);
+ this._map.openPopup(this._popup);
+ }
+}); \ No newline at end of file
diff --git a/extlib/leaflet/src/layer/vector/Path.VML.js b/extlib/leaflet/src/layer/vector/Path.VML.js
new file mode 100644
index 00000000..8481d994
--- /dev/null
+++ b/extlib/leaflet/src/layer/vector/Path.VML.js
@@ -0,0 +1,91 @@
+/*
+ * Vector rendering for IE6-8 through VML.
+ * Thanks to Dmitry Baranovsky and his Raphael library for inspiration!
+ */
+
+L.Path.VML = (function() {
+ var d = document.createElement('div'), s;
+ d.innerHTML = '<v:shape adj="1"/>';
+ s = d.firstChild;
+ s.style.behavior = 'url(#default#VML)';
+
+ return (s && (typeof s.adj == 'object'));
+})();
+
+L.Path = L.Path.SVG || !L.Path.VML ? L.Path : L.Path.extend({
+ statics: {
+ CLIP_PADDING: 0.02
+ },
+
+ _createElement: (function() {
+ try {
+ document.namespaces.add('lvml', 'urn:schemas-microsoft-com:vml');
+ return function(name) {
+ return document.createElement('<lvml:' + name + ' class="lvml">');
+ };
+ } catch (e) {
+ return function(name) {
+ return document.createElement('<' + name + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">');
+ };
+ }
+ })(),
+
+ _initRoot: function() {
+ if (!this._map._pathRoot) {
+ this._map._pathRoot = document.createElement('div');
+ this._map._pathRoot.className = 'leaflet-vml-container';
+ this._map._panes.overlayPane.appendChild(this._map._pathRoot);
+
+ this._map.on('moveend', this._updateViewport, this);
+ this._updateViewport();
+ }
+ },
+
+ _initPath: function() {
+ this._container = this._createElement('shape');
+ this._container.className += ' leaflet-vml-shape' +
+ (this.options.clickable ? ' leaflet-clickable' : '');
+ this._container.coordsize = '1 1';
+
+ this._path = this._createElement('path');
+ this._container.appendChild(this._path);
+
+ this._map._pathRoot.appendChild(this._container);
+ },
+
+ _initStyle: function() {
+ if (this.options.stroke) {
+ this._stroke = this._createElement('stroke');
+ this._stroke.endcap = 'round';
+ this._container.appendChild(this._stroke);
+ } else {
+ this._container.stroked = false;
+ }
+ if (this.options.fill) {
+ this._container.filled = true;
+ this._fill = this._createElement('fill');
+ this._container.appendChild(this._fill);
+ } else {
+ this._container.filled = false;
+ }
+ this._updateStyle();
+ },
+
+ _updateStyle: function() {
+ if (this.options.stroke) {
+ this._stroke.weight = this.options.weight + 'px';
+ this._stroke.color = this.options.color;
+ this._stroke.opacity = this.options.opacity;
+ }
+ if (this.options.fill) {
+ this._fill.color = this.options.fillColor || this.options.color;
+ this._fill.opacity = this.options.fillOpacity;
+ }
+ },
+
+ _updatePath: function() {
+ this._container.style.display = 'none';
+ this._path.v = this.getPathString() + ' '; // the space fixes IE empty path string bug
+ this._container.style.display = '';
+ }
+}); \ No newline at end of file
diff --git a/extlib/leaflet/src/layer/vector/Path.js b/extlib/leaflet/src/layer/vector/Path.js
new file mode 100644
index 00000000..3d4837cc
--- /dev/null
+++ b/extlib/leaflet/src/layer/vector/Path.js
@@ -0,0 +1,207 @@
+/*
+ * L.Path is a base class for rendering vector paths on a map. It's inherited by Polyline, Circle, etc.
+ */
+
+L.Path = L.Class.extend({
+ includes: [L.Mixin.Events],
+
+ statics: (function() {
+ var svgns = 'http://www.w3.org/2000/svg',
+ ce = 'createElementNS';
+
+ return {
+ SVG_NS: svgns,
+ SVG: !!(document[ce] && document[ce](svgns, 'svg').createSVGRect),
+
+ // how much to extend the clip area around the map view
+ // (relative to its size, e.g. 0.5 is half the screen in each direction)
+ CLIP_PADDING: 0.5
+ };
+ })(),
+
+ options: {
+ stroke: true,
+ color: '#0033ff',
+ weight: 5,
+ opacity: 0.5,
+
+ fill: false,
+ fillColor: null, //same as color by default
+ fillOpacity: 0.2,
+
+ clickable: true,
+
+ updateOnMoveEnd: false
+ },
+
+ initialize: function(options) {
+ L.Util.setOptions(this, options);
+ },
+
+ onAdd: function(map) {
+ this._map = map;
+
+ this._initElements();
+ this._initEvents();
+ this.projectLatlngs();
+ this._updatePath();
+
+ map.on('viewreset', this.projectLatlngs, this);
+
+ this._updateTrigger = this.options.updateOnMoveEnd ? 'moveend' : 'viewreset';
+ map.on(this._updateTrigger, this._updatePath, this);
+ },
+
+ onRemove: function(map) {
+ map._pathRoot.removeChild(this._container);
+ map.off('viewreset', this._projectLatlngs, this);
+ map.off(this._updateTrigger, this._updatePath, this);
+ },
+
+ projectLatlngs: function() {
+ // do all projection stuff here
+ },
+
+ getPathString: function() {
+ // form path string here
+ },
+
+ setStyle: function(style) {
+ L.Util.setOptions(this, style);
+ if (this._path) {
+ this._updateStyle();
+ }
+ },
+
+ _initElements: function() {
+ this._initRoot();
+ this._initPath();
+ this._initStyle();
+ },
+
+ _initRoot: function() {
+ if (!this._map._pathRoot) {
+ this._map._pathRoot = this._createElement('svg');
+ this._map._panes.overlayPane.appendChild(this._map._pathRoot);
+
+ this._map.on('moveend', this._updateSvgViewport, this);
+ this._updateSvgViewport();
+ }
+ },
+
+ _updateSvgViewport: function() {
+ this._updateViewport();
+
+ var vp = this._map._pathViewport,
+ min = vp.min,
+ max = vp.max,
+ width = max.x - min.x,
+ height = max.y - min.y,
+ root = this._map._pathRoot,
+ pane = this._map._panes.overlayPane;
+
+ // Hack to make flicker on drag end on mobile webkit less irritating
+ // Unfortunately I haven't found a good workaround for this yet
+ if (L.Browser.mobileWebkit) { pane.removeChild(root); }
+
+ L.DomUtil.setPosition(root, min);
+ root.setAttribute('width', width);
+ root.setAttribute('height', height);
+ root.setAttribute('viewBox', [min.x, min.y, width, height].join(' '));
+
+ if (L.Browser.mobileWebkit) { pane.appendChild(root); }
+ },
+
+ _updateViewport: function() {
+ var p = L.Path.CLIP_PADDING,
+ size = this._map.getSize(),
+ //TODO this._map._getMapPanePos()
+ panePos = L.DomUtil.getPosition(this._map._mapPane),
+ min = panePos.multiplyBy(-1).subtract(size.multiplyBy(p)),
+ max = min.add(size.multiplyBy(1 + p * 2));
+
+ this._map._pathViewport = new L.Bounds(min, max);
+ },
+
+ _initPath: function() {
+ this._container = this._createElement('g');
+
+ this._path = this._createElement('path');
+ this._container.appendChild(this._path);
+
+ this._map._pathRoot.appendChild(this._container);
+ },
+
+ _initStyle: function() {
+ if (this.options.stroke) {
+ this._path.setAttribute('stroke-linejoin', 'round');
+ this._path.setAttribute('stroke-linecap', 'round');
+ }
+ if (this.options.fill) {
+ this._path.setAttribute('fill-rule', 'evenodd');
+ } else {
+ this._path.setAttribute('fill', 'none');
+ }
+ this._updateStyle();
+ },
+
+ _updateStyle: function() {
+ if (this.options.stroke) {
+ this._path.setAttribute('stroke', this.options.color);
+ this._path.setAttribute('stroke-opacity', this.options.opacity);
+ this._path.setAttribute('stroke-width', this.options.weight);
+ }
+ if (this.options.fill) {
+ this._path.setAttribute('fill', this.options.fillColor || this.options.color);
+ this._path.setAttribute('fill-opacity', this.options.fillOpacity);
+ }
+ },
+
+ _updatePath: function() {
+ var str = this.getPathString();
+ if (!str) {
+ // fix webkit empty string parsing bug
+ str = 'M0 0';
+ }
+ this._path.setAttribute('d', str);
+ },
+
+ _createElement: function(name) {
+ return document.createElementNS(L.Path.SVG_NS, name);
+ },
+
+ // TODO remove duplication with L.Map
+ _initEvents: function() {
+ if (this.options.clickable) {
+ if (!L.Path.VML) {
+ this._path.setAttribute('class', 'leaflet-clickable');
+ }
+
+ L.DomEvent.addListener(this._container, 'click', this._onMouseClick, this);
+
+ var events = ['dblclick', 'mousedown', 'mouseover', 'mouseout'];
+ for (var i = 0; i < events.length; i++) {
+ L.DomEvent.addListener(this._container, events[i], this._fireMouseEvent, this);
+ }
+ }
+ },
+
+ _onMouseClick: function(e) {
+ if (this._map.dragging && this._map.dragging.moved()) { return; }
+ this._fireMouseEvent(e);
+ },
+
+ _fireMouseEvent: function(e) {
+ if (!this.hasEventListeners(e.type)) { return; }
+ this.fire(e.type, {
+ latlng: this._map.mouseEventToLatLng(e),
+ layerPoint: this._map.mouseEventToLayerPoint(e)
+ });
+ L.DomEvent.stopPropagation(e);
+ },
+
+ _redraw: function() {
+ this.projectLatlngs();
+ this._updatePath();
+ }
+}); \ No newline at end of file
diff --git a/extlib/leaflet/src/layer/vector/Polygon.js b/extlib/leaflet/src/layer/vector/Polygon.js
new file mode 100644
index 00000000..52bf2d6b
--- /dev/null
+++ b/extlib/leaflet/src/layer/vector/Polygon.js
@@ -0,0 +1,58 @@
+/*
+ * L.Polygon is used to display polygons on a map.
+ */
+
+L.Polygon = L.Polyline.extend({
+ options: {
+ fill: true
+ },
+
+ initialize: function(latlngs, options) {
+ L.Polyline.prototype.initialize.call(this, latlngs, options);
+
+ if (latlngs[0] instanceof Array) {
+ this._latlngs = latlngs[0];
+ this._holes = latlngs.slice(1);
+ }
+ },
+
+ projectLatlngs: function() {
+ L.Polyline.prototype.projectLatlngs.call(this);
+
+ // project polygon holes points
+ // TODO move this logic to Polyline to get rid of duplication
+ this._holePoints = [];
+
+ if (!this._holes) return;
+
+ for (var i = 0, len = this._holes.length, hole; i < len; i++) {
+ this._holePoints[i] = [];
+
+ for(var j = 0, len2 = this._holes[i].length; j < len2; j++) {
+ this._holePoints[i][j] = this._map.latLngToLayerPoint(this._holes[i][j]);
+ }
+ }
+ },
+
+ _clipPoints: function() {
+ var points = this._originalPoints,
+ newParts = [];
+
+ this._parts = [points].concat(this._holePoints);
+
+ if (this.options.noClip) return;
+
+ for (var i = 0, len = this._parts.length; i < len; i++) {
+ var clipped = L.PolyUtil.clipPolygon(this._parts[i], this._map._pathViewport);
+ if (!clipped.length) continue;
+ newParts.push(clipped);
+ }
+
+ this._parts = newParts;
+ },
+
+ _getPathPartStr: function(points) {
+ var str = L.Polyline.prototype._getPathPartStr.call(this, points);
+ return str + (L.Path.SVG ? 'z' : 'x');
+ }
+}); \ No newline at end of file
diff --git a/extlib/leaflet/src/layer/vector/Polyline.js b/extlib/leaflet/src/layer/vector/Polyline.js
new file mode 100644
index 00000000..606d7d71
--- /dev/null
+++ b/extlib/leaflet/src/layer/vector/Polyline.js
@@ -0,0 +1,112 @@
+
+L.Polyline = L.Path.extend({
+ initialize: function(latlngs, options) {
+ L.Path.prototype.initialize.call(this, options);
+ this._latlngs = latlngs;
+ },
+
+ options: {
+ // how much to simplify the polyline on each zoom level
+ // more = better performance and smoother look, less = more accurate
+ smoothFactor: 1.0,
+ noClip: false,
+
+ updateOnMoveEnd: true
+ },
+
+ projectLatlngs: function() {
+ this._originalPoints = [];
+
+ for (var i = 0, len = this._latlngs.length; i < len; i++) {
+ this._originalPoints[i] = this._map.latLngToLayerPoint(this._latlngs[i]);
+ }
+ },
+
+ getPathString: function() {
+ for (var i = 0, len = this._parts.length, str = ''; i < len; i++) {
+ str += this._getPathPartStr(this._parts[i]);
+ }
+ return str;
+ },
+
+ getLatLngs: function() {
+ return this._latlngs;
+ },
+
+ setLatLngs: function(latlngs) {
+ this._latlngs = latlngs;
+ this._redraw();
+ return this;
+ },
+
+ addLatLng: function(latlng) {
+ this._latlngs.push(latlng);
+ this._redraw();
+ return this;
+ },
+
+ spliceLatLngs: function(index, howMany) {
+ var removed = [].splice.apply(this._latlngs, arguments);
+ this._redraw();
+ return removed;
+ },
+
+ _getPathPartStr: function(points) {
+ var round = L.Path.VML;
+
+ for (var j = 0, len2 = points.length, str = '', p; j < len2; j++) {
+ p = points[j];
+ if (round) p._round();
+ str += (j ? 'L' : 'M') + p.x + ' ' + p.y;
+ }
+ return str;
+ },
+
+ _clipPoints: function() {
+ var points = this._originalPoints,
+ len = points.length,
+ i, k, segment;
+
+ if (this.options.noClip) {
+ this._parts = [points];
+ return;
+ }
+
+ this._parts = [];
+
+ var parts = this._parts,
+ vp = this._map._pathViewport,
+ lu = L.LineUtil;
+
+ for (i = 0, k = 0; i < len - 1; i++) {
+ segment = lu.clipSegment(points[i], points[i+1], vp, i);
+ if (!segment) continue;
+
+ parts[k] = parts[k] || [];
+ parts[k].push(segment[0]);
+
+ // if segment goes out of screen, or it's the last one, it's the end of the line part
+ if ((segment[1] != points[i+1]) || (i == len - 2)) {
+ parts[k].push(segment[1]);
+ k++;
+ }
+ }
+ },
+
+ // simplify each clipped part of the polyline
+ _simplifyPoints: function() {
+ var parts = this._parts,
+ lu = L.LineUtil;
+
+ for (var i = 0, len = parts.length; i < len; i++) {
+ parts[i] = lu.simplify(parts[i], this.options.smoothFactor);
+ }
+ },
+
+ _updatePath: function() {
+ this._clipPoints();
+ this._simplifyPoints();
+
+ L.Path.prototype._updatePath.call(this);
+ }
+}); \ No newline at end of file