Merge branch 'leaflet'

This commit is contained in:
Tom Hughes 2012-11-23 10:41:45 +00:00
commit 7d92ec7047
61 changed files with 10245 additions and 1696 deletions

BIN
vendor/assets/leaflet/images/layers.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
vendor/assets/leaflet/images/zoom-in.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,017 B

401
vendor/assets/leaflet/leaflet.css vendored Normal file
View file

@ -0,0 +1,401 @@
/* 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,
.leaflet-layer {
position: absolute;
left: 0;
}
.leaflet-container {
overflow: hidden;
-ms-touch-action: none;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
/* map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container img {
max-width: none !important;
}
/* stupid Android 2 doesn't understand "max-width: none" properly */
.leaflet-container img.leaflet-image-layer {
max-width: 15000px !important;
}
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
}
.leaflet-tile-pane { z-index: 2; }
.leaflet-objects-pane { z-index: 3; }
.leaflet-overlay-pane { z-index: 4; }
.leaflet-shadow-pane { z-index: 5; }
.leaflet-marker-pane { z-index: 6; }
.leaflet-popup-pane { z-index: 7; }
/* control positioning */
.leaflet-control {
position: relative;
z-index: 7;
pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
position: absolute;
z-index: 1000;
pointer-events: none;
}
.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;
}
/* zoom and fade animations */
.leaflet-fade-anim .leaflet-tile,
.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-tile-loaded,
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
-o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile,
.leaflet-touching .leaflet-zoom-animated {
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* cursors */
.leaflet-clickable {
cursor: pointer;
}
.leaflet-container {
cursor: -webkit-grab;
cursor: -moz-grab;
}
.leaflet-popup-pane,
.leaflet-control {
cursor: auto;
}
.leaflet-dragging,
.leaflet-dragging .leaflet-clickable,
.leaflet-dragging .leaflet-container {
cursor: move;
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
}
/* visual tweaks */
.leaflet-container {
background: #ddd;
outline: 0;
}
.leaflet-container a {
color: #0078A8;
}
.leaflet-container a.leaflet-active {
outline: 2px solid orange;
}
.leaflet-zoom-box {
border: 2px dotted #05f;
background: white;
opacity: 0.5;
}
/* general typography */
.leaflet-container {
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
}
/* zoom control */
.leaflet-control-zoom {
-webkit-border-radius: 7px;
border-radius: 7px;
}
.leaflet-control-zoom {
padding: 5px;
background: rgba(0, 0, 0, 0.25);
}
.leaflet-control-zoom a {
width: 19px;
height: 19px;
background-color: rgba(255, 255, 255, 0.75);
-webkit-border-radius: 4px;
border-radius: 4px;
}
.leaflet-control-zoom a,
.leaflet-control-layers-toggle {
background-position: 50% 50%;
background-repeat: no-repeat;
display: block;
}
.leaflet-control-zoom a:hover {
background-color: #fff;
}
.leaflet-touch .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);
}
/* layers control */
.leaflet-control-layers {
box-shadow: 0 1px 7px #999;
background: #f8f8f9;
-webkit-border-radius: 8px;
border-radius: 8px;
}
.leaflet-control-layers-toggle {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
.leaflet-touch .leaflet-control-layers-toggle {
width: 44px;
height: 44px;
}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
display: none;
}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
display: block;
position: relative;
}
.leaflet-control-layers-expanded {
padding: 6px 10px 6px 6px;
color: #333;
background: #fff;
}
.leaflet-control-layers-selector {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-layers label {
display: block;
}
.leaflet-control-layers-separator {
height: 0;
border-top: 1px solid #ddd;
margin: 5px -10px 5px -6px;
}
/* attribution and scale controls */
.leaflet-container .leaflet-control-attribution {
background-color: rgba(255, 255, 255, 0.7);
box-shadow: 0 0 5px #bbb;
margin: 0;
}
.leaflet-control-attribution,
.leaflet-control-scale-line {
padding: 0 5px;
color: #333;
}
.leaflet-container .leaflet-control-attribution,
.leaflet-container .leaflet-control-scale {
font-size: 11px;
}
.leaflet-left .leaflet-control-scale {
margin-left: 5px;
}
.leaflet-bottom .leaflet-control-scale {
margin-bottom: 5px;
}
.leaflet-control-scale-line {
border: 2px solid #777;
border-top: none;
color: black;
line-height: 1;
font-size: 10px;
padding-bottom: 2px;
text-shadow: 1px 1px 1px #fff;
background-color: rgba(255, 255, 255, 0.5);
}
.leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777;
padding-top: 1px;
border-bottom: none;
margin-top: -2px;
}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
border-bottom: 2px solid #777;
}
.leaflet-touch .leaflet-control-attribution, .leaflet-touch .leaflet-control-layers {
box-shadow: none;
}
.leaflet-touch .leaflet-control-layers {
border: 5px solid #bbb;
}
/* popup */
.leaflet-popup {
position: absolute;
text-align: center;
}
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
-webkit-border-radius: 20px;
border-radius: 20px;
}
.leaflet-popup-content {
margin: 14px 20px;
line-height: 1.4;
}
.leaflet-popup-content p {
margin: 18px 0;
}
.leaflet-popup-tip-container {
margin: 0 auto;
width: 40px;
height: 20px;
position: relative;
overflow: hidden;
}
.leaflet-popup-tip {
width: 15px;
height: 15px;
padding: 1px;
margin: -8px auto 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
background: white;
box-shadow: 0 3px 14px rgba(0,0,0,0.35);
-webkit-box-shadow: 0 3px 18px rgba(0,0,0,0.33);
}
.leaflet-container a.leaflet-popup-close-button {
position: absolute;
top: 0;
right: 0;
padding: 4px 5px 0 0;
text-align: center;
width: 18px;
height: 14px;
font: 16px/14px Tahoma, Verdana, sans-serif;
color: #c3c3c3;
text-decoration: none;
font-weight: bold;
}
.leaflet-container a.leaflet-popup-close-button:hover {
color: #999;
}
.leaflet-popup-scrolled {
overflow: auto;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
}
/* div icon */
.leaflet-div-icon {
background: #fff;
border: 1px solid #666;
}
.leaflet-editing-icon {
-webkit-border-radius: 2px;
border-radius: 2px;
}

