Merge remote-tracking branch 'joar/exif-rebase'

This commit is contained in:
Joar Wandborg 2012-01-28 18:47:01 +01:00
commit 3d0d3bc972
134 changed files with 12382 additions and 39 deletions

37
.gitignore vendored
View File

@ -1,20 +1,27 @@
dist/
bin/
develop-eggs/
build/
eggs/
lib/
include/
parts/
# / means repository root, not filesystem root
# Top-level files and directories
/dist/
/bin/
/develop-eggs/
/build/
/eggs/
/lib/
/include/
/parts/
/mediagoblin.egg-info
/docs/_build/
/docs/build
/user_dev/
/paste_local.ini
/mediagoblin_local.ini
/server-log.txt
# Tests
/mediagoblin/tests/user_dev/
.installed.cfg
mediagoblin.egg-info
*.pyc
*.pyo
docs/_build/
docs/build
user_dev/
paste_local.ini
mediagoblin_local.ini
server-log.txt
*~
*.swp

1767
extlib/exif/EXIF.py Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,88 @@
Leaflet Changelog
=================
## 0.3 (master)
## 0.2.1 (2011-06-18)
* Fixed regression that caused error in `TileLayer.Canvas`
## 0.2 (2011-06-17)
### Major features
* Added **WMS** support (`TileLayer.WMS` layer).
* Added different **projections** support, having `EPSG:3857`, `EPSG:4326` and `EPSG:3395` out of the box (through `crs` option in `Map`). Thanks to [@Miroff](https://github.com/Miroff) & [@Komzpa](https://github.com/Komzpa) for great advice and explanation regarding this.
* Added **GeoJSON** layer support.
### Improvements
#### Usability improvements
* Improved panning performance in Chrome and FF considerably with the help of `requestAnimationFrame`. [#130](https://github.com/CloudMade/Leaflet/issues/130)
* Improved click responsiveness in mobile WebKit (now it happens without delay). [#26](https://github.com/CloudMade/Leaflet/issues/26)
* Added tap tolerance (so click happens even if you moved your finger slighly when tapping).
* Improved geolocation error handling: better error messages, explicit timeout, set world view on locateAndSetView failure. [#61](https://github.com/CloudMade/Leaflet/issues/61)
#### API improvements
* Added **MultiPolyline** and **MultiPolygon** layers. [#77](https://github.com/CloudMade/Leaflet/issues/77)
* Added **LayerGroup** and **FeatureGroup** layers for grouping other layers.
* Added **TileLayer.Canvas** for easy creation of canvas-based tile layers.
* Changed `Circle` to be zoom-dependent (with radius in meters); circle of a permanent size is now called `CircleMarker`.
* Added `mouseover` and `mouseout` events to map, markers and paths; added map `mousemove` event.
* Added `setLatLngs`, `spliceLatLngs`, `addLatLng`, `getLatLngs` methods to polylines and polygons.
* Added `setLatLng` and `setRadius` methods to `Circle` and `CircleMarker`.
* Improved `LatLngBounds contains` method to accept `LatLng` in addition to `LatLngBounds`, the same for `Bounds contains` and `Point`
* Improved `LatLngBounds` & `Bounds` to allow their instantiation without arguments (by [@snc](https://github.com/snc)).
* Added TMS tile numbering support through `TileLayer` `scheme: 'tms'` option (by [@tmcw](https://github.com/tmcw)).
* Added `TileLayer` `noWrap` option to disable wrapping `x` tile coordinate (by [@jasondavies](https://github.com/jasondavies)).
* Added `opacity` option and `setOpacity` method to `TileLayer`.
* Added `setLatLng` and `setIcon` methods to `Marker`.
* Added `title` option to `Marker`.
* Added `maxZoom` argument to `map.locateAndSetView` method.
* Added ability to pass Geolocation options to map `locate` and `locateAndSetView` methods (by [@JasonSanford](https://github.com/JasonSanford)).
* Improved `Popup` to accept HTML elements in addition to strings as its content.
#### Development workflow improvements
* Added `Makefile` for building `leaflet.js` on non-Windows machines (by [@tmcw](https://github.com/tmcw)).
* Improved `debug/leaflet-include.js` script to allow using it outside of `debug` folder (by [@antonj](https://github.com/antonj)).
* Improved `L` definition to be compatible with CommonJS. [#122](https://github.com/CloudMade/Leaflet/issues/122)
### Bug fixes
#### General bugfixes
* Fixed a bug where zooming is broken if the map contains a polygon and you zoom to an area where it's not visible. [#47](https://github.com/CloudMade/Leaflet/issues/47)
* Fixed a bug where closed polylines would not appear on the map.
* Fixed a bug where marker that was added, removed and then added again would not appear on the map. [#66](https://github.com/CloudMade/Leaflet/issues/66)
* Fixed a bug where tile layer that was added, removed and then added again would not appear on the map.
* Fixed a bug where some tiles would not load when panning across the date line. [#97](https://github.com/CloudMade/Leaflet/issues/97)
* Fixed a bug where map div with `position: absolute` is reset to `relative`. [#100](https://github.com/CloudMade/Leaflet/issues/100)
* Fixed a bug that caused an error when trying to add a marker without shadow in its icon.
* Fixed a bug where popup content would not update on `setContent` call. [#94](https://github.com/CloudMade/Leaflet/issues/94)
* Fixed a bug where double click zoom wouldn't work if popup is opened on map click
* Fixed a bug with click propagation on popup close button. [#99](https://github.com/CloudMade/Leaflet/issues/99)
* Fixed inability to remove ImageOverlay layer.
#### Browser bugfixes
* Fixed a bug where paths would not appear in IE8.
* Fixed a bug where there were occasional slowdowns before zoom animation in WebKit. [#123](https://github.com/CloudMade/Leaflet/issues/123)
* Fixed incorrect zoom animation & popup styling in Opera 11.11.
* Fixed popup fade animation in Firefox and Opera.
* Fixed a bug where map isn't displayed in Firefox when there's an `img { max-width: 100% }` rule.
#### Mobile browsers bugfixes
* Fixed a bug that prevented panning on some Android 2.1 (and possibly older) devices. [#84](https://github.com/CloudMade/Leaflet/issues/84)
* Disabled zoom animation on Android by default because it's buggy on some devices (will be enabled back when it's stable enough). [#32](https://github.com/CloudMade/Leaflet/issues/32)
* Fixed a bug where map would occasionally break while multi-touch-zooming on iOS. [#32](https://github.com/CloudMade/Leaflet/issues/32)
* Fixed a bug that prevented panning/clicking on Android 3 tablets. [#121](https://github.com/CloudMade/Leaflet/issues/121)
* Fixed a bug that prevented panning/clicking on Opera Mobile. [#138](https://github.com/CloudMade/Leaflet/issues/138)
* Fixed potentional memory leak on WebKit when removing tiles, thanks to [@Scalar4eg](https://github.com/Scalar4eg). [#107](https://github.com/CloudMade/Leaflet/issues/107)
## 0.1 (2011-05-13)
* Initial Leaflet release.

22
extlib/leaflet/LICENSE Normal file
View File

@ -0,0 +1,22 @@
Copyright (c) 2010-2011, CloudMade, Vladimir Agafonkin
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

10
extlib/leaflet/README.md Normal file
View File

@ -0,0 +1,10 @@
<img src="http://leaflet.cloudmade.com/docs/images/logo.png" alt="Leaflet" />
Leaflet is a modern, lightweight BSD-licensed JavaScript library for making tile-based interactive maps for both desktop and mobile web browsers, developed by [CloudMade](http://cloudmade.com) to form the core of its next generation JavaScript API.
It is built from the ground up to work efficiently and smoothly on both platforms, utilizing cutting-edge technologies included in HTML5. Its top priorities are usability, performance and small size, [A-grade](http://developer.yahoo.com/yui/articles/gbs/) browser support, flexibility and easy to use API. The OOP-based code of the library is designed to be modular, extensible and very easy to understand.
Check out the website for more information: [leaflet.cloudmade.com](http://leaflet.cloudmade.com)
## Contributing to Leaflet
Let's make the best open-source library for maps that can possibly exist! Please send your pull requests to [Vladimir Agafonkin](http://github.com/mourner) (Leaflet maintainer) - we'll be happy to accept your contributions! [List of Leaflet contributors](http://github.com/CloudMade/Leaflet/contributors)

View File

@ -0,0 +1,65 @@
../dist/leaflet.js: Makefile
java -jar ../lib/closure-compiler/compiler.jar \
--js ../src/Leaflet.js \
--js ../src/core/Util.js \
--js ../src/core/Class.js \
--js ../src/core/Events.js \
--js ../src/core/Browser.js \
--js ../src/geometry/Point.js \
--js ../src/geometry/Bounds.js \
--js ../src/geometry/Transformation.js \
--js ../src/geometry/LineUtil.js \
--js ../src/geometry/PolyUtil.js \
--js ../src/dom/DomEvent.js \
--js ../src/dom/DomEvent.DoubleTap.js \
--js ../src/dom/DomUtil.js \
--js ../src/dom/Draggable.js \
--js ../src/dom/transition/Transition.js \
--js ../src/dom/transition/Transition.Native.js \
--js ../src/dom/transition/Transition.Timer.js \
--js ../src/geo/LatLng.js \
--js ../src/geo/LatLngBounds.js \
--js ../src/geo/projection/Projection.js \
--js ../src/geo/projection/Projection.SphericalMercator.js \
--js ../src/geo/projection/Projection.LonLat.js \
--js ../src/geo/projection/Projection.Mercator.js \
--js ../src/geo/crs/CRS.js \
--js ../src/geo/crs/CRS.EPSG3857.js \
--js ../src/geo/crs/CRS.EPSG4326.js \
--js ../src/geo/crs/CRS.EPSG3395.js \
--js ../src/layer/LayerGroup.js \
--js ../src/layer/FeatureGroup.js \
--js ../src/layer/tile/TileLayer.js \
--js ../src/layer/tile/TileLayer.WMS.js \
--js ../src/layer/tile/TileLayer.Canvas.js \
--js ../src/layer/ImageOverlay.js \
--js ../src/layer/Popup.js \
--js ../src/layer/marker/Icon.js \
--js ../src/layer/marker/Marker.js \
--js ../src/layer/marker/Marker.Popup.js \
--js ../src/layer/vector/Path.js \
--js ../src/layer/vector/Path.VML.js \
--js ../src/layer/vector/Path.Popup.js \
--js ../src/layer/vector/Polyline.js \
--js ../src/layer/vector/Polygon.js \
--js ../src/layer/vector/MultiPoly.js \
--js ../src/layer/vector/Circle.js \
--js ../src/layer/vector/CircleMarker.js \
--js ../src/layer/GeoJSON.js \
--js ../src/handler/Handler.js \
--js ../src/handler/MapDrag.js \
--js ../src/handler/TouchZoom.js \
--js ../src/handler/ScrollWheelZoom.js \
--js ../src/handler/DoubleClickZoom.js \
--js ../src/handler/ShiftDragZoom.js \
--js ../src/handler/MarkerDrag.js \
--js ../src/control/Control.js \
--js ../src/control/Control.Zoom.js \
--js ../src/control/Control.Attribution.js \
--js ../src/map/Map.js \
--js ../src/map/ext/Map.Geolocation.js \
--js ../src/map/ext/Map.Popup.js \
--js ../src/map/ext/Map.PanAnimation.js \
--js ../src/map/ext/Map.ZoomAnimation.js \
--js ../src/map/ext/Map.Control.js \
--js_output_file ../dist/leaflet.js

View File

@ -0,0 +1,65 @@
@echo off
java -jar ../lib/closure-compiler/compiler.jar ^
--js ../src/Leaflet.js ^
--js ../src/core/Util.js ^
--js ../src/core/Class.js ^
--js ../src/core/Events.js ^
--js ../src/core/Browser.js ^
--js ../src/geometry/Point.js ^
--js ../src/geometry/Bounds.js ^
--js ../src/geometry/Transformation.js ^
--js ../src/geometry/LineUtil.js ^
--js ../src/geometry/PolyUtil.js ^
--js ../src/dom/DomEvent.js ^
--js ../src/dom/DomEvent.DoubleTap.js ^
--js ../src/dom/DomUtil.js ^
--js ../src/dom/Draggable.js ^
--js ../src/dom/transition/Transition.js ^
--js ../src/dom/transition/Transition.Native.js ^
--js ../src/dom/transition/Transition.Timer.js ^
--js ../src/geo/LatLng.js ^
--js ../src/geo/LatLngBounds.js ^
--js ../src/geo/projection/Projection.js ^
--js ../src/geo/projection/Projection.SphericalMercator.js ^
--js ../src/geo/projection/Projection.LonLat.js ^
--js ../src/geo/projection/Projection.Mercator.js ^
--js ../src/geo/crs/CRS.js ^
--js ../src/geo/crs/CRS.EPSG3857.js ^
--js ../src/geo/crs/CRS.EPSG4326.js ^
--js ../src/geo/crs/CRS.EPSG3395.js ^
--js ../src/layer/LayerGroup.js ^
--js ../src/layer/FeatureGroup.js ^
--js ../src/layer/tile/TileLayer.js ^
--js ../src/layer/tile/TileLayer.WMS.js ^
--js ../src/layer/tile/TileLayer.Canvas.js ^
--js ../src/layer/ImageOverlay.js ^
--js ../src/layer/Popup.js ^
--js ../src/layer/marker/Icon.js ^
--js ../src/layer/marker/Marker.js ^
--js ../src/layer/marker/Marker.Popup.js ^
--js ../src/layer/vector/Path.js ^
--js ../src/layer/vector/Path.VML.js ^
--js ../src/layer/vector/Path.Popup.js ^
--js ../src/layer/vector/Polyline.js ^
--js ../src/layer/vector/Polygon.js ^
--js ../src/layer/vector/MultiPoly.js ^
--js ../src/layer/vector/Circle.js ^
--js ../src/layer/vector/CircleMarker.js ^
--js ../src/layer/GeoJSON.js ^
--js ../src/handler/Handler.js ^
--js ../src/handler/MapDrag.js ^
--js ../src/handler/TouchZoom.js ^
--js ../src/handler/ScrollWheelZoom.js ^
--js ../src/handler/DoubleClickZoom.js ^
--js ../src/handler/ShiftDragZoom.js ^
--js ../src/handler/MarkerDrag.js ^
--js ../src/control/Control.js ^
--js ../src/control/Control.Zoom.js ^
--js ../src/control/Control.Attribution.js ^
--js ../src/map/Map.js ^
--js ../src/map/ext/Map.Geolocation.js ^
--js ../src/map/ext/Map.Popup.js ^
--js ../src/map/ext/Map.PanAnimation.js ^
--js ../src/map/ext/Map.ZoomAnimation.js ^
--js ../src/map/ext/Map.Control.js ^
--js_output_file ../dist/leaflet.js

View File

@ -0,0 +1,208 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet Build Helper</title>
<script type="text/javascript" src="deps.js"></script>
<style type="text/css">
body {
font: 12px/1.4 Verdana, sans-serif;
text-align: center;
padding: 2em 0;
}
#container {
text-align: left;
margin: 0 auto;
width: 600px;
}
#deplist {
list-style: none;
padding: 0;
}
#deplist li {
padding-top: 10px;
padding-bottom: 10px;
border-top: 1px solid #eee;
}
#deplist li.heading {
border: none;
background: #eee;
padding: 5px 10px;
margin-top: 10px;
}
#deplist input {
float: left;
margin-right: 5px;
display: inline;
}
#deplist label {
float: left;
width: 190px;
font-weight: bold;
}
#deplist div {
display: table-cell;
height: 1%;
}
#deplist .desc {
}
#deplist .deps {
color: #777;
}
#command {
width: 100%;
}
</style>
</head>
<body>
<div id="container">
<h1>Leaflet Build Helper</h1>
<p>
<a id="select-all" href="#all">Select All</a> |
<a id="deselect-all" href="#none">Deselect All</a>
</p>
<ul id="deplist"></ul>
<p>
Run this command in the build directory:<br />
<input type="text" id="command" />
</p>
</div>
<script type="text/javascript">
var deplist = document.getElementById('deplist'),
commandInput = document.getElementById('command');
document.getElementById('select-all').onclick = function() {
var checks = deplist.getElementsByTagName('input');
for (var i = 0; i < checks.length; i++) {
checks[i].checked = true;
}
updateCommand();
return false;
};
document.getElementById('deselect-all').onclick = function() {
var checks = deplist.getElementsByTagName('input');
for (var i = 0; i < checks.length; i++) {
if (!checks[i].disabled) {
checks[i].checked = false;
}
}
updateCommand();
return false;
};
function updateCommand() {
var files = {};
var checks = deplist.getElementsByTagName('input');
for (var i = 0; i < checks.length; i++) {
if (checks[i].checked) {
var srcs = deps[checks[i].id].src;
for (var j = 0; j < srcs.length; j++) {
files[srcs[j]] = true;
}
}
}
var command = 'java -jar ../lib/closure-compiler/compiler.jar ';
for (var src in files) {
command += '--js ../src/' + src + ' ';
}
command += '--js_output_file ../dist/leaflet-custom.js';
commandInput.value = command;
}
commandInput.onclick = function() {
commandInput.focus();
commandInput.select();
};
function onCheckboxChange() {
if (this.checked) {
var depDeps = deps[this.id].deps;
if (!depDeps) { return; }
for (var i = 0; i < depDeps.length; i++) {
var check = document.getElementById(depDeps[i]);
if (!check.checked) {
check.checked = true;
check.onchange();
}
}
} else {
var checks = deplist.getElementsByTagName('input');
for (var i = 0; i < checks.length; i++) {
var dep = deps[checks[i].id];
if (!dep.deps) { continue; }
for (var j = 0; j < dep.deps.length; j++) {
if (dep.deps[j] == this.id) {
if (checks[i].checked) {
checks[i].checked = false;
checks[i].onchange();
}
}
}
}
}
updateCommand();
}
for (var name in deps) {
var li = document.createElement('li');
if (deps[name].heading) {
var heading = document.createElement('li');
heading.className = 'heading';
heading.appendChild(document.createTextNode(deps[name].heading));
deplist.appendChild(heading);
}
var div = document.createElement('div');
var label = document.createElement('label');
var check = document.createElement('input');
check.type = 'checkbox';
check.id = name;
label.appendChild(check);
check.onchange = onCheckboxChange;
if (name == 'Core') {
check.checked = true;
check.disabled = true;
}
label.appendChild(document.createTextNode(name));
label.htmlFor = name;
li.appendChild(label);
var desc = document.createElement('span');
desc.className = 'desc';
desc.appendChild(document.createTextNode(deps[name].desc));
var depText = deps[name].deps && deps[name].deps.join(', ');
if (depText) {
var depspan = document.createElement('span');
depspan.className = 'deps';
depspan.appendChild(document.createTextNode('Deps: ' + depText));
}
div.appendChild(desc);
div.appendChild(document.createElement('br'));
if (depText) { div.appendChild(depspan); }
li.appendChild(div);
deplist.appendChild(li);
}
updateCommand();
</script>
</body>
</html>

View File

@ -0,0 +1,211 @@
var deps = {
Core: {
src: ['Leaflet.js',
'core/Browser.js',
'core/Class.js',
'core/Events.js',
'core/Util.js',
'dom/DomUtil.js',
'geo/LatLng.js',
'geo/LatLngBounds.js',
'geo/projection/Projection.js',
'geo/projection/Projection.SphericalMercator.js',
'geo/projection/Projection.LonLat.js',
'geo/crs/CRS.js',
'geo/crs/CRS.EPSG3857.js',
'geo/crs/CRS.EPSG4326.js',
'geometry/Bounds.js',
'geometry/Point.js',
'geometry/Transformation.js',
'map/Map.js'],
desc: 'The core of the library, including OOP, events, DOM facilities, basic units, projections (EPSG:3857 and EPSG:4326) and the base Map class.'
},
EPSG3395: {
src: ['geo/projection/Projection.Mercator.js',
'geo/crs/CRS.EPSG3395.js'],
desc: 'EPSG:3395 projection (used by some map providers).',
heading: 'Additional projections'
},
TileLayer: {
src: ['layer/tile/TileLayer.js'],
desc: 'The base class for displaying tile layers on the map.',
heading: 'Layers'
},
TileLayerWMS: {
src: ['layer/tile/TileLayer.WMS.js'],
desc: 'WMS tile layer.',
deps: ['TileLayer']
},
TileLayerCanvas: {
src: ['layer/tile/TileLayer.Canvas.js'],
desc: 'Tile layer made from canvases (for custom drawing purposes).',
deps: ['TileLayer']
},
ImageOverlay: {
src: ['layer/ImageOverlay.js'],
desc: 'Used to display an image over a particular rectangular area of the map.'
},
Marker: {
src: ['layer/marker/Icon.js', 'layer/marker/Marker.js'],
desc: 'Markers to put on the map.'
},
Popup: {
src: ['layer/Popup.js', 'layer/marker/Marker.Popup.js', 'map/ext/Map.Popup.js'],
deps: ['Marker'],
desc: 'Used to display the map popup (used mostly for binding HTML data to markers and paths on click).'
},
LayerGroup: {
src: ['layer/LayerGroup.js'],
desc: 'Allows grouping several layers to handle them as one.'
},
FeatureGroup: {
src: ['layer/FeatureGroup.js'],
deps: ['LayerGroup', 'Popup'],
desc: 'Extends LayerGroup with mouse events and bindPopup method shared between layers.'
},
Path: {
src: ['layer/vector/Path.js', 'layer/vector/Path.Popup.js'],
desc: 'Vector rendering core (SVG-powered), enables overlaying the map with SVG paths.',
heading: 'Vector layers'
},
PathVML: {
src: ['layer/vector/Path.VML.js'],
desc: 'VML fallback for vector rendering core (IE 6-8).'
},
Polyline: {
src: ['geometry/LineUtil.js', 'layer/vector/Polyline.js'],
deps: ['Path'],
desc: 'Polyline overlays.'
},
Polygon: {
src: ['geometry/PolyUtil.js', 'layer/vector/Polygon.js'],
deps: ['Polyline'],
desc: 'Polygon overlays.'
},
MultiPoly: {
src: ['layer/vector/MultiPoly.js'],
deps: ['FeatureGroup', 'Polyline', 'Polygon'],
desc: 'MultiPolygon and MultyPolyline layers.'
},
Circle: {
src: ['layer/vector/Circle.js'],
deps: ['Path'],
desc: 'Circle overlays (with radius in meters).'
},
CircleMarker: {
src: ['layer/vector/CircleMarker.js'],
deps: ['Circle'],
desc: 'Circle overlays with a constant pixel radius.'
},
GeoJSON: {
src: ['layer/GeoJSON.js'],
deps: ['Marker', 'MultiPoly', 'FeatureGroup'],
desc: 'GeoJSON layer, parses the data and adds corresponding layers above.'
},
MapDrag: {
src: ['dom/DomEvent.js',
'dom/Draggable.js',
'handler/Handler.js',
'handler/MapDrag.js'],
desc: 'Makes the map draggable (by mouse or touch).',
heading: 'Interaction'
},
MouseZoom: {
src: ['dom/DomEvent.js',
'handler/Handler.js',
'handler/DoubleClickZoom.js',
'handler/ScrollWheelZoom.js'],
desc: 'Scroll wheel zoom and double click zoom on the map.'
},
TouchZoom: {
src: ['dom/DomEvent.js',
'dom/DomEvent.DoubleTap.js',
'handler/Handler.js',
'handler/TouchZoom.js'],
deps: ['MapAnimationZoom'],
desc: 'Enables smooth touch zooming on iOS and double tap on iOS/Android.'
},
ShiftDragZoom: {
src: ['handler/ShiftDragZoom.js'],
desc: 'Enables zooming to bounding box by shift-dragging the map.'
},
MarkerDrag: {
src: ['handler/MarkerDrag.js'],
desc: 'Makes markers draggable (by mouse or touch).'
},
ControlZoom: {
src: ['control/Control.js',
'map/ext/Map.Control.js',
'control/Control.Zoom.js'],
heading: 'Controls',
desc: 'Basic zoom control with two buttons (zoom in / zoom out).'
},
ControlZoom: {
src: ['control/Control.js',
'map/ext/Map.Control.js',
'control/Control.Attribution.js'],
desc: 'Attribution control.'
},
MapAnimationNative: {
src: ['dom/DomEvent.js',
'dom/transition/Transition.js',
'dom/transition/Transition.Native.js'],
desc: 'Animation core that uses CSS3 Transitions (for powering pan & zoom animations). Works on mobile webkit-powered browsers and some modern desktop browsers.',
heading: 'Visual effects'
},
MapAnimationFallback: {
src: ['dom/transition/Transition.Timer.js'],
deps: ['MapAnimationNative'],
desc: 'Timer-based animation fallback for browsers that don\'t support CSS3 transitions.'
},
MapAnimationPan: {
src: ['map/ext/Map.PanAnimation.js'],
deps: ['MapAnimationNative'],
desc: 'Panning animation. Can use both native and timer-based animation.'
},
MapAnimationZoom: {
src: ['map/ext/Map.ZoomAnimation.js'],
deps: ['MapAnimationPan', 'MapAnimationNative'],
desc: 'Smooth zooming animation. So far it works only on browsers that support CSS3 Transitions.'
},
MapGeolocation: {
src: ['map/ext/Map.Geolocation.js'],
desc: 'Adds Map#locate method and related events to make geolocation easier.',
heading: 'Misc'
}
};

View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet debug page</title>
<link rel="stylesheet" href="../../dist/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="../css/screen.css" />
<script src="../include.js"></script>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18}),
latlng = new L.LatLng(50.5, 30.51);
var map = new L.Map('map').addLayer(cloudmade).setView(latlng, 15);
var zoomControl = new L.Control.Zoom();
map.addControl(zoomControl);
</script>
</body>
</html>

View File

@ -0,0 +1,6 @@
html, body, #map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}

View File

@ -0,0 +1,5 @@
#map {
width: 800px;
height: 600px;
border: 1px solid #ccc;
}

View File

@ -0,0 +1,50 @@
var geojsonSample = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"prop0": "value0",
"color": "blue"
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]]
},
"properties": {
"color": "red",
"prop1": 0.0
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]]
},
"properties": {
"color": "green",
"prop1": {
"this": "that"
}
}
},
{
"type": "Feature",
"geometry": {
"type": "MultiPolygon",
"coordinates": [[[[100.0, 1.5], [100.5, 1.5], [100.5, 2.0], [100.0, 2.0], [100.0, 1.5]]], [[[100.5, 2.0], [100.5, 2.5], [101.0, 2.5], [101.0, 2.0], [100.5, 2.0]]]]
}
}
]
};

View File

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet debug page</title>
<link rel="stylesheet" href="../../dist/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="../css/screen.css" />
<script src="../leaflet-include.js"></script>
</head>
<body>
<div id="map" style="width: 600px; height: 600px; border: 1px solid #ccc"></div>
<button id="populate">Populate with 10 markers</button>
<script type="text/javascript" src="geojson-sample.js"></script>
<script type="text/javascript">
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
cloudmadeAttribution = 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2011 CloudMade',
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18, attribution: cloudmadeAttribution});
var map = new L.Map('map', {
center: new L.LatLng(0.78, 102.37),
zoom: 7,
layers: [cloudmade]
});
var geojson = new L.GeoJSON();
/* points are rendered as markers by default, but you can change this:
var geojson = new L.GeoJSON(null, {
pointToLayer: function(latlng) { return new L.CircleMarker(latlng); }
});
*/
geojson.on('featureparse', function(e) {
// you can style features depending on their properties, etc.
var popupText = 'geometry type: ' + e.geometryType + '<br/>';
if (e.layer instanceof L.Path) {
e.layer.setStyle({color: e.properties.color});
popupText += 'color: ' + e.properties.color;
}
e.layer.bindPopup(popupText);
});
geojson.addGeoJSON(geojsonSample);
map.addLayer(geojson);
</script>
</body>
</html>

View File

@ -0,0 +1,100 @@
(function() {
//TODO replace script list with the one from ../buid/deps.js
var scripts = [
'Leaflet.js',
'core/Util.js',
'core/Class.js',
'core/Events.js',
'core/Browser.js',
'geometry/Point.js',
'geometry/Bounds.js',
'geometry/Transformation.js',
'geometry/LineUtil.js',
'geometry/PolyUtil.js',
'dom/DomEvent.js',
'dom/DomEvent.DoubleTap.js',
'dom/DomUtil.js',
'dom/Draggable.js',
'dom/transition/Transition.js',
'dom/transition/Transition.Native.js',
'dom/transition/Transition.Timer.js',
'geo/LatLng.js',
'geo/LatLngBounds.js',
'geo/projection/Projection.js',
'geo/projection/Projection.SphericalMercator.js',
'geo/projection/Projection.LonLat.js',
'geo/projection/Projection.Mercator.js',
'geo/crs/CRS.js',
'geo/crs/CRS.EPSG3857.js',
'geo/crs/CRS.EPSG4326.js',
'geo/crs/CRS.EPSG3395.js',
'layer/LayerGroup.js',
'layer/FeatureGroup.js',
'layer/tile/TileLayer.js',
'layer/tile/TileLayer.WMS.js',
'layer/tile/TileLayer.Canvas.js',
'layer/ImageOverlay.js',
'layer/Popup.js',
'layer/marker/Icon.js',
'layer/marker/Marker.js',
'layer/marker/Marker.Popup.js',
'layer/vector/Path.js',
'layer/vector/Path.VML.js',
'layer/vector/Path.Popup.js',
'layer/vector/Polyline.js',
'layer/vector/Polygon.js',
'layer/vector/MultiPoly.js',
'layer/vector/Circle.js',
'layer/vector/CircleMarker.js',
'layer/GeoJSON.js',
'handler/Handler.js',
'handler/MapDrag.js',
'handler/TouchZoom.js',
'handler/DoubleClickZoom.js',
'handler/ScrollWheelZoom.js',
'handler/ShiftDragZoom.js',
'handler/MarkerDrag.js',
'control/Control.js',
'control/Control.Zoom.js',
'control/Control.Attribution.js',
'map/Map.js',
'map/ext/Map.Geolocation.js',
'map/ext/Map.Popup.js',
'map/ext/Map.PanAnimation.js',
'map/ext/Map.ZoomAnimation.js',
'map/ext/Map.Control.js'
];
function getSrcUrl() {
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
var src = scripts[i].src;
if (src) {
var res = src.match(/^(.*)leaflet-include\.js$/);
if (res) {
return res[1] + '../src/';
}
}
}
}
var path = getSrcUrl();
for (var i = 0; i < scripts.length; i++) {
document.writeln("<script type='text/javascript' src='" + path + "../src/" + scripts[i] + "'></script>");
}
})();

View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet debug page</title>
<link rel="stylesheet" href="../../dist/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="../css/screen.css" />
<script src="../leaflet-include.js"></script>
</head>
<body>
<div id="map" style="width: 600px; height: 600px; border: 1px solid #ccc"></div>
<script type="text/javascript">
var tiles = new L.TileLayer.Canvas();
tiles.drawTile = function(canvas, tile, zoom) {
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, 255, 255);
ctx.fillStyle = 'black';
ctx.fillText('x: ' + tile.x + ', y: ' + tile.y + ', zoom:' + zoom, 20, 20);
ctx.strokeStyle = 'red';
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(255, 0);
ctx.lineTo(255, 255);
ctx.lineTo(0, 255);
ctx.closePath();
ctx.stroke();
}
var map = new L.Map('map', {center: new L.LatLng(50.5, 30.51), zoom: 15, layers: [tiles]});
</script>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet debug page</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<link rel="stylesheet" href="../../dist/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="../css/mobile.css" />
<script src="../leaflet-include.js"></script>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
cloudmadeAttribution = 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2011 CloudMade',
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18, attribution: cloudmadeAttribution});
var map = new L.Map('map').addLayer(cloudmade);
map.on('locationfound', function(e) {
var marker = new L.Marker(e.latlng);
map.addLayer(marker);
marker.bindPopup("<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.</p><p>Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.</p>");
});
map.on('locationerror', function(e) {
alert(e.message);
map.fitWorld();
});
map.locateAndSetView();
</script>
</body>
</html>

View File

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet debug page</title>
<link rel="stylesheet" href="../../dist/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="../css/screen.css" />
<script src="../leaflet-include.js"></script>
</head>
<body>
<div id="map" style="width: 600px; height: 600px; border: 1px solid #ccc"></div>
<button id="populate">Populate with 10 markers</button>
<script type="text/javascript">
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
cloudmadeAttribution = 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2011 CloudMade',
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18, attribution: cloudmadeAttribution}),
latlng = new L.LatLng(50.5, 30.51);
var map = new L.Map('map', {center: latlng, zoom: 15, layers: [cloudmade]});
var markers = new L.FeatureGroup();
function populate() {
var bounds = map.getBounds(),
southWest = bounds.getSouthWest(),
northEast = bounds.getNorthEast(),
lngSpan = northEast.lng - southWest.lng,
latSpan = northEast.lat - southWest.lat;
for (var i = 0; i < 10; i++) {
var latlng = new L.LatLng(
southWest.lat + latSpan * Math.random(),
southWest.lng + lngSpan * Math.random());
markers.addLayer(new L.Marker(latlng));
}
return false;
};
markers.bindPopup("<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.</p><p>Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque.</p>");
map.addLayer(markers);
populate();
L.DomUtil.get('populate').onclick = populate;
</script>
</body>
</html>

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet debug page</title>
<link rel="stylesheet" href="../../dist/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="../css/screen.css" />
<script src="../leaflet-include.js"></script>
</head>
<body>
<div id="map" style="width: 1024px; height: 440px; border: 1px solid #ccc"></div>
<script type="text/javascript">
var map = new L.Map('map', {crs: L.CRS.EPSG4326});
var bluemarble = new L.TileLayer.WMS("http://maps.opengeo.org/geowebcache/service/wms", {
layers: 'bluemarble',
attribution: "Data &copy; NASA Blue Marble, image service by OpenGeo",
minZoom: 2,
maxZoom: 5,
});
map.addLayer(bluemarble).fitWorld();
</script>
</body>
</html>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet debug page</title>
<link rel="stylesheet" href="../../dist/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="../css/screen.css" />
<script src="../leaflet-include.js"></script>
</head>
<body>
<div id="map" style="width: 800px; height: 600px; border: 1px solid #ccc"></div>
<script type="text/javascript">
var map = new L.Map('map');
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
cloudmadeAttribution = 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2011 CloudMade',
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18, attribution: cloudmadeAttribution});
var nexrad = new L.TileLayer.WMS("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", {
layers: 'nexrad-n0r-900913',
format: 'image/png',
transparent: true,
attribution: "Weather data &copy; 2011 IEM Nexrad",
opacity: 0.4
});
var bounds = new L.LatLngBounds(new L.LatLng(32, -126), new L.LatLng(50, -64));
map.addLayer(cloudmade).addLayer(nexrad).fitBounds(bounds);
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet debug page</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<link rel="stylesheet" href="../../dist/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="../css/mobile.css" />
<script src="../leaflet-include.js"></script>
</head>
<body>
<div id="map"></div>
<script src="route.js"></script>
<script>
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18});
for (var i = 0, latlngs = [], len = route.length; i < len; i++) {
latlngs.push(new L.LatLng(route[i][0], route[i][1]));
}
var path = new L.Polyline(latlngs, {smoothFactor: 1});
var map = new L.Map('map', {layers: [cloudmade]});
map.fitBounds(new L.LatLngBounds(latlngs));
map.addLayer(new L.Marker(latlngs[0]));
map.addLayer(new L.Marker(latlngs[latlngs.length - 1]));
map.addLayer(path);
</script>
</body>
</html>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet debug page</title>
<link rel="stylesheet" href="../../dist/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
<link rel="stylesheet" href="../css/screen.css" />
<script src="../leaflet-include.js"></script>
</head>
<body>
<div id="map" style="width: 800px; height: 600px; border: 1px solid #ccc"></div>
<script src="route.js"></script>
<script>
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18});
for (var i = 0, latlngs = [], len = route.length; i < len; i++) {
latlngs.push(new L.LatLng(route[i][0], route[i][1]));
}
var path = new L.Polyline(latlngs);
var map = new L.Map('map', {layers: [cloudmade]});
map.fitBounds(new L.LatLngBounds(latlngs));
map.addLayer(new L.Marker(latlngs[0]));
map.addLayer(new L.Marker(latlngs[len - 1]));
map.addLayer(path);
path.bindPopup("Hello world");
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
extlib/leaflet/dist/images/marker.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
extlib/leaflet/dist/images/zoom-in.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 963 B

