From 674b92003c9cf639a2ad7bd6f48d1ea9231fe5d9 Mon Sep 17 00:00:00 2001 From: FrozenCow Date: Sat, 16 Jul 2011 23:53:15 +0200 Subject: [PATCH] Added (proper) initial Leaflet support. --- web/css/dynmap_style.css | 16 +- web/images/layers.png | Bin 0 -> 3945 bytes web/images/marker-shadow.png | Bin 0 -> 1649 bytes web/images/marker.png | Bin 0 -> 2519 bytes web/images/popup-close.png | Bin 0 -> 1125 bytes web/images/zoom-in.png | Bin 0 -> 963 bytes web/images/zoom-out.png | Bin 0 -> 959 bytes web/index.html | 13 +- web/js/custommarker.js | 187 +++++++++++--------- web/js/dynmaputils.js | 181 ++++++++++++++++++++ web/js/flatmap.js | 50 ++++-- web/js/map.js | 136 +++++++++------ web/js/playermarkers.js | 27 +-- web/js/projectiontest.js | 31 ++++ web/leaflet.css | 321 +++++++++++++++++++++++++++++++++++ web/leaflet.ie.css | 48 ++++++ web/leaflet.js | 118 +++++++++++++ 17 files changed, 950 insertions(+), 178 deletions(-) create mode 100644 web/images/layers.png create mode 100644 web/images/marker-shadow.png create mode 100644 web/images/marker.png create mode 100644 web/images/popup-close.png create mode 100644 web/images/zoom-in.png create mode 100644 web/images/zoom-out.png create mode 100644 web/js/dynmaputils.js create mode 100644 web/js/projectiontest.js create mode 100644 web/leaflet.css create mode 100644 web/leaflet.ie.css create mode 100644 web/leaflet.js diff --git a/web/css/dynmap_style.css b/web/css/dynmap_style.css index fe5be88f..b9d4785b 100644 --- a/web/css/dynmap_style.css +++ b/web/css/dynmap_style.css @@ -1,3 +1,10 @@ +/* DEBUGGING */ +.leaflet-tile { + margin: -1; + border: 1px solid red; +} + + /******************* * Page setup */ @@ -39,13 +46,6 @@ margin-left:-20px } -/* Google branding */ - -.dynmap > div.map > DIV > DIV:first-child + DIV, -.dynmap > div.map > DIV > DIV:first-child + DIV + DIV { - visibility: hidden !important; -} - /******************* * Alerts are pretty. @@ -705,4 +705,4 @@ } .infowindow { color:black; -} \ No newline at end of file +} diff --git a/web/images/layers.png b/web/images/layers.png new file mode 100644 index 0000000000000000000000000000000000000000..9be965fc80847f26f93ab6390e9228077a7f1aa6 GIT binary patch literal 3945 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 literal 0 HcmV?d00001 diff --git a/web/images/popup-close.png b/web/images/popup-close.png new file mode 100644 index 0000000000000000000000000000000000000000..c8faec5ea909075fd573e032a67f867e66b0eea7 GIT binary patch literal 1125 zcmaJ=U1$?o6rLt(YiKdcqR^`BW&B}LlbK1Hgp7%uB$L`er<63sh@ehpZricW+;QgC zOuH_d3gSPgpuSYm-G{BPhzPPQtGl8_5EMlar2agJZ-NRUiZAs}ZK4mxd6;|d<@>(# zopaAU*xR$Q#n>KMTC}YD)T%|iUfP}*n0Ucr)IQmY*=A9%xtILzvJ!WVy3&F!l`m?E` z)C)4mf*=xP0}2~uL6i$};r3W8whn|?j%C;o!-WD|j1Px+mIZSkO|n_)0G}5-=W>x< zk{-g?oXbWd(O5JbuX07CjOft7Rjyj&rrEk&cMx=wWEP>N?S^Wn zg>*1mFt643BG%QL*vJk)eL}?$4X# zK|Ichse&_IO8oM%eXZA<3HaA~cl~$#;O(X0uKDUts}1@WOuem?wzQ7>mX1%ffdS8R zNtkG!x-4Av9q6xoX!W1IL@iu3N&DY;pPv-g`TFO1^1@#Y`64wnAuMY?X_kb_HsOh9 z>dcXunVH6a_AlCTqVdG1}u0u|Jx8&bb>M_o>Ex haIv46e`t9_6HEPiDxppP-SyOc__=J4crm?w?fToD8KiK*P3E+rbu&-aPsj zc=Ebe6OGZUe}O-uN6*HX7;iXbf%PCZY2SO3@B7}5d41Y!+}qo|xeEZ;tDhJxZm*~B z&Nlykc<@W$W}lf|)}{j%+aUpEO#1}ZJ$p!6#KzM{?@0-OZRmEotZSWW4)sJk#fXU) za5ey?<0P=1F=4PzhOVy*-(SBKpo?|ktY9H4sFIO;G7Cw2*6291u~Wpt@m*L-G%nx~ zX2Zlg_aiOQg@vxh{q$H8-~z(Nx^P)k*J{El4GAoWDC-~vK}8nj{E@1vw_y&+NJ2SD z&Shm)%jYzN;PMf8wh#}rmQh>g;*lisM*}^CAt0l3XknQ;l3M%MsaV>N7jZ z`q9Bk!61k4^u_EPbW+lc%_#uc)?oMkCtQN1CtUvkYo|1Ev~0&A=y-9rCKwJE3QGEiAQ|4;^Hgr zosHad5xjtBHc03`Cb$+-4=x(k+|9KVHtH?8cylevMy|w*kzY?be0NfJy|g@7 zuRZbku7`Z7zr6c-gZ~hj=4r>|c0QlK`1JfM_pY&4qdf=TUZVRv+OHesPV%|m!x;B^ h;MvFS@2!V#z*YuiF2JonxqT_OXvHc_ulvJ`@VbDZr$16ySWDd*l(VgHk)_z zajn4qAMgF**mQ%|yR<|4bm}G;RDIIJuo=1oY-87-J$R3g04Tt~>C&!ss(B>j-5kSb zVa(V7935w|>y0plJv;~^o%{Lr9R~wn=g!I&vSI@dgOhoJJM)&~%}1Wk^({SCUycGsI`)ycl}&YxV_ f86W-zukSws1+e=GC?7;Gf1;pSZ<()Z=a2sY#=<8c literal 0 HcmV?d00001 diff --git a/web/index.html b/web/index.html index a2d246f7..acafd42f 100644 --- a/web/index.html +++ b/web/index.html @@ -14,19 +14,24 @@ + + + + + + + + - - - - + diff --git a/web/js/custommarker.js b/web/js/custommarker.js index 81c6b4aa..e40c4640 100644 --- a/web/js/custommarker.js +++ b/web/js/custommarker.js @@ -1,90 +1,111 @@ -function CustomMarker(latlng, map, oncreated) { - google.maps.OverlayView.call(this); - - this.latlng_ = latlng; - - // Once the LatLng and text are set, add the overlay to the map. This will - // trigger a call to panes_changed which should in turn call draw. - this.setMap(map); - - this.oncreated = oncreated; -} +L.CustomMarker = L.Class.extend({ -CustomMarker.prototype = new google.maps.OverlayView(); - -CustomMarker.prototype.draw = function() { - var me = this; - if (this.removed) - return; - // Check if the div has been created. - var div = this.div_; - if (!div) { - // Create a overlay text DIV - div = this.div_ = document.createElement('DIV'); - // Create the DIV representing our CustomMarker - div.style.position = "absolute"; + includes: L.Mixin.Events, + + options: { + contentCreator: undefined, + shadowCreator: undefined, + clickable: true, + draggable: false + }, + + initialize: function(latlng, options) { + L.Util.setOptions(this, options); + this._latlng = latlng; + }, + + onAdd: function(map) { + this._map = map; - google.maps.event.addDomListener(div, "click", function(event) { - google.maps.event.trigger(me, "click"); - }); + if (!this._element && this.options.elementCreator) { + this._element = this.options.elementCreator(); + + + // TODO: Pass this fix to Leaflet-dev(s), it may be a bug in Leaflet. + this._element.style.position = 'absolute'; + + + this._initInteraction(); + } + if (!this._shadow && this.options.shadowCreator) { + this._shadow = this.options.shadowCreator(); + } - this.oncreated(div); + if (this._element) { + map._panes.markerPane.appendChild(this._element); + } + if (this._shadow) { + map._panes.shadowPane.appendChild(this._shadow); + } - // Then add the overlay to the DOM - var panes = this.getPanes(); - panes.overlayLayer.appendChild(div); - } + map.on('viewreset', this._reset, this); + this._reset(); + }, - // Position the overlay - var point = this.getProjection().fromLatLngToDivPixel(this.latlng_); - if (point) { - div.style.left = point.x + 'px'; - div.style.top = point.y + 'px'; - } -}; + onRemove: function(map) { + if (this._element) { + map._panes.markerPane.removeChild(this._element); + } + if (this._shadow) { + map._panes.shadowPane.removeChild(this._elementShadow); + } + + map.off('viewreset', this._reset, this); + }, + + getLatLng: function() { + return this._latlng; + }, + + setLatLng: function(latlng) { + this._latlng = latlng; + this._reset(); + }, + + _reset: function() { + var pos = this._map.latLngToLayerPoint(this._latlng); + + if (this._element) { + L.DomUtil.setPosition(this._element, pos); + } + if (this._shadow) { + L.DomUtil.setPosition(this._shadow, pos); + } + + if (this._element) { + this._element.style.zIndex = pos.y; + } + }, + + _initInteraction: function() { + if (this._element && this.options.clickable) { + this._element.className += ' leaflet-clickable'; + + L.DomEvent.addListener(this._element, 'click', this._onMouseClick, this); -CustomMarker.prototype.setPosition = function(p) { - this.latlng_ = p; - var projection = this.getProjection(); - if (projection) { - var point = projection.fromLatLngToDivPixel(this.latlng_); - this.div_.style.left = point.x + 'px'; - this.div_.style.top = point.y + 'px'; + var events = ['dblclick', 'mousedown', 'mouseover', 'mouseout']; + for (var i = 0; i < events.length; i++) { + L.DomEvent.addListener(this._element, events[i], this._fireMouseEvent, this); + } + } + + if (this._element && L.Handler.MarkerDrag) { + this.dragging = new L.Handler.MarkerDrag(this); + + if (this.options.draggable) { + this.dragging.enable(); + } + } + }, + + _onMouseClick: function(e) { + L.DomEvent.stopPropagation(e); + if (this.dragging && this.dragging.moved()) { return; } + this.fire(e.type); + }, + + _fireMouseEvent: function(e) { + this.fire(e.type); + L.DomEvent.stopPropagation(e); } -}; - -CustomMarker.prototype.getPosition = function(p) { - return this.latlng_; -}; - -CustomMarker.prototype.hide = function() { - if (this.div_ && !this.isHidden) { - this.div_.style.display = 'none'; - this.isHidden = true; - } -} - -CustomMarker.prototype.show = function() { - if (this.div_ && this.isHidden) { - this.div_.style.display = 'block'; - this.isHidden = false; - } -} - -CustomMarker.prototype.toggle = function(t) { - if ((typeof t) == "boolean") { - if (t) { this.show(); } - else { this.hide(); } - } else { - this.toggle((this.isHidden) == true); - } -} - -CustomMarker.prototype.remove = function() { - // Check if the overlay was on the map and needs to be removed. - if (this.div_) { - this.div_.parentNode.removeChild(this.div_); - this.div_ = null; - this.removed = true; - } -}; +}); \ No newline at end of file diff --git a/web/js/dynmaputils.js b/web/js/dynmaputils.js new file mode 100644 index 00000000..f97f0964 --- /dev/null +++ b/web/js/dynmaputils.js @@ -0,0 +1,181 @@ +var DynmapProjection = L.Class.extend({ + fromLocationToLatLng: function(location) { + throw "fromLocationToLatLng not implemented"; + } +}); + +var DynmapTileLayer = L.TileLayer.extend({ + _currentzoom: undefined, + getProjection: function() { + return this.projection; + }, + onTileUpdated: function(tile, tileName) { + var src = this.dynmap.getTileUrl(tileName); + tile.attr('src', src); + tile.show(); + }, + + getTileName: function(tilePoint, zoom) { + throw "getTileName not implemented"; + }, + + getTileUrl: function(tilePoint, zoom) { + var tileName = this.getTileName(tilePoint, zoom); + var url = this._cachedTileUrls[tileName]; + if (!url) { + this._cachedTileUrls[tileName] = url = this.options.dynmap.getTileUrl(tileName) + '?' + new Date().getUTCMilliseconds(); + } + return url; + }, + + updateNamedTile: function(name) { + var tile = this._namedTiles[name]; + delete this._cachedTileUrls[name]; + if (tile) { + this.updateTile(tile); + } + }, + + updateTile: function(tile) { + this._loadTile(tile, tile.tilePoint, this._map.getZoom()); + }, + + // We should override this, since Leaflet does modulo on tilePoint by default. (https://github.com/CloudMade/Leaflet/blob/master/src/layer/tile/TileLayer.js#L151) + _addTile: function(tilePoint) { + var tilePos = this._getTilePos(tilePoint), + zoom = this._map.getZoom(), + key = tilePoint.x + ':' + tilePoint.y, + name = this.getTileName(tilePoint, zoom); + + // create tile + var tile = this._createTile(); + tile.tileName = name; + tile.tilePoint = tilePoint; + L.DomUtil.setPosition(tile, tilePos); + + this._tiles[key] = tile; + this._namedTiles[name] = tile; + + this._loadTile(tile, tilePoint, zoom); + + this._container.appendChild(tile); + }, + + _removeOtherTiles: function(bounds) { + var kArr, x, y, key; + + for (key in this._tiles) { + if (this._tiles.hasOwnProperty(key)) { + kArr = key.split(':'); + x = parseInt(kArr[0], 10); + y = parseInt(kArr[1], 10); + + // remove tile if it's out of bounds + if (x < bounds.min.x || x > bounds.max.x || y < bounds.min.y || y > bounds.max.y) { + var tile = this._tiles[key]; + if (tile.parentNode === this._container) { + this._container.removeChild(this._tiles[key]); + } + delete this._namedTiles[tile.tileName]; + delete this._tiles[key]; + } + } + } + }, + _updateTileSize: function() { + var newzoom = this._map.getZoom(); + if (this._currentzoom !== newzoom) { + var newTileSize = this.calculateTileSize(newzoom); + this._currentzoom = newzoom; + if (newTileSize !== this.options.tileSize) { + this.setTileSize(newTileSize); + } + } + }, + + _reset: function() { + this._updateTileSize(); + this._tiles = {}; + this._namedTiles = {}; + this._cachedTileUrls = {}; + this._initContainer(); + this._container.innerHTML = ''; + }, + + _update: function() { + this._updateTileSize(); + var bounds = this._map.getPixelBounds(), + tileSize = this.options.tileSize; + + var nwTilePoint = new L.Point( + Math.floor(bounds.min.x / tileSize), + Math.floor(bounds.min.y / tileSize)), + seTilePoint = new L.Point( + Math.floor(bounds.max.x / tileSize), + Math.floor(bounds.max.y / tileSize)), + tileBounds = new L.Bounds(nwTilePoint, seTilePoint); + + this._addTilesFromCenterOut(tileBounds); + + if (this.options.unloadInvisibleTiles) { + this._removeOtherTiles(tileBounds); + } + }, + calculateTileSize: function(zoom) { + return this.options.tileSize; + }, + setTileSize: function(tileSize) { + this.options.tileSize = tileSize; + this._tiles = {}; + this._container.innerHTML = ''; + this._createTileProto(); + }, + updateTileSize: function(zoom) {} +}); + +function loadjs(url, completed) { + var script = document.createElement('script'); + script.setAttribute('src', url); + script.setAttribute('type', 'text/javascript'); + var isloaded = false; + script.onload = function() { + if (isloaded) { return; } + isloaded = true; + completed(); + }; + + // Hack for IE, don't know whether this still applies to IE9. + script.onreadystatechange = function() { + script.onload(); + }; + (document.head || document.getElementsByTagName('head')[0]).appendChild(script); +} + +function splitArgs(s) { + var r = s.split(' '); + delete arguments[0]; + var obj = {}; + var index = 0; + $.each(arguments, function(argumentIndex, argument) { + if (!argumentIndex) { return; } + var value = r[argumentIndex-1]; + obj[argument] = value; + }); + return obj; +} + +function swtch(value, options, defaultOption) { + return (options[value] || defaultOption || function(){})(value); +} +(function( $ ){ + $.fn.scrollHeight = function(height) { + return this[0].scrollHeight; + }; +})($); + +function Location(world, x, y, z) { + this.world = world; + this.x = x; + this.y = y; + this.z = z; +} diff --git a/web/js/flatmap.js b/web/js/flatmap.js index 11cbf3b8..3235235b 100644 --- a/web/js/flatmap.js +++ b/web/js/flatmap.js @@ -1,23 +1,39 @@ -function FlatProjection() {} -FlatProjection.prototype = { - extrazoom: 0, - fromLatLngToPoint: function(latLng) { - return new google.maps.Point(latLng.lat()*config.tileWidth, latLng.lng()*config.tileHeight); - }, - fromPointToLatLng: function(point) { - return new google.maps.LatLng(point.x/config.tileWidth, point.y/config.tileHeight); - }, - fromWorldToLatLng: function(x, y, z) { - return new google.maps.LatLng(-z / config.tileWidth / (1 << this.extrazoom), x / config.tileHeight / (1 << this.extrazoom)); - } -}; +var FlatProjection = DynmapProjection.extend({ + fromLocationToLatLng: function(location) { + return new L.LatLng(-location.z, location.x, true); + } +}); +var FlatMapType = DynmapTileLayer.extend({ + projection: new FlatProjection({}), + options: { + minZoom: 0, + maxZoom: 4 + }, + initialize: function(options) { + L.Util.setOptions(this, options); + }, + getTileName: function(tilePoint, zoom) { + var tileName; + var dnprefix = ''; + if(this.options.nightandday && this.dynmap.serverday) { + dnprefix = '_day'; + } + tileName = this.options.prefix + dnprefix + '_128_' + tilePoint.x + '_' + tilePoint.y + '.png'; + return tileName; + }, + calculateTileSize: function(zoom) { + return Math.pow(2, 7+zoom); + } +}) + +/* function FlatMapType(configuration) { $.extend(this, configuration); } FlatMapType.prototype = $.extend(new DynMapType(), { constructor: FlatMapType, projection: new FlatProjection(), - tileSize: new google.maps.Size(128.0, 128.0), + tileSize: 128.0, minZoom: 0, maxZoom: 3, prefix: null, @@ -81,8 +97,8 @@ FlatMapType.prototype = $.extend(new DynMapType(), { else { size = Math.pow(2, 7+zoom-extrazoom); } - this.tileSize = new google.maps.Size(size, size); + this.tileSize = size; } }); - -maptypes.FlatMapType = function(configuration) { return new FlatMapType(configuration); }; \ No newline at end of file +*/ +maptypes.FlatMapType = function(options) { return new FlatMapType(options); }; \ No newline at end of file diff --git a/web/js/map.js b/web/js/map.js index fbc17716..39e821a3 100644 --- a/web/js/map.js +++ b/web/js/map.js @@ -158,17 +158,25 @@ DynMap.prototype = { if(urlzoom != null) me.options.defaultzoom = urlzoom; - var map = this.map = new google.maps.Map(mapContainer.get(0), { - zoom: me.options.defaultzoom || 0, - center: new google.maps.LatLng(0, 1), - navigationControl: true, - navigationControlOptions: { - style: google.maps.NavigationControlStyle.DEFAULT - }, - scaleControl: false, - mapTypeControl: false, - streetViewControl: false, - backgroundColor: '#000000' + var map = this.map = new L.Map(mapContainer.get(0), { + zoom: 1, //TODO: me.options.defaultzoom || 1, + center: new L.LatLng(0, 0), + zoomAnimation: true, + crs: L.Util.extend({}, L.CRS, { + code: 'simple', + projection: { + project: function(latlng) { + return new L.Point(latlng.lat, latlng.lng); + }, + unproject: function(point, unbounded) { + return new L.LatLng(point.x, point.y, true); + } + }, + transformation: new L.Transformation(1, 0, 1, 0) + }), + scale: function(zoom) { + return (1 << zoom); + } }); map.zoom_changed = function() { @@ -176,18 +184,9 @@ DynMap.prototype = { $(me).trigger('zoomchanged'); }; - google.maps.event.addListener(map, 'dragstart', function(mEvent) { + /*google.maps.event.addListener(map, 'dragstart', function(mEvent) { me.followPlayer(null); - }); - // TODO: Enable hash-links. - /* - google.maps.event.addListener(map, 'zoom_changed', function() { - me.updateLink(); - }); - google.maps.event.addListener(map, 'center_changed', function() { - me.updateLink(); - }); - */ + });*/ // Sidebar var panel; @@ -239,7 +238,7 @@ DynMap.prototype = { .appendTo(worldlist); $.each(world.maps, function(index, map) { - me.map.mapTypes.set(map.world.name + '.' + map.name, map); + //me.map.mapTypes.set(map.world.name + '.' + map.name, map); map.element = $('
  • ') .addClass('map') @@ -349,14 +348,17 @@ DynMap.prototype = { }); }); }, + getProjection: function() { return this.maptype.getProjection(); }, selectMap: function(map, completed) { if (!map) { throw "Cannot select map " + map; } + console.log('Selecting map...'); var me = this; if (me.maptype === map) { return; } $(me).trigger('mapchanging'); + var mapWorld = map.options.world; if (me.maptype) { $('.compass').removeClass('compass_' + me.maptype.compassview); $('.compass').removeClass('compass_' + me.maptype.name); @@ -364,31 +366,33 @@ DynMap.prototype = { $('.compass').addClass('compass_' + map.compassview); $('.compass').addClass('compass_' + map.name); var worldChanged = me.world !== map.world; - var projectionChanged = me.map.getProjection() !== map.projection; - me.map.setMapTypeId('none'); - me.world = map.world; + var projectionChanged = (me.maptype && me.maptype.getProjection()) !== (map && map.projection); + if (me.maptype) { + me.map.removeLayer(me.maptype); + } + me.world = mapWorld; me.maptype = map; - me.maptype.updateTileSize(me.map.zoom); - window.setTimeout(function() { - me.map.setMapTypeId(map.world.name + '.' + map.name); - if (worldChanged) { - $(me).trigger('worldchanged'); - } - if (projectionChanged || worldChanged) { - if (map.world.center) { - me.map.panTo(map.projection.fromWorldToLatLng(map.world.center.x||0,map.world.center.y||64,map.world.center.z||0)); - } else { - me.map.panTo(map.projection.fromWorldToLatLng(0,64,0)); - } - } - $(me).trigger('mapchanged'); - if (completed) { - completed(); - } - }, 1); + me.map.addLayer(me.maptype); + + if (worldChanged) { + $(me).trigger('worldchanged'); + } + if (projectionChanged || worldChanged) { + var centerLocation = $.extend({ x: 0, y: 64, z: 0 }, mapWorld.center); + var centerPoint = map.getProjection().fromLocationToLatLng(centerLocation); + me.map.setView(centerPoint, 0, true); + } + $(me).trigger('mapchanged'); + $('.map', me.worldlist).removeClass('selected'); $(map.element).addClass('selected'); me.updateBackground(); + + + if (completed) { + completed(); + } + console.log('Map selected.'); }, selectWorld: function(world, completed) { var me = this; @@ -399,12 +403,34 @@ DynMap.prototype = { } me.selectMap(world.defaultmap, completed); }, - panTo: function(location, completed) { + panToLocation: function(location, completed) { var me = this; - me.selectWorld(location.world, function() { - var position = me.map.getProjection().fromWorldToLatLng(location.x, location.y, location.z); - me.map.panTo(position); - }); + var pan = function() { + var latlng = me.maptype.getProjection().fromLocationToLatLng(location); + me.panToLatLng(latlng, completed); + }; + + if (location.world) { + me.selectWorld(location.world, function() { + pan(); + }); + } else { + pan(); + } + }, + panToLayerPoint: function(point, completed) { + var me = this; + var latlng = me.map.layerPointToLatLng(point); + me.map.panToLatLng(latlng); + if (completed) { + completed(); + } + }, + panToLatLng: function(latlng, completed) { + this.map.panTo(latlng); + if (completed) { + completed(); + } }, update: function() { var me = this; @@ -473,12 +499,13 @@ DynMap.prototype = { if(me.serverday != oldday) { me.updateBackground(); var mtid = me.map.mapTypeId; - if(me.map.mapTypes[mtid].nightandday) { + console.log('TODO: RENDER NIGHTANDDAY!!!') + /*if(me.map.mapTypes[mtid].nightandday) { me.map.setMapTypeId('none'); window.setTimeout(function() { me.map.setMapTypeId(mtid); }, 0.1); - } + }*/ } $(me).trigger('worldupdated', [ update ]); @@ -526,6 +553,7 @@ DynMap.prototype = { tile.lastseen = timestamp; tile.mapType.onTileUpdated(tile.tileElement, tileName); } + me.maptype.updateNamedTile(tileName); }, addPlayer: function(update) { var me = this; @@ -563,7 +591,7 @@ DynMap.prototype = { if (me.followingPlayer !== player) { me.followPlayer(null); } - me.panTo(player.location); + me.panToLocation(player.location); }) .appendTo(me.playerlist); if (me.options.showplayerfacesinmenu) { @@ -586,7 +614,7 @@ DynMap.prototype = { if (player === me.followingPlayer) { // Follow the updated player. - me.panTo(player.location); + me.panToLocation(player.location); } }, removePlayer: function(player) { @@ -605,7 +633,7 @@ DynMap.prototype = { if(player) { $(player.menuitem).addClass('following'); - me.panTo(player.location); + me.panToLocation(player.location); } this.followingPlayer = player; }, diff --git a/web/js/playermarkers.js b/web/js/playermarkers.js index d4432fc7..3459f018 100644 --- a/web/js/playermarkers.js +++ b/web/js/playermarkers.js @@ -2,11 +2,12 @@ componentconstructors['playermarkers'] = function(dynmap, configuration) { var me = this; $(dynmap).bind('playeradded', function(event, player) { // Create the player-marker. - var markerPosition = dynmap.map.getProjection().fromWorldToLatLng(player.location.x, player.location.y, player.location.z); - player.marker = new CustomMarker(markerPosition, dynmap.map, function(div) { + var markerPosition = dynmap.getProjection().fromLocationToLatLng(player.location); + player.marker = new L.CustomMarker(markerPosition, { elementCreator: function() { + var div = document.createElement('div'); var playerImage; - player.marker.toggle(dynmap.world === player.location.world); + $(player.marker._element).toggle(dynmap.world === player.location.world); $(div) .addClass('Marker') @@ -62,17 +63,19 @@ componentconstructors['playermarkers'] = function(dynmap, configuration) { player.healthContainer.css('display','none'); } } - }); + return div; + }}); + dynmap.map.addLayer(player.marker); }); $(dynmap).bind('playerremoved', function(event, player) { // Remove the marker. - player.marker.remove(); + dynmap.map.removeLayer(player.marker); }); $(dynmap).bind('playerupdated', function(event, player) { // Update the marker. - var markerPosition = dynmap.map.getProjection().fromWorldToLatLng(player.location.x, player.location.y, player.location.z); - player.marker.toggle(dynmap.world === player.location.world); - player.marker.setPosition(markerPosition); + var markerPosition = dynmap.getProjection().fromLocationToLatLng(player.location); + $(player.marker._element).toggle(dynmap.world === player.location.world); + player.marker.setLatLng(markerPosition); // Update health if (configuration.showplayerhealth) { if (player.health !== undefined && player.armor !== undefined) { @@ -90,7 +93,7 @@ componentconstructors['playermarkers'] = function(dynmap, configuration) { for(name in dynmap.players) { var player = dynmap.players[name]; // Turn off marker - let update turn it back on - player.marker.hide(); + $(player.marker._element).toggle(false); } }); // Remove marker on map change - let update place it again @@ -98,9 +101,9 @@ componentconstructors['playermarkers'] = function(dynmap, configuration) { var name; for(name in dynmap.players) { var player = dynmap.players[name]; - var markerPosition = dynmap.map.getProjection().fromWorldToLatLng(player.location.x, player.location.y, player.location.z); - player.marker.setPosition(markerPosition); - player.marker.toggle(dynmap.world === player.location.world); + var markerPosition = dynmap.getProjection().fromLocationToLatLng(player.location); + player.marker.setLatLng(markerPosition); + $(player.marker._element).toggle(dynmap.world === player.location.world); } }); }; diff --git a/web/js/projectiontest.js b/web/js/projectiontest.js new file mode 100644 index 00000000..6b6dad16 --- /dev/null +++ b/web/js/projectiontest.js @@ -0,0 +1,31 @@ +componentconstructors['projectiontest'] = function(dynmap, configuration) { + var me = this; + var marker = new L.CustomMarker(new L.LatLng(0,0,true), { + elementCreator: function() { + var div = document.createElement('div'); + var textContainer; + $(div) + .css({margin: '10px 10px 10px 10px'}) + .append( + textContainer = $('') + .css({'white-space': 'pre'}) + .text('') + ); + marker.setText = function(text) { + $(textContainer).text(text); + }; + return div; + } + }); + dynmap.map.addLayer(marker); + + dynmap.map.on('mousemove', function(event) { + marker.setLatLng(event.latlng); + if (marker.setText) { + marker.setText('LatLng: (' + event.latlng.lat + ',' + event.latlng.lng + ')\n'+ + 'LayerPoint: (' + event.layerPoint.x + ',' + event.layerPoint.y + ')\n'+ + 'World: (?,?,?)' + ); + } + }); +}; \ No newline at end of file diff --git a/web/leaflet.css b/web/leaflet.css new file mode 100644 index 00000000..4cb788c7 --- /dev/null +++ b/web/leaflet.css @@ -0,0 +1,321 @@ +/* required styles */ + +.leaflet-map-pane, +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow, +.leaflet-tile-pane, +.leaflet-overlay-pane, +.leaflet-shadow-pane, +.leaflet-marker-pane, +.leaflet-popup-pane, +.leaflet-overlay-pane svg, +.leaflet-zoom-box, +.leaflet-image-layer { /* TODO optimize classes */ + position: absolute; + } +.leaflet-container { + overflow: hidden; + } +.leaflet-tile-pane { + -webkit-transform: translate3d(0,0,0); + } +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow { + -moz-user-select: none; + -webkit-user-select: none; + user-select: none; + } +.leaflet-marker-icon, +.leaflet-marker-shadow { + display: block; + } +.leaflet-clickable { + cursor: pointer; + } +.leaflet-container img { + max-width: auto; + } + +.leaflet-tile-pane { z-index: 2; } +.leaflet-overlay-pane { z-index: 3; } +.leaflet-shadow-pane { z-index: 4; } +.leaflet-marker-pane { z-index: 5; } +.leaflet-popup-pane { z-index: 6; } + +.leaflet-zoom-box { + width: 0; + height: 0; + } + +.leaflet-tile { + visibility: hidden; + } +.leaflet-tile-loaded { + visibility: inherit; + } + +a.leaflet-active { + outline: 2px solid orange; + } + + +/* Leaflet controls */ + +.leaflet-control { + position: relative; + z-index: 7; + } +.leaflet-top, +.leaflet-bottom { + position: absolute; + } +.leaflet-top { + top: 0; + } +.leaflet-right { + right: 0; + } +.leaflet-bottom { + bottom: 0; + } +.leaflet-left { + left: 0; + } +.leaflet-control { + float: left; + clear: both; + } +.leaflet-right .leaflet-control { + float: right; + } +.leaflet-top .leaflet-control { + margin-top: 10px; + } +.leaflet-bottom .leaflet-control { + margin-bottom: 10px; + } +.leaflet-left .leaflet-control { + margin-left: 10px; + } +.leaflet-right .leaflet-control { + margin-right: 10px; + } + +.leaflet-control-zoom, .leaflet-control-layers { + -moz-border-radius: 7px; + -webkit-border-radius: 7px; + border-radius: 7px; + } +.leaflet-control-zoom { + padding: 5px; + background: rgba(0, 0, 0, 0.25); + } +.leaflet-control-zoom a { + background-color: rgba(255, 255, 255, 0.75); + } +.leaflet-control-zoom a, .leaflet-control-layers a { + background-position: 50% 50%; + background-repeat: no-repeat; + display: block; + } +.leaflet-control-zoom a { + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + width: 19px; + height: 19px; + } +.leaflet-control-zoom a:hover { + background-color: #fff; + } +.leaflet-big-buttons .leaflet-control-zoom a { + width: 27px; + height: 27px; + } +.leaflet-control-zoom-in { + background-image: url(images/zoom-in.png); + margin-bottom: 5px; + } +.leaflet-control-zoom-out { + background-image: url(images/zoom-out.png); + } + +.leaflet-control-layers { + -moz-box-shadow: 0 0 7px #999; + -webkit-box-shadow: 0 0 7px #999; + box-shadow: 0 0 7px #999; + + background: #f8f8f9; + } +.leaflet-control-layers a { + background-image: url(images/layers.png); + width: 36px; + height: 36px; + } +.leaflet-big-buttons .leaflet-control-layers a { + width: 44px; + height: 44px; + } +.leaflet-control-layers .leaflet-control-layers-list, +.leaflet-control-layers-expanded .leaflet-control-layers-toggle { + display: none; + } +.leaflet-control-layers-expanded .leaflet-control-layers-list { + display: block; + position: relative; + } +.leaflet-control-layers-expanded { + padding: 6px 10px 6px 6px; + font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; + color: #333; + background: #fff; + } +.leaflet-control-layers input { + margin-top: 2px; + position: relative; + top: 1px; + } +.leaflet-control-layers label { + display: block; + } +.leaflet-control-layers-separator { + height: 0; + border-top: 1px solid #ddd; + margin: 5px -10px 5px -6px; + } + +.leaflet-container .leaflet-control-attribution { + margin: 0; + padding: 0 5px; + + font: 11px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; + color: #333; + + background-color: rgba(255, 255, 255, 0.7); + + -moz-box-shadow: 0 0 7px #ccc; + -webkit-box-shadow: 0 0 7px #ccc; + box-shadow: 0 0 7px #ccc; + } + + +/* Fade animations */ + +.leaflet-fade-anim .leaflet-tile { + opacity: 0; + + -webkit-transition: opacity 0.2s linear; + -moz-transition: opacity 0.2s linear; + -o-transition: opacity 0.2s linear; + transition: opacity 0.2s linear; + } +.leaflet-fade-anim .leaflet-tile-loaded { + opacity: 1; + } + +.leaflet-fade-anim .leaflet-popup { + opacity: 0; + + -webkit-transition: opacity 0.2s linear; + -moz-transition: opacity 0.2s linear; + -o-transition: opacity 0.2s linear; + transition: opacity 0.2s linear; + } +.leaflet-fade-anim .leaflet-map-pane .leaflet-popup { + opacity: 1; + } + +.leaflet-zoom-anim .leaflet-tile { + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; + } + +.leaflet-zoom-anim .leaflet-objects-pane { + visibility: hidden; + } + + +/* Popup layout */ + +.leaflet-popup { + position: absolute; + text-align: center; + -webkit-transform: translate3d(0,0,0); + } +.leaflet-popup-content-wrapper { + padding: 1px; + text-align: left; + } +.leaflet-popup-content { + margin: 19px; + } +.leaflet-popup-tip-container { + margin: 0 auto; + width: 40px; + height: 16px; + position: relative; + overflow: hidden; + } +.leaflet-popup-tip { + width: 15px; + height: 15px; + padding: 1px; + + margin: -8px auto 0; + + -moz-transform: rotate(45deg); + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + } +.leaflet-popup-close-button { + position: absolute; + top: 9px; + right: 9px; + + width: 10px; + height: 10px; + + overflow: hidden; + } +.leaflet-popup-content p { + margin: 18px 0; + } + + +/* Visual appearance */ + +.leaflet-container { + background: #ddd; + } +.leaflet-container a { + color: #0078A8; + } +.leaflet-zoom-box { + border: 2px dotted #05f; + background: white; + opacity: 0.5; + } +.leaflet-popup-content-wrapper, .leaflet-popup-tip { + background: white; + + box-shadow: 0 1px 10px #888; + -moz-box-shadow: 0 1px 10px #888; + -webkit-box-shadow: 0 1px 14px #999; + } +.leaflet-popup-content-wrapper { + -moz-border-radius: 20px; + -webkit-border-radius: 20px; + border-radius: 20px; + } +.leaflet-popup-content { + font: 12px/1.4 "Helvetica Neue", Arial, Helvetica, sans-serif; + } +.leaflet-popup-close-button { + background: white url(images/popup-close.png); + } \ No newline at end of file diff --git a/web/leaflet.ie.css b/web/leaflet.ie.css new file mode 100644 index 00000000..a120c0cb --- /dev/null +++ b/web/leaflet.ie.css @@ -0,0 +1,48 @@ +.leaflet-tile { + filter: inherit; + } + +.leaflet-vml-shape { + width: 1px; + height: 1px; + } +.lvml { + behavior: url(#default#VML); + display: inline-block; + position: absolute; + } + +.leaflet-control { + display: inline; + } + +.leaflet-popup-tip { + width: 21px; + _width: 27px; + margin: 0 auto; + _margin-top: -3px; + + filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); + -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; + } +.leaflet-popup-tip-container { + margin-top: -1px; + } +.leaflet-popup-content-wrapper, .leaflet-popup-tip { + border: 1px solid #bbb; + } + +.leaflet-control-zoom { + filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#3F000000',EndColorStr='#3F000000'); + } +.leaflet-control-zoom a { + background-color: #eee; + } +.leaflet-control-zoom a:hover { + background-color: #fff; + } +.leaflet-control-layers-toggle { + } +.leaflet-control-attribution, .leaflet-control-layers { + background: white; + } \ No newline at end of file diff --git a/web/leaflet.js b/web/leaflet.js new file mode 100644 index 00000000..4ca74d8c --- /dev/null +++ b/web/leaflet.js @@ -0,0 +1,118 @@ +/* + Copyright (c) 2010-2011, CloudMade, Vladimir Agafonkin + Leaflet is a BSD-licensed JavaScript library for map display and interaction. + See http://cloudmade.github.com/Leaflet/ for more information. +*/ +(function(a){var b={VERSION:"0.2",ROOT_URL:function(){for(var a=document.getElementsByTagName("script"),b=/^(.*\/)leaflet-?([\w-]*)\.js.*$/,e=0,f=a.length;e0},removeEventListener:function(a,b,c){if(!this.hasEventListeners(a))return this;for(var d=0,e=this._leaflet_events,f=e[a].length;d=this.min.x&&a.x<=this.max.x&&b.y>=this.min.y&&a.y<=this.max.y}});L.Transformation=L.Class.extend({initialize:function(a,b,c,d){this._a=a;this._b=b;this._c=c;this._d=d},transform:function(a,b){return this._transform(a.clone(),b)},_transform:function(a,b){b=b||1;a.x=b*(this._a*a.x+this._b);a.y=b*(this._c*a.y+this._d);return a},untransform:function(a,b){b=b||1;return new L.Point((a.x/b-this._b)/this._a,(a.y/b-this._d)/this._c)}});L.LineUtil={simplify:function(a,b){if(!b)return a.slice();a=this.reducePoints(a,b);return a=this.simplifyDP(a,b)},pointToSegmentDistance:function(a,b,c){return Math.sqrt(this._sqPointToSegmentDist(a,b,c))},simplifyDP:function(a,b){for(var c=0,d=0,e=b*b,f=1,g=a.length,h;fc&&(d=f,c=h);return c>=e?(c=a.slice(0,d),d=a.slice(d),g=this.simplifyDP(c,b).slice(0,g-2),d=this.simplifyDP(d,b),g.concat(d)):[a[0],a[g-1]]},reducePoints:function(a,b){for(var c= +[a[0]],d=b*b,e=1,f=0,g=a.length;eb.max.x&&(c|=2);a.yb.max.y&&(c|=8);return c},_sqDist:function(a,b){var c=b.x-a.x,d=b.y-a.y;return c*c+d*d},_sqPointToSegmentDist:function(a,b,c){var d=c.x-b.x,e=c.y-b.y;if(!d&&!e)return this._sqDist(a,b);var f=((a.x-b.x)*d+(a.y-b.y)*e)/this._sqDist(b,c);if(f< +0)return this._sqDist(a,b);if(f>1)return this._sqDist(a,c);b=new L.Point(b.x+d*f,b.y+e*f);return this._sqDist(a,b)}};L.PolyUtil={};L.PolyUtil.clipPolygon=function(a,b){var c,d=[1,4,2,8],e,f,g,h,j,k,l=L.LineUtil;e=0;for(j=a.length;e0&&c<=h;f=b}}function e(){if(g)j.type="dblclick",b(j),f=null}var f,g=!1,h=250,j;a["_leaflet_touchstart"+c]=d;a["_leaflet_touchend"+c]=e;a.addEventListener("touchstart",d,!1);a.addEventListener("touchend",e,!1)},removeDoubleTapListener:function(a,b){a.removeEventListener(a,a["_leaflet_touchstart"+b],!1);a.removeEventListener(a,a["_leaflet_touchend"+b], +!1)}});L.DomUtil={get:function(a){return typeof a=="string"?document.getElementById(a):a},getStyle:function(a,b){var c=a.style[b];!c&&a.currentStyle&&(c=a.currentStyle[b]);if(!c||c=="auto")c=(c=document.defaultView.getComputedStyle(a,null))?c[b]:null;return c=="auto"?null:c},getCumulativeOffset:function(a){var b=0,c=0;do b+=a.offsetTop||0,c+=a.offsetLeft||0,a=a.offsetParent;while(a);return new L.Point(c,b)},create:function(a,b,c){a=document.createElement(a);a.className=b;c&&c.appendChild(a);return a},disableTextSelection:function(){document.selection&& +document.selection.empty&&document.selection.empty();if(!this._onselectstart)this._onselectstart=document.onselectstart,document.onselectstart=L.Util.falseFn},enableTextSelection:function(){document.onselectstart=this._onselectstart;this._onselectstart=null},CLASS_RE:/(\\s|^)'+cls+'(\\s|$)/,hasClass:function(a,b){return a.className.length>0&&RegExp("(^|\\s)"+b+"(\\s|$)").test(a.className)},addClass:function(a,b){L.DomUtil.hasClass(a,b)||(a.className+=(a.className?" ":"")+b)},setOpacity:function(a, +b){L.Browser.ie?a.style.filter="alpha(opacity="+Math.round(b*100)+")":a.style.opacity=b},testProp:function(a){for(var b=document.documentElement.style,c=0;c1)){var b=a.touches&&a.touches.length==1?a.touches[0]:a;L.DomEvent.preventDefault(a);L.Browser.touch&&(b.target.className+=" leaflet-active");this._moved=!1;L.DomUtil.disableTextSelection();this._setMovingCursor();this._startPos=this._newPos=L.DomUtil.getPosition(this._element);this._startPoint=new L.Point(b.clientX,b.clientY);L.DomEvent.addListener(document, +L.Draggable.MOVE,this._onMove,this);L.DomEvent.addListener(document,L.Draggable.END,this._onUp,this)}},_onMove:function(a){if(!(a.touches&&a.touches.length>1)){L.DomEvent.preventDefault(a);a=a.touches&&a.touches.length==1?a.touches[0]:a;if(!this._moved)this.fire("dragstart"),this._moved=!0;this._newPos=this._startPos.add(new L.Point(a.clientX,a.clientY)).subtract(this._startPoint);L.Util.requestAnimFrame(this._updatePosition,this,!0);this.fire("drag")}},_updatePosition:function(){L.DomUtil.setPosition(this._element, +this._newPos)},_onUp:function(a){if(a.changedTouches){var a=a.changedTouches[0],b=a.target,c=this._newPos&&this._newPos.distanceTo(this._startPos)||0;b.className=b.className.replace(" leaflet-active","");c=b.lat&&a.lat<=c.lat&&d.lng>=b.lng&&a.lng<=c.lng}});L.Projection={};L.Projection.SphericalMercator={MAX_LATITUDE:85.0511287798,project:function(a){var b=L.LatLng.DEG_TO_RAD,c=this.MAX_LATITUDE,d=a.lng*b,a=Math.max(Math.min(c,a.lat),-c)*b,a=Math.log(Math.tan(Math.PI/4+a/2));return new L.Point(d,a)},unproject:function(a,b){var c=L.LatLng.RAD_TO_DEG;return new L.LatLng((2*Math.atan(Math.exp(a.y))-Math.PI/2)*c,a.x*c,b)}};L.Projection.LonLat={project:function(a){return new L.Point(a.lng,a.lat)},unproject:function(a,b){return new L.LatLng(a.y,a.x,b)}};L.Projection.Mercator={MAX_LATITUDE:85.0840591556,R_MINOR:6356752.3142,R_MAJOR:6378137,project:function(a){var b=L.LatLng.DEG_TO_RAD,c=this.MAX_LATITUDE,d=this.R_MAJOR,e=a.lng*b*d,a=Math.max(Math.min(c,a.lat),-c)*b,b=this.R_MINOR/d,b=Math.sqrt(1-b*b),c=b*Math.sin(a),c=Math.pow((1-c)/(1+c),b*0.5),a=-d*Math.log(Math.tan(0.5*(Math.PI*0.5-a))/c);return new L.Point(e,a)},unproject:function(a,b){for(var c=L.LatLng.RAD_TO_DEG,d=this.R_MAJOR,e=a.x*c/d,f=this.R_MINOR/d,f=Math.sqrt(1-f*f),d=Math.exp(-a.y/d), +g=Math.PI/2-2*Math.atan(d),h=15,j=0.1;Math.abs(j)>1.0E-7&&--h>0;)j=f*Math.sin(g),j=Math.PI/2-2*Math.atan(d*Math.pow((1-j)/(1+j),0.5*f))-g,g+=j;return new L.LatLng(g*c,e,b)}};L.CRS={latLngToPoint:function(a,b){return this.transformation._transform(this.projection.project(a),b)},pointToLatLng:function(a,b,c){return this.projection.unproject(this.transformation.untransform(a,b),c)},project:function(a){return this.projection.project(a)}};L.CRS.EPSG3857=L.Util.extend({},L.CRS,{code:"EPSG:3857",projection:L.Projection.SphericalMercator,transformation:new L.Transformation(0.5/Math.PI,0.5,-0.5/Math.PI,0.5),project:function(a){return this.projection.project(a).multiplyBy(6378137)}});L.CRS.EPSG900913=L.Util.extend({},L.CRS.EPSG3857,{code:"EPSG:900913"});L.CRS.EPSG4326=L.Util.extend({},L.CRS,{code:"EPSG:4326",projection:L.Projection.LonLat,transformation:new L.Transformation(1/360,0.5,-1/360,0.5)});L.CRS.EPSG3395=L.Util.extend({},L.CRS,{code:"EPSG:3395",projection:L.Projection.Mercator,transformation:function(){var a=L.Projection.Mercator;return new L.Transformation(0.5/(Math.PI*a.R_MAJOR),0.5,-0.5/(Math.PI*a.R_MINOR),0.5)}()});L.LayerGroup=L.Class.extend({initialize:function(a){this._layers={};if(a)for(var b=0,c=a.length;ba.max.x||ba.max.y)){if(!L.Browser.android)this._tiles[d].src="";this._tiles[d].parentNode==this._container&&this._container.removeChild(this._tiles[d]);delete this._tiles[d]}}, +_addTile:function(a,b){var c=this._getTilePos(a),d=this._map.getZoom(),e=a.x+":"+a.y,f=1<=f)){var g=this._createTile();L.DomUtil.setPosition(g,c);this._tiles[e]=g;if(this.options.scheme=="tms")a.y=f-a.y-1;this._loadTile(g,a,d);b.appendChild(g)}},_getTilePos:function(a){var b=this._map.getPixelOrigin();return a.multiplyBy(this.options.tileSize).subtract(b)},getTileUrl:function(a,b){return this._url.replace("{s}",this.options.subdomains[(a.x+ +a.y)%this.options.subdomains.length]).replace("{z}",b).replace("{x}",a.x).replace("{y}",a.y)},_createTileProto:function(){this._tileImg=L.DomUtil.create("img","leaflet-tile");this._tileImg.galleryimg="no";var a=this.options.tileSize;this._tileImg.style.width=a+"px";this._tileImg.style.height=a+"px"},_createTile:function(){var a=this._tileImg.cloneNode(!1);a.onselectstart=a.onmousemove=L.Util.falseFn;return a},_loadTile:function(a,b,c){a._layer=this;a.onload=this._tileOnLoad;a.onerror=this._tileOnError; +a.src=this.getTileUrl(b,c)},_tileOnLoad:function(){var a=this._layer;this.className+=" leaflet-tile-loaded";a.fire("tileload",{tile:this,url:this.src});a._tilesToLoad--;a._tilesToLoad||a.fire("load")},_tileOnError:function(){var a=this._layer;a.fire("tileerror",{tile:this,url:this.src});if(a=a.options.errorTileUrl)this.src=a}});L.TileLayer.WMS=L.TileLayer.extend({defaultWmsParams:{service:"WMS",request:"GetMap",version:"1.1.1",layers:"",styles:"",format:"image/jpeg",transparent:!1},initialize:function(a,b){this._url=a;this.wmsParams=L.Util.extend({},this.defaultWmsParams);this.wmsParams.width=this.wmsParams.height=this.options.tileSize;for(var c in b)this.options.hasOwnProperty(c)||(this.wmsParams[c]=b[c]);L.Util.setOptions(this,b)},onAdd:function(a){this.wmsParams[parseFloat(this.wmsParams.version)>=1.3?"crs":"srs"]=a.options.crs.code; +L.TileLayer.prototype.onAdd.call(this,a)},getTileUrl:function(a){var b=this.options.tileSize,a=a.multiplyBy(b),b=a.add(new L.Point(b,b)),a=this._map.unproject(a,this._zoom,!0),b=this._map.unproject(b,this._zoom,!0),a=this._map.options.crs.project(a),b=this._map.options.crs.project(b),b=[a.x,b.y,b.x,a.y].join(",");return this._url+L.Util.getParamString(this.wmsParams)+"&bbox="+b}});L.TileLayer.Canvas=L.TileLayer.extend({options:{async:!1},initialize:function(a){L.Util.setOptions(this,a)},_createTileProto:function(){this._canvasProto=L.DomUtil.create("canvas","leaflet-tile");var a=this.options.tileSize;this._canvasProto.width=a;this._canvasProto.height=a},_createTile:function(){var a=this._canvasProto.cloneNode(!1);a.onselectstart=a.onmousemove=L.Util.falseFn;return a},_loadTile:function(a,b,c){a._layer=this;this.drawTile(a,b,c);this.options.async||this.tileDrawn(a)},drawTile:function(){}, +tileDrawn:function(a){this._tileOnLoad.call(a)}});L.ImageOverlay=L.Class.extend({includes:L.Mixin.Events,initialize:function(a,b){this._url=a;this._bounds=b},onAdd:function(a){this._map=a;this._image||this._initImage();a.getPanes().overlayPane.appendChild(this._image);a.on("viewreset",this._reset,this);this._reset()},onRemove:function(a){a.getPanes().overlayPane.removeChild(this._image);a.off("viewreset",this._reset,this)},_initImage:function(){this._image=L.DomUtil.create("img","leaflet-image-layer");this._image.style.visibility="hidden";L.Util.extend(this._image, +{galleryimg:"no",onselectstart:L.Util.falseFn,onmousemove:L.Util.falseFn,onload:this._onImageLoad,src:this._url})},_reset:function(){var a=this._map.latLngToLayerPoint(this._bounds.getNorthWest()),b=this._map.latLngToLayerPoint(this._bounds.getSouthEast()).subtract(a);L.DomUtil.setPosition(this._image,a);this._image.style.width=b.x+"px";this._image.style.height=b.y+"px"},_onImageLoad:function(){this.style.visibility=""}});L.Popup=L.Class.extend({includes:L.Mixin.Events,options:{maxWidth:300,autoPan:!0,closeButton:!0,offset:new L.Point(0,2),autoPanPadding:new L.Point(5,5)},initialize:function(a){L.Util.setOptions(this,a)},onAdd:function(a){this._map=a;this._container||this._initLayout();this._updateContent();this._container.style.opacity="0";this._map._panes.popupPane.appendChild(this._container);this._map.on("viewreset",this._updatePosition,this);if(this._map.options.closePopupOnClick)this._map.on("preclick",this._close, +this);this._update();this._container.style.opacity="1";this._opened=!0},onRemove:function(a){a._panes.popupPane.removeChild(this._container);a.off("viewreset",this._updatePosition,this);a.off("click",this._close,this);this._container.style.opacity="0";this._opened=!1},setLatLng:function(a){this._latlng=a;this._opened&&this._update();return this},setContent:function(a){this._content=a;this._opened&&this._update();return this},_close:function(){this._opened&&this._map.removeLayer(this)},_initLayout:function(){this._container= +L.DomUtil.create("div","leaflet-popup");if(this.options.closeButton)this._closeButton=L.DomUtil.create("a","leaflet-popup-close-button",this._container),this._closeButton.href="#close",this._closeButton.onclick=L.Util.bind(this._onCloseButtonClick,this);this._wrapper=L.DomUtil.create("div","leaflet-popup-content-wrapper",this._container);L.DomEvent.disableClickPropagation(this._wrapper);this._contentNode=L.DomUtil.create("div","leaflet-popup-content",this._wrapper);this._tipContainer=L.DomUtil.create("div", +"leaflet-popup-tip-container",this._container);this._tip=L.DomUtil.create("div","leaflet-popup-tip",this._tipContainer)},_update:function(){this._container.style.visibility="hidden";this._updateContent();this._updateLayout();this._updatePosition();this._container.style.visibility="";this._adjustPan()},_updateContent:function(){if(this._content)typeof this._content=="string"?this._contentNode.innerHTML=this._content:(this._contentNode.innerHTML="",this._contentNode.appendChild(this._content))},_updateLayout:function(){this._container.style.width= +"";this._container.style.whiteSpace="nowrap";var a=this._container.offsetWidth;this._container.style.width=(a>this.options.maxWidth?this.options.maxWidth:a)+"px";this._container.style.whiteSpace="";this._containerWidth=this._container.offsetWidth},_updatePosition:function(){var a=this._map.latLngToLayerPoint(this._latlng);this._containerBottom=-a.y-this.options.offset.y;this._containerLeft=a.x-Math.round(this._containerWidth/2)+this.options.offset.x;this._container.style.bottom=this._containerBottom+ +"px";this._container.style.left=this._containerLeft+"px"},_adjustPan:function(){if(this.options.autoPan){var a=this._container.offsetHeight,b=this._map.layerPointToContainerPoint(new L.Point(this._containerLeft,-a-this._containerBottom)),c=new L.Point(0,0),d=this.options.autoPanPadding,e=this._map.getSize();if(b.x<0)c.x=b.x-d.x;if(b.x+this._containerWidth>e.x)c.x=b.x+this._containerWidth-e.x+d.x;if(b.y<0)c.y=b.y-d.y;if(b.y+a>e.y)c.y=b.y+a-e.y+d.y;(c.x||c.y)&&this._map.panBy(c)}},_onCloseButtonClick:function(a){this._close(); +L.DomEvent.stop(a)}});L.Icon=L.Class.extend({iconUrl:L.ROOT_URL+"images/marker.png",shadowUrl:L.ROOT_URL+"images/marker-shadow.png",iconSize:new L.Point(25,41),shadowSize:new L.Point(41,41),iconAnchor:new L.Point(13,41),popupAnchor:new L.Point(0,-33),initialize:function(a){if(a)this.iconUrl=a},createIcon:function(){return this._createIcon("icon")},createShadow:function(){return this._createIcon("shadow")},_createIcon:function(a){var b=this[a+"Size"],c=this[a+"Url"],d=this._createImg(c);if(!c)return null;d.className="leaflet-marker-"+ +a;d.style.marginLeft=-this.iconAnchor.x+"px";d.style.marginTop=-this.iconAnchor.y+"px";if(b)d.style.width=b.x+"px",d.style.height=b.y+"px";return d},_createImg:function(a){var b;L.Browser.ie6?(b=document.createElement("div"),b.style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+a+'")'):(b=document.createElement("img"),b.src=a);return b}});L.Marker=L.Class.extend({includes:L.Mixin.Events,options:{icon:new L.Icon,title:"",clickable:!0,draggable:!1},initialize:function(a,b){L.Util.setOptions(this,b);this._latlng=a},onAdd:function(a){this._map=a;this._initIcon();a.on("viewreset",this._reset,this);this._reset()},onRemove:function(a){this._removeIcon();a.off("viewreset",this._reset,this)},getLatLng:function(){return this._latlng},setLatLng:function(a){this._latlng=a;this._reset()},setIcon:function(a){this._removeIcon();this._icon=this._shadow= +null;this.options.icon=a;this._initIcon()},_initIcon:function(){if(!this._icon){this._icon=this.options.icon.createIcon();if(this.options.title)this._icon.title=this.options.title;this._initInteraction()}if(!this._shadow)this._shadow=this.options.icon.createShadow();this._map._panes.markerPane.appendChild(this._icon);this._shadow&&this._map._panes.shadowPane.appendChild(this._shadow)},_removeIcon:function(){this._map._panes.markerPane.removeChild(this._icon);this._shadow&&this._map._panes.shadowPane.removeChild(this._shadow)}, +_reset:function(){var a=this._map.latLngToLayerPoint(this._latlng).round();L.DomUtil.setPosition(this._icon,a);this._shadow&&L.DomUtil.setPosition(this._shadow,a);this._icon.style.zIndex=a.y},_initInteraction:function(){if(this.options.clickable){this._icon.className+=" leaflet-clickable";L.DomEvent.addListener(this._icon,"click",this._onMouseClick,this);for(var a=["dblclick","mousedown","mouseover","mouseout"],b=0;b';a=a.firstChild;a.style.behavior="url(#default#VML)";return a&&typeof a.adj=="object"}(); +L.Path=L.Browser.svg||!L.Browser.vml?L.Path:L.Path.extend({statics:{VML:!0,CLIP_PADDING:0.02},_createElement:function(){try{return document.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(a){return document.createElement("')}}catch(a){return function(a){return document.createElement("<"+a+' 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(){this.options.stroke? +(this._stroke=this._createElement("stroke"),this._stroke.endcap="round",this._container.appendChild(this._stroke)):this._container.stroked=!1;this.options.fill?(this._container.filled=!0,this._fill=this._createElement("fill"),this._container.appendChild(this._fill)):this._container.filled=!1;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()+" ";this._container.style.display=""}});L.Browser.canvas=function(){return!!document.createElement("canvas").getContext}(); +L.Path=L.Path.SVG&&!window.L_PREFER_CANVAS||!L.Browser.canvas?L.Path:L.Path.extend({statics:{CANVAS:!0,SVG:!1},options:{updateOnMoveEnd:!0},_initElements:function(){this._initRoot()},_initRoot:function(){var a=this._map._pathRoot,b=this._map._canvasCtx;if(!a)a=this._map._pathRoot=document.createElement("canvas"),a.style.position="absolute",b=this._map._canvasCtx=a.getContext("2d"),b.lineCap="round",b.lineJoin="round",this._map._panes.overlayPane.appendChild(a),this._map.on("moveend",this._updateCanvasViewport, +this),this._updateCanvasViewport();this._ctx=b},_updateStyle:function(){if(this.options.stroke)this._ctx.lineWidth=this.options.weight,this._ctx.strokeStyle=this.options.color;if(this.options.fill)this._ctx.fillStyle=this.options.fillColor||this.options.color},_drawPath:function(){var a,b,c,d,e,f;this._ctx.beginPath();a=0;for(c=this._parts.length;aa.y!=e.y>a.y&&a.x<(e.x-d.x)*(a.y-d.y)/(e.y-d.y)+d.x&&(b=!b)}return b}});(function(){function a(a){return L.FeatureGroup.extend({initialize:function(c,d){this._layers={};for(var e=0,f=c.length;ea.max.x||c.y-b>a.max.y||c.x+b0?Math.ceil(b):Math.floor(b))),a=b-a,c=this._centerOffset.subtract(this._delta).divideBy(this._scale),d=this._map.unproject(this._map.getPixelOrigin().add(this._startCenter).add(c));L.DomEvent.removeListener(document,"touchmove",this._onTouchMove);L.DomEvent.removeListener(document,"touchend",this._onTouchEnd);this._map._runAnimation(d,b,Math.pow(2,a)/this._scale,this._startCenter.add(c))}}});L.Handler.ScrollWheelZoom=L.Handler.extend({enable:function(){if(!this._enabled)L.DomEvent.addListener(this._map._container,"mousewheel",this._onWheelScroll,this),this._delta=0,this._enabled=!0},disable:function(){if(this._enabled)L.DomEvent.removeListener(this._map._container,"mousewheel",this._onWheelScroll),this._enabled=!1},_onWheelScroll:function(a){this._delta+=L.DomEvent.getWheelDelta(a);this._lastMousePos=this._map.mouseEventToContainerPoint(a);clearTimeout(this._timer);this._timer=setTimeout(L.Util.bind(this._performZoom, +this),50);L.DomEvent.preventDefault(a)},_performZoom:function(){var a=Math.round(this._delta);this._delta=0;if(a){var b=this._getCenterForScrollWheelZoom(this._lastMousePos,a),a=this._map.getZoom()+a;this._map._limitZoom(a)!=this._map._zoom&&this._map.setView(b,a)}},_getCenterForScrollWheelZoom:function(a,b){var c=this._map.getPixelBounds().getCenter(),d=this._map.getSize().divideBy(2),d=a.subtract(d).multiplyBy(1-Math.pow(2,-b));return this._map.unproject(c.add(d),this._map._zoom,!0)}});L.Handler.DoubleClickZoom=L.Handler.extend({enable:function(){if(!this._enabled)this._map.on("dblclick",this._onDoubleClick,this._map),this._enabled=!0},disable:function(){if(this._enabled)this._map.off("dblclick",this._onDoubleClick,this._map),this._enabled=!1},_onDoubleClick:function(a){this.setView(a.latlng,this._zoom+1)}});L.Handler.ShiftDragZoom=L.Handler.extend({initialize:function(a){this._map=a;this._container=a._container;this._pane=a._panes.overlayPane},enable:function(){if(!this._enabled)L.DomEvent.addListener(this._container,"mousedown",this._onMouseDown,this),this._enabled=!0},disable:function(){if(this._enabled)L.DomEvent.removeListener(this._container,"mousedown",this._onMouseDown),this._enabled=!1},_onMouseDown:function(a){if(!a.shiftKey||a.which!=1&&a.button!=1)return!1;L.DomUtil.disableTextSelection(); +this._startLayerPoint=this._map.mouseEventToLayerPoint(a);this._box=L.DomUtil.create("div","leaflet-zoom-box",this._pane);L.DomUtil.setPosition(this._box,this._startLayerPoint);this._container.style.cursor="crosshair";L.DomEvent.addListener(document,"mousemove",this._onMouseMove,this);L.DomEvent.addListener(document,"mouseup",this._onMouseUp,this);L.DomEvent.preventDefault(a)},_onMouseMove:function(a){var b=this._map.mouseEventToLayerPoint(a),a=b.x-this._startLayerPoint.x,c=b.y-this._startLayerPoint.y, +b=new L.Point(Math.min(b.x,this._startLayerPoint.x),Math.min(b.y,this._startLayerPoint.y));L.DomUtil.setPosition(this._box,b);this._box.style.width=Math.abs(a)-4+"px";this._box.style.height=Math.abs(c)-4+"px"},_onMouseUp:function(a){this._pane.removeChild(this._box);this._container.style.cursor="";L.DomUtil.enableTextSelection();L.DomEvent.removeListener(document,"mousemove",this._onMouseMove);L.DomEvent.removeListener(document,"mouseup",this._onMouseUp);a=this._map.mouseEventToLayerPoint(a);this._map.fitBounds(new L.LatLngBounds(this._map.layerPointToLatLng(this._startLayerPoint), +this._map.layerPointToLatLng(a)))}});L.Handler.MarkerDrag=L.Handler.extend({initialize:function(a){this._marker=a},enable:function(){if(!this._enabled){if(!this._draggable)this._draggable=new L.Draggable(this._marker._icon,this._marker._icon),this._draggable.on("dragstart",this._onDragStart,this),this._draggable.on("drag",this._onDrag,this),this._draggable.on("dragend",this._onDragEnd,this);this._draggable.enable();this._enabled=!0}},disable:function(){if(this._enabled)this._draggable.disable(),this._enabled=!1},moved:function(){return this._draggable&& +this._draggable._moved},_onDragStart:function(){this._marker.closePopup();this._marker.fire("movestart");this._marker.fire("dragstart")},_onDrag:function(){var a=L.DomUtil.getPosition(this._marker._icon);this._marker._shadow&&L.DomUtil.setPosition(this._marker._shadow,a);this._marker._latlng=this._marker._map.layerPointToLatLng(a);this._marker.fire("move");this._marker.fire("drag")},_onDragEnd:function(){this._marker.fire("moveend");this._marker.fire("dragend")}});L.Control={};L.Control.Position={TOP_LEFT:"topLeft",TOP_RIGHT:"topRight",BOTTOM_LEFT:"bottomLeft",BOTTOM_RIGHT:"bottomRight"};L.Control.Zoom=L.Class.extend({onAdd:function(a){this._map=a;this._container=L.DomUtil.create("div","leaflet-control-zoom");this._zoomInButton=this._createButton("Zoom in","leaflet-control-zoom-in",this._map.zoomIn,this._map);this._zoomOutButton=this._createButton("Zoom out","leaflet-control-zoom-out",this._map.zoomOut,this._map);this._container.appendChild(this._zoomInButton);this._container.appendChild(this._zoomOutButton)},getContainer:function(){return this._container},getPosition:function(){return L.Control.Position.TOP_LEFT}, +_createButton:function(a,b,c,d){var e=document.createElement("a");e.href="#";e.title=a;e.className=b;L.DomEvent.disableClickPropagation(e);L.DomEvent.addListener(e,"click",L.DomEvent.preventDefault);L.DomEvent.addListener(e,"click",c,d);return e}});L.Control.Attribution=L.Class.extend({onAdd:function(a){this._container=L.DomUtil.create("div","leaflet-control-attribution");this._map=a;this._prefix='Powered by Leaflet';this._attributions={};this._update()},getPosition:function(){return L.Control.Position.BOTTOM_RIGHT},getContainer:function(){return this._container},setPrefix:function(a){this._prefix=a},addAttribution:function(a){a&&(this._attributions[a]=!0,this._update())},removeAttribution:function(a){a&& +(delete this._attributions[a],this._update())},_update:function(){if(this._map){var a=[],b;for(b in this._attributions)this._attributions.hasOwnProperty(b)&&a.push(b);b=[];this._prefix&&b.push(this._prefix);a.length&&b.push(a.join(", "));this._container.innerHTML=b.join(" — ")}}});L.Map=L.Class.extend({includes:L.Mixin.Events,options:{crs:L.CRS.EPSG3857||L.CRS.EPSG4326,scale:function(a){return 256*(1<