47
vendor/assets/leaflet/leaflet.ie.css vendored Normal file
View file

@ -0,0 +1,47 @@
.leaflet-vml-shape {
width: 1px;
height: 1px;
}
.lvml {
behavior: url(#default#VML);
display: inline-block;
position: absolute;
}
.leaflet-control {
display: inline;
}
.leaflet-popup-tip {
width: 21px;
_width: 27px;
margin: 0 auto;
_margin-top: -3px;
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
}
.leaflet-popup-tip-container {
margin-top: -1px;
}
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
border: 1px solid #bbb;
}
.leaflet-control-zoom {
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#3F000000',EndColorStr='#3F000000');
}
.leaflet-control-zoom a {
background-color: #eee;
}
.leaflet-control-zoom a:hover {
background-color: #fff;
}
.leaflet-control-layers-toggle {
}
.leaflet-control-attribution, .leaflet-control-layers {
background: white;
}
.leaflet-zoom-box {
filter: alpha(opacity=50);
}

8008
vendor/assets/leaflet/leaflet.js vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,78 @@
div.leaflet-marker-icon.location-filter.resize-marker {
background: url( img/resize-handle.png ) no-repeat;
cursor: move;
}
div.leaflet-marker-icon.location-filter.move-marker {
background: url( img/move-handle.png ) no-repeat;
cursor: move;
}
div.location-filter.button-container {
background: #bfbfbf;
background: rgba(0, 0, 0, 0.25);
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
border-radius: 7px;
padding: 5px;
}
.leaflet-container div.location-filter.button-container a {
display: inline-block;
color: #0F2416;
font-size: 11px;
font-weight: normal;
text-shadow: #A1BB9C 0 1px;
padding: 6px 7px;
border: 1px solid #9CC5A4;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
-webkit-box-shadow: inset rgba(255,255,255,0.75) 0 1px 1px;
-moz-box-shadow: inset rgba(255,255,255,0.75) 0 1px 1px;
box-shadow: inset rgba(255,255,255,0.75) 0 1px 1px;
background: #c4e3b9;
background: rgba(218, 252, 205, 0.9);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(218, 252, 205, 0.9)), color-stop(100%, rgba(173, 226, 176, 0.9)));
background: -webkit-linear-gradient(top, rgba(218, 252, 205, 0.9) 0%, rgba(173, 226, 176, 0.9) 100%);
background: -moz-linear-gradient(top, rgba(218, 252, 205, 0.9) 0%, rgba(173, 226, 176, 0.9) 100%);
background: -ms-linear-gradient(top, rgba(218, 252, 205, 0.9) 0%, rgba(173, 226, 176, 0.9) 100%);
background: -o-linear-gradient(top, rgba(218, 252, 205, 0.9) 0%, rgba(173, 226, 176, 0.9) 100%);
background: linear-gradient(top, rgba(218, 252, 205, 0.9) 0%, rgba(173, 226, 176, 0.9) 100%);
}
.leaflet-container div.location-filter.button-container a:hover {
color: #263F1C;
background: #dde6d8;
background: rgba(245, 255, 240, 0.9);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(245, 255, 240, 0.9)), color-stop(100%, rgba(203, 228, 205, 0.9)));
background: -webkit-linear-gradient(top, rgba(245, 255, 240, 0.9) 0%, rgba(203, 228, 205, 0.9) 100%);
background: -moz-linear-gradient(top, rgba(245, 255, 240, 0.9) 0%, rgba(203, 228, 205, 0.9) 100%);
background: -ms-linear-gradient(top, rgba(245, 255, 240, 0.9) 0%, rgba(203, 228, 205, 0.9) 100%);
background: -o-linear-gradient(top, rgba(245, 255, 240, 0.9) 0%, rgba(203, 228, 205, 0.9) 100%);
background: linear-gradient(top, rgba(245, 255, 240, 0.9) 0%, rgba(203, 228, 205, 0.9) 100%);
}
.leaflet-container div.location-filter.button-container a.enable-button {
padding: 6px 7px 6px 25px;
background-image: url( img/filter-icon.png ), -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(218, 252, 205, 0.9)), color-stop(100%, rgba(173, 226, 176, 0.9)));
background-image: url( img/filter-icon.png ), -webkit-linear-gradient(top, rgba(218, 252, 205, 0.9) 0%, rgba(173, 226, 176, 0.9) 100%);
background-image: url( img/filter-icon.png ), -moz-linear-gradient(top, rgba(218, 252, 205, 0.9) 0%, rgba(173, 226, 176, 0.9) 100%);
background-image: url( img/filter-icon.png ), -ms-linear-gradient(top, rgba(218, 252, 205, 0.9) 0%, rgba(173, 226, 176, 0.9) 100%);
background-image: url( img/filter-icon.png ), -o-linear-gradient(top, rgba(218, 252, 205, 0.9) 0%, rgba(173, 226, 176, 0.9) 100%);
background-image: url( img/filter-icon.png ), linear-gradient(top, rgba(218, 252, 205, 0.9) 0%, rgba(173, 226, 176, 0.9) 100%);
background-repeat: no-repeat;
background-position: left center;
}
.leaflet-container div.location-filter.button-container a.enable-button:hover,
.leaflet-container div.location-filter.button-container.enabled a.enable-button {
background-image: url( img/filter-icon.png ), -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(245, 255, 240, 0.9)), color-stop(100%, rgba(203, 228, 205, 0.9)));
background-image: url( img/filter-icon.png ), -webkit-linear-gradient(top, rgba(245, 255, 240, 0.9) 0%, rgba(203, 228, 205, 0.9) 100%);
background-image: url( img/filter-icon.png ), -moz-linear-gradient(top, rgba(245, 255, 240, 0.9) 0%, rgba(203, 228, 205, 0.9) 100%);
background-image: url( img/filter-icon.png ), -ms-linear-gradient(top, rgba(245, 255, 240, 0.9) 0%, rgba(203, 228, 205, 0.9) 100%);
background-image: url( img/filter-icon.png ), -o-linear-gradient(top, rgba(245, 255, 240, 0.9) 0%, rgba(203, 228, 205, 0.9) 100%);
background-image: url( img/filter-icon.png ), linear-gradient(top, rgba(245, 255, 240, 0.9) 0%, rgba(203, 228, 205, 0.9) 100%);
background-repeat: no-repeat;
background-position: left center;
}
.leaflet-container div.location-filter.button-container a.adjust-button {
margin-left: 2px;
}