BIN
extlib/leaflet/dist/images/zoom-out.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 959 B

273
extlib/leaflet/dist/leaflet.css vendored Normal file
View File

@ -0,0 +1,273 @@
/* 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 {
padding: 5px;
background: rgba(0, 0, 0, 0.25);
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
border-radius: 7px;
}
.leaflet-control-zoom a {
display: block;
width: 19px;
height: 19px;
background-position: 50% 50%;
background-repeat: no-repeat;
background-color: rgba(255, 255, 255, 0.75);
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
}
.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-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);
}

46
extlib/leaflet/dist/leaflet.ie.css vendored Normal file
View File

@ -0,0 +1,46 @@
.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-attribution {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#B2FFFFFF,endColorstr=#B2FFFFFF);
}

114
extlib/leaflet/dist/leaflet.js vendored Normal file
View File

@ -0,0 +1,114 @@
/*
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;e<f;e++){var g=a[e].src;if(g=g&&g.match(b)){if(g[2]=="include")break;return g[1]}}return"../../dist/"}(),noConflict:function(){a.L=this._originalL;return this},_originalL:a.L};window.L=b})(this);L.Util={extend:function(a){for(var b=Array.prototype.slice.call(arguments,1),c=0,d=b.length,e;c<d;c++){e=b[c]||{};for(var f in e)e.hasOwnProperty(f)&&(a[f]=e[f])}return a},bind:function(a,b){return function(){return a.apply(b,arguments)}},stamp:function(){var a=0;return function(b){b._leaflet_id=b._leaflet_id||++a;return b._leaflet_id}}(),requestAnimFrame:function(){function a(a){window.setTimeout(a,1E3/60)}var b=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||
window.oRequestAnimationFrame||window.msRequestAnimationFrame||a;return function(c,d,e){c=d?L.Util.bind(c,d):d;e&&b===a?c():b(c)}}(),limitExecByInterval:function(a,b,c){function d(){e=!1;f&&(g.callee.apply(c,g),f=!1)}var e,f,g;return function(){g=arguments;e?f=!0:(e=!0,setTimeout(d,b),a.apply(c,g))}},falseFn:function(){return!1},formatNum:function(a,b){var c=Math.pow(10,b||5);return Math.round(a*c)/c},setOptions:function(a,b){a.options=L.Util.extend({},a.options,b)},getParamString:function(a){var b=
[],c;for(c in a)a.hasOwnProperty(c)&&b.push(c+"="+a[c]);return"?"+b.join("&")}};L.Class=function(){};
L.Class.extend=function(a){var b=function(){!L.Class._prototyping&&this.initialize&&this.initialize.apply(this,arguments)};L.Class._prototyping=!0;var c=new this;L.Class._prototyping=!1;c.constructor=b;b.prototype=c;c.superclass=this.prototype;a.statics&&(L.Util.extend(b,a.statics),delete a.statics);a.includes&&(L.Util.extend.apply(null,[c].concat(a.includes)),delete a.includes);if(a.options&&c.options)a.options=L.Util.extend({},c.options,a.options);L.Util.extend(c,a);b.extend=arguments.callee;b.include=
function(a){L.Util.extend(this.prototype,a)};for(var d in this)this.hasOwnProperty(d)&&d!="prototype"&&(b[d]=this[d]);return b};L.Mixin={};
L.Mixin.Events={addEventListener:function(a,b,c){var d=this._leaflet_events=this._leaflet_events||{};d[a]=d[a]||[];d[a].push({action:b,context:c});return this},hasEventListeners:function(a){return"_leaflet_events"in this&&a in this._leaflet_events&&this._leaflet_events[a].length>0},removeEventListener:function(a,b,c){if(!this.hasEventListeners(a))return this;for(var d=0,e=this._leaflet_events,f=e[a].length;d<f;d++)if(e[a][d].action===b&&(!c||e[a][d].context===c)){e[a].splice(d,1);break}return this},fireEvent:function(a,
b){if(this.hasEventListeners(a)){for(var c=L.Util.extend({type:a,target:this},b),d=this._leaflet_events[a].slice(),e=0,f=d.length;e<f;e++)d[e].action.call(d[e].context||this,c);return this}}};L.Mixin.Events.on=L.Mixin.Events.addEventListener;L.Mixin.Events.off=L.Mixin.Events.removeEventListener;L.Mixin.Events.fire=L.Mixin.Events.fireEvent;(function(){var a=navigator.userAgent.toLowerCase(),b=!!window.ActiveXObject,c=a.indexOf("webkit")!=-1,d=a.indexOf("mobi")!=-1,e=a.indexOf("android")!=-1,f=window.opera;L.Browser={ie:b,ie6:b&&!window.XMLHttpRequest,webkit:c,webkit3d:c&&"WebKitCSSMatrix"in window&&"m11"in new WebKitCSSMatrix,mobileWebkit:c&&(d||e),mobileOpera:d&&f,gecko:a.indexOf("gecko")!=-1,android:e};L.Browser.touch=L.Browser.mobileWebkit||L.Browser.mobileOpera})();L.Point=function(a,b,c){this.x=c?Math.round(a):a;this.y=c?Math.round(b):b};
L.Point.prototype={add:function(a){return this.clone()._add(a)},_add:function(a){this.x+=a.x;this.y+=a.y;return this},subtract:function(a){return this.clone()._subtract(a)},_subtract:function(a){this.x-=a.x;this.y-=a.y;return this},divideBy:function(a,b){return new L.Point(this.x/a,this.y/a,b)},multiplyBy:function(a){return new L.Point(this.x*a,this.y*a)},distanceTo:function(a){var b=a.x-this.x,a=a.y-this.y;return Math.sqrt(b*b+a*a)},round:function(){return this.clone()._round()},_round:function(){this.x=
Math.round(this.x);this.y=Math.round(this.y);return this},clone:function(){return new L.Point(this.x,this.y)},toString:function(){return"Point("+L.Util.formatNum(this.x)+", "+L.Util.formatNum(this.y)+")"}};L.Bounds=L.Class.extend({initialize:function(a,b){if(a)for(var c=a instanceof Array?a:[a,b],d=0,e=c.length;d<e;d++)this.extend(c[d])},extend:function(a){!this.min&&!this.max?(this.min=new L.Point(a.x,a.y),this.max=new L.Point(a.x,a.y)):(this.min.x=Math.min(a.x,this.min.x),this.max.x=Math.max(a.x,this.max.x),this.min.y=Math.min(a.y,this.min.y),this.max.y=Math.max(a.y,this.max.y))},getCenter:function(a){return new L.Point((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,a)},contains:function(a){var b;
if(a instanceof L.Bounds)b=a.min,a=a.max;return b.x>=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;f<g-1;f++)h=this._sqPointToSegmentDist(a[f],a[0],a[g-1]),h>c&&(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;e<g;e++)this._sqDist(a[e],a[f])<d||(c.push(a[e]),f=e);f<g-1&&c.push(a[g-1]);return c},clipSegment:function(a,b,c,d){var d=d?this._lastCode:this._getBitCode(a,c),e=this._getBitCode(b,c);for(this._lastCode=e;;)if(d|e)if(d&e)return!1;else{var f=d||e,g=this._getEdgeIntersection(a,b,f,c),h=this._getBitCode(g,c);f==d?(a=g,d=h):(b=g,e=h)}else return[a,b]},_getEdgeIntersection:function(a,b,c,d){var e=b.x-a.x,b=b.y-a.y,f=d.min,d=d.max;if(c&8)return new L.Point(a.x+e*(d.y-a.y)/
b,d.y);else if(c&4)return new L.Point(a.x+e*(f.y-a.y)/b,f.y);else if(c&2)return new L.Point(d.x,a.y+b*(d.x-a.x)/e);else if(c&1)return new L.Point(f.x,a.y+b*(f.x-a.x)/e)},_getBitCode:function(a,b){var c=0;a.x<b.min.x?c|=1:a.x>b.max.x&&(c|=2);a.y<b.min.y?c|=4:a.y>b.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;e<j;e++)a[e]._code=l._getBitCode(a[e],b);for(g=0;g<4;g++){k=d[g];c=[];e=0;j=a.length;for(f=j-1;e<j;f=e++)if(h=a[e],f=a[f],h._code&k){if(!(f._code&k))f=l._getEdgeIntersection(f,h,k,b),f._code=l._getBitCode(f,b),c.push(f)}else{if(f._code&k)f=l._getEdgeIntersection(f,h,k,b),f._code=l._getBitCode(f,b),c.push(f);c.push(h)}a=c}return a};L.DomEvent={addListener:function(a,b,c,d){function e(b){return c.call(d||a,b||L.DomEvent._getEvent())}var f=L.Util.stamp(c);if(L.Browser.touch&&b=="dblclick"&&this.addDoubleTapListener)this.addDoubleTapListener(a,e,f);else if("addEventListener"in a)if(b=="mousewheel")a.addEventListener("DOMMouseScroll",e,!1),a.addEventListener(b,e,!1);else if(b=="mouseenter"||b=="mouseleave"){var g=e,e=function(b){if(L.DomEvent._checkMouse(a,b))return g(b)};a.addEventListener(b=="mouseenter"?"mouseover":"mouseout",
e,!1)}else a.addEventListener(b,e,!1);else"attachEvent"in a&&a.attachEvent("on"+b,e);a["_leaflet_"+b+f]=e},removeListener:function(a,b,c){var c=L.Util.stamp(c),d="_leaflet_"+b+c;handler=a[d];L.Browser.mobileWebkit&&b=="dblclick"&&this.removeDoubleTapListener?this.removeDoubleTapListener(a,c):"removeEventListener"in a?b=="mousewheel"?(a.removeEventListener("DOMMouseScroll",handler,!1),a.removeEventListener(b,handler,!1)):b=="mouseenter"||b=="mouseleave"?a.removeEventListener(b=="mouseenter"?"mouseover":
"mouseout",handler,!1):a.removeEventListener(b,handler,!1):"detachEvent"in a&&a.detachEvent("on"+b,handler);a[d]=null},_checkMouse:function(a,b){var c=b.relatedTarget;if(!c)return!0;try{for(;c&&c!=a;)c=c.parentNode}catch(d){return!1}return c!=a},_getEvent:function(){var a=window.event;if(!a)for(var b=arguments.callee.caller;b;){if((a=b.arguments[0])&&Event==a.constructor)break;b=b.caller}return a},stopPropagation:function(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},disableClickPropagation:function(a){L.DomEvent.addListener(a,
"mousedown",L.DomEvent.stopPropagation);L.DomEvent.addListener(a,"click",L.DomEvent.stopPropagation);L.DomEvent.addListener(a,"dblclick",L.DomEvent.stopPropagation)},preventDefault:function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},stop:function(a){L.DomEvent.preventDefault(a);L.DomEvent.stopPropagation(a)},getMousePosition:function(a,b){var c=new L.Point(a.pageX?a.pageX:a.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,a.pageY?a.pageY:a.clientY+document.body.scrollTop+
document.documentElement.scrollTop);return b?c.subtract(L.DomUtil.getCumulativeOffset(b)):c},getWheelDelta:function(a){var b=0;a.wheelDelta&&(b=a.wheelDelta/120);a.detail&&(b=-a.detail/3);return b}};L.Util.extend(L.DomEvent,{addDoubleTapListener:function(a,b,c){function d(a){if(a.touches.length==1){var b=Date.now(),c=b-(f||b);j=a.touches[0];g=c>0&&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;c<a.length;c++)if(a[c]in b)return a[c];return!1},getTranslateString:function(a){return L.DomUtil.TRANSLATE_OPEN+a.x+"px,"+a.y+"px"+L.DomUtil.TRANSLATE_CLOSE},getScaleString:function(a,b){return L.DomUtil.getTranslateString(b)+" scale("+a+") "+L.DomUtil.getTranslateString(b.multiplyBy(-1))},setPosition:function(a,b){a._leaflet_pos=b;L.Browser.webkit?
a.style[L.DomUtil.TRANSFORM]=L.DomUtil.getTranslateString(b):(a.style.left=b.x+"px",a.style.top=b.y+"px")},getPosition:function(a){return a._leaflet_pos}};
L.Util.extend(L.DomUtil,{TRANSITION:L.DomUtil.testProp(["transition","webkitTransition","OTransition","MozTransition","msTransition"]),TRANSFORM:L.DomUtil.testProp(["transformProperty","WebkitTransform","OTransform","MozTransform","msTransform"]),TRANSLATE_OPEN:"translate"+(L.Browser.webkit3d?"3d(":"("),TRANSLATE_CLOSE:L.Browser.webkit3d?",0)":")"});L.Draggable=L.Class.extend({includes:L.Mixin.Events,statics:{START:L.Browser.touch?"touchstart":"mousedown",END:L.Browser.touch?"touchend":"mouseup",MOVE:L.Browser.touch?"touchmove":"mousemove",TAP_TOLERANCE:15},initialize:function(a,b){this._element=a;this._dragStartTarget=b||a},enable:function(){if(!this._enabled)L.DomEvent.addListener(this._dragStartTarget,L.Draggable.START,this._onDown,this),this._enabled=!0},disable:function(){if(this._enabled)L.DomEvent.removeListener(this._dragStartTarget,
L.Draggable.START,this._onDown),this._enabled=!1},_onDown:function(a){if(!(a.shiftKey||a.which!=1&&a.button!=1&&!a.touches)&&!(a.touches&&a.touches.length>1)){var b=a.touches&&a.touches.length==1?a.touches[0]:a;L.DomEvent.preventDefault(a);L.Browser.mobileWebkit&&(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<L.Draggable.TAP_TOLERANCE&&this._simulateEvent("click",a)}L.DomUtil.enableTextSelection();this._restoreCursor();L.DomEvent.removeListener(document,L.Draggable.MOVE,this._onMove);L.DomEvent.removeListener(document,L.Draggable.END,this._onUp);this._moved&&this.fire("dragend")},_removeActiveClass:function(){},
_setMovingCursor:function(){this._bodyCursor=document.body.style.cursor;document.body.style.cursor="move"},_restoreCursor:function(){document.body.style.cursor=this._bodyCursor},_simulateEvent:function(a,b){var c=document.createEvent("MouseEvent");c.initMouseEvent(a,!0,!0,window,1,b.screenX,b.screenY,b.clientX,b.clientY,!1,!1,!1,!1,0,null);b.target.dispatchEvent(c)}});L.Transition=L.Class.extend({includes:L.Mixin.Events,statics:{CUSTOM_PROPS_SETTERS:{position:L.DomUtil.setPosition},implemented:function(){return L.Transition.NATIVE||L.Transition.TIMER}},options:{easing:"ease",duration:0.5},_setProperty:function(a,b){var c=L.Transition.CUSTOM_PROPS_SETTERS;if(a in c)c[a](this._el,b);else this._el.style[a]=b}});L.Transition=L.Transition.extend({statics:function(){var a=L.DomUtil.TRANSITION;return{NATIVE:!!a,TRANSITION:a,PROPERTY:a+"Property",DURATION:a+"Duration",EASING:a+"TimingFunction",END:a=="webkitTransition"||a=="OTransition"?a+"End":"transitionend",CUSTOM_PROPS_PROPERTIES:{position:L.Browser.webkit?L.DomUtil.TRANSFORM:"top, left"}}}(),options:{fakeStepInterval:100},initialize:function(a,b){this._el=a;L.Util.setOptions(this,b);L.DomEvent.addListener(a,L.Transition.END,this._onTransitionEnd,this);this._onFakeStep=
L.Util.bind(this._onFakeStep,this)},run:function(a){var b,c=[],d=L.Transition.CUSTOM_PROPS_PROPERTIES;for(b in a)a.hasOwnProperty(b)&&(b=d[b]?d[b]:b,b=b.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()}),c.push(b));this._el.style[L.Transition.DURATION]=this.options.duration+"s";this._el.style[L.Transition.EASING]=this.options.easing;this._el.style[L.Transition.PROPERTY]=c.join(", ");for(b in a)a.hasOwnProperty(b)&&this._setProperty(b,a[b]);this._inProgress=!0;this.fire("start");L.Transition.NATIVE?
this._timer=setInterval(this._onFakeStep,this.options.fakeStepInterval):this._onTransitionEnd()},_onFakeStep:function(){this.fire("step")},_onTransitionEnd:function(){if(this._inProgress)this._inProgress=!1,clearInterval(this._timer),this._el.style[L.Transition.PROPERTY]="none",this.fire("step"),this.fire("end")}});L.Transition=L.Transition.NATIVE?L.Transition:L.Transition.extend({statics:{getTime:Date.now||function(){return+new Date},TIMER:!0,EASINGS:{ease:[0.25,0.1,0.25,1],linear:[0,0,1,1],"ease-in":[0.42,0,1,1],"ease-out":[0,0,0.58,1],"ease-in-out":[0.42,0,0.58,1]},CUSTOM_PROPS_GETTERS:{position:L.DomUtil.getPosition},UNIT_RE:/^[\d\.]+(\D*)$/},options:{fps:50},initialize:function(a,b){this._el=a;L.Util.extend(this.options,b);var c=L.Transition.EASINGS[this.options.easing]||L.Transition.EASINGS.ease;this._p1=
new L.Point(0,0);this._p2=new L.Point(c[0],c[1]);this._p3=new L.Point(c[2],c[3]);this._p4=new L.Point(1,1);this._step=L.Util.bind(this._step,this);this._interval=Math.round(1E3/this.options.fps)},run:function(a){this._props={};var b=L.Transition.CUSTOM_PROPS_GETTERS,c=L.Transition.UNIT_RE;this.fire("start");for(var d in a)if(a.hasOwnProperty(d)){var e={};if(d in b)e.from=b[d](this._el);else{var f=this._el.style[d].match(c);e.from=parseFloat(f[0]);e.unit=f[1]}e.to=a[d];this._props[d]=e}clearInterval(this._timer);
this._timer=setInterval(this._step,this._interval);this._startTime=L.Transition.getTime()},_step:function(){var a=L.Transition.getTime()-this._startTime,b=this.options.duration*1E3;a<b?this._runFrame(this._cubicBezier(a/b)):(this._runFrame(1),this._complete())},_runFrame:function(a){var b=L.Transition.CUSTOM_PROPS_SETTERS,c,d;for(c in this._props)this._props.hasOwnProperty(c)&&(d=this._props[c],c in b?(d=d.to.subtract(d.from).multiplyBy(a).add(d.from),b[c](this._el,d)):this._el.style[c]=(d.to-d.from)*
a+d.from+d.unit);this.fire("step")},_complete:function(){clearInterval(this._timer);this.fire("end")},_cubicBezier:function(a){var b=3*Math.pow(1-a,2)*a,c=3*(1-a)*Math.pow(a,2),d=Math.pow(a,3),a=this._p1.multiplyBy(Math.pow(1-a,3)),b=this._p2.multiplyBy(b),c=this._p3.multiplyBy(c),d=this._p4.multiplyBy(d);return a.add(b).add(c).add(d).y}});L.LatLng=function(a,b,c){c!==!0&&(a=Math.max(Math.min(a,90),-90),b=(b+180)%360+(b<-180?180:-180));this.lat=a;this.lng=b};L.Util.extend(L.LatLng,{DEG_TO_RAD:Math.PI/180,RAD_TO_DEG:180/Math.PI,MAX_MARGIN:1.0E-9});L.LatLng.prototype={equals:function(a){if(!(a instanceof L.LatLng))return!1;return Math.max(Math.abs(this.lat-a.lat),Math.abs(this.lng-a.lng))<=L.LatLng.MAX_MARGIN},toString:function(){return"LatLng("+L.Util.formatNum(this.lat)+", "+L.Util.formatNum(this.lng)+")"}};L.LatLngBounds=L.Class.extend({initialize:function(a,b){if(a)for(var c=a instanceof Array?a:[a,b],d=0,e=c.length;d<e;d++)this.extend(c[d])},extend:function(a){!this._southWest&&!this._northEast?(this._southWest=new L.LatLng(a.lat,a.lng),this._northEast=new L.LatLng(a.lat,a.lng)):(this._southWest.lat=Math.min(a.lat,this._southWest.lat),this._southWest.lng=Math.min(a.lng,this._southWest.lng),this._northEast.lat=Math.max(a.lat,this._northEast.lat),this._northEast.lng=Math.max(a.lng,this._northEast.lng))},
getCenter:function(){return new L.LatLng((this._southWest.lat+this._northEast.lat)/2,(this._southWest.lng+this._northEast.lng)/2)},getSouthWest:function(){return this._southWest},getNorthEast:function(){return this._northEast},getNorthWest:function(){return new L.LatLng(this._northEast.lat,this._southWest.lng)},getSouthEast:function(){return new L.LatLng(this._southWest.lat,this._northEast.lng)},contains:function(a){var b=this._southWest,c=this._northEast,d;a instanceof L.LatLngBounds?(d=a.getSouthWest(),
a=a.getNorthEast()):d=a;return d.lat>=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;b<c;b++)this.addLayer(a[b])},addLayer:function(a){this._layers[L.Util.stamp(a)]=a;this._map&&this._map.addLayer(a);return this},removeLayer:function(a){delete this._layers[L.Util.stamp(a)];this._map&&this._map.removeLayer(a);return this},clearLayers:function(){this._iterateLayers(this.removeLayer,this);return this},onAdd:function(a){this._map=a;this._iterateLayers(a.addLayer,a)},onRemove:function(a){this._iterateLayers(a.removeLayer,
a);delete this._map},_iterateLayers:function(a,b){for(var c in this._layers)this._layers.hasOwnProperty(c)&&a.call(b,this._layers[c])}});L.FeatureGroup=L.LayerGroup.extend({includes:L.Mixin.Events,addLayer:function(a){this._initEvents(a);L.LayerGroup.prototype.addLayer.call(this,a);this._popupContent&&a.bindPopup&&a.bindPopup(this._popupContent)},bindPopup:function(a){this._popupContent=a;for(var b in this._layers)this._layers.hasOwnProperty(b)&&this._layers[b].bindPopup&&this._layers[b].bindPopup(a)},_events:["click","dblclick","mouseover","mouseout"],_initEvents:function(a){for(var b=0,c=this._events.length;b<c;b++)a.on(this._events[b],
this._propagateEvent,this)},_propagateEvent:function(a){a.layer=a.target;a.target=this;this.fire(a.type,a)}});L.TileLayer=L.Class.extend({includes:L.Mixin.Events,options:{minZoom:0,maxZoom:18,tileSize:256,subdomains:"abc",errorTileUrl:"",attribution:"",opacity:1,scheme:"xyz",noWrap:!1,unloadInvisibleTiles:L.Browser.mobileWebkit,updateWhenIdle:L.Browser.mobileWebkit},initialize:function(a,b){L.Util.setOptions(this,b);this._url=a;if(typeof this.options.subdomains=="string")this.options.subdomains=this.options.subdomains.split("")},onAdd:function(a){this._map=a;this._initContainer();this._createTileProto();
a.on("viewreset",this._reset,this);if(this.options.updateWhenIdle)a.on("moveend",this._update,this);else this._limitedUpdate=L.Util.limitExecByInterval(this._update,100,this),a.on("move",this._limitedUpdate,this);this._reset();this._update()},onRemove:function(){this._map.getPanes().tilePane.removeChild(this._container);this._container=null;this._map.off("viewreset",this._reset,this);this.options.updateWhenIdle?this._map.off("moveend",this._update,this):this._map.off("move",this._limitedUpdate,this)},
getAttribution:function(){return this.options.attribution},setOpacity:function(a){this.options.opacity=a;this._setOpacity(a);if(L.Browser.webkit)for(i in this._tiles)this._tiles[i].style.webkitTransform+=" translate(0,0)"},_setOpacity:function(a){a<1&&L.DomUtil.setOpacity(this._container,a)},_initContainer:function(){var a=this._map.getPanes().tilePane;if(!this._container||a.empty)this._container=L.DomUtil.create("div","leaflet-layer",a),this._setOpacity(this.options.opacity)},_reset:function(){this._tiles=
{};this._initContainer();this._container.innerHTML=""},_update:function(){var a=this._map.getPixelBounds(),b=this.options.tileSize,c=new L.Point(Math.floor(a.min.x/b),Math.floor(a.min.y/b)),a=new L.Point(Math.floor(a.max.x/b),Math.floor(a.max.y/b)),c=new L.Bounds(c,a);this._addTilesFromCenterOut(c);this.options.unloadInvisibleTiles&&this._removeOtherTiles(c)},_addTilesFromCenterOut:function(a){for(var b=[],c=a.getCenter(),d=a.min.y;d<=a.max.y;d++)for(var e=a.min.x;e<=a.max.x;e++)e+":"+d in this._tiles||
b.push(new L.Point(e,d));b.sort(function(a,b){return a.distanceTo(c)-b.distanceTo(c)});this._tilesToLoad=b.length;a=0;for(d=this._tilesToLoad;a<d;a++)this._addTile(b[a])},_removeOtherTiles:function(a){var b,c,d;for(d in this._tiles)if(this._tiles.hasOwnProperty(d)&&(b=d.split(":"),c=parseInt(b[0],10),b=parseInt(b[1],10),c<a.min.x||c>a.max.x||b<a.min.y||b>a.max.y))this._tiles[d].src="",this._tiles[d].parentNode==this._container&&this._container.removeChild(this._tiles[d]),delete this._tiles[d]},_addTile:function(a){var b=
this._getTilePos(a),c=this._map.getZoom(),d=a.x+":"+a.y,e=1<<c;if(!this.options.noWrap)a.x=(a.x%e+e)%e;if(!(a.y<0||a.y>=e)){var f=this._createTile();L.DomUtil.setPosition(f,b);this._tiles[d]=f;if(this.options.scheme=="tms")a.y=e-a.y-1;this._loadTile(f,a,c);this._container.appendChild(f)}},_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");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.length;b++)L.DomEvent.addListener(this._icon,a[b],this._fireMouseEvent,this)}if(L.Handler.MarkerDrag)this.dragging=
new L.Handler.MarkerDrag(this),this.options.draggable&&this.dragging.enable()},_onMouseClick:function(a){L.DomEvent.stopPropagation(a);(!this.dragging||!this.dragging.moved())&&this.fire(a.type)},_fireMouseEvent:function(a){this.fire(a.type);L.DomEvent.stopPropagation(a)}});L.Marker.include({openPopup:function(){this._popup.setLatLng(this._latlng);this._map.openPopup(this._popup);return this},closePopup:function(){this._popup&&this._popup._close()},bindPopup:function(a,b){b=L.Util.extend({offset:this.options.icon.popupAnchor},b);this._popup=new L.Popup(b);this._popup.setContent(a);this.on("click",this.openPopup,this);return this}});L.Path=L.Class.extend({includes:[L.Mixin.Events],statics:function(){return{SVG_NS:"http://www.w3.org/2000/svg",SVG:!(!document.createElementNS||!document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect),CLIP_PADDING:0.5}}(),options:{stroke:!0,color:"#0033ff",weight:5,opacity:0.5,fill:!1,fillColor:null,fillOpacity:0.2,clickable:!0,updateOnMoveEnd:!1},initialize:function(a){L.Util.setOptions(this,a)},onAdd:function(a){this._map=a;this._initElements();this._initEvents();this.projectLatlngs();
this._updatePath();a.on("viewreset",this.projectLatlngs,this);this._updateTrigger=this.options.updateOnMoveEnd?"moveend":"viewreset";a.on(this._updateTrigger,this._updatePath,this)},onRemove:function(a){a._pathRoot.removeChild(this._container);a.off("viewreset",this._projectLatlngs,this);a.off(this._updateTrigger,this._updatePath,this)},projectLatlngs:function(){},getPathString:function(){},setStyle:function(a){L.Util.setOptions(this,a);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 a=this._map._pathViewport,b=a.min,c=a.max,a=c.x-b.x,c=c.y-b.y,d=this._map._pathRoot,e=this._map._panes.overlayPane;L.Browser.mobileWebkit&&e.removeChild(d);L.DomUtil.setPosition(d,
b);d.setAttribute("width",a);d.setAttribute("height",c);d.setAttribute("viewBox",[b.x,b.y,a,c].join(" "));L.Browser.mobileWebkit&&e.appendChild(d)},_updateViewport:function(){var a=L.Path.CLIP_PADDING,b=this._map.getSize(),c=L.DomUtil.getPosition(this._map._mapPane).multiplyBy(-1).subtract(b.multiplyBy(a)),a=c.add(b.multiplyBy(1+a*2));this._map._pathViewport=new L.Bounds(c,a)},_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(){this.options.stroke&&(this._path.setAttribute("stroke-linejoin","round"),this._path.setAttribute("stroke-linecap","round"));this.options.fill?this._path.setAttribute("fill-rule","evenodd"):this._path.setAttribute("fill","none");this._updateStyle()},_updateStyle:function(){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));this.options.fill&&(this._path.setAttribute("fill",this.options.fillColor||this.options.color),this._path.setAttribute("fill-opacity",this.options.fillOpacity))},_updatePath:function(){var a=this.getPathString();a||(a="M0 0");this._path.setAttribute("d",a)},_createElement:function(a){return document.createElementNS(L.Path.SVG_NS,a)},_initEvents:function(){if(this.options.clickable){L.Path.VML||this._path.setAttribute("class","leaflet-clickable");L.DomEvent.addListener(this._container,
"click",this._onMouseClick,this);for(var a=["dblclick","mousedown","mouseover","mouseout"],b=0;b<a.length;b++)L.DomEvent.addListener(this._container,a[b],this._fireMouseEvent,this)}},_onMouseClick:function(a){(!this._map.dragging||!this._map.dragging.moved())&&this._fireMouseEvent(a)},_fireMouseEvent:function(a){this.hasEventListeners(a.type)&&(this.fire(a.type,{latlng:this._map.mouseEventToLatLng(a),layerPoint:this._map.mouseEventToLayerPoint(a)}),L.DomEvent.stopPropagation(a))},_redraw:function(){this.projectLatlngs();
this._updatePath()}});L.Path.VML=function(){var a=document.createElement("div");a.innerHTML='<v:shape adj="1"/>';a=a.firstChild;a.style.behavior="url(#default#VML)";return a&&typeof a.adj=="object"}();
L.Path=L.Path.SVG||!L.Path.VML?L.Path:L.Path.extend({statics:{CLIP_PADDING:0.02},_createElement:function(){try{return document.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(a){return document.createElement("<lvml:"+a+' class="lvml">')}}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.Path.include({bindPopup:function(a,b){if(!this._popup||this._popup.options!==b)this._popup=new L.Popup(b);this._popup.setContent(a);if(!this._openPopupAdded)this.on("click",this._openPopup,this),this._openPopupAdded=!0;return this},_openPopup:function(a){this._popup.setLatLng(a.latlng);this._map.openPopup(this._popup)}});L.Polyline=L.Path.extend({initialize:function(a,b){L.Path.prototype.initialize.call(this,b);this._latlngs=a},options:{smoothFactor:1,noClip:!1,updateOnMoveEnd:!0},projectLatlngs:function(){this._originalPoints=[];for(var a=0,b=this._latlngs.length;a<b;a++)this._originalPoints[a]=this._map.latLngToLayerPoint(this._latlngs[a])},getPathString:function(){for(var a=0,b=this._parts.length,c="";a<b;a++)c+=this._getPathPartStr(this._parts[a]);return c},getLatLngs:function(){return this._latlngs},setLatLngs:function(a){this._latlngs=
a;this._redraw();return this},addLatLng:function(a){this._latlngs.push(a);this._redraw();return this},spliceLatLngs:function(){var a=[].splice.apply(this._latlngs,arguments);this._redraw();return a},_getPathPartStr:function(a){for(var b=L.Path.VML,c=0,d=a.length,e="",f;c<d;c++)f=a[c],b&&f._round(),e+=(c?"L":"M")+f.x+" "+f.y;return e},_clipPoints:function(){var a=this._originalPoints,b=a.length,c,d,e;if(this.options.noClip)this._parts=[a];else{var f=this._parts=[],g=this._map._pathViewport,h=L.LineUtil;
for(d=c=0;c<b-1;c++)if(e=h.clipSegment(a[c],a[c+1],g,c))if(f[d]=f[d]||[],f[d].push(e[0]),e[1]!=a[c+1]||c==b-2)f[d].push(e[1]),d++}},_simplifyPoints:function(){for(var a=this._parts,b=L.LineUtil,c=0,d=a.length;c<d;c++)a[c]=b.simplify(a[c],this.options.smoothFactor)},_updatePath:function(){this._clipPoints();this._simplifyPoints();L.Path.prototype._updatePath.call(this)}});L.Polygon=L.Polyline.extend({options:{fill:!0},initialize:function(a,b){L.Polyline.prototype.initialize.call(this,a,b);if(a[0]instanceof Array)this._latlngs=a[0],this._holes=a.slice(1)},projectLatlngs:function(){L.Polyline.prototype.projectLatlngs.call(this);this._holePoints=[];if(this._holes)for(var a=0,b=this._holes.length;a<b;a++){this._holePoints[a]=[];for(var c=0,d=this._holes[a].length;c<d;c++)this._holePoints[a][c]=this._map.latLngToLayerPoint(this._holes[a][c])}},_clipPoints:function(){var a=
[];this._parts=[this._originalPoints].concat(this._holePoints);if(!this.options.noClip){for(var b=0,c=this._parts.length;b<c;b++){var d=L.PolyUtil.clipPolygon(this._parts[b],this._map._pathViewport);d.length&&a.push(d)}this._parts=a}},_getPathPartStr:function(a){return L.Polyline.prototype._getPathPartStr.call(this,a)+(L.Path.SVG?"z":"x")}});(function(){function a(a){return L.FeatureGroup.extend({initialize:function(c,d){this._layers={};for(var e=0,f=c.length;e<f;e++)this.addLayer(new a(c[e],d))},setStyle:function(a){for(var b in this._layers)this._layers.hasOwnProperty(b)&&this._layers[b].setStyle&&this._layers[b].setStyle(a)}})}L.MultiPolyline=a(L.Polyline);L.MultiPolygon=a(L.Polygon)})();L.Circle=L.Path.extend({initialize:function(a,b,c){L.Path.prototype.initialize.call(this,c);this._latlng=a;this._mRadius=b},options:{fill:!0},setLatLng:function(a){this._latlng=a;this._redraw();return this},setRadius:function(a){this._mRadius=a;this._redraw();return this},projectLatlngs:function(){var a=this._map.options.scale(this._map._zoom);this._point=this._map.latLngToLayerPoint(this._latlng);this._radius=this._mRadius/40075017*a},getPathString:function(){var a=this._point,b=this._radius;return L.Path.SVG?
"M"+a.x+","+(a.y-b)+"A"+b+","+b+",0,1,1,"+(a.x-0.1)+","+(a.y-b)+" z":(a._round(),b=Math.round(b),"AL "+a.x+","+a.y+" "+b+","+b+" 0,23592600")}});L.CircleMarker=L.Circle.extend({options:{radius:10,weight:2},initialize:function(a,b){L.Circle.prototype.initialize.call(this,a,null,b);this._radius=this.options.radius},projectLatlngs:function(){this._point=this._map.latLngToLayerPoint(this._latlng)},setRadius:function(a){this._radius=a;this._redraw();return this}});L.GeoJSON=L.LayerGroup.extend({includes:L.Mixin.Events,initialize:function(a,b){L.Util.setOptions(this,b);this._geojson=a;this._layers={};a&&this.addGeoJSON(a)},addGeoJSON:function(a){if(a.features)for(var b=0,c=a.features.length;b<c;b++)this.addGeoJSON(a.features[b]);else b=a.type=="Feature"?a.geometry:a,c=L.GeoJSON.geometryToLayer(b,this.options.pointToLayer),this.fire("featureparse",{layer:c,properties:a.properties,geometryType:b.type,bbox:a.bbox,id:a.id}),this.addLayer(c)}});
L.Util.extend(L.GeoJSON,{geometryToLayer:function(a,b){var c=a.coordinates,d,e,f,g=[];switch(a.type){case "Point":return d=this.coordsToLatLng(c),b?b(d):new L.Marker(d);case "MultiPoint":e=0;for(f=c.length;e<f;e++)d=this.coordsToLatLng(c[e]),d=b?b(d):new L.Marker(d),g.push(d);return new L.FeatureGroup(g);case "LineString":return c=this.coordsToLatLngs(c),new L.Polyline(c);case "Polygon":return c=this.coordsToLatLngs(c,1),new L.Polygon(c);case "MultiLineString":return c=this.coordsToLatLngs(c,1),new L.MultiPolyline(c);
case "MultiPolygon":return c=this.coordsToLatLngs(c,2),new L.MultiPolygon(c);case "GeometryCollection":e=0;for(f=a.geometries.length;e<f;e++)d=this.geometryToLayer(a.geometries[e]),g.push(d);return new L.FeatureGroup(g);default:throw Error("Invalid GeoJSON object.");}},coordsToLatLng:function(a,b){var c=parseFloat(a[b?0:1]),d=parseFloat(a[b?1:0]);return new L.LatLng(c,d)},coordsToLatLngs:function(a,b,c){var d,e=[],f,g=a.length;for(f=0;f<g;f++)d=b?this.coordsToLatLngs(a[f],b-1,c):this.coordsToLatLng(a[f],
c),e.push(d);return e}});L.Handler=L.Class.extend({initialize:function(a){this._map=a},enabled:function(){return!!this._enabled}});L.Handler.MapDrag=L.Handler.extend({enable:function(){if(!this._enabled){if(!this._draggable)this._draggable=new L.Draggable(this._map._mapPane,this._map._container),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._moved},_onDragStart:function(){this._map.fire("movestart");
this._map.fire("dragstart")},_onDrag:function(){this._map.fire("move");this._map.fire("drag")},_onDragEnd:function(){this._map.fire("moveend");this._map.fire("dragend")}});L.Handler.TouchZoom=L.Handler.extend({enable:function(){if(L.Browser.mobileWebkit&&!this._enabled)L.DomEvent.addListener(this._map._container,"touchstart",this._onTouchStart,this),this._enabled=!0},disable:function(){if(this._enabled)L.DomEvent.removeListener(this._map._container,"touchstart",this._onTouchStart,this),this._enabled=!1},_onTouchStart:function(a){if(a.touches&&!(a.touches.length!=2||this._map._animatingZoom)){var b=this._map.mouseEventToLayerPoint(a.touches[0]),c=this._map.mouseEventToLayerPoint(a.touches[1]),
d=this._map.containerPointToLayerPoint(this._map.getSize().divideBy(2));this._startCenter=b.add(c).divideBy(2,!0);this._startDist=b.distanceTo(c);this._moved=!1;this._zooming=!0;this._centerOffset=d.subtract(this._startCenter);L.DomEvent.addListener(document,"touchmove",this._onTouchMove,this);L.DomEvent.addListener(document,"touchend",this._onTouchEnd,this);L.DomEvent.preventDefault(a)}},_onTouchMove:function(a){if(a.touches&&a.touches.length==2){if(!this._moved)this._map._mapPane.className+=" leaflet-zoom-anim",
this._map._prepareTileBg(),this._moved=!0;var b=this._map.mouseEventToLayerPoint(a.touches[0]),c=this._map.mouseEventToLayerPoint(a.touches[1]);this._scale=b.distanceTo(c)/this._startDist;this._delta=b.add(c).divideBy(2,!0).subtract(this._startCenter);this._map._tileBg.style.webkitTransform=[L.DomUtil.getTranslateString(this._delta),L.DomUtil.getScaleString(this._scale,this._startCenter)].join(" ");L.DomEvent.preventDefault(a)}},_onTouchEnd:function(){if(this._moved&&this._zooming){this._zooming=
!1;var a=this._map.getZoom(),b=Math.log(this._scale)/Math.LN2,b=this._map._limitZoom(a+(b>0?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);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 <a href="http://leaflet.cloudmade.com">Leaflet</a>';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(" &mdash; ")}}});L.Map=L.Class.extend({includes:L.Mixin.Events,options:{crs:L.CRS.EPSG3857||L.CRS.EPSG4326,scale:function(a){return 256*(1<<a)},center:null,zoom:null,layers:[],dragging:!0,touchZoom:L.Browser.mobileWebkit&&!L.Browser.android,scrollWheelZoom:!L.Browser.mobileWebkit,doubleClickZoom:!0,shiftDragZoom:!0,zoomControl:!0,attributionControl:!0,fadeAnimation:L.DomUtil.TRANSITION&&!L.Browser.android,zoomAnimation:L.DomUtil.TRANSITION&&!L.Browser.android&&!L.Browser.mobileOpera,trackResize:!0,closePopupOnClick:!0},
initialize:function(a,b){L.Util.setOptions(this,b);this._container=L.DomUtil.get(a);this._initLayout();L.DomEvent&&(this._initEvents(),L.Handler&&this._initInteraction(),L.Control&&this._initControls());var c=this.options.center,d=this.options.zoom;c!==null&&d!==null&&this.setView(c,d,!0);c=this.options.layers;c=c instanceof Array?c:[c];this._tileLayersNum=0;this._initLayers(c)},setView:function(a,b){this._resetView(a,this._limitZoom(b));return this},setZoom:function(a){return this.setView(this.getCenter(),
a)},zoomIn:function(){return this.setZoom(this._zoom+1)},zoomOut:function(){return this.setZoom(this._zoom-1)},fitBounds:function(a){var b=this.getBoundsZoom(a);return this.setView(a.getCenter(),b)},fitWorld:function(){var a=new L.LatLng(-60,-170),b=new L.LatLng(85,179);return this.fitBounds(new L.LatLngBounds(a,b))},panTo:function(a){return this.setView(a,this._zoom)},panBy:function(a){this.fire("movestart");this._rawPanBy(a);this.fire("move");this.fire("moveend");return this},addLayer:function(a){var b=
L.Util.stamp(a);if(this._layers[b])return this;this._layers[b]=a;if(a.options&&!isNaN(a.options.maxZoom))this._layersMaxZoom=Math.max(this._layersMaxZoom||0,a.options.maxZoom);if(a.options&&!isNaN(a.options.minZoom))this._layersMinZoom=Math.min(this._layersMinZoom||Infinity,a.options.minZoom);this.options.zoomAnimation&&L.TileLayer&&a instanceof L.TileLayer&&(this._tileLayersNum++,a.on("load",this._onTileLayerLoad,this));this.attributionControl&&a.getAttribution&&this.attributionControl.addAttribution(a.getAttribution());
b=function(){a.onAdd(this);this.fire("layeradd",{layer:a})};if(this._loaded)b.call(this);else this.on("load",b,this);return this},removeLayer:function(a){var b=L.Util.stamp(a);this._layers[b]&&(a.onRemove(this),delete this._layers[b],this.options.zoomAnimation&&L.TileLayer&&a instanceof L.TileLayer&&(this._tileLayersNum--,a.off("load",this._onTileLayerLoad,this)),this.attributionControl&&a.getAttribution&&this.attributionControl.removeAttribution(a.getAttribution()),this.fire("layerremove",{layer:a}));
return this},invalidateSize:function(){this._sizeChanged=!0;this.fire("move");clearTimeout(this._sizeTimer);this._sizeTimer=setTimeout(L.Util.bind(function(){this.fire("moveend")},this),200);return this},getCenter:function(a){var b=this.getSize().divideBy(2);return this.unproject(this._getTopLeftPoint().add(b),this._zoom,a)},getZoom:function(){return this._zoom},getBounds:function(){var a=this.getPixelBounds(),b=this.unproject(new L.Point(a.min.x,a.max.y)),a=this.unproject(new L.Point(a.max.x,a.min.y));
return new L.LatLngBounds(b,a)},getMinZoom:function(){return isNaN(this.options.minZoom)?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return isNaN(this.options.maxZoom)?this._layersMaxZoom||Infinity:this.options.maxZoom},getBoundsZoom:function(a){var b=this.getSize(),c=this.getMinZoom(),d=this.getMaxZoom(),e=a.getNorthEast(),a=a.getSouthWest(),f,g;do c++,f=this.project(e,c),g=this.project(a,c),f=new L.Point(f.x-g.x,g.y-f.y);while(f.x<=b.x&&f.y<=b.y&&c<=d);return c-1},getSize:function(){if(!this._size||
this._sizeChanged)this._size=new L.Point(this._container.clientWidth,this._container.clientHeight),this._sizeChanged=!1;return this._size},getPixelBounds:function(){var a=this._getTopLeftPoint(),b=this.getSize();return new L.Bounds(a,a.add(b))},getPixelOrigin:function(){return this._initialTopLeftPoint},getPanes:function(){return this._panes},mouseEventToContainerPoint:function(a){return L.DomEvent.getMousePosition(a,this._container)},mouseEventToLayerPoint:function(a){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(a))},
mouseEventToLatLng:function(a){return this.layerPointToLatLng(this.mouseEventToLayerPoint(a))},containerPointToLayerPoint:function(a){return a.subtract(L.DomUtil.getPosition(this._mapPane))},layerPointToContainerPoint:function(a){return a.add(L.DomUtil.getPosition(this._mapPane))},layerPointToLatLng:function(a){return this.unproject(a.add(this._initialTopLeftPoint))},latLngToLayerPoint:function(a){return this.project(a)._subtract(this._initialTopLeftPoint)},project:function(a,b){b=typeof b=="undefined"?
this._zoom:b;return this.options.crs.latLngToPoint(a,this.options.scale(b))},unproject:function(a,b,c){b=typeof b=="undefined"?this._zoom:b;return this.options.crs.pointToLatLng(a,this.options.scale(b),c)},_initLayout:function(){var a=this._container;a.className+=" leaflet-container";this.options.fadeAnimation&&(a.className+=" leaflet-fade-anim");var b=L.DomUtil.getStyle(a,"position");if(b!="absolute"&&b!="relative")a.style.position="relative";this._initPanes();this._initControlPos&&this._initControlPos()},
_initPanes:function(){var a=this._panes={};this._mapPane=a.mapPane=this._createPane("leaflet-map-pane",this._container);this._tilePane=a.tilePane=this._createPane("leaflet-tile-pane",this._mapPane);this._objectsPane=a.objectsPane=this._createPane("leaflet-objects-pane",this._mapPane);a.shadowPane=this._createPane("leaflet-shadow-pane");a.overlayPane=this._createPane("leaflet-overlay-pane");a.markerPane=this._createPane("leaflet-marker-pane");a.popupPane=this._createPane("leaflet-popup-pane")},_createPane:function(a,
b){return L.DomUtil.create("div",a,b||this._objectsPane)},_resetView:function(a,b,c){var d=this._zoom!=b;this.fire("movestart");this._zoom=b;this._initialTopLeftPoint=this._getNewTopLeftPoint(a);c?this._initialTopLeftPoint._add(L.DomUtil.getPosition(this._mapPane)):L.DomUtil.setPosition(this._mapPane,new L.Point(0,0));this._tileLayersToLoad=this._tileLayersNum;this.fire("viewreset");this.fire("move");d&&this.fire("zoomend");this.fire("moveend");if(!this._loaded)this._loaded=!0,this.fire("load")},
_initLayers:function(a){this._layers={};for(var b=0,c=a.length;b<c;b++)this.addLayer(a[b])},_initControls:function(){this.options.zoomControl&&this.addControl(new L.Control.Zoom);if(this.options.attributionControl)this.attributionControl=new L.Control.Attribution,this.addControl(this.attributionControl)},_rawPanBy:function(a){var b=L.DomUtil.getPosition(this._mapPane);L.DomUtil.setPosition(this._mapPane,b.subtract(a))},_initEvents:function(){L.DomEvent.addListener(this._container,"click",this._onMouseClick,
this);for(var a=["dblclick","mousedown","mouseenter","mouseleave","mousemove"],b=0;b<a.length;b++)L.DomEvent.addListener(this._container,a[b],this._fireMouseEvent,this);this.options.trackResize&&L.DomEvent.addListener(window,"resize",this.invalidateSize,this)},_onMouseClick:function(a){if(!this.dragging||!this.dragging.moved())this.fire("pre"+a.type),this._fireMouseEvent(a)},_fireMouseEvent:function(a){var b=a.type,b=b=="mouseenter"?"mouseover":b=="mouseleave"?"mouseout":b;this.hasEventListeners(b)&&
this.fire(b,{latlng:this.mouseEventToLatLng(a),layerPoint:this.mouseEventToLayerPoint(a)})},_initInteraction:function(){var a={dragging:L.Handler.MapDrag,touchZoom:L.Handler.TouchZoom,doubleClickZoom:L.Handler.DoubleClickZoom,scrollWheelZoom:L.Handler.ScrollWheelZoom,shiftDragZoom:L.Handler.ShiftDragZoom},b;for(b in a)a.hasOwnProperty(b)&&a[b]&&(this[b]=new a[b](this),this.options[b]&&this[b].enable())},_onTileLayerLoad:function(){this._tileLayersToLoad--;if(this._tileLayersNum&&!this._tileLayersToLoad&&
this._tileBg)clearTimeout(this._clearTileBgTimer),this._clearTileBgTimer=setTimeout(L.Util.bind(this._clearTileBg,this),500)},_getTopLeftPoint:function(){if(!this._loaded)throw Error("Set map center and zoom first.");return this._initialTopLeftPoint.subtract(L.DomUtil.getPosition(this._mapPane))},_getNewTopLeftPoint:function(a){var b=this.getSize().divideBy(2);return this.project(a).subtract(b).round()},_limitZoom:function(a){var b=this.getMinZoom(),c=this.getMaxZoom();return Math.max(b,Math.min(c,
a))}});L.Map.include({locate:function(a){var b={timeout:1E4};L.Util.extend(b,a);navigator.geolocation?navigator.geolocation.getCurrentPosition(L.Util.bind(this._handleGeolocationResponse,this),L.Util.bind(this._handleGeolocationError,this),b):this.fire("locationerror",{code:0,message:"Geolocation not supported."});return this},locateAndSetView:function(a,b){this._setViewOnLocate=!0;this._maxLocateZoom=a||Infinity;return this.locate(b)},_handleGeolocationError:function(a){var a=a.code,b=a==1?"permission denied":
a==2?"position unavailable":"timeout";if(this._setViewOnLocate)this.fitWorld(),this._setViewOnLocate=!1;this.fire("locationerror",{code:a,message:"Geolocation error: "+b+"."})},_handleGeolocationResponse:function(a){var b=180*a.coords.accuracy/4E7,c=b*2,d=a.coords.latitude,e=a.coords.longitude,f=new L.LatLng(d-b,e-c),b=new L.LatLng(d+b,e+c),f=new L.LatLngBounds(f,b);if(this._setViewOnLocate)b=Math.min(this.getBoundsZoom(f),this._maxLocateZoom),this.setView(f.getCenter(),b),this._setViewOnLocate=!1;
this.fire("locationfound",{latlng:new L.LatLng(d,e),bounds:f,accuracy:a.coords.accuracy})}});L.Map.include({openPopup:function(a){this.closePopup();this._popup=a;return this.addLayer(a)},closePopup:function(){this._popup&&this.removeLayer(this._popup);return this}});L.Map.include(!L.Transition||!L.Transition.implemented()?{}:{setView:function(a,b,c){var b=this._limitZoom(b),d=this._zoom!=b;if(this._loaded&&!c&&this._layers&&(c=this._getNewTopLeftPoint(a).subtract(this._getTopLeftPoint()),d?this._zoomToIfCenterInView&&this._zoomToIfCenterInView(a,b,c):this._panByIfClose(c)))return this;this._resetView(a,b);return this},panBy:function(a){if(!this._panTransition)this._panTransition=new L.Transition(this._mapPane,{duration:0.3}),this._panTransition.on("step",this._onPanTransitionStep,
this),this._panTransition.on("end",this._onPanTransitionEnd,this);this.fire(this,"movestart");this._panTransition.run({position:L.DomUtil.getPosition(this._mapPane).subtract(a)});return this},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){this.fire("moveend")},_panByIfClose:function(a){if(this._offsetIsWithinView(a))return this.panBy(a),!0;return!1},_offsetIsWithinView:function(a,b){var c=b||1,d=this.getSize();return Math.abs(a.x)<=d.x*c&&Math.abs(a.y)<=d.y*c}});L.Map.include(!L.DomUtil.TRANSITION?{}:{_zoomToIfCenterInView:function(a,b,c){if(this._animatingZoom)return!0;if(!this.options.zoomAnimation)return!1;var d=Math.pow(2,b-this._zoom),c=c.divideBy(1-1/d);if(!this._offsetIsWithinView(c,1))return!1;this._mapPane.className+=" leaflet-zoom-anim";c=this.containerPointToLayerPoint(this.getSize().divideBy(2)).add(c);this._prepareTileBg();this._runAnimation(a,b,d,c);return!0},_runAnimation:function(a,b,c,d){this._animatingZoom=!0;this._animateToCenter=a;this._animateToZoom=
b;a=L.DomUtil.TRANSFORM;if(L.Browser.gecko||window.opera)this._tileBg.style[a]+=" translate(0,0)";L.Browser.android?(this._tileBg.style[a+"Origin"]=d.x+"px "+d.y+"px",c="scale("+c+")"):c=L.DomUtil.getScaleString(c,d);L.Util.falseFn(this._tileBg.offsetWidth);d={};d[a]=this._tileBg.style[a]+" "+c;this._tileBg.transition.run(d)},_prepareTileBg:function(){if(!this._tileBg)this._tileBg=this._createPane("leaflet-tile-pane",this._mapPane),this._tileBg.style.zIndex=1;var a=this._tilePane,b=this._tileBg;b.style[L.DomUtil.TRANSFORM]=
"";b.style.visibility="hidden";b.empty=!0;a.empty=!1;this._tilePane=this._panes.tilePane=b;this._tileBg=a;if(!this._tileBg.transition)this._tileBg.transition=new L.Transition(this._tileBg,{duration:0.3,easing:"cubic-bezier(0.25,0.1,0.25,0.75)"}),this._tileBg.transition.on("end",this._onZoomTransitionEnd,this);this._stopLoadingBgTiles()},_stopLoadingBgTiles:function(){for(var a=[].slice.call(this._tileBg.getElementsByTagName("img")),b=0,c=a.length;b<c;b++)if(!a[b].complete)a[b].src="",a[b].parentNode.removeChild(a[b])},
_onZoomTransitionEnd:function(){this._restoreTileFront();L.Util.falseFn(this._tileBg.offsetWidth);this._resetView(this._animateToCenter,this._animateToZoom,!0);this._mapPane.className=this._mapPane.className.replace(" leaflet-zoom-anim","");this._animatingZoom=!1},_restoreTileFront:function(){this._tilePane.innerHTML="";this._tilePane.style.visibility="";this._tilePane.style.zIndex=2;this._tileBg.style.zIndex=1},_clearTileBg:function(){if(!this._animatingZoom&&!this.touchZoom._zooming)this._tileBg.innerHTML=
""}});L.Map.include({addControl:function(a){a.onAdd(this);var b=a.getPosition(),c=this._controlCorners[b],a=a.getContainer();L.DomUtil.addClass(a,"leaflet-control");b.indexOf("bottom")!=-1?c.insertBefore(a,c.firstChild):c.appendChild(a);return this},removeControl:function(a){var b=this._controlCorners[a.getPosition()],c=a.getContainer();b.removeChild(c);if(a.onRemove)a.onRemove(this);return this},_initControlPos:function(){var a=this._controlCorners={},b=L.DomUtil.create("div","leaflet-control-container",
this._container);L.Browser.mobileWebkit&&(b.className+=" leaflet-big-buttons");a.topLeft=L.DomUtil.create("div","leaflet-top leaflet-left",b);a.topRight=L.DomUtil.create("div","leaflet-top leaflet-right",b);a.bottomLeft=L.DomUtil.create("div","leaflet-bottom leaflet-left",b);a.bottomRight=L.DomUtil.create("div","leaflet-bottom leaflet-right",b)}});

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,278 @@
/*
* Copyright 2009 The Closure Compiler Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//
// Contents
//
The Closure Compiler performs checking, instrumentation, and
optimizations on JavaScript code. The purpose of this README is to
explain how to build and run the Closure Compiler.
The Closure Compiler requires Java 6 or higher.
http://www.java.com/
//
// Building The Closure Compiler
//
There are three ways to get a Closure Compiler executable.
1) Use one we built for you.
Pre-built Closure binaries can be found at
http://code.google.com/p/closure-compiler/downloads/list
2) Check out the source and build it with Apache Ant.
First, check out the full source tree of the Closure Compiler. There
are instructions on how to do this at the project site.
http://code.google.com/p/closure-compiler/source/checkout
Apache Ant is a cross-platform build tool.
http://ant.apache.org/
At the root of the source tree, there is an Ant file named
build.xml. To use it, navigate to the same directory and type the
command
ant jar
This will produce a jar file called "build/compiler.jar".
3) Check out the source and build it with Eclipse.
Eclipse is a cross-platform IDE.
http://www.eclipse.org/
Under Eclipse's File menu, click "New > Project ..." and create a
"Java Project." You will see an options screen. Give the project a
name, select "Create project from existing source," and choose the
root of the checked-out source tree as the existing directory. Verify
that you are using JRE version 6 or higher.
Eclipse can use the build.xml file to discover rules. When you
navigate to the build.xml file, you will see all the build rules in
the "Outline" pane. Run the "jar" rule to build the compiler in
build/compiler.jar.
//
// Running The Closure Compiler
//
Once you have the jar binary, running the Closure Compiler is straightforward.
On the command line, type
java -jar compiler.jar
This starts the compiler in interactive mode. Type
var x = 17 + 25;
then hit "Enter", then hit "Ctrl-Z" (on Windows) or "Ctrl-D" (on Mac or Linux)
and "Enter" again. The Compiler will respond:
var x=42;
The Closure Compiler has many options for reading input from a file,
writing output to a file, checking your code, and running
optimizations. To learn more, type
java -jar compiler.jar --help
You can read more detailed documentation about the many flags at
http://code.google.com/closure/compiler/docs/gettingstarted_app.html
//
// Compiling Multiple Scripts
//
If you have multiple scripts, you should compile them all together with
one compile command.
java -jar compiler.jar --js=in1.js --js=in2.js ... --js_output_file=out.js
The Closure Compiler will concatenate the files in the order they're
passed at the command line.
If you need to compile many, many scripts together, you may start to
run into problems with managing dependencies between scripts. You
should check out the Closure Library. It contains functions for
enforcing dependencies between scripts, and a tool called calcdeps.py
that knows how to give scripts to the Closure Compiler in the right
order.
http://code.google.com/p/closure-library/
//
// Licensing
//
Unless otherwise stated, all source files are licensed under
the Apache License, Version 2.0.
-----
Code under:
src/com/google/javascript/rhino
test/com/google/javascript/rhino
URL: http://www.mozilla.org/rhino
Version: 1.5R3, with heavy modifications
License: Netscape Public License and MPL / GPL dual license
Description: A partial copy of Mozilla Rhino. Mozilla Rhino is an
implementation of JavaScript for the JVM. The JavaScript parser and
the parse tree data structures were extracted and modified
significantly for use by Google's JavaScript compiler.
Local Modifications: The packages have been renamespaced. All code not
relavant to parsing has been removed. A JSDoc parser and static typing
system have been added.
-----
Code in:
lib/libtrunk_rhino_parser_jarjared.jar
Rhino
URL: http://www.mozilla.org/rhino
Version: Trunk
License: Netscape Public License and MPL / GPL dual license
Description: Mozilla Rhino is an implementation of JavaScript for the JVM.
Local Modifications: None. We've used JarJar to renamespace the code
post-compilation. See:
http://code.google.com/p/jarjar/
-----
Code in:
lib/args4j.jar
Args4j
URL: https://args4j.dev.java.net/
Version: 2.0.12
License: MIT
Description:
args4j is a small Java class library that makes it easy to parse command line
options/arguments in your CUI application.
Local Modifications: None.
-----
Code in:
lib/guava.jar
Guava Libraries
URL: http://code.google.com/p/guava-libraries/
Version: r08
License: Apache License 2.0
Description: Google's core Java libraries.
Local Modifications: None.
-----
Code in:
lib/jsr305.jar
Annotations for software defect detection
URL: http://code.google.com/p/jsr-305/
Version: svn revision 47
License: BSD License
Description: Annotations for software defect detection.
Local Modifications: None.
----
Code in:
lib/junit.jar
JUnit
URL: http://sourceforge.net/projects/junit/
Version: 4.8.2
License: Common Public License 1.0
Description: A framework for writing and running automated tests in Java.
Local Modifications: None.
---
Code in:
lib/protobuf-java.jar
Protocol Buffers
URL: http://code.google.com/p/protobuf/
Version: 2.3.0
License: New BSD License
Description: Supporting libraries for protocol buffers,
an encoding of structured data.
Local Modifications: None
---
Code in:
lib/ant.jar
lib/ant-launcher.jar
URL: http://ant.apache.org/bindownload.cgi
Version: 1.8.1
License: Apache License 2.0
Description:
Ant is a Java based build tool. In theory it is kind of like "make"
without make's wrinkles and with the full portability of pure java code.
Local Modifications: None
---
Code in:
lib/json.jar
URL: http://json.org/java/index.html
Version: JSON version 20090211
License: MIT license
Description:
JSON is a set of java files for use in transmitting data in JSON format.
Local Modifications: None
---
Code in:
tools/maven-ant-tasks-2.1.1.jar
URL: http://maven.apache.org
Version 2.1.1
License: Apache License 2.0
Description:
Maven Ant tasks are used to manage dependencies and to install/deploy to
maven repositories.
Local Modifications: None

Binary file not shown.

View File

@ -0,0 +1,182 @@
jasmine.TrivialReporter = function(doc) {
this.document = doc || document;
this.suiteDivs = {};
this.logRunningSpecs = false;
};
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
var el = document.createElement(type);
for (var i = 2; i < arguments.length; i++) {
var child = arguments[i];
if (typeof child === 'string') {
el.appendChild(document.createTextNode(child));
} else {
if (child) { el.appendChild(child); }
}
}
for (var attr in attrs) {
if (attr == "className") {
el[attr] = attrs[attr];
} else {
el.setAttribute(attr, attrs[attr]);
}
}
return el;
};
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
var showPassed, showSkipped;
this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
this.createDom('div', { className: 'banner' },
this.createDom('div', { className: 'logo' },
"Jasmine",
this.createDom('span', { className: 'version' }, runner.env.versionString())),
this.createDom('div', { className: 'options' },
"Show ",
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
)
),
this.runnerDiv = this.createDom('div', { className: 'runner running' },
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
);
this.document.body.appendChild(this.outerDiv);
var suites = runner.suites();
for (var i = 0; i < suites.length; i++) {
var suite = suites[i];
var suiteDiv = this.createDom('div', { className: 'suite' },
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
this.suiteDivs[suite.id] = suiteDiv;
var parentDiv = this.outerDiv;
if (suite.parentSuite) {
parentDiv = this.suiteDivs[suite.parentSuite.id];
}
parentDiv.appendChild(suiteDiv);
}
this.startedAt = new Date();
var self = this;
showPassed.onchange = function(evt) {
if (evt.target.checked) {
self.outerDiv.className += ' show-passed';
} else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
}
};
showSkipped.onchange = function(evt) {
if (evt.target.checked) {
self.outerDiv.className += ' show-skipped';
} else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
}
};
};
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
var results = runner.results();
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
this.runnerDiv.setAttribute("class", className);
//do it twice for IE
this.runnerDiv.setAttribute("className", className);
var specs = runner.specs();
var specCount = 0;
for (var i = 0; i < specs.length; i++) {
if (this.specFilter(specs[i])) {
specCount++;
}
}
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
};
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
var results = suite.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.totalCount == 0) { // todo: change this to check results.skipped
status = 'skipped';
}
this.suiteDivs[suite.id].className += " " + status;
};
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
if (this.logRunningSpecs) {
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
}
};
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
var results = spec.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.skipped) {
status = 'skipped';
}
var specDiv = this.createDom('div', { className: 'spec ' + status },
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
this.createDom('a', {
className: 'description',
href: '?spec=' + encodeURIComponent(spec.getFullName()),
title: spec.getFullName()
}, spec.description));
var resultItems = results.getItems();
var messagesDiv = this.createDom('div', { className: 'messages' });
for (var i = 0; i < resultItems.length; i++) {
var result = resultItems[i];
if (result.type == 'log') {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
} else if (result.type == 'expect' && result.passed && !result.passed()) {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
if (result.trace.stack) {
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
}
}
}
if (messagesDiv.childNodes.length > 0) {
specDiv.appendChild(messagesDiv);
}
this.suiteDivs[spec.suite.id].appendChild(specDiv);
};
jasmine.TrivialReporter.prototype.log = function() {
var console = jasmine.getGlobal().console;
if (console && console.log) console.log.apply(console, arguments);
};
jasmine.TrivialReporter.prototype.getLocation = function() {
return this.document.location;
};
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
var paramMap = {};
var params = this.getLocation().search.substring(1).split('&');
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
}
if (!paramMap["spec"]) return true;
return spec.getFullName().indexOf(paramMap["spec"]) == 0;
};

View File

@ -0,0 +1,166 @@
body {
font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
}
.jasmine_reporter a:visited, .jasmine_reporter a {
color: #303;
}
.jasmine_reporter a:hover, .jasmine_reporter a:active {
color: blue;
}
.run_spec {
float:right;
padding-right: 5px;
font-size: .8em;
text-decoration: none;
}
.jasmine_reporter {
margin: 0 5px;
}
.banner {
color: #303;
background-color: #fef;
padding: 5px;
}
.logo {
float: left;
font-size: 1.1em;
padding-left: 5px;
}
.logo .version {
font-size: .6em;
padding-left: 1em;
}
.runner.running {
background-color: yellow;
}
.options {
text-align: right;
font-size: .8em;
}
.suite {
border: 1px outset gray;
margin: 5px 0;
padding-left: 1em;
}
.suite .suite {
margin: 5px;
}
.suite.passed {
background-color: #dfd;
}
.suite.failed {
background-color: #fdd;
}
.spec {
margin: 5px;
padding-left: 1em;
clear: both;
}
.spec.failed, .spec.passed, .spec.skipped {
padding-bottom: 5px;
border: 1px solid gray;
}
.spec.failed {
background-color: #fbb;
border-color: red;
}
.spec.passed {
background-color: #bfb;
border-color: green;
}
.spec.skipped {
background-color: #bbb;
}
.messages {
border-left: 1px dashed gray;
padding-left: 1em;
padding-right: 1em;
}
.passed {
background-color: #cfc;
display: none;
}
.failed {
background-color: #fbb;
}
.skipped {
color: #777;
background-color: #eee;
display: none;
}
/*.resultMessage {*/
/*white-space: pre;*/
/*}*/
.resultMessage span.result {
display: block;
line-height: 2em;
color: black;
}
.resultMessage .mismatch {
color: black;
}
.stackTrace {
white-space: pre;
font-size: .8em;
margin-left: 10px;
max-height: 5em;
overflow: auto;
border: 1px inset red;
padding: 1em;
background: #eef;
}
.finished-at {
padding-left: 1em;
font-size: .6em;
}
.show-passed .passed,
.show-skipped .skipped {
display: block;
}
#jasmine_content {
position:fixed;
right: 100%;
}
.runner {
border: 1px solid gray;
display: block;
margin: 5px 0;
padding: 2px 0 2px 10px;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html>
<head>
<title>Jasmine Test Runner</title>
<link rel="stylesheet" type="text/css" href="../lib/jasmine/jasmine.css">
<script type="text/javascript" src="../lib/jasmine/jasmine.js"></script>
<script type="text/javascript" src="../lib/jasmine/jasmine-html.js"></script>
<!-- source files -->
<script type="text/javascript">
L = 'test'; //to test L#noConflict later
</script>
<script type="text/javascript" src="../src/Leaflet.js"></script>
<!-- /core -->
<script type="text/javascript" src="../src/core/Util.js"></script>
<script type="text/javascript" src="../src/core/Class.js"></script>
<script type="text/javascript" src="../src/core/Events.js"></script>
<script type="text/javascript" src="../src/core/Browser.js"></script>
<!-- /dom -->
<script type="text/javascript" src="../src/dom/DomEvent.js"></script>
<script type="text/javascript" src="../src/dom/DomUtil.js"></script>
<!-- /geo -->
<script type="text/javascript" src="../src/geo/LatLng.js"></script>
<script type="text/javascript" src="../src/geo/LatLngBounds.js"></script>
<script type="text/javascript" src="../src/geo/Projection.js"></script>
<!-- /geometry -->
<script type="text/javascript" src="../src/geometry/Point.js"></script>
<script type="text/javascript" src="../src/geometry/Bounds.js"></script>
<script type="text/javascript" src="../src/geometry/Transformation.js"></script>
<!-- /layer -->
<script type="text/javascript" src="../src/layer/TileLayer.js"></script>
<!-- /map -->
<script type="text/javascript" src="../src/map/Map.js"></script>
<!-- spec files -->
<script type="text/javascript" src="suites/SpecHelper.js"></script>
<script type="text/javascript" src="suites/LeafletSpec.js"></script>
<!-- /core -->
<script type="text/javascript" src="suites/core/UtilSpec.js"></script>
<script type="text/javascript" src="suites/core/ClassSpec.js"></script>
<script type="text/javascript" src="suites/core/EventsSpec.js"></script>
<!-- /geometry -->
<script type="text/javascript" src="suites/geometry/PointSpec.js"></script>
<script type="text/javascript" src="suites/geometry/BoundsSpec.js"></script>
<script type="text/javascript" src="suites/geometry/TransformationSpec.js"></script>
<!-- /geo -->
<script type="text/javascript" src="suites/geo/LatLngSpec.js"></script>
<script type="text/javascript" src="suites/geo/LatLngBoundsSpec.js"></script>
<script type="text/javascript" src="suites/geo/ProjectionSpec.js"></script>
<!-- /dom -->
<script type="text/javascript" src="suites/dom/DomEventSpec.js"></script>
<script type="text/javascript" src="suites/dom/DomUtilSpec.js"></script>
<!-- /layer -->
<script type="text/javascript" src="suites/layer/TileLayerSpec.js"></script>
<!-- /map -->
<script type="text/javascript" src="suites/map/MapSpec.js"></script>
</head>
<body>
<script type="text/javascript">
jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
jasmine.getEnv().execute();
</script>
</body>
</html>

View File

@ -0,0 +1,15 @@
describe('L#noConflict', function() {
it('should restore the previous L value and return Leaflet namespace', function(){
expect(L.VERSION).toBeDefined();
var L2 = L.noConflict();
expect(L).toEqual('test');
expect(L2.VERSION).toBeDefined();
this.after(function() {
window.L = L2;
});
});
});

View File

@ -0,0 +1,5 @@
function noSpecs() {
it('should have specs', function() {
expect('specs').toBe();
});
}

View File

@ -0,0 +1,120 @@
describe("Class", function() {
describe("#extend", function() {
var Klass,
constructor,
method;
beforeEach(function() {
constructor = jasmine.createSpy(),
method = jasmine.createSpy();
Klass = L.Class.extend({
statics: {bla: 1},
includes: {mixin: true},
initialize: constructor,
foo: 5,
bar: method
});
});
it("should create a class with the given constructor & properties", function() {
var a = new Klass();
expect(constructor).toHaveBeenCalled();
expect(a.foo).toEqual(5);
a.bar();
expect(method).toHaveBeenCalled();
});
it("should inherit parent classes' constructor & properties", function() {
var Klass2 = Klass.extend({baz: 2});
var b = new Klass2();
expect(b instanceof Klass).toBeTruthy();
expect(b instanceof Klass2).toBeTruthy();
expect(constructor).toHaveBeenCalled();
expect(b.baz).toEqual(2);
b.bar();
expect(method).toHaveBeenCalled();
});
it("should grant the ability to call parent methods, including constructor", function() {
var Klass2 = Klass.extend({
initialize: function() {},
bar: function() {}
});
var b = new Klass2();
expect(constructor).not.toHaveBeenCalled();
b.superclass.initialize.call(this);
expect(constructor).toHaveBeenCalled();
b.superclass.bar.call(this);
expect(method).toHaveBeenCalled();
});
it("should support static properties", function() {
expect(Klass.bla).toEqual(1);
});
it("should inherit parent static properties", function() {
var Klass2 = Klass.extend({});
expect(Klass2.bla).toEqual(1);
});
it("should include the given mixin", function() {
var a = new Klass();
expect(a.mixin).toBeTruthy();
});
it("should be able to include multiple mixins", function() {
var Klass2 = L.Class.extend({
includes: [{mixin: true}, {mixin2: true}]
});
var a = new Klass2();
expect(a.mixin).toBeTruthy();
expect(a.mixin2).toBeTruthy();
});
it("should grant the ability to include the given mixin", function() {
Klass.include({mixin2: true});
var a = new Klass();
expect(a.mixin2).toBeTruthy();
});
it("should merge options instead of replacing them", function() {
var KlassWithOptions1 = L.Class.extend({
options: {
foo1: 1,
foo2: 2
}
});
var KlassWithOptions2 = KlassWithOptions1.extend({
options: {
foo2: 3,
foo3: 4
}
});
var a = new KlassWithOptions2();
expect(a.options).toEqual({
foo1: 1,
foo2: 3,
foo3: 4
});
});
});
});

View File

@ -0,0 +1,110 @@
describe('Events', function() {
var Klass;
beforeEach(function() {
Klass = L.Class.extend({
includes: L.Mixin.Events
});
});
describe('#fireEvent', function() {
it('should fire all listeners added through #addEventListener', function() {
var obj = new Klass(),
spy = jasmine.createSpy(),
spy2 = jasmine.createSpy(),
spy3 = jasmine.createSpy();
obj.addEventListener('test', spy);
obj.addEventListener('test', spy2);
obj.addEventListener('other', spy3);
expect(spy).not.toHaveBeenCalled();
expect(spy2).not.toHaveBeenCalled();
expect(spy3).not.toHaveBeenCalled();
obj.fireEvent('test');
expect(spy).toHaveBeenCalled();
expect(spy2).toHaveBeenCalled();
expect(spy3).not.toHaveBeenCalled();
});
it('should provide event object to listeners and execute them in the right context', function() {
var obj = new Klass(),
obj2 = new Klass(),
foo = {};
function listener1(e) {
expect(e.type).toEqual('test');
expect(e.target).toEqual(obj);
expect(this).toEqual(obj);
expect(e.bar).toEqual(3);
};
function listener2(e) {
expect(e.target).toEqual(obj2);
expect(this).toEqual(foo);
};
obj.addEventListener('test', listener1);
obj2.addEventListener('test', listener2, foo);
obj.fireEvent('test', {bar: 3});
});
it('should not call listeners removed through #removeEventListener', function() {
var obj = new Klass(),
spy = jasmine.createSpy();
obj.addEventListener('test', spy);
obj.removeEventListener('test', spy);
obj.fireEvent('test');
expect(spy).not.toHaveBeenCalled();
});
});
describe('#on, #off & #fire', function() {
it('should work like #addEventListener && #removeEventListener', function() {
var obj = new Klass(),
spy = jasmine.createSpy();
obj.on('test', spy);
obj.fire('test');
expect(spy).toHaveBeenCalled();
obj.off('test', spy);
obj.fireEvent('test');
expect(spy.callCount).toBeLessThan(2);
});
it('should not override existing methods with the same name', function() {
var spy1 = jasmine.createSpy(),
spy2 = jasmine.createSpy(),
spy3 = jasmine.createSpy();
var Klass2 = L.Class.extend({
includes: L.Mixin.Events,
on: spy1,
off: spy2,
fire: spy3
});
var obj = new Klass2();
obj.on();
expect(spy1).toHaveBeenCalled();
obj.off();
expect(spy2).toHaveBeenCalled();
obj.fire();
expect(spy3).toHaveBeenCalled();
});
});
});

View File

@ -0,0 +1,63 @@
describe('Util', function() {
describe('#extend', function() {
var a;
beforeEach(function() {
a = {
foo: 5,
bar: 'asd'
};
});
it('should extend the first argument with the properties of the second', function() {
L.Util.extend(a, {
bar: 7,
baz: 3
});
expect(a).toEqual({
foo: 5,
bar: 7,
baz: 3
});
});
it('should work with more than 2 arguments', function() {
L.Util.extend(a, {bar: 7}, {baz: 3});
expect(a).toEqual({
foo: 5,
bar: 7,
baz: 3
});
});
});
describe('#bind', function() {
it('should return the given function with the given context', function() {
var fn = function() {
return this;
};
var fn2 = L.Util.bind(fn, 5);
expect(fn2()).toEqual(5);
});
});
describe('#stamp', function() {
it('should set a unique id on the given object and return it', function() {
var a = {},
id = L.Util.stamp(a);
expect(typeof id).toEqual('number');
expect(L.Util.stamp(a)).toEqual(id);
var b = {},
id2 = L.Util.stamp(b);
expect(id2).not.toEqual(id);
});
});
});

View File

@ -0,0 +1,102 @@
describe('DomEvent', function() {
var el;
function simulateClick(el) {
if (document.createEvent) {
var e = document.createEvent('MouseEvents');
e.initMouseEvent('click', true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
return el.dispatchEvent(e);
} else if (el.fireEvent) {
return el.fireEvent('onclick');
}
}
beforeEach(function() {
el = document.createElement('div');
el.style.position = 'absolute';
el.style.top = el.style.left = '-10000px';
document.body.appendChild(el);
});
afterEach(function() {
document.body.removeChild(el);
});
describe('#addListener', function() {
it('should add a listener and call it on event', function() {
var listener1 = jasmine.createSpy('listener1'),
listener2 = jasmine.createSpy('listener2');
L.DomEvent.addListener(el, 'click', listener1);
L.DomEvent.addListener(el, 'click', listener2);
simulateClick(el);
expect(listener1).toHaveBeenCalled();
expect(listener2).toHaveBeenCalled();
});
it('should have "this" keyword point to the given context', function() {
var obj = {foo: 'bar'},
result;
L.DomEvent.addListener(el, 'click', function() {
result = this;
}, obj);
simulateClick(el);
expect(result).toEqual(obj);
});
it('should pass an event object to the listener', function() {
var type;
L.DomEvent.addListener(el, 'click', function(e) {
type = e && e.type;
});
simulateClick(el);
expect(type).toEqual('click');
});
});
describe('#removeListener', function() {
it('should remove prevously added listener', function() {
var listener = jasmine.createSpy('listener');
L.DomEvent.addListener(el, 'click', listener);
L.DomEvent.removeListener(el, 'click', listener);
simulateClick(el);
expect(listener).not.toHaveBeenCalled();
});
});
describe('#stopPropagation', function() {
it('should stop propagation of the given event', function() {
var child = document.createElement('div'),
listener = jasmine.createSpy('listener');
el.appendChild(child);
L.DomEvent.addListener(child, 'click', L.DomEvent.stopPropagation);
L.DomEvent.addListener(el, 'click', listener);
simulateClick(child);
expect(listener).not.toHaveBeenCalled();
el.removeChild(child);
});
});
describe('#preventDefault', function() {
it('should prevent the default action of event', function() {
L.DomEvent.addListener(el, 'click', L.DomEvent.preventDefault);
expect(simulateClick(el)).toBe(false);
});
});
});

View File

@ -0,0 +1,29 @@
describe('DomUtil', function() {
var el;
beforeEach(function() {
el = document.createElement('div');
el.style.position = 'absolute';
el.style.top = el.style.left = '-10000px';
document.body.appendChild(el);
});
afterEach(function() {
document.body.removeChild(el);
});
describe('#get', function() {
it('should get element by id if the given argument is string', function() {
el.id = 'testId';
expect(L.DomUtil.get(el.id)).toBe(el);
});
it('should return the element if it is given as an argument', function() {
expect(L.DomUtil.get(el)).toBe(el);
});
});
describe('#setPosition', noSpecs);
describe('#getStyle', noSpecs);
});

View File

@ -0,0 +1 @@
describe('LatLngBounds', noSpecs);

View File

@ -0,0 +1,70 @@
describe('LatLng', function() {
describe('constructor', function() {
it("should set lat and lng", function() {
var a = new L.LatLng(25, 74);
expect(a.lat).toEqual(25);
expect(a.lng).toEqual(74);
var a = new L.LatLng(-25, -74);
expect(a.lat).toEqual(-25);
expect(a.lng).toEqual(-74);
});
it("should clamp latitude to lie between -90 and 90", function() {
var a = new L.LatLng(150, 0).lat;
expect(a).toEqual(90);
var b = new L.LatLng(-230, 0).lat;
expect(b).toEqual(-90);
});
it("should clamp longtitude to lie between -180 and 180", function() {
var a = new L.LatLng(0, 190).lng;
expect(a).toEqual(-170);
var b = new L.LatLng(0, 360).lng;
expect(b).toEqual(0);
var c = new L.LatLng(0, 380).lng;
expect(c).toEqual(20);
var d = new L.LatLng(0, -190).lng;
expect(d).toEqual(170);
var e = new L.LatLng(0, -360).lng;
expect(e).toEqual(0);
var f = new L.LatLng(0, -380).lng;
expect(f).toEqual(-20);
});
it("should not clamp latitude and longtitude if unbounded flag set to true", function() {
var a = new L.LatLng(150, 0, true).lat;
expect(a).toEqual(150);
var b = new L.LatLng(-230, 0, true).lat;
expect(b).toEqual(-230);
var c = new L.LatLng(0, 250, true).lng;
expect(c).toEqual(250);
var d = new L.LatLng(0, -190, true).lng;
expect(d).toEqual(-190);
});
});
describe('#equals', function() {
it("should return true if compared objects are equal within a certain margin", function() {
var a = new L.LatLng(10, 20);
var b = new L.LatLng(10 + 1.0E-10, 20 - 1.0E-10);
expect(a.equals(b)).toBe(true);
});
it("should return false if compared objects are not equal within a certain margin", function() {
var a = new L.LatLng(10, 20);
var b = new L.LatLng(10, 23.3);
expect(a.equals(b)).toBe(false);
});
});
});

View File

@ -0,0 +1,42 @@
describe("Projection.Mercator", function() {
var p = L.Projection.Mercator;
beforeEach(function() {
function almostEqual(a, b, p) {
return Math.abs(a - b) <= (p || 1.0E-12);
};
this.addMatchers({
toAlmostEqual: function(expected, margin) {
var p1 = this.actual,
p2 = expected;
return almostEqual(p1.x, p2.x, margin) && almostEqual(p1.y, p2.y, margin);
}
});
});
describe("#project", function() {
it("should do projection properly", function() {
//edge cases
expect(p.project(new L.LatLng(0, 0))).toAlmostEqual(new L.Point(0, 0));
expect(p.project(new L.LatLng(90, 180))).toAlmostEqual(new L.Point(-Math.PI, Math.PI));
expect(p.project(new L.LatLng(-90, -180))).toAlmostEqual(new L.Point(-Math.PI, -Math.PI));
expect(p.project(new L.LatLng(50, 30))).toAlmostEqual(new L.Point(0.523598775598, 1.010683188683));
});
});
describe("#unproject", function() {
it("should do unprojection properly", function() {
function pr(point) {
return p.project(p.unproject(point));
}
expect(pr(new L.Point(0, 0))).toAlmostEqual(new L.Point(0, 0));
expect(pr(new L.Point(-Math.PI, Math.PI))).toAlmostEqual(new L.Point(-Math.PI, Math.PI));
expect(pr(new L.Point(-Math.PI, -Math.PI))).toAlmostEqual(new L.Point(-Math.PI, -Math.PI));
expect(pr(new L.Point(0.523598775598, 1.010683188683))).toAlmostEqual(new L.Point(0.523598775598, 1.010683188683));
});
});
});

View File

@ -0,0 +1,43 @@
describe('Bounds', function() {
var a, b;
beforeEach(function() {
a = new L.Bounds(
new L.Point(14, 12),
new L.Point(30, 40));
b = new L.Bounds([
new L.Point(20, 12),
new L.Point(14, 20),
new L.Point(30, 40)
]);
});
describe('constructor', function() {
it('should create bounds with proper min & max on (Point, Point)', function() {
expect(a.min).toEqual(new L.Point(14, 12));
expect(a.max).toEqual(new L.Point(30, 40));
});
it('should create bounds with proper min & max on (Point[])', function() {
expect(b.min).toEqual(new L.Point(14, 12));
expect(b.max).toEqual(new L.Point(30, 40));
});
});
describe('#extend', function() {
it('should extend the bounds to contain the given point', function() {
a.extend(new L.Point(50, 20));
expect(a.min).toEqual(new L.Point(14, 12));
expect(a.max).toEqual(new L.Point(50, 40));
b.extend(new L.Point(25, 50));
expect(b.min).toEqual(new L.Point(14, 12));
expect(b.max).toEqual(new L.Point(30, 50));
});
});
describe('#getCenter', function() {
it('should return the center point', function() {
expect(a.getCenter()).toEqual(new L.Point(22, 26));
});
});
});

View File

@ -0,0 +1,45 @@
describe("Point", function() {
describe('constructor', function() {
it("should create a point with the given x and y", function() {
var p = new L.Point(1.5, 2.5);
expect(p.x).toEqual(1.5);
expect(p.y).toEqual(2.5);
});
it("should round the given x and y if the third argument is true", function() {
var p = new L.Point(1.3, 2.7, true);
expect(p.x).toEqual(1);
expect(p.y).toEqual(3);
});
});
describe('#subtract', function() {
it('should subtract the given point from this one', function() {
var a = new L.Point(50, 30),
b = new L.Point(20, 10);
expect(a.subtract(b)).toEqual(new L.Point(30, 20));
});
});
describe('#add', function() {
it('should add the given point to this one', function() {
expect(new L.Point(50, 30).add(new L.Point(20, 10))).toEqual(new L.Point(70, 40));
});
});
describe('#divideBy', function() {
it('should divide this point by the given amount', function() {
expect(new L.Point(50, 30).divideBy(5)).toEqual(new L.Point(10, 6));
});
});
describe('#multiplyBy', function() {
it('should multiply this point by the given amount', function() {
expect(new L.Point(50, 30).multiplyBy(2)).toEqual(new L.Point(100, 60));
});
});
describe('#distanceTo', noSpecs);
});

View File

@ -0,0 +1,19 @@
describe("Transformation", function() {
var t, p;
beforeEach(function() {
t = new L.Transformation(1, 2, 3, 4);
p = new L.Point(10, 20);
});
it("#transform should perform a transformation", function() {
var p2 = t.transform(p, 2);
expect(p2).toEqual(new L.Point(24, 128));
});
it("#untransform should perform a reverse transformation", function() {
var p2 = t.transform(p, 2);
var p3 = t.untransform(p2, 2);
expect(p3).toEqual(p);
});
});

View File

@ -0,0 +1 @@
describe('TileLayer', noSpecs);

View File

@ -0,0 +1 @@
describe("Map", noSpecs);

View File

@ -0,0 +1,35 @@
/**
* @preserve 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(root) {
var L = {
VERSION: '0.2',
ROOT_URL: (function() {
var scripts = document.getElementsByTagName('script'),
leafletRe = /^(.*\/)leaflet-?([\w-]*)\.js.*$/;
for (var i = 0, len = scripts.length; i < len; i++) {
var src = scripts[i].src,
res = src && src.match(leafletRe);
if (res) {
if (res[2] == 'include') break;
return res[1];
}
}
return '../../dist/';
})(),
noConflict: function() {
root.L = this._originalL;
return this;
},
_originalL: root.L
};
window.L = L;
}(this));

View File

@ -0,0 +1,55 @@
L.Control.Attribution = L.Class.extend({
onAdd: function(map) {
this._container = L.DomUtil.create('div', 'leaflet-control-attribution');
this._map = map;
this._prefix = 'Powered by <a href="http://leaflet.cloudmade.com">Leaflet</a>';
this._attributions = {};
this._update();
},
getPosition: function() {
return L.Control.Position.BOTTOM_RIGHT;
},
getContainer: function() {
return this._container;
},
setPrefix: function(prefix) {
this._prefix = prefix;
},
addAttribution: function(text) {
if (!text) return;
this._attributions[text] = true;
this._update();
},
removeAttribution: function(text) {
if (!text) return;
delete this._attributions[text];
this._update();
},
_update: function() {
if (!this._map) return;
var attribs = [];
for (var i in this._attributions) {
if (this._attributions.hasOwnProperty(i)) {
attribs.push(i);
}
}
var prefixAndAttribs = [];
if (this._prefix) {
prefixAndAttribs.push(this._prefix);
}
if (attribs.length) {
prefixAndAttribs.push(attribs.join(', '));
}
this._container.innerHTML = prefixAndAttribs.join(' &mdash; ');
}
});

View File

@ -0,0 +1,36 @@
L.Control.Zoom = L.Class.extend({
onAdd: function(map) {
this._map = map;
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(title, className, fn, context) {
var link = document.createElement('a');
link.href = '#';
link.title = title;
link.className = className;
L.DomEvent.disableClickPropagation(link);
L.DomEvent.addListener(link, 'click', L.DomEvent.preventDefault);
L.DomEvent.addListener(link, 'click', fn, context);
return link;
}
});

View File

@ -0,0 +1,9 @@
L.Control = {};
L.Control.Position = {
TOP_LEFT: 'topLeft',
TOP_RIGHT: 'topRight',
BOTTOM_LEFT: 'bottomLeft',
BOTTOM_RIGHT: 'bottomRight'
};

View File

@ -0,0 +1,23 @@
(function() {
var ua = navigator.userAgent.toLowerCase(),
ie = !!window.ActiveXObject,
webkit = ua.indexOf("webkit") != -1,
mobile = ua.indexOf("mobi") != -1,
android = ua.indexOf("android") != -1,
opera = window.opera;
L.Browser = {
ie: ie,
ie6: ie && !window.XMLHttpRequest,
webkit: webkit,
webkit3d: webkit && ('WebKitCSSMatrix' in window) && ('m11' in new WebKitCSSMatrix()),
mobileWebkit: webkit && (mobile || android),
mobileOpera: mobile && opera,
gecko: ua.indexOf("gecko") != -1,
android: android
};
//TODO replace ugly ua sniffing with feature detection
L.Browser.touch = L.Browser.mobileWebkit || L.Browser.mobileOpera;
})();

View File

@ -0,0 +1,66 @@
/*
* Class powers the OOP facilities of the library. Thanks to John Resig and Dean Edwards for inspiration!
*/
L.Class = function() {};
L.Class.extend = function(/*Object*/ props) /*-> Class*/ {
// extended class with the new prototype
var NewClass = function() {
if (!L.Class._prototyping && this.initialize) {
this.initialize.apply(this, arguments);
}
};
// instantiate class without calling constructor
L.Class._prototyping = true;
var proto = new this();
L.Class._prototyping = false;
proto.constructor = NewClass;
NewClass.prototype = proto;
// add superclass access
proto.superclass = this.prototype;
// add class name
//proto.className = props;
// mix static properties into the class
if (props.statics) {
L.Util.extend(NewClass, props.statics);
delete props.statics;
}
// mix includes into the prototype
if (props.includes) {
L.Util.extend.apply(null, [proto].concat(props.includes));
delete props.includes;
}
// merge options
if (props.options && proto.options) {
props.options = L.Util.extend({}, proto.options, props.options);
}
// mix given properties into the prototype
L.Util.extend(proto, props);
// allow inheriting further
NewClass.extend = arguments.callee;
// method for adding properties to prototype
NewClass.include = function(props) {
L.Util.extend(this.prototype, props);
};
//inherit parent's statics
for (var i in this) {
if (this.hasOwnProperty(i) && i != 'prototype') {
NewClass[i] = this[i];
}
}
return NewClass;
};

View File

@ -0,0 +1,58 @@
/*
* L.Mixin.Events adds custom events functionality to Leaflet classes
*/
L.Mixin = {};
L.Mixin.Events = {
addEventListener: function(/*String*/ type, /*Function*/ fn, /*(optional) Object*/ context) {
var events = this._leaflet_events = this._leaflet_events || {};
events[type] = events[type] || [];
events[type].push({
action: fn,
context: context
});
return this;
},
hasEventListeners: function(/*String*/ type) /*-> Boolean*/ {
var k = '_leaflet_events';
return (k in this) && (type in this[k]) && (this[k][type].length > 0);
},
removeEventListener: function(/*String*/ type, /*Function*/ fn, /*(optional) Object*/ context) {
if (!this.hasEventListeners(type)) { return this; }
for (var i = 0, events = this._leaflet_events, len = events[type].length; i < len; i++) {
if (
(events[type][i].action === fn) &&
(!context || (events[type][i].context === context))
) {
events[type].splice(i, 1);
return this;
}
}
return this;
},
fireEvent: function(/*String*/ type, /*(optional) Object*/ data) {
if (!this.hasEventListeners(type)) { return; }
var event = L.Util.extend({
type: type,
target: this
}, data);
var listeners = this._leaflet_events[type].slice();
for (var i = 0, len = listeners.length; i < len; i++) {
listeners[i].action.call(listeners[i].context || this, event);
}
return this;
}
};
L.Mixin.Events.on = L.Mixin.Events.addEventListener;
L.Mixin.Events.off = L.Mixin.Events.removeEventListener;
L.Mixin.Events.fire = L.Mixin.Events.fireEvent;

View File

@ -0,0 +1,96 @@
/*
* L.Util is a namespace for various utility functions.
*/
L.Util = {
extend: function(/*Object*/ dest) /*-> Object*/ { // merge src properties into dest
var sources = Array.prototype.slice.call(arguments, 1);
for (var j = 0, len = sources.length, src; j < len; j++) {
src = sources[j] || {};
for (var i in src) {
if (src.hasOwnProperty(i)) {
dest[i] = src[i];
}
}
}
return dest;
},
bind: function(/*Function*/ fn, /*Object*/ obj) /*-> Object*/ {
return function() {
return fn.apply(obj, arguments);
};
},
stamp: (function() {
var lastId = 0, key = '_leaflet_id';
return function(/*Object*/ obj) {
obj[key] = obj[key] || ++lastId;
return obj[key];
};
})(),
requestAnimFrame: (function() {
function timeoutDefer(callback) {
window.setTimeout(callback, 1000 / 60);
}
var requestFn = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
timeoutDefer;
return function(callback, context, immediate) {
callback = context ? L.Util.bind(callback, context) : context;
if (immediate && requestFn === timeoutDefer) {
callback();
} else {
requestFn(callback);
}
};
})(),
limitExecByInterval: function(fn, time, context) {
var lock, execOnUnlock, args;
function exec(){
lock = false;
if (execOnUnlock) {
args.callee.apply(context, args);
execOnUnlock = false;
}
}
return function() {
args = arguments;
if (!lock) {
lock = true;
setTimeout(exec, time);
fn.apply(context, args);
} else {
execOnUnlock = true;
}
};
},
falseFn: function() { return false; },
formatNum: function(num, digits) {
var pow = Math.pow(10, digits || 5);
return Math.round(num * pow) / pow;
},
setOptions: function(obj, options) {
obj.options = L.Util.extend({}, obj.options, options);
},
getParamString: function(obj) {
var params = [];
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
params.push(i + '=' + obj[i]);
}
}
return '?' + params.join('&');
}
};

