From c5ba5b0456a711d157e317f220e9c739226e7f50 Mon Sep 17 00:00:00 2001 From: Joar Wandborg Date: Tue, 10 Jan 2012 01:54:37 +0100 Subject: Installed leaflet in extlib --- extlib/leaflet/src/layer/vector/Circle.js | 51 ++++++ extlib/leaflet/src/layer/vector/CircleMarker.js | 25 +++ extlib/leaflet/src/layer/vector/MultiPoly.js | 27 ++++ extlib/leaflet/src/layer/vector/Path.Popup.js | 24 +++ extlib/leaflet/src/layer/vector/Path.VML.js | 91 +++++++++++ extlib/leaflet/src/layer/vector/Path.js | 207 ++++++++++++++++++++++++ extlib/leaflet/src/layer/vector/Polygon.js | 58 +++++++ extlib/leaflet/src/layer/vector/Polyline.js | 112 +++++++++++++ 8 files changed, 595 insertions(+) create mode 100644 extlib/leaflet/src/layer/vector/Circle.js create mode 100644 extlib/leaflet/src/layer/vector/CircleMarker.js create mode 100644 extlib/leaflet/src/layer/vector/MultiPoly.js create mode 100644 extlib/leaflet/src/layer/vector/Path.Popup.js create mode 100644 extlib/leaflet/src/layer/vector/Path.VML.js create mode 100644 extlib/leaflet/src/layer/vector/Path.js create mode 100644 extlib/leaflet/src/layer/vector/Polygon.js create mode 100644 extlib/leaflet/src/layer/vector/Polyline.js (limited to 'extlib/leaflet/src/layer/vector') 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 = ''; + 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(''); + }; + } 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 -- cgit v1.2.3