View file

@ -0,0 +1,493 @@
/*
* Leaflet.locationfilter - leaflet location filter plugin
* Copyright (C) 2012, Tripbirds.com
* http://tripbirds.com
*
* Licensed under the MIT License.
*
* Date: 2012-09-24
* Version: 0.1
*/
L.LatLngBounds.prototype.modify = function(map, amount) {
var sw = this.getSouthWest(),
ne = this.getNorthEast(),
swPoint = map.latLngToLayerPoint(sw),
nePoint = map.latLngToLayerPoint(ne);
sw = map.layerPointToLatLng(new L.Point(swPoint.x-amount, swPoint.y+amount));
ne = map.layerPointToLatLng(new L.Point(nePoint.x+amount, nePoint.y-amount));
return new L.LatLngBounds(sw, ne);
};
L.Control.Button = L.Class.extend({
initialize: function(options) {
L.Util.setOptions(this, options);
},
addTo: function(container) {
container.addButton(this);
return this;
},
onAdd: function (buttonContainer) {
this._buttonContainer = buttonContainer;
this._button = L.DomUtil.create('a', this.options.className, this._buttonContainer.getContainer());
this._button.href = '#';
this.setText(this.options.text);
var that = this;
this._onClick = function(event) {
that.options.onClick.call(that, event);
};
L.DomEvent
.on(this._button, 'click', L.DomEvent.stopPropagation)
.on(this._button, 'mousedown', L.DomEvent.stopPropagation)
.on(this._button, 'dblclick', L.DomEvent.stopPropagation)
.on(this._button, 'click', L.DomEvent.preventDefault)
.on(this._button, 'click', this._onClick, this);
},
remove: function() {
L.DomEvent.off(this._button, "click", this._onClick);
this._buttonContainer.getContainer().removeChild(this._button);
},
setText: function(text) {
this._button.title = text;
this._button.innerHTML = text;
}
});
L.Control.ButtonContainer = L.Control.extend({
options: {
position: 'topleft'
},
getContainer: function() {
if (!this._container) {
this._container = L.DomUtil.create('div', this.options.className);
}
return this._container;
},
onAdd: function (map) {
this._map = map;
return this.getContainer();
},
addButton: function(button) {
button.onAdd(this);
},
addClass: function(className) {
L.DomUtil.addClass(this.getContainer(), className);
},
removeClass: function(className) {
L.DomUtil.removeClass(this.getContainer(), className);
}
});
L.LocationFilter = L.Class.extend({
includes: L.Mixin.Events,
options: {
enableButton: {
enableText: "Select area",
disableText: "Remove selection"
},
adjustButton: {
text: "Select area within current zoom"
}
},
initialize: function(options) {
L.Util.setOptions(this, options);
},
addTo: function(map) {
map.addLayer(this);
return this;
},
onAdd: function(map) {
this._map = map;
this._layer = new L.LayerGroup();
if (this.options.enableButton || this.options.adjustButton) {
this._initializeButtonContainer();
}
if (this.options.enable) {
this.enable();
}
},
onRemove: function(map) {
this.disable();
if (this._buttonContainer) {
this._buttonContainer.removeFrom(map);
}
},
/* Get the current filter bounds */
getBounds: function() {
return new L.LatLngBounds(this._sw, this._ne);
},
setBounds: function(bounds) {
this._nw = bounds.getNorthWest();
this._ne = bounds.getNorthEast();
this._sw = bounds.getSouthWest();
this._se = bounds.getSouthEast();
if (this.isEnabled()) {
this._draw();
this.fire("change", {bounds: bounds});
}
},
isEnabled: function() {
return this._enabled;
},
/* Draw a rectangle */
_drawRectangle: function(bounds, options) {
options = options || {};
var defaultOptions = {
stroke: false,
fill: true,
fillColor: "black",
fillOpacity: 0.3,
clickable: false
};
options = L.Util.extend(defaultOptions, options);
var rect = new L.Rectangle(bounds, options);
rect.addTo(this._layer);
return rect;
},
/* Draw a draggable marker */
_drawImageMarker: function(point, options) {
var marker = new L.Marker(point, {
icon: new L.DivIcon({
iconAnchor: options.anchor,
iconSize: options.size,
className: options.className
}),
draggable: true
});
marker.addTo(this._layer);
return marker;
},
/* Draw a move marker. Sets up drag listener that updates the
filter corners and redraws the filter when the move marker is
moved */
_drawMoveMarker: function(point) {
var that = this;
this._moveMarker = this._drawImageMarker(point, {
"className": "location-filter move-marker",
"anchor": [-10, -10],
"size": [13,13]
});
this._moveMarker.on('drag', function(e) {
var markerPos = that._moveMarker.getLatLng(),
latDelta = markerPos.lat-that._nw.lat,
lngDelta = markerPos.lng-that._nw.lng;
that._nw = new L.LatLng(that._nw.lat+latDelta, that._nw.lng+lngDelta, true);
that._ne = new L.LatLng(that._ne.lat+latDelta, that._ne.lng+lngDelta, true);
that._sw = new L.LatLng(that._sw.lat+latDelta, that._sw.lng+lngDelta, true);
that._se = new L.LatLng(that._se.lat+latDelta, that._se.lng+lngDelta, true);
that._draw();
});
this._setupDragendListener(this._moveMarker);
return this._moveMarker;
},
/* Draw a resize marker */
_drawResizeMarker: function(point, latFollower, lngFollower, otherPos) {
return this._drawImageMarker(point, {
"className": "location-filter resize-marker",
"anchor": [7, 6],
"size": [13, 12]
});
},
/* Track moving of the given resize marker and update the markers
given in options.moveAlong to match the position of the moved
marker. Update filter corners and redraw the filter */
_setupResizeMarkerTracking: function(marker, options) {
var that = this;
marker.on('drag', function(e) {
var curPosition = marker.getLatLng(),
latMarker = options.moveAlong.lat,
lngMarker = options.moveAlong.lng;
// Move follower markers when this marker is moved
latMarker.setLatLng(new L.LatLng(curPosition.lat, latMarker.getLatLng().lng, true));
lngMarker.setLatLng(new L.LatLng(lngMarker.getLatLng().lat, curPosition.lng, true));
// Sort marker positions in nw, ne, sw, se order
var corners = [that._nwMarker.getLatLng(),
that._neMarker.getLatLng(),
that._swMarker.getLatLng(),
that._seMarker.getLatLng()];
corners.sort(function(a, b) {
if (a.lat != b.lat)
return b.lat-a.lat;
else
return a.lng-b.lng;
});
// Update corner points and redraw everything except the resize markers
that._nw = corners[0];
that._ne = corners[1];
that._sw = corners[2];
that._se = corners[3];
that._draw({repositionResizeMarkers: false});
});
this._setupDragendListener(marker);
},
/* Emit a change event whenever dragend is triggered on the
given marker */
_setupDragendListener: function(marker) {
var that = this;
marker.on('dragend', function(e) {
that.fire("change", {bounds: that.getBounds()});
});
},
/* Create bounds for the mask rectangles and the location
filter rectangle */
_calculateBounds: function() {
var mapBounds = this._map.getBounds(),
outerBounds = new L.LatLngBounds(
new L.LatLng(mapBounds.getSouthWest().lat-0.1,
mapBounds.getSouthWest().lng-0.1, true),
new L.LatLng(mapBounds.getNorthEast().lat+0.1,
mapBounds.getNorthEast().lng+0.1, true)
);
// The south west and north east points of the mask */
this._osw = outerBounds.getSouthWest();
this._one = outerBounds.getNorthEast();
// Bounds for the mask rectangles
this._northBounds = new L.LatLngBounds(new L.LatLng(this._ne.lat, this._osw.lng, true), this._one);
this._westBounds = new L.LatLngBounds(new L.LatLng(this._sw.lat, this._osw.lng, true), this._nw);
this._eastBounds = new L.LatLngBounds(this._se, new L.LatLng(this._ne.lat, this._one.lng, true));
this._southBounds = new L.LatLngBounds(this._osw, new L.LatLng(this._sw.lat, this._one.lng, true));
},
/* Initializes rectangles and markers */
_initialDraw: function() {
if (this._initialDrawCalled) {
return;
}
// Calculate filter bounds
this._calculateBounds();
// Create rectangles
this._northRect = this._drawRectangle(this._northBounds);
this._westRect = this._drawRectangle(this._westBounds);
this._eastRect = this._drawRectangle(this._eastBounds);
this._southRect = this._drawRectangle(this._southBounds);
this._innerRect = this._drawRectangle(this.getBounds(), {
fillColor: "transparent",
stroke: true,
color: "white",
weight: 1,
opacity: 0.9
});
// Create resize markers
this._nwMarker = this._drawResizeMarker(this._nw);
this._neMarker = this._drawResizeMarker(this._ne);
this._swMarker = this._drawResizeMarker(this._sw);
this._seMarker = this._drawResizeMarker(this._se);
// Setup tracking of resize markers. Each marker has pair of
// follower markers that must be moved whenever the marker is
// moved. For example, whenever the north west resize marker
// moves, the south west marker must move along on the x-axis
// and the north east marker must move on the y axis
this._setupResizeMarkerTracking(this._nwMarker, {moveAlong: {lat: this._neMarker, lng: this._swMarker}});
this._setupResizeMarkerTracking(this._neMarker, {moveAlong: {lat: this._nwMarker, lng: this._seMarker}});
this._setupResizeMarkerTracking(this._swMarker, {moveAlong: {lat: this._seMarker, lng: this._nwMarker}});
this._setupResizeMarkerTracking(this._seMarker, {moveAlong: {lat: this._swMarker, lng: this._neMarker}});
// Create move marker
this._moveMarker = this._drawMoveMarker(this._nw);
this._initialDrawCalled = true;
},
/* Reposition all rectangles and markers to the current filter bounds. */
_draw: function(options) {
options = L.Util.extend({repositionResizeMarkers: true}, options);
// Calculate filter bounds
this._calculateBounds();
// Reposition rectangles
this._northRect.setBounds(this._northBounds);
this._westRect.setBounds(this._westBounds);
this._eastRect.setBounds(this._eastBounds);
this._southRect.setBounds(this._southBounds);
this._innerRect.setBounds(this.getBounds());
// Reposition resize markers
if (options.repositionResizeMarkers) {
this._nwMarker.setLatLng(this._nw);
this._neMarker.setLatLng(this._ne);
this._swMarker.setLatLng(this._sw);
this._seMarker.setLatLng(this._se);
}
// Reposition the move marker
this._moveMarker.setLatLng(this._nw);
},
/* Adjust the location filter to the current map bounds */
_adjustToMap: function() {
this.setBounds(this._map.getBounds());
this._map.zoomOut();
},
/* Enable the location filter */
enable: function() {
if (this._enabled) {
return;
}
// Initialize corners
var bounds;
if (this._sw && this._ne) {
bounds = new L.LatLngBounds(this._sw, this._ne);
} else if (this.options.bounds) {
bounds = this.options.bounds;
} else {
bounds = this._map.getBounds();
}
this._map.invalidateSize();
this._nw = bounds.getNorthWest();
this._ne = bounds.getNorthEast();
this._sw = bounds.getSouthWest();
this._se = bounds.getSouthEast();
// Update buttons
if (this._buttonContainer) {
this._buttonContainer.addClass("enabled");
}
if (this._enableButton) {
this._enableButton.setText(this.options.enableButton.disableText);
}
if (this.options.adjustButton) {
this._createAdjustButton();
}
// Draw filter
this._initialDraw();
this._draw();
// Set up map move event listener
var that = this;
this._moveHandler = function() {
that._draw();
};
this._map.on("move", this._moveHandler);
// Add the filter layer to the map
this._layer.addTo(this._map);
// Zoom out the map if necessary
var mapBounds = this._map.getBounds();
bounds = new L.LatLngBounds(this._sw, this._ne).modify(this._map, 10);
if (!mapBounds.contains(bounds.getSouthWest()) || !mapBounds.contains(bounds.getNorthEast())) {
this._map.fitBounds(bounds);
}
this._enabled = true;
// Fire the enabled event
this.fire("enabled");
},
/* Disable the location filter */
disable: function() {
if (!this._enabled) {
return;
}
// Update buttons
if (this._buttonContainer) {
this._buttonContainer.removeClass("enabled");
}
if (this._enableButton) {
this._enableButton.setText(this.options.enableButton.enableText);
}
if (this._adjustButton) {
this._adjustButton.remove();
}
// Remove event listener
this._map.off("move", this._moveHandler);
// Remove rectangle layer from map
this._map.removeLayer(this._layer);
this._enabled = false;
// Fire the disabled event
this.fire("disabled");
},
/* Create a button that allows the user to adjust the location
filter to the current zoom */
_createAdjustButton: function() {
var that = this;
this._adjustButton = new L.Control.Button({
className: "adjust-button",
text: this.options.adjustButton.text,
onClick: function(event) {
that._adjustToMap();
that.fire("adjustToZoomClick");
}
}).addTo(this._buttonContainer);
},
/* Create the location filter button container and the button that
toggles the location filter */
_initializeButtonContainer: function() {
var that = this;
this._buttonContainer = new L.Control.ButtonContainer({className: "location-filter button-container"});
if (this.options.enableButton) {
this._enableButton = new L.Control.Button({
className: "enable-button",
text: this.options.enableButton.enableText,
onClick: function(event) {
if (!that._enabled) {
// Enable the location filter
that.enable();
that.fire("enableClick");
} else {
// Disable the location filter
that.disable();
that.fire("disableClick");
}
}
}).addTo(this._buttonContainer);
}
this._buttonContainer.addTo(this._map);
}
});