View File

@ -0,0 +1,41 @@
L.Util.extend(L.DomEvent, {
// inspired by Zepto touch code by Thomas Fuchs
addDoubleTapListener: function(obj, handler, id) {
var last,
doubleTap = false,
delay = 250,
touch,
pre = '_leaflet_',
touchstart = 'touchstart',
touchend = 'touchend';
function onTouchStart(e) {
if (e.touches.length != 1) return;
var now = Date.now(),
delta = now - (last || now);
touch = e.touches[0];
doubleTap = (delta > 0 && delta <= delay);
last = now;
}
function onTouchEnd(e) {
if (doubleTap) {
touch.type = 'dblclick';
handler(touch);
last = null;
}
}
obj[pre + touchstart + id] = onTouchStart;
obj[pre + touchend + id] = onTouchEnd;
obj.addEventListener(touchstart, onTouchStart, false);
obj.addEventListener(touchend, onTouchEnd, false);
},
removeDoubleTapListener: function(obj, id) {
var pre = '_leaflet_';
obj.removeEventListener(obj, obj[pre + 'touchstart' + id], false);
obj.removeEventListener(obj, obj[pre + 'touchend' + id], false);
}
});

View File

@ -0,0 +1,132 @@
/*
* L.DomEvent contains functions for working with DOM events.
*/
L.DomEvent = {
/* inpired by John Resig, Dean Edwards and YUI addEvent implementations */
addListener: function(/*HTMLElement*/ obj, /*String*/ type, /*Function*/ fn, /*Object*/ context) {
var id = L.Util.stamp(fn);
function handler(e) {
return fn.call(context || obj, e || L.DomEvent._getEvent());
}
if (L.Browser.touch && (type == 'dblclick') && this.addDoubleTapListener) {
this.addDoubleTapListener(obj, handler, id);
} else if ('addEventListener' in obj) {
if (type == 'mousewheel') {
obj.addEventListener('DOMMouseScroll', handler, false);
obj.addEventListener(type, handler, false);
} else if ((type == 'mouseenter') || (type == 'mouseleave')) {
var originalHandler = handler,
newType = (type == 'mouseenter' ? 'mouseover' : 'mouseout');
handler = function(e) {
if (!L.DomEvent._checkMouse(obj, e)) return;
return originalHandler(e);
};
obj.addEventListener(newType, handler, false);
} else {
obj.addEventListener(type, handler, false);
}
} else if ('attachEvent' in obj) {
obj.attachEvent("on" + type, handler);
}
obj['_leaflet_' + type + id] = handler;
},
removeListener: function(/*HTMLElement*/ obj, /*String*/ type, /*Function*/ fn) {
var id = L.Util.stamp(fn),
key = '_leaflet_' + type + id;
handler = obj[key];
if (L.Browser.mobileWebkit && (type == 'dblclick') && this.removeDoubleTapListener) {
this.removeDoubleTapListener(obj, id);
} else if ('removeEventListener' in obj) {
if (type == 'mousewheel') {
obj.removeEventListener('DOMMouseScroll', handler, false);
obj.removeEventListener(type, handler, false);
} else if ((type == 'mouseenter') || (type == 'mouseleave')) {
obj.removeEventListener((type == 'mouseenter' ? 'mouseover' : 'mouseout'), handler, false);
} else {
obj.removeEventListener(type, handler, false);
}
} else if ('detachEvent' in obj) {
obj.detachEvent("on" + type, handler);
}
obj[key] = null;
},
_checkMouse: function(el, e) {
var related = e.relatedTarget;
if (!related) return true;
try {
while (related && (related != el)) {
related = related.parentNode;
}
} catch(err) { return false; }
return (related != el);
},
_getEvent: function()/*->Event*/ {
var e = window.event;
if (!e) {
var caller = arguments.callee.caller;
while (caller) {
e = caller['arguments'][0];
if (e && Event == e.constructor) { break; }
caller = caller.caller;
}
}
return e;
},
stopPropagation: function(/*Event*/ e) {
if (e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble = true;
}
},
disableClickPropagation: function(/*HTMLElement*/ el) {
L.DomEvent.addListener(el, 'mousedown', L.DomEvent.stopPropagation);
L.DomEvent.addListener(el, 'click', L.DomEvent.stopPropagation);
L.DomEvent.addListener(el, 'dblclick', L.DomEvent.stopPropagation);
},
preventDefault: function(/*Event*/ e) {
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
},
stop: function(e) {
L.DomEvent.preventDefault(e);
L.DomEvent.stopPropagation(e);
},
getMousePosition: function(e, container) {
var x = e.pageX ? e.pageX : e.clientX +
document.body.scrollLeft + document.documentElement.scrollLeft,
y = e.pageY ? e.pageY : e.clientY +
document.body.scrollTop + document.documentElement.scrollTop,
pos = new L.Point(x, y);
return (container ?
pos.subtract(L.DomUtil.getCumulativeOffset(container)) : pos);
},
getWheelDelta: function(e) {
var delta = 0;
if (e.wheelDelta) { delta = e.wheelDelta/120; }
if (e.detail) { delta = -e.detail/3; }
return delta;
}
};

