Merge branch 'leaflet'
BIN
vendor/assets/leaflet/images/layers.png
vendored
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
vendor/assets/leaflet/images/marker-icon.png
vendored
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
vendor/assets/leaflet/images/marker-shadow.png
vendored
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
vendor/assets/leaflet/images/zoom-in.png
vendored
Normal file
After Width: | Height: | Size: 955 B |
BIN
vendor/assets/leaflet/images/zoom-out.png
vendored
Normal file
After Width: | Height: | Size: 955 B |
BIN
vendor/assets/leaflet/img/filter-icon.png
vendored
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
vendor/assets/leaflet/img/move-handle.png
vendored
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
vendor/assets/leaflet/img/resize-handle.png
vendored
Normal file
After Width: | Height: | Size: 1,017 B |
401
vendor/assets/leaflet/leaflet.css
vendored
Normal 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
|
@ -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
78
vendor/assets/leaflet/leaflet.locationfilter.css
vendored
Normal 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;
|
||||
}
|
493
vendor/assets/leaflet/leaflet.locationfilter.js
vendored
Normal 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
|
@ -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
|
@ -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
|
@ -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;
|
||||
}
|
||||
});
|