200
vendor/assets/leaflet/leaflet.osm.js vendored Normal file
View file

@ -0,0 +1,200 @@
L.OSM = {};
L.OSM.TileLayer = L.TileLayer.extend({
options: {
url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '© <a target="_parent" href="http://www.openstreetmap.org">OpenStreetMap</a> and contributors, under an <a target="_parent" href="http://www.openstreetmap.org/copyright">open license</a>'
},
initialize: function (options) {
options = L.Util.setOptions(this, options);
L.TileLayer.prototype.initialize.call(this, options.url);
}
});
L.OSM.Mapnik = L.OSM.TileLayer.extend({
options: {
url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
}
});
L.OSM.CycleMap = L.OSM.TileLayer.extend({
options: {
url: 'http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png'
}
});
L.OSM.TransportMap = L.OSM.TileLayer.extend({
options: {
url: 'http://{s}.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png'
}
});
L.OSM.MapQuestOpen = L.OSM.TileLayer.extend({
options: {
url: 'http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png',
subdomains: '1234',
attribution: "Tiles courtesy of <a href='http://www.mapquest.com/' target='_blank'>MapQuest</a> <img src='http://developer.mapquest.com/content/osm/mq_logo.png'>"
}
});
L.OSM.DataLayer = L.FeatureGroup.extend({
options: {
areaTags: ['area', 'building', 'leisure', 'tourism', 'ruins', 'historic', 'landuse', 'military', 'natural', 'sport'],
uninterestingTags: ['source', 'source_ref', 'source:ref', 'history', 'attribution', 'created_by', 'tiger:county', 'tiger:tlid', 'tiger:upload_uuid'],
styles: {}
},
initialize: function (xml, options) {
L.Util.setOptions(this, options);
L.FeatureGroup.prototype.initialize.call(this);
if (xml) {
this.addData(xml);
}
},
addData: function (features) {
if (!(features instanceof Array)) {
features = this.buildFeatures(features);
}
for (var i = 0; i < features.length; i++) {
var feature = features[i], layer;
if (feature.type === "node") {
layer = L.circleMarker(feature.latLng, this.options.styles.node);
} else {
var latLngs = new Array(feature.nodes.length);
for (var j = 0; j < feature.nodes.length; j++) {
latLngs[j] = feature.nodes[j].latLng;
}
if (this.isWayArea(feature)) {
latLngs.pop(); // Remove last == first.
layer = L.polygon(latLngs, this.options.styles.area);
} else {
layer = L.polyline(latLngs, this.options.styles.way);
}
}
layer.addTo(this);
layer.feature = feature;
}
},
buildFeatures: function (xml) {
var features = [],
nodes = L.OSM.getNodes(xml),
ways = L.OSM.getWays(xml, nodes);
for (var node_id in nodes) {
var node = nodes[node_id];
if (this.interestingNode(node, ways)) {
features.push(node);
}
}
for (var i = 0; i < ways.length; i++) {
var way = ways[i];
features.push(way);
}
return features;
},
isWayArea: function (way) {
if (way.nodes[0] != way.nodes[way.nodes.length - 1]) {
return false;
}
for (var key in way.tags) {
if (~this.options.areaTags.indexOf(key)) {
return true;
}
}
return false;
},
interestingNode: function (node, ways) {
var used = false;
for (var i = 0; i < ways.length; i++) {
if (ways[i].nodes.indexOf(node) >= 0) {
used = true;
break;
}
}
if (!used) {
return true;
}
for (var key in node.tags) {
if (this.options.uninterestingTags.indexOf(key) < 0) {
return true;
}
}
return false;
}
});
L.Util.extend(L.OSM, {
getNodes: function (xml) {
var result = {};
var nodes = xml.getElementsByTagName("node");
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i], id = node.getAttribute("id");
result[id] = {
id: id,
type: "node",
latLng: L.latLng(node.getAttribute("lat"),
node.getAttribute("lon"),
true),
tags: this.getTags(node)
};
}
return result;
},
getWays: function (xml, nodes) {
var result = [];
var ways = xml.getElementsByTagName("way");
for (var i = 0; i < ways.length; i++) {
var way = ways[i], nds = way.getElementsByTagName("nd");
var way_object = {
id: way.getAttribute("id"),
type: "way",
nodes: new Array(nds.length),
tags: this.getTags(way)
};
for (var j = 0; j < nds.length; j++) {
way_object.nodes[j] = nodes[nds[j].getAttribute("ref")];
}
result.push(way_object);
}
return result;
},
getTags: function (xml) {
var result = {};
var tags = xml.getElementsByTagName("tag");
for (var j = 0; j < tags.length; j++) {
result[tags[j].getAttribute("k")] = tags[j].getAttribute("v");
}
return result;
}
});