View File

@ -0,0 +1,124 @@
/*
* L.DomUtil contains various utility functions for working with DOM
*/
L.DomUtil = {
get: function(id) {
return (typeof id == 'string' ? document.getElementById(id) : id);
},
getStyle: function(el, style) {
var value = el.style[style];
if (!value && el.currentStyle) {
value = el.currentStyle[style];
}
if (!value || value == 'auto') {
var css = document.defaultView.getComputedStyle(el, null);
value = css ? css[style] : null;
}
return (value == 'auto' ? null : value);
},
getCumulativeOffset: function(el) {
var top = 0,
left = 0;
do {
top += el.offsetTop || 0;
left += el.offsetLeft || 0;
el = el.offsetParent;
} while (el);
return new L.Point(left, top);
},
create: function(tagName, className, container) {
var el = document.createElement(tagName);
el.className = className;
if (container) {
container.appendChild(el);
}
return el;
},
disableTextSelection: function() {
if (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(el, name) {
return (el.className.length > 0) &&
new RegExp("(^|\\s)" + name + "(\\s|$)").test(el.className);
},
addClass: function(el, name) {
if (!L.DomUtil.hasClass(el, name)) {
el.className += (el.className ? ' ' : '') + name;
}
},
setOpacity: function(el, value) {
if (L.Browser.ie) {
el.style.filter = 'alpha(opacity=' + Math.round(value * 100) + ')';
} else {
el.style.opacity = value;
}
},
//TODO refactor away this ugly translate/position mess
testProp: function(props) {
var style = document.documentElement.style;
for (var i = 0; i < props.length; i++) {
if (props[i] in style) {
return props[i];
}
}
return false;
},
getTranslateString: function(point) {
return L.DomUtil.TRANSLATE_OPEN +
point.x + 'px,' + point.y + 'px' +
L.DomUtil.TRANSLATE_CLOSE;
},
getScaleString: function(scale, origin) {
return L.DomUtil.getTranslateString(origin) +
' scale(' + scale + ') ' +
L.DomUtil.getTranslateString(origin.multiplyBy(-1));
},
setPosition: function(el, point) {
el._leaflet_pos = point;
if (L.Browser.webkit) {
el.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(point);
} else {
el.style.left = point.x + 'px';
el.style.top = point.y + 'px';
}
},
getPosition: function(el) {
return el._leaflet_pos;
}
};
L.Util.extend(L.DomUtil, {
TRANSITION: L.DomUtil.testProp(['transition', 'webkitTransition', 'OTransition', 'MozTransition', 'msTransition']),
TRANSFORM: L.DomUtil.testProp(['transformProperty', 'WebkitTransform', 'OTransform', 'MozTransform', 'msTransform']),
TRANSLATE_OPEN: 'translate' + (L.Browser.webkit3d ? '3d(' : '('),
TRANSLATE_CLOSE: L.Browser.webkit3d ? ',0)' : ')'
});

View File

@ -0,0 +1,129 @@
/*
* L.Draggable allows you to add dragging capabilities to any element. Supports mobile devices too.
*/
L.Draggable = L.Class.extend({
includes: L.Mixin.Events,
statics: {
START: L.Browser.touch ? 'touchstart' : 'mousedown',
END: L.Browser.touch ? 'touchend' : 'mouseup',
MOVE: L.Browser.touch ? 'touchmove' : 'mousemove',
TAP_TOLERANCE: 15
},
initialize: function(element, dragStartTarget) {
this._element = element;
this._dragStartTarget = dragStartTarget || element;
},
enable: function() {
if (this._enabled) { return; }
L.DomEvent.addListener(this._dragStartTarget, L.Draggable.START, this._onDown, this);
this._enabled = true;
},
disable: function() {
if (!this._enabled) { return; }
L.DomEvent.removeListener(this._dragStartTarget, L.Draggable.START, this._onDown);
this._enabled = false;
},
_onDown: function(e) {
if (e.shiftKey || ((e.which != 1) && (e.button != 1) && !e.touches)) { return; }
if (e.touches && e.touches.length > 1) { return; }
var first = (e.touches && e.touches.length == 1 ? e.touches[0] : e);
L.DomEvent.preventDefault(e);
if (L.Browser.mobileWebkit) {
first.target.className += ' leaflet-active';
}
this._moved = false;
L.DomUtil.disableTextSelection();
this._setMovingCursor();
this._startPos = this._newPos = L.DomUtil.getPosition(this._element);
this._startPoint = new L.Point(first.clientX, first.clientY);
L.DomEvent.addListener(document, L.Draggable.MOVE, this._onMove, this);
L.DomEvent.addListener(document, L.Draggable.END, this._onUp, this);
},
_onMove: function(e) {
if (e.touches && e.touches.length > 1) { return; }
L.DomEvent.preventDefault(e);
var first = (e.touches && e.touches.length == 1 ? e.touches[0] : e);
if (!this._moved) {
this.fire('dragstart');
this._moved = true;
}
var newPoint = new L.Point(first.clientX, first.clientY);
this._newPos = this._startPos.add(newPoint).subtract(this._startPoint);
L.Util.requestAnimFrame(this._updatePosition, this, true);
this.fire('drag');
},
_updatePosition: function() {
L.DomUtil.setPosition(this._element, this._newPos);
},
_onUp: function(e) {
if (e.changedTouches) {
var first = e.changedTouches[0],
el = first.target,
dist = (this._newPos && this._newPos.distanceTo(this._startPos)) || 0;
el.className = el.className.replace(' leaflet-active', '');
if (dist < L.Draggable.TAP_TOLERANCE) {
this._simulateEvent('click', first);
}
}
L.DomUtil.enableTextSelection();
this._restoreCursor();
L.DomEvent.removeListener(document, L.Draggable.MOVE, this._onMove);
L.DomEvent.removeListener(document, L.Draggable.END, this._onUp);
if (this._moved) {
this.fire('dragend');
}
},
_removeActiveClass: function(el) {
},
_setMovingCursor: function() {
this._bodyCursor = document.body.style.cursor;
document.body.style.cursor = 'move';
},
_restoreCursor: function() {
document.body.style.cursor = this._bodyCursor;
},
_simulateEvent: function(type, e) {
var simulatedEvent = document.createEvent('MouseEvent');
simulatedEvent.initMouseEvent(
type, true, true, window, 1,
e.screenX, e.screenY,
e.clientX, e.clientY,
false, false, false, false, 0, null);
e.target.dispatchEvent(simulatedEvent);
}
});

View File

@ -0,0 +1,89 @@
/*
* L.Transition native implementation that powers Leaflet animation
* in browsers that support CSS3 Transitions
*/
L.Transition = L.Transition.extend({
statics: (function() {
var transition = L.DomUtil.TRANSITION,
transitionEnd = (transition == 'webkitTransition' || transition == 'OTransition' ?
transition + 'End' : 'transitionend');
return {
NATIVE: !!transition,
TRANSITION: transition,
PROPERTY: transition + 'Property',
DURATION: transition + 'Duration',
EASING: transition + 'TimingFunction',
END: transitionEnd,
// transition-property value to use with each particular custom property
CUSTOM_PROPS_PROPERTIES: {
position: L.Browser.webkit ? L.DomUtil.TRANSFORM : 'top, left'
}
};
})(),
options: {
fakeStepInterval: 100
},
initialize: function(/*HTMLElement*/ el, /*Object*/ options) {
this._el = el;
L.Util.setOptions(this, options);
L.DomEvent.addListener(el, L.Transition.END, this._onTransitionEnd, this);
this._onFakeStep = L.Util.bind(this._onFakeStep, this);
},
run: function(/*Object*/ props) {
var prop,
propsList = [],
customProp = L.Transition.CUSTOM_PROPS_PROPERTIES;
for (prop in props) {
if (props.hasOwnProperty(prop)) {
prop = customProp[prop] ? customProp[prop] : prop;
prop = prop.replace(/([A-Z])/g, function(w) { return '-' + w.toLowerCase(); });
propsList.push(prop);
}
}
this._el.style[L.Transition.DURATION] = this.options.duration + 's';
this._el.style[L.Transition.EASING] = this.options.easing;
this._el.style[L.Transition.PROPERTY] = propsList.join(', ');
for (prop in props) {
if (props.hasOwnProperty(prop)) {
this._setProperty(prop, props[prop]);
}
}
this._inProgress = true;
this.fire('start');
if (L.Transition.NATIVE) {
this._timer = setInterval(this._onFakeStep, this.options.fakeStepInterval);
} else {
this._onTransitionEnd();
}
},
_onFakeStep: function() {
this.fire('step');
},
_onTransitionEnd: function() {
if (this._inProgress) {
this._inProgress = false;
clearInterval(this._timer);
this._el.style[L.Transition.PROPERTY] = 'none';
this.fire('step');
this.fire('end');
}
}
});

View File

@ -0,0 +1,124 @@
/*
* L.Transition fallback implementation that powers Leaflet animation
* in browsers that don't support CSS3 Transitions
*/
L.Transition = L.Transition.NATIVE ? L.Transition : L.Transition.extend({
statics: {
getTime: Date.now || function() { return +new Date(); },
TIMER: true,
EASINGS: {
'ease': [0.25, 0.1, 0.25, 1.0],
'linear': [0.0, 0.0, 1.0, 1.0],
'ease-in': [0.42, 0, 1.0, 1.0],
'ease-out': [0, 0, 0.58, 1.0],
'ease-in-out': [0.42, 0, 0.58, 1.0]
},
CUSTOM_PROPS_GETTERS: {
position: L.DomUtil.getPosition
},
//used to get units from strings like "10.5px" (->px)
UNIT_RE: /^[\d\.]+(\D*)$/
},
options: {
fps: 50
},
initialize: function(el, options) {
this._el = el;
L.Util.extend(this.options, options);
var easings = L.Transition.EASINGS[this.options.easing] || L.Transition.EASINGS['ease'];
this._p1 = new L.Point(0, 0);
this._p2 = new L.Point(easings[0], easings[1]);
this._p3 = new L.Point(easings[2], easings[3]);
this._p4 = new L.Point(1, 1);
this._step = L.Util.bind(this._step, this);
this._interval = Math.round(1000 / this.options.fps);
},
run: function(props) {
this._props = {};
var getters = L.Transition.CUSTOM_PROPS_GETTERS,
re = L.Transition.UNIT_RE;
this.fire('start');
for (var prop in props) {
if (props.hasOwnProperty(prop)) {
var p = {};
if (prop in getters) {
p.from = getters[prop](this._el);
} else {
var matches = this._el.style[prop].match(re);
p.from = parseFloat(matches[0]);
p.unit = matches[1];
}
p.to = props[prop];
this._props[prop] = p;
}
}
clearInterval(this._timer);
this._timer = setInterval(this._step, this._interval);
this._startTime = L.Transition.getTime();
},
_step: function() {
var time = L.Transition.getTime(),
elapsed = time - this._startTime,
duration = this.options.duration * 1000;
if (elapsed < duration) {
this._runFrame(this._cubicBezier(elapsed / duration));
} else {
this._runFrame(1);
this._complete();
}
},
_runFrame: function(percentComplete) {
var setters = L.Transition.CUSTOM_PROPS_SETTERS,
prop, p, value;
for (prop in this._props) {
if (this._props.hasOwnProperty(prop)) {
p = this._props[prop];
if (prop in setters) {
value = p.to.subtract(p.from).multiplyBy(percentComplete).add(p.from);
setters[prop](this._el, value);
} else {
this._el.style[prop] =
((p.to - p.from) * percentComplete + p.from) + p.unit;
}
}
}
this.fire('step');
},
_complete: function() {
clearInterval(this._timer);
this.fire('end');
},
_cubicBezier: function(t) {
var a = Math.pow(1 - t, 3),
b = 3 * Math.pow(1 - t, 2) * t,
c = 3 * (1 - t) * Math.pow(t, 2),
d = Math.pow(t, 3),
p1 = this._p1.multiplyBy(a),
p2 = this._p2.multiplyBy(b),
p3 = this._p3.multiplyBy(c),
p4 = this._p4.multiplyBy(d);
return p1.add(p2).add(p3).add(p4).y;
}
});

View File

@ -0,0 +1,28 @@
L.Transition = L.Class.extend({
includes: L.Mixin.Events,
statics: {
CUSTOM_PROPS_SETTERS: {
position: L.DomUtil.setPosition
//TODO transform custom attr
},
implemented: function() {
return L.Transition.NATIVE || L.Transition.TIMER;
}
},
options: {
easing: 'ease',
duration: 0.5
},
_setProperty: function(prop, value) {
var setters = L.Transition.CUSTOM_PROPS_SETTERS;
if (prop in setters) {
setters[prop](this._el, value);
} else {
this._el.style[prop] = value;
}
}
});

View File

@ -0,0 +1,35 @@
/*
CM.LatLng represents a geographical point with latitude and longtitude coordinates.
*/
L.LatLng = function(/*Number*/ lat, /*Number*/ lng, /*Boolean*/ noWrap) {
if (noWrap !== true) {
lat = Math.max(Math.min(lat, 90), -90); // clamp latitude into -90..90
lng = (lng + 180) % 360 + (lng < -180 ? 180 : -180); // wrap longtitude into -180..180
}
//TODO change to lat() & lng()
this.lat = lat;
this.lng = lng;
};
L.Util.extend(L.LatLng, {
DEG_TO_RAD: Math.PI / 180,
RAD_TO_DEG: 180 / Math.PI,
MAX_MARGIN: 1.0E-9 // max margin of error for the "equals" check
});
L.LatLng.prototype = {
equals: function(/*LatLng*/ obj) {
if (!(obj instanceof L.LatLng)) { return false; }
var margin = Math.max(Math.abs(this.lat - obj.lat), Math.abs(this.lng - obj.lng));
return margin <= L.LatLng.MAX_MARGIN;
},
toString: function() {
return 'LatLng(' +
L.Util.formatNum(this.lat) + ', ' +
L.Util.formatNum(this.lng) + ')';
}
};

View File

@ -0,0 +1,62 @@
/*
* L.LatLngBounds represents a rectangular area on the map in geographical coordinates.
*/
L.LatLngBounds = L.Class.extend({
initialize: function(southWest, northEast) { // (LatLng, LatLng) or (LatLng[])
if (!southWest) return;
var latlngs = (southWest instanceof Array ? southWest : [southWest, northEast]);
for (var i = 0, len = latlngs.length; i < len; i++) {
this.extend(latlngs[i]);
}
},
// extend the bounds to contain the given point
extend: function(/*LatLng*/ latlng) {
if (!this._southWest && !this._northEast) {
this._southWest = new L.LatLng(latlng.lat, latlng.lng);
this._northEast = new L.LatLng(latlng.lat, latlng.lng);
} else {
this._southWest.lat = Math.min(latlng.lat, this._southWest.lat);
this._southWest.lng = Math.min(latlng.lng, this._southWest.lng);
this._northEast.lat = Math.max(latlng.lat, this._northEast.lat);
this._northEast.lng = Math.max(latlng.lng, this._northEast.lng);
}
},
getCenter: function() /*-> LatLng*/ {
return new L.LatLng(
(this._southWest.lat + this._northEast.lat) / 2,
(this._southWest.lng + this._northEast.lng) / 2);
},
getSouthWest: function() { return this._southWest; },
getNorthEast: function() { return this._northEast; },
getNorthWest: function() {
return new L.LatLng(this._northEast.lat, this._southWest.lng);
},
getSouthEast: function() {
return new L.LatLng(this._southWest.lat, this._northEast.lng);
},
contains: function(/*LatLngBounds or LatLng*/ obj) /*-> Boolean*/ {
var sw = this._southWest,
ne = this._northEast,
sw2, ne2;
if (obj instanceof L.LatLngBounds) {
sw2 = obj.getSouthWest();
ne2 = obj.getNorthEast();
} else {
sw2 = ne2 = obj;
}
return (sw2.lat >= sw.lat) && (ne2.lat <= ne.lat) &&
(sw2.lng >= sw.lng) && (ne2.lng <= ne.lng);
}
});
//TODO International date line?

View File

@ -0,0 +1,13 @@
L.CRS.EPSG3395 = L.Util.extend({}, L.CRS, {
code: 'EPSG:3395',
projection: L.Projection.Mercator,
transformation: (function() {
var m = L.Projection.Mercator,
r = m.R_MAJOR,
r2 = m.R_MINOR;
return new L.Transformation(0.5/(Math.PI * r), 0.5, -0.5/(Math.PI * r2), 0.5);
})()
});

View File

@ -0,0 +1,17 @@
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(/*LatLng*/ latlng)/*-> Point*/ {
var projectedPoint = this.projection.project(latlng),
earthRadius = 6378137;
return projectedPoint.multiplyBy(earthRadius);
}
});
L.CRS.EPSG900913 = L.Util.extend({}, L.CRS.EPSG3857, {
code: 'EPSG:900913'
});

