check-in bower_components
13
bower_components/leaflet-gpx/.bower.json
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "leaflet-gpx",
|
||||
"homepage": "https://github.com/mpetazzoni/leaflet-gpx",
|
||||
"_release": "f0622fa76e",
|
||||
"_resolution": {
|
||||
"type": "branch",
|
||||
"branch": "master",
|
||||
"commit": "f0622fa76ec80639b530a2348a7b291ed05a4418"
|
||||
},
|
||||
"_source": "git://github.com/mpetazzoni/leaflet-gpx.git",
|
||||
"_target": "*",
|
||||
"_originalSource": "mpetazzoni/leaflet-gpx"
|
||||
}
|
||||
24
bower_components/leaflet-gpx/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
Copyright (C) 2011-2012 Pavel Shramov
|
||||
Copyright (C) 2013 Maxime Petazzoni <maxime.petazzoni@bulix.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
- 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.
|
||||
126
bower_components/leaflet-gpx/README.md
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
GPX plugin for Leaflet
|
||||
======================
|
||||
|
||||
[Leaflet](http://www.leafletjs.com) is a Javascript library for displaying
|
||||
interactive maps. This plugin, based on the work of [Pavel
|
||||
Shramov](http://github.com/shramov) and his
|
||||
[leaflet-plugins](http://github.com/shramov/leaflet-plugins), it allows for the
|
||||
analysis and parsing of a GPX track in order to display it as a Leaflet map
|
||||
layer. As it parses the GPX data, it will record information about the recorded
|
||||
track, including total time, moving time, total distance, elevation stats and
|
||||
heart-rate.
|
||||
|
||||
GPX parsing will automatically handle pauses in the track with a default
|
||||
tolerance interval of 15 seconds between points. You can configure this
|
||||
interval by setting `max_point_interval`, in milliseconds, in the options
|
||||
passed to the `GPX` constructor.
|
||||
|
||||
I've put together a complete example as a
|
||||
[demo](http://mpetazzoni.github.com/leaflet-gpx/).
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
`leaflet-gpx` is under the *BSD 2-clause license*. Please refer to the
|
||||
attached LICENSE file and/or to the copyright header in gpx.js for more
|
||||
information.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Usage is very simple. Let's consider we have a Leaflet map:
|
||||
|
||||
```javascript
|
||||
var map = L.map('map');
|
||||
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: 'Map data © <a href="http://www.osm.org">OpenStreetMap</a>'
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
Displaying the GPX track is as easy as:
|
||||
|
||||
```javascript
|
||||
var gpx = '...'; // URL to your GPX file or the GPX itself
|
||||
new L.GPX(gpx, {async: true}).on('loaded', function(e) {
|
||||
map.fitBounds(e.target.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
If you want to display additional information about the GPX track, you can do
|
||||
so in the 'loaded' event handler, calling one of the following methods on the
|
||||
`GPX` object `e.target`:
|
||||
|
||||
* `get_name()`: returns the name of the GPX track
|
||||
* `get_distance()`: returns the total track distance, in meters
|
||||
* `get_start_time()`: returns a Javascript `Date` object representing the
|
||||
starting time
|
||||
* `get_end_time()`: returns a Javascript `Date` object representing when the
|
||||
last point was recorded
|
||||
* `get_moving_time()`: returns the moving time, in milliseconds
|
||||
* `get_total_time()`: returns the total track time, in milliseconds
|
||||
* `get_moving_pace()`: returns the average moving pace in milliseconds per km
|
||||
* `get_elevation_gain()`: returns the cumulative elevation gain, in meters
|
||||
* `get_elevation_loss()`: returns the cumulative elevation loss, in meters
|
||||
* `get_average_hr()`: returns the average heart rate (if available)
|
||||
|
||||
If you're not a fan of the metric system, you also have the following methods
|
||||
at your disposal:
|
||||
|
||||
* `get_distance_imp()`: returns the total track distance in miles
|
||||
* `get_moving_pace_imp()`: returns the average moving pace in milliseconds per
|
||||
mile
|
||||
|
||||
The reason why these methods return milliseconds is that you have at your
|
||||
disposal a nice helper method to format a duration in milliseconds into a cool
|
||||
string like `3:07'48"` or `59'32.431`:
|
||||
|
||||
* `get_duration_string(duration, hidems)`, where `duration` is in
|
||||
milliseconds and `hidems` is an optional boolean you can use to request never
|
||||
to display millisecond precision.
|
||||
|
||||
You can also get full elevation and heartrate data with:
|
||||
|
||||
* `get_elevation_data()` and `get_elevation_data_imp()`
|
||||
* `get_heartrate_data()` and `get_heartrate_data_imp()`
|
||||
|
||||
These methods all return an array of points `[distance, value, tooltip]` where
|
||||
the distance is either in kilometers or in miles and the elevation in meters of
|
||||
feet, depending on whether you use the `_imp` variant or not. Heart rate,
|
||||
obviously, doesn't change.
|
||||
|
||||
|
||||
About marker icons
|
||||
------------------
|
||||
|
||||
By default `gpx.js` will use `pin-icon-start.png`, `pin-icon-end.png` and
|
||||
`pin-shadow.png` as the marker icons URLs for, respectively, the start marker,
|
||||
the end marker and their drop shadow. Since it might not be convenient that
|
||||
these images have to reside under the same directory as your HTML page, it is
|
||||
possible to override the marker icon URLs and sizes by passing a
|
||||
`marker_options` object to the `GPX` options object.
|
||||
|
||||
The field names are the same as for custom Leaflet icons, as explained in the
|
||||
[Markers with custom icons](http://leafletjs.com/examples/custom-icons.html)
|
||||
page in Leaflet's documentation. The only difference is that instead of
|
||||
`iconUrl` you should specify `startIconUrl` and `endIconUrl` for the start and
|
||||
end markers, respectively.
|
||||
|
||||
Note that you do not need to override all the marker icon options as `gpx.js`
|
||||
will use sensible defaults with sizes matching the provided icon images. Here
|
||||
is how you would override the URL of the provided icons if you decided to place
|
||||
them in an `images/` directory:
|
||||
|
||||
```javascript
|
||||
var url = '...'; // URL to your GPX file
|
||||
new L.GPX(url, {
|
||||
async: true,
|
||||
marker_options: {
|
||||
startIconUrl: 'images/pin-icon-start.png',
|
||||
endIconUrl: 'images/pin-icon-end.png',
|
||||
shadowUrl: 'images/pin-shadow.png'
|
||||
}
|
||||
}).on('loaded', function(e) {
|
||||
map.fitBounds(e.target.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
337
bower_components/leaflet-gpx/gpx.js
vendored
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
/**
|
||||
* Copyright (C) 2011-2012 Pavel Shramov
|
||||
* Copyright (C) 2013 Maxime Petazzoni <maxime.petazzoni@bulix.org>
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Thanks to Pavel Shramov who provided the initial implementation and Leaflet
|
||||
* integration. Original code was at https://github.com/shramov/leaflet-plugins.
|
||||
*
|
||||
* It was then cleaned-up and modified to record and make available more
|
||||
* information about the GPX track while it is being parsed so that the result
|
||||
* can be used to display additional information about the track that is
|
||||
* rendered on the Leaflet map.
|
||||
*/
|
||||
|
||||
var _MAX_POINT_INTERVAL_MS = 15000;
|
||||
var _SECOND_IN_MILLIS = 1000;
|
||||
var _MINUTE_IN_MILLIS = 60 * _SECOND_IN_MILLIS;
|
||||
var _HOUR_IN_MILLIS = 60 * _MINUTE_IN_MILLIS;
|
||||
|
||||
var _DEFAULT_MARKER_OPTS = {
|
||||
startIconUrl: 'pin-icon-start.png',
|
||||
endIconUrl: 'pin-icon-end.png',
|
||||
shadowUrl: 'pin-shadow.png',
|
||||
iconSize: [33, 50],
|
||||
shadowSize: [50, 50],
|
||||
iconAnchor: [16, 45],
|
||||
shadowAnchor: [16, 47]
|
||||
};
|
||||
var _DEFAULT_POLYLINE_OPTS = {
|
||||
color:'blue'
|
||||
};
|
||||
L.GPX = L.FeatureGroup.extend({
|
||||
initialize: function(gpx, options) {
|
||||
options.max_point_interval = options.max_point_interval || _MAX_POINT_INTERVAL_MS;
|
||||
options.marker_options = this._merge_objs(
|
||||
_DEFAULT_MARKER_OPTS,
|
||||
options.marker_options || {});
|
||||
options.polyline_options = this._merge_objs(
|
||||
_DEFAULT_POLYLINE_OPTS,
|
||||
options.polyline_options || {});
|
||||
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
// Base icon class for track pins.
|
||||
L.GPXTrackIcon = L.Icon.extend({ options: options.marker_options });
|
||||
|
||||
this._gpx = gpx;
|
||||
this._layers = {};
|
||||
this._info = {
|
||||
name: null,
|
||||
length: 0.0,
|
||||
elevation: {gain: 0.0, loss: 0.0, _points: []},
|
||||
hr: {avg: 0, _total: 0, _points: []},
|
||||
duration: {start: null, end: null, moving: 0, total: 0},
|
||||
};
|
||||
|
||||
if (gpx) {
|
||||
this._parse(gpx, options, this.options.async);
|
||||
}
|
||||
},
|
||||
|
||||
get_duration_string: function(duration, hidems) {
|
||||
var s = '';
|
||||
|
||||
if (duration >= _HOUR_IN_MILLIS) {
|
||||
s += Math.floor(duration / _HOUR_IN_MILLIS) + ':';
|
||||
duration = duration % _HOUR_IN_MILLIS;
|
||||
}
|
||||
|
||||
var mins = Math.floor(duration / _MINUTE_IN_MILLIS);
|
||||
duration = duration % _MINUTE_IN_MILLIS;
|
||||
if (mins < 10) s += '0';
|
||||
s += mins + '\'';
|
||||
|
||||
var secs = Math.floor(duration / _SECOND_IN_MILLIS);
|
||||
duration = duration % _SECOND_IN_MILLIS;
|
||||
if (secs < 10) s += '0';
|
||||
s += secs;
|
||||
|
||||
if (!hidems && duration > 0) s += '.' + Math.round(Math.floor(duration)*1000)/1000;
|
||||
else s += '"';
|
||||
|
||||
return s;
|
||||
},
|
||||
|
||||
to_miles: function(v) { return v / 1.60934; },
|
||||
to_ft: function(v) { return v * 3.28084; },
|
||||
m_to_km: function(v) { return v / 1000; },
|
||||
m_to_mi: function(v) { return v / 1609.34; },
|
||||
|
||||
get_name: function() { return this._info.name; },
|
||||
get_distance: function() { return this._info.length; },
|
||||
get_distance_imp: function() { return this.to_miles(this.m_to_km(this.get_distance())); },
|
||||
|
||||
get_start_time: function() { return this._info.duration.start; },
|
||||
get_end_time: function() { return this._info.duration.end; },
|
||||
get_moving_time: function() { return this._info.duration.moving; },
|
||||
get_total_time: function() { return this._info.duration.total; },
|
||||
|
||||
get_moving_pace: function() { return this.get_moving_time() / this.m_to_km(this.get_distance()); },
|
||||
get_moving_pace_imp: function() { return this.get_moving_time() / this.get_distance_imp(); },
|
||||
|
||||
get_elevation_gain: function() { return this._info.elevation.gain; },
|
||||
get_elevation_loss: function() { return this._info.elevation.loss; },
|
||||
get_elevation_data: function() {
|
||||
var _this = this;
|
||||
return this._info.elevation._points.map(
|
||||
function(p) { return _this._prepare_data_point(p, _this.m_to_km, null,
|
||||
function(a, b) { return a.toFixed(2) + ' km, ' + b.toFixed(0) + ' m'; });
|
||||
});
|
||||
},
|
||||
get_elevation_data_imp: function() {
|
||||
var _this = this;
|
||||
return this._info.elevation._points.map(
|
||||
function(p) { return _this._prepare_data_point(p, _this.m_to_mi, _this.to_ft,
|
||||
function(a, b) { return a.toFixed(2) + ' mi, ' + b.toFixed(0) + ' ft'; });
|
||||
});
|
||||
},
|
||||
|
||||
get_average_hr: function() { return this._info.hr.avg; },
|
||||
get_heartrate_data: function() {
|
||||
var _this = this;
|
||||
return this._info.hr._points.map(
|
||||
function(p) { return _this._prepare_data_point(p, _this.m_to_km, null,
|
||||
function(a, b) { return a.toFixed(2) + ' km, ' + b.toFixed(0) + ' bpm'; });
|
||||
});
|
||||
},
|
||||
get_heartrate_data_imp: function() {
|
||||
var _this = this;
|
||||
return this._info.hr._points.map(
|
||||
function(p) { return _this._prepare_data_point(p, _this.m_to_mi, null,
|
||||
function(a, b) { return a.toFixed(2) + ' mi, ' + b.toFixed(0) + ' bpm'; });
|
||||
});
|
||||
},
|
||||
|
||||
// Private methods
|
||||
|
||||
_merge_objs: function(a, b) {
|
||||
var _ = {};
|
||||
for (var attr in a) { _[attr] = a[attr]; }
|
||||
for (var attr in b) { _[attr] = b[attr]; }
|
||||
return _;
|
||||
},
|
||||
|
||||
_prepare_data_point: function(p, trans1, trans2, trans_tooltip) {
|
||||
var r = [trans1 && trans1(p[0]) || p[0], trans2 && trans2(p[1]) || p[1]];
|
||||
r.push(trans_tooltip && trans_tooltip(r[0], r[1]) || (r[0] + ': ' + r[1]));
|
||||
return r;
|
||||
},
|
||||
|
||||
_load_xml: function(url, cb, options, async) {
|
||||
if (async == undefined) async = this.options.async;
|
||||
if (options == undefined) options = this.options;
|
||||
|
||||
var req = new window.XMLHttpRequest();
|
||||
req.open('GET', url, async);
|
||||
try {
|
||||
req.overrideMimeType('text/xml'); // unsupported by IE
|
||||
} catch(e) {}
|
||||
req.onreadystatechange = function() {
|
||||
if (req.readyState != 4) return;
|
||||
if(req.status == 200) cb(req.responseXML, options);
|
||||
};
|
||||
req.send(null);
|
||||
},
|
||||
|
||||
_parse: function(input, options, async) {
|
||||
var _this = this;
|
||||
var cb = function(gpx, options) {
|
||||
var layers = _this._parse_gpx_data(gpx, options);
|
||||
if (!layers) return;
|
||||
_this.addLayer(layers);
|
||||
_this.fire('loaded');
|
||||
}
|
||||
if (input.substr(0,1)==='<') { // direct XML has to start with a <
|
||||
var parser = new DOMParser();
|
||||
setTimeout(function() {
|
||||
cb(parser.parseFromString(input, "text/xml"), options);
|
||||
});
|
||||
} else {
|
||||
this._load_xml(input, cb, options, async);
|
||||
}
|
||||
},
|
||||
|
||||
_parse_gpx_data: function(xml, options) {
|
||||
var j, i, el, layers = [];
|
||||
var tags = [['rte','rtept'], ['trkseg','trkpt']];
|
||||
|
||||
var name = xml.getElementsByTagName('name');
|
||||
if (name.length > 0) {
|
||||
this._info.name = name[0].textContent;
|
||||
}
|
||||
|
||||
for (j = 0; j < tags.length; j++) {
|
||||
el = xml.getElementsByTagName(tags[j][0]);
|
||||
for (i = 0; i < el.length; i++) {
|
||||
var coords = this._parse_trkseg(el[i], xml, options, tags[j][1]);
|
||||
if (coords.length === 0) continue;
|
||||
|
||||
// add track
|
||||
var l = new L.Polyline(coords, options.polyline_options);
|
||||
this.fire('addline', { line: l })
|
||||
layers.push(l);
|
||||
|
||||
if (options.marker_options.startIconUrl) {
|
||||
// add start pin
|
||||
var p = new L.Marker(coords[0], {
|
||||
clickable: false,
|
||||
icon: new L.GPXTrackIcon({iconUrl: options.marker_options.startIconUrl})
|
||||
});
|
||||
this.fire('addpoint', { point: p });
|
||||
layers.push(p);
|
||||
}
|
||||
|
||||
if (options.marker_options.endIconUrl) {
|
||||
// add end pin
|
||||
p = new L.Marker(coords[coords.length-1], {
|
||||
clickable: false,
|
||||
icon: new L.GPXTrackIcon({iconUrl: options.marker_options.endIconUrl})
|
||||
});
|
||||
this.fire('addpoint', { point: p });
|
||||
layers.push(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._info.hr.avg = Math.round(this._info.hr._total / this._info.hr._points.length);
|
||||
|
||||
if (!layers.length) return;
|
||||
var layer = layers[0];
|
||||
if (layers.length > 1)
|
||||
layer = new L.FeatureGroup(layers);
|
||||
return layer;
|
||||
},
|
||||
|
||||
_parse_trkseg: function(line, xml, options, tag) {
|
||||
var el = line.getElementsByTagName(tag);
|
||||
if (!el.length) return [];
|
||||
var coords = [];
|
||||
var last = null;
|
||||
|
||||
for (var i = 0; i < el.length; i++) {
|
||||
var _, ll = new L.LatLng(
|
||||
el[i].getAttribute('lat'),
|
||||
el[i].getAttribute('lon'));
|
||||
ll.meta = { time: null, ele: null, hr: null };
|
||||
|
||||
_ = el[i].getElementsByTagName('time');
|
||||
if (_.length > 0) {
|
||||
ll.meta.time = new Date(Date.parse(_[0].textContent));
|
||||
}
|
||||
|
||||
_ = el[i].getElementsByTagName('ele');
|
||||
if (_.length > 0) {
|
||||
ll.meta.ele = parseFloat(_[0].textContent);
|
||||
}
|
||||
|
||||
_ = el[i].getElementsByTagNameNS('*', 'hr');
|
||||
if (_.length > 0) {
|
||||
ll.meta.hr = parseInt(_[0].textContent);
|
||||
this._info.hr._points.push([this._info.length, ll.meta.hr]);
|
||||
this._info.hr._total += ll.meta.hr;
|
||||
}
|
||||
|
||||
this._info.elevation._points.push([this._info.length, ll.meta.ele]);
|
||||
this._info.duration.end = ll.meta.time;
|
||||
|
||||
if (last != null) {
|
||||
this._info.length += this._dist3d(last, ll);
|
||||
|
||||
var t = ll.meta.ele - last.meta.ele;
|
||||
if (t > 0) this._info.elevation.gain += t;
|
||||
else this._info.elevation.loss += Math.abs(t);
|
||||
|
||||
t = Math.abs(ll.meta.time - last.meta.time);
|
||||
this._info.duration.total += t;
|
||||
if (t < options.max_point_interval) this._info.duration.moving += t;
|
||||
} else {
|
||||
this._info.duration.start = ll.meta.time;
|
||||
}
|
||||
|
||||
last = ll;
|
||||
coords.push(ll);
|
||||
}
|
||||
|
||||
return coords;
|
||||
},
|
||||
|
||||
_dist2d: function(a, b) {
|
||||
var R = 6371000;
|
||||
var dLat = this._deg2rad(b.lat - a.lat);
|
||||
var dLon = this._deg2rad(b.lng - a.lng);
|
||||
var r = Math.sin(dLat/2) *
|
||||
Math.sin(dLat/2) +
|
||||
Math.cos(this._deg2rad(a.lat)) *
|
||||
Math.cos(this._deg2rad(b.lat)) *
|
||||
Math.sin(dLon/2) *
|
||||
Math.sin(dLon/2);
|
||||
var c = 2 * Math.atan2(Math.sqrt(r), Math.sqrt(1-r));
|
||||
var d = R * c;
|
||||
return d;
|
||||
},
|
||||
|
||||
_dist3d: function(a, b) {
|
||||
var planar = this._dist2d(a, b);
|
||||
var height = Math.abs(b.meta.ele - a.meta.ele);
|
||||
return Math.sqrt(Math.pow(planar, 2) + Math.pow(height, 2));
|
||||
},
|
||||
|
||||
_deg2rad: function(deg) {
|
||||
return deg * Math.PI / 180;
|
||||
},
|
||||
});
|
||||
BIN
bower_components/leaflet-gpx/pin-icon-end.png
vendored
Normal file
|
After Width: | Height: | Size: 842 B |
BIN
bower_components/leaflet-gpx/pin-icon-start.png
vendored
Normal file
|
After Width: | Height: | Size: 945 B |
BIN
bower_components/leaflet-gpx/pin-shadow.png
vendored
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
14
bower_components/leaflet-plugins/.bower.json
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "shramov-plugins-permalink",
|
||||
"homepage": "https://github.com/shramov/leaflet-plugins",
|
||||
"version": "1.0.1",
|
||||
"_release": "1.0.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.0.1",
|
||||
"commit": "a03de1df77d53c58dd7194bf7e1ddbc100231ac2"
|
||||
},
|
||||
"_source": "git://github.com/shramov/leaflet-plugins.git",
|
||||
"_target": "*",
|
||||
"_originalSource": "leaflet-plugins"
|
||||
}
|
||||
22
bower_components/leaflet-plugins/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2011-2012, Pavel Shramov
|
||||
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.
|
||||
41
bower_components/leaflet-plugins/README.asciidoc
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
Leaflet plugins
|
||||
===============
|
||||
|
||||
== What's it?
|
||||
|
||||
Miscellaneous plugins for Leaflet library for services that need to display
|
||||
route information and need satellite imagery from different providers.
|
||||
Currently it consists of:
|
||||
|
||||
- Vector layers (`layer/vector/`):
|
||||
* GPX
|
||||
* KML
|
||||
|
||||
- Providers (`layer/tile`):
|
||||
* Google - using Google Maps API v3;
|
||||
* Yandex - using Yandex Maps API v2;
|
||||
* Bing - with proper attribution.
|
||||
|
||||
All these providers are implemented with respect to terms of use.
|
||||
|
||||
Also there are some useful control plugins (`control/`):
|
||||
|
||||
* Permalink - OpenLayers compatible permanent link with support for storing
|
||||
location data in hash part (#lat=...);
|
||||
* Scale - scale ruler which looks like one on paper maps.
|
||||
|
||||
== How to get?
|
||||
|
||||
http://psha.org.ru/cgit/psha/leaflet-plugins.git
|
||||
|
||||
or
|
||||
|
||||
http://github.com/shramov/leaflet-plugins.git
|
||||
|
||||
== Russian docs
|
||||
|
||||
See link:http://psha.org.ru/b/leaflet-plugins.ru.html[russian documentation] for more info.
|
||||
|
||||
////////////////////////////////////
|
||||
vim: sts=4 sw=4 et tw=80 ft=asciidoc
|
||||
////////////////////////////////////
|
||||
28
bower_components/leaflet-plugins/build/Makefile
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
JS := $(wildcard ../layer/*/*.js ../layer/*.js ../control/*js)
|
||||
#JS += control/Scale.js control/Distance.js
|
||||
#JS += control/Permalink.js $(wildcard control/Permalink.*.js)
|
||||
JS := $(shell python ./deps.py $(JS))
|
||||
|
||||
#JS_EXTRA := $(JS) $(wildcard layer/*.js)
|
||||
all: compiled.yui.js compiled.closure.js
|
||||
|
||||
compile: $(patsubst %,compiled/%,$(JS))
|
||||
|
||||
closure/%: ../%
|
||||
mkdir -p $(dir $@)
|
||||
java -jar /tmp/closure.jar --compilation_level ADVANCED_OPTIMIZATIONS --charset UTF-8 --js $< --js_output_file $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
yui/%: ../%
|
||||
mkdir -p $(dir $@)
|
||||
yui-compressor --charset UTF-8 -o $@.tmp $<
|
||||
mv $@.tmp $@
|
||||
|
||||
compiled.yui.js: $(patsubst ../%,yui/%,$(JS))
|
||||
compiled.closure.js: $(patsubst ../%,closure/%,$(JS))
|
||||
|
||||
compiled.%.js:
|
||||
for f in $^; do cat $$f >> $@.tmp; echo >> $@.tmp; done
|
||||
mv $@.tmp $@
|
||||
|
||||
.PHONY: all compile
|
||||
26
bower_components/leaflet-plugins/build/deps.py
vendored
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env python
|
||||
# vim: sts=4 sw=4 et
|
||||
|
||||
import os, sys
|
||||
|
||||
printed = set()
|
||||
|
||||
def includes(f):
|
||||
d = os.path.dirname(f)
|
||||
for l in open(f):
|
||||
if l.startswith('//#include'):
|
||||
yield os.path.join(d, l.strip().split(None, 1)[1].strip(""""'"""))
|
||||
|
||||
work = list(sys.argv[1:])
|
||||
|
||||
while work:
|
||||
f = work.pop(0)
|
||||
if f in printed:
|
||||
continue
|
||||
i = list(filter(lambda x: x not in printed, includes(f)))
|
||||
if i:
|
||||
work = i + [f] + work
|
||||
continue
|
||||
printed.add(f)
|
||||
print f
|
||||
|
||||
127
bower_components/leaflet-plugins/control/Distance.js
vendored
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
L.Control.Distance = L.Control.extend({
|
||||
options: {
|
||||
position: 'topleft',
|
||||
popups: true
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
L.Util.setOptions(this, options);
|
||||
this._line = new L.Polyline([], {editable: true});
|
||||
this._line.on('edit', this._update, this);
|
||||
this._line.on('click', function(e) {});
|
||||
this._active = false;
|
||||
},
|
||||
|
||||
getLine: function() { return this._line; },
|
||||
|
||||
onAdd: function(map) {
|
||||
var className = 'leaflet-control-distance',
|
||||
container = this._container = L.DomUtil.create('div', className);
|
||||
|
||||
function cb() {
|
||||
if (this._active)
|
||||
this._calc_disable();
|
||||
else
|
||||
this._calc_enable();
|
||||
}
|
||||
|
||||
var link = this._link = this._createButton('Edit', 'leaflet-control-distance leaflet-control-distance-edit', container, cb, this);
|
||||
var del = this._link_delete = this._createButton('Delete', 'leaflet-control-distance leaflet-control-distance-delete', container, this._reset, this);
|
||||
var text = this._text = L.DomUtil.create('div', 'leaflet-control-distance-text', container);
|
||||
|
||||
//text.style.display = 'inline';
|
||||
//text.style.float = 'right';
|
||||
|
||||
this._map.addLayer(this._line);
|
||||
this._calc_disable();
|
||||
return container;
|
||||
},
|
||||
|
||||
_createButton: function (title, className, container, fn, context) {
|
||||
var link = L.DomUtil.create('a', className, container);
|
||||
link.href = '#';
|
||||
link.title = title;
|
||||
|
||||
L.DomEvent
|
||||
.addListener(link, 'click', L.DomEvent.stopPropagation)
|
||||
.addListener(link, 'click', L.DomEvent.preventDefault)
|
||||
.addListener(link, 'click', fn, context);
|
||||
|
||||
return link;
|
||||
},
|
||||
|
||||
onRemove: function(map) {
|
||||
this._calc_disable();
|
||||
},
|
||||
|
||||
_calc_enable: function() {
|
||||
this._map.on('click', this._add_point, this);
|
||||
|
||||
this._map.getContainer().style.cursor = 'crosshair';
|
||||
//this._map.addLayer(this._line);
|
||||
L.DomUtil.addClass(this._link, 'leaflet-control-distance-active');
|
||||
this._container.appendChild(this._link_delete);
|
||||
this._container.appendChild(this._text);
|
||||
this._active = true;
|
||||
this._line.editing.enable();
|
||||
if (!this._map.hasLayer(this._line))
|
||||
this._map.addLayer(this._line);
|
||||
this._update();
|
||||
},
|
||||
|
||||
_calc_disable: function() {
|
||||
this._map.off('click', this._add_point, this);
|
||||
//this._map.removeLayer(this._line);
|
||||
this._map.getContainer().style.cursor = 'default';
|
||||
this._container.removeChild(this._link_delete);
|
||||
this._container.removeChild(this._text);
|
||||
L.DomUtil.removeClass(this._link, 'leaflet-control-distance-active');
|
||||
this._active = false;
|
||||
this._line.editing.disable();
|
||||
},
|
||||
|
||||
_add_point: function (e) {
|
||||
var len = this._line.getLatLngs().length;
|
||||
this._line.addLatLng(e.latlng);
|
||||
this._line.editing.updateMarkers();
|
||||
this._line.fire('edit', {});
|
||||
},
|
||||
|
||||
_reset: function(e) {
|
||||
this._line.setLatLngs([]);
|
||||
this._line.fire('edit', {});
|
||||
this._line.redraw();
|
||||
this._line.editing.updateMarkers();
|
||||
},
|
||||
|
||||
_update: function(e) {
|
||||
console.info("Update");
|
||||
this._text.textContent = this._d2txt(this._distance_calc());
|
||||
},
|
||||
|
||||
_d2txt: function(d) {
|
||||
if (d < 2000)
|
||||
return d.toFixed(0) + " m";
|
||||
else
|
||||
return (d/1000).toFixed(1) + " km";
|
||||
},
|
||||
|
||||
_distance_calc: function(e) {
|
||||
var ll = this._line.getLatLngs();
|
||||
var d = 0, p = null;
|
||||
for (var i = 0; i < ll.length; i++) {
|
||||
if (i)
|
||||
d += p.distanceTo(ll[i]);
|
||||
if (this.options.popups) {
|
||||
var m = this._line.editing._markers[i];
|
||||
if (m) {
|
||||
m.bindPopup(this._d2txt(d));
|
||||
m.on('mouseover', m.openPopup, m);
|
||||
m.on('mouseout', m.closePopup, m);
|
||||
}
|
||||
}
|
||||
p = ll[i];
|
||||
}
|
||||
return d;
|
||||
}
|
||||
});
|
||||
60
bower_components/leaflet-plugins/control/Layers.Load.js
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Add async initialization of layers to L.Control.Layers
|
||||
*/
|
||||
L.Control.Layers.include({
|
||||
_loadScripts: function(scripts, cb, args) {
|
||||
if (!scripts || scripts.length == 0)
|
||||
return cb(args);
|
||||
var _this = this, s = scripts.pop(), c;
|
||||
c = L.Control.Layers._script_cache[s];
|
||||
if (c === undefined) {
|
||||
c = {url: s, wait: []};
|
||||
//console.info("Load " + s);
|
||||
var script = document.createElement('script');
|
||||
script.src = s;
|
||||
script.type = 'text/javascript';
|
||||
script.onload = function () {
|
||||
var i = 0;
|
||||
for (i = 0; i < c.wait.length; i++)
|
||||
c.wait[i]();
|
||||
}
|
||||
c.e = script;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
}
|
||||
function _cb() { _this._loadScripts(scripts, cb, args); }
|
||||
c.wait.push(_cb);
|
||||
if (c.e.readyState == "completed")
|
||||
_cb();
|
||||
L.Control.Layers._script_cache[s] = c;
|
||||
},
|
||||
|
||||
addLayerDef: function(name, def) {
|
||||
if (this._layer_defs === undefined)
|
||||
this._layer_defs = {};
|
||||
this._layer_defs[name] = def;
|
||||
},
|
||||
|
||||
addLayerDefs: function(defs) {
|
||||
if (this._layer_defs === undefined)
|
||||
this._layer_defs = {};
|
||||
L.Util.extend(this._layer_defs, defs);
|
||||
},
|
||||
|
||||
loadLayer: function(name, deflt) {
|
||||
var _this = this, l = this._layer_defs[name];
|
||||
l['default'] = deflt;
|
||||
this._loadScripts(l.js.reverse(), function(l) {_this._loadLayer(l)}, l);
|
||||
},
|
||||
|
||||
_loadLayer: function(l) {
|
||||
var x = l.init();
|
||||
if (l['default'] && this._map)
|
||||
this._map.addLayer(x);
|
||||
if (!l.overlay)
|
||||
this.addBaseLayer(x, l.name);
|
||||
else
|
||||
this.addOverlay(x, l.name);
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Layers._script_cache = {};
|
||||
76
bower_components/leaflet-plugins/control/Permalink.Layer.js
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
//#include "Permalink.js
|
||||
|
||||
L.Control.Permalink.include({
|
||||
/*
|
||||
options: {
|
||||
useMarker: true,
|
||||
markerOptions: {}
|
||||
},
|
||||
*/
|
||||
|
||||
initialize_layer: function() {
|
||||
//console.info("Initialize layer");
|
||||
this.on('update', this._set_layer, this);
|
||||
this.on('add', this._onadd_layer, this);
|
||||
},
|
||||
|
||||
_onadd_layer: function(e) {
|
||||
//console.info("onAdd::layer", e);
|
||||
this._map.on('layeradd', this._update_layer, this);
|
||||
this._map.on('layerremove', this._update_layer, this);
|
||||
this._update_layer();
|
||||
},
|
||||
|
||||
_update_layer: function() {
|
||||
if (!this.options.layers) return;
|
||||
//console.info(this.options.layers);
|
||||
var layer = this.options.layers.currentBaseLayer();
|
||||
if (layer)
|
||||
this._update({layer: layer.name});
|
||||
},
|
||||
|
||||
_set_layer: function(e) {
|
||||
//console.info("Set layer", e);
|
||||
var p = e.params;
|
||||
if (!this.options.layers || !p.layer) return;
|
||||
this.options.layers.chooseBaseLayer(p.layer);
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Layers.include({
|
||||
chooseBaseLayer: function(name) {
|
||||
var layer, obj;
|
||||
for (var i in this._layers) {
|
||||
if (!this._layers.hasOwnProperty(i))
|
||||
continue;
|
||||
obj = this._layers[i];
|
||||
if (!obj.overlay && obj.name == name)
|
||||
layer = obj.layer;
|
||||
}
|
||||
if (!layer || this._map.hasLayer(layer))
|
||||
return;
|
||||
|
||||
for (var i in this._layers) {
|
||||
if (!this._layers.hasOwnProperty(i))
|
||||
continue;
|
||||
obj = this._layers[i];
|
||||
if (!obj.overlay && this._map.hasLayer(obj.layer))
|
||||
this._map.removeLayer(obj.layer)
|
||||
}
|
||||
this._map.addLayer(layer)
|
||||
this._update();
|
||||
},
|
||||
|
||||
currentBaseLayer: function() {
|
||||
for (var i in this._layers) {
|
||||
if (!this._layers.hasOwnProperty(i))
|
||||
continue;
|
||||
var obj = this._layers[i];
|
||||
//console.info("Layer: ", obj.name, obj);
|
||||
if (obj.overlay) continue;
|
||||
if (!obj.overlay && this._map.hasLayer(obj.layer))
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
49
bower_components/leaflet-plugins/control/Permalink.Line.js
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
//#include "Permalink.js
|
||||
|
||||
L.Control.Permalink.include({
|
||||
/*
|
||||
options: {
|
||||
line: null
|
||||
},
|
||||
*/
|
||||
|
||||
initialize_line: function() {
|
||||
this.on('update', this._set_line, this);
|
||||
this.on('add', this._onadd_line, this);
|
||||
},
|
||||
|
||||
_onadd_line: function(e) {
|
||||
//console.info("onAdd::line", e);
|
||||
if (!this.options.line) return;
|
||||
this.options.line.on('edit', this._update_line, this);
|
||||
this._update_line()
|
||||
},
|
||||
|
||||
_update_line: function() {
|
||||
if (!this.options.line) return;
|
||||
var line = this.options.line;
|
||||
if (!line) return;
|
||||
var text = [], coords = line.getLatLngs();
|
||||
if (!coords.length)
|
||||
return this._update({line: null});
|
||||
for (var i in coords)
|
||||
text.push(coords[i].lat.toFixed(4) + "," + coords[i].lng.toFixed(4))
|
||||
this._update({line: text.join(';')});
|
||||
},
|
||||
|
||||
_set_line: function(e) {
|
||||
//console.info("Set line", e.params.line);
|
||||
var p = e.params, l = this.options.line;
|
||||
if (!l || !p.line) return;
|
||||
var coords = [], text = p.line.split(';');
|
||||
for (var i in text) {
|
||||
var ll = text[i].split(',');
|
||||
if (ll.length != 2) continue;
|
||||
coords.push(new L.LatLng(ll[0], ll[1]));
|
||||
}
|
||||
if (!coords.length) return;
|
||||
l.setLatLngs(coords);
|
||||
if (!this._map.hasLayer(l))
|
||||
this._map.addLayer(l);
|
||||
}
|
||||
});
|
||||
31
bower_components/leaflet-plugins/control/Permalink.Marker.js
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
//#include "Permalink.js
|
||||
|
||||
L.Control.Permalink.include({
|
||||
/*
|
||||
options: {
|
||||
useMarker: true,
|
||||
markerOptions: {}
|
||||
},
|
||||
*/
|
||||
|
||||
initialize_marker: function() {
|
||||
//console.info("Initialize marker");
|
||||
this.on('update', this._set_marker, this);
|
||||
},
|
||||
|
||||
_set_marker: function(e) {
|
||||
//console.info("Set marker", e);
|
||||
var p = e.params;
|
||||
//if (!this.options.useMarker) return;
|
||||
if (this._marker) return;
|
||||
if (p.marker != 1) return;
|
||||
if (p.mlat !== undefined && p.mlon !== undefined)
|
||||
return this._update({mlat: null, mlon: null,
|
||||
lat: p.mlat, lon: p.mlon, marker: 1});
|
||||
this._marker = new L.Marker(new L.LatLng(p.lat, p.lon),
|
||||
this.options.markerOptions);
|
||||
this._marker.bindPopup("<a href='" + this._update_href() + "'>" + this.options.text + "</a>");
|
||||
this._map.addLayer(this._marker);
|
||||
this._update({marker: null});
|
||||
}
|
||||
});
|
||||
163
bower_components/leaflet-plugins/control/Permalink.js
vendored
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
L.Control.Permalink = L.Control.extend({
|
||||
includes: L.Mixin.Events,
|
||||
|
||||
options: {
|
||||
position: "bottomleft",
|
||||
useAnchor: true,
|
||||
useLocation: false,
|
||||
text: "Permalink"
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
L.Util.setOptions(this, options);
|
||||
this._params = {};
|
||||
this._set_urlvars();
|
||||
this.on("update", this._set_center, this);
|
||||
for (var i in this) {
|
||||
if (typeof(i) === "string" && i.indexOf('initialize_') == 0)
|
||||
this[i]();
|
||||
}
|
||||
},
|
||||
|
||||
onAdd: function(map) {
|
||||
this._container = L.DomUtil.create('div', 'leaflet-control-attribution leaflet-control-permalink');
|
||||
L.DomEvent.disableClickPropagation(this._container);
|
||||
this._map = map;
|
||||
this._href = L.DomUtil.create('a', null, this._container);
|
||||
this._href.innerHTML = this.options.text
|
||||
|
||||
map.on('moveend', this._update_center, this);
|
||||
this.fire("update", {params: this._params})
|
||||
this._update_center();
|
||||
|
||||
if (this.options.useAnchor && 'onhashchange' in window) {
|
||||
var _this = this, fn = window.onhashchange;
|
||||
window.onhashchange = function() {
|
||||
_this._set_urlvars();
|
||||
if (fn) return fn();
|
||||
}
|
||||
}
|
||||
|
||||
this.fire('add', {map: map});
|
||||
|
||||
return this._container;
|
||||
},
|
||||
|
||||
_update_center: function() {
|
||||
if (!this._map) return;
|
||||
|
||||
var center = this._round_point(this._map.getCenter());
|
||||
this._update({zoom: this._map.getZoom(), lat: center.lat, lon: center.lng});
|
||||
},
|
||||
|
||||
_update_href: function() {
|
||||
var params = L.Util.getParamString(this._params);
|
||||
var sep = '?';
|
||||
if (this.options.useAnchor) sep = '#';
|
||||
var url = this._url_base + sep + params.slice(1);
|
||||
if (this._href) this._href.setAttribute('href', url);
|
||||
if (this.options.useLocation)
|
||||
location.replace('#' + params.slice(1));
|
||||
return url;
|
||||
},
|
||||
|
||||
_round_point : function(point) {
|
||||
var bounds = this._map.getBounds(), size = this._map.getSize();
|
||||
var ne = bounds.getNorthEast(), sw = bounds.getSouthWest();
|
||||
|
||||
var round = function (x, p) {
|
||||
if (p == 0) return x;
|
||||
shift = 1;
|
||||
while (p < 1 && p > -1) {
|
||||
x *= 10;
|
||||
p *= 10;
|
||||
shift *= 10;
|
||||
}
|
||||
return Math.floor(x)/shift;
|
||||
}
|
||||
point.lat = round(point.lat, (ne.lat - sw.lat) / size.y);
|
||||
point.lng = round(point.lng, (ne.lng - sw.lng) / size.x);
|
||||
return point;
|
||||
},
|
||||
|
||||
_update: function(obj, source) {
|
||||
//console.info("Update", obj, this._params);
|
||||
for(var i in obj) {
|
||||
if (!obj.hasOwnProperty(i)) continue;
|
||||
if (obj[i] != null && obj[i] != undefined)
|
||||
this._params[i] = obj[i]
|
||||
else
|
||||
delete this._params[i];
|
||||
}
|
||||
|
||||
this._update_href();
|
||||
},
|
||||
|
||||
_set_urlvars: function()
|
||||
{
|
||||
this._url_base = window.location.href.split('#')[0].split('?')[0];
|
||||
|
||||
var p;
|
||||
if (this.options.useAnchor)
|
||||
p = L.UrlUtil.queryParse(L.UrlUtil.hash());
|
||||
else
|
||||
p = L.UrlUtil.queryParse(L.UrlUtil.query());
|
||||
|
||||
function eq(x, y) {
|
||||
for(var i in x)
|
||||
if (x.hasOwnProperty(i) && x[i] != y[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (eq(p, this._params) && eq(this._params, p))
|
||||
return;
|
||||
this._params = p;
|
||||
this._update_href();
|
||||
this.fire("update", {params: this._params})
|
||||
},
|
||||
|
||||
_set_center: function(e)
|
||||
{
|
||||
//console.info("Update center", e);
|
||||
var params = e.params;
|
||||
if (params.zoom == undefined ||
|
||||
params.lat == undefined ||
|
||||
params.lon == undefined) return;
|
||||
this._map.setView(new L.LatLng(params.lat, params.lon), params.zoom);
|
||||
}
|
||||
});
|
||||
|
||||
L.UrlUtil = {
|
||||
queryParse: function(s) {
|
||||
var p = {};
|
||||
var sep = "&";
|
||||
if (s.search("&") != -1)
|
||||
sep = "&";
|
||||
var params = s.split(sep);
|
||||
for(var i = 0; i < params.length; i++) {
|
||||
var tmp = params[i].split('=');
|
||||
if (tmp.length != 2) continue;
|
||||
p[tmp[0]] = decodeURI(tmp[1]);
|
||||
}
|
||||
return p;
|
||||
},
|
||||
|
||||
query: function() {
|
||||
var href = window.location.href.split('#')[0], idx = href.indexOf('?');
|
||||
if (idx < 0)
|
||||
return '';
|
||||
return href.slice(idx+1);
|
||||
},
|
||||
|
||||
hash: function() { return window.location.hash.slice(1) },
|
||||
|
||||
updateParamString: function (q, obj) {
|
||||
var p = L.UrlUtil.queryParse(q);
|
||||
for (var i in obj) {
|
||||
if (obj.hasOwnProperty(i))
|
||||
p[i] = obj[i];
|
||||
}
|
||||
return L.Util.getParamString(p).slice(1);
|
||||
}
|
||||
};
|
||||
118
bower_components/leaflet-plugins/control/Scale.js
vendored
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
L.Control.Scale = L.Control.extend({
|
||||
options: {
|
||||
position: "bottomleft",
|
||||
useCanvas: null,
|
||||
width: 100
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
L.Util.setOptions(this, options);
|
||||
},
|
||||
|
||||
onAdd: function(map) {
|
||||
this._map = map;
|
||||
|
||||
this._container = L.DomUtil.create('div', 'leaflet-control-attribution leaflet-control-scale');
|
||||
this._label = L.DomUtil.create('div', null, this._container);
|
||||
this._label.style.textAlign = 'right';
|
||||
|
||||
if (!this.options.useCanvas && this.options.useCanvas != false)
|
||||
this.options.useCanvas = "HTMLCanvasElement" in window;
|
||||
if (this.options.useCanvas) {
|
||||
this._canvas = L.DomUtil.create('canvas', 'leaflet-canvas-marker', this._container);
|
||||
} else {
|
||||
this._canvas = L.DomUtil.create('div', null, this._container);
|
||||
this._canvas.style.border = "1px solid black";
|
||||
this._canvas.innerHTML = " ";
|
||||
//this._canvas.style.padding = "none";
|
||||
//this._canvas.style.margin = "none";
|
||||
//this._canvas.style.width = 100;
|
||||
//this._canvas.style.height = 5;
|
||||
}
|
||||
map.on('zoomend', this._update, this);
|
||||
this._update();
|
||||
return this._container;
|
||||
},
|
||||
|
||||
onRemove: function(map) {
|
||||
map._container.removeChild(this._label);
|
||||
map._container.removeChild(this._canvas);
|
||||
map.off('zoomend', this._reset);
|
||||
},
|
||||
|
||||
getPosition: function() {
|
||||
return this.options.position;
|
||||
},
|
||||
|
||||
getContainer: function() {
|
||||
return this._container;
|
||||
},
|
||||
|
||||
_update: function() {
|
||||
if (!this._map) return;
|
||||
|
||||
var size = this.options.width;
|
||||
|
||||
var b = this._map.getBounds(), pb = this._map.getPixelBounds();
|
||||
var width = this._deg_length(b.getNorthEast(), b.getNorthWest());
|
||||
width = size * width / (pb.max.x - pb.min.x);
|
||||
var iw = this._round(width);
|
||||
|
||||
if (iw >= 1)
|
||||
this._label.innerHTML = iw + " km";
|
||||
else
|
||||
this._label.innerHTML = Math.round(1000 * iw) + " m";
|
||||
|
||||
size = size * iw / width;
|
||||
|
||||
if (this.options.useCanvas) {
|
||||
this._canvas.width = size+1;
|
||||
this._canvas.height = 10+1;
|
||||
|
||||
var ctx = this._canvas.getContext("2d");
|
||||
this._draw(ctx, size, 5);
|
||||
} else {
|
||||
this._canvas.style.width = size;
|
||||
this._canvas.style.height = 5;
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
_draw: function(ctx, width, height) {
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = ctx.strokeStyle = '#000';
|
||||
ctx.lineWidth = 0.5;
|
||||
|
||||
ctx.strokeRect(0, height, width/2, height);
|
||||
ctx.fillRect(0, height, width/2, height);
|
||||
ctx.strokeRect(width/2, height, width/2, height);
|
||||
|
||||
ctx.moveTo(0, 0);
|
||||
ctx.lineTo(0, height);
|
||||
ctx.moveTo(width/2, 0);
|
||||
ctx.lineTo(width/2, height);
|
||||
ctx.moveTo(width, 0);
|
||||
ctx.lineTo(width, height);
|
||||
ctx.stroke();
|
||||
},
|
||||
|
||||
_deg_length : function(p1, p2) {
|
||||
var deglen = 111.12 * L.LatLng.RAD_TO_DEG;
|
||||
var p1lat = p1.lat * L.LatLng.DEG_TO_RAD,
|
||||
p1lng = p1.lng * L.LatLng.DEG_TO_RAD,
|
||||
p2lat = p2.lat * L.LatLng.DEG_TO_RAD,
|
||||
p2lng = p2.lng * L.LatLng.DEG_TO_RAD;
|
||||
return deglen * Math.acos(Math.sin(p1lat) * Math.sin(p2lat) +
|
||||
Math.cos(p1lat) * Math.cos(p2lat) * Math.cos(p2lng - p1lng));
|
||||
},
|
||||
|
||||
_round : function (x) {
|
||||
var div = 1;
|
||||
while (div < x) div *= 10;
|
||||
while (div > x) div /= 10;
|
||||
var s = div;
|
||||
while (s < x) s += div;
|
||||
if (s > 5 * div) s = 10 * div;
|
||||
return s;
|
||||
}
|
||||
});
|
||||
BIN
bower_components/leaflet-plugins/css/cross.png
vendored
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
48
bower_components/leaflet-plugins/css/distance.css
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
.leaflet-control-distance {
|
||||
-moz-border-radius: 7px;
|
||||
-webkit-border-radius: 7px;
|
||||
border-radius: 7px;
|
||||
|
||||
padding: 5px;
|
||||
background-color: rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.leaflet-control-distance a, .leaflet-control-distance div {
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
|
||||
padding: 2px;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-color: rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
|
||||
.leaflet-control-distance a {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.leaflet-control-distance div {
|
||||
font: 11px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
color: #333;
|
||||
height: 16px;
|
||||
margin-top: 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.leaflet-control-distance-edit {
|
||||
/* http://openclipart.org/detail/114727/ftview-ruler-by-anonymous */
|
||||
background-image: url('measure.png');
|
||||
}
|
||||
|
||||
.leaflet-control-distance-delete {
|
||||
margin-left: 5px;
|
||||
/* Based on http://openclipart.org/detail/34729/architetto----tasto-8-by-anonymous */
|
||||
background-image: url('cross.png');
|
||||
}
|
||||
|
||||
a.leaflet-control-distance-active {
|
||||
background-color: yellow;
|
||||
}
|
||||
BIN
bower_components/leaflet-plugins/css/measure.png
vendored
Normal file
|
After Width: | Height: | Size: 470 B |
97
bower_components/leaflet-plugins/css/osb.css
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
.osb-popup {
|
||||
font-family: sans-serif;
|
||||
font-size: small;
|
||||
max-width: 380px;
|
||||
overflow: auto;
|
||||
}
|
||||
.osb-popup a:link, .osb-popup a:visited {
|
||||
border-bottom: 1px dotted #C0C0C0;
|
||||
text-decoration: none;
|
||||
}
|
||||
.osb-popup a:link {
|
||||
color: #990000;
|
||||
}
|
||||
.osb-popup a:visited {
|
||||
color: #500000;
|
||||
}
|
||||
.osb-popup a:link:hover, .osb-popup a:visited:hover {
|
||||
border-bottom: 1px solid #C0C0C0;
|
||||
color: red;
|
||||
}
|
||||
.osb-popup a:link:focus .osb-popup a:visited:focus {
|
||||
outline: 1px dotted #C0C0C0;
|
||||
}
|
||||
.osb-popup a:link:active, .osb-popup a:visited:active {
|
||||
border-bottom: 1px solid #F0F0F0;
|
||||
color: red;
|
||||
outline: 1px solid #C0C0C0;
|
||||
}
|
||||
.osb-popup h1 {
|
||||
color: #176BC1;
|
||||
font-size: medium;
|
||||
margin-bottom: 7px;
|
||||
margin-top: 0;
|
||||
}
|
||||
.osb-popup p {
|
||||
margin-bottom: 0;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.osb-popup p.Comment {
|
||||
margin-left: 15px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.osb-popup p.Note {
|
||||
border-top: 1px solid gray;
|
||||
font-size: x-small;
|
||||
margin-top: 7px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
.osb-popup form + p {
|
||||
border-top: 1px solid gray;
|
||||
margin-top: 15px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.osb-popup ul {
|
||||
border-top: 1px solid gray;
|
||||
margin: 10px 0 0;
|
||||
padding: 5px 0 0;
|
||||
text-align: center;
|
||||
}
|
||||
.osb-popup ul li {
|
||||
display: inline;
|
||||
margin-left: 12px;
|
||||
margin-right: 12px;
|
||||
padding: 0;
|
||||
}
|
||||
.osb-popup form {
|
||||
margin-bottom: 0;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.osb-popup form.osb-comment {
|
||||
border-top: 1px solid gray;
|
||||
padding-top: 5px;
|
||||
}
|
||||
.osb-popup form div {
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.osb-popup form div.osb-footer {
|
||||
margin-bottom: 0;
|
||||
margin-top: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
.osb-popup span.osb-inputlabel {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
min-width: 110px;
|
||||
}
|
||||
.osb-popup input[type="text"] {
|
||||
min-width: 190px;
|
||||
}
|
||||
.osb-popup input[type="button"] {
|
||||
margin-left: 3px;
|
||||
margin-right: 3px;
|
||||
min-width: 75px;
|
||||
}
|
||||
|
||||
915
bower_components/leaflet-plugins/examples/KML_Samples.kml
vendored
Normal file
|
|
@ -0,0 +1,915 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<kml xmlns="http://www.opengis.net/kml/2.2">
|
||||
<Document>
|
||||
<name>KML Samples</name>
|
||||
<open>1</open>
|
||||
<description>Unleash your creativity with the help of these examples!</description>
|
||||
<Style id="downArrowIcon">
|
||||
<IconStyle>
|
||||
<Icon>
|
||||
<href>http://maps.google.com/mapfiles/kml/pal4/icon28.png</href>
|
||||
</Icon>
|
||||
</IconStyle>
|
||||
</Style>
|
||||
<Style id="globeIcon">
|
||||
<IconStyle>
|
||||
<Icon>
|
||||
<href>http://maps.google.com/mapfiles/kml/pal3/icon19.png</href>
|
||||
</Icon>
|
||||
</IconStyle>
|
||||
<LineStyle>
|
||||
<width>2</width>
|
||||
</LineStyle>
|
||||
</Style>
|
||||
<Style id="transPurpleLineGreenPoly">
|
||||
<LineStyle>
|
||||
<color>7fff00ff</color>
|
||||
<width>4</width>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>7f00ff00</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="yellowLineGreenPoly">
|
||||
<LineStyle>
|
||||
<color>7f00ffff</color>
|
||||
<width>4</width>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>7f00ff00</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="thickBlackLine">
|
||||
<LineStyle>
|
||||
<color>87000000</color>
|
||||
<width>10</width>
|
||||
</LineStyle>
|
||||
</Style>
|
||||
<Style id="redLineBluePoly">
|
||||
<LineStyle>
|
||||
<color>ff0000ff</color>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>ffff0000</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="blueLineRedPoly">
|
||||
<LineStyle>
|
||||
<color>ffff0000</color>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>ff0000ff</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="transRedPoly">
|
||||
<LineStyle>
|
||||
<width>1.5</width>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>7d0000ff</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="transBluePoly">
|
||||
<LineStyle>
|
||||
<width>1.5</width>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>7dff0000</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="transGreenPoly">
|
||||
<LineStyle>
|
||||
<width>1.5</width>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>7d00ff00</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="transYellowPoly">
|
||||
<LineStyle>
|
||||
<width>1.5</width>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>7d00ffff</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="noDrivingDirections">
|
||||
<BalloonStyle>
|
||||
<text><![CDATA[
|
||||
<b>$[name]</b>
|
||||
<br /><br />
|
||||
$[description]
|
||||
]]></text>
|
||||
</BalloonStyle>
|
||||
</Style>
|
||||
<Folder>
|
||||
<name>Placemarks</name>
|
||||
<description>These are just some of the different kinds of placemarks with
|
||||
which you can mark your favorite places</description>
|
||||
<LookAt>
|
||||
<longitude>-122.0839597145766</longitude>
|
||||
<latitude>37.42222904525232</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-148.4122922628044</heading>
|
||||
<tilt>40.5575073395506</tilt>
|
||||
<range>500.6566641072245</range>
|
||||
</LookAt>
|
||||
<Placemark>
|
||||
<name>Simple placemark</name>
|
||||
<description>Attached to the ground. Intelligently places itself at the
|
||||
height of the underlying terrain.</description>
|
||||
<Point>
|
||||
<coordinates>-122.0822035425683,37.42228990140251,0</coordinates>
|
||||
</Point>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Floating placemark</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Floats a defined distance above the ground.</description>
|
||||
<LookAt>
|
||||
<longitude>-122.0839597145766</longitude>
|
||||
<latitude>37.42222904525232</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-148.4122922628044</heading>
|
||||
<tilt>40.5575073395506</tilt>
|
||||
<range>500.6566641072245</range>
|
||||
</LookAt>
|
||||
<styleUrl>#downArrowIcon</styleUrl>
|
||||
<Point>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<coordinates>-122.084075,37.4220033612141,50</coordinates>
|
||||
</Point>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Extruded placemark</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Tethered to the ground by a customizable
|
||||
"tail"</description>
|
||||
<LookAt>
|
||||
<longitude>-122.0845787421525</longitude>
|
||||
<latitude>37.42215078737763</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-148.4126684946234</heading>
|
||||
<tilt>40.55750733918048</tilt>
|
||||
<range>365.2646606980322</range>
|
||||
</LookAt>
|
||||
<styleUrl>#globeIcon</styleUrl>
|
||||
<Point>
|
||||
<extrude>1</extrude>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<coordinates>-122.0857667006183,37.42156927867553,50</coordinates>
|
||||
</Point>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Styles and Markup</name>
|
||||
<visibility>0</visibility>
|
||||
<description>With KML it is easy to create rich, descriptive markup to
|
||||
annotate and enrich your placemarks</description>
|
||||
<LookAt>
|
||||
<longitude>-122.0845787422371</longitude>
|
||||
<latitude>37.42215078726837</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-148.4126777488172</heading>
|
||||
<tilt>40.55750733930874</tilt>
|
||||
<range>365.2646826292919</range>
|
||||
</LookAt>
|
||||
<styleUrl>#noDrivingDirections</styleUrl>
|
||||
<Document>
|
||||
<name>Highlighted Icon</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Place your mouse over the icon to see it display the new
|
||||
icon</description>
|
||||
<LookAt>
|
||||
<longitude>-122.0856552124024</longitude>
|
||||
<latitude>37.4224281311035</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>0</heading>
|
||||
<tilt>0</tilt>
|
||||
<range>265.8520424250024</range>
|
||||
</LookAt>
|
||||
<Style id="highlightPlacemark">
|
||||
<IconStyle>
|
||||
<Icon>
|
||||
<href>http://maps.google.com/mapfiles/kml/paddle/red-stars.png</href>
|
||||
</Icon>
|
||||
</IconStyle>
|
||||
</Style>
|
||||
<Style id="normalPlacemark">
|
||||
<IconStyle>
|
||||
<Icon>
|
||||
<href>http://maps.google.com/mapfiles/kml/paddle/wht-blank.png</href>
|
||||
</Icon>
|
||||
</IconStyle>
|
||||
</Style>
|
||||
<StyleMap id="exampleStyleMap">
|
||||
<Pair>
|
||||
<key>normal</key>
|
||||
<styleUrl>#normalPlacemark</styleUrl>
|
||||
</Pair>
|
||||
<Pair>
|
||||
<key>highlight</key>
|
||||
<styleUrl>#highlightPlacemark</styleUrl>
|
||||
</Pair>
|
||||
</StyleMap>
|
||||
<Placemark>
|
||||
<name>Roll over this icon</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#exampleStyleMap</styleUrl>
|
||||
<Point>
|
||||
<coordinates>-122.0856545755255,37.42243077405461,0</coordinates>
|
||||
</Point>
|
||||
</Placemark>
|
||||
</Document>
|
||||
<Placemark>
|
||||
<name>Descriptive HTML</name>
|
||||
<visibility>0</visibility>
|
||||
<description><![CDATA[Click on the blue link!<br><br>
|
||||
Placemark descriptions can be enriched by using many standard HTML tags.<br>
|
||||
For example:
|
||||
<hr>
|
||||
Styles:<br>
|
||||
<i>Italics</i>,
|
||||
<b>Bold</b>,
|
||||
<u>Underlined</u>,
|
||||
<s>Strike Out</s>,
|
||||
subscript<sub>subscript</sub>,
|
||||
superscript<sup>superscript</sup>,
|
||||
<big>Big</big>,
|
||||
<small>Small</small>,
|
||||
<tt>Typewriter</tt>,
|
||||
<em>Emphasized</em>,
|
||||
<strong>Strong</strong>,
|
||||
<code>Code</code>
|
||||
<hr>
|
||||
Fonts:<br>
|
||||
<font color="red">red by name</font>,
|
||||
<font color="#408010">leaf green by hexadecimal RGB</font>
|
||||
<br>
|
||||
<font size=1>size 1</font>,
|
||||
<font size=2>size 2</font>,
|
||||
<font size=3>size 3</font>,
|
||||
<font size=4>size 4</font>,
|
||||
<font size=5>size 5</font>,
|
||||
<font size=6>size 6</font>,
|
||||
<font size=7>size 7</font>
|
||||
<br>
|
||||
<font face=times>Times</font>,
|
||||
<font face=verdana>Verdana</font>,
|
||||
<font face=arial>Arial</font><br>
|
||||
<hr>
|
||||
Links:
|
||||
<br>
|
||||
<a href="http://earth.google.com/">Google Earth!</a>
|
||||
<br>
|
||||
or: Check out our website at www.google.com
|
||||
<hr>
|
||||
Alignment:<br>
|
||||
<p align=left>left</p>
|
||||
<p align=center>center</p>
|
||||
<p align=right>right</p>
|
||||
<hr>
|
||||
Ordered Lists:<br>
|
||||
<ol><li>First</li><li>Second</li><li>Third</li></ol>
|
||||
<ol type="a"><li>First</li><li>Second</li><li>Third</li></ol>
|
||||
<ol type="A"><li>First</li><li>Second</li><li>Third</li></ol>
|
||||
<hr>
|
||||
Unordered Lists:<br>
|
||||
<ul><li>A</li><li>B</li><li>C</li></ul>
|
||||
<ul type="circle"><li>A</li><li>B</li><li>C</li></ul>
|
||||
<ul type="square"><li>A</li><li>B</li><li>C</li></ul>
|
||||
<hr>
|
||||
Definitions:<br>
|
||||
<dl>
|
||||
<dt>Google:</dt><dd>The best thing since sliced bread</dd>
|
||||
</dl>
|
||||
<hr>
|
||||
Centered:<br><center>
|
||||
Time present and time past<br>
|
||||
Are both perhaps present in time future,<br>
|
||||
And time future contained in time past.<br>
|
||||
If all time is eternally present<br>
|
||||
All time is unredeemable.<br>
|
||||
</center>
|
||||
<hr>
|
||||
Block Quote:
|
||||
<br>
|
||||
<blockquote>
|
||||
We shall not cease from exploration<br>
|
||||
And the end of all our exploring<br>
|
||||
Will be to arrive where we started<br>
|
||||
And know the place for the first time.<br>
|
||||
<i>-- T.S. Eliot</i>
|
||||
</blockquote>
|
||||
<br>
|
||||
<hr>
|
||||
Headings:<br>
|
||||
<h1>Header 1</h1>
|
||||
<h2>Header 2</h2>
|
||||
<h3>Header 3</h3>
|
||||
<h3>Header 4</h4>
|
||||
<h3>Header 5</h5>
|
||||
<hr>
|
||||
Images:<br>
|
||||
<i>Remote image</i><br>
|
||||
<img src="//developers.google.com/kml/documentation/images/googleSample.png"><br>
|
||||
<i>Scaled image</i><br>
|
||||
<img src="//developers.google.com/kml/documentation/images/googleSample.png" width=100><br>
|
||||
<hr>
|
||||
Simple Tables:<br>
|
||||
<table border="1" padding="1">
|
||||
<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
|
||||
<tr><td>a</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>
|
||||
</table>
|
||||
<br>
|
||||
[Did you notice that double-clicking on the placemark doesn't cause the viewer to take you anywhere? This is because it is possible to directly author a "placeless placemark". If you look at the code for this example, you will see that it has neither a point coordinate nor a LookAt element.]]]></description>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Ground Overlays</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Examples of ground overlays</description>
|
||||
<GroundOverlay>
|
||||
<name>Large-scale overlay on terrain</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Overlay shows Mount Etna erupting on July 13th, 2001.</description>
|
||||
<LookAt>
|
||||
<longitude>15.02468937557116</longitude>
|
||||
<latitude>37.67395167941667</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-16.5581842842829</heading>
|
||||
<tilt>58.31228652890705</tilt>
|
||||
<range>30350.36838438907</range>
|
||||
</LookAt>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/etna.jpg</href>
|
||||
</Icon>
|
||||
<LatLonBox>
|
||||
<north>37.91904192681665</north>
|
||||
<south>37.46543388598137</south>
|
||||
<east>15.35832653742206</east>
|
||||
<west>14.60128369746704</west>
|
||||
<rotation>-0.1556640799496235</rotation>
|
||||
</LatLonBox>
|
||||
</GroundOverlay>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Screen Overlays</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Screen overlays have to be authored directly in KML. These
|
||||
examples illustrate absolute and dynamic positioning in screen space.</description>
|
||||
<ScreenOverlay>
|
||||
<name>Simple crosshairs</name>
|
||||
<visibility>0</visibility>
|
||||
<description>This screen overlay uses fractional positioning to put the
|
||||
image in the exact center of the screen</description>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/crosshairs.png</href>
|
||||
</Icon>
|
||||
<overlayXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/>
|
||||
<size x="0" y="0" xunits="pixels" yunits="pixels"/>
|
||||
</ScreenOverlay>
|
||||
<ScreenOverlay>
|
||||
<name>Absolute Positioning: Top left</name>
|
||||
<visibility>0</visibility>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/top_left.jpg</href>
|
||||
</Icon>
|
||||
<overlayXY x="0" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="0" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
</ScreenOverlay>
|
||||
<ScreenOverlay>
|
||||
<name>Absolute Positioning: Top right</name>
|
||||
<visibility>0</visibility>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/top_right.jpg</href>
|
||||
</Icon>
|
||||
<overlayXY x="1" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="1" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
</ScreenOverlay>
|
||||
<ScreenOverlay>
|
||||
<name>Absolute Positioning: Bottom left</name>
|
||||
<visibility>0</visibility>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/bottom_left.jpg</href>
|
||||
</Icon>
|
||||
<overlayXY x="0" y="-1" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
</ScreenOverlay>
|
||||
<ScreenOverlay>
|
||||
<name>Absolute Positioning: Bottom right</name>
|
||||
<visibility>0</visibility>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/bottom_right.jpg</href>
|
||||
</Icon>
|
||||
<overlayXY x="1" y="-1" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="1" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
</ScreenOverlay>
|
||||
<ScreenOverlay>
|
||||
<name>Dynamic Positioning: Top of screen</name>
|
||||
<visibility>0</visibility>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/dynamic_screenoverlay.jpg</href>
|
||||
</Icon>
|
||||
<overlayXY x="0" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="0" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<size x="1" y="0.2" xunits="fraction" yunits="fraction"/>
|
||||
</ScreenOverlay>
|
||||
<ScreenOverlay>
|
||||
<name>Dynamic Positioning: Right of screen</name>
|
||||
<visibility>0</visibility>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/dynamic_right.jpg</href>
|
||||
</Icon>
|
||||
<overlayXY x="1" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="1" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<size x="0" y="1" xunits="fraction" yunits="fraction"/>
|
||||
</ScreenOverlay>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Paths</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Examples of paths. Note that the tessellate tag is by default
|
||||
set to 0. If you want to create tessellated lines, they must be authored
|
||||
(or edited) directly in KML.</description>
|
||||
<Placemark>
|
||||
<name>Tessellated</name>
|
||||
<visibility>0</visibility>
|
||||
<description><![CDATA[If the <tessellate> tag has a value of 1, the line will contour to the underlying terrain]]></description>
|
||||
<LookAt>
|
||||
<longitude>-112.0822680013139</longitude>
|
||||
<latitude>36.09825589333556</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>103.8120432044965</heading>
|
||||
<tilt>62.04855796276328</tilt>
|
||||
<range>2889.145007690472</range>
|
||||
</LookAt>
|
||||
<LineString>
|
||||
<tessellate>1</tessellate>
|
||||
<coordinates> -112.0814237830345,36.10677870477137,0
|
||||
-112.0870267752693,36.0905099328766,0 </coordinates>
|
||||
</LineString>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Untessellated</name>
|
||||
<visibility>0</visibility>
|
||||
<description><![CDATA[If the <tessellate> tag has a value of 0, the line follow a simple straight-line path from point to point]]></description>
|
||||
<LookAt>
|
||||
<longitude>-112.0822680013139</longitude>
|
||||
<latitude>36.09825589333556</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>103.8120432044965</heading>
|
||||
<tilt>62.04855796276328</tilt>
|
||||
<range>2889.145007690472</range>
|
||||
</LookAt>
|
||||
<LineString>
|
||||
<tessellate>0</tessellate>
|
||||
<coordinates> -112.080622229595,36.10673460007995,0
|
||||
-112.085242575315,36.09049598612422,0 </coordinates>
|
||||
</LineString>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Absolute</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Transparent purple line</description>
|
||||
<LookAt>
|
||||
<longitude>-112.2719329043177</longitude>
|
||||
<latitude>36.08890633450894</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-106.8161545998597</heading>
|
||||
<tilt>44.60763714063257</tilt>
|
||||
<range>2569.386744398339</range>
|
||||
</LookAt>
|
||||
<styleUrl>#transPurpleLineGreenPoly</styleUrl>
|
||||
<LineString>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>absolute</altitudeMode>
|
||||
<coordinates> -112.265654928602,36.09447672602546,2357
|
||||
-112.2660384528238,36.09342608838671,2357
|
||||
-112.2668139013453,36.09251058776881,2357
|
||||
-112.2677826834445,36.09189827357996,2357
|
||||
-112.2688557510952,36.0913137941187,2357
|
||||
-112.2694810717219,36.0903677207521,2357
|
||||
-112.2695268555611,36.08932171487285,2357
|
||||
-112.2690144567276,36.08850916060472,2357
|
||||
-112.2681528815339,36.08753813597956,2357
|
||||
-112.2670588176031,36.08682685262568,2357
|
||||
-112.2657374587321,36.08646312301303,2357 </coordinates>
|
||||
</LineString>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Absolute Extruded</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Transparent green wall with yellow outlines</description>
|
||||
<LookAt>
|
||||
<longitude>-112.2643334742529</longitude>
|
||||
<latitude>36.08563154742419</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-125.7518698668815</heading>
|
||||
<tilt>44.61038665812578</tilt>
|
||||
<range>4451.842204068102</range>
|
||||
</LookAt>
|
||||
<styleUrl>#yellowLineGreenPoly</styleUrl>
|
||||
<LineString>
|
||||
<extrude>1</extrude>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>absolute</altitudeMode>
|
||||
<coordinates> -112.2550785337791,36.07954952145647,2357
|
||||
-112.2549277039738,36.08117083492122,2357
|
||||
-112.2552505069063,36.08260761307279,2357
|
||||
-112.2564540158376,36.08395660588506,2357
|
||||
-112.2580238976449,36.08511401044813,2357
|
||||
-112.2595218489022,36.08584355239394,2357
|
||||
-112.2608216347552,36.08612634548589,2357
|
||||
-112.262073428656,36.08626019085147,2357
|
||||
-112.2633204928495,36.08621519860091,2357
|
||||
-112.2644963846444,36.08627897945274,2357
|
||||
-112.2656969554589,36.08649599090644,2357 </coordinates>
|
||||
</LineString>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Relative</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Black line (10 pixels wide), height tracks terrain</description>
|
||||
<LookAt>
|
||||
<longitude>-112.2580438551384</longitude>
|
||||
<latitude>36.1072674824385</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>4.947421249553717</heading>
|
||||
<tilt>44.61324882043339</tilt>
|
||||
<range>2927.61105910266</range>
|
||||
</LookAt>
|
||||
<styleUrl>#thickBlackLine</styleUrl>
|
||||
<LineString>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<coordinates> -112.2532845153347,36.09886943729116,645
|
||||
-112.2540466121145,36.09919570465255,645
|
||||
-112.254734666947,36.09984998366178,645
|
||||
-112.255493345654,36.10051310621746,645
|
||||
-112.2563157098468,36.10108441943419,645
|
||||
-112.2568033076439,36.10159722088088,645
|
||||
-112.257494011321,36.10204323542867,645
|
||||
-112.2584106072308,36.10229131995655,645
|
||||
-112.2596588987972,36.10240001286358,645
|
||||
-112.2610581199487,36.10213176873407,645
|
||||
-112.2626285262793,36.10157011437219,645 </coordinates>
|
||||
</LineString>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Relative Extruded</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Opaque blue walls with red outline, height tracks terrain</description>
|
||||
<LookAt>
|
||||
<longitude>-112.2683594333433</longitude>
|
||||
<latitude>36.09884362144909</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-72.24271551768405</heading>
|
||||
<tilt>44.60855445139561</tilt>
|
||||
<range>2184.193522571467</range>
|
||||
</LookAt>
|
||||
<styleUrl>#redLineBluePoly</styleUrl>
|
||||
<LineString>
|
||||
<extrude>1</extrude>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<coordinates> -112.2656634181359,36.09445214722695,630
|
||||
-112.2652238941097,36.09520916122063,630
|
||||
-112.2645079986395,36.09580763864907,630
|
||||
-112.2638827428817,36.09628572284063,630
|
||||
-112.2635746835406,36.09679275951239,630
|
||||
-112.2635711822407,36.09740038871899,630
|
||||
-112.2640296531825,36.09804913435539,630
|
||||
-112.264327720538,36.09880337400301,630
|
||||
-112.2642436562271,36.09963644790288,630
|
||||
-112.2639148687042,36.10055381117246,630
|
||||
-112.2626894973474,36.10149062823369,630 </coordinates>
|
||||
</LineString>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Polygons</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Examples of polygon shapes</description>
|
||||
<Folder>
|
||||
<name>Google Campus</name>
|
||||
<visibility>0</visibility>
|
||||
<description>A collection showing how easy it is to create 3-dimensional
|
||||
buildings</description>
|
||||
<LookAt>
|
||||
<longitude>-122.084120030116</longitude>
|
||||
<latitude>37.42174011925477</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-34.82469740081282</heading>
|
||||
<tilt>53.454348562403</tilt>
|
||||
<range>276.7870053764046</range>
|
||||
</LookAt>
|
||||
<Placemark>
|
||||
<name>Building 40</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#transRedPoly</styleUrl>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -122.0848938459612,37.42257124044786,17
|
||||
-122.0849580979198,37.42211922626856,17
|
||||
-122.0847469573047,37.42207183952619,17
|
||||
-122.0845725380962,37.42209006729676,17
|
||||
-122.0845954886723,37.42215932700895,17
|
||||
-122.0838521118269,37.42227278564371,17
|
||||
-122.083792243335,37.42203539112084,17
|
||||
-122.0835076656616,37.42209006957106,17
|
||||
-122.0834709464152,37.42200987395161,17
|
||||
-122.0831221085748,37.4221046494946,17
|
||||
-122.0829247374572,37.42226503990386,17
|
||||
-122.0829339169385,37.42231242843094,17
|
||||
-122.0833837359737,37.42225046087618,17
|
||||
-122.0833607854248,37.42234159228745,17
|
||||
-122.0834204551642,37.42237075460644,17
|
||||
-122.083659133885,37.42251292011001,17
|
||||
-122.0839758438952,37.42265873093781,17
|
||||
-122.0842374743331,37.42265143972521,17
|
||||
-122.0845036949503,37.4226514386435,17
|
||||
-122.0848020460801,37.42261133916315,17
|
||||
-122.0847882750515,37.42256395055121,17
|
||||
-122.0848938459612,37.42257124044786,17 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Building 41</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#transBluePoly</styleUrl>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -122.0857412771483,37.42227033155257,17
|
||||
-122.0858169768481,37.42231408832346,17
|
||||
-122.085852582875,37.42230337469744,17
|
||||
-122.0858799945639,37.42225686138789,17
|
||||
-122.0858860101409,37.4222311076138,17
|
||||
-122.0858069157288,37.42220250173855,17
|
||||
-122.0858379542653,37.42214027058678,17
|
||||
-122.0856732640519,37.42208690214408,17
|
||||
-122.0856022926407,37.42214885429042,17
|
||||
-122.0855902778436,37.422128290487,17
|
||||
-122.0855841672237,37.42208171967246,17
|
||||
-122.0854852065741,37.42210455874995,17
|
||||
-122.0855067264352,37.42214267949824,17
|
||||
-122.0854430712915,37.42212783846172,17
|
||||
-122.0850990714904,37.42251282407603,17
|
||||
-122.0856769818632,37.42281815323651,17
|
||||
-122.0860162273783,37.42244918858722,17
|
||||
-122.0857260327004,37.42229239604253,17
|
||||
-122.0857412771483,37.42227033155257,17 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Building 42</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#transGreenPoly</styleUrl>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -122.0857862287242,37.42136208886969,25
|
||||
-122.0857312990603,37.42136935989481,25
|
||||
-122.0857312992918,37.42140934910903,25
|
||||
-122.0856077073679,37.42138390166565,25
|
||||
-122.0855802426516,37.42137299550869,25
|
||||
-122.0852186221971,37.42137299504316,25
|
||||
-122.0852277765639,37.42161656508265,25
|
||||
-122.0852598189347,37.42160565894403,25
|
||||
-122.0852598185499,37.42168200156,25
|
||||
-122.0852369311478,37.42170017860346,25
|
||||
-122.0852643957828,37.42176197982575,25
|
||||
-122.0853239032746,37.42176198013907,25
|
||||
-122.0853559454324,37.421852864452,25
|
||||
-122.0854108752463,37.42188921823734,25
|
||||
-122.0854795379357,37.42189285337048,25
|
||||
-122.0855436229819,37.42188921797546,25
|
||||
-122.0856260178042,37.42186013499926,25
|
||||
-122.085937287963,37.42186013453605,25
|
||||
-122.0859428718666,37.42160898590042,25
|
||||
-122.0859655469861,37.42157992759144,25
|
||||
-122.0858640462341,37.42147115002957,25
|
||||
-122.0858548911215,37.42140571326184,25
|
||||
-122.0858091162768,37.4214057134039,25
|
||||
-122.0857862287242,37.42136208886969,25 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Building 43</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#transYellowPoly</styleUrl>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -122.0844371128284,37.42177253003091,19
|
||||
-122.0845118855746,37.42191111542896,19
|
||||
-122.0850470999805,37.42178755121535,19
|
||||
-122.0850719913391,37.42143663023161,19
|
||||
-122.084916406232,37.42137237822116,19
|
||||
-122.0842193868167,37.42137237801626,19
|
||||
-122.08421938659,37.42147617161496,19
|
||||
-122.0838086419991,37.4214613409357,19
|
||||
-122.0837899728564,37.42131306410796,19
|
||||
-122.0832796534698,37.42129328840593,19
|
||||
-122.0832609819207,37.42139213944298,19
|
||||
-122.0829373621737,37.42137236399876,19
|
||||
-122.0829062425667,37.42151569778871,19
|
||||
-122.0828502269665,37.42176282576465,19
|
||||
-122.0829435788635,37.42176776969635,19
|
||||
-122.083217411188,37.42179248552686,19
|
||||
-122.0835970430103,37.4217480074456,19
|
||||
-122.0839455556771,37.42169364237603,19
|
||||
-122.0840077894637,37.42176283815853,19
|
||||
-122.084113587521,37.42174801104392,19
|
||||
-122.0840762473784,37.42171341292375,19
|
||||
-122.0841447047739,37.42167881534569,19
|
||||
-122.084144704223,37.42181720660197,19
|
||||
-122.0842503333074,37.4218170700446,19
|
||||
-122.0844371128284,37.42177253003091,19 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Extruded Polygon</name>
|
||||
<description>A simple way to model a building</description>
|
||||
<Placemark>
|
||||
<name>The Pentagon</name>
|
||||
<LookAt>
|
||||
<longitude>-77.05580139178142</longitude>
|
||||
<latitude>38.870832443487</latitude>
|
||||
<heading>59.88865561738225</heading>
|
||||
<tilt>48.09646074797388</tilt>
|
||||
<range>742.0552506670548</range>
|
||||
</LookAt>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -77.05788457660967,38.87253259892824,100
|
||||
-77.05465973756702,38.87291016281703,100
|
||||
-77.05315536854791,38.87053267794386,100
|
||||
-77.05552622493516,38.868757801256,100
|
||||
-77.05844056290393,38.86996206506943,100
|
||||
-77.05788457660967,38.87253259892824,100 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
<innerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -77.05668055019126,38.87154239798456,100
|
||||
-77.05542625960818,38.87167890344077,100
|
||||
-77.05485125901024,38.87076535397792,100
|
||||
-77.05577677433152,38.87008686581446,100
|
||||
-77.05691162017543,38.87054446963351,100
|
||||
-77.05668055019126,38.87154239798456,100 </coordinates>
|
||||
</LinearRing>
|
||||
</innerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Absolute and Relative</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Four structures whose roofs meet exactly. Turn on/off
|
||||
terrain to see the difference between relative and absolute
|
||||
positioning.</description>
|
||||
<LookAt>
|
||||
<longitude>-112.3348969157552</longitude>
|
||||
<latitude>36.14845533214919</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-86.91235037566909</heading>
|
||||
<tilt>49.30695423894192</tilt>
|
||||
<range>990.6761201087104</range>
|
||||
</LookAt>
|
||||
<Placemark>
|
||||
<name>Absolute</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#transBluePoly</styleUrl>
|
||||
<Polygon>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>absolute</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -112.3372510731295,36.14888505105317,1784
|
||||
-112.3356128688403,36.14781540589019,1784
|
||||
-112.3368169371048,36.14658677734382,1784
|
||||
-112.3384408457543,36.14762778914076,1784
|
||||
-112.3372510731295,36.14888505105317,1784 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Absolute Extruded</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#transRedPoly</styleUrl>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>absolute</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -112.3396586818843,36.14637618647505,1784
|
||||
-112.3380597654315,36.14531751871353,1784
|
||||
-112.3368254237788,36.14659596244607,1784
|
||||
-112.3384555043203,36.14762621763982,1784
|
||||
-112.3396586818843,36.14637618647505,1784 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Relative</name>
|
||||
<visibility>0</visibility>
|
||||
<LookAt>
|
||||
<longitude>-112.3350152490417</longitude>
|
||||
<latitude>36.14943123077423</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-118.9214100848499</heading>
|
||||
<tilt>37.92486261093203</tilt>
|
||||
<range>345.5169113679813</range>
|
||||
</LookAt>
|
||||
<styleUrl>#transGreenPoly</styleUrl>
|
||||
<Polygon>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -112.3349463145932,36.14988705767721,100
|
||||
-112.3354019540677,36.14941108398372,100
|
||||
-112.3344428289146,36.14878490381308,100
|
||||
-112.3331289492913,36.14780840132443,100
|
||||
-112.3317019516947,36.14680755678357,100
|
||||
-112.331131440106,36.1474173426228,100
|
||||
-112.332616324338,36.14845453364654,100
|
||||
-112.3339876620524,36.14926570522069,100
|
||||
-112.3349463145932,36.14988705767721,100 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Relative Extruded</name>
|
||||
<visibility>0</visibility>
|
||||
<LookAt>
|
||||
<longitude>-112.3351587892382</longitude>
|
||||
<latitude>36.14979247129029</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-55.42811560891606</heading>
|
||||
<tilt>56.10280503739589</tilt>
|
||||
<range>401.0997279712519</range>
|
||||
</LookAt>
|
||||
<styleUrl>#transYellowPoly</styleUrl>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -112.3348783983763,36.1514008468736,100
|
||||
-112.3372535345629,36.14888517553886,100
|
||||
-112.3356068927954,36.14781612679284,100
|
||||
-112.3350034807972,36.14846469024177,100
|
||||
-112.3358353861232,36.1489624162954,100
|
||||
-112.3345888301373,36.15026229372507,100
|
||||
-112.3337937856278,36.14978096026463,100
|
||||
-112.3331798208424,36.1504472788618,100
|
||||
-112.3348783983763,36.1514008468736,100 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
</Folder>
|
||||
</Document>
|
||||
</kml>
|
||||
19
bower_components/leaflet-plugins/examples/bing.html
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="../layer/tile/Bing.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(67.6755, 33.936), zoom: 10 });
|
||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
var bing = new L.BingLayer("Anqm0F_JjIZvT0P3abS6KONpaBaKuTnITRrnYuiJCE0WOhH6ZbE4DzeT6brvKVR5");
|
||||
map.addLayer(bing);
|
||||
map.addControl(new L.Control.Layers({'OSM':osm, "Bing":bing}, {}));
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
54
bower_components/leaflet-plugins/examples/deferred.html
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<!--<script src="http://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU" type="text/javascript"></script>-->
|
||||
<script src="../layer/Layer.Deferred.js"></script>
|
||||
<!--<script src="../layer/tile/Yandex.js"></script>-->
|
||||
</head>
|
||||
<body>
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(67.6755, 33.936), zoom: 10, zoomAnimation: false });
|
||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
||||
|
||||
var layerdefs = {
|
||||
mapnik: { name: "Mapnik", js: [],
|
||||
init: function() {return new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');}},
|
||||
kosmo: { name: "Космоснимки", js: [],
|
||||
init: function() {return new L.TileLayer('http://{s}.tile.osmosnimki.ru/kosmo/{z}/{x}/{y}.png', {attribution:'Tiles Courtesy of <a href="http://kosmosnimki.ru/" target="_blank">kosmosnimki.ru</a>'});}},
|
||||
gsat: { name: "Google", js: ["../layer/tile/Google.js", "http://maps.google.com/maps/api/js?v=3&sensor=false&callback=L.Google.asyncInitialize"],
|
||||
init: function() {return new L.Google(); }},
|
||||
ysat: { name: "Yandex", js: ["../layer/tile/Yandex.js", "http://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU"],
|
||||
init: function() {return new L.Yandex("satellite"); }},
|
||||
nyak: { name: "НЯК", js: ["../layer/tile/Yandex.js", "http://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU"],
|
||||
init: function() {return new L.Yandex("publicMap"); }},
|
||||
traffic: { name: "Пробки", js: ["../layer/tile/Yandex.js", "http://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU"],
|
||||
init: function() {return new L.Yandex("null", {traffic: true, opacity: 0.8, overlay: true}); }, overlay: true},
|
||||
mso: { name: "Mapsurfer", js: [], overlay: true,
|
||||
init: function() {return new L.TileLayer('http://129.206.74.245:8003/tms_h.ashx?x={x}&y={y}&z={z}');}}
|
||||
};
|
||||
|
||||
var yndx = new L.DeferredLayer(layerdefs.ysat);
|
||||
var kosmo = new L.DeferredLayer(layerdefs.kosmo);
|
||||
var google = new L.DeferredLayer(layerdefs.gsat);
|
||||
var ytraffic = new L.DeferredLayer(layerdefs.traffic);
|
||||
var mso = new L.DeferredLayer(layerdefs.mso);
|
||||
|
||||
L.control.layers(
|
||||
{
|
||||
'OSM':osm,
|
||||
"Kosmo":kosmo,
|
||||
"Google":google,
|
||||
"Yandex":yndx
|
||||
},{
|
||||
"Пробки":ytraffic,
|
||||
"OpenMapSurfer":mso
|
||||
}
|
||||
).addTo(map);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
36
bower_components/leaflet-plugins/examples/distance.html
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<html>
|
||||
<!--
|
||||
vim: sts=4 sw=4 et
|
||||
-->
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<link rel="stylesheet" href="../css/distance.css" />
|
||||
<link rel="stylesheet" href="http://leaflet.github.io/Leaflet.draw/leaflet.draw.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="http://leaflet.github.io/Leaflet.draw/leaflet.draw.js"></script>
|
||||
<script src="../layer/vector/GPX.js"></script>
|
||||
<script src="../control/Scale.js"></script>
|
||||
<script src="../control/Permalink.js"></script>
|
||||
<script src="../control/Permalink.Line.js"></script>
|
||||
<script src="../control/Distance.js"></script>
|
||||
</head>
|
||||
</head>
|
||||
<body>
|
||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var map = new L.Map('map', {center: new L.LatLng(58.4, 43.0), zoom: 11});
|
||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
|
||||
map.addLayer(osm);
|
||||
var d = new L.Control.Distance(); map.addControl(d);
|
||||
map.addControl(new L.Control.Scale());
|
||||
map.addControl(new L.Control.Permalink({line: d.getLine(), useLocation: true}));
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1077
bower_components/leaflet-plugins/examples/fells_loop.gpx
vendored
Normal file
33
bower_components/leaflet-plugins/examples/google-custom.html
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Google Custom Styles // Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
|
||||
<script src="../layer/tile/Google.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(53.9618, 58.4277), zoom: 13});
|
||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
|
||||
var styles = [
|
||||
{
|
||||
featureType: 'all',
|
||||
stylers: [{hue: '#ff0000'}]
|
||||
}
|
||||
];
|
||||
|
||||
var ggl = new L.Google('ROADMAP', {
|
||||
mapOptions: {
|
||||
styles: styles
|
||||
}
|
||||
});
|
||||
map.addLayer(ggl);
|
||||
map.addControl(new L.Control.Layers( {'OSM':osm, 'Google':ggl}, {}));
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
22
bower_components/leaflet-plugins/examples/google.html
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Google // Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
|
||||
<script src="../layer/tile/Google.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(53.9618, 58.4277), zoom: 13});
|
||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
var ggl = new L.Google();
|
||||
var ggl2 = new L.Google('TERRAIN');
|
||||
map.addLayer(ggl);
|
||||
map.addControl(new L.Control.Layers( {'OSM':osm, 'Google':ggl, 'Google Terrain':ggl2}, {}));
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
24
bower_components/leaflet-plugins/examples/gpx-no-wpt.html
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Leaflet - GPX track without Waypoints</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="../layer/vector/GPX.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(58.4, 43.0), zoom: 11});
|
||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
|
||||
var track = new L.GPX("fells_loop.gpx", {async: true, display_wpt:false})
|
||||
.on("loaded", function(e) { map.fitBounds(e.target.getBounds()); });
|
||||
|
||||
map.addLayer(track);
|
||||
map.addLayer(osm);
|
||||
map.addControl(new L.Control.Layers({}, {'GPX':track}));
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
26
bower_components/leaflet-plugins/examples/gpx-speed.html
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="../layer/vector/GPX.js"></script>
|
||||
<script src="../layer/vector/GPX.Speed.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(58.4, 43.0), zoom: 11});
|
||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
|
||||
var track = new L.GPX("speed.gpx", {async: true})
|
||||
.on("loaded", function(e) { map.fitBounds(e.target.getBounds()); })
|
||||
.speedSplitEnable({maxSpeed: 100, chunks: 1000});
|
||||
|
||||
map.addLayer(track);
|
||||
map.addLayer(osm);
|
||||
map.addControl(new L.Control.Layers({}, {'GPX':track}));
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
24
bower_components/leaflet-plugins/examples/gpx.html
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="../layer/vector/GPX.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(58.4, 43.0), zoom: 11});
|
||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
|
||||
var track = new L.GPX("fells_loop.gpx", {async: true})
|
||||
.on("loaded", function(e) { map.fitBounds(e.target.getBounds()); });
|
||||
|
||||
map.addLayer(track);
|
||||
map.addLayer(osm);
|
||||
map.addControl(new L.Control.Layers({}, {'GPX':track}));
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
24
bower_components/leaflet-plugins/examples/kml.html
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="../layer/vector/KML.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(58.4, 43.0), zoom: 11});
|
||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
|
||||
var track = new L.KML("KML_Samples.kml", {async: true});
|
||||
track.on("loaded", function(e) { map.fitBounds(e.target.getBounds()); });
|
||||
|
||||
map.addLayer(track);
|
||||
map.addLayer(osm);
|
||||
map.addControl(new L.Control.Layers({}, {'Track':track}));
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
39
bower_components/leaflet-plugins/examples/marker-canvas.html
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="../layer/Icon.Canvas.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
|
||||
var map = new L.Map('map', {center: new L.LatLng(67.66904, 33.68595), zoom: 10});
|
||||
map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'));
|
||||
|
||||
var circle = new L.Icon.Canvas({iconSize: new L.Point(30, 30)});
|
||||
circle.draw = function(ctx, w, h) {
|
||||
ctx.translate(w/2, h/2);
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = "#F00";
|
||||
ctx.arc(0, 0, w/2-1, 0, Math.PI*2, true);
|
||||
ctx.fill();
|
||||
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = '#FFF';
|
||||
ctx.moveTo(-w/5, -h/5);
|
||||
ctx.lineTo(w/5, h/5);
|
||||
ctx.moveTo(-w/5, h/5);
|
||||
ctx.lineTo(w/5, -h/5);
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
}
|
||||
|
||||
map.addLayer(new L.Marker(map.getCenter(), {icon: circle, draggable: true, opacity: 0.7}));
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
27
bower_components/leaflet-plugins/examples/marker-rotate.html
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="../layer/Marker.Rotate.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(67.6755, 33.936), zoom: 10});
|
||||
map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'));
|
||||
|
||||
var marker = new L.Marker(map.getCenter(), {iconAngle: 90});
|
||||
map.addLayer(marker);
|
||||
|
||||
var angle = 0;
|
||||
function _rotate() {
|
||||
marker.setIconAngle(angle);
|
||||
angle = (angle + 10) % 360;
|
||||
setTimeout(_rotate, 1000);
|
||||
}
|
||||
_rotate();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
21
bower_components/leaflet-plugins/examples/marker-text.html
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="../layer/Marker.Text.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(67.66904, 33.68595), zoom: 10});
|
||||
map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'));
|
||||
|
||||
var marker = new L.Marker.Text(map.getCenter(), 'Sweet!');
|
||||
map.addLayer(new L.Marker(map.getCenter(), {opacity: 0.5}));
|
||||
map.addLayer(marker);
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
24
bower_components/leaflet-plugins/examples/osb.html
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<html>
|
||||
<!--
|
||||
vim: sts=4 sw=4 et
|
||||
-->
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<link rel="stylesheet" href="../css/osb.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="../layer/OpenStreetBugs.js"></script>
|
||||
</head>
|
||||
</head>
|
||||
<body>
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type="text/javascript">
|
||||
|
||||
var map = new L.Map('map', {center: new L.LatLng(57.62, 39.89), zoom: 11});
|
||||
|
||||
map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'));
|
||||
map.addLayer(new L.OpenStreetBugs());
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
21
bower_components/leaflet-plugins/examples/osm.html
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="../layer/vector/OSM.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(55.7, 37.6), zoom: 9, zoomAnimation: false });
|
||||
map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'));
|
||||
var layer = new L.OSM('ulugo.osm')
|
||||
.on("loaded", function(e) { map.fitBounds(e.target.getBounds()); });
|
||||
map.addLayer(layer);
|
||||
map.addControl(new L.Control.Layers({}, {"OSM":layer}));
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
23
bower_components/leaflet-plugins/examples/permalink.html
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="../control/Permalink.js"></script>
|
||||
<script src="../control/Permalink.Marker.js"></script>
|
||||
<script src="../control/Permalink.Layer.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(67.6755, 33.936), zoom: 10});
|
||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
map.addLayer(osm);
|
||||
var kosm = new L.TileLayer('http://{s}.tile.osmosnimki.ru/kosmo/{z}/{x}/{y}.png', {attribution:'Tiles Courtesy of <a href="http://kosmosnimki.ru/" target="_blank">kosmosnimki.ru</a>'});
|
||||
var layers = new L.Control.Layers({'OSM':osm, "Kosmo":kosm});
|
||||
map.addControl(layers);
|
||||
map.addControl(new L.Control.Permalink({text: 'Permalink', layers: layers}));
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
80059
bower_components/leaflet-plugins/examples/speed.gpx
vendored
Executable file
24
bower_components/leaflet-plugins/examples/yandex.html
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="http://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU" type="text/javascript"></script>
|
||||
<script src="../layer/tile/Yandex.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script type='text/javascript'>
|
||||
var map = new L.Map('map', {center: new L.LatLng(67.6755, 33.936), zoom: 10, zoomAnimation: false });
|
||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
var yndx = new L.Yandex();
|
||||
var ytraffic = new L.Yandex("null", {traffic:true, opacity:0.8, overlay:true});
|
||||
|
||||
map.addLayer(osm);
|
||||
map.addLayer(ytraffic);
|
||||
map.addControl(new L.Control.Layers({'OSM':osm, "Yandex":yndx},
|
||||
{"Traffic":ytraffic}));
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
27
bower_components/leaflet-plugins/layer/Icon.Canvas.js
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
L.Icon.Canvas = L.Icon.extend({
|
||||
options: {
|
||||
iconSize: new L.Point(20, 20), // Have to be supplied
|
||||
/*
|
||||
iconAnchor: (Point)
|
||||
popupAnchor: (Point)
|
||||
*/
|
||||
className: 'leaflet-canvas-icon'
|
||||
},
|
||||
|
||||
createIcon: function () {
|
||||
var e = document.createElement('canvas');
|
||||
this._setIconStyles(e, 'icon');
|
||||
var s = this.options.iconSize;
|
||||
e.width = s.x
|
||||
e.height = s.y;
|
||||
this.draw(e.getContext('2d'), s.x, s.y);
|
||||
return e;
|
||||
},
|
||||
|
||||
createShadow: function () {
|
||||
return null;
|
||||
},
|
||||
|
||||
draw: function(canvas, width, height) {
|
||||
}
|
||||
});
|
||||
57
bower_components/leaflet-plugins/layer/Layer.Deferred.js
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
L.DeferredLayer = L.LayerGroup.extend({
|
||||
options: {
|
||||
js: [],
|
||||
init: null
|
||||
},
|
||||
|
||||
_script_cache: {},
|
||||
|
||||
initialize: function(options) {
|
||||
L.Util.setOptions(this, options);
|
||||
L.LayerGroup.prototype.initialize.apply(this);
|
||||
this._loaded = false;
|
||||
},
|
||||
|
||||
onAdd: function(map) {
|
||||
L.LayerGroup.prototype.onAdd.apply(this, [map]);
|
||||
if (this._loaded) return;
|
||||
//console.info("Script cache", this._script_cache);
|
||||
var loaded = function() {
|
||||
//console.info("Loaded", this, this.options);
|
||||
this._loaded = true;
|
||||
var l = this.options.init();
|
||||
if (l)
|
||||
this.addLayer(l);
|
||||
}
|
||||
this._loadScripts(this.options.js.reverse(), L.Util.bind(loaded, this));
|
||||
},
|
||||
|
||||
_loadScripts: function(scripts, cb, args) {
|
||||
if (!scripts || scripts.length == 0)
|
||||
return cb(args);
|
||||
var _this = this, s = scripts.pop(), c;
|
||||
c = this._script_cache[s];
|
||||
if (c === undefined) {
|
||||
c = {url: s, wait: []};
|
||||
//console.info("Load ", s);
|
||||
var script = document.createElement('script');
|
||||
script.src = s;
|
||||
script.type = 'text/javascript';
|
||||
script.onload = function () {
|
||||
//console.info("Element(cb)", c.e.readyState);
|
||||
c.e.readyState = "completed";
|
||||
var i = 0;
|
||||
for (i = 0; i < c.wait.length; i++)
|
||||
c.wait[i]();
|
||||
}
|
||||
c.e = script;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
}
|
||||
function _cb() { _this._loadScripts(scripts, cb, args); }
|
||||
c.wait.push(_cb);
|
||||
//console.info("Element", c.e.readyState);
|
||||
if (c.e.readyState == "completed")
|
||||
_cb();
|
||||
this._script_cache[s] = c;
|
||||
}
|
||||
});
|
||||
53
bower_components/leaflet-plugins/layer/Marker.Rotate.js
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Based on comments by @runanet and @coomsie
|
||||
* https://github.com/CloudMade/Leaflet/issues/386
|
||||
*
|
||||
* Wrapping function is needed to preserve L.Marker.update function
|
||||
*/
|
||||
(function () {
|
||||
var _old__setPos = L.Marker.prototype._setPos;
|
||||
L.Marker.include({
|
||||
_updateImg: function(i, a, s) {
|
||||
a = L.point(s).divideBy(2)._subtract(L.point(a));
|
||||
var transform = '';
|
||||
transform += ' translate(' + -a.x + 'px, ' + -a.y + 'px)';
|
||||
transform += ' rotate(' + this.options.iconAngle + 'deg)';
|
||||
transform += ' translate(' + a.x + 'px, ' + a.y + 'px)';
|
||||
i.style[L.DomUtil.TRANSFORM] += transform;
|
||||
},
|
||||
|
||||
setIconAngle: function (iconAngle) {
|
||||
this.options.iconAngle = iconAngle;
|
||||
|
||||
if (this._map) this.update();
|
||||
},
|
||||
|
||||
_setPos: function (pos) {
|
||||
if (this._icon) {
|
||||
this._icon.style[L.DomUtil.TRANSFORM] = "";
|
||||
}
|
||||
if (this._shadow) {
|
||||
this._shadow.style[L.DomUtil.TRANSFORM] = "";
|
||||
}
|
||||
|
||||
_old__setPos.apply(this,[pos]);
|
||||
|
||||
if (this.options.iconAngle) {
|
||||
var a = this.options.icon.options.iconAnchor;
|
||||
var s = this.options.icon.options.iconSize;
|
||||
var i;
|
||||
if (this._icon) {
|
||||
i = this._icon;
|
||||
this._updateImg(i, a, s);
|
||||
}
|
||||
|
||||
if (this._shadow) {
|
||||
// Rotate around the icons anchor.
|
||||
s = this.options.icon.options.shadowSize;
|
||||
i = this._shadow;
|
||||
this._updateImg(i, a, s);
|
||||
}
|
||||
|
||||
} }
|
||||
});
|
||||
}());
|
||||
51
bower_components/leaflet-plugins/layer/Marker.Text.js
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
L.Icon.Text = L.Icon.extend({
|
||||
initialize: function (text, options) {
|
||||
this._text = text;
|
||||
L.Icon.prototype.initialize.apply(this, [options]);
|
||||
},
|
||||
|
||||
createIcon: function() {
|
||||
var el = document.createElement('div');
|
||||
el.appendChild(document.createTextNode(this._text));
|
||||
this._setIconStyles(el, 'icon');
|
||||
el.style.textShadow = "2px 2px 2px #fff";
|
||||
return el;
|
||||
},
|
||||
|
||||
createShadow: function() { return null; }
|
||||
|
||||
});
|
||||
|
||||
L.Marker.Text = L.Marker.extend({
|
||||
initialize: function (latlng, text, options) {
|
||||
L.Marker.prototype.initialize.apply(this, [latlng, options]);
|
||||
this._fakeicon = new L.Icon.Text(text);
|
||||
},
|
||||
|
||||
_initIcon: function() {
|
||||
L.Marker.prototype._initIcon.apply(this);
|
||||
|
||||
var i = this._icon, s = this._shadow, obj = this.options.icon
|
||||
this._icon = this._shadow = null;
|
||||
|
||||
this.options.icon = this._fakeicon;
|
||||
L.Marker.prototype._initIcon.apply(this);
|
||||
this.options.icon = obj;
|
||||
|
||||
if (s) {
|
||||
s.parentNode.removeChild(s);
|
||||
this._icon.appendChild(s);
|
||||
}
|
||||
|
||||
i.parentNode.removeChild(i);
|
||||
this._icon.appendChild(i);
|
||||
|
||||
var w = this._icon.clientWidth, h = this._icon.clientHeight;
|
||||
this._icon.style.marginLeft = -w / 2 + "px";
|
||||
//this._icon.style.backgroundColor = "red";
|
||||
var off = new L.Point(w/2, 0);
|
||||
if (L.Browser.webkit) off.y = -h;
|
||||
L.DomUtil.setPosition(i, off);
|
||||
if (s) L.DomUtil.setPosition(s, off);
|
||||
}
|
||||
});
|
||||
497
bower_components/leaflet-plugins/layer/OpenStreetBugs.js
vendored
Normal file
|
|
@ -0,0 +1,497 @@
|
|||
L.OpenStreetBugs = L.FeatureGroup.extend({
|
||||
options : {
|
||||
serverURL : "http://openstreetbugs.schokokeks.org/api/0.1/",
|
||||
readonly : false,
|
||||
setCookie : true,
|
||||
username : "NoName",
|
||||
cookieLifetime : 1000,
|
||||
cookiePath : null,
|
||||
permalinkZoom : 14,
|
||||
permalinkUrl: null,
|
||||
opacity : 0.7,
|
||||
showOpen: true,
|
||||
showClosed: true,
|
||||
iconOpen: "http://openstreetbugs.schokokeks.org/client/open_bug_marker.png",
|
||||
iconClosed:"http://openstreetbugs.schokokeks.org/client/closed_bug_marker.png",
|
||||
iconActive: undefined,
|
||||
editArea: 0.01,
|
||||
popupOptions: {autoPan: false},
|
||||
dblClick: true
|
||||
},
|
||||
|
||||
initialize : function(options)
|
||||
{
|
||||
var tmp = L.Util.extend({}, this.options.popupOptions, (options || {}).popupOptions)
|
||||
L.Util.setOptions(this, options)
|
||||
this.options.popupOptions = tmp;
|
||||
|
||||
putAJAXMarker.layers.push(this);
|
||||
|
||||
this.bugs = {};
|
||||
this._layers = {};
|
||||
|
||||
var username = this.get_cookie("osbUsername");
|
||||
if (username)
|
||||
this.options.username = username;
|
||||
|
||||
L.OpenStreetBugs.setCSS();
|
||||
},
|
||||
|
||||
onAdd : function(map)
|
||||
{
|
||||
L.FeatureGroup.prototype.onAdd.apply(this, [map]);
|
||||
|
||||
this._map.on("moveend", this.loadBugs, this);
|
||||
this.loadBugs();
|
||||
if (!this.options.readonly) {
|
||||
if (this.options.dblClick) {
|
||||
map.doubleClickZoom.disable();
|
||||
map.on('dblclick', this.addBug, this);
|
||||
}
|
||||
else {
|
||||
map.on('click', this.addBug, this);
|
||||
}
|
||||
}
|
||||
this.fire('add');
|
||||
},
|
||||
|
||||
onRemove : function(map)
|
||||
{
|
||||
this._map.off("moveend", this.loadBugs, this);
|
||||
this._iterateLayers(map.removeLayer, map);
|
||||
delete this._map;
|
||||
if (!this.options.readonly) {
|
||||
if (this.options.dblClick) {
|
||||
map.doubleClickZoom.enable();
|
||||
map.off('dblclick', this.addBug, this);
|
||||
}
|
||||
else {
|
||||
map.off('click', this.addBug, this);
|
||||
}
|
||||
}
|
||||
this.fire('remove');
|
||||
},
|
||||
|
||||
set_cookie : function(name, value)
|
||||
{
|
||||
var expires = (new Date((new Date()).getTime() + 604800000)).toGMTString(); // one week from now
|
||||
document.cookie = name+"="+escape(value)+";";
|
||||
},
|
||||
|
||||
get_cookie : function(name)
|
||||
{
|
||||
var cookies = (document.cookie || '').split(/;\s*/);
|
||||
for(var i=0; i<cookies.length; i++)
|
||||
{
|
||||
var cookie = cookies[i].split("=");
|
||||
if(cookie[0] == name)
|
||||
return unescape(cookie[1]);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
loadBugs : function()
|
||||
{
|
||||
//if(!this.getVisibility())
|
||||
// return true;
|
||||
|
||||
var bounds = this._map.getBounds();
|
||||
if(!bounds) return false;
|
||||
var sw = bounds.getSouthWest(), ne = bounds.getNorthEast();
|
||||
|
||||
function round(number, digits) {
|
||||
var factor = Math.pow(10, digits);
|
||||
return Math.round(number*factor)/factor;
|
||||
}
|
||||
|
||||
this.apiRequest("getBugs"
|
||||
+ "?t="+round(ne.lat, 5)
|
||||
+ "&r="+round(ne.lng, 5)
|
||||
+ "&b="+round(sw.lat, 5)
|
||||
+ "&l="+round(sw.lng, 5));
|
||||
},
|
||||
|
||||
apiRequest : function(url, reload)
|
||||
{
|
||||
var script = document.createElement("script");
|
||||
script.type = "text/javascript";
|
||||
script.src = this.options.serverURL + url + "&nocache="+(new Date()).getTime();
|
||||
var _this = this;
|
||||
script.onload = function(e) {
|
||||
document.body.removeChild(this);
|
||||
if (reload) _this.loadBugs();
|
||||
};
|
||||
document.body.appendChild(script);
|
||||
},
|
||||
|
||||
createMarker: function(id, force)
|
||||
{
|
||||
var bug = putAJAXMarker.bugs[id];
|
||||
if(this.bugs[id])
|
||||
{
|
||||
if (force || this.bugs[id].osb.closed != bug[2])
|
||||
this.removeLayer(this.bugs[id]);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
var closed = bug[2];
|
||||
|
||||
if (closed && !this.options.showClosed) return;
|
||||
if (!closed && !this.options.showOpen) return;
|
||||
|
||||
var icon_url = null;
|
||||
var class_popup = ' osb';
|
||||
if (bug[2]) {
|
||||
icon_url = this.options.iconClosed;
|
||||
class_popup += ' osbClosed';
|
||||
}
|
||||
else if (bug[1].length == 1) {
|
||||
icon_url = this.options.iconOpen;
|
||||
class_popup += ' osbOpen';
|
||||
}
|
||||
else {
|
||||
if (this.options.iconActive) {
|
||||
icon_url = this.options.iconActive;
|
||||
class_popup += ' osbActive';
|
||||
}
|
||||
else {
|
||||
icon_url = this.options.iconOpen;
|
||||
class_popup += ' osbOpen';
|
||||
}
|
||||
}
|
||||
var feature = new L.Marker(bug[0], {icon:new this.osbIcon({iconUrl: icon_url})});
|
||||
feature.osb = {id: id, closed: closed};
|
||||
this.addLayer(feature);
|
||||
this.bugs[id] = feature;
|
||||
this.setPopupContent(id);
|
||||
feature._popup.options.className += class_popup;
|
||||
|
||||
if (this.options.bugid && (parseInt(this.options.bugid) == id))
|
||||
feature.openPopup();
|
||||
|
||||
//this.events.triggerEvent("markerAdded");
|
||||
},
|
||||
|
||||
osbIcon : L.Icon.extend({
|
||||
options: {
|
||||
iconUrl: 'http://openstreetbugs.schokokeks.org/client/open_bug_marker.png',
|
||||
iconSize: new L.Point(22, 22),
|
||||
shadowSize: new L.Point(0, 0),
|
||||
iconAnchor: new L.Point(11, 11),
|
||||
popupAnchor: new L.Point(0, -11)
|
||||
}
|
||||
}),
|
||||
|
||||
setPopupContent: function(id) {
|
||||
if(this.bugs[id]._popup_content)
|
||||
return;
|
||||
|
||||
var el1,el2,el3;
|
||||
var layer = this;
|
||||
|
||||
var rawbug = putAJAXMarker.bugs[id];
|
||||
var isclosed = rawbug[2];
|
||||
|
||||
var newContent = L.DomUtil.create('div', 'osb-popup');
|
||||
var h1 = L.DomUtil.create('h1', null, newContent);
|
||||
if (rawbug[2])
|
||||
h1.textContent = L.i18n("Fixed Error");
|
||||
else if (rawbug[1].length == 1)
|
||||
h1.textContent = L.i18n("Unresolved Error");
|
||||
else
|
||||
h1.textContent = L.i18n("Active Error");
|
||||
|
||||
var divinfo = L.DomUtil.create('div', 'osb-info', newContent);
|
||||
var table = L.DomUtil.create('table', 'osb-table', divinfo);
|
||||
for(var i=0; i<rawbug[1].length; i++)
|
||||
{
|
||||
var tr = L.DomUtil.create('tr', "osb-tr-info", table);
|
||||
tr.setAttribute("valign","top")
|
||||
var td = L.DomUtil.create('td', "osb-td-nickname", tr);
|
||||
td.textContent = rawbug[5][i] + ':';
|
||||
var td = L.DomUtil.create('td', "osb-td-datetime", tr);
|
||||
td.textContent = rawbug[6][i];
|
||||
var td = L.DomUtil.create('td', "osb-td-comment", L.DomUtil.create('tr', "osb-tr-comment", table));
|
||||
td.setAttribute("colspan","2");
|
||||
td.setAttribute("charoff","2");
|
||||
td.textContent = rawbug[4][i];
|
||||
}
|
||||
|
||||
function create_link(ul, text) {
|
||||
var a = L.DomUtil.create('a', null,
|
||||
L.DomUtil.create('li', null, ul));
|
||||
a.href = '#';
|
||||
a.textContent = L.i18n(text);
|
||||
return a;
|
||||
};
|
||||
|
||||
var ul = L.DomUtil.create('ul', null, newContent);
|
||||
var _this = this;
|
||||
var bug = this.bugs[id];
|
||||
|
||||
function showComment(title, add_comment) {
|
||||
h1.textContent_old = h1.textContent;
|
||||
h1.textContent = L.i18n(title);
|
||||
var form = _this.createCommentForm();
|
||||
form.osbid.value = id;
|
||||
form.cancel.onclick = function (e) {
|
||||
h1.textContent = h1.textContent_old;
|
||||
newContent.removeChild(form);
|
||||
newContent.appendChild(ul);
|
||||
}
|
||||
form.ok.onclick = function(e) {
|
||||
bug.closePopup();
|
||||
if (!add_comment)
|
||||
_this.closeBug(form);
|
||||
else
|
||||
_this.submitComment(form);
|
||||
return false;
|
||||
};
|
||||
newContent.appendChild(form);
|
||||
newContent.removeChild(ul);
|
||||
return false;
|
||||
};
|
||||
|
||||
if (!isclosed && !this.options.readonly) {
|
||||
var a;
|
||||
a = create_link(ul, "Add comment");
|
||||
a.onclick = function(e) { return showComment("Add comment", true); }
|
||||
|
||||
a = create_link(ul, "Mark as Fixed");
|
||||
a.onclick = function(e) { return showComment("Close bug", false); }
|
||||
}
|
||||
var a = create_link(ul, "JOSM");
|
||||
a.onclick = function() { _this.remoteEdit(rawbug[0]); };
|
||||
|
||||
var a = create_link(ul, "Link");
|
||||
var vars = {lat:rawbug[0].lat, lon:rawbug[0].lng, zoom:this.options.permalinkZoom, bugid:id}
|
||||
if (this.options.permalinkUrl)
|
||||
a.href = L.Util.template(this.options.permalinkUrl, vars)
|
||||
else
|
||||
a.href = location.protocol + '//' + location.host + location.pathname +
|
||||
L.Util.getParamString(vars)
|
||||
|
||||
|
||||
bug._popup_content = newContent;
|
||||
bug.bindPopup(newContent, this.options.popupOptions);
|
||||
bug._popup.options.maxWidth=410;
|
||||
bug._popup.options.minWidth=410;
|
||||
bug.on('mouseover', bug.openTempPopup, bug);
|
||||
},
|
||||
|
||||
submitComment: function(form) {
|
||||
if (!form.osbcomment.value) return;
|
||||
var nickname = form.osbnickname.value || this.options.username;
|
||||
this.apiRequest("editPOIexec"
|
||||
+ "?id="+encodeURIComponent(form.osbid.value)
|
||||
+ "&text="+encodeURIComponent(form.osbcomment.value + " [" + nickname + "]")
|
||||
+ "&format=js", true
|
||||
);
|
||||
this.set_cookie("osbUsername",nickname);
|
||||
this.options.username=nickname;
|
||||
},
|
||||
|
||||
closeBug: function(form) {
|
||||
var id = form.osbid.value;
|
||||
this.submitComment(form);
|
||||
this.apiRequest("closePOIexec"
|
||||
+ "?id="+encodeURIComponent(id)
|
||||
+ "&format=js", true
|
||||
);
|
||||
},
|
||||
|
||||
createCommentForm: function(elt) {
|
||||
var form = L.DomUtil.create("form", 'osb-add-comment', elt);
|
||||
var content = '';
|
||||
content += '<input name="osbid" type="hidden"/>';
|
||||
content += '<input name="osblat" type="hidden"/>';
|
||||
content += '<input name="osblon" type="hidden"/>';
|
||||
content += '<div><span class="osb-inputlabel">'+L.i18n('Nickname')+':</span><input type="text" name="osbnickname"></div>';
|
||||
content += '<div><span class="osb-inputlabel">'+L.i18n('Comment')+':</span><input type="text" name="osbcomment"></div>';
|
||||
content += '<div class="osb-formfooter"><input type="submit" name="ok"/><input type="button" name="cancel"/></div>';
|
||||
form.innerHTML = content;
|
||||
form.ok.value = L.i18n('OK');
|
||||
form.cancel.value = L.i18n('Cancel');
|
||||
form.osbnickname.value = this.options.username;
|
||||
return form;
|
||||
},
|
||||
|
||||
addBug: function(e) {
|
||||
var newContent = L.DomUtil.create('div', 'osb-popup');
|
||||
|
||||
newContent.innerHTML += '<h1>'+L.i18n("New bug")+'</h1>';
|
||||
newContent.innerHTML += '<div class="osbCreateInfo">'+L.i18n("Find your bug?")+'<br />'+L.i18n("Contact details and someone will fix it.")+'</div>';
|
||||
|
||||
var popup = new L.Popup();
|
||||
var _this = this;
|
||||
var form = this.createCommentForm(newContent);
|
||||
form.osblat.value = e.latlng.lat;
|
||||
form.osblon.value = e.latlng.lng;
|
||||
form.ok.value = L.i18n("Add comment");
|
||||
form.onsubmit = function(e) {
|
||||
_this._map.closePopup(popup);
|
||||
_this.createBug(form);
|
||||
return false;
|
||||
};
|
||||
form.cancel.onclick = function(e) { _this._map.closePopup(popup); }
|
||||
|
||||
popup.setLatLng(e.latlng);
|
||||
popup.setContent(newContent);
|
||||
popup.options.maxWidth=410;
|
||||
popup.options.minWidth=410;
|
||||
popup.options.className += ' osb osbCreate'
|
||||
|
||||
this._map.openPopup(popup);
|
||||
},
|
||||
|
||||
createBug: function(form) {
|
||||
if (!form.osbcomment.value) return;
|
||||
var nickname = form.osbnickname.value || this.options.username;
|
||||
this.apiRequest("addPOIexec"
|
||||
+ "?lat="+encodeURIComponent(form.osblat.value)
|
||||
+ "&lon="+encodeURIComponent(form.osblon.value)
|
||||
+ "&text="+encodeURIComponent(form.osbcomment.value + " [" + nickname + "]")
|
||||
+ "&format=js", true
|
||||
);
|
||||
this.set_cookie("osbUsername",nickname);
|
||||
this.options.username=nickname;
|
||||
},
|
||||
|
||||
remoteEdit: function(x) {
|
||||
var ydelta = this.options.editArea || 0.01;
|
||||
var xdelta = ydelta * 2;
|
||||
var p = [ 'left=' + (x.lng - xdelta), 'bottom=' + (x.lat - ydelta)
|
||||
, 'right=' + (x.lng + xdelta), 'top=' + (x.lat + ydelta)];
|
||||
var url = 'http://localhost:8111/load_and_zoom?' + p.join('&');
|
||||
var frame = L.DomUtil.create('iframe', null);
|
||||
frame.style.display = 'none';
|
||||
frame.src = url;
|
||||
document.body.appendChild(frame);
|
||||
frame.onload = function(e) { document.body.removeChild(frame); };
|
||||
return false;
|
||||
}
|
||||
})
|
||||
|
||||
L.OpenStreetBugs.setCSS = function() {
|
||||
if(L.OpenStreetBugs.setCSS.done)
|
||||
return;
|
||||
else
|
||||
L.OpenStreetBugs.setCSS.done = true;
|
||||
|
||||
// See http://www.hunlock.com/blogs/Totally_Pwn_CSS_with_Javascript
|
||||
var idx = 0;
|
||||
var addRule = function(selector, rules) {
|
||||
var s = document.styleSheets[0];
|
||||
var rule;
|
||||
if(s.addRule) // M$IE
|
||||
rule = s.addRule(selector, rules, idx);
|
||||
else
|
||||
rule = s.insertRule(selector + " { " + rules + " }", idx);
|
||||
s.style = L.Util.extend(s.style || {}, rules);
|
||||
idx++;
|
||||
};
|
||||
|
||||
addRule(".osb-popup dl", 'margin:0; padding:0;');
|
||||
addRule(".osb-popup dt", 'margin:0; padding:0; font-weight:bold; float:left; clear:left;');
|
||||
addRule(".osb-popup dt:after", 'content: ": ";');
|
||||
addRule("* html .osb-popup dt", 'margin-right:1ex;');
|
||||
addRule(".osb-popup dd", 'margin:0; padding:0;');
|
||||
addRule(".osb-popup ul.buttons", 'list-style-type:none; padding:0; margin:0;');
|
||||
addRule(".osb-popup ul.buttons li", 'display:inline; margin:0; padding:0;');
|
||||
addRule(".osb-popup h3", 'font-size:1.2em; margin:.2em 0 .7em 0;');
|
||||
};
|
||||
|
||||
function putAJAXMarker(id, lon, lat, text, closed)
|
||||
{
|
||||
var comments = text.split(/<hr \/>/);
|
||||
var comments_only = []
|
||||
var nickname = [];
|
||||
var datetime = [];
|
||||
var info = null;
|
||||
var isplit = 0;
|
||||
for(var i=0; i<comments.length; i++) {
|
||||
info = null;
|
||||
isplit = 0;
|
||||
comments[i] = comments[i].replace(/"/g, "\"").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&");
|
||||
isplit = comments[i].lastIndexOf("[");
|
||||
if (isplit > 0) {
|
||||
comments_only[i] = comments[i].substr(0,isplit-1);
|
||||
info = comments[i].substr(isplit+1);
|
||||
nickname[i] = info.substr(0,info.lastIndexOf(","));
|
||||
datetime[i] = info.substr(info.lastIndexOf(",")+2);
|
||||
datetime[i] = datetime[i].substr(0,datetime[i].lastIndexOf("]"));
|
||||
}
|
||||
else {
|
||||
comments_only[i] = comments[i];
|
||||
}
|
||||
}
|
||||
var old = putAJAXMarker.bugs[id];
|
||||
putAJAXMarker.bugs[id] = [
|
||||
new L.LatLng(lat, lon),
|
||||
comments,
|
||||
closed,
|
||||
text,
|
||||
comments_only,
|
||||
nickname,
|
||||
datetime
|
||||
];
|
||||
var force = (old && old[3]) != text;
|
||||
for(var i=0; i<putAJAXMarker.layers.length; i++)
|
||||
putAJAXMarker.layers[i].createMarker(id, force);
|
||||
}
|
||||
|
||||
function osbResponse(error)
|
||||
{
|
||||
if(error)
|
||||
alert("Error: "+error);
|
||||
|
||||
return;
|
||||
for(var i=0; i<putAJAXMarker.layers.length; i++)
|
||||
putAJAXMarker.layers[i].loadBugs();
|
||||
}
|
||||
|
||||
putAJAXMarker.layers = [ ];
|
||||
putAJAXMarker.bugs = { };
|
||||
|
||||
L.Marker.include({
|
||||
openTempPopup: function() {
|
||||
this.openPopup();
|
||||
this.off('click', this.openPopup, this);
|
||||
|
||||
function onclick() {
|
||||
this.off('mouseout', onout, this);
|
||||
this.off('click', onclick, this);
|
||||
this.on('click', this.openPopup, this)
|
||||
}
|
||||
|
||||
function onout() {
|
||||
onclick.call(this);
|
||||
this.closePopup();
|
||||
};
|
||||
this.on("mouseout", onout, this);
|
||||
this.on("click", onclick, this);
|
||||
}
|
||||
});
|
||||
|
||||
L.i18n = function(s) { return (L.i18n.lang[L.i18n.current] || {})[s] || s; }
|
||||
L.i18n.current = 'ru';
|
||||
L.i18n.lang = {};
|
||||
L.i18n.extend = function(lang, args) {
|
||||
L.i18n.lang[lang] = L.Util.extend(L.i18n.lang[lang] || {}, args)
|
||||
};
|
||||
|
||||
L.i18n.extend('ru', {
|
||||
"Fixed Error":"Ошибка исправлена",
|
||||
"Unresolved Error":"Неисправленная ошибка",
|
||||
"Active Error":"Ошибка уточняется",
|
||||
"Description":"Описание",
|
||||
"Comment":"Описание",
|
||||
"Add comment":"Дополнить",
|
||||
"Mark as Fixed":"Исправлено",
|
||||
"Link":"Ссылка",
|
||||
"Cancel":"Отмена",
|
||||
"New bug":"Я нашел ошибку",
|
||||
"Find your bug?":"Нашли ошибку?",
|
||||
"Contact details and someone will fix it.":"Напишите подробнее и кто-нибудь её исправит."
|
||||
});
|
||||
124
bower_components/leaflet-plugins/layer/tile/Bing.js
vendored
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
L.BingLayer = L.TileLayer.extend({
|
||||
options: {
|
||||
subdomains: [0, 1, 2, 3],
|
||||
type: 'Aerial',
|
||||
attribution: 'Bing',
|
||||
culture: ''
|
||||
},
|
||||
|
||||
initialize: function(key, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
this._key = key;
|
||||
this._url = null;
|
||||
this.meta = {};
|
||||
this.loadMetadata();
|
||||
},
|
||||
|
||||
tile2quad: function(x, y, z) {
|
||||
var quad = '';
|
||||
for (var i = z; i > 0; i--) {
|
||||
var digit = 0;
|
||||
var mask = 1 << (i - 1);
|
||||
if ((x & mask) != 0) digit += 1;
|
||||
if ((y & mask) != 0) digit += 2;
|
||||
quad = quad + digit;
|
||||
}
|
||||
return quad;
|
||||
},
|
||||
|
||||
getTileUrl: function(p, z) {
|
||||
var z = this._getZoomForUrl();
|
||||
var subdomains = this.options.subdomains,
|
||||
s = this.options.subdomains[Math.abs((p.x + p.y) % subdomains.length)];
|
||||
return this._url.replace('{subdomain}', s)
|
||||
.replace('{quadkey}', this.tile2quad(p.x, p.y, z))
|
||||
.replace('http:', document.location.protocol)
|
||||
.replace('{culture}', this.options.culture);
|
||||
},
|
||||
|
||||
loadMetadata: function() {
|
||||
var _this = this;
|
||||
var cbid = '_bing_metadata_' + L.Util.stamp(this);
|
||||
window[cbid] = function (meta) {
|
||||
_this.meta = meta;
|
||||
window[cbid] = undefined;
|
||||
var e = document.getElementById(cbid);
|
||||
e.parentNode.removeChild(e);
|
||||
if (meta.errorDetails) {
|
||||
if (window.console) console.log("Leaflet Bing Plugin Error - Got metadata: " + meta.errorDetails);
|
||||
return;
|
||||
}
|
||||
_this.initMetadata();
|
||||
};
|
||||
var url = document.location.protocol + "//dev.virtualearth.net/REST/v1/Imagery/Metadata/" + this.options.type + "?include=ImageryProviders&jsonp=" + cbid + "&key=" + this._key;
|
||||
var script = document.createElement("script");
|
||||
script.type = "text/javascript";
|
||||
script.src = url;
|
||||
script.id = cbid;
|
||||
document.getElementsByTagName("head")[0].appendChild(script);
|
||||
},
|
||||
|
||||
initMetadata: function() {
|
||||
var r = this.meta.resourceSets[0].resources[0];
|
||||
this.options.subdomains = r.imageUrlSubdomains;
|
||||
this._url = r.imageUrl;
|
||||
this._providers = [];
|
||||
if (r.imageryProviders) {
|
||||
for (var i = 0; i < r.imageryProviders.length; i++) {
|
||||
var p = r.imageryProviders[i];
|
||||
for (var j = 0; j < p.coverageAreas.length; j++) {
|
||||
var c = p.coverageAreas[j];
|
||||
var coverage = {zoomMin: c.zoomMin, zoomMax: c.zoomMax, active: false};
|
||||
var bounds = new L.LatLngBounds(
|
||||
new L.LatLng(c.bbox[0]+0.01, c.bbox[1]+0.01),
|
||||
new L.LatLng(c.bbox[2]-0.01, c.bbox[3]-0.01)
|
||||
);
|
||||
coverage.bounds = bounds;
|
||||
coverage.attrib = p.attribution;
|
||||
this._providers.push(coverage);
|
||||
}
|
||||
}
|
||||
}
|
||||
this._update();
|
||||
},
|
||||
|
||||
_update: function() {
|
||||
if (this._url == null || !this._map) return;
|
||||
this._update_attribution();
|
||||
L.TileLayer.prototype._update.apply(this, []);
|
||||
},
|
||||
|
||||
_update_attribution: function() {
|
||||
var bounds = this._map.getBounds();
|
||||
var zoom = this._map.getZoom();
|
||||
for (var i = 0; i < this._providers.length; i++) {
|
||||
var p = this._providers[i];
|
||||
if ((zoom <= p.zoomMax && zoom >= p.zoomMin) &&
|
||||
bounds.intersects(p.bounds)) {
|
||||
if (!p.active && this._map.attributionControl)
|
||||
this._map.attributionControl.addAttribution(p.attrib);
|
||||
p.active = true;
|
||||
} else {
|
||||
if (p.active && this._map.attributionControl)
|
||||
this._map.attributionControl.removeAttribution(p.attrib);
|
||||
p.active = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onRemove: function(map) {
|
||||
for (var i = 0; i < this._providers.length; i++) {
|
||||
var p = this._providers[i];
|
||||
if (p.active && this._map.attributionControl) {
|
||||
this._map.attributionControl.removeAttribution(p.attrib);
|
||||
p.active = false;
|
||||
}
|
||||
}
|
||||
L.TileLayer.prototype.onRemove.apply(this, [map]);
|
||||
}
|
||||
});
|
||||
|
||||
L.bingLayer = function (key, options) {
|
||||
return new L.BingLayer(key, options);
|
||||
};
|
||||
202
bower_components/leaflet-plugins/layer/tile/Google.js
vendored
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Google layer using Google Maps API
|
||||
*/
|
||||
//(function (google, L) {
|
||||
|
||||
L.Google = L.Class.extend({
|
||||
includes: L.Mixin.Events,
|
||||
|
||||
options: {
|
||||
minZoom: 0,
|
||||
maxZoom: 18,
|
||||
tileSize: 256,
|
||||
subdomains: 'abc',
|
||||
errorTileUrl: '',
|
||||
attribution: '',
|
||||
opacity: 1,
|
||||
continuousWorld: false,
|
||||
noWrap: false,
|
||||
mapOptions: {
|
||||
backgroundColor: '#dddddd'
|
||||
}
|
||||
},
|
||||
|
||||
// Possible types: SATELLITE, ROADMAP, HYBRID, TERRAIN
|
||||
initialize: function(type, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
this._ready = google.maps.Map != undefined;
|
||||
if (!this._ready) L.Google.asyncWait.push(this);
|
||||
|
||||
this._type = type || 'SATELLITE';
|
||||
},
|
||||
|
||||
onAdd: function(map, insertAtTheBottom) {
|
||||
this._map = map;
|
||||
this._insertAtTheBottom = insertAtTheBottom;
|
||||
|
||||
// create a container div for tiles
|
||||
this._initContainer();
|
||||
this._initMapObject();
|
||||
|
||||
// set up events
|
||||
map.on('viewreset', this._resetCallback, this);
|
||||
|
||||
this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this);
|
||||
map.on('move', this._update, this);
|
||||
|
||||
map.on('zoomanim', this._handleZoomAnim, this);
|
||||
|
||||
//20px instead of 1em to avoid a slight overlap with google's attribution
|
||||
map._controlCorners['bottomright'].style.marginBottom = "20px";
|
||||
|
||||
this._reset();
|
||||
this._update();
|
||||
},
|
||||
|
||||
onRemove: function(map) {
|
||||
this._map._container.removeChild(this._container);
|
||||
//this._container = null;
|
||||
|
||||
this._map.off('viewreset', this._resetCallback, this);
|
||||
|
||||
this._map.off('move', this._update, this);
|
||||
|
||||
this._map.off('zoomanim', this._handleZoomAnim, this);
|
||||
|
||||
map._controlCorners['bottomright'].style.marginBottom = "0em";
|
||||
//this._map.off('moveend', this._update, this);
|
||||
},
|
||||
|
||||
getAttribution: function() {
|
||||
return this.options.attribution;
|
||||
},
|
||||
|
||||
setOpacity: function(opacity) {
|
||||
this.options.opacity = opacity;
|
||||
if (opacity < 1) {
|
||||
L.DomUtil.setOpacity(this._container, opacity);
|
||||
}
|
||||
},
|
||||
|
||||
setElementSize: function(e, size) {
|
||||
e.style.width = size.x + "px";
|
||||
e.style.height = size.y + "px";
|
||||
},
|
||||
|
||||
_initContainer: function() {
|
||||
var tilePane = this._map._container,
|
||||
first = tilePane.firstChild;
|
||||
|
||||
if (!this._container) {
|
||||
this._container = L.DomUtil.create('div', 'leaflet-google-layer leaflet-top leaflet-left');
|
||||
this._container.id = "_GMapContainer_" + L.Util.stamp(this);
|
||||
this._container.style.zIndex = "auto";
|
||||
}
|
||||
|
||||
if (true) {
|
||||
tilePane.insertBefore(this._container, first);
|
||||
|
||||
this.setOpacity(this.options.opacity);
|
||||
this.setElementSize(this._container, this._map.getSize());
|
||||
}
|
||||
},
|
||||
|
||||
_initMapObject: function() {
|
||||
if (!this._ready) return;
|
||||
this._google_center = new google.maps.LatLng(0, 0);
|
||||
var map = new google.maps.Map(this._container, {
|
||||
center: this._google_center,
|
||||
zoom: 0,
|
||||
tilt: 0,
|
||||
mapTypeId: google.maps.MapTypeId[this._type],
|
||||
disableDefaultUI: true,
|
||||
keyboardShortcuts: false,
|
||||
draggable: false,
|
||||
disableDoubleClickZoom: true,
|
||||
scrollwheel: false,
|
||||
streetViewControl: false,
|
||||
styles: this.options.mapOptions.styles,
|
||||
backgroundColor: this.options.mapOptions.backgroundColor
|
||||
});
|
||||
|
||||
var _this = this;
|
||||
this._reposition = google.maps.event.addListenerOnce(map, "center_changed",
|
||||
function() { _this.onReposition(); });
|
||||
this._google = map;
|
||||
|
||||
google.maps.event.addListenerOnce(map, "idle",
|
||||
function() { _this._checkZoomLevels(); });
|
||||
},
|
||||
|
||||
_checkZoomLevels: function() {
|
||||
//setting the zoom level on the Google map may result in a different zoom level than the one requested
|
||||
//(it won't go beyond the level for which they have data).
|
||||
// verify and make sure the zoom levels on both Leaflet and Google maps are consistent
|
||||
if (this._google.getZoom() !== this._map.getZoom()) {
|
||||
//zoom levels are out of sync. Set the leaflet zoom level to match the google one
|
||||
this._map.setZoom( this._google.getZoom() );
|
||||
}
|
||||
},
|
||||
|
||||
_resetCallback: function(e) {
|
||||
this._reset(e.hard);
|
||||
},
|
||||
|
||||
_reset: function(clearOldContainer) {
|
||||
this._initContainer();
|
||||
},
|
||||
|
||||
_update: function(e) {
|
||||
if (!this._google) return;
|
||||
this._resize();
|
||||
|
||||
var center = e && e.latlng ? e.latlng : this._map.getCenter();
|
||||
var _center = new google.maps.LatLng(center.lat, center.lng);
|
||||
|
||||
this._google.setCenter(_center);
|
||||
this._google.setZoom(this._map.getZoom());
|
||||
|
||||
this._checkZoomLevels();
|
||||
//this._google.fitBounds(google_bounds);
|
||||
},
|
||||
|
||||
_resize: function() {
|
||||
var size = this._map.getSize();
|
||||
if (this._container.style.width == size.x &&
|
||||
this._container.style.height == size.y)
|
||||
return;
|
||||
this.setElementSize(this._container, size);
|
||||
this.onReposition();
|
||||
},
|
||||
|
||||
|
||||
_handleZoomAnim: function (e) {
|
||||
var center = e.center;
|
||||
var _center = new google.maps.LatLng(center.lat, center.lng);
|
||||
|
||||
this._google.setCenter(_center);
|
||||
this._google.setZoom(e.zoom);
|
||||
},
|
||||
|
||||
|
||||
onReposition: function() {
|
||||
if (!this._google) return;
|
||||
google.maps.event.trigger(this._google, "resize");
|
||||
}
|
||||
});
|
||||
|
||||
L.Google.asyncWait = [];
|
||||
L.Google.asyncInitialize = function() {
|
||||
var i;
|
||||
for (i = 0; i < L.Google.asyncWait.length; i++) {
|
||||
var o = L.Google.asyncWait[i];
|
||||
o._ready = true;
|
||||
if (o._container) {
|
||||
o._initMapObject();
|
||||
o._update();
|
||||
}
|
||||
}
|
||||
L.Google.asyncWait = [];
|
||||
};
|
||||
//})(window.google, L)
|
||||
161
bower_components/leaflet-plugins/layer/tile/Yandex.js
vendored
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* L.TileLayer is used for standard xyz-numbered tile layers.
|
||||
*/
|
||||
//(function (ymaps, L) {
|
||||
|
||||
L.Yandex = L.Class.extend({
|
||||
includes: L.Mixin.Events,
|
||||
|
||||
options: {
|
||||
minZoom: 0,
|
||||
maxZoom: 18,
|
||||
attribution: '',
|
||||
opacity: 1,
|
||||
traffic: false
|
||||
},
|
||||
|
||||
// Possible types: map, satellite, hybrid, publicMap, publicMapHybrid
|
||||
initialize: function(type, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
this._type = "yandex#" + (type || 'map');
|
||||
},
|
||||
|
||||
onAdd: function(map, insertAtTheBottom) {
|
||||
this._map = map;
|
||||
this._insertAtTheBottom = insertAtTheBottom;
|
||||
|
||||
// create a container div for tiles
|
||||
this._initContainer();
|
||||
this._initMapObject();
|
||||
|
||||
// set up events
|
||||
map.on('viewreset', this._resetCallback, this);
|
||||
|
||||
this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this);
|
||||
map.on('move', this._update, this);
|
||||
|
||||
map._controlCorners['bottomright'].style.marginBottom = "3em";
|
||||
|
||||
this._reset();
|
||||
this._update(true);
|
||||
},
|
||||
|
||||
onRemove: function(map) {
|
||||
this._map._container.removeChild(this._container);
|
||||
|
||||
this._map.off('viewreset', this._resetCallback, this);
|
||||
|
||||
this._map.off('move', this._update, this);
|
||||
|
||||
map._controlCorners['bottomright'].style.marginBottom = "0em";
|
||||
},
|
||||
|
||||
getAttribution: function() {
|
||||
return this.options.attribution;
|
||||
},
|
||||
|
||||
setOpacity: function(opacity) {
|
||||
this.options.opacity = opacity;
|
||||
if (opacity < 1) {
|
||||
L.DomUtil.setOpacity(this._container, opacity);
|
||||
}
|
||||
},
|
||||
|
||||
setElementSize: function(e, size) {
|
||||
e.style.width = size.x + "px";
|
||||
e.style.height = size.y + "px";
|
||||
},
|
||||
|
||||
_initContainer: function() {
|
||||
var tilePane = this._map._container,
|
||||
first = tilePane.firstChild;
|
||||
|
||||
if (!this._container) {
|
||||
this._container = L.DomUtil.create('div', 'leaflet-yandex-layer leaflet-top leaflet-left');
|
||||
this._container.id = "_YMapContainer_" + L.Util.stamp(this);
|
||||
this._container.style.zIndex = "auto";
|
||||
}
|
||||
|
||||
if (this.options.overlay) {
|
||||
first = this._map._container.getElementsByClassName('leaflet-map-pane')[0];
|
||||
first = first.nextSibling;
|
||||
// XXX: Bug with layer order
|
||||
if (L.Browser.opera)
|
||||
this._container.className += " leaflet-objects-pane";
|
||||
}
|
||||
tilePane.insertBefore(this._container, first);
|
||||
|
||||
this.setOpacity(this.options.opacity);
|
||||
this.setElementSize(this._container, this._map.getSize());
|
||||
},
|
||||
|
||||
_initMapObject: function() {
|
||||
if (this._yandex) return;
|
||||
|
||||
// Check that ymaps.Map is ready
|
||||
if (ymaps.Map === undefined) {
|
||||
if (console) {
|
||||
console.debug("L.Yandex: Waiting on ymaps.load('package.map')");
|
||||
}
|
||||
return ymaps.load(["package.map"], this._initMapObject, this);
|
||||
}
|
||||
|
||||
// If traffic layer is requested check if control.TrafficControl is ready
|
||||
if (this.options.traffic)
|
||||
if (ymaps.control === undefined ||
|
||||
ymaps.control.TrafficControl === undefined) {
|
||||
if (console) {
|
||||
console.debug("L.Yandex: loading traffic and controls");
|
||||
}
|
||||
return ymaps.load(["package.traffic", "package.controls"],
|
||||
this._initMapObject, this);
|
||||
}
|
||||
|
||||
var map = new ymaps.Map(this._container, {center: [0,0], zoom: 0, behaviors: []});
|
||||
|
||||
if (this.options.traffic)
|
||||
map.controls.add(new ymaps.control.TrafficControl({shown: true}));
|
||||
|
||||
if (this._type == "yandex#null") {
|
||||
this._type = new ymaps.MapType("null", []);
|
||||
map.container.getElement().style.background = "transparent";
|
||||
}
|
||||
map.setType(this._type);
|
||||
|
||||
this._yandex = map;
|
||||
this._update(true);
|
||||
},
|
||||
|
||||
_resetCallback: function(e) {
|
||||
this._reset(e.hard);
|
||||
},
|
||||
|
||||
_reset: function(clearOldContainer) {
|
||||
this._initContainer();
|
||||
},
|
||||
|
||||
_update: function(force) {
|
||||
if (!this._yandex) return;
|
||||
this._resize(force);
|
||||
|
||||
var center = this._map.getCenter();
|
||||
var _center = [center.lat, center.lng];
|
||||
var zoom = this._map.getZoom();
|
||||
|
||||
if (force || this._yandex.getZoom() != zoom)
|
||||
this._yandex.setZoom(zoom);
|
||||
this._yandex.panTo(_center, {duration: 0, delay: 0});
|
||||
},
|
||||
|
||||
_resize: function(force) {
|
||||
var size = this._map.getSize(), style = this._container.style;
|
||||
if (style.width == size.x + "px" &&
|
||||
style.height == size.y + "px")
|
||||
if (force != true) return;
|
||||
this.setElementSize(this._container, size);
|
||||
var b = this._map.getBounds(), sw = b.getSouthWest(), ne = b.getNorthEast();
|
||||
this._yandex.container.fitToViewport();
|
||||
}
|
||||
});
|
||||
//})(ymaps, L)
|
||||
80
bower_components/leaflet-plugins/layer/vector/GPX.Speed.js
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
//#include "GPX.js"
|
||||
|
||||
(function() {
|
||||
|
||||
function d2h(d) {
|
||||
var hex = '0123456789ABCDEF';
|
||||
var r = '';
|
||||
d = Math.floor(d);
|
||||
while (d != 0) {
|
||||
r = hex[d % 16] + r;
|
||||
d = Math.floor(d / 16);
|
||||
}
|
||||
while (r.length < 2) r = '0' + r;
|
||||
return r;
|
||||
}
|
||||
|
||||
function gradient(color) {
|
||||
// First arc (0, PI) in HSV colorspace
|
||||
function f2h(d) { return d2h(256 * d); }
|
||||
if (color < 0)
|
||||
return "#FF0000";
|
||||
else if (color < 1.0/3)
|
||||
return "#FF" + f2h(3 * color) + "00";
|
||||
else if (color < 2.0/3)
|
||||
return "#" + f2h(2 - 3 * color) + "FF00";
|
||||
else if (color < 1)
|
||||
return "#00FF" + f2h(3 * color - 2);
|
||||
else
|
||||
return "#00FFFF";
|
||||
};
|
||||
|
||||
function gpx2time(s) {
|
||||
// 2011-09-24T12:07:53Z
|
||||
if (s.length != 10 + 1 + 8 + 1)
|
||||
return new Date();
|
||||
return new Date(s);
|
||||
};
|
||||
|
||||
L.GPX.include({
|
||||
options: {
|
||||
maxSpeed: 110,
|
||||
chunks: 200
|
||||
},
|
||||
|
||||
speedSplitEnable: function(options) {
|
||||
L.Util.setOptions(this, options);
|
||||
return this.on('addline', this.speed_split, this);
|
||||
},
|
||||
|
||||
speedSplitDisable: function() {
|
||||
return this.off('addline', this.speed_split, this);
|
||||
},
|
||||
|
||||
speed_split: function(e) {
|
||||
var l = e.line.pop(), ll = l.getLatLngs();
|
||||
var chunk = Math.floor(ll.length / this.options.chunks);
|
||||
if (chunk < 3) chunk = 3;
|
||||
var p = null;
|
||||
for (var i = 0; i < ll.length; i += chunk) {
|
||||
var d = 0, t = null;
|
||||
if (i + chunk > ll.length)
|
||||
chunk = ll.length - i;
|
||||
for (var j = 0; j < chunk; j++) {
|
||||
if (p) d += p.distanceTo(ll[i+j]);
|
||||
p = ll[i + j];
|
||||
if (!t) t = gpx2time(p.meta.time);
|
||||
}
|
||||
p = ll[i + chunk - 1];
|
||||
t = (gpx2time(p.meta.time) - t) / (3600 * 1000);
|
||||
var speed = 0.001 * d / t;
|
||||
//console.info('Dist: ' + d + "; Speed: " + speed);
|
||||
var color = gradient(speed / this.options.maxSpeed);
|
||||
var l = new L.Polyline(ll.slice(i, i+chunk+1), {color: color, weight: 2, opacity: 1});
|
||||
l.bindPopup('Dist: ' + d.toFixed() + "m; Speed: " + speed.toFixed(2) + " km/h");
|
||||
e.line.push(l);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
})();
|
||||
143
bower_components/leaflet-plugins/layer/vector/GPX.js
vendored
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/*global L: true */
|
||||
|
||||
L.GPX = L.FeatureGroup.extend({
|
||||
initialize: function(gpx, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
this._gpx = gpx;
|
||||
this._layers = {};
|
||||
|
||||
if (gpx) {
|
||||
this.addGPX(gpx, options, this.options.async);
|
||||
}
|
||||
},
|
||||
|
||||
loadXML: function(url, cb, options, async) {
|
||||
if (async == undefined) async = this.options.async;
|
||||
if (options == undefined) options = this.options;
|
||||
|
||||
var req = new window.XMLHttpRequest();
|
||||
req.open('GET', url, async);
|
||||
try {
|
||||
req.overrideMimeType('text/xml'); // unsupported by IE
|
||||
} catch(e) {}
|
||||
req.onreadystatechange = function() {
|
||||
if (req.readyState != 4) return;
|
||||
if(req.status == 200) cb(req.responseXML, options);
|
||||
};
|
||||
req.send(null);
|
||||
},
|
||||
|
||||
_humanLen: function(l) {
|
||||
if (l < 2000)
|
||||
return l.toFixed(0) + " m";
|
||||
else
|
||||
return (l/1000).toFixed(1) + " km";
|
||||
},
|
||||
|
||||
_polylineLen: function(line)//line is a L.Polyline()
|
||||
{
|
||||
var ll = line._latlngs;
|
||||
var d = 0, p = null;
|
||||
for (var i = 0; i < ll.length; i++)
|
||||
{
|
||||
if(i && p)
|
||||
d += p.distanceTo(ll[i]);
|
||||
p = ll[i];
|
||||
}
|
||||
return d;
|
||||
},
|
||||
|
||||
addGPX: function(url, options, async) {
|
||||
var _this = this;
|
||||
var cb = function(gpx, options) { _this._addGPX(gpx, options) };
|
||||
this.loadXML(url, cb, options, async);
|
||||
},
|
||||
|
||||
_addGPX: function(gpx, options) {
|
||||
var layers = this.parseGPX(gpx, options);
|
||||
if (!layers) return;
|
||||
this.addLayer(layers);
|
||||
this.fire("loaded");
|
||||
},
|
||||
|
||||
parseGPX: function(xml, options) {
|
||||
var j, i, el, layers = [];
|
||||
var named = false, tags = [['rte','rtept'], ['trkseg','trkpt']];
|
||||
|
||||
for (j = 0; j < tags.length; j++) {
|
||||
el = xml.getElementsByTagName(tags[j][0]);
|
||||
for (i = 0; i < el.length; i++) {
|
||||
var l = this.parse_trkseg(el[i], xml, options, tags[j][1]);
|
||||
for (var k = 0; k < l.length; k++) {
|
||||
if (this.parse_name(el[i], l[k])) named = true;
|
||||
layers.push(l[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
el = xml.getElementsByTagName('wpt');
|
||||
if (options.display_wpt != false) {
|
||||
for (i = 0; i < el.length; i++) {
|
||||
var l = this.parse_wpt(el[i], xml, options);
|
||||
if (!l) continue;
|
||||
if (this.parse_name(el[i], l)) named = true;
|
||||
layers.push(l);
|
||||
}
|
||||
}
|
||||
|
||||
if (!layers.length) return;
|
||||
var layer = layers[0];
|
||||
if (layers.length > 1)
|
||||
layer = new L.FeatureGroup(layers);
|
||||
if (!named) this.parse_name(xml, layer);
|
||||
return layer;
|
||||
},
|
||||
|
||||
parse_name: function(xml, layer) {
|
||||
var i, el, txt="", name, descr="", len=0;
|
||||
el = xml.getElementsByTagName('name');
|
||||
if (el.length)
|
||||
name = el[0].childNodes[0].nodeValue;
|
||||
el = xml.getElementsByTagName('desc');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
for (var j = 0; j < el[i].childNodes.length; j++)
|
||||
descr = descr + el[i].childNodes[j].nodeValue;
|
||||
}
|
||||
|
||||
if(layer instanceof L.Path)
|
||||
len = this._polylineLen(layer);
|
||||
|
||||
if (name) txt += "<h2>" + name + "</h2>" + descr;
|
||||
if (len) txt += "<p>" + this._humanLen(len) + "</p>";
|
||||
|
||||
if (layer && layer._popup === undefined) layer.bindPopup(txt);
|
||||
return txt;
|
||||
},
|
||||
|
||||
parse_trkseg: function(line, xml, options, tag) {
|
||||
var el = line.getElementsByTagName(tag);
|
||||
if (!el.length) return [];
|
||||
var coords = [];
|
||||
for (var i = 0; i < el.length; i++) {
|
||||
var ll = new L.LatLng(el[i].getAttribute('lat'),
|
||||
el[i].getAttribute('lon'));
|
||||
ll.meta = {};
|
||||
for (var j in el[i].childNodes) {
|
||||
var e = el[i].childNodes[j];
|
||||
if (!e.tagName) continue;
|
||||
ll.meta[e.tagName] = e.textContent;
|
||||
}
|
||||
coords.push(ll);
|
||||
}
|
||||
var l = [new L.Polyline(coords, options)];
|
||||
this.fire('addline', {line:l})
|
||||
return l;
|
||||
},
|
||||
|
||||
parse_wpt: function(e, xml, options) {
|
||||
var m = new L.Marker(new L.LatLng(e.getAttribute('lat'),
|
||||
e.getAttribute('lon')), options);
|
||||
this.fire('addpoint', {point:m});
|
||||
return m;
|
||||
}
|
||||
});
|
||||
359
bower_components/leaflet-plugins/layer/vector/KML.js
vendored
Normal file
|
|
@ -0,0 +1,359 @@
|
|||
/*global L: true */
|
||||
|
||||
L.KML = L.FeatureGroup.extend({
|
||||
options: {
|
||||
async: true
|
||||
},
|
||||
|
||||
initialize: function(kml, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
this._kml = kml;
|
||||
this._layers = {};
|
||||
|
||||
if (kml) {
|
||||
this.addKML(kml, options, this.options.async);
|
||||
}
|
||||
},
|
||||
|
||||
loadXML: function(url, cb, options, async) {
|
||||
if (async == undefined) async = this.options.async;
|
||||
if (options == undefined) options = this.options;
|
||||
|
||||
var req = new window.XMLHttpRequest();
|
||||
req.open('GET', url, async);
|
||||
try {
|
||||
req.overrideMimeType('text/xml'); // unsupported by IE
|
||||
} catch(e) {}
|
||||
req.onreadystatechange = function() {
|
||||
if (req.readyState != 4) return;
|
||||
if(req.status == 200) cb(req.responseXML, options);
|
||||
};
|
||||
req.send(null);
|
||||
},
|
||||
|
||||
addKML: function(url, options, async) {
|
||||
var _this = this;
|
||||
var cb = function(gpx, options) { _this._addKML(gpx, options) };
|
||||
this.loadXML(url, cb, options, async);
|
||||
},
|
||||
|
||||
_addKML: function(xml, options) {
|
||||
var layers = L.KML.parseKML(xml);
|
||||
if (!layers || !layers.length) return;
|
||||
for (var i = 0; i < layers.length; i++)
|
||||
{
|
||||
this.fire('addlayer', {
|
||||
layer: layers[i]
|
||||
});
|
||||
this.addLayer(layers[i]);
|
||||
}
|
||||
this.latLngs = L.KML.getLatLngs(xml);
|
||||
this.fire("loaded");
|
||||
},
|
||||
|
||||
latLngs: []
|
||||
});
|
||||
|
||||
L.Util.extend(L.KML, {
|
||||
|
||||
parseKML: function (xml) {
|
||||
var style = this.parseStyle(xml);
|
||||
this.parseStyleMap(xml, style);
|
||||
var el = xml.getElementsByTagName("Folder");
|
||||
var layers = [], l;
|
||||
for (var i = 0; i < el.length; i++) {
|
||||
if (!this._check_folder(el[i])) { continue; }
|
||||
l = this.parseFolder(el[i], style);
|
||||
if (l) { layers.push(l); }
|
||||
}
|
||||
el = xml.getElementsByTagName('Placemark');
|
||||
for (var j = 0; j < el.length; j++) {
|
||||
if (!this._check_folder(el[j])) { continue; }
|
||||
l = this.parsePlacemark(el[j], xml, style);
|
||||
if (l) { layers.push(l); }
|
||||
}
|
||||
return layers;
|
||||
},
|
||||
|
||||
// Return false if e's first parent Folder is not [folder]
|
||||
// - returns true if no parent Folders
|
||||
_check_folder: function (e, folder) {
|
||||
e = e.parentElement;
|
||||
while (e && e.tagName !== "Folder")
|
||||
{
|
||||
e = e.parentElement;
|
||||
}
|
||||
return !e || e === folder;
|
||||
},
|
||||
|
||||
parseStyle: function (xml) {
|
||||
var style = {};
|
||||
var sl = xml.getElementsByTagName("Style");
|
||||
|
||||
//for (var i = 0; i < sl.length; i++) {
|
||||
var attributes = {color: true, width: true, Icon: true, href: true,
|
||||
hotSpot: true};
|
||||
|
||||
function _parse(xml) {
|
||||
var options = {};
|
||||
for (var i = 0; i < xml.childNodes.length; i++) {
|
||||
var e = xml.childNodes[i];
|
||||
var key = e.tagName;
|
||||
if (!attributes[key]) { continue; }
|
||||
if (key === 'hotSpot')
|
||||
{
|
||||
for (var j = 0; j < e.attributes.length; j++) {
|
||||
options[e.attributes[j].name] = e.attributes[j].nodeValue;
|
||||
}
|
||||
} else {
|
||||
var value = e.childNodes[0].nodeValue;
|
||||
if (key === 'color') {
|
||||
options.opacity = parseInt(value.substring(0, 2), 16) / 255.0;
|
||||
options.color = "#" + value.substring(6, 8) + value.substring(4, 6) + value.substring(2, 4);
|
||||
} else if (key === 'width') {
|
||||
options.weight = value;
|
||||
} else if (key === 'Icon') {
|
||||
ioptions = _parse(e);
|
||||
if (ioptions.href) { options.href = ioptions.href; }
|
||||
} else if (key === 'href') {
|
||||
options.href = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
for (var i = 0; i < sl.length; i++) {
|
||||
var e = sl[i], el;
|
||||
var options = {}, poptions = {}, ioptions = {};
|
||||
el = e.getElementsByTagName("LineStyle");
|
||||
if (el && el[0]) { options = _parse(el[0]); }
|
||||
el = e.getElementsByTagName("PolyStyle");
|
||||
if (el && el[0]) { poptions = _parse(el[0]); }
|
||||
if (poptions.color) { options.fillColor = poptions.color; }
|
||||
if (poptions.opacity) { options.fillOpacity = poptions.opacity; }
|
||||
el = e.getElementsByTagName("IconStyle");
|
||||
if (el && el[0]) { ioptions = _parse(el[0]); }
|
||||
if (ioptions.href) {
|
||||
// save anchor info until the image is loaded
|
||||
options.icon = new L.KMLIcon({
|
||||
iconUrl: ioptions.href,
|
||||
shadowUrl: null,
|
||||
iconAnchorRef: {x: ioptions.x, y: ioptions.y},
|
||||
iconAnchorType: {x: ioptions.xunits, y: ioptions.yunits}
|
||||
});
|
||||
}
|
||||
style['#' + e.getAttribute('id')] = options;
|
||||
}
|
||||
return style;
|
||||
},
|
||||
|
||||
parseStyleMap: function (xml, existingStyles) {
|
||||
var sl = xml.getElementsByTagName("StyleMap");
|
||||
|
||||
for (var i = 0; i < sl.length; i++) {
|
||||
var e = sl[i], el;
|
||||
var smKey, smStyleUrl;
|
||||
|
||||
el = e.getElementsByTagName("key");
|
||||
if (el && el[0]) { smKey = el[0].textContent; }
|
||||
el = e.getElementsByTagName("styleUrl");
|
||||
if (el && el[0]) { smStyleUrl = el[0].textContent; }
|
||||
|
||||
if (smKey=='normal')
|
||||
{
|
||||
existingStyles['#' + e.getAttribute('id')] = existingStyles[smStyleUrl];
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
},
|
||||
|
||||
parseFolder: function (xml, style) {
|
||||
var el, layers = [], l;
|
||||
el = xml.getElementsByTagName('Folder');
|
||||
for (var i = 0; i < el.length; i++) {
|
||||
if (!this._check_folder(el[i], xml)) { continue; }
|
||||
l = this.parseFolder(el[i], style);
|
||||
if (l) { layers.push(l); }
|
||||
}
|
||||
el = xml.getElementsByTagName('Placemark');
|
||||
for (var j = 0; j < el.length; j++) {
|
||||
if (!this._check_folder(el[j], xml)) { continue; }
|
||||
l = this.parsePlacemark(el[j], xml, style);
|
||||
if (l) { layers.push(l); }
|
||||
}
|
||||
if (!layers.length) { return; }
|
||||
if (layers.length === 1) { return layers[0]; }
|
||||
return new L.FeatureGroup(layers);
|
||||
},
|
||||
|
||||
parsePlacemark: function (place, xml, style) {
|
||||
var i, j, el, options = {};
|
||||
el = place.getElementsByTagName('styleUrl');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
var url = el[i].childNodes[0].nodeValue;
|
||||
for (var a in style[url])
|
||||
{
|
||||
// for jshint
|
||||
if (true)
|
||||
{
|
||||
options[a] = style[url][a];
|
||||
}
|
||||
}
|
||||
}
|
||||
var layers = [];
|
||||
|
||||
var parse = ['LineString', 'Polygon', 'Point'];
|
||||
for (j in parse) {
|
||||
// for jshint
|
||||
if (true)
|
||||
{
|
||||
var tag = parse[j];
|
||||
el = place.getElementsByTagName(tag);
|
||||
for (i = 0; i < el.length; i++) {
|
||||
var l = this["parse" + tag](el[i], xml, options);
|
||||
if (l) { layers.push(l); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!layers.length) {
|
||||
return;
|
||||
}
|
||||
var layer = layers[0];
|
||||
if (layers.length > 1) {
|
||||
layer = new L.FeatureGroup(layers);
|
||||
}
|
||||
|
||||
var name, descr = "";
|
||||
el = place.getElementsByTagName('name');
|
||||
if (el.length && el[0].childNodes.length) {
|
||||
name = el[0].childNodes[0].nodeValue;
|
||||
}
|
||||
el = place.getElementsByTagName('description');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
for (j = 0; j < el[i].childNodes.length; j++) {
|
||||
descr = descr + el[i].childNodes[j].nodeValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (name) {
|
||||
layer.bindPopup("<h2>" + name + "</h2>" + descr);
|
||||
}
|
||||
|
||||
return layer;
|
||||
},
|
||||
|
||||
parseCoords: function (xml) {
|
||||
var el = xml.getElementsByTagName('coordinates');
|
||||
return this._read_coords(el[0]);
|
||||
},
|
||||
|
||||
parseLineString: function (line, xml, options) {
|
||||
var coords = this.parseCoords(line);
|
||||
if (!coords.length) { return; }
|
||||
return new L.Polyline(coords, options);
|
||||
},
|
||||
|
||||
parsePoint: function (line, xml, options) {
|
||||
var el = line.getElementsByTagName('coordinates');
|
||||
if (!el.length) {
|
||||
return;
|
||||
}
|
||||
var ll = el[0].childNodes[0].nodeValue.split(',');
|
||||
return new L.KMLMarker(new L.LatLng(ll[1], ll[0]), options);
|
||||
},
|
||||
|
||||
parsePolygon: function (line, xml, options) {
|
||||
var el, polys = [], inner = [], i, coords;
|
||||
el = line.getElementsByTagName('outerBoundaryIs');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
coords = this.parseCoords(el[i]);
|
||||
if (coords) {
|
||||
polys.push(coords);
|
||||
}
|
||||
}
|
||||
el = line.getElementsByTagName('innerBoundaryIs');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
coords = this.parseCoords(el[i]);
|
||||
if (coords) {
|
||||
inner.push(coords);
|
||||
}
|
||||
}
|
||||
if (!polys.length) {
|
||||
return;
|
||||
}
|
||||
if (options.fillColor) {
|
||||
options.fill = true;
|
||||
}
|
||||
if (polys.length === 1) {
|
||||
return new L.Polygon(polys.concat(inner), options);
|
||||
}
|
||||
return new L.MultiPolygon(polys, options);
|
||||
},
|
||||
|
||||
getLatLngs: function (xml) {
|
||||
var el = xml.getElementsByTagName('coordinates');
|
||||
var coords = [];
|
||||
for (var j = 0; j < el.length; j++) {
|
||||
// text might span many childNodes
|
||||
coords = coords.concat(this._read_coords(el[j]));
|
||||
}
|
||||
return coords;
|
||||
},
|
||||
|
||||
_read_coords: function (el) {
|
||||
var text = "", coords = [], i;
|
||||
for (i = 0; i < el.childNodes.length; i++) {
|
||||
text = text + el.childNodes[i].nodeValue;
|
||||
}
|
||||
text = text.split(/[\s\n]+/);
|
||||
for (i = 0; i < text.length; i++) {
|
||||
var ll = text[i].split(',');
|
||||
if (ll.length < 2) {
|
||||
continue;
|
||||
}
|
||||
coords.push(new L.LatLng(ll[1], ll[0]));
|
||||
}
|
||||
return coords;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
L.KMLIcon = L.Icon.extend({
|
||||
|
||||
createIcon: function () {
|
||||
var img = this._createIcon('icon');
|
||||
img.onload = function () {
|
||||
var i = new Image();
|
||||
i.src = this.src;
|
||||
this.style.width = i.width + 'px';
|
||||
this.style.height = i.height + 'px';
|
||||
|
||||
if (this.anchorType.x === 'UNITS_FRACTION' || this.anchorType.x === 'fraction') {
|
||||
img.style.marginLeft = (-this.anchor.x * i.width) + 'px';
|
||||
}
|
||||
if (this.anchorType.y === 'UNITS_FRACTION' || this.anchorType.x === 'fraction') {
|
||||
img.style.marginTop = (-(1 - this.anchor.y) * i.height) + 'px';
|
||||
}
|
||||
this.style.display = "";
|
||||
};
|
||||
return img;
|
||||
},
|
||||
|
||||
_setIconStyles: function (img, name) {
|
||||
L.Icon.prototype._setIconStyles.apply(this, [img, name])
|
||||
// save anchor information to the image
|
||||
img.anchor = this.options.iconAnchorRef;
|
||||
img.anchorType = this.options.iconAnchorType;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
L.KMLMarker = L.Marker.extend({
|
||||
options: {
|
||||
icon: new L.KMLIcon.Default()
|
||||
}
|
||||
});
|
||||
|
||||
172
bower_components/leaflet-plugins/layer/vector/OSM.js
vendored
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/*global L: true */
|
||||
|
||||
L.OSM = L.FeatureGroup.extend({
|
||||
options: {
|
||||
async: true,
|
||||
forceAll: false
|
||||
},
|
||||
|
||||
initialize: function(url, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
this._url = url;
|
||||
this._layers = {};
|
||||
|
||||
if (url) {
|
||||
this.addXML(url, options, this.options.async);
|
||||
}
|
||||
},
|
||||
|
||||
loadXML: function(url, cb, options, async) {
|
||||
if (async == undefined) async = this.options.async;
|
||||
if (options == undefined) options = this.options;
|
||||
|
||||
var req = new window.XMLHttpRequest();
|
||||
req.open('GET', url, async);
|
||||
req.overrideMimeType('text/xml');
|
||||
req.onreadystatechange = function() {
|
||||
if (req.readyState != 4) return;
|
||||
if(req.status == 200) cb(req.responseXML, options);
|
||||
};
|
||||
req.send(null);
|
||||
},
|
||||
|
||||
addXML: function(url, options, async) {
|
||||
var _this = this;
|
||||
var cb = function(xml, options) { _this._addXML(xml, options) };
|
||||
this.loadXML(url, cb, options, async);
|
||||
},
|
||||
|
||||
_addXML: function(xml, options) {
|
||||
var layers = this.parseOSM(xml, options);
|
||||
if (!layers) return;
|
||||
this.addLayer(layers);
|
||||
this.fire("loaded");
|
||||
},
|
||||
|
||||
parseOSM: function(xml, options) {
|
||||
var i, el, ll, layers = [];
|
||||
var nodes = {};
|
||||
var ways = {};
|
||||
var named = false;
|
||||
|
||||
el = xml.getElementsByTagName('node');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
var l = this.parse_node(el[i], xml, options);
|
||||
if (l == undefined) continue;
|
||||
nodes[l.osmid] = l;
|
||||
if (!this.options.forceAll && !l.tags.length) continue;
|
||||
var m = this.named_node(l, options);
|
||||
if (!ll) ll = m.getLatLng();
|
||||
if (this.parse_name(m, l, "Node")) named = true;
|
||||
layers.push(m);
|
||||
}
|
||||
|
||||
el = xml.getElementsByTagName('way');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
if (i > 10) break;
|
||||
var l = this.parse_way(el[i], nodes, options);
|
||||
if (!l) continue;
|
||||
if (!ll) ll = l.getLatLngs()[0];
|
||||
if (this.parse_name(l, l, "Way")) named = true;
|
||||
layers.push(l);
|
||||
ways[l.osmid] = l;
|
||||
}
|
||||
|
||||
el = xml.getElementsByTagName('relation');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
if (i > 10) break;
|
||||
var l = this.parse_relation(el[i], ways, options);
|
||||
if (!l) continue;
|
||||
if (!ll) ll = l.getLatLngs()[0];
|
||||
if (this.parse_name(l, l, "Relation")) named = true;
|
||||
layers.push(l);
|
||||
}
|
||||
|
||||
if (!layers.length) return;
|
||||
var layer = layers[0];
|
||||
if (layers.length > 1)
|
||||
layer = new L.FeatureGroup(layers);
|
||||
if (!named) this.parse_name(xml, layer);
|
||||
layer.focusPoint = ll;
|
||||
return layer;
|
||||
},
|
||||
|
||||
parse_name: function(layer, obj, obj_name) {
|
||||
console.info("parse name");
|
||||
console.info(this.options);
|
||||
if (!this.options.forceAll)
|
||||
if (!obj.tags || !obj.tags.length) return;
|
||||
var i, txt = "<table>";
|
||||
for (i = 0; i < obj.tags.length; i++) {
|
||||
var t = obj.tags[i];
|
||||
txt += "<tr><td>" + t.k + "</td><td>=</td><td>" + t.v + "</td></tr>";
|
||||
}
|
||||
txt += "</table>"
|
||||
txt = "<h2>" + obj_name + " " + obj.osmid + "</h2>" + txt;
|
||||
if (layer) layer.bindPopup(txt);
|
||||
return txt;
|
||||
},
|
||||
|
||||
parse_tags: function(line) {
|
||||
var tags = [], el = line.getElementsByTagName('tag');
|
||||
for (var i = 0; i < el.length; i++)
|
||||
tags.push({k: el[i].getAttribute('k'), v: el[i].getAttribute('v')})
|
||||
return tags;
|
||||
},
|
||||
|
||||
parse_node: function(e) {
|
||||
var n = { osmid: e.getAttribute('id')
|
||||
, lat:e.getAttribute('lat')
|
||||
, lon:e.getAttribute('lon')
|
||||
}
|
||||
n.ll = new L.LatLng(n.lat, n.lon);
|
||||
n.tags = this.parse_tags(e);
|
||||
return n;
|
||||
},
|
||||
|
||||
parse_way: function(line, nodes, options) {
|
||||
var el = line.getElementsByTagName('nd');
|
||||
if (!el.length) return;
|
||||
var coords = [], tags = [];
|
||||
for (var i = 0; i < el.length; i++) {
|
||||
var ref = el[i].getAttribute('ref'), n = nodes[ref];
|
||||
if (!n) return;
|
||||
coords.push(n.ll);
|
||||
}
|
||||
var layer = new L.Polyline(coords, options);
|
||||
layer.tags = this.parse_tags(line);
|
||||
layer.osmid = line.getAttribute('id')
|
||||
return layer;
|
||||
},
|
||||
|
||||
parse_relation: function(line, ways, options) {
|
||||
var el = line.getElementsByTagName('member');
|
||||
if (!el.length) return;
|
||||
var rt, coords = [], tags = this.parse_tags(line);
|
||||
for (var i = 0; i < tags.length; i++)
|
||||
if (tags[i].k == "type") rt = tags[i].v;
|
||||
|
||||
if (rt != "multipolygon" && rt != "boundary" && rt != "waterway")
|
||||
return;
|
||||
|
||||
for (var i = 0; i < el.length; i++) {
|
||||
var mt = el[i].getAttribute("type"), ref = el[i].getAttribute("ref");
|
||||
if (mt != "way") continue;
|
||||
var w = ways[ref];
|
||||
console.info("Way: " + ref + " " + w);
|
||||
if (!w) return;
|
||||
coords.push(w);
|
||||
}
|
||||
console.info("Coords: " + coords.length);
|
||||
if (!coords.length) return;
|
||||
var layer = new L.MultiPolyline(coords, options);
|
||||
layer.tags = this.parse_tags(line);
|
||||
layer.osmid = line.getAttribute('id')
|
||||
return layer;
|
||||
},
|
||||
|
||||
named_node: function(node, options) {
|
||||
var marker = new L.Marker(new L.LatLng(node.lat, node.lon), options);
|
||||
return marker;
|
||||
}
|
||||
});
|
||||
22
bower_components/leaflet-plugins/package.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"author": "Pavel Shramov",
|
||||
"name": "leaflet-plugins",
|
||||
"version": "1.0.1",
|
||||
"description": "Miscellaneous plugins for Leaflet library for services that need to display route information and need satellite imagery from different providers",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:shramov/leaflet-plugins.git"
|
||||
},
|
||||
"contributors": [
|
||||
"Bruno Bergot <bruno@eliaz.fr>",
|
||||
"Andrey Lushchick <andrew@lushchick.org>"
|
||||
],
|
||||
"keywords": [
|
||||
"leaflet",
|
||||
"plugins",
|
||||
"map",
|
||||
"google",
|
||||
"bing",
|
||||
"yandex"
|
||||
]
|
||||
}
|
||||
13
bower_components/leaflet-routing/.bower.json
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "leaflet-routing",
|
||||
"homepage": "https://github.com/Turistforeningen/leaflet-routing",
|
||||
"_release": "9d66697f2a",
|
||||
"_resolution": {
|
||||
"type": "branch",
|
||||
"branch": "gh-pages",
|
||||
"commit": "9d66697f2a0e547b61a48c7a5358f5f0bba280fe"
|
||||
},
|
||||
"_source": "git://github.com/Turistforeningen/leaflet-routing.git",
|
||||
"_target": "gh-pages",
|
||||
"_originalSource": "Turistforeningen/leaflet-routing"
|
||||
}
|
||||
1
bower_components/leaflet-routing/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
*.swp
|
||||
22
bower_components/leaflet-routing/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 2013, Turistforeningen, Hans Kristian Flaatten
|
||||
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.
|
||||
80
bower_components/leaflet-routing/README.md
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
Routing in Leaflet
|
||||
==================
|
||||
|
||||
Research and development of a Leaflet.js routing module. The module will be capable of the routing markers and returning geojson in various ways.
|
||||
|
||||

|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var routing = new L.Routing({
|
||||
position: 'topright'
|
||||
,routing: {
|
||||
router: myRouter
|
||||
}
|
||||
,snapping: {
|
||||
layers: [snapping]
|
||||
,sensitivity: 15
|
||||
,vertexonly: false
|
||||
}
|
||||
});
|
||||
map.addControl(routing);
|
||||
```
|
||||
|
||||
### Enable Drawing
|
||||
|
||||
```javascript
|
||||
routing.draw(true);
|
||||
```
|
||||
|
||||
### Enable Routing `NOT IMPLEMENTED`
|
||||
|
||||
```javascript
|
||||
routing.routing(true);
|
||||
```
|
||||
|
||||
### Enable Snapping `NOT IMPLEMETED`
|
||||
```javascript
|
||||
routing.snapping(true);
|
||||
```
|
||||
|
||||
### Get first waypoint
|
||||
|
||||
```javascript
|
||||
var first = routing.getFirst();
|
||||
```
|
||||
|
||||
### Get last waypoint
|
||||
```javascript
|
||||
var last = routing.getLast();
|
||||
```
|
||||
|
||||
### Get all waypoints
|
||||
```javascript
|
||||
var waypointsArray = routing.getWaypoints();
|
||||
```
|
||||
|
||||
### Routing to Polyline
|
||||
```javascript
|
||||
var polyline = routing.toPolyline();
|
||||
```
|
||||
|
||||
### To GeoJSON
|
||||
```javascript
|
||||
var geoJSON3D = routing.toGeoJSON();
|
||||
var geoJSON2D = routing.toGeoJSON(false);
|
||||
```
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright (c) 2013, Turistforeningen
|
||||
|
||||
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.
|
||||
68
bower_components/leaflet-routing/app.css
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#map {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div.line-mouse-marker {
|
||||
background-color: #ffffff;
|
||||
border: 2px solid black;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#export {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
background-color: rgb(228,225,218);
|
||||
border: 1px solid rgb(196, 196, 196);
|
||||
padding: 10px;
|
||||
z-index: 3000;
|
||||
}
|
||||
|
||||
#search {
|
||||
position: relative;
|
||||
margin: 10px auto;
|
||||
background-color: rgb(228,225,218);
|
||||
border: 1px solid rgb(196, 196, 196);
|
||||
padding: 10px;
|
||||
z-index: 3000;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
#search input {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.typeahead {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.tt-dropdown-menu {
|
||||
width: 240px;
|
||||
padding: 8px 0;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.tt-suggestion {
|
||||
padding: 3px 20px;
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.tt-suggestion.tt-is-under-cursor {
|
||||
color: #fff;
|
||||
background-color: #0097cf;
|
||||
|
||||
}
|
||||
|
||||
.tt-suggestion p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#export input {
|
||||
width: 70px;
|
||||
}
|
||||
228
bower_components/leaflet-routing/app.js
vendored
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
Routing capability using the Leaflet framework
|
||||
Copyright (c) 2013, Turistforeningen, Hans Kristian Flaatten
|
||||
|
||||
https://github.com/Turistforeningen/leaflet-routing
|
||||
*/
|
||||
|
||||
var routing, data;
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
jQuery(function($) {
|
||||
var api, apiKey, rUrl, sUrl, topo, map, snapping, inport, myRouter;
|
||||
|
||||
api = window.location.hash.substr(1).split('@');
|
||||
if (api.length === 2) {
|
||||
rUrl = 'http://' + api[1] + '/route/?coords='
|
||||
sUrl = 'http://' + api[1] + '/bbox/?bbox=';
|
||||
apiKey = api[0];
|
||||
} else {
|
||||
throw new Error('API auth failed');
|
||||
}
|
||||
|
||||
topo = L.tileLayer('http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo2&zoom={z}&x={x}&y={y}', {
|
||||
maxZoom: 16,
|
||||
attribution: '<a href="http://www.statkart.no/">Statens kartverk</a>'
|
||||
});
|
||||
|
||||
var summer = L.tileLayer('http://mt3.turistforeningen.no/prod/trail_summer/{z}/{x}/{y}.png', {
|
||||
maxZoom: 16,
|
||||
attribution: '<a href="http://www.turistforeningen.no/">DNT</a>'
|
||||
});
|
||||
var winter = L.tileLayer('http://mt3.turistforeningen.no/prod/trail_winter/{z}/{x}/{y}.png', {
|
||||
maxZoom: 16,
|
||||
attribution: '<a href="http://www.turistforeningen.no/">DNT</a>'
|
||||
});
|
||||
var cabin = L.tileLayer('http://mt3.turistforeningen.no/prod/cabin/{z}/{x}/{y}.png', {
|
||||
maxZoom: 16,
|
||||
attribution: '<a href="http://www.turistforeningen.no/">DNT</a>'
|
||||
});
|
||||
|
||||
map = new L.Map('map', {
|
||||
layers: [topo]
|
||||
,center: new L.LatLng(61.5, 9)
|
||||
,zoom: 13
|
||||
});
|
||||
cabin.addTo(map);
|
||||
summer.addTo(map);
|
||||
|
||||
L.control.layers({'Topo 2': topo}, {
|
||||
'DNTs merkede stier': summer
|
||||
,'DNTs merkede vinterruter': winter
|
||||
,'DNTs turisthytter': cabin
|
||||
}, {
|
||||
position: 'topleft'
|
||||
}).addTo(map);
|
||||
|
||||
// Import Layer
|
||||
inport = new L.layerGroup(null, {
|
||||
style: {
|
||||
opacity:0.5
|
||||
,clickable:false
|
||||
}
|
||||
}).addTo(map);
|
||||
|
||||
// Snapping Layer
|
||||
snapping = new L.geoJson(null, {
|
||||
style: {
|
||||
opacity:0
|
||||
,clickable:false
|
||||
}
|
||||
}).addTo(map);
|
||||
map.on('moveend', function() {
|
||||
if (map.getZoom() > 12) {
|
||||
var url;
|
||||
url = sUrl + map.getBounds().toBBoxString() + '&callback=?';
|
||||
$.getJSON(url).always(function(data, status) {
|
||||
if (status === 'success') {
|
||||
data = JSON.parse(data);
|
||||
if (data.geometries && data.geometries.length > 0) {
|
||||
snapping.clearLayers();
|
||||
snapping.addData(data);
|
||||
}
|
||||
} else {
|
||||
console.error('Could not load snapping data');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
snapping.clearLayers();
|
||||
}
|
||||
});
|
||||
map.fire('moveend');
|
||||
|
||||
// Routing Function
|
||||
// @todo speed up geometryToLayer()
|
||||
myRouter = function(l1, l2, cb) {
|
||||
var req = $.getJSON(rUrl + [l1.lng, l1.lat, l2.lng, l2.lat].join(',') + '&callback=?');
|
||||
req.always(function(data, status) {
|
||||
if (status === 'success') {
|
||||
try {
|
||||
L.GeoJSON.geometryToLayer(JSON.parse(data)).eachLayer(function (layer) {
|
||||
// 14026
|
||||
var d1 = l1.distanceTo(layer._latlngs[0]);
|
||||
var d2 = l2.distanceTo(layer._latlngs[layer._latlngs.length-1]);
|
||||
|
||||
if (d1 < 10 && d2 < 10) {
|
||||
return cb(null, layer);
|
||||
} else {
|
||||
return cb(new Error('This has been discarded'));
|
||||
}
|
||||
});
|
||||
} catch(e) {
|
||||
return cb(new Error('Invalid JSON'));
|
||||
}
|
||||
} else {
|
||||
return cb(new Error('Routing failed'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Leaflet Routing Module
|
||||
routing = new L.Routing({
|
||||
position: 'topleft'
|
||||
,routing: {
|
||||
router: myRouter
|
||||
}
|
||||
,snapping: {
|
||||
layers: [snapping]
|
||||
,sensitivity: 15
|
||||
,vertexonly: false
|
||||
}
|
||||
});
|
||||
map.addControl(routing);
|
||||
routing.draw(true); // enable drawing mode
|
||||
|
||||
$('#eta-export').hide();
|
||||
$('#eta-export').on('click', function() {
|
||||
var id = $('#eta-id').val();
|
||||
if (!id) { alert('Ingen tp_id definert!'); return; }
|
||||
if (confirm('Eksport til ETA vil overskrive eksisterende geometri!')) {
|
||||
var coords = routing.toGeoJSON().coordinates;
|
||||
var data = [];
|
||||
for (var i = 0; i < coords.length; i++) {
|
||||
data.push(coords[i][1] + ' ' + coords[i][0]);
|
||||
}
|
||||
data = 'LINESTRING(' + data.join(',') + ')';
|
||||
$.post('http://mintur.ut.no/lib/ajax/post_geom.php?api_key=' + apiKey + '&tp_id=' + id, {coords: data}, function(data) {
|
||||
if (data.error) {
|
||||
alert('Eksport feilet med feilkode ' + data.error);
|
||||
} else if (data.success) {
|
||||
window.location.href = 'http://mintur.ut.no/index.php?tp_id=' + id + '&tab=kart';
|
||||
//alert('Eksport suksess!');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('#eta-import').on('click', function() {
|
||||
var id = $('#eta-id').val();
|
||||
if (!id) { alert('Ingen tp_id definert!'); return; }
|
||||
$.get('http://mintur.ut.no/lib/ajax/post_geom.php?api_key=' + apiKey + '&tp_id=' + id, function(data) {
|
||||
if (data.error) {
|
||||
alert('Import feilet med feilkode ' + data.error);
|
||||
} else if (typeof data.coords !== 'undefined') {
|
||||
$('#eta-import').hide();
|
||||
$('#eta-export').show();
|
||||
$('#eta-id').attr('readonly', 'readonly');
|
||||
|
||||
if (data.coords) {
|
||||
data.coords = data.coords.replace('LINESTRING(', '').replace(')', '').split(',');
|
||||
for (var i = 0; i < data.coords.length; i++) {
|
||||
data.coords[i] = new L.LatLng(data.coords[i].split(' ')[1], data.coords[i].split(' ')[0]);
|
||||
}
|
||||
inport.clearLayers();
|
||||
var p = new L.Polyline(data.coords, {clickable:false, color: '#000000', opacity: 0.4});
|
||||
inport.addLayer(p);
|
||||
map.fitBounds(p.getBounds());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function fetchSsrAc(search, cb) {
|
||||
var result = [];
|
||||
$.ajax({
|
||||
url: "https://ws.geonorge.no/SKWS3Index/ssr/sok?navn=" + search + "*&epsgKode=4326&antPerSide=10"
|
||||
,type: "GET"
|
||||
,dataType: 'xml'
|
||||
,success: function(xml) {
|
||||
$(xml).find('sokRes > stedsnavn').each(function(){
|
||||
result.push({
|
||||
title: $(this).find('stedsnavn').text()
|
||||
,lat: $(this).find('aust').text()
|
||||
,lng: $(this).find('nord').text()
|
||||
});
|
||||
});
|
||||
cb(null, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$('#ssr-search').typeahead({
|
||||
remote: {
|
||||
url: 'https://ws.geonorge.no/SKWS3Index/ssr/sok?navn=%QUERY*&epsgKode=4326&antPerSide=10',
|
||||
dataType: 'xml',
|
||||
filter: function(xml) {
|
||||
var result = [];
|
||||
$(xml).find('sokRes > stedsnavn').each(function(){
|
||||
result.push({
|
||||
value: $(this).find('stedsnavn').text()
|
||||
,tokens: [$(this).find('stedsnavn').text()]
|
||||
,lat: $(this).find('nord').text()
|
||||
,lng: $(this).find('aust').text()
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#ssr-search').on('typeahead:selected', function(e, object) {
|
||||
var ll = new L.LatLng(object.lat, object.lng);
|
||||
map.panTo(ll);
|
||||
$('#ssr-search').val('');
|
||||
})
|
||||
|
||||
});
|
||||
}).call(this);
|
||||
BIN
bower_components/leaflet-routing/images/promo.gif
vendored
Normal file
|
After Width: | Height: | Size: 3.2 MiB |
BIN
bower_components/leaflet-routing/images/promo.png
vendored
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
44
bower_components/leaflet-routing/index.html
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Routing in Leaflet</title>
|
||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="libs/leaflet/leaflet.ie.css" /><![endif]-->
|
||||
<link rel="stylesheet" href="app.css" />
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-38558206-1']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="search">
|
||||
<strong>Søk:</strong> <input type="text" id="ssr-search">
|
||||
</div>
|
||||
|
||||
<div id="export">
|
||||
<strong>tp_id</strong>: <input type="text" id="eta-id">
|
||||
<button id="eta-export">Eksport</button>
|
||||
<button id="eta-import">Import</button>
|
||||
</div>
|
||||
<div id="map"></div>
|
||||
|
||||
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
|
||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
||||
<script src="src/utils/LineUtil.Snapping.js"></script>
|
||||
<script src="src/utils/Marker.Snapping.js"></script>
|
||||
<script src="src/L.Routing.js"></script>
|
||||
<script src="src/L.Routing.Storage.js"></script>
|
||||
<script src="src/L.Routing.Draw.js"></script>
|
||||
<script src="src/L.Routing.Edit.js"></script>
|
||||
<script src="http://twitter.github.io/typeahead.js/releases/latest/typeahead.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
286
bower_components/leaflet-routing/src/L.Routing.Draw.js
vendored
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* L.Routing.Draw class
|
||||
*
|
||||
* Responsible for drawing and contine drawing
|
||||
*
|
||||
* @dependencies L, L.Routing
|
||||
*
|
||||
* @usage new L.Routing.Draw(map, options);
|
||||
*/
|
||||
|
||||
L.Routing.Draw = L.Handler.extend({
|
||||
|
||||
// INCLUDES
|
||||
includes: [L.Mixin.Events]
|
||||
|
||||
// OPTIONS
|
||||
,options: {}
|
||||
|
||||
/**
|
||||
* Draw Constructor
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param <> parent - parent class instance
|
||||
* @param <Oject> options - routing options
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo fetch last waypoint
|
||||
*/
|
||||
,initialize: function (parent, options) {
|
||||
this._parent = parent;
|
||||
this._map = parent._map;
|
||||
|
||||
this._enabled = false;
|
||||
|
||||
L.Util.setOptions(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable drawing
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @event map.routing:draw-start
|
||||
* @event map.routing:draw-new
|
||||
* @event map.routing:draw-continue
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,enable: function() {
|
||||
if (this._enabled) { return; }
|
||||
|
||||
this._enabled = true;
|
||||
this._hidden = false;
|
||||
this._dragging = false;
|
||||
this._addHooks();
|
||||
this.fire('enabled');
|
||||
|
||||
this._map.fire('routing:draw-start');
|
||||
if (this._parent._segments._layers.length === 0) {
|
||||
this._map.fire('routing:draw-new');
|
||||
} else {
|
||||
this._map.fire('routing:draw-continue');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable drawing
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @event map.routing:draw-end
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,disable: function() {
|
||||
if (!this._enabled) { return; }
|
||||
|
||||
this._enabled = false;
|
||||
this._removeHooks();
|
||||
this.fire('disabled');
|
||||
|
||||
this._map.fire('routing:draw-end');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add hooks
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo hide and style the trailer!
|
||||
*/
|
||||
,_addHooks: function() {
|
||||
if (!this._map) { return; }
|
||||
|
||||
// Visible Marker
|
||||
if (!this._marker) {
|
||||
this._marker = new L.Marker(this._map.getCenter(), {
|
||||
icon: this.options.icons.normal
|
||||
,zIndexOffset: this.options.zIndexOffset
|
||||
,clickable: false
|
||||
});
|
||||
}
|
||||
|
||||
// Trailing line
|
||||
if (!this._trailer) {
|
||||
var ll = this._map.getCenter();
|
||||
this._trailer = new L.Polyline([ll, ll], {
|
||||
opacity: 0.2
|
||||
,clickable: false
|
||||
});
|
||||
}
|
||||
|
||||
this._parent.on('waypoint:mouseover', this._catchWaypointEvent, this);
|
||||
this._parent.on('waypoint:mouseout' , this._catchWaypointEvent, this);
|
||||
this._parent.on('waypoint:dragstart', this._catchWaypointEvent, this);
|
||||
this._parent.on('waypoint:dragend' , this._catchWaypointEvent, this);
|
||||
|
||||
this._parent.on('segment:mouseover' , this._catchWaypointEvent, this);
|
||||
this._parent.on('segment:mouseout' , this._catchWaypointEvent, this);
|
||||
this._parent.on('segment:dragstart' , this._catchWaypointEvent, this);
|
||||
this._parent.on('segment:dragend' , this._catchWaypointEvent, this);
|
||||
|
||||
this._map.on('mousemove', this._onMouseMove, this);
|
||||
this._map.on('click', this._onMouseClick, this);
|
||||
|
||||
this._marker.addTo(this._map);
|
||||
this._trailer.addTo(this._map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove hooks
|
||||
*
|
||||
* This method is invoked after the `disable()` has been called and removes
|
||||
* all the hooks set up using the `_addHooks()` method.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_removeHooks: function() {
|
||||
if (!this._map) { return; }
|
||||
|
||||
this._parent.off('waypoint:mouseover', this._catchWaypointEvent, this);
|
||||
this._parent.off('waypoint:mouseout' , this._catchWaypointEvent, this);
|
||||
this._parent.off('waypoint:dragstart', this._catchWaypointEvent, this);
|
||||
this._parent.off('waypoint:dragend' , this._catchWaypointEvent, this);
|
||||
|
||||
this._parent.off('segment:mouseover' , this._catchWaypointEvent, this);
|
||||
this._parent.off('segment:mouseout' , this._catchWaypointEvent, this);
|
||||
this._parent.off('segment:dragstart' , this._catchWaypointEvent, this);
|
||||
this._parent.off('segment:dragend' , this._catchWaypointEvent, this);
|
||||
|
||||
this._map.off('click', this._onMouseClick, this);
|
||||
this._map.off('mousemove', this._onMouseMove, this);
|
||||
|
||||
this._map.removeLayer(this._marker);
|
||||
this._map.removeLayer(this._trailer);
|
||||
|
||||
delete this._marker;
|
||||
delete this._trailer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle waypoint events
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - waypoint event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_catchWaypointEvent: function(e) {
|
||||
var type = e.type.split(':')[1];
|
||||
|
||||
if (this._hidden) {
|
||||
if (this._dragging) {
|
||||
if (type === 'dragend') {
|
||||
this._dragging = false;
|
||||
}
|
||||
} else {
|
||||
if (type === 'mouseout') {
|
||||
this._show();
|
||||
} else if (type === 'dragstart') {
|
||||
this._dragging = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (type === 'mouseover') {
|
||||
this._hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide HUD
|
||||
*
|
||||
* Call this method in order to quickly hide graphical drawing elements for
|
||||
* instance hoovering over draggable objects which should tempoarily disable
|
||||
* dragging.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_hide: function() {
|
||||
this._hidden = true;
|
||||
this._marker.setOpacity(0.0);
|
||||
this._trailer.setStyle({opacity: 0.0});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show HUD
|
||||
*
|
||||
* Call this method to restore graphical drawing elements after they have been
|
||||
* hidden.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_show: function() {
|
||||
this._hidden = false;
|
||||
this._marker.setOpacity(1.0);
|
||||
this._trailer.setStyle({opacity: 0.2});
|
||||
}
|
||||
|
||||
/**
|
||||
* Mouse move handler
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse move event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_onMouseMove : function(e) {
|
||||
if (this._hidden) { return; }
|
||||
|
||||
var latlng = e.latlng;
|
||||
var last = this._parent.getLast();
|
||||
|
||||
if (this.options.snapping) {
|
||||
latlng = L.LineUtil.snapToLayers(latlng, null, this.options.snapping);
|
||||
}
|
||||
|
||||
this._marker.setLatLng(latlng);
|
||||
|
||||
|
||||
if (last !== null) {
|
||||
this._trailer.setLatLngs([last.getLatLng(), latlng]);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Mouse click handler
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse click event
|
||||
*
|
||||
* @event map.routing:new-waypoint
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_onMouseClick: function(e) {
|
||||
if (this._hidden) { return; }
|
||||
|
||||
var marker, latlng, last;
|
||||
|
||||
latlng = e.latlng;
|
||||
if (this.options.snapping) {
|
||||
latlng = L.LineUtil.snapToLayers(latlng, null, this.options.snapping);
|
||||
}
|
||||
marker = new L.Marker(latlng);
|
||||
last = this._parent.getLast();
|
||||
|
||||
this._trailer.setLatLngs([latlng, latlng]);
|
||||
this._parent.addWaypoint(marker, last, null, function(err, data) {
|
||||
// console.log(err, data);
|
||||
});
|
||||
}
|
||||
});
|
||||
387
bower_components/leaflet-routing/src/L.Routing.Edit.js
vendored
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
/*
|
||||
* L.Routing.Edit class
|
||||
*
|
||||
* Responsible handle edits
|
||||
*
|
||||
* @dependencies L, L.Routing
|
||||
*
|
||||
* @usage new L.Routing.Draw(map, options);
|
||||
*/
|
||||
|
||||
L.Routing.Edit = L.Handler.extend({
|
||||
|
||||
// INCLUDES
|
||||
includes: [L.Mixin.Events]
|
||||
|
||||
// OPTIONS
|
||||
,options: {}
|
||||
|
||||
/**
|
||||
* Edit Constructor
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param <> parent - parent class instance
|
||||
* @param <Oject> options - routing options
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo fetch last waypoint
|
||||
*/
|
||||
,initialize: function (parent, options) {
|
||||
this._parent = parent;
|
||||
this._map = parent._map;
|
||||
|
||||
this._enabled = false;
|
||||
|
||||
L.Util.setOptions(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable drawing
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @event map.routing:edit-start
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,enable: function() {
|
||||
if (this._enabled) { return; }
|
||||
|
||||
this._enabled = true;
|
||||
this._addHooks();
|
||||
this.fire('enabled');
|
||||
|
||||
this._map.fire('routing:edit-start');
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable drawing
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @event map.draw:edit-end
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,disable: function() {
|
||||
if (!this._enabled) { return; }
|
||||
|
||||
this._enabled = false;
|
||||
this._removeHooks();
|
||||
this.fire('disabled');
|
||||
|
||||
this._map.fire('routing:edit-end');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add hooks
|
||||
*
|
||||
* This method is invoked when `enable()` is called – and sets up all
|
||||
* necessary hooks such as:
|
||||
* * text selection
|
||||
* * key listeners
|
||||
* * mouse marker
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo hide and style the trailer!
|
||||
*/
|
||||
,_addHooks: function() {
|
||||
if (!this._map) { return; }
|
||||
|
||||
if (!this._mouseMarker) {
|
||||
this._mouseMarker = L.marker(this._map.getCenter(), {
|
||||
icon: L.divIcon({
|
||||
className: 'line-mouse-marker'
|
||||
,iconAnchor: [5, 5]
|
||||
,iconSize: [10, 10]
|
||||
})
|
||||
,clickable: true
|
||||
,draggable: true
|
||||
,opacity: 0
|
||||
,zIndexOffset: this.options.zIndexOffset
|
||||
});
|
||||
}
|
||||
this._mouseMarker.addTo(this._map);
|
||||
|
||||
if (!this._trailer1) {
|
||||
var ll = this._map.getCenter();
|
||||
var style = {opacity: 0.0,clickable: false};
|
||||
this._trailer1 = new L.Polyline([ll, ll], style);
|
||||
this._trailer2 = new L.Polyline([ll, ll], style);
|
||||
}
|
||||
this._trailer1.addTo(this._map);
|
||||
this._trailer2.addTo(this._map);
|
||||
|
||||
this._parent.on('segment:mouseover' , this._segmentOnMouseover, this);
|
||||
|
||||
this._mouseMarker.on('dragstart' , this._segmentOnDragstart, this);
|
||||
this._mouseMarker.on('drag' , this._segmentOnDrag, this);
|
||||
this._mouseMarker.on('dragend' , this._segmentOnDragend, this);
|
||||
|
||||
this._parent.on('waypoint:dragstart', this._waypointOnDragstart, this);
|
||||
this._parent.on('waypoint:drag' , this._waypointOnDrag, this);
|
||||
this._parent.on('waypoint:dragend' , this._waypointOnDragend, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove hooks
|
||||
*
|
||||
* This method is invoked after the `disable()` has been called and removes
|
||||
* all the hooks set up using the `_addHooks()` method.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_removeHooks: function() {
|
||||
if (!this._map) { return; }
|
||||
|
||||
// this._trailer1.addTo(this._map);
|
||||
// this._trailer2.addTo(this._map);
|
||||
|
||||
this._parent.off('segment:mouseover' , this._segmentOnMouseover, this);
|
||||
|
||||
this._mouseMarker.off('dragstart' , this._segmentOnDragstart, this);
|
||||
this._mouseMarker.off('drag' , this._segmentOnDrag, this);
|
||||
this._mouseMarker.off('dragend' , this._segmentOnDragend, this);
|
||||
|
||||
this._parent.off('waypoint:dragstart', this._waypointOnDragstart, this);
|
||||
this._parent.off('waypoint:drag' , this._waypointOnDrag, this);
|
||||
this._parent.off('waypoint:dragend' , this._waypointOnDragend, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when the mouse first enters a segment
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse over event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_segmentOnMouseover: function(e) {
|
||||
this._mouseMarker.setOpacity(1.0);
|
||||
this._map.on('mousemove', this._segmentOnMousemove, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when the mouse leaves a segement
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse move event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_segmentOnMouseout: function(e) {
|
||||
if (this._dragging) { return; }
|
||||
|
||||
this._mouseMarker.setOpacity(0.0);
|
||||
this._map.off('mousemove', this._segmentOnMousemove, this);
|
||||
|
||||
this.fire('segment:mouseout');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when the mouse is moved
|
||||
*
|
||||
* This method is fired continously when mouse is moved in edition mode.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse move event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_segmentOnMousemove: function(e) {
|
||||
if (this._dragging) { return; }
|
||||
|
||||
var latlng = L.LineUtil.snapToLayers(e.latlng, null, {
|
||||
layers: [this._parent._segments]
|
||||
,sensitivity: 40
|
||||
,vertexonly: false
|
||||
});
|
||||
|
||||
if (latlng._feature === null) {
|
||||
this._segmentOnMouseout(e);
|
||||
} else {
|
||||
this._mouseMarker._snapping = latlng._feature._routing;
|
||||
this._mouseMarker.setLatLng(latlng);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mouse marker dragstart
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse dragstart event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_segmentOnDragstart: function(e) {
|
||||
var latlng = e.target.getLatLng();
|
||||
var next = e.target._snapping.nextMarker;
|
||||
var prev = e.target._snapping.prevMarker;
|
||||
|
||||
this._setTrailers(latlng, next, prev, true);
|
||||
|
||||
this._dragging = true;
|
||||
this.fire('segment:dragstart');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when a marker is dragged
|
||||
*
|
||||
* This method is fired continously when dragging a marker and snapps the
|
||||
* marker to the snapping layer.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse drag event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_segmentOnDrag: function(e) {
|
||||
var latlng = e.target.getLatLng();
|
||||
var next = e.target._snapping.nextMarker;
|
||||
var prev = e.target._snapping.prevMarker;
|
||||
|
||||
if (this.options.snapping) {
|
||||
latlng = L.LineUtil.snapToLayers(latlng, null, this.options.snapping);
|
||||
}
|
||||
|
||||
e.target.setLatLng(latlng);
|
||||
this._setTrailers(latlng, next, prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mouse marker dragend
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse dragend event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_segmentOnDragend: function(e) {
|
||||
var next = this._mouseMarker._snapping.nextMarker;
|
||||
var prev = this._mouseMarker._snapping.prevMarker;
|
||||
var latlng = this._mouseMarker.getLatLng();
|
||||
|
||||
this._parent.addWaypoint(latlng, prev, next, function(err, data) {
|
||||
//console.log(err, data);
|
||||
});
|
||||
|
||||
this._dragging = false;
|
||||
this._setTrailers(null, null, null, false);
|
||||
this.fire('segment:dragend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when marker drag start
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse dragend event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_waypointOnDragstart: function(e) {
|
||||
var next = e.marker._routing.nextMarker;
|
||||
var prev = e.marker._routing.prevMarker;
|
||||
|
||||
this._setTrailers(e.marker.getLatLng(), next, prev, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired while dragging marker
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse drag event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_waypointOnDrag: function(e) {
|
||||
var latlng = e.marker._latlng;
|
||||
var next = e.marker._routing.nextMarker;
|
||||
var prev = e.marker._routing.prevMarker;
|
||||
|
||||
if (this.options.snapping) {
|
||||
latlng = L.LineUtil.snapToLayers(latlng, null, this.options.snapping);
|
||||
}
|
||||
|
||||
e.marker.setLatLng(latlng);
|
||||
this._setTrailers(latlng, next, prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when marker drag ends
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse dragend event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_waypointOnDragend: function(e) {
|
||||
this._setTrailers(null, null, null, false);
|
||||
this._parent.routeWaypoint(e.marker, function(err, data) {
|
||||
//console.log('_waypointOnDragend.cb', err, data);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when marker is clicked
|
||||
*
|
||||
* This method is fired when a marker is clicked by the user. It will then
|
||||
* procede to remove the marker and reroute any connected line segments.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse click event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_waypointOnClick: function(e) {
|
||||
this._parent.removeWaypoint(e.layer, function(err, data) {
|
||||
//console.log('_waypointOnDragend.cb', err, data);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set trailing guide lines
|
||||
*
|
||||
*/
|
||||
,_setTrailers: function(latlng, next, prev, show) {
|
||||
if (typeof show !== 'undefined') {
|
||||
if (show === false) {
|
||||
this._trailer1.setStyle({opacity: 0.0});
|
||||
this._trailer2.setStyle({opacity: 0.0});
|
||||
return;
|
||||
} else {
|
||||
if (next !== null) {
|
||||
this._trailer1.setStyle({opacity: 0.2});
|
||||
}
|
||||
if (prev !== null) {
|
||||
this._trailer2.setStyle({opacity: 0.2});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (next) {
|
||||
this._trailer1.setLatLngs([latlng, next.getLatLng()]);
|
||||
}
|
||||
if (prev) {
|
||||
this._trailer2.setLatLngs([latlng, prev.getLatLng()]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
31
bower_components/leaflet-routing/src/L.Routing.Storage.js
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Leaflet Routing Storage
|
||||
*
|
||||
* Storing routable objects
|
||||
*
|
||||
* @dependencies L, L.Routing
|
||||
*
|
||||
* @usage new L.Routing(options);
|
||||
*/
|
||||
|
||||
(function () {
|
||||
L.Routing.Storage = L.MultiPolyline.extend({
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
initialize: function (latlngs, options) {
|
||||
this._layers = {};
|
||||
this._options = options;
|
||||
this.setLatLngs(latlngs);
|
||||
|
||||
this.on('layeradd', function() {
|
||||
console.log('layeradd', arguments);
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
|
||||
L.Routing.storage = function (latlngs, options) {
|
||||
return new L.MultiPolyline(latlngs, options);
|
||||
};
|
||||
|
||||
}());
|
||||
556
bower_components/leaflet-routing/src/L.Routing.js
vendored
Normal file
|
|
@ -0,0 +1,556 @@
|
|||
/*
|
||||
* L.Routing main class
|
||||
*
|
||||
* Main clase for the Leaflet routing module
|
||||
*
|
||||
* @dependencies L
|
||||
*
|
||||
* @usage new L.Routing(options);
|
||||
*
|
||||
* @todo use L.Class.extend instead?
|
||||
*/
|
||||
|
||||
L.Routing = L.Control.extend({
|
||||
|
||||
// INCLUDES
|
||||
includes: [L.Mixin.Events]
|
||||
|
||||
// CONSTANTS
|
||||
,statics: {
|
||||
VERSION: '0.0.2-dev'
|
||||
}
|
||||
|
||||
// OPTIONS
|
||||
,options: {
|
||||
position: 'topleft'
|
||||
,icons: {
|
||||
start: new L.Icon.Default()
|
||||
,end: new L.Icon.Default()
|
||||
,normal: new L.Icon.Default()
|
||||
}
|
||||
,zIndexOffset: 2000
|
||||
,routing: {
|
||||
router: null // function (<L.Latlng> l1, <L.Latlng> l2, <Function> cb)
|
||||
}
|
||||
,snapping: {
|
||||
layers: [] // layers to snap to
|
||||
,sensitivity: 10 // snapping sensitivity
|
||||
,vertexonly: false // vertex only snapping
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Routing Constructor
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param <Object> options - non-default options
|
||||
*
|
||||
* @todo render display of segments and waypoints
|
||||
*/
|
||||
,initialize: function (options) {
|
||||
this._editing = false;
|
||||
this._drawing = false;
|
||||
|
||||
L.Util.setOptions(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when controller is added to map
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param <L.Map> map - map instance
|
||||
*
|
||||
* @return <HTMLElement> container
|
||||
*/
|
||||
,onAdd: function (map) {
|
||||
this._map = map;
|
||||
this._container = this._map._container;
|
||||
this._overlayPane = this._map._panes.overlayPane;
|
||||
this._popupPane = this._map._panes.popupPane;
|
||||
|
||||
this._router = this.options.routing.router;
|
||||
this._segments = new L.FeatureGroup().addTo(map);
|
||||
this._waypoints = new L.FeatureGroup().addTo(map);
|
||||
this._waypoints._first = null;
|
||||
this._waypoints._last = null;
|
||||
|
||||
//L.DomUtil.disableTextSelection();
|
||||
//this._tooltip = new L.Tooltip(this._map);
|
||||
//this._tooltip.updateContent({ text: L.drawLocal.draw.marker.tooltip.start });
|
||||
L.DomEvent.addListener(this._container, 'keyup', this._keyupListener, this);
|
||||
|
||||
this._draw = new L.Routing.Draw(this, {
|
||||
icons: this.options.icons
|
||||
,zIndexOffset: this.options.zIndexOffset
|
||||
,snapping: this.options.snapping
|
||||
});
|
||||
|
||||
this._edit = new L.Routing.Edit(this, {
|
||||
icons: this.options.icons
|
||||
,zIndexOffset: this.options.zIndexOffset
|
||||
,snapping: this.options.snapping
|
||||
});
|
||||
this._edit.enable();
|
||||
|
||||
this.on('waypoint:click', this._waypointClickHandler, this)
|
||||
this._segments.on('mouseover' , this._fireSegmentEvent, this);
|
||||
this._edit.on('segment:mouseout' , this._fireSegmentEvent, this);
|
||||
this._edit.on('segment:dragstart', this._fireSegmentEvent, this);
|
||||
this._edit.on('segment:dragend' , this._fireSegmentEvent, this);
|
||||
|
||||
var container = L.DomUtil.create('div', 'leaflet-routing');
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when controller is removed from map
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param <L.Map> map - map instance
|
||||
*/
|
||||
,onRemove: function(map) {
|
||||
//L.DomUtil.create('div', 'leaflet-routing'); <= delete this
|
||||
|
||||
this.off('waypoint:click', this._waypointClickHandler, this)
|
||||
this._segments.off('mouseover' , this._fireSegmentEvent, this);
|
||||
this._edit.off('segment:mouseout' , this._fireSegmentEvent, this);
|
||||
this._edit.off('segment:dragstart', this._fireSegmentEvent, this);
|
||||
this._edit.off('segment:dragend' , this._fireSegmentEvent, this);
|
||||
|
||||
this._edit.disable();
|
||||
this._draw.disable();
|
||||
|
||||
L.DomUtil.enableTextSelection();
|
||||
// this._tooltip.dispose();
|
||||
// this._tooltip = null;
|
||||
L.DomEvent.removeListener(this._container, 'keyup', this._keyupListener);
|
||||
|
||||
delete this._draw;
|
||||
delete this._edit;
|
||||
delete this._map;
|
||||
delete this._router;
|
||||
delete this._segments;
|
||||
delete this._waypoints;
|
||||
delete this.options;
|
||||
}
|
||||
|
||||
,_waypointClickHandler: function(e) {
|
||||
this.removeWaypoint(e.marker, function() {
|
||||
console.log(arguments);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new waypoint to path
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param <L.Marker> marker - new waypoint marker (can be ll)
|
||||
* @param <L.Marker> prev - previous waypoint marker
|
||||
* @param <L.Marker> next - next waypoint marker
|
||||
* @param <Function> cb - callback method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,addWaypoint: function(marker, prev, next, cb) {
|
||||
if (marker instanceof L.LatLng) {
|
||||
marker = new L.Marker(marker);
|
||||
}
|
||||
|
||||
marker._routing = {
|
||||
prevMarker : prev
|
||||
,nextMarker : next
|
||||
,prevLine : null
|
||||
,nextLine : null
|
||||
,timeoutID : null
|
||||
};
|
||||
|
||||
if (this._waypoints._first === null && this._waypoints._last === null) {
|
||||
this._waypoints._first = marker;
|
||||
this._waypoints._last = marker;
|
||||
} else if (next === null) {
|
||||
this._waypoints._last = marker;
|
||||
} else if (prev === null) {
|
||||
this._waypoints._first = marker;
|
||||
}
|
||||
|
||||
if (marker._routing.prevMarker !== null) {
|
||||
marker._routing.prevMarker._routing.nextMarker = marker;
|
||||
marker._routing.prevLine = marker._routing.prevMarker._routing.nextLine;
|
||||
if (marker._routing.prevLine !== null) {
|
||||
marker._routing.prevLine._routing.nextMarker = marker;
|
||||
}
|
||||
}
|
||||
|
||||
if (marker._routing.nextMarker !== null) {
|
||||
marker._routing.nextMarker._routing.prevMarker = marker;
|
||||
marker.nextLine = marker._routing.nextMarker._routing.prevLine;
|
||||
if (marker._routing.nextLine !== null) {
|
||||
marker._routing.nextLine._routing.prevMarker = marker;
|
||||
}
|
||||
}
|
||||
|
||||
marker.on('mouseover', this._fireWaypointEvent, this);
|
||||
marker.on('mouseout' , this._fireWaypointEvent, this);
|
||||
marker.on('dragstart', this._fireWaypointEvent, this);
|
||||
marker.on('dragend' , this._fireWaypointEvent, this);
|
||||
marker.on('drag' , this._fireWaypointEvent, this);
|
||||
marker.on('click' , this._fireWaypointEvent, this);
|
||||
|
||||
this.routeWaypoint(marker, cb);
|
||||
this._waypoints.addLayer(marker);
|
||||
marker.dragging.enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a waypoint from path
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param <L.Marker> marker - new waypoint marker (can be ll)
|
||||
* @param <Function> cb - callback method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,removeWaypoint: function(marker, cb) {
|
||||
marker.off('mouseover', this._fireWaypointEvent, this);
|
||||
marker.off('mouseout' , this._fireWaypointEvent, this);
|
||||
marker.off('dragstart', this._fireWaypointEvent, this);
|
||||
marker.off('dragend' , this._fireWaypointEvent, this);
|
||||
marker.off('drag' , this._fireWaypointEvent, this);
|
||||
marker.off('click' , this._fireWaypointEvent, this);
|
||||
|
||||
var prev = marker._routing.prevMarker;
|
||||
var next = marker._routing.nextMarker;
|
||||
|
||||
if (this._waypoints._first && marker._leaflet_id === this._waypoints._first._leaflet_id) {
|
||||
this._waypoints._first = next;
|
||||
}
|
||||
|
||||
if (this._waypoints._last && marker._leaflet_id === this._waypoints._last._leaflet_id) {
|
||||
this._waypoints._last = prev;
|
||||
}
|
||||
|
||||
if (prev !== null) {
|
||||
prev._routing.nextMarker = next;
|
||||
prev._routing.nextLine = null;
|
||||
}
|
||||
|
||||
if (next !== null) {
|
||||
next._routing.prevMarker = prev;
|
||||
next._routing.prevLine = null;
|
||||
}
|
||||
|
||||
if (marker._routing.nextLine !== null) {
|
||||
this._segments.removeLayer(marker._routing.nextLine);
|
||||
}
|
||||
|
||||
if (marker._routing.prevLine !== null) {
|
||||
this._segments.removeLayer(marker._routing.prevLine);
|
||||
}
|
||||
|
||||
this._waypoints.removeLayer(marker);
|
||||
|
||||
if (prev !== null) {
|
||||
this.routeWaypoint(prev, cb);
|
||||
} else if (next !== null) {
|
||||
this.routeWaypoint(next, cb);
|
||||
} else {
|
||||
this._draw.enable();
|
||||
cb(null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Route with respect to waypoint
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param <L.Marker> marker - marker to route on
|
||||
* @param <Function> cb - callback function
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo add propper error checking for callback
|
||||
*/
|
||||
,routeWaypoint: function(marker, cb) {
|
||||
var i = 0;
|
||||
var $this = this;
|
||||
var callback = function(err, data) {
|
||||
i++;
|
||||
if (i === 2) {
|
||||
$this.fire('routing:routeWaypointEnd');
|
||||
cb(err, marker);
|
||||
}
|
||||
}
|
||||
|
||||
this.fire('routing:routeWaypointStart');
|
||||
|
||||
this._routeSegment(marker._routing.prevMarker, marker, callback);
|
||||
this._routeSegment(marker, marker._routing.nextMarker, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route segment between two markers
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Marker> m1 - first waypoint marker
|
||||
* @param <L.Marker> m2 - second waypoint marker
|
||||
* @param <Function> cb - callback function (<Error> err, <String> data)
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo logic if router fails
|
||||
*/
|
||||
,_routeSegment: function(m1, m2, cb) {
|
||||
var $this = this;
|
||||
|
||||
if (m1 === null || m2 === null) {
|
||||
return cb(null, true);
|
||||
}
|
||||
|
||||
this._router(m1.getLatLng(), m2.getLatLng(), function(err, layer) {
|
||||
if (typeof layer === 'undefined') {
|
||||
var layer = new L.Polyline([m1.getLatLng(), m2.getLatLng()]);
|
||||
}
|
||||
|
||||
layer._routing = {
|
||||
prevMarker: m1
|
||||
,nextMarker: m2
|
||||
};
|
||||
|
||||
if (m1._routing.nextLine !== null) {
|
||||
$this._segments.removeLayer(m1._routing.nextLine);
|
||||
}
|
||||
$this._segments.addLayer(layer);
|
||||
|
||||
m1._routing.nextLine = layer;
|
||||
m2._routing.prevLine = layer;
|
||||
|
||||
return cb(null, layer);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate over all segments and execute callback for each segment
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <function> callback - function to call for each segment
|
||||
* @param <object> context - callback execution context (this). Optional, default: this
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_eachSegment: function(callback, context) {
|
||||
var thisArg = context || this;
|
||||
var marker = this.getFirst();
|
||||
|
||||
if (marker === null) { return; }
|
||||
|
||||
while (marker._routing.nextMarker !== null) {
|
||||
var m1 = marker;
|
||||
var m2 = marker._routing.nextMarker;
|
||||
var line = marker._routing.nextLine;
|
||||
|
||||
callback.call(thisArg, m1, m2, line);
|
||||
|
||||
marker = marker._routing.nextMarker;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire events
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param <L.Event> e - mouse event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_fireWaypointEvent: function(e) {
|
||||
this.fire('waypoint:' + e.type, {marker:e.target});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
,_fireSegmentEvent: function(e) {
|
||||
if (e.type.split(':').length === 2) {
|
||||
this.fire(e.type);
|
||||
} else {
|
||||
this.fire('segment:' + e.type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get first waypoint
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return L.Marker
|
||||
*/
|
||||
,getFirst: function() {
|
||||
return this._waypoints._first;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last waypoint
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return L.Marker
|
||||
*/
|
||||
,getLast: function() {
|
||||
return this._waypoints._last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all waypoints
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return <L.LatLng[]> all waypoints or empty array if none
|
||||
*/
|
||||
,getWaypoints: function() {
|
||||
var latLngs = [];
|
||||
|
||||
this._eachSegment(function(m1) {
|
||||
latLngs.push(m1.getLatLng());
|
||||
});
|
||||
|
||||
if (this.getLast()) {
|
||||
latLngs.push(this.getLast().getLatLng());
|
||||
}
|
||||
|
||||
return latLngs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates all route segments to a single polyline
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return <L.Polyline> polyline, with empty _latlngs when no route segments
|
||||
*/
|
||||
,toPolyline: function() {
|
||||
var latLngs = [];
|
||||
|
||||
this._eachSegment(function(m1, m2, line) {
|
||||
latLngs = latLngs.concat(line.getLatLngs());
|
||||
});
|
||||
|
||||
return L.polyline(latLngs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export route to GeoJSON
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param <boolean> enforce2d - enforce 2DGeoJSON
|
||||
*
|
||||
* @return <object> GeoJSON object
|
||||
*
|
||||
*/
|
||||
,toGeoJSON: function(enforce2d) {
|
||||
var geojson = {type: "LineString", properties: {waypoints: []}, coordinates: []};
|
||||
var current = this._waypoints._first;
|
||||
|
||||
if (current === null) { return geojson; }
|
||||
|
||||
geojson.properties.waypoints.push([current.getLatLng().lng, current.getLatLng().lat]);
|
||||
|
||||
while (current._routing.nextMarker) {
|
||||
var next = current._routing.nextMarker
|
||||
geojson.properties.waypoints.push([next.getLatLng().lng, next.getLatLng().lat]);
|
||||
|
||||
var tmp = current._routing.nextLine.getLatLngs();
|
||||
for (var i = 0; i < tmp.length; i++) {
|
||||
if (tmp[i].alt && (typeof enforce2d === 'undefined' || enforce2d === false)) {
|
||||
geojson.coordinates.push([tmp[i].lat, tmp[i].lng, tmp[i].alt]);
|
||||
} else {
|
||||
geojson.coordinates.push([tmp[i].lat, tmp[i].lng]);
|
||||
}
|
||||
}
|
||||
|
||||
current = current._routing.nextMarker;
|
||||
}
|
||||
|
||||
return geojson
|
||||
}
|
||||
|
||||
/**
|
||||
* Start (or continue) drawing
|
||||
*
|
||||
* Call this method in order to start or continue drawing. The drawing handler
|
||||
* will be activate and the user can draw on the map.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo check enable
|
||||
*/
|
||||
,draw: function (enable) {
|
||||
if (typeof enable === 'undefined') {
|
||||
var enable = true;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
this._draw.enable();
|
||||
} else {
|
||||
this._draw.disable();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable routing
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo check enable
|
||||
*/
|
||||
,routing: function (enable) {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable snapping
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @todo check enable
|
||||
*/
|
||||
,snapping: function (enable) {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* Key up listener
|
||||
*
|
||||
* * `ESC` to cancel drawing
|
||||
* * `M` to enable drawing
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
,_keyupListener: function (e) {
|
||||
if (e.keyCode === 27) {
|
||||
this._draw.disable();
|
||||
} else if (e.keyCode === 77) {
|
||||
this._draw.enable();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
186
bower_components/leaflet-routing/src/utils/LineUtil.Snapping.js
vendored
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
L.Util.extend(L.LineUtil, {
|
||||
|
||||
/**
|
||||
* Snap to all layers
|
||||
*
|
||||
* @param <Latlng> latlng - original position
|
||||
* @param <Number> id - leaflet unique id
|
||||
* @param <Object> opts - snapping options
|
||||
*
|
||||
* @return <Latlng> closest point
|
||||
*/
|
||||
snapToLayers: function (latlng, id, opts) {
|
||||
var i, j, keys, feature, res, sensitivity, vertexonly, layers, minDist, minPoint, map;
|
||||
|
||||
sensitivity = opts.sensitivity || 10;
|
||||
vertexonly = opts.vertexonly || false;
|
||||
layers = opts.layers || [];
|
||||
minDist = Infinity;
|
||||
minPoint = latlng;
|
||||
minPoint._feature = null; // containing layer
|
||||
map = opts.layers[0]._map; // @todo check for undef
|
||||
|
||||
for (i = 0; i < opts.layers.length; i++) {
|
||||
keys = Object.keys(opts.layers[i]._layers);
|
||||
for (j = 0; j < keys.length; j++) {
|
||||
feature = opts.layers[i]._layers[keys[j]];
|
||||
|
||||
// Don't even try snapping to itself!
|
||||
if (id === feature._leaflet_id) { continue; }
|
||||
|
||||
// GeometryCollection
|
||||
if (feature._layers) {
|
||||
var newLatlng = this.snapToLayers(latlng, id, {
|
||||
'sensitivity': sensitivity,
|
||||
'vertexonly': vertexonly,
|
||||
'layers': [feature]
|
||||
});
|
||||
// What if this is the same?
|
||||
res = {'minDist': latlng.distanceTo(newLatlng), 'minPoint': newLatlng};
|
||||
|
||||
// Marker
|
||||
} else if (feature instanceof L.Marker) {
|
||||
res = this._snapToLatlngs(latlng, [feature.getLatLng()], map, sensitivity, vertexonly, minDist);
|
||||
|
||||
// Polyline
|
||||
} else if (feature instanceof L.Polyline) {
|
||||
res = this._snapToLatlngs(latlng, feature.getLatLngs(), map, sensitivity, vertexonly, minDist);
|
||||
|
||||
// MultiPolyline
|
||||
} else if (feature instanceof L.MultiPolyline) {
|
||||
console.error('Snapping to MultiPolyline is currently unsupported', feature);
|
||||
res = {'minDist': minDist, 'minPoint': minPoint};
|
||||
|
||||
// Polygon
|
||||
} else if (feature instanceof L.Polygon) {
|
||||
res = this._snapToPolygon(latlng, feature, map, sensitivity, vertexonly, minDist);
|
||||
|
||||
// MultiPolygon
|
||||
} else if (feature instanceof L.MultiPolygon) {
|
||||
res = this._snapToMultiPolygon(latlng, feature, map, sensitivity, vertexonly, minDist);
|
||||
|
||||
// Unknown
|
||||
} else {
|
||||
console.error('Unsupported snapping feature', feature);
|
||||
res = {'minDist': minDist, 'minPoint': minPoint};
|
||||
}
|
||||
|
||||
if (res.minDist < minDist) {
|
||||
minDist = res.minDist;
|
||||
minPoint = res.minPoint;
|
||||
minPoint._feature = feature;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return minPoint;
|
||||
},
|
||||
|
||||
/**
|
||||
* Snap to Polygon
|
||||
*
|
||||
* @param <Latlng> latlng - original position
|
||||
* @param <L.Polygon> feature -
|
||||
* @param <L.Map> map -
|
||||
* @param <Number> sensitivity -
|
||||
* @param <Boolean> vertexonly -
|
||||
* @param <Number> minDist -
|
||||
*
|
||||
* @return <Object> minDist and minPoint
|
||||
*/
|
||||
_snapToPolygon: function (latlng, polygon, map, sensitivity, vertexonly, minDist) {
|
||||
var res, keys, latlngs, i, minPoint;
|
||||
|
||||
minPoint = null;
|
||||
|
||||
latlngs = polygon.getLatLngs();
|
||||
latlngs.push(latlngs[0]);
|
||||
res = this._snapToLatlngs(latlng, polygon.getLatLngs(), map, sensitivity, vertexonly, minDist);
|
||||
if (res.minDist < minDist) {
|
||||
minDist = res.minDist;
|
||||
minPoint = res.minPoint;
|
||||
}
|
||||
|
||||
keys = Object.keys(polygon._holes);
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
latlngs = polygon._holes[keys[i]];
|
||||
latlngs.push(latlngs[0]);
|
||||
res = this._snapToLatlngs(latlng, polygon._holes[keys[i]], map, sensitivity, vertexonly, minDist);
|
||||
if (res.minDist < minDist) {
|
||||
minDist = res.minDist;
|
||||
minPoint = res.minPoint;
|
||||
}
|
||||
}
|
||||
|
||||
return {'minDist': minDist, 'minPoint': minPoint};
|
||||
},
|
||||
|
||||
/**
|
||||
* Snap to MultiPolygon
|
||||
*
|
||||
* @param <Latlng> latlng - original position
|
||||
* @param <L.Polygon> feature -
|
||||
* @param <L.Map> map -
|
||||
* @param <Number> sensitivity -
|
||||
* @param <Boolean> vertexonly -
|
||||
* @param <Number> minDist -
|
||||
*
|
||||
* @return <Object> minDist and minPoint
|
||||
*/
|
||||
_snapToMultiPolygon: function (latlng, multipolygon, map, sensitivity, vertexonly, minDist) {
|
||||
var i, keys, res, minPoint;
|
||||
|
||||
minPoint = null;
|
||||
|
||||
keys = Object.keys(multipolygon._layers);
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
res = this._snapToPolygon(latlng, multipolygon._layers[keys[i]], map, sensitivity, vertexonly, minDist);
|
||||
|
||||
if (res.minDist < minDist) {
|
||||
minDist = res.minDist;
|
||||
minPoint = res.minPoint;
|
||||
}
|
||||
}
|
||||
|
||||
return {'minDist': minDist, 'minPoint': minPoint};
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Snap to <Array> of <Latlang>
|
||||
*
|
||||
* @param <LatLng> latlng - cursor click
|
||||
* @param <Array> latlngs - array of <L.LatLngs> to snap to
|
||||
* @param <Object> opts - snapping options
|
||||
* @param <Boolean> isPolygon - if feature is a polygon
|
||||
*
|
||||
* @return <Object> minDist and minPoint
|
||||
*/
|
||||
_snapToLatlngs: function (latlng, latlngs, map, sensitivity, vertexonly, minDist) {
|
||||
var i, tmpDist, minPoint, p, p1, p2, d2;
|
||||
|
||||
p = map.latLngToLayerPoint(latlng);
|
||||
p1 = minPoint = null;
|
||||
|
||||
for (i = 0; i < latlngs.length; i++) {
|
||||
p2 = map.latLngToLayerPoint(latlngs[i]);
|
||||
|
||||
if (!vertexonly && p1 !== null) {
|
||||
tmpDist = L.LineUtil.pointToSegmentDistance(p, p1, p2);
|
||||
if (tmpDist < minDist && tmpDist <= sensitivity) {
|
||||
minDist = tmpDist;
|
||||
minPoint = map.layerPointToLatLng(L.LineUtil.closestPointOnSegment(p, p1, p2));
|
||||
}
|
||||
} else if ((d2 = p.distanceTo(p2)) && d2 <= sensitivity && d2 < minDist) {
|
||||
minDist = d2;
|
||||
minPoint = latlngs[i];
|
||||
}
|
||||
|
||||
p1 = p2;
|
||||
}
|
||||
|
||||
return {'minDist': minDist, 'minPoint': minPoint};
|
||||
}
|
||||
|
||||
});
|
||||
12
bower_components/leaflet-routing/src/utils/Marker.Snapping.js
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
L.Marker.include({
|
||||
/**
|
||||
* Snap to function
|
||||
*
|
||||
* @param <LatLng> latlng - original position
|
||||
*
|
||||
* @return <LatLng> - new position
|
||||
*/
|
||||
snapTo: function (latlng) {
|
||||
return L.LineUtil.snapToLayers(latlng, this._leaflet_id, this.options.snapping);
|
||||
}
|
||||
});
|
||||
12
bower_components/leaflet-routing/src/utils/Polyline.Snapping.js
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
L.Polyline.include({
|
||||
/**
|
||||
* Snap to function
|
||||
*
|
||||
* @param <LatLng> latlng - original position
|
||||
*
|
||||
* @return <LatLng> - new position
|
||||
*/
|
||||
snapTo: function (latlng) {
|
||||
return L.LineUtil.snapToLayers(latlng, this._leaflet_id, this.options.snapping);
|
||||
}
|
||||
});
|
||||
22
bower_components/leaflet-search/.bower.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "leaflet-search",
|
||||
"version": "1.4.7",
|
||||
"main": "leaflet-search.js",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"components",
|
||||
"bower_components",
|
||||
"examples"
|
||||
],
|
||||
"homepage": "https://github.com/stefanocudini/leaflet-search",
|
||||
"_release": "1.4.7",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.4.7",
|
||||
"commit": "411f216e1f407da9ef61047832b227c19ed47fab"
|
||||
},
|
||||
"_source": "git://github.com/stefanocudini/leaflet-search.git",
|
||||
"_target": "*",
|
||||
"_originalSource": "leaflet-search"
|
||||
}
|
||||
12
bower_components/leaflet-search/BUGS
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
. option condition problem {autoCollapse: true, markerLocation: true} not show location, row 61
|
||||
|
||||
. option condition problem {autoCollapse:false }, row 62
|
||||
|
||||
. problem with jsonp/ajax when remote filter has different behavior of this._filterRecords, row 322
|
||||
|
||||
. _handleAutoresize Should resize max search box size when map is resized., row 616
|
||||
|
||||
. if collapse in _handleSubmit hide _markerLoc!, row 684
|
||||
|
||||
. autoCollapse option hide this._markerLoc before that visualized!!, row 714
|
||||
|
||||
115
bower_components/leaflet-search/Gruntfile.js
vendored
Executable file
|
|
@ -0,0 +1,115 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = function(grunt) {
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-todos');
|
||||
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
meta: {
|
||||
banner:
|
||||
'/* \n'+
|
||||
' * Leaflet Search Control v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %> \n'+
|
||||
' * \n'+
|
||||
' * Copyright 2014 <%= pkg.author.name %> \n'+
|
||||
' * <%= pkg.author.email %> \n'+
|
||||
' * <%= pkg.author.url %> \n'+
|
||||
' * \n'+
|
||||
' * Licensed under the <%= pkg.license %> license. \n'+
|
||||
' * \n'+
|
||||
' * Demo: \n'+
|
||||
' * <%= pkg.homepage %> \n'+
|
||||
' * \n'+
|
||||
' * Source: \n'+
|
||||
' * <%= pkg.repository.url %> \n'+
|
||||
' * \n'+
|
||||
' */\n'
|
||||
},
|
||||
clean: {
|
||||
dist: {
|
||||
src: ['dist/*']
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
options: {
|
||||
globals: {
|
||||
console: true,
|
||||
module: true
|
||||
},
|
||||
"-W099": true, //ignora tabs e space warning
|
||||
"-W033": true,
|
||||
"-W044": true //ignore regexp
|
||||
},
|
||||
files: ['src/*.js']
|
||||
},
|
||||
concat: {
|
||||
//TODO cut out SearchMarker
|
||||
options: {
|
||||
banner: '<%= meta.banner %>'
|
||||
},
|
||||
dist: {
|
||||
files: {
|
||||
'dist/leaflet-search.src.js': ['src/leaflet-search.js'],
|
||||
'dist/leaflet-search.src.css': ['src/leaflet-search.css'],
|
||||
'dist/leaflet-search.mobile.src.css': ['src/leaflet-search.mobile.css']
|
||||
}
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
options: {
|
||||
banner: '<%= meta.banner %>'
|
||||
},
|
||||
dist: {
|
||||
files: {
|
||||
'dist/leaflet-search.min.js': ['dist/leaflet-search.src.js']
|
||||
}
|
||||
}
|
||||
},
|
||||
cssmin: {
|
||||
combine: {
|
||||
files: {
|
||||
'dist/leaflet-search.min.css': ['src/leaflet-search.css'],
|
||||
'dist/leaflet-search.mobile.min.css': ['src/leaflet-search.mobile.css']
|
||||
}
|
||||
},
|
||||
options: {
|
||||
banner: '<%= meta.banner %>'
|
||||
},
|
||||
minify: {
|
||||
expand: true,
|
||||
cwd: 'dist/',
|
||||
files: {
|
||||
'dist/leaflet-search.min.css': ['src/leaflet-search.css'],
|
||||
'dist/leaflet-search.mobile.min.css': ['src/leaflet-search.mobile.css']
|
||||
}
|
||||
}
|
||||
},
|
||||
todos: {
|
||||
options: { verbose: false },
|
||||
TODO: ['src/*.js'],
|
||||
},
|
||||
watch: {
|
||||
dist: {
|
||||
options: { livereload: true },
|
||||
files: ['src/*'],
|
||||
tasks: ['clean','concat','cssmin','jshint']
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.registerTask('default', [
|
||||
'clean',
|
||||
'concat',
|
||||
'cssmin',
|
||||
'jshint',
|
||||
'uglify',
|
||||
'todos'
|
||||
]);
|
||||
|
||||
};
|
||||
21
bower_components/leaflet-search/LICENSE.txt
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Stefano Cudini
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
65
bower_components/leaflet-search/README.md
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
Leaflet.Control.Search
|
||||
============
|
||||
|
||||
#What
|
||||
A leaflet control that search markers/features location by cutstom property.
|
||||
With ajax/jsonp autocompletion and json fields re-mapping
|
||||
|
||||
Tested in Leaflet 0.6.4
|
||||
|
||||
|
||||
#Where
|
||||
|
||||
**Demos:**
|
||||
[labs.easyblog.it/maps/leaflet-search](http://labs.easyblog.it/maps/leaflet-search/)
|
||||
|
||||
**Source code:**
|
||||
[Github](https://github.com/stefanocudini/leaflet-search)
|
||||
[Bitbucket](https://bitbucket.org/zakis_/leaflet-search)
|
||||
[NPM](https://npmjs.org/package/leaflet-search)
|
||||
[Atmosphere](https://atmosphere.meteor.com/package/leaflet-search)
|
||||
|
||||
#How
|
||||
Insert leaflet-search.css styles to your css page
|
||||
|
||||
Adding the search control to the map:
|
||||
|
||||
```
|
||||
map.addControl( new L.Control.Search({layer: searchLayer}) );
|
||||
//searchLayer if a L.LayerGroup contains searched markers
|
||||
```
|
||||
short way:
|
||||
```
|
||||
var map = new L.Map('map', { searchControl: {layer: searchLayer} });
|
||||
```
|
||||
|
||||
other examples:
|
||||
```
|
||||
//ajax request to search.php for retrieve elements locations
|
||||
map.addControl( new L.Control.Search({url: 'search.php?q={s}'}) );
|
||||
|
||||
|
||||
//jsonp request to 3rd party service, implements Geocode Searching using OSM API
|
||||
map.addControl( new L.Control.Search({
|
||||
url: 'http://nominatim.openstreetmap.org/search?format=json&q={s}',
|
||||
jsonpParam: 'json_callback',
|
||||
propertyName: 'display_name',
|
||||
propertyLoc: ['lat','lon']
|
||||
}) );
|
||||
|
||||
|
||||
//geojson layer, search and color feature vector
|
||||
var searchControl = new L.Control.Search({layer: geojsonLayer, circleLocation:false});
|
||||
searchControl.on('search_locationfound', function(e) {
|
||||
|
||||
e.layer.setStyle({fillColor: '#3f0'});
|
||||
|
||||
}).on('search_collapsed', function(e) {
|
||||
|
||||
featuresLayer.eachLayer(function(layer) {
|
||||
featuresLayer.resetStyle(layer);
|
||||
});
|
||||
});
|
||||
map.addControl(searchControl);
|
||||
```
|
||||
|
||||
27
bower_components/leaflet-search/TODO
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
Tasks found in: src/leaflet-search.js
|
||||
[Line: 22] [low] //TODO important! implements uniq option 'sourceData' that recognizes source type: url,array,callback or layer
|
||||
[Line: 23] [low] //TODO implement can do research on multiple sources
|
||||
[Line: 26] [low] //TODO implement sub property filter for propertyName,propertyLoc like this: "prop.subprop.title"
|
||||
[Line: 37] [low] //TODO add option for persist markerLoc after collapse!
|
||||
[Line: 47] [low] //TODO add option collapsed, like control.layers
|
||||
[Line: 296] [low] //TODO add option for case sesitive search, also showLocation
|
||||
[Line: 299] [low] //TODO use .filter or .map
|
||||
[Line: 361] [low] //TODO verify json[n].hasOwnProperty(propName)
|
||||
[Line: 367] [low] //TODO remove script node after call run
|
||||
[Line: 376] [low] //TODO add rnd param or randomize callback name! in recordsFromJsonp
|
||||
[Line: 396] [low] //TODO add rnd param or randomize callback name! in recordsFromAjax
|
||||
[Line: 458] [low] //TODO implements autype without selection(useful for mobile device)
|
||||
[Line: 558] [low] //TODO important optimization!!! always append data in this._recordsCache
|
||||
[Line: 562] [low] //TODO here insert function that search inputText FIRST in _recordsCache keys and if not find results..
|
||||
[Line: 565] [low] //TODO change structure of _recordsCache
|
||||
[Line: 616] [low] //TODO refact _handleAutoresize now is not accurate
|
||||
[Line: 712] [low] //TODO showLocation: start animation after setView or panTo, maybe with map.on('moveend')...
|
||||
[Line: 733] [low] //TODO add custom icon!
|
||||
[Line: 741] [low] //TODO add inner circle
|
||||
[Line: 797] [low] //TODO refact animate() more smooth! like this: http://goo.gl/DDlRs
|
||||
[Line: 819] [low] //TODO use create event 'animateEnd' in SearchMarker
|
||||
[Line: 49] [med] //FIXME option condition problem {autoCollapse: true, markerLocation: true} not show location
|
||||
[Line: 50] [med] //FIXME option condition problem {autoCollapse: false }
|
||||
[Line: 312] [med] //FIXME problem with jsonp/ajax when remote filter has different behavior of this._filterRecords
|
||||
[Line: 685] [med] //FIXME if collapse in _handleSubmit hide _markerLoc!
|
||||
[Line: 715] [med] //FIXME autoCollapse option hide this._markerLoc before that visualized!!
|
||||
12
bower_components/leaflet-search/bower.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "leaflet-search",
|
||||
"version": "1.4.6",
|
||||
"main": "leaflet-search.js",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"components",
|
||||
"bower_components",
|
||||
"examples"
|
||||
]
|
||||
}
|
||||
18
bower_components/leaflet-search/dist/leaflet-search.min.css
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Leaflet Search Control v1.4.7 - 2014-01-04
|
||||
*
|
||||
* Copyright 2014 Stefano Cudini
|
||||
* stefano.cudini@gmail.com
|
||||
* http://labs.easyblog.it/
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
*
|
||||
* Demo:
|
||||
* http://labs.easyblog.it/maps/leaflet-search/
|
||||
*
|
||||
* Source:
|
||||
* git@github.com:stefanocudini/leaflet-search.git
|
||||
*
|
||||
*/
|
||||
|
||||
.leaflet-container .leaflet-control-search{position:relative;float:left;background:#fff;color:#1978cf;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;background-color:rgba(255,255,255,.8);z-index:1000;box-shadow:0 1px 7px rgba(0,0,0,.65);margin-left:10px;margin-top:10px}.leaflet-control-search.search-exp{box-shadow:0 1px 7px #999;background:#fff}.leaflet-control-search .search-input{display:block;float:left;background:#fff;border:1px solid #666;border-radius:2px;height:18px;padding:0 18px 0 2px;margin:3px 0 3px 3px}.leaflet-control-search.search-load .search-input{background:url(../images/loader.gif) no-repeat center right #fff}.leaflet-control-search.search-load .search-cancel{visibility:hidden}.leaflet-control-search .search-cancel{display:block;width:22px;height:18px;position:absolute;right:22px;margin:3px 0;background:url(../images/search-icon.png) no-repeat 0 -46px;text-decoration:none;filter:alpha(opacity=80);opacity:.8}.leaflet-control-search .search-cancel:hover{filter:alpha(opacity=100);opacity:1}.leaflet-control-search .search-cancel span{display:none;font-size:18px;line-height:20px;color:#ccc;font-weight:700}.leaflet-control-search .search-cancel:hover span{color:#aaa}.leaflet-control-search .search-button{display:block;float:left;width:26px;height:26px;background:url(../images/search-icon.png) no-repeat 2px 2px;border-radius:4px}.leaflet-control-search .search-button:hover{background:url(../images/search-icon.png) no-repeat 2px -22px}.leaflet-control-search .search-tooltip{position:absolute;top:100%;left:0;float:left;min-width:80px;max-height:106px;box-shadow:0 0 8px rgba(0,0,0,.4);-webkit-border-radius:5px;-webkit-border-top-left-radius:0;-moz-border-radius:5px;-moz-border-radius-topleft:0;border-radius:5px;border-top-left-radius:0;background-color:rgba(0,0,0,.25);z-index:1010;overflow-y:auto;overflow-x:hidden}.leaflet-control-search .search-tip{margin:2px;padding:2px;display:block;color:#000;background:#ddd;border-radius:.25em;text-decoration:none;white-space:nowrap;font-size:.85em;vertical-align:center}.leaflet-control-search .search-button:hover,.leaflet-control-search .search-tip-select,.leaflet-control-search .search-tip:hover{background-color:#fff}.leaflet-control-search .search-alert{cursor:pointer;clear:both;font-size:.75em;margin-bottom:5px;padding:0 .25em;color:#e00;font-weight:700;border-radius:.25em}
|
||||
17
bower_components/leaflet-search/dist/leaflet-search.min.js
vendored
Normal file
18
bower_components/leaflet-search/dist/leaflet-search.mobile.min.css
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Leaflet Search Control v1.4.7 - 2014-01-04
|
||||
*
|
||||
* Copyright 2014 Stefano Cudini
|
||||
* stefano.cudini@gmail.com
|
||||
* http://labs.easyblog.it/
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
*
|
||||
* Demo:
|
||||
* http://labs.easyblog.it/maps/leaflet-search/
|
||||
*
|
||||
* Source:
|
||||
* git@github.com:stefanocudini/leaflet-search.git
|
||||
*
|
||||
*/
|
||||
|
||||
.leaflet-control.leaflet-control-search{z-index:2000}.leaflet-control-search .search-input{display:block;float:left;background:#fff;border:1px solid #666;border-radius:2px;height:24px;font-size:1.25em;padding:0 .125em;margin:3px;padding-right:30px}.leaflet-control-search .search-button,.leaflet-control-search .search-button:hover{background-image:url(../images/search-icon-mobile.png);-webkit-border-radius:4px;border-radius:4px;background-position:1px 1px;width:32px;height:32px}.leaflet-control-search.search-load .search-input{background:url(../images/loader.gif) no-repeat center right #fff}.leaflet-control-search .search-cancel{background-image:url(../images/search-icon-mobile.png);-webkit-border-radius:4px;border-radius:4px;background-position:0 -62px;width:26px;height:26px;right:34px;margin:3px}.leaflet-control-search .search-tooltip{max-height:142px}.leaflet-control-search .search-tip{font-size:1em;margin:2px;padding:2px;display:block;color:#000;background:rgba(255,255,255,.8);border-radius:.25em;text-decoration:none;white-space:nowrap;vertical-align:center}.leaflet-control-search .search-tip .climbo-icon-mini{float:right;display:block;white-space:nowrap}.leaflet-control-search .search-button:hover,.leaflet-control-search .search-tip-select,.leaflet-control-search .search-tip:hover{background-color:#fff}.leaflet-control-search .search-alert{font-size:1.2em}
|
||||
83
bower_components/leaflet-search/dist/leaflet-search.mobile.src.css
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Leaflet Search Control v1.4.7 - 2014-01-04
|
||||
*
|
||||
* Copyright 2014 Stefano Cudini
|
||||
* stefano.cudini@gmail.com
|
||||
* http://labs.easyblog.it/
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
*
|
||||
* Demo:
|
||||
* http://labs.easyblog.it/maps/leaflet-search/
|
||||
*
|
||||
* Source:
|
||||
* git@github.com:stefanocudini/leaflet-search.git
|
||||
*
|
||||
*/
|
||||
|
||||
/* SEARCH */
|
||||
.leaflet-control.leaflet-control-search {
|
||||
z-index:2000;
|
||||
}
|
||||
.leaflet-control-search .search-input {
|
||||
display:block;
|
||||
float:left;
|
||||
background: #fff;
|
||||
border:1px solid #666;
|
||||
border-radius:2px;
|
||||
height:24px;
|
||||
font-size:1.25em;
|
||||
padding:0 .125em;
|
||||
margin:3px;
|
||||
padding-right:30px;
|
||||
}
|
||||
.leaflet-control-search .search-button:hover,
|
||||
.leaflet-control-search .search-button {
|
||||
background-image: url('../images/search-icon-mobile.png');
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
background-position: 1px 1px;
|
||||
width:32px;
|
||||
height:32px;
|
||||
}
|
||||
.leaflet-control-search.search-load .search-input {
|
||||
background: url('../images/loader.gif') no-repeat center right #fff;
|
||||
}
|
||||
.leaflet-control-search .search-cancel {
|
||||
background-image: url('../images/search-icon-mobile.png');
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
background-position: 0px -62px;
|
||||
width:26px;
|
||||
height:26px;
|
||||
right:34px;
|
||||
margin:3px;
|
||||
}
|
||||
.leaflet-control-search .search-tooltip {
|
||||
max-height:142px;/*(.search-tip height * 5)*/
|
||||
}
|
||||
.leaflet-control-search .search-tip {
|
||||
font-size:1em;
|
||||
margin:2px;
|
||||
padding:2px;
|
||||
display:block;
|
||||
color:black;
|
||||
background: rgba(255,255,255,0.8);
|
||||
border-radius:.25em;
|
||||
text-decoration:none;
|
||||
white-space:nowrap;
|
||||
vertical-align:center;
|
||||
}
|
||||
.leaflet-control-search .search-tip .climbo-icon-mini {
|
||||
float:right;
|
||||
display:block;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.leaflet-control-search .search-button:hover,
|
||||
.leaflet-control-search .search-tip-select,
|
||||
.leaflet-control-search .search-tip:hover {
|
||||
background-color: #fff;
|
||||
}
|
||||
.leaflet-control-search .search-alert {
|
||||
font-size:1.2em;
|
||||
}
|
||||
137
bower_components/leaflet-search/dist/leaflet-search.src.css
vendored
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Leaflet Search Control v1.4.7 - 2014-01-04
|
||||
*
|
||||
* Copyright 2014 Stefano Cudini
|
||||
* stefano.cudini@gmail.com
|
||||
* http://labs.easyblog.it/
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
*
|
||||
* Demo:
|
||||
* http://labs.easyblog.it/maps/leaflet-search/
|
||||
*
|
||||
* Source:
|
||||
* git@github.com:stefanocudini/leaflet-search.git
|
||||
*
|
||||
*/
|
||||
|
||||
.leaflet-container .leaflet-control-search {
|
||||
position:relative;
|
||||
float:left;
|
||||
background:#fff;
|
||||
color:#1978cf;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
z-index:1000;
|
||||
box-shadow: 0 1px 7px rgba(0,0,0,0.65);
|
||||
margin-left: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-control-search.search-exp {/*expanded*/
|
||||
box-shadow: 0 1px 7px #999;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-search .search-input {
|
||||
display:block;
|
||||
float:left;
|
||||
background: #fff;
|
||||
border:1px solid #666;
|
||||
border-radius:2px;
|
||||
height:18px;
|
||||
padding:0 18px 0 2px;
|
||||
margin:3px 0 3px 3px;
|
||||
}
|
||||
.leaflet-control-search.search-load .search-input {
|
||||
background: url('../images/loader.gif') no-repeat center right #fff;
|
||||
}
|
||||
.leaflet-control-search.search-load .search-cancel {
|
||||
visibility:hidden;
|
||||
}
|
||||
.leaflet-control-search .search-cancel {
|
||||
display:block;
|
||||
width:22px;
|
||||
height:18px;
|
||||
position:absolute;
|
||||
right:22px;
|
||||
margin:3px 0;
|
||||
background: url('../images/search-icon.png') no-repeat 0 -46px;
|
||||
text-decoration:none;
|
||||
filter: alpha(opacity=80);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.leaflet-control-search .search-cancel:hover {
|
||||
filter: alpha(opacity=100);
|
||||
opacity: 1;
|
||||
}
|
||||
.leaflet-control-search .search-cancel span {
|
||||
display:none;/* comment for cancel button imageless */
|
||||
font-size:18px;
|
||||
line-height:20px;
|
||||
color:#ccc;
|
||||
font-weight:bold;
|
||||
}
|
||||
.leaflet-control-search .search-cancel:hover span {
|
||||
color:#aaa;
|
||||
}
|
||||
.leaflet-control-search .search-button {
|
||||
display:block;
|
||||
float:left;
|
||||
width:26px;
|
||||
height:26px;
|
||||
background: url('../images/search-icon.png') no-repeat 2px 2px;
|
||||
border-radius:4px;
|
||||
}
|
||||
.leaflet-control-search .search-button:hover {
|
||||
background: url('../images/search-icon.png') no-repeat 2px -22px;
|
||||
}
|
||||
.leaflet-control-search .search-tooltip {
|
||||
position:absolute;
|
||||
top:100%;
|
||||
left:0;
|
||||
float:left;
|
||||
min-width:80px;
|
||||
max-height:106px;/*(.search-tip height * 5)*/
|
||||
box-shadow: 0 0 8px rgba(0,0,0,0.4);
|
||||
-webkit-border-radius: 5px;
|
||||
-webkit-border-top-left-radius: 0;
|
||||
-moz-border-radius: 5px;
|
||||
-moz-border-radius-topleft: 0;
|
||||
border-radius: 5px;
|
||||
border-top-left-radius: 0;
|
||||
background-color: rgba(0, 0, 0, 0.25);
|
||||
z-index:1010;
|
||||
overflow-y:auto;
|
||||
overflow-x:hidden;
|
||||
}
|
||||
.leaflet-control-search .search-tip {
|
||||
font-size:.85em;
|
||||
margin:2px;
|
||||
padding:2px;
|
||||
display:block;
|
||||
color:black;
|
||||
background: #ddd;
|
||||
border-radius:.25em;
|
||||
text-decoration:none;
|
||||
white-space:nowrap;
|
||||
font-size:.85em;
|
||||
vertical-align:center;
|
||||
}
|
||||
.leaflet-control-search .search-tip-select,
|
||||
.leaflet-control-search .search-tip:hover,
|
||||
.leaflet-control-search .search-button:hover {
|
||||
background-color: #fff;
|
||||
}
|
||||
.leaflet-control-search .search-alert {
|
||||
cursor:pointer;
|
||||
clear:both;
|
||||
font-size:.75em;
|
||||
margin-bottom:5px;
|
||||
padding:0 .25em;
|
||||
color:#e00;
|
||||
font-weight:bold;
|
||||
border-radius:.25em;
|
||||
}
|
||||
|
||||
|
||||
855
bower_components/leaflet-search/dist/leaflet-search.src.js
vendored
Normal file
|
|
@ -0,0 +1,855 @@
|
|||
/*
|
||||
* Leaflet Search Control v1.4.7 - 2014-01-04
|
||||
*
|
||||
* Copyright 2014 Stefano Cudini
|
||||
* stefano.cudini@gmail.com
|
||||
* http://labs.easyblog.it/
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
*
|
||||
* Demo:
|
||||
* http://labs.easyblog.it/maps/leaflet-search/
|
||||
*
|
||||
* Source:
|
||||
* git@github.com:stefanocudini/leaflet-search.git
|
||||
*
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
L.Control.Search = L.Control.extend({
|
||||
includes: L.Mixin.Events,
|
||||
//
|
||||
// Name Data passed Description
|
||||
//
|
||||
//Managed Events:
|
||||
// search_locationfound {latlng, title} fired after moved and show markerLocation
|
||||
// search_collapsed {} fired after control was collapsed
|
||||
//
|
||||
//Public methods:
|
||||
// setLayer() L.LayerGroup() set layer search at runtime
|
||||
// showAlert() 'Text message' Show alert message
|
||||
//
|
||||
options: {
|
||||
url: '', //url for search by ajax request, ex: "search.php?q={s}"
|
||||
jsonpParam: null, //jsonp param name for search by jsonp service, ex: "callback"
|
||||
layer: null, //layer where search markers(is a L.LayerGroup)
|
||||
callData: null, //function that fill _recordsCache, passed searching text by first param and callback in second
|
||||
//TODO important! implements uniq option 'sourceData' that recognizes source type: url,array,callback or layer
|
||||
//TODO implement can do research on multiple sources
|
||||
propertyName: 'title', //property in marker.options(or feature.properties for vector layer) trough filter elements in layer
|
||||
propertyLoc: 'loc', //field name for remapping location, using array: ['latname','lonname'] for select double fields(ex. ['lat','lon'] )
|
||||
//TODO implement sub property filter for propertyName,propertyLoc like this: "prop.subprop.title"
|
||||
callTip: null, //function that return row tip html node(or html string), receive text tooltip in first param
|
||||
filterJSON: null, //callback for filtering data to _recordsCache
|
||||
minLength: 1, //minimal text length for autocomplete
|
||||
initial: true, //search elements only by initial text
|
||||
autoType: true, //complete input with first suggested result and select this filled-in text.
|
||||
delayType: 400, //delay while typing for show tooltip
|
||||
tooltipLimit: -1, //limit max results to show in tooltip. -1 for no limit.
|
||||
tipAutoSubmit: true, //auto map panTo when click on tooltip
|
||||
autoResize: true, //autoresize on input change
|
||||
autoCollapse: false, //collapse search control after submit(on button or on tips if enabled tipAutoSubmit)
|
||||
//TODO add option for persist markerLoc after collapse!
|
||||
autoCollapseTime: 1200, //delay for autoclosing alert and collapse after blur
|
||||
animateLocation: true, //animate a circle over location found
|
||||
circleLocation: true, //draw a circle in location found
|
||||
markerLocation: false, //draw a marker in location found
|
||||
zoom: null, //zoom after pan to location found, default: map.getZoom()
|
||||
text: 'Search...', //placeholder value
|
||||
textCancel: 'Cancel', //title in cancel button
|
||||
textErr: 'Location not found', //error message
|
||||
position: 'topleft'
|
||||
//TODO add option collapsed, like control.layers
|
||||
},
|
||||
//FIXME option condition problem {autoCollapse: true, markerLocation: true} not show location
|
||||
//FIXME option condition problem {autoCollapse: false }
|
||||
|
||||
initialize: function(options) {
|
||||
L.Util.setOptions(this, options || {});
|
||||
this._inputMinSize = this.options.text ? this.options.text.length : 10;
|
||||
this._layer = this.options.layer || new L.LayerGroup();
|
||||
this._filterJSON = this.options.filterJSON || this._defaultFilterJSON;
|
||||
this._autoTypeTmp = this.options.autoType; //useful for disable autoType temporarily in delete/backspace keydown
|
||||
this._countertips = 0; //number of tips items
|
||||
this._recordsCache = {}; //key,value table! that store locations! format: key,latlng
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
this._map = map;
|
||||
this._container = L.DomUtil.create('div', 'leaflet-control-search');
|
||||
this._input = this._createInput(this.options.text, 'search-input');
|
||||
this._tooltip = this._createTooltip('search-tooltip');
|
||||
this._cancel = this._createCancel(this.options.textCancel, 'search-cancel');
|
||||
this._button = this._createButton(this.options.text, 'search-button');
|
||||
this._alert = this._createAlert('search-alert');
|
||||
|
||||
if(this.options.circleLocation || this.options.markerLocation)
|
||||
this._markerLoc = new SearchMarker([0,0], {marker: this.options.markerLocation});//see below
|
||||
|
||||
this.setLayer( this._layer );
|
||||
map.on({
|
||||
// 'layeradd': this._onLayerAddRemove,
|
||||
// 'layerremove': this._onLayerAddRemove
|
||||
'resize':this._handleAutoresize()
|
||||
}, this);
|
||||
return this._container;
|
||||
},
|
||||
|
||||
onRemove: function(map) {
|
||||
this._recordsCache = {};
|
||||
// map.off({
|
||||
// 'layeradd': this._onLayerAddRemove,
|
||||
// 'layerremove': this._onLayerAddRemove
|
||||
// }, this);
|
||||
},
|
||||
|
||||
// _onLayerAddRemove: function(e) {
|
||||
// //console.info('_onLayerAddRemove');
|
||||
// //without this, run setLayer also for each Markers!! to optimize!
|
||||
// if(e.layer instanceof L.LayerGroup)
|
||||
// if( L.stamp(e.layer) != L.stamp(this._layer) )
|
||||
// this.setLayer(e.layer);
|
||||
// },
|
||||
|
||||
setLayer: function(layer) { //set search layer at runtime
|
||||
//this.options.layer = layer; //setting this, run only this._recordsFromLayer()
|
||||
this._layer = layer;
|
||||
this._layer.addTo(this._map);
|
||||
if(this._markerLoc)
|
||||
this._layer.addLayer(this._markerLoc);
|
||||
return this;
|
||||
},
|
||||
|
||||
showAlert: function(text) {
|
||||
text = text || this.options.textErr;
|
||||
this._alert.style.display = 'block';
|
||||
this._alert.innerHTML = text;
|
||||
clearTimeout(this.timerAlert);
|
||||
var that = this;
|
||||
this.timerAlert = setTimeout(function() {
|
||||
that.hideAlert();
|
||||
},this.options.autoCollapseTime);
|
||||
return this;
|
||||
},
|
||||
|
||||
hideAlert: function() {
|
||||
this._alert.style.display = 'none';
|
||||
return this;
|
||||
},
|
||||
|
||||
cancel: function() {
|
||||
this._input.value = '';
|
||||
this._handleKeypress({keyCode:8});//simulate backspace keypress
|
||||
this._input.size = this._inputMinSize;
|
||||
this._input.focus();
|
||||
this._cancel.style.display = 'none';
|
||||
return this;
|
||||
},
|
||||
|
||||
expand: function() {
|
||||
this._input.style.display = 'block';
|
||||
L.DomUtil.addClass(this._container, 'search-exp');
|
||||
this._input.focus();
|
||||
this._map.on('dragstart', this.collapse, this);
|
||||
return this;
|
||||
},
|
||||
|
||||
collapse: function() {
|
||||
this._hideTooltip();
|
||||
this.cancel();
|
||||
this._alert.style.display = 'none';
|
||||
this._input.style.display = 'none';
|
||||
this._input.blur();
|
||||
this._cancel.style.display = 'none';
|
||||
L.DomUtil.removeClass(this._container, 'search-exp');
|
||||
//this._markerLoc.hide();//maybe unuseful
|
||||
this._map.off('dragstart', this.collapse, this);
|
||||
this.fire('search_collapsed');
|
||||
return this;
|
||||
},
|
||||
|
||||
collapseDelayed: function() { //collapse after delay, used on_input blur
|
||||
if (!this.options.autoCollapse) return this;
|
||||
var that = this;
|
||||
clearTimeout(this.timerCollapse);
|
||||
this.timerCollapse = setTimeout(function() {
|
||||
that.collapse();
|
||||
}, this.options.autoCollapseTime);
|
||||
return this;
|
||||
},
|
||||
|
||||
collapseDelayedStop: function() {
|
||||
clearTimeout(this.timerCollapse);
|
||||
return this;
|
||||
},
|
||||
|
||||
////start DOM creations
|
||||
_createAlert: function(className) {
|
||||
var alert = L.DomUtil.create('div', className, this._container);
|
||||
alert.style.display = 'none';
|
||||
|
||||
L.DomEvent
|
||||
.on(alert, 'click', L.DomEvent.stop, this)
|
||||
.on(alert, 'click', this.hideAlert, this);
|
||||
|
||||
return alert;
|
||||
},
|
||||
|
||||
_createInput: function (text, className) {
|
||||
var input = L.DomUtil.create('input', className, this._container);
|
||||
input.type = 'text';
|
||||
input.size = this._inputMinSize;
|
||||
input.value = '';
|
||||
input.autocomplete = 'off';
|
||||
input.placeholder = text;
|
||||
input.style.display = 'none';
|
||||
|
||||
L.DomEvent
|
||||
.disableClickPropagation(input)
|
||||
.on(input, 'keyup', this._handleKeypress, this)
|
||||
.on(input, 'keydown', this._handleAutoresize, this)
|
||||
.on(input, 'blur', this.collapseDelayed, this)
|
||||
.on(input, 'focus', this.collapseDelayedStop, this);
|
||||
|
||||
return input;
|
||||
},
|
||||
|
||||
_createCancel: function (title, className) {
|
||||
var cancel = L.DomUtil.create('a', className, this._container);
|
||||
cancel.href = '#';
|
||||
cancel.title = title;
|
||||
cancel.style.display = 'none';
|
||||
cancel.innerHTML = "<span>⊗</span>";//imageless(see css)
|
||||
|
||||
L.DomEvent
|
||||
.on(cancel, 'click', L.DomEvent.stop, this)
|
||||
.on(cancel, 'click', this.cancel, this);
|
||||
|
||||
return cancel;
|
||||
},
|
||||
|
||||
_createButton: function (title, className) {
|
||||
var button = L.DomUtil.create('a', className, this._container);
|
||||
button.href = '#';
|
||||
button.title = title;
|
||||
|
||||
L.DomEvent
|
||||
.on(button, 'click', L.DomEvent.stop, this)
|
||||
.on(button, 'click', this._handleSubmit, this)
|
||||
.on(button, 'focus', this.collapseDelayedStop, this)
|
||||
.on(button, 'blur', this.collapseDelayed, this);
|
||||
|
||||
return button;
|
||||
},
|
||||
|
||||
_createTooltip: function(className) {
|
||||
var tool = L.DomUtil.create('div', className, this._container);
|
||||
tool.style.display = 'none';
|
||||
|
||||
var that = this;
|
||||
L.DomEvent
|
||||
.disableClickPropagation(tool)
|
||||
.on(tool, 'blur', this.collapseDelayed, this)
|
||||
.on(tool, 'mousewheel', function(e) {
|
||||
that.collapseDelayedStop();
|
||||
L.DomEvent.stopPropagation(e);//disable zoom map
|
||||
}, this)
|
||||
.on(tool, 'mouseover', function(e) {
|
||||
that.collapseDelayedStop();
|
||||
}, this);
|
||||
return tool;
|
||||
},
|
||||
|
||||
_createTip: function(text, val) {//val is object in recordCache, usually is Latlng
|
||||
var tip;
|
||||
|
||||
if(this.options.callTip)
|
||||
{
|
||||
tip = this.options.callTip(text,val); //custom tip node or html string
|
||||
if(typeof tip === 'string')
|
||||
{
|
||||
var tmpNode = L.DomUtil.create('div');
|
||||
tmpNode.innerHTML = tip;
|
||||
tip = tmpNode.firstChild;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tip = L.DomUtil.create('a', '');
|
||||
tip.href = '#';
|
||||
tip.innerHTML = text;
|
||||
}
|
||||
|
||||
L.DomUtil.addClass(tip, 'search-tip');
|
||||
tip._text = text; //value replaced in this._input and used by _autoType
|
||||
|
||||
L.DomEvent
|
||||
.disableClickPropagation(tip)
|
||||
.on(tip, 'click', L.DomEvent.stop, this)
|
||||
.on(tip, 'click', function(e) {
|
||||
this._input.value = text;
|
||||
this._handleAutoresize();
|
||||
this._input.focus();
|
||||
this._hideTooltip();
|
||||
if(this.options.tipAutoSubmit)//go to location at once
|
||||
this._handleSubmit();
|
||||
}, this);
|
||||
|
||||
return tip;
|
||||
},
|
||||
|
||||
//////end DOM creations
|
||||
|
||||
_filterRecords: function(text) { //Filter this._recordsCache case insensitive and much more..
|
||||
|
||||
var regFilter = new RegExp("^[.]$|[\[\]|()*]",'g'), //remove . * | ( ) ] [
|
||||
I, regSearch,
|
||||
frecords = {};
|
||||
|
||||
text = text.replace(regFilter,''); //sanitize text
|
||||
I = this.options.initial ? '^' : ''; //search only initial text
|
||||
//TODO add option for case sesitive search, also showLocation
|
||||
regSearch = new RegExp(I + text,'i');
|
||||
|
||||
//TODO use .filter or .map
|
||||
for(var key in this._recordsCache)
|
||||
if( regSearch.test(key) )
|
||||
frecords[key]= this._recordsCache[key];
|
||||
|
||||
return frecords;
|
||||
},
|
||||
|
||||
showTooltip: function() {
|
||||
var filteredRecords, newTip;
|
||||
|
||||
this._countertips = 0;
|
||||
|
||||
//FIXME problem with jsonp/ajax when remote filter has different behavior of this._filterRecords
|
||||
if(this.options.layer)
|
||||
filteredRecords = this._filterRecords( this._input.value );
|
||||
else
|
||||
filteredRecords = this._recordsCache;
|
||||
|
||||
this._tooltip.innerHTML = '';
|
||||
this._tooltip.currentSelection = -1; //inizialized for _handleArrowSelect()
|
||||
|
||||
for(var key in filteredRecords)//fill tooltip
|
||||
{
|
||||
if(++this._countertips == this.options.tooltipLimit) break;
|
||||
|
||||
newTip = this._createTip(key, filteredRecords[key] );
|
||||
|
||||
this._tooltip.appendChild(newTip);
|
||||
}
|
||||
|
||||
if(this._countertips > 0)
|
||||
{
|
||||
this._tooltip.style.display = 'block';
|
||||
if(this._autoTypeTmp)
|
||||
this._autoType();
|
||||
this._autoTypeTmp = this.options.autoType;//reset default value
|
||||
}
|
||||
else
|
||||
this._hideTooltip();
|
||||
|
||||
this._tooltip.scrollTop = 0;
|
||||
return this._countertips;
|
||||
},
|
||||
|
||||
_hideTooltip: function() {
|
||||
this._tooltip.style.display = 'none';
|
||||
this._tooltip.innerHTML = '';
|
||||
return 0;
|
||||
},
|
||||
|
||||
_defaultFilterJSON: function(json) { //default callback for filter data
|
||||
var jsonret = {},
|
||||
propName = this.options.propertyName,
|
||||
propLoc = this.options.propertyLoc;
|
||||
|
||||
if( L.Util.isArray(propLoc) )
|
||||
for(var i in json)
|
||||
jsonret[ json[i][propName] ]= L.latLng( json[i][ propLoc[0] ], json[i][ propLoc[1] ] );
|
||||
else
|
||||
for(var n in json)
|
||||
jsonret[ json[n][propName] ]= L.latLng( json[n][ propLoc ] );
|
||||
//TODO verify json[n].hasOwnProperty(propName)
|
||||
//throw new Error("propertyName '"+propName+"' not found in JSON data");
|
||||
return jsonret;
|
||||
},
|
||||
|
||||
_recordsFromJsonp: function(text, callAfter) { //extract searched records from remote jsonp service
|
||||
//TODO remove script node after call run
|
||||
var that = this;
|
||||
L.Control.Search.callJsonp = function(data) { //jsonp callback
|
||||
var fdata = that._filterJSON(data);//_filterJSON defined in inizialize...
|
||||
callAfter(fdata);
|
||||
}
|
||||
var script = L.DomUtil.create('script','search-jsonp', document.getElementsByTagName('body')[0] ),
|
||||
url = L.Util.template(this.options.url+'&'+this.options.jsonpParam+'=L.Control.Search.callJsonp', {s: text}); //parsing url
|
||||
//rnd = '&_='+Math.floor(Math.random()*10000);
|
||||
//TODO add rnd param or randomize callback name! in recordsFromJsonp
|
||||
script.type = 'text/javascript';
|
||||
script.src = url;
|
||||
return this;
|
||||
//may be return {abort: function() { script.parentNode.removeChild(script); } };
|
||||
},
|
||||
|
||||
_recordsFromAjax: function(text, callAfter) { //Ajax request
|
||||
if (window.XMLHttpRequest === undefined) {
|
||||
window.XMLHttpRequest = function() {
|
||||
try { return new ActiveXObject("Microsoft.XMLHTTP.6.0"); }
|
||||
catch (e1) {
|
||||
try { return new ActiveXObject("Microsoft.XMLHTTP.3.0"); }
|
||||
catch (e2) { throw new Error("XMLHttpRequest is not supported"); }
|
||||
}
|
||||
};
|
||||
}
|
||||
var request = new XMLHttpRequest(),
|
||||
url = L.Util.template(this.options.url, {s: text}), //parsing url
|
||||
//rnd = '&_='+Math.floor(Math.random()*10000);
|
||||
//TODO add rnd param or randomize callback name! in recordsFromAjax
|
||||
response = {};
|
||||
|
||||
request.open("GET", url);
|
||||
var that = this;
|
||||
request.onreadystatechange = function() {
|
||||
if(request.readyState === 4 && request.status === 200) {
|
||||
response = JSON.parse(request.responseText);
|
||||
var fdata = that._filterJSON(response);//_filterJSON defined in inizialize...
|
||||
callAfter(fdata);
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
return this;
|
||||
},
|
||||
|
||||
_recordsFromLayer: function() { //return table: key,value from layer
|
||||
var retRecords = {},
|
||||
propName = this.options.propertyName,
|
||||
loc;
|
||||
|
||||
this._layer.eachLayer(function(layer) {
|
||||
|
||||
if(layer instanceof SearchMarker) return;
|
||||
|
||||
if(layer instanceof L.Marker)
|
||||
{
|
||||
if(layer.options.hasOwnProperty(propName))
|
||||
{
|
||||
loc = layer.getLatLng();
|
||||
loc.layer = layer;
|
||||
retRecords[ layer.options[propName] ] = loc;
|
||||
|
||||
}else if(layer.feature.properties.hasOwnProperty(propName)){
|
||||
|
||||
loc = layer.getLatLng();
|
||||
loc.layer = layer;
|
||||
retRecords[ layer.feature.properties[propName] ] = loc;
|
||||
|
||||
}else{
|
||||
console.log("propertyName '"+propName+"' not found in marker", layer);
|
||||
}
|
||||
}
|
||||
else if(layer.hasOwnProperty('feature'))//GeoJSON layer
|
||||
{
|
||||
if(layer.feature.properties.hasOwnProperty(propName))
|
||||
{
|
||||
loc = layer.getBounds().getCenter();
|
||||
loc.layer = layer;
|
||||
retRecords[ layer.feature.properties[propName] ] = loc;
|
||||
}
|
||||
else
|
||||
console.log("propertyName '"+propName+"' not found in feature", layer);
|
||||
}
|
||||
|
||||
},this);
|
||||
|
||||
return retRecords;
|
||||
},
|
||||
|
||||
_autoType: function() {
|
||||
|
||||
//TODO implements autype without selection(useful for mobile device)
|
||||
|
||||
var start = this._input.value.length,
|
||||
firstRecord = this._tooltip.firstChild._text,
|
||||
end = firstRecord.length;
|
||||
|
||||
if (firstRecord.indexOf(this._input.value) === 0) { // If prefix match
|
||||
this._input.value = firstRecord;
|
||||
this._handleAutoresize();
|
||||
|
||||
if (this._input.createTextRange) {
|
||||
var selRange = this._input.createTextRange();
|
||||
selRange.collapse(true);
|
||||
selRange.moveStart('character', start);
|
||||
selRange.moveEnd('character', end);
|
||||
selRange.select();
|
||||
}
|
||||
else if(this._input.setSelectionRange) {
|
||||
this._input.setSelectionRange(start, end);
|
||||
}
|
||||
else if(this._input.selectionStart) {
|
||||
this._input.selectionStart = start;
|
||||
this._input.selectionEnd = end;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_hideAutoType: function() { // deselect text:
|
||||
|
||||
var sel;
|
||||
if ((sel = this._input.selection) && sel.empty) {
|
||||
sel.empty();
|
||||
}
|
||||
else if (this._input.createTextRange) {
|
||||
sel = this._input.createTextRange();
|
||||
sel.collapse(true);
|
||||
var end = this._input.value.length;
|
||||
sel.moveStart('character', end);
|
||||
sel.moveEnd('character', end);
|
||||
sel.select();
|
||||
}
|
||||
else {
|
||||
if (this._input.getSelection) {
|
||||
this._input.getSelection().removeAllRanges();
|
||||
}
|
||||
this._input.selectionStart = this._input.selectionEnd;
|
||||
}
|
||||
},
|
||||
|
||||
_handleKeypress: function (e) { //run _input keyup event
|
||||
|
||||
switch(e.keyCode)
|
||||
{
|
||||
case 27: //Esc
|
||||
this.collapse();
|
||||
break;
|
||||
case 13: //Enter
|
||||
if(this._countertips == 1)
|
||||
this._handleArrowSelect(1);
|
||||
this._handleSubmit(); //do search
|
||||
break;
|
||||
case 38://Up
|
||||
this._handleArrowSelect(-1);
|
||||
break;
|
||||
case 40://Down
|
||||
this._handleArrowSelect(1);
|
||||
break;
|
||||
case 37://Left
|
||||
case 39://Right
|
||||
case 16://Shift
|
||||
case 17://Ctrl
|
||||
//case 32://Space
|
||||
break;
|
||||
case 8://backspace
|
||||
case 46://delete
|
||||
this._autoTypeTmp = false;//disable temporarily autoType
|
||||
break;
|
||||
default://All keys
|
||||
|
||||
if(this._input.value.length)
|
||||
this._cancel.style.display = 'block';
|
||||
else
|
||||
this._cancel.style.display = 'none';
|
||||
|
||||
if(this._input.value.length >= this.options.minLength)
|
||||
{
|
||||
var that = this;
|
||||
clearTimeout(this.timerKeypress); //cancel last search request while type in
|
||||
this.timerKeypress = setTimeout(function() { //delay before request, for limit jsonp/ajax request
|
||||
|
||||
that._fillRecordsCache();
|
||||
|
||||
}, this.options.delayType);
|
||||
}
|
||||
else
|
||||
this._hideTooltip();
|
||||
}
|
||||
},
|
||||
|
||||
_fillRecordsCache: function() {
|
||||
//TODO important optimization!!! always append data in this._recordsCache
|
||||
// now _recordsCache content is emptied and replaced with new data founded
|
||||
// always appending data on _recordsCache give the possibility of caching ajax, jsonp and layersearch!
|
||||
//
|
||||
//TODO here insert function that search inputText FIRST in _recordsCache keys and if not find results..
|
||||
// run one of callbacks search(callData,jsonpUrl or options.layer) and run this.showTooltip
|
||||
//
|
||||
//TODO change structure of _recordsCache
|
||||
// like this: _recordsCache = {"text-key1": {loc:[lat,lng], ..other attributes.. }, {"text-key2": {loc:[lat,lng]}...}, ...}
|
||||
// in this mode every record can have a free structure of attributes, only 'loc' is required
|
||||
|
||||
var inputText = this._input.value,
|
||||
that;
|
||||
|
||||
L.DomUtil.addClass(this._container, 'search-load');
|
||||
|
||||
if(this.options.callData) //CUSTOM SEARCH CALLBACK(USUALLY FOR AJAX SEARCHING)
|
||||
{
|
||||
that = this;
|
||||
this.options.callData(inputText, function(jsonraw) {
|
||||
|
||||
that._recordsCache = that._filterJSON(jsonraw);
|
||||
|
||||
that.showTooltip();
|
||||
|
||||
L.DomUtil.removeClass(that._container, 'search-load');
|
||||
});
|
||||
}
|
||||
else if(this.options.url) //JSONP/AJAX REQUEST
|
||||
{
|
||||
if(this.options.jsonpParam)
|
||||
{
|
||||
that = this;
|
||||
this._recordsFromJsonp(inputText, function(data) {// is async request then it need callback
|
||||
that._recordsCache = data;
|
||||
that.showTooltip();
|
||||
L.DomUtil.removeClass(that._container, 'search-load');
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
that = this;
|
||||
this._recordsFromAjax(inputText, function(data) {// is async request then it need callback
|
||||
that._recordsCache = data;
|
||||
that.showTooltip();
|
||||
L.DomUtil.removeClass(that._container, 'search-load');
|
||||
});
|
||||
}
|
||||
}
|
||||
else if(this.options.layer) //SEARCH ELEMENTS IN PRELOADED LAYER
|
||||
{
|
||||
this._recordsCache = this._recordsFromLayer(); //fill table key,value from markers into layer
|
||||
this.showTooltip();
|
||||
L.DomUtil.removeClass(this._container, 'search-load');
|
||||
}
|
||||
},
|
||||
|
||||
_handleAutoresize: function() { //autoresize this._input
|
||||
//TODO refact _handleAutoresize now is not accurate
|
||||
if (this._input.style.maxWidth != this._map._container.offsetWidth) //If maxWidth isn't the same as when first set, reset to current Map width
|
||||
this._input.style.maxWidth = L.DomUtil.getStyle(this._map._container, 'width');
|
||||
|
||||
if(this.options.autoResize && (this._container.offsetWidth + 45 < this._map._container.offsetWidth))
|
||||
this._input.size = this._input.value.length<this._inputMinSize ? this._inputMinSize : this._input.value.length;
|
||||
},
|
||||
|
||||
_handleArrowSelect: function(velocity) {
|
||||
|
||||
var searchTips = this._tooltip.hasChildNodes() ? this._tooltip.childNodes : [];
|
||||
|
||||
for (i=0; i<searchTips.length; i++)
|
||||
L.DomUtil.removeClass(searchTips[i], 'search-tip-select');
|
||||
|
||||
if ((velocity == 1 ) && (this._tooltip.currentSelection >= (searchTips.length - 1))) {// If at end of list.
|
||||
L.DomUtil.addClass(searchTips[this._tooltip.currentSelection], 'search-tip-select');
|
||||
}
|
||||
else if ((velocity == -1 ) && (this._tooltip.currentSelection <= 0)) { // Going back up to the search box.
|
||||
this._tooltip.currentSelection = -1;
|
||||
}
|
||||
else if (this._tooltip.style.display != 'none') { // regular up/down
|
||||
this._tooltip.currentSelection += velocity;
|
||||
|
||||
L.DomUtil.addClass(searchTips[this._tooltip.currentSelection], 'search-tip-select');
|
||||
|
||||
this._input.value = searchTips[this._tooltip.currentSelection]._text;
|
||||
|
||||
// scroll:
|
||||
var tipOffsetTop = searchTips[this._tooltip.currentSelection].offsetTop;
|
||||
|
||||
if (tipOffsetTop + searchTips[this._tooltip.currentSelection].clientHeight >= this._tooltip.scrollTop + this._tooltip.clientHeight) {
|
||||
this._tooltip.scrollTop = tipOffsetTop - this._tooltip.clientHeight + searchTips[this._tooltip.currentSelection].clientHeight;
|
||||
}
|
||||
else if (tipOffsetTop <= this._tooltip.scrollTop) {
|
||||
this._tooltip.scrollTop = tipOffsetTop;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_handleSubmit: function() { //button and tooltip click and enter submit
|
||||
|
||||
this._hideAutoType();
|
||||
|
||||
this.hideAlert();
|
||||
this._hideTooltip();
|
||||
|
||||
if(this._input.style.display == 'none') //on first click show _input only
|
||||
this.expand();
|
||||
else
|
||||
{
|
||||
if(this._input.value === '') //hide _input only
|
||||
this.collapse();
|
||||
else
|
||||
{
|
||||
var loc = this._getLocation(this._input.value);
|
||||
|
||||
if(loc===false)
|
||||
this.showAlert();
|
||||
else
|
||||
{
|
||||
this.showLocation(loc, this._input.value);
|
||||
this.fire('search_locationfound', {
|
||||
latlng: loc,
|
||||
text: this._input.value,
|
||||
layer: loc.layer ? loc.layer : null
|
||||
});
|
||||
}
|
||||
//this.collapse();
|
||||
//FIXME if collapse in _handleSubmit hide _markerLoc!
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_getLocation: function(key) { //extract latlng from _recordsCache
|
||||
|
||||
if( this._recordsCache.hasOwnProperty(key) )
|
||||
return this._recordsCache[key];//then after use .loc attribute
|
||||
else
|
||||
return false;
|
||||
},
|
||||
|
||||
showLocation: function(latlng, title) { //set location on map from _recordsCache
|
||||
|
||||
if(this.options.zoom)
|
||||
this._map.setView(latlng, this.options.zoom);
|
||||
else
|
||||
this._map.panTo(latlng);
|
||||
|
||||
if(this._markerLoc)
|
||||
{
|
||||
this._markerLoc.setLatLng(latlng); //show circle/marker in location found
|
||||
this._markerLoc.setTitle(title);
|
||||
this._markerLoc.show();
|
||||
if(this.options.animateLocation)
|
||||
this._markerLoc.animate();
|
||||
//TODO showLocation: start animation after setView or panTo, maybe with map.on('moveend')...
|
||||
}
|
||||
|
||||
//FIXME autoCollapse option hide this._markerLoc before that visualized!!
|
||||
if(this.options.autoCollapse)
|
||||
this.collapse();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
var SearchMarker = L.Marker.extend({
|
||||
|
||||
includes: L.Mixin.Events,
|
||||
|
||||
options: {
|
||||
radius: 10,
|
||||
weight: 3,
|
||||
color: '#e03',
|
||||
stroke: true,
|
||||
fill: false,
|
||||
title: '',
|
||||
//TODO add custom icon!
|
||||
marker: false //show icon optional, show only circleLoc
|
||||
},
|
||||
|
||||
initialize: function (latlng, options) {
|
||||
L.setOptions(this, options);
|
||||
L.Marker.prototype.initialize.call(this, latlng, options);
|
||||
this._circleLoc = new L.CircleMarker(latlng, this.options);
|
||||
//TODO add inner circle
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
L.Marker.prototype.onAdd.call(this, map);
|
||||
map.addLayer(this._circleLoc);
|
||||
this.hide();
|
||||
},
|
||||
|
||||
onRemove: function (map) {
|
||||
L.Marker.prototype.onRemove.call(this, map);
|
||||
map.removeLayer(this._circleLoc);
|
||||
},
|
||||
|
||||
setLatLng: function (latlng) {
|
||||
L.Marker.prototype.setLatLng.call(this, latlng);
|
||||
this._circleLoc.setLatLng(latlng);
|
||||
return this;
|
||||
},
|
||||
|
||||
setTitle: function(title) {
|
||||
title = title || '';
|
||||
this.options.title = title;
|
||||
if(this._icon)
|
||||
this._icon.title = title;
|
||||
return this;
|
||||
},
|
||||
|
||||
show: function() {
|
||||
if(this.options.marker)
|
||||
{
|
||||
if(this._icon)
|
||||
this._icon.style.display = 'block';
|
||||
if(this._shadow)
|
||||
this._shadow.style.display = 'block';
|
||||
//this._bringToFront();
|
||||
}
|
||||
if(this._circleLoc)
|
||||
{
|
||||
this._circleLoc.setStyle({fill: this.options.fill, stroke: this.options.stroke});
|
||||
//this._circleLoc.bringToFront();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if(this._icon)
|
||||
this._icon.style.display = 'none';
|
||||
if(this._shadow)
|
||||
this._shadow.style.display = 'none';
|
||||
if(this._circleLoc)
|
||||
this._circleLoc.setStyle({fill: false, stroke: false});
|
||||
return this;
|
||||
},
|
||||
|
||||
animate: function() {
|
||||
//TODO refact animate() more smooth! like this: http://goo.gl/DDlRs
|
||||
var circle = this._circleLoc,
|
||||
tInt = 200, //time interval
|
||||
ss = 10, //frames
|
||||
mr = parseInt(circle._radius/ss),
|
||||
oldrad = this.options.radius,
|
||||
newrad = circle._radius * 2.5,
|
||||
acc = 0;
|
||||
|
||||
circle._timerAnimLoc = setInterval(function() {
|
||||
acc += 0.5;
|
||||
mr += acc; //adding acceleration
|
||||
newrad -= mr;
|
||||
|
||||
circle.setRadius(newrad);
|
||||
|
||||
if(newrad<oldrad)
|
||||
{
|
||||
clearInterval(circle._timerAnimLoc);
|
||||
circle.setRadius(oldrad);//reset radius
|
||||
//if(typeof afterAnimCall == 'function')
|
||||
//afterAnimCall();
|
||||
//TODO use create event 'animateEnd' in SearchMarker
|
||||
}
|
||||
}, tInt);
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.addInitHook(function () {
|
||||
if (this.options.searchControl) {
|
||||
this.searchControl = L.control.search(this.options.searchControl);
|
||||
this.addControl(this.searchControl);
|
||||
}
|
||||
});
|
||||
|
||||
L.control.search = function (options) {
|
||||
return new L.Control.Search(options);
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
||||
BIN
bower_components/leaflet-search/images/back.png
vendored
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
bower_components/leaflet-search/images/loader.gif
vendored
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
bower_components/leaflet-search/images/search-icon-mobile.png
vendored
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
bower_components/leaflet-search/images/search-icon.png
vendored
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
102
bower_components/leaflet-search/index.html
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Leaflet.Control.Search</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body id="home">
|
||||
|
||||
<h2>Leaflet.Control.Search</h2>
|
||||
|
||||
<div id="desc">
|
||||
A Leaflet Control for search markers/features location by attribute<br />
|
||||
and much more.
|
||||
<div style="position:absolute;top:0;right:-120px">
|
||||
<iframe src="http://ghbtns.com/github-btn.html?user=stefanocudini&repo=leaflet-search&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="104px" height="20px"></iframe>
|
||||
</div>
|
||||
<br />
|
||||
Other useful stuff for <a href="http://labs.easyblog.it/maps/">Web Mapping...</a>
|
||||
</div>
|
||||
|
||||
<div style="clear:both"></div>
|
||||
|
||||
<div class="contents">
|
||||
<h4>Features</h4>
|
||||
<ul id="ff">
|
||||
<li>Autocomplete</li>
|
||||
<li>No require external Ajax libs</li>
|
||||
<li>Retrieve data locations by Ajax/Jsonp</li>
|
||||
<li>Pre-filtering data from Ajax/Jsonp</li>
|
||||
<li>Complete fields remapping for remote Jsonp service</li>
|
||||
<li>Data source callback support</li>
|
||||
<li>Localization placeholder and text alert</li>
|
||||
<li>Autozoom on location founded</li>
|
||||
<li>Autoresize textbox</li>
|
||||
<li>Customize tooltip menu</li>
|
||||
<li>Many options to customize the behavior</li>
|
||||
<li>Support search in features collection</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="contents">
|
||||
<h4>Examples</h4>
|
||||
<ul id="examples">
|
||||
<li><a href="examples/simple.html">Simple</a></li>
|
||||
<li><a href="examples/geojson-layer.html">GeoJSON features</a></li>
|
||||
<li><a href="examples/ajax.html">Ajax</a></li>
|
||||
<li><a href="examples/jsonp.html">Jsonp</a></li>
|
||||
<li><a href="examples/ajax-jquery.html">Ajax by jQuery</a></li>
|
||||
<li><a href="examples/jsonp-filtered.html">Jsonp Filtered</a></li>
|
||||
<li><a href="examples/ajax-bulk.html">Bulk data</a></li>
|
||||
<li><a href="examples/custom-tip.html">Custom Tip</a></li>
|
||||
<li><a href="examples/google-geocoding.html">GeoCode Search - Google Geocoding API</a></li>
|
||||
<li><a href="examples/nominatim.html">GeoCode Search - OSM Nominatim API</a></li>
|
||||
<li><a href="examples/cloudmade.html">GeoCode Search - Cloudmade API</a></li>
|
||||
<li><a href="examples/mobile.html">Mobile styled</a></li>
|
||||
<li><a href="examples/twitter.html">Twitter API</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="contents">
|
||||
<h4>Code repositories</h4>
|
||||
<a target="_blank" href="https://github.com/stefanocudini/leaflet-search">Github.com</a>
|
||||
<br />
|
||||
<a target="_blank" href="https://bitbucket.org/zakis_/leaflet-search">Bitbucket.org</a>
|
||||
<br />
|
||||
<a target="_blank" href="https://npmjs.org/package/leaflet-search">Node Packaged Module</a>
|
||||
<br />
|
||||
<a target="_blank" href="https://atmosphere.meteor.com/package/leaflet-search">Atmosphere Meteor JS</a>
|
||||
<br />
|
||||
|
||||
<h4>Website</h4>
|
||||
<a href="http://labs.easyblog.it/maps/leaflet-search/">labs.easyblog.it/maps/leaflet-search</a>
|
||||
<br />
|
||||
|
||||
<h4>Download</h4>
|
||||
<ul>
|
||||
<li><a href="https://github.com/stefanocudini/leaflet-search/archive/master.zip">Dev Pack (.zip)</a></li>
|
||||
<li><a href="dist/leaflet-search.src.js">Source Code (.js)</a></li>
|
||||
<li><a href="dist/leaflet-search.min.js">Compressed (.min.js)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="copy"><a href="http://labs.easyblog.it/">Labs</a> • <a rel="author" href="http://labs.easyblog.it/stefano-cudini/">Stefano Cudini</a></div>
|
||||
|
||||
<a href="https://github.com/stefanocudini/leaflet-search"><img id="ribbon" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
|
||||
|
||||
<div style="clear:both;font-size:.85em;margin-bottom:1em">
|
||||
<b>For questions and bugs</b> I recommend you to <a href="https://github.com/stefanocudini/leaflet-search/issues">create New Issue</a> on Github repository.</strong><br />
|
||||
Or to obtain a fast response consult <a href="https://groups.google.com/forum/?hl=it&fromgroups=#!forum/leaflet-js">Official Leaflet community forum</a>.<br />
|
||||
<br />
|
||||
This is a micro discussion area for methods of implementation.<br />
|
||||
</div>
|
||||
|
||||
<div id="comments">
|
||||
<div id="disqus_thread"></div>
|
||||
</div>
|
||||
<script>var disqus_shortname = 'easyblog-it'</script>
|
||||
|
||||
<script type="text/javascript" src="/labs-common.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
11
bower_components/leaflet-search/package.js
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
Package.describe({
|
||||
summary: "Leaflet Control Search"
|
||||
});
|
||||
|
||||
Package.on_use(function (api, where) {
|
||||
api.add_files('dist/leaflet-search.min.js', 'client');
|
||||
api.add_files('dist/leaflet-search.min.css', 'client');
|
||||
api.add_files('images/search-icon.png', 'client');
|
||||
api.add_files('images/loader.gif', 'client');
|
||||
//TODO server-side searching...
|
||||
});
|
||||
34
bower_components/leaflet-search/package.json
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "leaflet-search",
|
||||
"version": "1.4.7",
|
||||
"description": "Leaflet Control for searching markers/features by attribute on map or remote searching in jsonp/ajax",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:stefanocudini/leaflet-search.git"
|
||||
},
|
||||
"homepage": "http://labs.easyblog.it/maps/leaflet-search/",
|
||||
"author": {
|
||||
"name": "Stefano Cudini",
|
||||
"email": "stefano.cudini@gmail.com",
|
||||
"url": "http://labs.easyblog.it/"
|
||||
},
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"gis",
|
||||
"map",
|
||||
"leaflet"
|
||||
],
|
||||
"dependencies": {
|
||||
"leaflet": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt": "~0.4.2",
|
||||
"grunt-contrib-uglify": "~0.2.7",
|
||||
"grunt-contrib-concat": "~0.3.0",
|
||||
"grunt-contrib-clean": "~0.5.0",
|
||||
"grunt-contrib-cssmin": "~0.7.0",
|
||||
"grunt-contrib-jshint": "~0.7.2",
|
||||
"grunt-contrib-watch": "~0.5.3",
|
||||
"grunt-todos": "~0.2.0"
|
||||
}
|
||||
}
|
||||
8
bower_components/leaflet-search/smart.json
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "leaflet-search",
|
||||
"description": "Leaflet Control for searching markers/features by attribute on map or remote searching in jsonp/ajax",
|
||||
"homepage": "http://labs.easyblog.it/maps/leaflet-search/",
|
||||
"author": "Stefano Cudini <stefano.cudini@gmail.com>",
|
||||
"version": "1.4.7",
|
||||
"git": "https://github.com/stefanocudini/leaflet-search.git"
|
||||
}
|
||||
121
bower_components/leaflet-search/src/leaflet-search.css
vendored
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
|
||||
.leaflet-container .leaflet-control-search {
|
||||
position:relative;
|
||||
float:left;
|
||||
background:#fff;
|
||||
color:#1978cf;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
z-index:1000;
|
||||
box-shadow: 0 1px 7px rgba(0,0,0,0.65);
|
||||
margin-left: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-control-search.search-exp {/*expanded*/
|
||||
box-shadow: 0 1px 7px #999;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-search .search-input {
|
||||
display:block;
|
||||
float:left;
|
||||
background: #fff;
|
||||
border:1px solid #666;
|
||||
border-radius:2px;
|
||||
height:18px;
|
||||
padding:0 18px 0 2px;
|
||||
margin:3px 0 3px 3px;
|
||||
}
|
||||
.leaflet-control-search.search-load .search-input {
|
||||
background: url('../images/loader.gif') no-repeat center right #fff;
|
||||
}
|
||||
.leaflet-control-search.search-load .search-cancel {
|
||||
visibility:hidden;
|
||||
}
|
||||
.leaflet-control-search .search-cancel {
|
||||
display:block;
|
||||
width:22px;
|
||||
height:18px;
|
||||
position:absolute;
|
||||
right:22px;
|
||||
margin:3px 0;
|
||||
background: url('../images/search-icon.png') no-repeat 0 -46px;
|
||||
text-decoration:none;
|
||||
filter: alpha(opacity=80);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.leaflet-control-search .search-cancel:hover {
|
||||
filter: alpha(opacity=100);
|
||||
opacity: 1;
|
||||
}
|
||||
.leaflet-control-search .search-cancel span {
|
||||
display:none;/* comment for cancel button imageless */
|
||||
font-size:18px;
|
||||
line-height:20px;
|
||||
color:#ccc;
|
||||
font-weight:bold;
|
||||
}
|
||||
.leaflet-control-search .search-cancel:hover span {
|
||||
color:#aaa;
|
||||
}
|
||||
.leaflet-control-search .search-button {
|
||||
display:block;
|
||||
float:left;
|
||||
width:26px;
|
||||
height:26px;
|
||||
background: url('../images/search-icon.png') no-repeat 2px 2px;
|
||||
border-radius:4px;
|
||||
}
|
||||
.leaflet-control-search .search-button:hover {
|
||||
background: url('../images/search-icon.png') no-repeat 2px -22px;
|
||||
}
|
||||
.leaflet-control-search .search-tooltip {
|
||||
position:absolute;
|
||||
top:100%;
|
||||
left:0;
|
||||
float:left;
|
||||
min-width:80px;
|
||||
max-height:106px;/*(.search-tip height * 5)*/
|
||||
box-shadow: 0 0 8px rgba(0,0,0,0.4);
|
||||
-webkit-border-radius: 5px;
|
||||
-webkit-border-top-left-radius: 0;
|
||||
-moz-border-radius: 5px;
|
||||
-moz-border-radius-topleft: 0;
|
||||
border-radius: 5px;
|
||||
border-top-left-radius: 0;
|
||||
background-color: rgba(0, 0, 0, 0.25);
|
||||
z-index:1010;
|
||||
overflow-y:auto;
|
||||
overflow-x:hidden;
|
||||
}
|
||||
.leaflet-control-search .search-tip {
|
||||
font-size:.85em;
|
||||
margin:2px;
|
||||
padding:2px;
|
||||
display:block;
|
||||
color:black;
|
||||
background: #ddd;
|
||||
border-radius:.25em;
|
||||
text-decoration:none;
|
||||
white-space:nowrap;
|
||||
font-size:.85em;
|
||||
vertical-align:center;
|
||||
}
|
||||
.leaflet-control-search .search-tip-select,
|
||||
.leaflet-control-search .search-tip:hover,
|
||||
.leaflet-control-search .search-button:hover {
|
||||
background-color: #fff;
|
||||
}
|
||||
.leaflet-control-search .search-alert {
|
||||
cursor:pointer;
|
||||
clear:both;
|
||||
font-size:.75em;
|
||||
margin-bottom:5px;
|
||||
padding:0 .25em;
|
||||
color:#e00;
|
||||
font-weight:bold;
|
||||
border-radius:.25em;
|
||||
}
|
||||
|
||||
|
||||
839
bower_components/leaflet-search/src/leaflet-search.js
vendored
Normal file
|
|
@ -0,0 +1,839 @@
|
|||
|
||||
(function() {
|
||||
|
||||
L.Control.Search = L.Control.extend({
|
||||
includes: L.Mixin.Events,
|
||||
//
|
||||
// Name Data passed Description
|
||||
//
|
||||
//Managed Events:
|
||||
// search_locationfound {latlng, title} fired after moved and show markerLocation
|
||||
// search_collapsed {} fired after control was collapsed
|
||||
//
|
||||
//Public methods:
|
||||
// setLayer() L.LayerGroup() set layer search at runtime
|
||||
// showAlert() 'Text message' Show alert message
|
||||
//
|
||||
options: {
|
||||
url: '', //url for search by ajax request, ex: "search.php?q={s}"
|
||||
jsonpParam: null, //jsonp param name for search by jsonp service, ex: "callback"
|
||||
layer: null, //layer where search markers(is a L.LayerGroup)
|
||||
callData: null, //function that fill _recordsCache, passed searching text by first param and callback in second
|
||||
//TODO important! implements uniq option 'sourceData' that recognizes source type: url,array,callback or layer
|
||||
//TODO implement can do research on multiple sources
|
||||
propertyName: 'title', //property in marker.options(or feature.properties for vector layer) trough filter elements in layer
|
||||
propertyLoc: 'loc', //field name for remapping location, using array: ['latname','lonname'] for select double fields(ex. ['lat','lon'] )
|
||||
//TODO implement sub property filter for propertyName,propertyLoc like this: "prop.subprop.title"
|
||||
callTip: null, //function that return row tip html node(or html string), receive text tooltip in first param
|
||||
filterJSON: null, //callback for filtering data to _recordsCache
|
||||
minLength: 1, //minimal text length for autocomplete
|
||||
initial: true, //search elements only by initial text
|
||||
autoType: true, //complete input with first suggested result and select this filled-in text.
|
||||
delayType: 400, //delay while typing for show tooltip
|
||||
tooltipLimit: -1, //limit max results to show in tooltip. -1 for no limit.
|
||||
tipAutoSubmit: true, //auto map panTo when click on tooltip
|
||||
autoResize: true, //autoresize on input change
|
||||
autoCollapse: false, //collapse search control after submit(on button or on tips if enabled tipAutoSubmit)
|
||||
//TODO add option for persist markerLoc after collapse!
|
||||
autoCollapseTime: 1200, //delay for autoclosing alert and collapse after blur
|
||||
animateLocation: true, //animate a circle over location found
|
||||
circleLocation: true, //draw a circle in location found
|
||||
markerLocation: false, //draw a marker in location found
|
||||
zoom: null, //zoom after pan to location found, default: map.getZoom()
|
||||
text: 'Search...', //placeholder value
|
||||
textCancel: 'Cancel', //title in cancel button
|
||||
textErr: 'Location not found', //error message
|
||||
position: 'topleft'
|
||||
//TODO add option collapsed, like control.layers
|
||||
},
|
||||
//FIXME option condition problem {autoCollapse: true, markerLocation: true} not show location
|
||||
//FIXME option condition problem {autoCollapse: false }
|
||||
|
||||
initialize: function(options) {
|
||||
L.Util.setOptions(this, options || {});
|
||||
this._inputMinSize = this.options.text ? this.options.text.length : 10;
|
||||
this._layer = this.options.layer || new L.LayerGroup();
|
||||
this._filterJSON = this.options.filterJSON || this._defaultFilterJSON;
|
||||
this._autoTypeTmp = this.options.autoType; //useful for disable autoType temporarily in delete/backspace keydown
|
||||
this._countertips = 0; //number of tips items
|
||||
this._recordsCache = {}; //key,value table! that store locations! format: key,latlng
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
this._map = map;
|
||||
this._container = L.DomUtil.create('div', 'leaflet-control-search');
|
||||
this._input = this._createInput(this.options.text, 'search-input');
|
||||
this._tooltip = this._createTooltip('search-tooltip');
|
||||
this._cancel = this._createCancel(this.options.textCancel, 'search-cancel');
|
||||
this._button = this._createButton(this.options.text, 'search-button');
|
||||
this._alert = this._createAlert('search-alert');
|
||||
|
||||
if(this.options.circleLocation || this.options.markerLocation)
|
||||
this._markerLoc = new SearchMarker([0,0], {marker: this.options.markerLocation});//see below
|
||||
|
||||
this.setLayer( this._layer );
|
||||
map.on({
|
||||
// 'layeradd': this._onLayerAddRemove,
|
||||
// 'layerremove': this._onLayerAddRemove
|
||||
'resize':this._handleAutoresize()
|
||||
}, this);
|
||||
return this._container;
|
||||
},
|
||||
|
||||
onRemove: function(map) {
|
||||
this._recordsCache = {};
|
||||
// map.off({
|
||||
// 'layeradd': this._onLayerAddRemove,
|
||||
// 'layerremove': this._onLayerAddRemove
|
||||
// }, this);
|
||||
},
|
||||
|
||||
// _onLayerAddRemove: function(e) {
|
||||
// //console.info('_onLayerAddRemove');
|
||||
// //without this, run setLayer also for each Markers!! to optimize!
|
||||
// if(e.layer instanceof L.LayerGroup)
|
||||
// if( L.stamp(e.layer) != L.stamp(this._layer) )
|
||||
// this.setLayer(e.layer);
|
||||
// },
|
||||
|
||||
setLayer: function(layer) { //set search layer at runtime
|
||||
//this.options.layer = layer; //setting this, run only this._recordsFromLayer()
|
||||
this._layer = layer;
|
||||
this._layer.addTo(this._map);
|
||||
if(this._markerLoc)
|
||||
this._layer.addLayer(this._markerLoc);
|
||||
return this;
|
||||
},
|
||||
|
||||
showAlert: function(text) {
|
||||
text = text || this.options.textErr;
|
||||
this._alert.style.display = 'block';
|
||||
this._alert.innerHTML = text;
|
||||
clearTimeout(this.timerAlert);
|
||||
var that = this;
|
||||
this.timerAlert = setTimeout(function() {
|
||||
that.hideAlert();
|
||||
},this.options.autoCollapseTime);
|
||||
return this;
|
||||
},
|
||||
|
||||
hideAlert: function() {
|
||||
this._alert.style.display = 'none';
|
||||
return this;
|
||||
},
|
||||
|
||||
cancel: function() {
|
||||
this._input.value = '';
|
||||
this._handleKeypress({keyCode:8});//simulate backspace keypress
|
||||
this._input.size = this._inputMinSize;
|
||||
this._input.focus();
|
||||
this._cancel.style.display = 'none';
|
||||
return this;
|
||||
},
|
||||
|
||||
expand: function() {
|
||||
this._input.style.display = 'block';
|
||||
L.DomUtil.addClass(this._container, 'search-exp');
|
||||
this._input.focus();
|
||||
this._map.on('dragstart', this.collapse, this);
|
||||
return this;
|
||||
},
|
||||
|
||||
collapse: function() {
|
||||
this._hideTooltip();
|
||||
this.cancel();
|
||||
this._alert.style.display = 'none';
|
||||
this._input.style.display = 'none';
|
||||
this._input.blur();
|
||||
this._cancel.style.display = 'none';
|
||||
L.DomUtil.removeClass(this._container, 'search-exp');
|
||||
//this._markerLoc.hide();//maybe unuseful
|
||||
this._map.off('dragstart', this.collapse, this);
|
||||
this.fire('search_collapsed');
|
||||
return this;
|
||||
},
|
||||
|
||||
collapseDelayed: function() { //collapse after delay, used on_input blur
|
||||
if (!this.options.autoCollapse) return this;
|
||||
var that = this;
|
||||
clearTimeout(this.timerCollapse);
|
||||
this.timerCollapse = setTimeout(function() {
|
||||
that.collapse();
|
||||
}, this.options.autoCollapseTime);
|
||||
return this;
|
||||
},
|
||||
|
||||
collapseDelayedStop: function() {
|
||||
clearTimeout(this.timerCollapse);
|
||||
return this;
|
||||
},
|
||||
|
||||
////start DOM creations
|
||||
_createAlert: function(className) {
|
||||
var alert = L.DomUtil.create('div', className, this._container);
|
||||
alert.style.display = 'none';
|
||||
|
||||
L.DomEvent
|
||||
.on(alert, 'click', L.DomEvent.stop, this)
|
||||
.on(alert, 'click', this.hideAlert, this);
|
||||
|
||||
return alert;
|
||||
},
|
||||
|
||||
_createInput: function (text, className) {
|
||||
var input = L.DomUtil.create('input', className, this._container);
|
||||
input.type = 'text';
|
||||
input.size = this._inputMinSize;
|
||||
input.value = '';
|
||||
input.autocomplete = 'off';
|
||||
input.placeholder = text;
|
||||
input.style.display = 'none';
|
||||
|
||||
L.DomEvent
|
||||
.disableClickPropagation(input)
|
||||
.on(input, 'keyup', this._handleKeypress, this)
|
||||
.on(input, 'keydown', this._handleAutoresize, this)
|
||||
.on(input, 'blur', this.collapseDelayed, this)
|
||||
.on(input, 'focus', this.collapseDelayedStop, this);
|
||||
|
||||
return input;
|
||||
},
|
||||
|
||||
_createCancel: function (title, className) {
|
||||
var cancel = L.DomUtil.create('a', className, this._container);
|
||||
cancel.href = '#';
|
||||
cancel.title = title;
|
||||
cancel.style.display = 'none';
|
||||
cancel.innerHTML = "<span>⊗</span>";//imageless(see css)
|
||||
|
||||
L.DomEvent
|
||||
.on(cancel, 'click', L.DomEvent.stop, this)
|
||||
.on(cancel, 'click', this.cancel, this);
|
||||
|
||||
return cancel;
|
||||
},
|
||||
|
||||
_createButton: function (title, className) {
|
||||
var button = L.DomUtil.create('a', className, this._container);
|
||||
button.href = '#';
|
||||
button.title = title;
|
||||
|
||||
L.DomEvent
|
||||
.on(button, 'click', L.DomEvent.stop, this)
|
||||
.on(button, 'click', this._handleSubmit, this)
|
||||
.on(button, 'focus', this.collapseDelayedStop, this)
|
||||
.on(button, 'blur', this.collapseDelayed, this);
|
||||
|
||||
return button;
|
||||
},
|
||||
|
||||
_createTooltip: function(className) {
|
||||
var tool = L.DomUtil.create('div', className, this._container);
|
||||
tool.style.display = 'none';
|
||||
|
||||
var that = this;
|
||||
L.DomEvent
|
||||
.disableClickPropagation(tool)
|
||||
.on(tool, 'blur', this.collapseDelayed, this)
|
||||
.on(tool, 'mousewheel', function(e) {
|
||||
that.collapseDelayedStop();
|
||||
L.DomEvent.stopPropagation(e);//disable zoom map
|
||||
}, this)
|
||||
.on(tool, 'mouseover', function(e) {
|
||||
that.collapseDelayedStop();
|
||||
}, this);
|
||||
return tool;
|
||||
},
|
||||
|
||||
_createTip: function(text, val) {//val is object in recordCache, usually is Latlng
|
||||
var tip;
|
||||
|
||||
if(this.options.callTip)
|
||||
{
|
||||
tip = this.options.callTip(text,val); //custom tip node or html string
|
||||
if(typeof tip === 'string')
|
||||
{
|
||||
var tmpNode = L.DomUtil.create('div');
|
||||
tmpNode.innerHTML = tip;
|
||||
tip = tmpNode.firstChild;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tip = L.DomUtil.create('a', '');
|
||||
tip.href = '#';
|
||||
tip.innerHTML = text;
|
||||
}
|
||||
|
||||
L.DomUtil.addClass(tip, 'search-tip');
|
||||
tip._text = text; //value replaced in this._input and used by _autoType
|
||||
|
||||
L.DomEvent
|
||||
.disableClickPropagation(tip)
|
||||
.on(tip, 'click', L.DomEvent.stop, this)
|
||||
.on(tip, 'click', function(e) {
|
||||
this._input.value = text;
|
||||
this._handleAutoresize();
|
||||
this._input.focus();
|
||||
this._hideTooltip();
|
||||
if(this.options.tipAutoSubmit)//go to location at once
|
||||
this._handleSubmit();
|
||||
}, this);
|
||||
|
||||
return tip;
|
||||
},
|
||||
|
||||
//////end DOM creations
|
||||
|
||||
_filterRecords: function(text) { //Filter this._recordsCache case insensitive and much more..
|
||||
|
||||
var regFilter = new RegExp("^[.]$|[\[\]|()*]",'g'), //remove . * | ( ) ] [
|
||||
I, regSearch,
|
||||
frecords = {};
|
||||
|
||||
text = text.replace(regFilter,''); //sanitize text
|
||||
I = this.options.initial ? '^' : ''; //search only initial text
|
||||
//TODO add option for case sesitive search, also showLocation
|
||||
regSearch = new RegExp(I + text,'i');
|
||||
|
||||
//TODO use .filter or .map
|
||||
for(var key in this._recordsCache)
|
||||
if( regSearch.test(key) )
|
||||
frecords[key]= this._recordsCache[key];
|
||||
|
||||
return frecords;
|
||||
},
|
||||
|
||||
showTooltip: function() {
|
||||
var filteredRecords, newTip;
|
||||
|
||||
this._countertips = 0;
|
||||
|
||||
//FIXME problem with jsonp/ajax when remote filter has different behavior of this._filterRecords
|
||||
if(this.options.layer)
|
||||
filteredRecords = this._filterRecords( this._input.value );
|
||||
else
|
||||
filteredRecords = this._recordsCache;
|
||||
|
||||
this._tooltip.innerHTML = '';
|
||||
this._tooltip.currentSelection = -1; //inizialized for _handleArrowSelect()
|
||||
|
||||
for(var key in filteredRecords)//fill tooltip
|
||||
{
|
||||
if(++this._countertips == this.options.tooltipLimit) break;
|
||||
|
||||
newTip = this._createTip(key, filteredRecords[key] );
|
||||
|
||||
this._tooltip.appendChild(newTip);
|
||||
}
|
||||
|
||||
if(this._countertips > 0)
|
||||
{
|
||||
this._tooltip.style.display = 'block';
|
||||
if(this._autoTypeTmp)
|
||||
this._autoType();
|
||||
this._autoTypeTmp = this.options.autoType;//reset default value
|
||||
}
|
||||
else
|
||||
this._hideTooltip();
|
||||
|
||||
this._tooltip.scrollTop = 0;
|
||||
return this._countertips;
|
||||
},
|
||||
|
||||
_hideTooltip: function() {
|
||||
this._tooltip.style.display = 'none';
|
||||
this._tooltip.innerHTML = '';
|
||||
return 0;
|
||||
},
|
||||
|
||||
_defaultFilterJSON: function(json) { //default callback for filter data
|
||||
var jsonret = {},
|
||||
propName = this.options.propertyName,
|
||||
propLoc = this.options.propertyLoc;
|
||||
|
||||
if( L.Util.isArray(propLoc) )
|
||||
for(var i in json)
|
||||
jsonret[ json[i][propName] ]= L.latLng( json[i][ propLoc[0] ], json[i][ propLoc[1] ] );
|
||||
else
|
||||
for(var n in json)
|
||||
jsonret[ json[n][propName] ]= L.latLng( json[n][ propLoc ] );
|
||||
//TODO verify json[n].hasOwnProperty(propName)
|
||||
//throw new Error("propertyName '"+propName+"' not found in JSON data");
|
||||
return jsonret;
|
||||
},
|
||||
|
||||
_recordsFromJsonp: function(text, callAfter) { //extract searched records from remote jsonp service
|
||||
//TODO remove script node after call run
|
||||
var that = this;
|
||||
L.Control.Search.callJsonp = function(data) { //jsonp callback
|
||||
var fdata = that._filterJSON(data);//_filterJSON defined in inizialize...
|
||||
callAfter(fdata);
|
||||
}
|
||||
var script = L.DomUtil.create('script','search-jsonp', document.getElementsByTagName('body')[0] ),
|
||||
url = L.Util.template(this.options.url+'&'+this.options.jsonpParam+'=L.Control.Search.callJsonp', {s: text}); //parsing url
|
||||
//rnd = '&_='+Math.floor(Math.random()*10000);
|
||||
//TODO add rnd param or randomize callback name! in recordsFromJsonp
|
||||
script.type = 'text/javascript';
|
||||
script.src = url;
|
||||
return this;
|
||||
//may be return {abort: function() { script.parentNode.removeChild(script); } };
|
||||
},
|
||||
|
||||
_recordsFromAjax: function(text, callAfter) { //Ajax request
|
||||
if (window.XMLHttpRequest === undefined) {
|
||||
window.XMLHttpRequest = function() {
|
||||
try { return new ActiveXObject("Microsoft.XMLHTTP.6.0"); }
|
||||
catch (e1) {
|
||||
try { return new ActiveXObject("Microsoft.XMLHTTP.3.0"); }
|
||||
catch (e2) { throw new Error("XMLHttpRequest is not supported"); }
|
||||
}
|
||||
};
|
||||
}
|
||||
var request = new XMLHttpRequest(),
|
||||
url = L.Util.template(this.options.url, {s: text}), //parsing url
|
||||
//rnd = '&_='+Math.floor(Math.random()*10000);
|
||||
//TODO add rnd param or randomize callback name! in recordsFromAjax
|
||||
response = {};
|
||||
|
||||
request.open("GET", url);
|
||||
var that = this;
|
||||
request.onreadystatechange = function() {
|
||||
if(request.readyState === 4 && request.status === 200) {
|
||||
response = JSON.parse(request.responseText);
|
||||
var fdata = that._filterJSON(response);//_filterJSON defined in inizialize...
|
||||
callAfter(fdata);
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
return this;
|
||||
},
|
||||
|
||||
_recordsFromLayer: function() { //return table: key,value from layer
|
||||
var retRecords = {},
|
||||
propName = this.options.propertyName,
|
||||
loc;
|
||||
|
||||
this._layer.eachLayer(function(layer) {
|
||||
|
||||
if(layer instanceof SearchMarker) return;
|
||||
|
||||
if(layer instanceof L.Marker)
|
||||
{
|
||||
if(layer.options.hasOwnProperty(propName))
|
||||
{
|
||||
loc = layer.getLatLng();
|
||||
loc.layer = layer;
|
||||
retRecords[ layer.options[propName] ] = loc;
|
||||
|
||||
}else if(layer.feature.properties.hasOwnProperty(propName)){
|
||||
|
||||
loc = layer.getLatLng();
|
||||
loc.layer = layer;
|
||||
retRecords[ layer.feature.properties[propName] ] = loc;
|
||||
|
||||
}else{
|
||||
console.log("propertyName '"+propName+"' not found in marker", layer);
|
||||
}
|
||||
}
|
||||
else if(layer.hasOwnProperty('feature'))//GeoJSON layer
|
||||
{
|
||||
if(layer.feature.properties.hasOwnProperty(propName))
|
||||
{
|
||||
loc = layer.getBounds().getCenter();
|
||||
loc.layer = layer;
|
||||
retRecords[ layer.feature.properties[propName] ] = loc;
|
||||
}
|
||||
else
|
||||
console.log("propertyName '"+propName+"' not found in feature", layer);
|
||||
}
|
||||
|
||||
},this);
|
||||
|
||||
return retRecords;
|
||||
},
|
||||
|
||||
_autoType: function() {
|
||||
|
||||
//TODO implements autype without selection(useful for mobile device)
|
||||
|
||||
var start = this._input.value.length,
|
||||
firstRecord = this._tooltip.firstChild._text,
|
||||
end = firstRecord.length;
|
||||
|
||||
if (firstRecord.indexOf(this._input.value) === 0) { // If prefix match
|
||||
this._input.value = firstRecord;
|
||||
this._handleAutoresize();
|
||||
|
||||
if (this._input.createTextRange) {
|
||||
var selRange = this._input.createTextRange();
|
||||
selRange.collapse(true);
|
||||
selRange.moveStart('character', start);
|
||||
selRange.moveEnd('character', end);
|
||||
selRange.select();
|
||||
}
|
||||
else if(this._input.setSelectionRange) {
|
||||
this._input.setSelectionRange(start, end);
|
||||
}
|
||||
else if(this._input.selectionStart) {
|
||||
this._input.selectionStart = start;
|
||||
this._input.selectionEnd = end;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_hideAutoType: function() { // deselect text:
|
||||
|
||||
var sel;
|
||||
if ((sel = this._input.selection) && sel.empty) {
|
||||
sel.empty();
|
||||
}
|
||||
else if (this._input.createTextRange) {
|
||||
sel = this._input.createTextRange();
|
||||
sel.collapse(true);
|
||||
var end = this._input.value.length;
|
||||
sel.moveStart('character', end);
|
||||
sel.moveEnd('character', end);
|
||||
sel.select();
|
||||
}
|
||||
else {
|
||||
if (this._input.getSelection) {
|
||||
this._input.getSelection().removeAllRanges();
|
||||
}
|
||||
this._input.selectionStart = this._input.selectionEnd;
|
||||
}
|
||||
},
|
||||
|
||||
_handleKeypress: function (e) { //run _input keyup event
|
||||
|
||||
switch(e.keyCode)
|
||||
{
|
||||
case 27: //Esc
|
||||
this.collapse();
|
||||
break;
|
||||
case 13: //Enter
|
||||
if(this._countertips == 1)
|
||||
this._handleArrowSelect(1);
|
||||
this._handleSubmit(); //do search
|
||||
break;
|
||||
case 38://Up
|
||||
this._handleArrowSelect(-1);
|
||||
break;
|
||||
case 40://Down
|
||||
this._handleArrowSelect(1);
|
||||
break;
|
||||
case 37://Left
|
||||
case 39://Right
|
||||
case 16://Shift
|
||||
case 17://Ctrl
|
||||
//case 32://Space
|
||||
break;
|
||||
case 8://backspace
|
||||
case 46://delete
|
||||
this._autoTypeTmp = false;//disable temporarily autoType
|
||||
break;
|
||||
default://All keys
|
||||
|
||||
if(this._input.value.length)
|
||||
this._cancel.style.display = 'block';
|
||||
else
|
||||
this._cancel.style.display = 'none';
|
||||
|
||||
if(this._input.value.length >= this.options.minLength)
|
||||
{
|
||||
var that = this;
|
||||
clearTimeout(this.timerKeypress); //cancel last search request while type in
|
||||
this.timerKeypress = setTimeout(function() { //delay before request, for limit jsonp/ajax request
|
||||
|
||||
that._fillRecordsCache();
|
||||
|
||||
}, this.options.delayType);
|
||||
}
|
||||
else
|
||||
this._hideTooltip();
|
||||
}
|
||||
},
|
||||
|
||||
_fillRecordsCache: function() {
|
||||
//TODO important optimization!!! always append data in this._recordsCache
|
||||
// now _recordsCache content is emptied and replaced with new data founded
|
||||
// always appending data on _recordsCache give the possibility of caching ajax, jsonp and layersearch!
|
||||
//
|
||||
//TODO here insert function that search inputText FIRST in _recordsCache keys and if not find results..
|
||||
// run one of callbacks search(callData,jsonpUrl or options.layer) and run this.showTooltip
|
||||
//
|
||||
//TODO change structure of _recordsCache
|
||||
// like this: _recordsCache = {"text-key1": {loc:[lat,lng], ..other attributes.. }, {"text-key2": {loc:[lat,lng]}...}, ...}
|
||||
// in this mode every record can have a free structure of attributes, only 'loc' is required
|
||||
|
||||
var inputText = this._input.value,
|
||||
that;
|
||||
|
||||
L.DomUtil.addClass(this._container, 'search-load');
|
||||
|
||||
if(this.options.callData) //CUSTOM SEARCH CALLBACK(USUALLY FOR AJAX SEARCHING)
|
||||
{
|
||||
that = this;
|
||||
this.options.callData(inputText, function(jsonraw) {
|
||||
|
||||
that._recordsCache = that._filterJSON(jsonraw);
|
||||
|
||||
that.showTooltip();
|
||||
|
||||
L.DomUtil.removeClass(that._container, 'search-load');
|
||||
});
|
||||
}
|
||||
else if(this.options.url) //JSONP/AJAX REQUEST
|
||||
{
|
||||
if(this.options.jsonpParam)
|
||||
{
|
||||
that = this;
|
||||
this._recordsFromJsonp(inputText, function(data) {// is async request then it need callback
|
||||
that._recordsCache = data;
|
||||
that.showTooltip();
|
||||
L.DomUtil.removeClass(that._container, 'search-load');
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
that = this;
|
||||
this._recordsFromAjax(inputText, function(data) {// is async request then it need callback
|
||||
that._recordsCache = data;
|
||||
that.showTooltip();
|
||||
L.DomUtil.removeClass(that._container, 'search-load');
|
||||
});
|
||||
}
|
||||
}
|
||||
else if(this.options.layer) //SEARCH ELEMENTS IN PRELOADED LAYER
|
||||
{
|
||||
this._recordsCache = this._recordsFromLayer(); //fill table key,value from markers into layer
|
||||
this.showTooltip();
|
||||
L.DomUtil.removeClass(this._container, 'search-load');
|
||||
}
|
||||
},
|
||||
|
||||
_handleAutoresize: function() { //autoresize this._input
|
||||
//TODO refact _handleAutoresize now is not accurate
|
||||
if (this._input.style.maxWidth != this._map._container.offsetWidth) //If maxWidth isn't the same as when first set, reset to current Map width
|
||||
this._input.style.maxWidth = L.DomUtil.getStyle(this._map._container, 'width');
|
||||
|
||||
if(this.options.autoResize && (this._container.offsetWidth + 45 < this._map._container.offsetWidth))
|
||||
this._input.size = this._input.value.length<this._inputMinSize ? this._inputMinSize : this._input.value.length;
|
||||
},
|
||||
|
||||
_handleArrowSelect: function(velocity) {
|
||||
|
||||
var searchTips = this._tooltip.hasChildNodes() ? this._tooltip.childNodes : [];
|
||||
|
||||
for (i=0; i<searchTips.length; i++)
|
||||
L.DomUtil.removeClass(searchTips[i], 'search-tip-select');
|
||||
|
||||
if ((velocity == 1 ) && (this._tooltip.currentSelection >= (searchTips.length - 1))) {// If at end of list.
|
||||
L.DomUtil.addClass(searchTips[this._tooltip.currentSelection], 'search-tip-select');
|
||||
}
|
||||
else if ((velocity == -1 ) && (this._tooltip.currentSelection <= 0)) { // Going back up to the search box.
|
||||
this._tooltip.currentSelection = -1;
|
||||
}
|
||||
else if (this._tooltip.style.display != 'none') { // regular up/down
|
||||
this._tooltip.currentSelection += velocity;
|
||||
|
||||
L.DomUtil.addClass(searchTips[this._tooltip.currentSelection], 'search-tip-select');
|
||||
|
||||
this._input.value = searchTips[this._tooltip.currentSelection]._text;
|
||||
|
||||
// scroll:
|
||||
var tipOffsetTop = searchTips[this._tooltip.currentSelection].offsetTop;
|
||||
|
||||
if (tipOffsetTop + searchTips[this._tooltip.currentSelection].clientHeight >= this._tooltip.scrollTop + this._tooltip.clientHeight) {
|
||||
this._tooltip.scrollTop = tipOffsetTop - this._tooltip.clientHeight + searchTips[this._tooltip.currentSelection].clientHeight;
|
||||
}
|
||||
else if (tipOffsetTop <= this._tooltip.scrollTop) {
|
||||
this._tooltip.scrollTop = tipOffsetTop;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_handleSubmit: function() { //button and tooltip click and enter submit
|
||||
|
||||
this._hideAutoType();
|
||||
|
||||
this.hideAlert();
|
||||
this._hideTooltip();
|
||||
|
||||
if(this._input.style.display == 'none') //on first click show _input only
|
||||
this.expand();
|
||||
else
|
||||
{
|
||||
if(this._input.value === '') //hide _input only
|
||||
this.collapse();
|
||||
else
|
||||
{
|
||||
var loc = this._getLocation(this._input.value);
|
||||
|
||||
if(loc===false)
|
||||
this.showAlert();
|
||||
else
|
||||
{
|
||||
this.showLocation(loc, this._input.value);
|
||||
this.fire('search_locationfound', {
|
||||
latlng: loc,
|
||||
text: this._input.value,
|
||||
layer: loc.layer ? loc.layer : null
|
||||
});
|
||||
}
|
||||
//this.collapse();
|
||||
//FIXME if collapse in _handleSubmit hide _markerLoc!
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_getLocation: function(key) { //extract latlng from _recordsCache
|
||||
|
||||
if( this._recordsCache.hasOwnProperty(key) )
|
||||
return this._recordsCache[key];//then after use .loc attribute
|
||||
else
|
||||
return false;
|
||||
},
|
||||
|
||||
showLocation: function(latlng, title) { //set location on map from _recordsCache
|
||||
|
||||
if(this.options.zoom)
|
||||
this._map.setView(latlng, this.options.zoom);
|
||||
else
|
||||
this._map.panTo(latlng);
|
||||
|
||||
if(this._markerLoc)
|
||||
{
|
||||
this._markerLoc.setLatLng(latlng); //show circle/marker in location found
|
||||
this._markerLoc.setTitle(title);
|
||||
this._markerLoc.show();
|
||||
if(this.options.animateLocation)
|
||||
this._markerLoc.animate();
|
||||
//TODO showLocation: start animation after setView or panTo, maybe with map.on('moveend')...
|
||||
}
|
||||
|
||||
//FIXME autoCollapse option hide this._markerLoc before that visualized!!
|
||||
if(this.options.autoCollapse)
|
||||
this.collapse();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
var SearchMarker = L.Marker.extend({
|
||||
|
||||
includes: L.Mixin.Events,
|
||||
|
||||
options: {
|
||||
radius: 10,
|
||||
weight: 3,
|
||||
color: '#e03',
|
||||
stroke: true,
|
||||
fill: false,
|
||||
title: '',
|
||||
//TODO add custom icon!
|
||||
marker: false //show icon optional, show only circleLoc
|
||||
},
|
||||
|
||||
initialize: function (latlng, options) {
|
||||
L.setOptions(this, options);
|
||||
L.Marker.prototype.initialize.call(this, latlng, options);
|
||||
this._circleLoc = new L.CircleMarker(latlng, this.options);
|
||||
//TODO add inner circle
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
L.Marker.prototype.onAdd.call(this, map);
|
||||
map.addLayer(this._circleLoc);
|
||||
this.hide();
|
||||
},
|
||||
|
||||
onRemove: function (map) {
|
||||
L.Marker.prototype.onRemove.call(this, map);
|
||||
map.removeLayer(this._circleLoc);
|
||||
},
|
||||
|
||||
setLatLng: function (latlng) {
|
||||
L.Marker.prototype.setLatLng.call(this, latlng);
|
||||
this._circleLoc.setLatLng(latlng);
|
||||
return this;
|
||||
},
|
||||
|
||||
setTitle: function(title) {
|
||||
title = title || '';
|
||||
this.options.title = title;
|
||||
if(this._icon)
|
||||
this._icon.title = title;
|
||||
return this;
|
||||
},
|
||||
|
||||
show: function() {
|
||||
if(this.options.marker)
|
||||
{
|
||||
if(this._icon)
|
||||
this._icon.style.display = 'block';
|
||||
if(this._shadow)
|
||||
this._shadow.style.display = 'block';
|
||||
//this._bringToFront();
|
||||
}
|
||||
if(this._circleLoc)
|
||||
{
|
||||
this._circleLoc.setStyle({fill: this.options.fill, stroke: this.options.stroke});
|
||||
//this._circleLoc.bringToFront();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if(this._icon)
|
||||
this._icon.style.display = 'none';
|
||||
if(this._shadow)
|
||||
this._shadow.style.display = 'none';
|
||||
if(this._circleLoc)
|
||||
this._circleLoc.setStyle({fill: false, stroke: false});
|
||||
return this;
|
||||
},
|
||||
|
||||
animate: function() {
|
||||
//TODO refact animate() more smooth! like this: http://goo.gl/DDlRs
|
||||
var circle = this._circleLoc,
|
||||
tInt = 200, //time interval
|
||||
ss = 10, //frames
|
||||
mr = parseInt(circle._radius/ss),
|
||||
oldrad = this.options.radius,
|
||||
newrad = circle._radius * 2.5,
|
||||
acc = 0;
|
||||
|
||||
circle._timerAnimLoc = setInterval(function() {
|
||||
acc += 0.5;
|
||||
mr += acc; //adding acceleration
|
||||
newrad -= mr;
|
||||
|
||||
circle.setRadius(newrad);
|
||||
|
||||
if(newrad<oldrad)
|
||||
{
|
||||
clearInterval(circle._timerAnimLoc);
|
||||
circle.setRadius(oldrad);//reset radius
|
||||
//if(typeof afterAnimCall == 'function')
|
||||
//afterAnimCall();
|
||||
//TODO use create event 'animateEnd' in SearchMarker
|
||||
}
|
||||
}, tInt);
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.addInitHook(function () {
|
||||
if (this.options.searchControl) {
|
||||
this.searchControl = L.control.search(this.options.searchControl);
|
||||
this.addControl(this.searchControl);
|
||||
}
|
||||
});
|
||||
|
||||
L.control.search = function (options) {
|
||||
return new L.Control.Search(options);
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
||||
67
bower_components/leaflet-search/src/leaflet-search.mobile.css
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
|
||||
/* SEARCH */
|
||||
.leaflet-control.leaflet-control-search {
|
||||
z-index:2000;
|
||||
}
|
||||
.leaflet-control-search .search-input {
|
||||
display:block;
|
||||
float:left;
|
||||
background: #fff;
|
||||
border:1px solid #666;
|
||||
border-radius:2px;
|
||||
height:24px;
|
||||
font-size:1.25em;
|
||||
padding:0 .125em;
|
||||
margin:3px;
|
||||
padding-right:30px;
|
||||
}
|
||||
.leaflet-control-search .search-button:hover,
|
||||
.leaflet-control-search .search-button {
|
||||
background-image: url('../images/search-icon-mobile.png');
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
background-position: 1px 1px;
|
||||
width:32px;
|
||||
height:32px;
|
||||
}
|
||||
.leaflet-control-search.search-load .search-input {
|
||||
background: url('../images/loader.gif') no-repeat center right #fff;
|
||||
}
|
||||
.leaflet-control-search .search-cancel {
|
||||
background-image: url('../images/search-icon-mobile.png');
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
background-position: 0px -62px;
|
||||
width:26px;
|
||||
height:26px;
|
||||
right:34px;
|
||||
margin:3px;
|
||||
}
|
||||
.leaflet-control-search .search-tooltip {
|
||||
max-height:142px;/*(.search-tip height * 5)*/
|
||||
}
|
||||
.leaflet-control-search .search-tip {
|
||||
font-size:1em;
|
||||
margin:2px;
|
||||
padding:2px;
|
||||
display:block;
|
||||
color:black;
|
||||
background: rgba(255,255,255,0.8);
|
||||
border-radius:.25em;
|
||||
text-decoration:none;
|
||||
white-space:nowrap;
|
||||
vertical-align:center;
|
||||
}
|
||||
.leaflet-control-search .search-tip .climbo-icon-mini {
|
||||
float:right;
|
||||
display:block;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.leaflet-control-search .search-button:hover,
|
||||
.leaflet-control-search .search-tip-select,
|
||||
.leaflet-control-search .search-tip:hover {
|
||||
background-color: #fff;
|
||||
}
|
||||
.leaflet-control-search .search-alert {
|
||||
font-size:1.2em;
|
||||
}
|
||||
97
bower_components/leaflet-search/style.css
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
body {
|
||||
background:#b5d0d0;
|
||||
color:#285585;
|
||||
font-family:Arial;
|
||||
}
|
||||
body#home {
|
||||
background:url('images/back.png') no-repeat top left #b5d0d0;
|
||||
margin-left:150px;
|
||||
}
|
||||
|
||||
a {
|
||||
color:#1978cf;
|
||||
}
|
||||
a:hover {
|
||||
color:#fff;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
white-space:nowrap;
|
||||
margin:1em 0 0 0;
|
||||
}
|
||||
h3 a,
|
||||
h3 a:hover {
|
||||
text-decoration:none;
|
||||
}
|
||||
#desc {
|
||||
float: left;
|
||||
margin-bottom: 1em;
|
||||
position: relative;
|
||||
white-space:nowrap;
|
||||
font-size:1em;
|
||||
}
|
||||
#map {
|
||||
border-radius:.125em;
|
||||
border:2px solid #1978cf;
|
||||
box-shadow: 0 0 8px #999;
|
||||
float:left;
|
||||
width:600px;
|
||||
height:400px;
|
||||
}
|
||||
ul {
|
||||
font-size:.85em;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
li {
|
||||
margin:0 0 2px 18px;
|
||||
}
|
||||
#post-it {
|
||||
width:9em;
|
||||
height:9em;
|
||||
margin-left:2em;
|
||||
padding:1em;
|
||||
float:left;
|
||||
background:#fbf5bf;
|
||||
border:1px solid #c6bb58;
|
||||
box-shadow: 2px 2px 6px #999;
|
||||
color:#666;
|
||||
}
|
||||
#copy {
|
||||
position:fixed;
|
||||
z-index:1000;
|
||||
right:150px;
|
||||
top:-8px;
|
||||
font-size:.85em;
|
||||
padding:8px 8px 2px 8px;
|
||||
background: #323b44;
|
||||
border: 2px solid #737c85;
|
||||
border-radius:.7em;
|
||||
opacity: 0.9;
|
||||
box-shadow:0 0 8px #5f7182;
|
||||
color:#eee
|
||||
}
|
||||
#copy a {
|
||||
color:#ccc;
|
||||
text-decoration:none
|
||||
}
|
||||
#copy a:hover {
|
||||
color:#fff
|
||||
}
|
||||
#ribbon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
border: 0;
|
||||
filter: alpha(opacity=80);
|
||||
-khtml-opacity: .8;
|
||||
-moz-opacity: .8;
|
||||
opacity: .8;
|
||||
}
|
||||
.contents {
|
||||
float:left;
|
||||
margin:0 2em 2em 0;
|
||||
}
|
||||
#comments {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
22
bower_components/normalize-css/.bower.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "normalize-css",
|
||||
"version": "2.1.3",
|
||||
"main": "normalize.css",
|
||||
"author": "Nicolas Gallagher",
|
||||
"ignore": [
|
||||
"CHANGELOG.md",
|
||||
"CONTRIBUTING.md",
|
||||
"component.json",
|
||||
"test.html"
|
||||
],
|
||||
"homepage": "https://github.com/necolas/normalize.css",
|
||||
"_release": "2.1.3",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v2.1.3",
|
||||
"commit": "be14934fad255a01ed345de6ae59ff612adcf3b9"
|
||||
},
|
||||
"_source": "git://github.com/necolas/normalize.css.git",
|
||||
"_target": "*",
|
||||
"_originalSource": "normalize-css"
|
||||
}
|
||||
19
bower_components/normalize-css/LICENSE.md
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) Nicolas Gallagher and Jonathan Neal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
54
bower_components/normalize-css/README.md
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# normalize.css v2
|
||||
|
||||
Normalize.css is a customisable CSS file that makes browsers render all
|
||||
elements more consistently and in line with modern standards.
|
||||
|
||||
The project relies on researching the differences between default browser
|
||||
styles in order to precisely target only the styles that need or benefit from
|
||||
normalizing.
|
||||
|
||||
[Check out the demo](http://necolas.github.io/normalize.css/latest/test.html)
|
||||
|
||||
## Install
|
||||
|
||||
Download from the [project page](http://necolas.github.io/normalize.css/).
|
||||
|
||||
Install with [Bower](http://bower.io/): `bower install --save normalize-css`
|
||||
|
||||
Install with [Component(1)](http://component.io/): `component install necolas/normalize.css`
|
||||
|
||||
## What does it do?
|
||||
|
||||
* Preserves useful defaults, unlike many CSS resets.
|
||||
* Normalizes styles for a wide range of elements.
|
||||
* Corrects bugs and common browser inconsistencies.
|
||||
* Improves usability with subtle improvements.
|
||||
* Explains what code does using detailed comments.
|
||||
|
||||
## How to use it
|
||||
|
||||
No other styles should come before Normalize.css.
|
||||
|
||||
It is recommended that you include the `normalize.css` file as untouched
|
||||
library code.
|
||||
|
||||
## Browser support
|
||||
|
||||
* Google Chrome
|
||||
* Mozilla Firefox 4+
|
||||
* Apple Safari 5+
|
||||
* Opera 12+
|
||||
* Internet Explorer 8+
|
||||
|
||||
[Normalize.css v1 provides legacy browser
|
||||
support](https://github.com/necolas/normalize.css/tree/v1) (IE 6+, Safari 4+),
|
||||
but is no longer actively developed.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please read the CONTRIBUTING.md
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Normalize.css is a project by [Nicolas Gallagher](https://github.com/necolas),
|
||||
co-created with [Jonathan Neal](https://github.com/jonathantneal).
|
||||
12
bower_components/normalize-css/bower.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "normalize-css",
|
||||
"version": "2.1.3",
|
||||
"main": "normalize.css",
|
||||
"author": "Nicolas Gallagher",
|
||||
"ignore": [
|
||||
"CHANGELOG.md",
|
||||
"CONTRIBUTING.md",
|
||||
"component.json",
|
||||
"test.html"
|
||||
]
|
||||
}
|
||||