52
vendor/assets/leaflet/leaflet.pan.js vendored Normal file
View file

@ -0,0 +1,52 @@
L.Control.Pan = L.Control.extend({
options: {
position: 'topleft',
panOffset: 500
},
onAdd: function (map) {
var className = 'leaflet-control-pan',
container = L.DomUtil.create('div', className),
off = this.options.panOffset;
this._panButton('Up' , className + '-up'
, container, map, new L.Point( 0 , -off));
this._panButton('Left' , className + '-left'
, container, map, new L.Point( -off , 0));
this._panButton('Right', className + '-right'
, container, map, new L.Point( off , 0));
this._panButton('Down' , className + '-down'
, container, map, new L.Point( 0 , off));
return container;
},
_panButton: function (title, className, container, map, offset, text) {
var wrapper = L.DomUtil.create('div', className + "-wrap", container);
var link = L.DomUtil.create('a', className, wrapper);
link.href = '#';
link.title = title;
L.DomEvent
.on(link, 'click', L.DomEvent.stopPropagation)
.on(link, 'click', L.DomEvent.preventDefault)
.on(link, 'click', function(){ map.panBy(offset); }, map)
.on(link, 'dblclick', L.DomEvent.stopPropagation)
return link;
}
});
L.Map.mergeOptions({
panControl: true
});
L.Map.addInitHook(function () {
if (this.options.panControl) {
this.panControl = new L.Control.Pan();
this.addControl(this.panControl);
}
});
L.control.pan = function (options) {
return new L.Control.Pan(options);
};