View File

@ -0,0 +1,7 @@
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)
});

View File

@ -0,0 +1,17 @@
L.CRS = {
latLngToPoint: function(/*LatLng*/ latlng, /*Number*/ scale)/*-> Point*/ {
var projectedPoint = this.projection.project(latlng);
return this.transformation._transform(projectedPoint, scale);
},
pointToLatLng: function(/*Point*/ point, /*Number*/ scale, /*(optional) Boolean*/ unbounded)/*-> LatLng*/ {
var untransformedPoint = this.transformation.untransform(point, scale);
return this.projection.unproject(untransformedPoint, unbounded);
//TODO get rid of 'unbounded' everywhere
},
project: function(latlng) {
return this.projection.project(latlng);
}
};

View File

@ -0,0 +1,10 @@
L.Projection.LonLat = {
project: function(latlng) {
return new L.Point(latlng.lng, latlng.lat);
},
unproject: function(point, unbounded) {
return new L.LatLng(point.y, point.x, unbounded);
}
};

View File

@ -0,0 +1,49 @@
L.Projection.Mercator = {
MAX_LATITUDE: 85.0840591556,
R_MINOR: 6356752.3142,
R_MAJOR: 6378137,
project: function(/*LatLng*/ latlng) /*-> Point*/ {
var d = L.LatLng.DEG_TO_RAD,
max = this.MAX_LATITUDE,
lat = Math.max(Math.min(max, latlng.lat), -max),
r = this.R_MAJOR,
x = latlng.lng * d * r,
y = lat * d,
tmp = this.R_MINOR / r,
eccent = Math.sqrt(1.0 - tmp * tmp),
con = eccent * Math.sin(y);
con = Math.pow((1 - con)/(1 + con), eccent * 0.5);
var ts = Math.tan(0.5 * ((Math.PI * 0.5) - y)) / con;
y = -r * Math.log(ts);
return new L.Point(x, y);
},
unproject: function(/*Point*/ point, /*Boolean*/ unbounded) /*-> LatLng*/ {
var d = L.LatLng.RAD_TO_DEG,
r = this.R_MAJOR,
lng = point.x * d / r,
tmp = this.R_MINOR / r,
eccent = Math.sqrt(1 - (tmp * tmp)),
ts = Math.exp(- point.y / r),
phi = Math.PI/2 - 2 * Math.atan(ts),
numIter = 15,
tol = 1e-7,
i = numIter,
dphi = 0.1,
con;
while ((Math.abs(dphi) > tol) && (--i > 0)) {
con = eccent * Math.sin(phi);
dphi = Math.PI/2 - 2 * Math.atan(ts * Math.pow((1.0 - con)/(1.0 + con), 0.5 * eccent)) - phi;
phi += dphi;
}
return new L.LatLng(phi * d, lng, unbounded);
}
};