176
vendor/assets/leaflet/leaflet.zoom.js vendored Normal file
View file

@ -0,0 +1,176 @@
L.Control.Zoomslider = L.Control.extend({
options: {
position: 'topleft',
// height in px of zoom-slider.png
stepHeight: 9
},
onAdd: function (map) {
var className = 'leaflet-control-zoomslider',
container = L.DomUtil.create('div', className);
this._map = map;
this._createButton('Zoom in', className + '-in'
, container, this._zoomIn , this);
this._createSlider(className + '-slider', container, map);
this._createButton('Zoom out', className + '-out'
, container, this._zoomOut, this);
this._map.on('zoomend', this._snapToSliderValue, this);
this._snapToSliderValue();
return container;
},
onRemove: function(map){
map.off('zoomend', this._snapToSliderValue);
},
_createSlider: function (className, container, map) {
var zoomLevels = map.getMaxZoom() - map.getMinZoom();
this._sliderHeight = this.options.stepHeight * zoomLevels;
var wrapper = L.DomUtil.create('div', className + '-wrap', container);
wrapper.style.height = (this._sliderHeight + 5) + "px";
var slider = L.DomUtil.create('div', className, wrapper);
this._knob = L.DomUtil.create('div', className + '-knob', slider);
this._draggable = this._createDraggable();
this._draggable.enable();
L.DomEvent
.on(slider, 'click', L.DomEvent.stopPropagation)
.on(slider, 'click', L.DomEvent.preventDefault)
.on(slider, 'click', this._onSliderClick, this);
return slider;
},
_zoomIn: function (e) {
this._map.zoomIn(e.shiftKey ? 3 : 1);
},
_zoomOut: function (e) {
this._map.zoomOut(e.shiftKey ? 3 : 1);
},
_createButton: function (title, className, container, fn, context) {
var link = L.DomUtil.create('a', className, container);
link.href = '#';
link.title = title;
L.DomEvent
.on(link, 'click', L.DomEvent.stopPropagation)
.on(link, 'click', L.DomEvent.preventDefault)
.on(link, 'click', fn, context);
return link;
},
_createDraggable: function() {
L.DomUtil.setPosition(this._knob, new L.Point(0, 0));
L.DomEvent
.on(this._knob
, L.Draggable.START
, L.DomEvent.stopPropagation)
.on(this._knob, 'click', L.DomEvent.stopPropagation);
var bounds = new L.Bounds(
new L.Point(0, 0),
new L.Point(0, this._sliderHeight)
);
var draggable = new L.BoundedDraggable(this._knob,
this._knob,
bounds)
.on('drag', this._snap, this)
.on('dragend', this._setZoom, this);
return draggable;
},
_snap : function(){
this._snapToSliderValue(this._posToSliderValue());
},
_setZoom: function() {
this._map.setZoom(this._toZoomLevel(this._posToSliderValue()));
},
_onSliderClick: function(e){
var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e);
var offset = first.offsetY
? first.offsetY
: L.DomEvent.getMousePosition(first).y
- L.DomUtil.getViewportOffset(this._knob).y;
var value = this._posToSliderValue(offset - this._knob.offsetHeight / 2);
this._snapToSliderValue(value);
this._map.setZoom(this._toZoomLevel(value));
},
_posToSliderValue: function(pos) {
pos = isNaN(pos)
? L.DomUtil.getPosition(this._knob).y
: pos
return Math.round( (this._sliderHeight - pos) / this.options.stepHeight);
},
_snapToSliderValue: function(sliderValue) {
if(this._knob) {
sliderValue = isNaN(sliderValue)
? this._getSliderValue()
: sliderValue;
var y = this._sliderHeight
- (sliderValue * this.options.stepHeight);
L.DomUtil.setPosition(this._knob, new L.Point(0, y));
}
},
_toZoomLevel: function(sliderValue) {
return sliderValue + this._map.getMinZoom();
},
_toSliderValue: function(zoomLevel) {
return zoomLevel - this._map.getMinZoom();
},
_getSliderValue: function(){
return this._toSliderValue(this._map.getZoom());
}
});
L.Map.mergeOptions({
zoomControl: false,
zoomsliderControl: true
});
L.Map.addInitHook(function () {
if (this.options.zoomsliderControl) {
this.zoomsliderControl = new L.Control.Zoomslider();
this.addControl(this.zoomsliderControl);
}
});
L.control.zoomslider = function (options) {
return new L.Control.Zoomslider(options);
};
L.BoundedDraggable = L.Draggable.extend({
initialize: function(element, dragStartTarget, bounds) {
L.Draggable.prototype.initialize.call(this, element, dragStartTarget);
this._bounds = bounds;
this.on('predrag', function() {
if(!this._bounds.contains(this._newPos)){
this._newPos = this._fitPoint(this._newPos);
}
}, this);
},
_fitPoint: function(point){
var closest = new L.Point(
Math.min(point.x, this._bounds.max.x),
Math.min(point.y, this._bounds.max.y)
);
closest.x = Math.max(closest.x, this._bounds.min.x);
closest.y = Math.max(closest.y, this._bounds.min.y);
return closest;
}
});