View File

@ -0,0 +1,23 @@
L.Projection.SphericalMercator = {
MAX_LATITUDE: 85.0511287798,
project: function(/*LatLng*/ latlng) /*-> Point*/ {
var d = L.LatLng.DEG_TO_RAD,
max = this.MAX_LATITUDE,
lat = Math.max(Math.min(max, latlng.lat), -max),
x = latlng.lng * d,
y = lat * d;
y = Math.log(Math.tan(Math.PI/4 + y/2));
return new L.Point(x, y);
},
unproject: function(/*Point*/ point, /*Boolean*/ unbounded) /*-> LatLng*/ {
var d = L.LatLng.RAD_TO_DEG,
lng = point.x * d,
lat = (2 * Math.atan(Math.exp(point.y)) - Math.PI/2) * d;
return new L.LatLng(lat, lng, unbounded);
}
};

View File

@ -0,0 +1,5 @@
/*
* L.Projection contains various geographical projections used by CRS classes.
*/
L.Projection = {};

View File

@ -0,0 +1,48 @@
/*
* L.Bounds represents a rectangular area on the screen in pixel coordinates.
*/
L.Bounds = L.Class.extend({
initialize: function(min, max) { //(Point, Point) or Point[]
if (!min) return;
var points = (min instanceof Array ? min : [min, max]);
for (var i = 0, len = points.length; i < len; i++) {
this.extend(points[i]);
}
},
// extend the bounds to contain the given point
extend: function(/*Point*/ point) {
if (!this.min && !this.max) {
this.min = new L.Point(point.x, point.y);
this.max = new L.Point(point.x, point.y);
} else {
this.min.x = Math.min(point.x, this.min.x);
this.max.x = Math.max(point.x, this.max.x);
this.min.y = Math.min(point.y, this.min.y);
this.max.y = Math.max(point.y, this.max.y);
}
},
getCenter: function(round)/*->Point*/ {
return new L.Point(
(this.min.x + this.max.x) / 2,
(this.min.y + this.max.y) / 2, round);
},
contains: function(/*Bounds or Point*/ obj)/*->Boolean*/ {
var min, max;
if (obj instanceof L.Bounds) {
min = obj.min;
max = obj.max;
} else {
max = max = obj;
}
return (min.x >= this.min.x) &&
(max.x <= this.max.x) &&
(min.y >= this.min.y) &&
(max.y <= this.max.y);
}
});

View File

@ -0,0 +1,159 @@
/*
* L.LineUtil contains different utility functions for line segments
* and polylines (clipping, simplification, distances, etc.)
*/
L.LineUtil = {
/*
* Simplify polyline with vertex reduction and Douglas-Peucker simplification.
* Improves rendering performance dramatically by lessening the number of points to draw.
*/
simplify: function(/*Point[]*/ points, /*Number*/ tolerance) {
if (!tolerance) return points.slice();
// stage 1: vertex reduction
points = this.reducePoints(points, tolerance);
// stage 2: Douglas-Peucker simplification
points = this.simplifyDP(points, tolerance);
return points;
},
// distance from a point to a segment between two points
pointToSegmentDistance: function(/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
return Math.sqrt(this._sqPointToSegmentDist(p, p1, p2));
},
// Douglas-Peucker simplification, see http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm
simplifyDP: function(points, tol) {
var maxDist2 = 0,
index = 0,
t2 = tol * tol;
for (var i = 1, len = points.length, dist2; i < len - 1; i++) {
dist2 = this._sqPointToSegmentDist(points[i], points[0], points[len - 1]);
if (dist2 > maxDist2) {
index = i;
maxDist2 = dist2;
}
}
if (maxDist2 >= t2) {
var part1 = points.slice(0, index),
part2 = points.slice(index),
simplifiedPart1 = this.simplifyDP(part1, tol).slice(0, len - 2),
simplifiedPart2 = this.simplifyDP(part2, tol);
return simplifiedPart1.concat(simplifiedPart2);
} else {
return [points[0], points[len - 1]];
}
},
// reduce points that are too close to each other to a single point
reducePoints: function(points, tol) {
var reducedPoints = [points[0]],
t2 = tol * tol;
for (var i = 1, prev = 0, len = points.length; i < len; i++) {
if (this._sqDist(points[i], points[prev]) < t2) continue;
reducedPoints.push(points[i]);
prev = i;
}
if (prev < len - 1) {
reducedPoints.push(points[len - 1]);
}
return reducedPoints;
},
/*
* Cohen-Sutherland line clipping algorithm.
* Used to avoid rendering parts of a polyline that are not currently visible.
*/
clipSegment: function(a, b, bounds, useLastCode) {
var min = bounds.min,
max = bounds.max;
var codeA = useLastCode ? this._lastCode : this._getBitCode(a, bounds),
codeB = this._getBitCode(b, bounds);
// save 2nd code to avoid calculating it on the next segment
this._lastCode = codeB;
while (true) {
// if a,b is inside the clip window (trivial accept)
if (!(codeA | codeB)) {
return [a, b];
// if a,b is outside the clip window (trivial reject)
} else if (codeA & codeB) {
return false;
// other cases
} else {
var codeOut = codeA || codeB,
p = this._getEdgeIntersection(a, b, codeOut, bounds),
newCode = this._getBitCode(p, bounds);
if (codeOut == codeA) {
a = p;
codeA = newCode;
} else {
b = p;
codeB = newCode;
}
}
}
},
_getEdgeIntersection: function(a, b, code, bounds) {
var dx = b.x - a.x,
dy = b.y - a.y,
min = bounds.min,
max = bounds.max;
if (code & 8) { // top
return new L.Point(a.x + dx * (max.y - a.y) / dy, max.y);
} else if (code & 4) { // bottom
return new L.Point(a.x + dx * (min.y - a.y) / dy, min.y);
} else if (code & 2){ // right
return new L.Point(max.x, a.y + dy * (max.x - a.x) / dx);
} else if (code & 1) { // left
return new L.Point(min.x, a.y + dy * (min.x - a.x) / dx);
}
},
_getBitCode: function(/*Point*/ p, bounds) {
var code = 0;
if (p.x < bounds.min.x) code |= 1; // left
else if (p.x > bounds.max.x) code |= 2; // right
if (p.y < bounds.min.y) code |= 4; // bottom
else if (p.y > bounds.max.y) code |= 8; // top
return code;
},
// square distance (to avoid unnecessary Math.sqrt calls)
_sqDist: function(p1, p2) {
var dx = p2.x - p1.x,
dy = p2.y - p1.y;
return dx * dx + dy * dy;
},
// square distance from point to a segment
_sqPointToSegmentDist: function(p, p1, p2) {
var x2 = p2.x - p1.x,
y2 = p2.y - p1.y;
if (!x2 && !y2) return this._sqDist(p, p1);
var dot = (p.x - p1.x) * x2 + (p.y - p1.y) * y2,
t = dot / this._sqDist(p1, p2);
if (t < 0) return this._sqDist(p, p1);
if (t > 1) return this._sqDist(p, p2);
var proj = new L.Point(p1.x + x2 * t, p1.y + y2 * t);
return this._sqDist(p, proj);
}
};

View File

@ -0,0 +1,66 @@
/*
* L.Point represents a point with x and y coordinates.
*/
L.Point = function(/*Number*/ x, /*Number*/ y, /*Boolean*/ round) {
this.x = (round ? Math.round(x) : x);
this.y = (round ? Math.round(y) : y);
};
L.Point.prototype = {
add: function(point) {
return this.clone()._add(point);
},
_add: function(point) {
this.x += point.x;
this.y += point.y;
return this;
},
subtract: function(point) {
return this.clone()._subtract(point);
},
// destructive subtract (faster)
_subtract: function(point) {
this.x -= point.x;
this.y -= point.y;
return this;
},
divideBy: function(num, round) {
return new L.Point(this.x/num, this.y/num, round);
},
multiplyBy: function(num) {
return new L.Point(this.x * num, this.y * num);
},
distanceTo: function(point) {
var x = point.x - this.x,
y = point.y - this.y;
return Math.sqrt(x*x + y*y);
},
round: function() {
return this.clone()._round();
},
// destructive round
_round: function() {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
return this;
},
clone: function() {
return new L.Point(this.x, this.y);
},
toString: function() {
return 'Point(' +
L.Util.formatNum(this.x) + ', ' +
L.Util.formatNum(this.y) + ')';
}
};

View File

@ -0,0 +1,55 @@
/*
* L.PolyUtil contains utilify functions for polygons (clipping, etc.).
*/
L.PolyUtil = {};
/*
* Sutherland-Hodgeman polygon clipping algorithm.
* Used to avoid rendering parts of a polygon that are not currently visible.
*/
L.PolyUtil.clipPolygon = function(points, bounds) {
var min = bounds.min,
max = bounds.max,
clippedPoints,
edges = [1, 4, 2, 8],
i, j, k,
a, b,
len, edge, p,
lu = L.LineUtil;
for (i = 0, len = points.length; i < len; i++) {
points[i]._code = lu._getBitCode(points[i], bounds);
}
// for each edge (left, bottom, right, top)
for (k = 0; k < 4; k++) {
edge = edges[k];
clippedPoints = [];
for (i = 0, len = points.length, j = len - 1; i < len; j = i++) {
a = points[i];
b = points[j];
// if a is inside the clip window
if (!(a._code & edge)) {
// if b is outside the clip window (a->b goes out of screen)
if (b._code & edge) {
p = lu._getEdgeIntersection(b, a, edge, bounds);
p._code = lu._getBitCode(p, bounds);
clippedPoints.push(p);
}
clippedPoints.push(a);
// else if b is inside the clip window (a->b enters the screen)
} else if (!(b._code & edge)) {
p = lu._getEdgeIntersection(b, a, edge, bounds);
p._code = lu._getBitCode(p, bounds);
clippedPoints.push(p);
}
}
points = clippedPoints;
}
return points;
};

View File

@ -0,0 +1,31 @@
/*
* L.Transformation is an utility class to perform simple point transformations through a 2d-matrix.
*/
L.Transformation = L.Class.extend({
initialize: function(/*Number*/ a, /*Number*/ b, /*Number*/ c, /*Number*/ d) {
this._a = a;
this._b = b;
this._c = c;
this._d = d;
},
transform: function(point, scale) {
return this._transform(point.clone(), scale);
},
// destructive transform (faster)
_transform: function(/*Point*/ point, /*Number*/ scale) /*-> Point*/ {
scale = scale || 1;
point.x = scale * (this._a * point.x + this._b);
point.y = scale * (this._c * point.y + this._d);
return point;
},
untransform: function(/*Point*/ point, /*Number*/ scale) /*-> Point*/ {
scale = scale || 1;
return new L.Point(
(point.x/scale - this._b) / this._a,
(point.y/scale - this._d) / this._c);
}
});

View File

@ -0,0 +1,21 @@
/*
* L.Handler.DoubleClickZoom is used internally by L.Map to add double-click zooming.
*/
L.Handler.DoubleClickZoom = L.Handler.extend({
enable: function() {
if (this._enabled) { return; }
this._map.on('dblclick', this._onDoubleClick, this._map);
this._enabled = true;
},
disable: function() {
if (!this._enabled) { return; }
this._map.off('dblclick', this._onDoubleClick, this._map);
this._enabled = false;
},
_onDoubleClick: function(e) {
this.setView(e.latlng, this._zoom + 1);
}
});

View File

@ -0,0 +1,13 @@
/*
* L.Handler classes are used internally to inject interaction features to classes like Map and Marker.
*/
L.Handler = L.Class.extend({
initialize: function(map) {
this._map = map;
},
enabled: function() {
return !!this._enabled;
}
});

View File

@ -0,0 +1,44 @@
/*
* L.Handler.MapDrag is used internally by L.Map to make the map draggable.
*/
L.Handler.MapDrag = L.Handler.extend({
enable: function() {
if (this._enabled) { return; }
if (!this._draggable) {
this._draggable = new L.Draggable(this._map._mapPane, this._map._container);
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 = true;
},
disable: function() {
if (!this._enabled) { return; }
this._draggable.disable();
this._enabled = false;
},
moved: function() {
return this._draggable._moved;
},
_onDragStart: function() {
this._map.fire('movestart');
this._map.fire('dragstart');
},
_onDrag: function() {
this._map.fire('move');
this._map.fire('drag');
},
_onDragEnd: function() {
this._map.fire('moveend');
this._map.fire('dragend');
}
});

View File

@ -0,0 +1,54 @@
/*
* L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable.
*/
L.Handler.MarkerDrag = L.Handler.extend({
initialize: function(marker) {
this._marker = marker;
},
enable: function() {
if (this._enabled) { return; }
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 = true;
},
disable: function() {
if (!this._enabled) { return; }
this._draggable.disable();
this._enabled = false;
},
moved: function() {
return this._draggable && this._draggable._moved;
},
_onDragStart: function(e) {
this._marker.closePopup();
this._marker.fire('movestart');
this._marker.fire('dragstart');
},
_onDrag: function(e) {
// update shadow position
var iconPos = L.DomUtil.getPosition(this._marker._icon);
L.DomUtil.setPosition(this._marker._shadow, iconPos);
this._marker._latlng = this._marker._map.layerPointToLatLng(iconPos);
this._marker.fire('move');
this._marker.fire('drag');
},
_onDragEnd: function() {
this._marker.fire('moveend');
this._marker.fire('dragend');
}
});

View File

@ -0,0 +1,50 @@
/*
* L.Handler.ScrollWheelZoom is used internally by L.Map to enable mouse scroll wheel zooming on the map.
*/
L.Handler.ScrollWheelZoom = L.Handler.extend({
enable: function() {
if (this._enabled) { return; }
L.DomEvent.addListener(this._map._container, 'mousewheel', this._onWheelScroll, this);
this._delta = 0;
this._enabled = true;
},
disable: function() {
if (!this._enabled) { return; }
L.DomEvent.removeListener(this._map._container, 'mousewheel', this._onWheelScroll);
this._enabled = false;
},
_onWheelScroll: function(e) {
this._delta += L.DomEvent.getWheelDelta(e);
this._lastMousePos = this._map.mouseEventToContainerPoint(e);
clearTimeout(this._timer);
this._timer = setTimeout(L.Util.bind(this._performZoom, this), 50);
L.DomEvent.preventDefault(e);
},
_performZoom: function() {
var delta = Math.round(this._delta);
this._delta = 0;
if (!delta) { return; }
var center = this._getCenterForScrollWheelZoom(this._lastMousePos, delta),
zoom = this._map.getZoom() + delta;
if (this._map._limitZoom(zoom) == this._map._zoom) { return; }
this._map.setView(center, zoom);
},
_getCenterForScrollWheelZoom: function(mousePos, delta) {
var centerPoint = this._map.getPixelBounds().getCenter(),
viewHalf = this._map.getSize().divideBy(2),
centerOffset = mousePos.subtract(viewHalf).multiplyBy(1 - Math.pow(2, -delta)),
newCenterPoint = centerPoint.add(centerOffset);
return this._map.unproject(newCenterPoint, this._map._zoom, true);
}
});

View File

@ -0,0 +1,79 @@
/*
* L.Handler.ShiftDragZoom is used internally by L.Map to add shift-drag zoom (zoom to a selected bounding box).
*/
L.Handler.ShiftDragZoom = L.Handler.extend({
initialize: function(map) {
this._map = map;
this._container = map._container;
this._pane = map._panes.overlayPane;
},
enable: function() {
if (this._enabled) { return; }
L.DomEvent.addListener(this._container, 'mousedown', this._onMouseDown, this);
this._enabled = true;
},
disable: function() {
if (!this._enabled) { return; }
L.DomEvent.removeListener(this._container, 'mousedown', this._onMouseDown);
this._enabled = false;
},
_onMouseDown: function(e) {
if (!e.shiftKey || ((e.which != 1) && (e.button != 1))) { return false; }
L.DomUtil.disableTextSelection();
this._startLayerPoint = this._map.mouseEventToLayerPoint(e);
this._box = L.DomUtil.create('div', 'leaflet-zoom-box', this._pane);
L.DomUtil.setPosition(this._box, this._startLayerPoint);
//TODO move cursor to styles
this._container.style.cursor = 'crosshair';
L.DomEvent.addListener(document, 'mousemove', this._onMouseMove, this);
L.DomEvent.addListener(document, 'mouseup', this._onMouseUp, this);
L.DomEvent.preventDefault(e);
},
_onMouseMove: function(e) {
var layerPoint = this._map.mouseEventToLayerPoint(e),
dx = layerPoint.x - this._startLayerPoint.x,
dy = layerPoint.y - this._startLayerPoint.y;
var newX = Math.min(layerPoint.x, this._startLayerPoint.x),
newY = Math.min(layerPoint.y, this._startLayerPoint.y),
newPos = new L.Point(newX, newY);
L.DomUtil.setPosition(this._box, newPos);
this._box.style.width = (Math.abs(dx) - 4) + 'px';
this._box.style.height = (Math.abs(dy) - 4) + 'px';
},
_onMouseUp: function(e) {
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);
var layerPoint = this._map.mouseEventToLayerPoint(e);
var bounds = new L.LatLngBounds(
this._map.layerPointToLatLng(this._startLayerPoint),
this._map.layerPointToLatLng(layerPoint));
this._map.fitBounds(bounds);
}
});

View File

@ -0,0 +1,87 @@
/*
* L.Handler.TouchZoom is used internally by L.Map to add touch-zooming on Webkit-powered mobile browsers.
*/
L.Handler.TouchZoom = L.Handler.extend({
enable: function() {
if (!L.Browser.mobileWebkit || this._enabled) { return; }
L.DomEvent.addListener(this._map._container, 'touchstart', this._onTouchStart, this);
this._enabled = true;
},
disable: function() {
if (!this._enabled) { return; }
L.DomEvent.removeListener(this._map._container, 'touchstart', this._onTouchStart, this);
this._enabled = false;
},
_onTouchStart: function(e) {
if (!e.touches || e.touches.length != 2 || this._map._animatingZoom) { return; }
var p1 = this._map.mouseEventToLayerPoint(e.touches[0]),
p2 = this._map.mouseEventToLayerPoint(e.touches[1]),
viewCenter = this._map.containerPointToLayerPoint(this._map.getSize().divideBy(2));
this._startCenter = p1.add(p2).divideBy(2, true);
this._startDist = p1.distanceTo(p2);
//this._startTransform = this._map._mapPane.style.webkitTransform;
this._moved = false;
this._zooming = true;
this._centerOffset = viewCenter.subtract(this._startCenter);
L.DomEvent.addListener(document, 'touchmove', this._onTouchMove, this);
L.DomEvent.addListener(document, 'touchend', this._onTouchEnd, this);
L.DomEvent.preventDefault(e);
},
_onTouchMove: function(e) {
if (!e.touches || e.touches.length != 2) { return; }
if (!this._moved) {
this._map._mapPane.className += ' leaflet-zoom-anim';
this._map._prepareTileBg();
this._moved = true;
}
var p1 = this._map.mouseEventToLayerPoint(e.touches[0]),
p2 = this._map.mouseEventToLayerPoint(e.touches[1]);
this._scale = p1.distanceTo(p2) / this._startDist;
this._delta = p1.add(p2).divideBy(2, true).subtract(this._startCenter);
/*
* Used 2 translates instead of transform-origin because of a very strange bug -
* it didn't count the origin on the first touch-zoom but worked correctly afterwards
*/
this._map._tileBg.style.webkitTransform = [
L.DomUtil.getTranslateString(this._delta),
L.DomUtil.getScaleString(this._scale, this._startCenter)
].join(" ");
L.DomEvent.preventDefault(e);
},
_onTouchEnd: function(e) {
if (!this._moved || !this._zooming) { return; }
this._zooming = false;
var oldZoom = this._map.getZoom(),
floatZoomDelta = Math.log(this._scale)/Math.LN2,
roundZoomDelta = (floatZoomDelta > 0 ? Math.ceil(floatZoomDelta) : Math.floor(floatZoomDelta)),
zoom = this._map._limitZoom(oldZoom + roundZoomDelta),
zoomDelta = zoom - oldZoom,
centerOffset = this._centerOffset.subtract(this._delta).divideBy(this._scale),
centerPoint = this._map.getPixelOrigin().add(this._startCenter).add(centerOffset),
center = this._map.unproject(centerPoint);
L.DomEvent.removeListener(document, 'touchmove', this._onTouchMove);
L.DomEvent.removeListener(document, 'touchend', this._onTouchEnd);
var finalScale = Math.pow(2, zoomDelta);
this._map._runAnimation(center, zoom, finalScale / this._scale, this._startCenter.add(centerOffset));
}
});

View File

@ -0,0 +1,40 @@
/*
* L.FeatureGroup extends L.LayerGroup by introducing mouse events and bindPopup method shared between a group of layers.
*/
L.FeatureGroup = L.LayerGroup.extend({
includes: L.Mixin.Events,
addLayer: function(layer) {
this._initEvents(layer);
L.LayerGroup.prototype.addLayer.call(this, layer);
if (this._popupContent && layer.bindPopup) {
layer.bindPopup(this._popupContent);
}
},
bindPopup: function(content) {
this._popupContent = content;
for (var i in this._layers) {
if (this._layers.hasOwnProperty(i) && this._layers[i].bindPopup) {
this._layers[i].bindPopup(content);
}
}
},
_events: ['click', 'dblclick', 'mouseover', 'mouseout'],
_initEvents: function(layer) {
for (var i = 0, len = this._events.length; i < len; i++) {
layer.on(this._events[i], this._propagateEvent, this);
}
},
_propagateEvent: function(e) {
e.layer = e.target;
e.target = this;
this.fire(e.type, e);
}
});

View File

@ -0,0 +1,106 @@
L.GeoJSON = L.LayerGroup.extend({
includes: L.Mixin.Events,
initialize: function(geojson, options) {
L.Util.setOptions(this, options);
this._geojson = geojson;
this._layers = {};
if (geojson) {
this.addGeoJSON(geojson);
}
},
addGeoJSON: function(geojson) {
if (geojson.features) {
for (var i = 0, len = geojson.features.length; i < len; i++) {
this.addGeoJSON(geojson.features[i]);
}
return;
}
var isFeature = (geojson.type == 'Feature'),
geometry = (isFeature ? geojson.geometry : geojson),
layer = L.GeoJSON.geometryToLayer(geometry, this.options.pointToLayer);
this.fire('featureparse', {
layer: layer,
properties: geojson.properties,
geometryType: geometry.type,
bbox: geojson.bbox,
id: geojson.id
});
this.addLayer(layer);
}
});
L.Util.extend(L.GeoJSON, {
geometryToLayer: function(geometry, pointToLayer) {
var coords = geometry.coordinates,
latlng, latlngs,
i, len,
layer,
layers = [];
switch (geometry.type) {
case 'Point':
latlng = this.coordsToLatLng(coords);
return pointToLayer ? pointToLayer(latlng) : new L.Marker(latlng);
case 'MultiPoint':
for (i = 0, len = coords.length; i < len; i++) {
latlng = this.coordsToLatLng(coords[i]);
layer = pointToLayer ? pointToLayer(latlng) : new L.Marker(latlng);
layers.push(layer);
}
return new L.FeatureGroup(layers);
case 'LineString':
latlngs = this.coordsToLatLngs(coords);
return new L.Polyline(latlngs);
case 'Polygon':
latlngs = this.coordsToLatLngs(coords, 1);
return new L.Polygon(latlngs);
case 'MultiLineString':
latlngs = this.coordsToLatLngs(coords, 1);
return new L.MultiPolyline(latlngs);
case "MultiPolygon":
latlngs = this.coordsToLatLngs(coords, 2);
return new L.MultiPolygon(latlngs);
case "GeometryCollection":
for (i = 0, len = geometry.geometries.length; i < len; i++) {
layer = this.geometryToLayer(geometry.geometries[i]);
layers.push(layer);
}
return new L.FeatureGroup(layers);
default:
throw new Error('Invalid GeoJSON object.');
}
},
coordsToLatLng: function(/*Array*/ coords, /*Boolean*/ reverse)/*: LatLng*/ {
var lat = parseFloat(coords[reverse ? 0 : 1]),
lng = parseFloat(coords[reverse ? 1 : 0]);
return new L.LatLng(lat, lng);
},
coordsToLatLngs: function(/*Array*/ coords, /*Number*/ levelsDeep, /*Boolean*/ reverse)/*: Array*/ {
var latlng, latlngs = [],
i, len = coords.length;
for (i = 0; i < len; i++) {
latlng = levelsDeep ?
this.coordsToLatLngs(coords[i], levelsDeep - 1, reverse) :
this.coordsToLatLng(coords[i], reverse);
latlngs.push(latlng);
}
return latlngs;
}
});

View File

@ -0,0 +1,58 @@
L.ImageOverlay = L.Class.extend({
includes: L.Mixin.Events,
initialize: function(/*String*/ url, /*LatLngBounds*/ bounds) {
this._url = url;
this._bounds = bounds;
},
onAdd: function(map) {
this._map = map;
if (!this._image) {
this._initImage();
}
map.getPanes().overlayPane.appendChild(this._image);
map.on('viewreset', this._reset, this);
this._reset();
},
onRemove: function(map) {
map.getPanes().overlayPane.removeChild(this._image);
map.off('viewreset', this._reset, this);
},
_initImage: function() {
this._image = L.DomUtil.create('img', 'leaflet-image-layer');
this._image.style.visibility = 'hidden';
//TODO opacity option
//TODO createImage util method to remove duplication
L.Util.extend(this._image, {
galleryimg: 'no',
onselectstart: L.Util.falseFn,
onmousemove: L.Util.falseFn,
onload: this._onImageLoad,
src: this._url
});
},
_reset: function() {
var topLeft = this._map.latLngToLayerPoint(this._bounds.getNorthWest()),
bottomRight = this._map.latLngToLayerPoint(this._bounds.getSouthEast()),
size = bottomRight.subtract(topLeft);
L.DomUtil.setPosition(this._image, topLeft);
this._image.style.width = size.x + 'px';
this._image.style.height = size.y + 'px';
},
_onImageLoad: function() {
this.style.visibility = '';
//TODO fire layerload
}
});

View File

@ -0,0 +1,58 @@
/*
* L.LayerGroup is a class to combine several layers so you can manipulate the group (e.g. add/remove it) as one layer.
*/
L.LayerGroup = L.Class.extend({
initialize: function(layers) {
this._layers = {};
if (layers) {
for (var i = 0, len = layers.length; i < len; i++) {
this.addLayer(layers[i]);
}
}
},
addLayer: function(layer) {
var id = L.Util.stamp(layer);
this._layers[id] = layer;
if (this._map) {
this._map.addLayer(layer);
}
return this;
},
removeLayer: function(layer) {
var id = L.Util.stamp(layer);
delete this._layers[id];
if (this._map) {
this._map.removeLayer(layer);
}
return this;
},
clearLayers: function() {
this._iterateLayers(this.removeLayer, this);
return this;
},
onAdd: function(map) {
this._map = map;
this._iterateLayers(map.addLayer, map);
},
onRemove: function(map) {
this._iterateLayers(map.removeLayer, map);
delete this._map;
},
_iterateLayers: function(method, context) {
for (var i in this._layers) {
if (this._layers.hasOwnProperty(i)) {
method.call(context, this._layers[i]);
}
}
}
});

View File

@ -0,0 +1,165 @@
L.Popup = L.Class.extend({
includes: L.Mixin.Events,
options: {
maxWidth: 300,
autoPan: true,
closeButton: true,
offset: new L.Point(0, 2),
autoPanPadding: new L.Point(5, 5)
},
initialize: function(options) {
L.Util.setOptions(this, options);
},
onAdd: function(map) {
this._map = map;
if (!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'; //TODO fix ugly opacity hack
this._opened = true;
},
onRemove: function(map) {
map._panes.popupPane.removeChild(this._container);
map.off('viewreset', this._updatePosition, this);
map.off('click', this._close, this);
this._container.style.opacity = '0';
this._opened = false;
},
setLatLng: function(latlng) {
this._latlng = latlng;
if (this._opened) {
this._update();
}
return this;
},
setContent: function(content) {
this._content = content;
if (this._opened) {
this._update();
}
return this;
},
_close: function() {
if (this._opened) {
this._map.removeLayer(this);
}
},
_initLayout: function() {
this._container = L.DomUtil.create('div', 'leaflet-popup');
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) return;
if (typeof this._content == 'string') {
this._contentNode.innerHTML = this._content;
} else {
this._contentNode.innerHTML = '';
this._contentNode.appendChild(this._content);
}
},
_updateLayout: function() {
this._container.style.width = '';
this._container.style.whiteSpace = 'nowrap';
var width = this._container.offsetWidth;
this._container.style.width = (width > this.options.maxWidth ? this.options.maxWidth : width) + 'px';
this._container.style.whiteSpace = '';
this._containerWidth = this._container.offsetWidth;
},
_updatePosition: function() {
var pos = this._map.latLngToLayerPoint(this._latlng);
this._containerBottom = -pos.y - this.options.offset.y;
this._containerLeft = pos.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) { return; }
var containerHeight = this._container.offsetHeight,
layerPos = new L.Point(
this._containerLeft,
-containerHeight - this._containerBottom),
containerPos = this._map.layerPointToContainerPoint(layerPos),
adjustOffset = new L.Point(0, 0),
padding = this.options.autoPanPadding,
size = this._map.getSize();
if (containerPos.x < 0) {
adjustOffset.x = containerPos.x - padding.x;
}
if (containerPos.x + this._containerWidth > size.x) {
adjustOffset.x = containerPos.x + this._containerWidth - size.x + padding.x;
}
if (containerPos.y < 0) {
adjustOffset.y = containerPos.y - padding.y;
}
if (containerPos.y + containerHeight > size.y) {
adjustOffset.y = containerPos.y + containerHeight - size.y + padding.y;
}
if (adjustOffset.x || adjustOffset.y) {
this._map.panBy(adjustOffset);
}
},
_onCloseButtonClick: function(e) {
this._close();
L.DomEvent.stop(e);
}
});

View File

@ -0,0 +1,56 @@
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(iconUrl) {
if (iconUrl) {
this.iconUrl = iconUrl;
}
},
createIcon: function() {
return this._createIcon('icon');
},
createShadow: function() {
return this._createIcon('shadow');
},
_createIcon: function(name) {
var size = this[name + 'Size'],
src = this[name + 'Url'],
img = this._createImg(src);
if (!src) { return null; }
img.className = 'leaflet-marker-' + name;
img.style.marginLeft = (-this.iconAnchor.x) + 'px';
img.style.marginTop = (-this.iconAnchor.y) + 'px';
if (size) {
img.style.width = size.x + 'px';
img.style.height = size.y + 'px';
}
return img;
},
_createImg: function(src) {
var el;
if (!L.Browser.ie6) {
el = document.createElement('img');
el.src = src;
} else {
el = document.createElement('div');
el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + src + '")';
}
return el;
}
});

View File

@ -0,0 +1,28 @@
/*
* Popup extension to L.Marker, adding openPopup & bindPopup methods.
*/
L.Marker.include({
openPopup: function() {
this._popup.setLatLng(this._latlng);
this._map.openPopup(this._popup);
return this;
},
closePopup: function() {
if (this._popup) {
this._popup._close();
}
},
bindPopup: function(content, options) {
options = L.Util.extend({offset: this.options.icon.popupAnchor}, options);
this._popup = new L.Popup(options);
this._popup.setContent(content);
this.on('click', this.openPopup, this);
return this;
}
});

View File

@ -0,0 +1,123 @@
/*
* L.Marker is used to display clickable/draggable icons on the map.
*/
L.Marker = L.Class.extend({
includes: L.Mixin.Events,
options: {
icon: new L.Icon(),
title: '',
clickable: true,
draggable: false
},
initialize: function(latlng, options) {
L.Util.setOptions(this, options);
this._latlng = latlng;
},
onAdd: function(map) {
this._map = map;
this._initIcon();
map.on('viewreset', this._reset, this);
this._reset();
},
onRemove: function(map) {
this._removeIcon();
map.off('viewreset', this._reset, this);
},
getLatLng: function() {
return this._latlng;
},
setLatLng: function(latlng) {
this._latlng = latlng;
this._reset();
},
setIcon: function(icon) {
this._removeIcon();
this._icon = this._shadow = null;
this.options.icon = icon;
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);
if (this._shadow) {
this._map._panes.shadowPane.appendChild(this._shadow);
}
},
_removeIcon: function() {
this._map._panes.markerPane.removeChild(this._icon);
if (this._shadow) {
this._map._panes.shadowPane.removeChild(this._shadow);
}
},
_reset: function() {
var pos = this._map.latLngToLayerPoint(this._latlng).round();
L.DomUtil.setPosition(this._icon, pos);
if (this._shadow) {
L.DomUtil.setPosition(this._shadow, pos);
}
this._icon.style.zIndex = pos.y;
},
_initInteraction: function() {
if (this.options.clickable) {
this._icon.className += ' leaflet-clickable';
L.DomEvent.addListener(this._icon, 'click', this._onMouseClick, this);
var events = ['dblclick', 'mousedown', 'mouseover', 'mouseout'];
for (var i = 0; i < events.length; i++) {
L.DomEvent.addListener(this._icon, events[i], this._fireMouseEvent, this);
}
}
if (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);
}
});

View File

@ -0,0 +1,41 @@
L.TileLayer.Canvas = L.TileLayer.extend({
options: {
async: false
},
initialize: function(options) {
L.Util.setOptions(this, options);
},
_createTileProto: function() {
this._canvasProto = L.DomUtil.create('canvas', 'leaflet-tile');
var tileSize = this.options.tileSize;
this._canvasProto.width = tileSize;
this._canvasProto.height = tileSize;
},
_createTile: function() {
var tile = this._canvasProto.cloneNode(false);
tile.onselectstart = tile.onmousemove = L.Util.falseFn;
return tile;
},
_loadTile: function(tile, tilePoint, zoom) {
tile._layer = this;
this.drawTile(tile, tilePoint, zoom);
if (!this.options.async) {
this.tileDrawn(tile);
}
},
drawTile: function(tile, tilePoint, zoom) {
// override with rendering code
},
tileDrawn: function(tile) {
this._tileOnLoad.call(tile);
}
});

View File

@ -0,0 +1,47 @@
L.TileLayer.WMS = L.TileLayer.extend({
defaultWmsParams: {
service: 'WMS',
request: 'GetMap',
version: '1.1.1',
layers: '',
styles: '',
format: 'image/jpeg',
transparent: false
},
initialize: function(/*String*/ url, /*Object*/ options) {
this._url = url;
this.wmsParams = L.Util.extend({}, this.defaultWmsParams);
this.wmsParams.width = this.wmsParams.height = this.options.tileSize;
for (var i in options) {
// all keys that are not TileLayer options go to WMS params
if (!this.options.hasOwnProperty(i)) {
this.wmsParams[i] = options[i];
}
}
L.Util.setOptions(this, options);
},
onAdd: function(map) {
var projectionKey = (parseFloat(this.wmsParams.version) >= 1.3 ? 'crs' : 'srs');
this.wmsParams[projectionKey] = map.options.crs.code;
L.TileLayer.prototype.onAdd.call(this, map);
},
getTileUrl: function(/*Point*/ tilePoint, /*Number*/ zoom)/*-> String*/ {
var tileSize = this.options.tileSize,
nwPoint = tilePoint.multiplyBy(tileSize),
sePoint = nwPoint.add(new L.Point(tileSize, tileSize)),
nwMap = this._map.unproject(nwPoint, this._zoom, true),
seMap = this._map.unproject(sePoint, this._zoom, true),
nw = this._map.options.crs.project(nwMap),
se = this._map.options.crs.project(seMap),
bbox = [nw.x, se.y, se.x, nw.y].join(',');
return this._url + L.Util.getParamString(this.wmsParams) + "&bbox=" + bbox;
}
});

Some files were not shown because too many files have changed in this diff Show More