Initial commit
No files matched your search
@@ -0,0 +1,39 @@
|
||||
// Web Socket
|
||||
export function webSocketConnect() {
|
||||
var ws = new WebSocket (document.getElementById('connectInput').value);
|
||||
ws.onopen = function () {
|
||||
document.getElementById('connectBtn').classList.replace("btn-outline-danger", "btn-outline-success")
|
||||
servicePortsInformationRequest(ws);
|
||||
}
|
||||
|
||||
ws.onmessage = function(msg) {
|
||||
console.log(JSON.parse(msg.data).data)
|
||||
|
||||
var exercises = new Map;
|
||||
var object = (JSON.parse(msg.data)).data;
|
||||
object.forEach((item, index, array) => {
|
||||
if (item.exercisesId != 0) {
|
||||
console.log (item.exerciseId)
|
||||
exercises.set(item.exerciseId, item);
|
||||
document.getElementById('exerciseSelect').innerHTML += `<option value=${item.exerciseId}>Exercise ${item.exerciseId}</option>`
|
||||
}
|
||||
console.log(exercises)
|
||||
})
|
||||
|
||||
document.getElementById('exerciseSelect').disabled = false;
|
||||
document.getElementById('exerciseBtn').disabled = false;
|
||||
}
|
||||
|
||||
ws.onclose = function() {
|
||||
document.getElementById('connectBtn').classList.replace("btn-outline-success", "btn-outline-danger")
|
||||
}
|
||||
}
|
||||
|
||||
// Request
|
||||
function servicePortsInformationRequest(ws) {
|
||||
|
||||
ws.send(JSON.stringify({
|
||||
type: "servicePortsInformationRequest",
|
||||
uuid: "UUID"
|
||||
}));
|
||||
}
|
||||
@@ -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.
|
||||
@@ -0,0 +1,396 @@
|
||||
# GPX plugin for Leaflet
|
||||
|
||||
[](https://cdnjs.com/libraries/leaflet-gpx)
|
||||
|
||||
[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. First, include the Leaflet.js and Leaflet-GPX
|
||||
scripts in your HTML page:
|
||||
|
||||
```html
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.css" />
|
||||
<!-- ... -->
|
||||
</head>
|
||||
<body>
|
||||
<!-- ... -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-gpx/1.4.0/gpx.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Now, 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 a GPX track on it 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);
|
||||
```
|
||||
|
||||
Some GPX tracks contain the actual route/track twice, both the `<trk>` and
|
||||
`<rte>` elements are used. You can tell `leaflet-gpx` which tag to use or to
|
||||
use both (which is the default setting for backwards compatibility) with the
|
||||
`gpx_options` object in the second argument of the constructor. The member
|
||||
`parseElements` controls this behavior, it should be an array that contains
|
||||
`'route'` and/or `'track'`.
|
||||
|
||||
### Available functions
|
||||
|
||||
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_moving_speed()`: returns the average moving speed in km per hour
|
||||
* `get_total_speed()`: returns the average total speed in km per hour
|
||||
* `get_elevation_min()`: returns the lowest elevation, in meters
|
||||
* `get_elevation_max()`: returns the highest elevation, in meters
|
||||
* `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)
|
||||
* `get_average_cadence()`: returns the average cadence (if available)
|
||||
* `get_average_temp()`: returns the average of the temperature (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
|
||||
hour
|
||||
* `get_moving_speed_imp()`: returns the average moving speed in miles per hour
|
||||
* `get_total_speed_imp()`: returns the average total speed in miles per hour
|
||||
* `get_elevation_min_imp()`: returns the lowest elevation, in feet
|
||||
* `get_elevation_max_imp()`: returns the highest elevation, in feet
|
||||
* `get_elevation_gain_imp()`: returns the cumulative elevation gain, in feet
|
||||
* `get_elevation_loss_imp()`: returns the cumulative elevation loss, in feet
|
||||
|
||||
The reason why these methods return milliseconds is that you have at your
|
||||
disposal nice helper methods to format a duration in milliseconds into a cool
|
||||
string:
|
||||
|
||||
* `get_duration_string(duration, hidems)` format to a string like `3:07'48"`
|
||||
or `59'32.431`, where `duration` is in
|
||||
milliseconds and `hidems` is an optional boolean you can use to request never
|
||||
to display millisecond precision.
|
||||
* `get_duration_string_iso(duration, hidems)` formats to an ISO like
|
||||
representation like `3:07:48` or `59:32.431`, 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, heartrate, cadence and temperature data with:
|
||||
|
||||
* `get_elevation_data()` and `get_elevation_data_imp()`
|
||||
* `get_heartrate_data()` and `get_heartrate_data_imp()`
|
||||
* `get_cadence_data()` and `get_cadence_data_imp()`
|
||||
* `get_temp_data()` and `get_temp_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 or
|
||||
feet, depending on whether you use the `_imp` variant or not. Heart rate,
|
||||
obviously, doesn't change.
|
||||
|
||||
### Reloading
|
||||
|
||||
You can make `leaflet-gpx` reload the source GPX file by calling the
|
||||
`reload()` method. For example, to trigger a reload every 5 seconds, you
|
||||
can do:
|
||||
|
||||
```javascript
|
||||
var gpx = new L.GPX(gpxFile);
|
||||
setInterval(function() {
|
||||
gpx.reload();
|
||||
}, 5000);
|
||||
```
|
||||
|
||||
## 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);
|
||||
```
|
||||
|
||||
## About waypoints
|
||||
|
||||
By default `gpx.js` will parse Waypoints from a GPX file. This may also
|
||||
be steered via the value `waypoint` in `gpx_options`, e.g.
|
||||
`parseElements: ['track', 'route', 'waypoint']`.
|
||||
|
||||
Waypoint icons: by default the `pin-icon-wpt.png` icon is shown for each
|
||||
waypoint. This can be overridden by setting `marker_options.wptIconUrls`
|
||||
in the `L.GPX` constructor options, as a mapping from the waypoint "SYM"
|
||||
name to a user-supplied icon file or URL. The empty string `''` is used
|
||||
by the waypoint tag does not define a "SYM" name. See the example below:
|
||||
|
||||
```javascript
|
||||
new L.GPX(app.params.gpx_url, {
|
||||
async: true,
|
||||
marker_options: {
|
||||
wptIconUrls: {
|
||||
'': 'img/gpx/default-waypoint.png',
|
||||
'Geocache Found': 'img/gpx/geocache.png',
|
||||
'Park': 'img/gpx/tree.png'
|
||||
},
|
||||
...
|
||||
shadowUrl: 'http://github.com/mpetazzoni/leaflet-gpx/raw/master/pin-shadow.png'
|
||||
}
|
||||
}).on('loaded', function (e) {
|
||||
var gpx = e.target;
|
||||
map.fitBounds(gpx.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
## Custom markers
|
||||
|
||||
You can also use your own icons/markers if you want to use custom
|
||||
markers, for example from `leaflet-awesome-markers`. To specify you own
|
||||
markers, set `startIcon`, `endIcon`, and a map of `wptIcons` by waypoint
|
||||
symbol (see above). Those should be marker icon objects usable by
|
||||
Leaflet as the `icon` property of a `L.Marker` object.
|
||||
|
||||
```javascript
|
||||
new L.GPX(app.params.gpx_url, {
|
||||
async: true,
|
||||
marker_options: {
|
||||
wptIcons: {
|
||||
'Coffee shop': new L.AwesomeMarkers.icon({
|
||||
icon: 'coffee',
|
||||
prefix: 'fa',
|
||||
markerColor: 'blue',
|
||||
iconColor: 'white'
|
||||
})
|
||||
}
|
||||
}
|
||||
}).on('loaded', function (e) {
|
||||
var gpx = e.target;
|
||||
map.fitBounds(gpx.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
## Named points
|
||||
|
||||
GPX points can be named, for example to denote certain POIs (points of
|
||||
interest). You can setup rules to match point names to create labeled
|
||||
markers for those points by providing a `pointMatchers` array in the
|
||||
`marker_options`. Each element in this array must define a `regex` to
|
||||
match the point's name and an `icon` object (any `L.Marker` or
|
||||
for example an `L.AwesomeMarkers.icon` as shown above in _Custom
|
||||
markers_).
|
||||
|
||||
Each named point in the GPX track is evaluated against those rules and
|
||||
a marker is created with the point's name as label from the first
|
||||
matching rule.
|
||||
|
||||
```javascript
|
||||
new L.GPX(app.params.gpx_url, {
|
||||
async: true,
|
||||
marker_options: {
|
||||
pointMatchers: [
|
||||
{
|
||||
regex: /Coffee/,
|
||||
icon: new L.AwesomeMarkers.icon({
|
||||
icon: 'coffee',
|
||||
markerColor: 'blue',
|
||||
iconColor: 'white'
|
||||
}),
|
||||
},
|
||||
{
|
||||
regex: /Home/,
|
||||
icon: new L.AwesomeMarkers.icon({
|
||||
icon: 'home',
|
||||
markerColor: 'green',
|
||||
iconColor: 'white'
|
||||
}),
|
||||
}
|
||||
]
|
||||
}
|
||||
}).on('loaded', function(e) {
|
||||
var gpx = e.target;
|
||||
map.fitToBounds(gpx.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
Events are fired on the `L.GPX` object as the GPX data is being parsed
|
||||
and the map layers generated. You can listen for those events by
|
||||
attaching the corresponding event listener on the `L.GPX` object:
|
||||
|
||||
```javascript
|
||||
new L.GPX(app.params.gpx_url, {
|
||||
// options
|
||||
}).on('addpoint', function(e) {
|
||||
console.log('Added ' + e.point_type + ' point: ' + e.point);
|
||||
}).on('loaded', function(e) {
|
||||
var gpx = e.target;
|
||||
map.fitToBounds(gpx.getBounds());
|
||||
}).on('error', function(e) {
|
||||
console.log('Error loading file: ' + e.err);
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
`addpoint` events are fired for every marker added to the map, in
|
||||
particular for the start and end points, all the waypoints, and all the
|
||||
named points that matched `pointMatchers` rules. Each `addpoint` event
|
||||
contains the following properties:
|
||||
|
||||
- `point`: the marker object itself, from which you can get or modify
|
||||
the latitude and longitude of the point and any other attribute of the
|
||||
marker.
|
||||
- `point_type`: one of `start`, `end`, `waypoint` or `label`, allowing
|
||||
you to identify what type of point the marker is for.
|
||||
- `element`: the track point element the marker was created for.
|
||||
|
||||
One use case for those events is for example to attach additional
|
||||
content or behavior to the markers that were generated (popups, etc).
|
||||
|
||||
`error` events are fired when no layers of the type(s) specified in
|
||||
`options.gpx_options.parseElements` can be parsed out of the given
|
||||
file. For instance, `error` would be fired if a file with no waypoints
|
||||
was attempted to be loaded with `parseElements` set to `['waypoint']`.
|
||||
Each `error` event contains the following property:
|
||||
|
||||
- `err`: a message with details about the error that occurred.
|
||||
|
||||
## Line styling
|
||||
|
||||
`leaflet-gpx` understands the [GPX
|
||||
Style](http://www.topografix.com/GPX/gpx_style/0/2) extension, and will
|
||||
extract styling information defined on routes and track segments to use
|
||||
for drawing the corresponding polyline.
|
||||
|
||||
```xml
|
||||
<trkseg>
|
||||
<extensions>
|
||||
<line xmlns="http://www.topografix.com/GPX/gpx_style/0/2">
|
||||
<color>FF0000</color>
|
||||
<opacity>0.5</opacity>
|
||||
<weight>1</weight>
|
||||
<linecap>square</linecap>
|
||||
</line>
|
||||
</extensions>
|
||||
<trkpt lat="..." lon="..."></trkpt>
|
||||
</trkseg>
|
||||
```
|
||||
|
||||
You can override the style of the lines by passing a `polyline_options`
|
||||
object into the `options` argument of the `L.GPX` constructor:
|
||||
|
||||
```javascript
|
||||
new L.GPX(url, {
|
||||
polyline_options: {
|
||||
color: 'green',
|
||||
opacity: 0.75,
|
||||
weight: 3,
|
||||
lineCap: 'round'
|
||||
}
|
||||
}).on('loaded', function(e) {
|
||||
var gpx = e.target;
|
||||
map.fitToBounds(gpx.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
For more information on the available polyline styling options, refer to
|
||||
the [Leaflet documentation on
|
||||
Polyline](https://leafletjs.com/reference-1.3.0.html#polyline). By
|
||||
default, if no styling is available, the line will be drawn in _blue_.
|
||||
|
||||
## GPX parsing options
|
||||
|
||||
### Multiple track segments within each track
|
||||
|
||||
GPX file may contain multiple tracks represented by `<trk>` elements,
|
||||
each track possibly composed of multiple segments with `<trkseg>`
|
||||
elements. Although this plugin will always represent each GPX route and
|
||||
each GPX track as distinct entities with their own start and end
|
||||
markers, track segments will by default be joined into a single line.
|
||||
|
||||
You can disable this behavior by setting the `joinTrackSegments` flag to
|
||||
`false` in the `gpx_options`:
|
||||
|
||||
```javascript
|
||||
new L.GPX(url, {
|
||||
gpx_options: {
|
||||
joinTrackSegments: false
|
||||
}
|
||||
}).on('loaded', function(e) {
|
||||
map.fitBounds(e.target.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
## Caveats
|
||||
|
||||
* Distance calculation is relatively accurate, but elevation change
|
||||
calculation is not topographically adjusted, so the total elevation
|
||||
gain/loss/change might appear inaccurate in some situations.
|
||||
* Currently doesn't seem to work in IE8/9. See #9 and #11 for
|
||||
discussion.
|
||||
@@ -0,0 +1,600 @@
|
||||
/**
|
||||
* Copyright (C) 2011-2012 Pavel Shramov
|
||||
* Copyright (C) 2013-2017 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 L = L || require('leaflet');
|
||||
|
||||
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 _DAY_IN_MILLIS = 24 * _HOUR_IN_MILLIS;
|
||||
|
||||
var _GPX_STYLE_NS = 'http://www.topografix.com/GPX/gpx_style/0/2';
|
||||
|
||||
var _DEFAULT_MARKER_OPTS = {
|
||||
startIconUrl: 'pin-icon-start.png',
|
||||
endIconUrl: 'pin-icon-end.png',
|
||||
shadowUrl: 'pin-shadow.png',
|
||||
wptIcons: [],
|
||||
wptIconUrls : {
|
||||
'': 'pin-icon-wpt.png',
|
||||
},
|
||||
pointMatchers: [],
|
||||
iconSize: [33, 50],
|
||||
shadowSize: [50, 50],
|
||||
iconAnchor: [16, 45],
|
||||
shadowAnchor: [16, 47],
|
||||
clickable: false
|
||||
};
|
||||
var _DEFAULT_POLYLINE_OPTS = {
|
||||
color: 'blue'
|
||||
};
|
||||
var _DEFAULT_GPX_OPTS = {
|
||||
parseElements: ['track', 'route', 'waypoint'],
|
||||
joinTrackSegments: true
|
||||
};
|
||||
|
||||
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 = options.polyline_options || {};
|
||||
options.gpx_options = this._merge_objs(
|
||||
_DEFAULT_GPX_OPTS,
|
||||
options.gpx_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._init_info();
|
||||
|
||||
if (gpx) {
|
||||
this._parse(gpx, options, this.options.async);
|
||||
}
|
||||
},
|
||||
|
||||
get_duration_string: function(duration, hidems) {
|
||||
var s = '';
|
||||
|
||||
if (duration >= _DAY_IN_MILLIS) {
|
||||
s += Math.floor(duration / _DAY_IN_MILLIS) + 'd ';
|
||||
duration = duration % _DAY_IN_MILLIS;
|
||||
}
|
||||
|
||||
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;
|
||||
},
|
||||
|
||||
get_duration_string_iso: function(duration, hidems) {
|
||||
var s = this.get_duration_string(duration, hidems);
|
||||
return s.replace("'",':').replace('"','');
|
||||
},
|
||||
|
||||
// Public methods
|
||||
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_desc: function() { return this._info.desc; },
|
||||
get_author: function() { return this._info.author; },
|
||||
get_copyright: function() { return this._info.copyright; },
|
||||
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_moving_speed: function() { return this.m_to_km(this.get_distance()) / (this.get_moving_time() / (3600 * 1000)) ; },
|
||||
get_moving_speed_imp:function() { return this.to_miles(this.m_to_km(this.get_distance())) / (this.get_moving_time() / (3600 * 1000)) ; },
|
||||
|
||||
get_total_speed: function() { return this.m_to_km(this.get_distance()) / (this.get_total_time() / (3600 * 1000)); },
|
||||
get_total_speed_imp: function() { return this.to_miles(this.m_to_km(this.get_distance())) / (this.get_total_time() / (3600 * 1000)); },
|
||||
|
||||
get_elevation_gain: function() { return this._info.elevation.gain; },
|
||||
get_elevation_loss: function() { return this._info.elevation.loss; },
|
||||
get_elevation_gain_imp: function() { return this.to_ft(this.get_elevation_gain()); },
|
||||
get_elevation_loss_imp: function() { return this.to_ft(this.get_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_elevation_max: function() { return this._info.elevation.max; },
|
||||
get_elevation_min: function() { return this._info.elevation.min; },
|
||||
get_elevation_max_imp: function() { return this.to_ft(this.get_elevation_max()); },
|
||||
get_elevation_min_imp: function() { return this.to_ft(this.get_elevation_min()); },
|
||||
|
||||
get_average_hr: function() { return this._info.hr.avg; },
|
||||
get_average_temp: function() { return this._info.atemp.avg; },
|
||||
get_average_cadence: function() { return this._info.cad.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'; });
|
||||
});
|
||||
},
|
||||
get_cadence_data: function() {
|
||||
var _this = this;
|
||||
return this._info.cad._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) + ' rpm'; });
|
||||
});
|
||||
},
|
||||
get_temp_data: function() {
|
||||
var _this = this;
|
||||
return this._info.atemp._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) + ' degrees'; });
|
||||
});
|
||||
},
|
||||
get_cadence_data_imp: function() {
|
||||
var _this = this;
|
||||
return this._info.cad._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) + ' rpm'; });
|
||||
});
|
||||
},
|
||||
get_temp_data_imp: function() {
|
||||
var _this = this;
|
||||
return this._info.atemp._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) + ' degrees'; });
|
||||
});
|
||||
},
|
||||
|
||||
reload: function() {
|
||||
this._init_info();
|
||||
this.clearLayers();
|
||||
this._parse(this._gpx, this.options, this.options.async);
|
||||
},
|
||||
|
||||
// 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;
|
||||
},
|
||||
|
||||
_init_info: function() {
|
||||
this._info = {
|
||||
name: null,
|
||||
length: 0.0,
|
||||
elevation: {gain: 0.0, loss: 0.0, max: 0.0, min: Infinity, _points: []},
|
||||
hr: {avg: 0, _total: 0, _points: []},
|
||||
duration: {start: null, end: null, moving: 0, total: 0},
|
||||
atemp: {avg: 0, _total: 0, _points: []},
|
||||
cad: {avg: 0, _total: 0, _points: []}
|
||||
};
|
||||
},
|
||||
|
||||
_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) {
|
||||
_this.fire('error', { err: 'No parseable layers of type(s) ' + JSON.stringify(options.gpx_options.parseElements) });
|
||||
return;
|
||||
}
|
||||
_this.addLayer(layers);
|
||||
_this.fire('loaded', { layers: layers, element: gpx });
|
||||
}
|
||||
if (input.substr(0,1)==='<') { // direct XML has to start with a <
|
||||
var parser = new DOMParser();
|
||||
if (async) {
|
||||
setTimeout(function() {
|
||||
cb(parser.parseFromString(input, "text/xml"), options);
|
||||
});
|
||||
} else {
|
||||
cb(parser.parseFromString(input, "text/xml"), options);
|
||||
}
|
||||
} else {
|
||||
this._load_xml(input, cb, options, async);
|
||||
}
|
||||
},
|
||||
|
||||
_parse_gpx_data: function(xml, options) {
|
||||
var i, t, l, el, layers = [];
|
||||
|
||||
var name = xml.getElementsByTagName('name');
|
||||
if (name.length > 0) {
|
||||
this._info.name = name[0].textContent;
|
||||
}
|
||||
var desc = xml.getElementsByTagName('desc');
|
||||
if (desc.length > 0) {
|
||||
this._info.desc = desc[0].textContent;
|
||||
}
|
||||
var author = xml.getElementsByTagName('author');
|
||||
if (author.length > 0) {
|
||||
this._info.author = author[0].textContent;
|
||||
}
|
||||
var copyright = xml.getElementsByTagName('copyright');
|
||||
if (copyright.length > 0) {
|
||||
this._info.copyright = copyright[0].textContent;
|
||||
}
|
||||
|
||||
var parseElements = options.gpx_options.parseElements;
|
||||
if (parseElements.indexOf('route') > -1) {
|
||||
// routes are <rtept> tags inside <rte> sections
|
||||
var routes = xml.getElementsByTagName('rte');
|
||||
for (i = 0; i < routes.length; i++) {
|
||||
layers = layers.concat(this._parse_segment(routes[i], options, {}, 'rtept'));
|
||||
}
|
||||
}
|
||||
|
||||
if (parseElements.indexOf('track') > -1) {
|
||||
// tracks are <trkpt> tags in one or more <trkseg> sections in each <trk>
|
||||
var tracks = xml.getElementsByTagName('trk');
|
||||
for (i = 0; i < tracks.length; i++) {
|
||||
var track = tracks[i];
|
||||
var polyline_options = this._extract_styling(track);
|
||||
|
||||
if (options.gpx_options.joinTrackSegments) {
|
||||
layers = layers.concat(this._parse_segment(track, options, polyline_options, 'trkpt'));
|
||||
} else {
|
||||
var segments = track.getElementsByTagName('trkseg');
|
||||
for (j = 0; j < segments.length; j++) {
|
||||
layers = layers.concat(this._parse_segment(segments[j], options, polyline_options, 'trkpt'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._info.hr.avg = Math.round(this._info.hr._total / this._info.hr._points.length);
|
||||
this._info.cad.avg = Math.round(this._info.cad._total / this._info.cad._points.length);
|
||||
this._info.atemp.avg = Math.round(this._info.atemp._total / this._info.atemp._points.length);
|
||||
|
||||
// parse waypoints and add markers for each of them
|
||||
if (parseElements.indexOf('waypoint') > -1) {
|
||||
el = xml.getElementsByTagName('wpt');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
var ll = new L.LatLng(
|
||||
el[i].getAttribute('lat'),
|
||||
el[i].getAttribute('lon'));
|
||||
|
||||
var nameEl = el[i].getElementsByTagName('name');
|
||||
var name = '';
|
||||
if (nameEl.length > 0) {
|
||||
name = nameEl[0].textContent;
|
||||
}
|
||||
|
||||
var descEl = el[i].getElementsByTagName('desc');
|
||||
var desc = '';
|
||||
if (descEl.length > 0) {
|
||||
desc = descEl[0].textContent;
|
||||
}
|
||||
|
||||
var symEl = el[i].getElementsByTagName('sym');
|
||||
var symKey = '';
|
||||
if (symEl.length > 0) {
|
||||
symKey = symEl[0].textContent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add waypoint marker based on the waypoint symbol key.
|
||||
*
|
||||
* First look for a configured icon for that symKey. If not found, look
|
||||
* for a configured icon URL for that symKey and build an icon from it.
|
||||
* Otherwise, fall back to the default icon if one was configured, or
|
||||
* finally to the default icon URL.
|
||||
*/
|
||||
var wptIcons = options.marker_options.wptIcons;
|
||||
var wptIconUrls = options.marker_options.wptIconUrls;
|
||||
var symIcon;
|
||||
if (wptIcons && wptIcons[symKey]) {
|
||||
symIcon = wptIcons[symKey];
|
||||
} else if (wptIconUrls && wptIconUrls[symKey]) {
|
||||
symIcon = new L.GPXTrackIcon({iconUrl: wptIconUrls[symKey]});
|
||||
} else if (wptIcons && wptIcons['']) {
|
||||
symIcon = wptIcons[''];
|
||||
} else if (wptIconUrls && wptIconUrls['']) {
|
||||
symIcon = new L.GPXTrackIcon({iconUrl: wptIconUrls['']});
|
||||
} else {
|
||||
console.log('No icon or icon URL configured for symbol type "' + symKey
|
||||
+ '", and no fallback configured; ignoring waypoint.');
|
||||
continue;
|
||||
}
|
||||
|
||||
var marker = new L.Marker(ll, {
|
||||
clickable: options.marker_options.clickable,
|
||||
title: name,
|
||||
icon: symIcon
|
||||
});
|
||||
marker.bindPopup("<b>" + name + "</b>" + (desc.length > 0 ? '<br>' + desc : '')).openPopup();
|
||||
this.fire('addpoint', { point: marker, point_type: 'waypoint', element: el[i] });
|
||||
layers.push(marker);
|
||||
}
|
||||
}
|
||||
|
||||
if (layers.length > 1) {
|
||||
return new L.FeatureGroup(layers);
|
||||
} else if (layers.length == 1) {
|
||||
return layers[0];
|
||||
}
|
||||
},
|
||||
|
||||
_parse_segment: function(line, options, polyline_options, tag) {
|
||||
var el = line.getElementsByTagName(tag);
|
||||
if (!el.length) return [];
|
||||
|
||||
var coords = [];
|
||||
var markers = [];
|
||||
var layers = [];
|
||||
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, cad: null, atemp: null };
|
||||
|
||||
_ = el[i].getElementsByTagName('time');
|
||||
if (_.length > 0) {
|
||||
ll.meta.time = new Date(Date.parse(_[0].textContent));
|
||||
} else {
|
||||
ll.meta.time = new Date('1970-01-01T00:00:00');
|
||||
}
|
||||
|
||||
_ = el[i].getElementsByTagName('ele');
|
||||
if (_.length > 0) {
|
||||
ll.meta.ele = parseFloat(_[0].textContent);
|
||||
}
|
||||
|
||||
_ = el[i].getElementsByTagName('name');
|
||||
if (_.length > 0) {
|
||||
var name = _[0].textContent;
|
||||
var ptMatchers = options.marker_options.pointMatchers || [];
|
||||
|
||||
for (var j = 0; j < ptMatchers.length; j++) {
|
||||
if (ptMatchers[j].regex.test(name)) {
|
||||
markers.push({ label: name, coords: ll, icon: ptMatchers[j].icon, element: el[i] });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ = 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;
|
||||
}
|
||||
|
||||
_ = el[i].getElementsByTagNameNS('*', 'cad');
|
||||
if (_.length > 0) {
|
||||
ll.meta.cad = parseInt(_[0].textContent);
|
||||
this._info.cad._points.push([this._info.length, ll.meta.cad]);
|
||||
this._info.cad._total += ll.meta.cad;
|
||||
}
|
||||
|
||||
_ = el[i].getElementsByTagNameNS('*', 'atemp');
|
||||
if (_.length > 0) {
|
||||
ll.meta.atemp = parseInt(_[0].textContent);
|
||||
this._info.atemp._points.push([this._info.length, ll.meta.atemp]);
|
||||
this._info.atemp._total += ll.meta.atemp;
|
||||
}
|
||||
|
||||
if (ll.meta.ele > this._info.elevation.max) {
|
||||
this._info.elevation.max = ll.meta.ele;
|
||||
}
|
||||
|
||||
if (ll.meta.ele < this._info.elevation.min) {
|
||||
this._info.elevation.min = ll.meta.ele;
|
||||
}
|
||||
|
||||
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 if (this._info.duration.start == null) {
|
||||
this._info.duration.start = ll.meta.time;
|
||||
}
|
||||
|
||||
last = ll;
|
||||
coords.push(ll);
|
||||
}
|
||||
|
||||
// add track
|
||||
var l = new L.Polyline(coords, this._extract_styling(line, polyline_options, options.polyline_options));
|
||||
this.fire('addline', { line: l, element: line });
|
||||
layers.push(l);
|
||||
|
||||
if (options.marker_options.startIcon || options.marker_options.startIconUrl) {
|
||||
// add start pin
|
||||
var marker = new L.Marker(coords[0], {
|
||||
clickable: options.marker_options.clickable,
|
||||
icon: options.marker_options.startIcon || new L.GPXTrackIcon({iconUrl: options.marker_options.startIconUrl})
|
||||
});
|
||||
this.fire('addpoint', { point: marker, point_type: 'start', element: el[0] });
|
||||
layers.push(marker);
|
||||
}
|
||||
|
||||
if (options.marker_options.endIcon || options.marker_options.endIconUrl) {
|
||||
// add end pin
|
||||
var marker = new L.Marker(coords[coords.length-1], {
|
||||
clickable: options.marker_options.clickable,
|
||||
icon: options.marker_options.endIcon || new L.GPXTrackIcon({iconUrl: options.marker_options.endIconUrl})
|
||||
});
|
||||
this.fire('addpoint', { point: marker, point_type: 'end', element: el[el.length-1] });
|
||||
layers.push(marker);
|
||||
}
|
||||
|
||||
// add named markers
|
||||
for (var i = 0; i < markers.length; i++) {
|
||||
var marker = new L.Marker(markers[i].coords, {
|
||||
clickable: options.marker_options.clickable,
|
||||
title: markers[i].label,
|
||||
icon: markers[i].icon
|
||||
});
|
||||
this.fire('addpoint', { point: marker, point_type: 'label', element: markers[i].element });
|
||||
layers.push(marker);
|
||||
}
|
||||
|
||||
return layers;
|
||||
},
|
||||
|
||||
_extract_styling: function(el, base, overrides) {
|
||||
var style = this._merge_objs(_DEFAULT_POLYLINE_OPTS, base);
|
||||
var e = el.getElementsByTagNameNS(_GPX_STYLE_NS, 'line');
|
||||
if (e.length > 0) {
|
||||
var _ = e[0].getElementsByTagName('color');
|
||||
if (_.length > 0) style.color = '#' + _[0].textContent;
|
||||
var _ = e[0].getElementsByTagName('opacity');
|
||||
if (_.length > 0) style.opacity = _[0].textContent;
|
||||
var _ = e[0].getElementsByTagName('weight');
|
||||
if (_.length > 0) style.weight = _[0].textContent;
|
||||
var _ = e[0].getElementsByTagName('linecap');
|
||||
if (_.length > 0) style.lineCap = _[0].textContent;
|
||||
}
|
||||
return this._merge_objs(style, overrides)
|
||||
},
|
||||
|
||||
_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;
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
module.exports = L;
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
define(L);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "leaflet-gpx",
|
||||
"version": "1.5.0",
|
||||
"description": "A Leaflet plugin for showing a GPX track on a map",
|
||||
"main": "gpx.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/mpetazzoni/leaflet-gpx.git"
|
||||
},
|
||||
"keywords": [
|
||||
"leaflet",
|
||||
"gpx",
|
||||
"leaflet-gpx",
|
||||
"map",
|
||||
"gps"
|
||||
],
|
||||
"author": "Maxime Petazzoni <maxime.petazzoni@bulix.org> (https://www.bulix.org)",
|
||||
"license": "BSD-2-Clause",
|
||||
"bugs": {
|
||||
"url": "https://github.com/mpetazzoni/leaflet-gpx/issues"
|
||||
},
|
||||
"homepage": "https://github.com/mpetazzoni/leaflet-gpx#readme"
|
||||
}
|
||||
|
After Width: | Height: | Size: 960 B |
|
After Width: | Height: | Size: 971 B |
|
After Width: | Height: | Size: 660 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 696 B |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 618 B |
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"leaflet-src.esm.js","sources":["../src/core/Util.js","../src/core/Class.js","../src/core/Events.js","../src/geometry/Point.js","../src/geometry/Bounds.js","../src/geo/LatLngBounds.js","../src/geo/LatLng.js","../src/geo/crs/CRS.js","../src/geo/crs/CRS.Earth.js","../src/geo/projection/Projection.SphericalMercator.js","../src/geometry/Transformation.js","../src/geo/crs/CRS.EPSG3857.js","../src/layer/vector/SVG.Util.js","../src/core/Browser.js","../src/dom/DomEvent.Pointer.js","../src/dom/DomEvent.DoubleTap.js","../src/dom/DomUtil.js","../src/dom/DomEvent.js","../src/dom/PosAnimation.js","../src/map/Map.js","../src/control/Control.js","../src/control/Control.Layers.js","../src/control/Control.Zoom.js","../src/control/Control.Scale.js","../src/control/Control.Attribution.js","../src/control/index.js","../src/core/Handler.js","../src/core/index.js","../src/dom/Draggable.js","../src/geometry/LineUtil.js","../src/geometry/PolyUtil.js","../src/geo/projection/Projection.LonLat.js","../src/geo/projection/Projection.Mercator.js","../src/geo/projection/index.js","../src/geo/crs/CRS.EPSG3395.js","../src/geo/crs/CRS.EPSG4326.js","../src/geo/crs/CRS.Simple.js","../src/geo/crs/index.js","../src/layer/Layer.js","../src/layer/LayerGroup.js","../src/layer/FeatureGroup.js","../src/layer/marker/Icon.js","../src/layer/marker/Icon.Default.js","../src/layer/marker/Marker.Drag.js","../src/layer/marker/Marker.js","../src/layer/vector/Path.js","../src/layer/vector/CircleMarker.js","../src/layer/vector/Circle.js","../src/layer/vector/Polyline.js","../src/layer/vector/Polygon.js","../src/layer/GeoJSON.js","../src/layer/ImageOverlay.js","../src/layer/VideoOverlay.js","../src/layer/SVGOverlay.js","../src/layer/DivOverlay.js","../src/layer/Popup.js","../src/layer/Tooltip.js","../src/layer/marker/DivIcon.js","../src/layer/marker/index.js","../src/layer/tile/GridLayer.js","../src/layer/tile/TileLayer.js","../src/layer/tile/TileLayer.WMS.js","../src/layer/tile/index.js","../src/layer/vector/Renderer.js","../src/layer/vector/Canvas.js","../src/layer/vector/SVG.VML.js","../src/layer/vector/SVG.js","../src/layer/vector/Renderer.getRenderer.js","../src/layer/vector/Rectangle.js","../src/layer/vector/index.js","../src/layer/index.js","../src/map/handler/Map.BoxZoom.js","../src/map/handler/Map.DoubleClickZoom.js","../src/map/handler/Map.Drag.js","../src/map/handler/Map.Keyboard.js","../src/map/handler/Map.ScrollWheelZoom.js","../src/map/handler/Map.Tap.js","../src/map/handler/Map.TouchZoom.js","../src/map/index.js"],"sourcesContent":["/*\r\n * @namespace Util\r\n *\r\n * Various utility functions, used by Leaflet internally.\r\n */\r\n\r\n// @function extend(dest: Object, src?: Object): Object\r\n// Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut.\r\nexport function extend(dest) {\r\n\tvar i, j, len, src;\r\n\r\n\tfor (j = 1, len = arguments.length; j < len; j++) {\r\n\t\tsrc = arguments[j];\r\n\t\tfor (i in src) {\r\n\t\t\tdest[i] = src[i];\r\n\t\t}\r\n\t}\r\n\treturn dest;\r\n}\r\n\r\n// @function create(proto: Object, properties?: Object): Object\r\n// Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create)\r\nexport var create = Object.create || (function () {\r\n\tfunction F() {}\r\n\treturn function (proto) {\r\n\t\tF.prototype = proto;\r\n\t\treturn new F();\r\n\t};\r\n})();\r\n\r\n// @function bind(fn: Function, …): Function\r\n// Returns a new function bound to the arguments passed, like [Function.prototype.bind](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).\r\n// Has a `L.bind()` shortcut.\r\nexport function bind(fn, obj) {\r\n\tvar slice = Array.prototype.slice;\r\n\r\n\tif (fn.bind) {\r\n\t\treturn fn.bind.apply(fn, slice.call(arguments, 1));\r\n\t}\r\n\r\n\tvar args = slice.call(arguments, 2);\r\n\r\n\treturn function () {\r\n\t\treturn fn.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments);\r\n\t};\r\n}\r\n\r\n// @property lastId: Number\r\n// Last unique ID used by [`stamp()`](#util-stamp)\r\nexport var lastId = 0;\r\n\r\n// @function stamp(obj: Object): Number\r\n// Returns the unique ID of an object, assigning it one if it doesn't have it.\r\nexport function stamp(obj) {\r\n\t/*eslint-disable */\r\n\tobj._leaflet_id = obj._leaflet_id || ++lastId;\r\n\treturn obj._leaflet_id;\r\n\t/* eslint-enable */\r\n}\r\n\r\n// @function throttle(fn: Function, time: Number, context: Object): Function\r\n// Returns a function which executes function `fn` with the given scope `context`\r\n// (so that the `this` keyword refers to `context` inside `fn`'s code). The function\r\n// `fn` will be called no more than one time per given amount of `time`. The arguments\r\n// received by the bound function will be any arguments passed when binding the\r\n// function, followed by any arguments passed when invoLine truncated
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"leaflet-src.js","sources":["../src/core/Util.js","../src/core/Class.js","../src/core/Events.js","../src/geometry/Point.js","../src/geometry/Bounds.js","../src/geo/LatLngBounds.js","../src/geo/LatLng.js","../src/geo/crs/CRS.js","../src/geo/crs/CRS.Earth.js","../src/geo/projection/Projection.SphericalMercator.js","../src/geometry/Transformation.js","../src/geo/crs/CRS.EPSG3857.js","../src/layer/vector/SVG.Util.js","../src/core/Browser.js","../src/dom/DomEvent.Pointer.js","../src/dom/DomEvent.DoubleTap.js","../src/dom/DomUtil.js","../src/dom/DomEvent.js","../src/dom/PosAnimation.js","../src/map/Map.js","../src/control/Control.js","../src/control/Control.Layers.js","../src/control/Control.Zoom.js","../src/control/Control.Scale.js","../src/control/Control.Attribution.js","../src/control/index.js","../src/core/Handler.js","../src/core/index.js","../src/dom/Draggable.js","../src/geometry/LineUtil.js","../src/geometry/PolyUtil.js","../src/geo/projection/Projection.LonLat.js","../src/geo/projection/Projection.Mercator.js","../src/geo/projection/index.js","../src/geo/crs/CRS.EPSG3395.js","../src/geo/crs/CRS.EPSG4326.js","../src/geo/crs/CRS.Simple.js","../src/geo/crs/index.js","../src/layer/Layer.js","../src/layer/LayerGroup.js","../src/layer/FeatureGroup.js","../src/layer/marker/Icon.js","../src/layer/marker/Icon.Default.js","../src/layer/marker/Marker.Drag.js","../src/layer/marker/Marker.js","../src/layer/vector/Path.js","../src/layer/vector/CircleMarker.js","../src/layer/vector/Circle.js","../src/layer/vector/Polyline.js","../src/layer/vector/Polygon.js","../src/layer/GeoJSON.js","../src/layer/ImageOverlay.js","../src/layer/VideoOverlay.js","../src/layer/SVGOverlay.js","../src/layer/DivOverlay.js","../src/layer/Popup.js","../src/layer/Tooltip.js","../src/layer/marker/DivIcon.js","../src/layer/marker/index.js","../src/layer/tile/GridLayer.js","../src/layer/tile/TileLayer.js","../src/layer/tile/TileLayer.WMS.js","../src/layer/tile/index.js","../src/layer/vector/Renderer.js","../src/layer/vector/Canvas.js","../src/layer/vector/SVG.VML.js","../src/layer/vector/SVG.js","../src/layer/vector/Renderer.getRenderer.js","../src/layer/vector/Rectangle.js","../src/layer/vector/index.js","../src/layer/index.js","../src/map/handler/Map.BoxZoom.js","../src/map/handler/Map.DoubleClickZoom.js","../src/map/handler/Map.Drag.js","../src/map/handler/Map.Keyboard.js","../src/map/handler/Map.ScrollWheelZoom.js","../src/map/handler/Map.Tap.js","../src/map/handler/Map.TouchZoom.js","../src/map/index.js"],"sourcesContent":["/*\r\n * @namespace Util\r\n *\r\n * Various utility functions, used by Leaflet internally.\r\n */\r\n\r\n// @function extend(dest: Object, src?: Object): Object\r\n// Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut.\r\nexport function extend(dest) {\r\n\tvar i, j, len, src;\r\n\r\n\tfor (j = 1, len = arguments.length; j < len; j++) {\r\n\t\tsrc = arguments[j];\r\n\t\tfor (i in src) {\r\n\t\t\tdest[i] = src[i];\r\n\t\t}\r\n\t}\r\n\treturn dest;\r\n}\r\n\r\n// @function create(proto: Object, properties?: Object): Object\r\n// Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create)\r\nexport var create = Object.create || (function () {\r\n\tfunction F() {}\r\n\treturn function (proto) {\r\n\t\tF.prototype = proto;\r\n\t\treturn new F();\r\n\t};\r\n})();\r\n\r\n// @function bind(fn: Function, …): Function\r\n// Returns a new function bound to the arguments passed, like [Function.prototype.bind](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).\r\n// Has a `L.bind()` shortcut.\r\nexport function bind(fn, obj) {\r\n\tvar slice = Array.prototype.slice;\r\n\r\n\tif (fn.bind) {\r\n\t\treturn fn.bind.apply(fn, slice.call(arguments, 1));\r\n\t}\r\n\r\n\tvar args = slice.call(arguments, 2);\r\n\r\n\treturn function () {\r\n\t\treturn fn.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments);\r\n\t};\r\n}\r\n\r\n// @property lastId: Number\r\n// Last unique ID used by [`stamp()`](#util-stamp)\r\nexport var lastId = 0;\r\n\r\n// @function stamp(obj: Object): Number\r\n// Returns the unique ID of an object, assigning it one if it doesn't have it.\r\nexport function stamp(obj) {\r\n\t/*eslint-disable */\r\n\tobj._leaflet_id = obj._leaflet_id || ++lastId;\r\n\treturn obj._leaflet_id;\r\n\t/* eslint-enable */\r\n}\r\n\r\n// @function throttle(fn: Function, time: Number, context: Object): Function\r\n// Returns a function which executes function `fn` with the given scope `context`\r\n// (so that the `this` keyword refers to `context` inside `fn`'s code). The function\r\n// `fn` will be called no more than one time per given amount of `time`. The arguments\r\n// received by the bound function will be any arguments passed when binding the\r\n// function, followed by any arguments passed when invokingLine truncated
|
||||
@@ -0,0 +1,640 @@
|
||||
/* required styles */
|
||||
|
||||
.leaflet-pane,
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-pane > svg,
|
||||
.leaflet-pane > canvas,
|
||||
.leaflet-zoom-box,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
/* Prevents IE11 from highlighting tiles in blue */
|
||||
.leaflet-tile::selection {
|
||||
background: transparent;
|
||||
}
|
||||
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
|
||||
.leaflet-safari .leaflet-tile {
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
}
|
||||
/* hack that prevents hw layers "stretching" when loading new tiles */
|
||||
.leaflet-safari .leaflet-tile-container {
|
||||
width: 1600px;
|
||||
height: 1600px;
|
||||
-webkit-transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
display: block;
|
||||
}
|
||||
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
|
||||
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
|
||||
.leaflet-container .leaflet-overlay-pane svg,
|
||||
.leaflet-container .leaflet-marker-pane img,
|
||||
.leaflet-container .leaflet-shadow-pane img,
|
||||
.leaflet-container .leaflet-tile-pane img,
|
||||
.leaflet-container img.leaflet-image-layer,
|
||||
.leaflet-container .leaflet-tile {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
}
|
||||
|
||||
.leaflet-container.leaflet-touch-zoom {
|
||||
-ms-touch-action: pan-x pan-y;
|
||||
touch-action: pan-x pan-y;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag {
|
||||
-ms-touch-action: pinch-zoom;
|
||||
/* Fallback for FF which doesn't support pinch-zoom */
|
||||
touch-action: none;
|
||||
touch-action: pinch-zoom;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.leaflet-container {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.leaflet-container a {
|
||||
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
|
||||
}
|
||||
.leaflet-tile {
|
||||
filter: inherit;
|
||||
visibility: hidden;
|
||||
}
|
||||
.leaflet-tile-loaded {
|
||||
visibility: inherit;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
width: 0;
|
||||
height: 0;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
z-index: 800;
|
||||
}
|
||||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
|
||||
.leaflet-overlay-pane svg {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.leaflet-pane { z-index: 400; }
|
||||
|
||||
.leaflet-tile-pane { z-index: 200; }
|
||||
.leaflet-overlay-pane { z-index: 400; }
|
||||
.leaflet-shadow-pane { z-index: 500; }
|
||||
.leaflet-marker-pane { z-index: 600; }
|
||||
.leaflet-tooltip-pane { z-index: 650; }
|
||||
.leaflet-popup-pane { z-index: 700; }
|
||||
|
||||
.leaflet-map-pane canvas { z-index: 100; }
|
||||
.leaflet-map-pane svg { z-index: 200; }
|
||||
|
||||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.leaflet-control {
|
||||
position: relative;
|
||||
z-index: 800;
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-top,
|
||||
.leaflet-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-top {
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-right {
|
||||
right: 0;
|
||||
}
|
||||
.leaflet-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.leaflet-left {
|
||||
left: 0;
|
||||
}
|
||||
.leaflet-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
float: right;
|
||||
}
|
||||
.leaflet-top .leaflet-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.leaflet-left .leaflet-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-tile {
|
||||
will-change: opacity;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
.leaflet-zoom-animated {
|
||||
-webkit-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
will-change: transform;
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-tile,
|
||||
.leaflet-pan-anim .leaflet-tile {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* cursors */
|
||||
|
||||
.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
}
|
||||
.leaflet-grab {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
.leaflet-crosshair,
|
||||
.leaflet-crosshair .leaflet-interactive {
|
||||
cursor: crosshair;
|
||||
}
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-control {
|
||||
cursor: auto;
|
||||
}
|
||||
.leaflet-dragging .leaflet-grab,
|
||||
.leaflet-dragging .leaflet-grab .leaflet-interactive,
|
||||
.leaflet-dragging .leaflet-marker-draggable {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
/* marker & overlays interactivity */
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-pane > svg path,
|
||||
.leaflet-tile-container {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.leaflet-marker-icon.leaflet-interactive,
|
||||
.leaflet-image-layer.leaflet-interactive,
|
||||
.leaflet-pane > svg path.leaflet-interactive,
|
||||
svg.leaflet-image-layer.leaflet-interactive path {
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* visual tweaks */
|
||||
|
||||
.leaflet-container {
|
||||
background: #ddd;
|
||||
outline: 0;
|
||||
}
|
||||
.leaflet-container a {
|
||||
color: #0078A8;
|
||||
}
|
||||
.leaflet-container a.leaflet-active {
|
||||
outline: 2px solid orange;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
border: 2px dotted #38f;
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
|
||||
/* general typography */
|
||||
.leaflet-container {
|
||||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.leaflet-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:first-child {
|
||||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-control-zoom-in,
|
||||
.leaflet-control-zoom-out {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
text-indent: 1px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.leaflet-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers.png);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.leaflet-retina .leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers-2x.png);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.leaflet-control-layers .leaflet-control-layers-list,
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.leaflet-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-layers-scrollbar {
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.leaflet-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.leaflet-control-layers label {
|
||||
display: block;
|
||||
}
|
||||
.leaflet-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
||||
/* Default icon URLs */
|
||||
.leaflet-default-icon-path {
|
||||
background-image: url(images/marker-icon.png);
|
||||
}
|
||||
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.leaflet-container .leaflet-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
margin: 0;
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
}
|
||||
.leaflet-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.leaflet-control-attribution a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.leaflet-container .leaflet-control-attribution,
|
||||
.leaflet-container .leaflet-control-scale {
|
||||
font-size: 11px;
|
||||
}
|
||||
.leaflet-left .leaflet-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.leaflet-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-attribution,
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* popup */
|
||||
|
||||
.leaflet-popup {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
padding: 1px;
|
||||
text-align: left;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.leaflet-popup-content {
|
||||
margin: 13px 19px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.leaflet-popup-content p {
|
||||
margin: 18px 0;
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -20px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-popup-tip {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 1px;
|
||||
|
||||
margin: -10px auto 0;
|
||||
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
background: white;
|
||||
color: #333;
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 4px 4px 0 0;
|
||||
border: none;
|
||||
text-align: center;
|
||||
width: 18px;
|
||||
height: 14px;
|
||||
font: 16px/14px Tahoma, Verdana, sans-serif;
|
||||
color: #c3c3c3;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background: transparent;
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button:hover {
|
||||
color: #999;
|
||||
}
|
||||
.leaflet-popup-scrolled {
|
||||
overflow: auto;
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper {
|
||||
-ms-zoom: 1;
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
width: 24px;
|
||||
margin: 0 auto;
|
||||
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip-container {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-zoom,
|
||||
.leaflet-oldie .leaflet-control-layers,
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper,
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
|
||||
/* div icon */
|
||||
|
||||
.leaflet-div-icon {
|
||||
background: #fff;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
|
||||
/* Tooltip */
|
||||
/* Base styles for the element that has a tooltip */
|
||||
.leaflet-tooltip {
|
||||
position: absolute;
|
||||
padding: 6px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
white-space: nowrap;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-tooltip.leaflet-clickable {
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-tooltip-top:before,
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border: 6px solid transparent;
|
||||
background: transparent;
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Directions */
|
||||
|
||||
.leaflet-tooltip-bottom {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.leaflet-tooltip-top {
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-top:before {
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-top:before {
|
||||
bottom: 0;
|
||||
margin-bottom: -12px;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before {
|
||||
top: 0;
|
||||
margin-top: -12px;
|
||||
margin-left: -6px;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-left {
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-right {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before {
|
||||
right: 0;
|
||||
margin-right: -12px;
|
||||
border-left-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-right:before {
|
||||
left: 0;
|
||||
margin-left: -12px;
|
||||
border-right-color: #fff;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/* @preserve
|
||||
* Leaflet 1.7.1, a JS library for interactive maps. http://leafletjs.com
|
||||
* (c) 2010-2019 Vladimir Agafonkin, (c) 2010-2011 CloudMade
|
||||
*/
|
||||
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i(t.L={})}(this,function(t){"use strict";function h(t){for(var i,e,n=1,o=arguments.length;n<o;n++)for(i in e=arguments[n])t[i]=e[i];return t}var s=Object.create||function(t){return i.prototype=t,new i};function i(){}function p(t,i){var e=Array.prototype.slice;if(t.bind)return t.bind.apply(t,e.call(arguments,1));var n=e.call(arguments,2);return function(){return t.apply(i,n.length?n.concat(e.call(arguments)):arguments)}}var e=0;function m(t){return t._leaflet_id=t._leaflet_id||++e,t._leaflet_id}function n(t,i,e){var n,o,s=function(){n=!1,o&&(r.apply(e,o),o=!1)},r=function(){n?o=arguments:(t.apply(e,arguments),setTimeout(s,i),n=!0)};return r}function o(t,i,e){var n=i[1],o=i[0],s=n-o;return t===n&&e?t:((t-o)%s+s)%s+o}function a(){return!1}function r(t,i){var e=Math.pow(10,void 0===i?6:i);return Math.round(t*e)/e}function u(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}function l(t){return u(t).split(/\s+/)}function c(t,i){for(var e in Object.prototype.hasOwnProperty.call(t,"options")||(t.options=t.options?s(t.options):{}),i)t.options[e]=i[e];return t.options}function _(t,i,e){var n=[];for(var o in t)n.push(encodeURIComponent(e?o.toUpperCase():o)+"="+encodeURIComponent(t[o]));return(i&&-1!==i.indexOf("?")?"&":"?")+n.join("&")}var d=/\{ *([\w_-]+) *\}/g;function f(t,n){return t.replace(d,function(t,i){var e=n[i];if(void 0===e)throw new Error("No value provided for variable "+t);return"function"==typeof e&&(e=e(n)),e})}var g=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)};function v(t,i){for(var e=0;e<t.length;e++)if(t[e]===i)return e;return-1}var y="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function x(t){return window["webkit"+t]||window["moz"+t]||window["ms"+t]}var w=0;function P(t){var i=+new Date,e=Math.max(0,16-(i-w));return w=i+e,window.setTimeout(t,e)}var b=window.requestAnimationFrame||x("RequestAnimationFrame")||P,T=window.cancelAnimationFrame||x("CancelAnimationFrame")||x("CancelRequestAnimationFrame")||function(t){window.clearTimeout(t)};function M(t,i,e){if(!e||b!==P)return b.call(window,p(t,i));t.call(i)}function z(t){t&&T.call(window,t)}var C={extend:h,create:s,bind:p,lastId:e,stamp:m,throttle:n,wrapNum:o,falseFn:a,formatNum:r,trim:u,splitWords:l,setOptions:c,getParamString:_,template:f,isArray:g,indexOf:v,emptyImageUrl:y,requestFn:b,cancelFn:T,requestAnimFrame:M,cancelAnimFrame:z};function S(){}S.extend=function(t){function i(){this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()}var e=i.__super__=this.prototype,n=s(e);for(var o in(n.constructor=i).prototype=n,this)Object.prototype.hasOwnProperty.call(this,o)&&"prototype"!==o&&"__super__"!==o&&(i[o]=this[o]);return t.statics&&(h(i,t.statics),delete t.statics),t.includes&&(function(t){if("undefined"==typeof L||!L||!L.Mixin)return;t=g(t)?t:[t];for(var i=0;i<t.length;i++)t[i]===L.Mixin.Events&&console.warn("Deprecated include of L.Mixin.Events: this property will be removed in future releases, please inherit from L.Evented instead.",(new Error).stack)}(t.includes),h.apply(null,[n].concat(t.includes)),delete t.includes),n.options&&(t.options=h(s(n.options),t.options)),h(n,t),n._initHooks=[],n.callInitHooks=function(){if(!this._initHooksCalled){e.callInitHooks&&e.callInitHooks.call(this),this._initHooksCalled=!0;for(var t=0,i=n._initHooks.length;t<i;t++)n._initHooks[t].call(this)}},i},S.include=function(t){return h(this.prototype,t),this},S.mergeOptions=function(t){return h(this.prototype.options,t),this},S.addInitHook=function(t){var i=Array.prototype.slice.call(arguments,1),e="function"==typeof t?t:function(){this[t].apply(this,i)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(e),this};var Z={on:function(t,i,e){if("object"==typeof t)for(var n in t)this._on(n,t[n],i);else for(var o=0,s=(t=l(t)).length;o<s;o++)this._on(t[o],i,e);return this},off:function(t,i,e){if(t)if("object"==typeof t)for(var n in t)this._off(n,t[n],i);else for(var o=0,s=(t=l(t)).length;o<s;o++)this._off(t[o],i,e);else delete this._events;return this},_on:function(t,i,e){this._events=this._events||{};var n=this._events[t];n||(n=[],this._events[t]=n),e===this&&(e=void 0);for(var o={fn:i,ctx:e},s=n,r=0,a=s.length;r<a;r++)if(s[r].fn===i&&s[r].ctx===e)return;s.push(o)},_off:function(t,i,e){var n,o,s;if(this._events&&(n=this._events[t]))if(i){if(e===this&&(e=void 0),n)for(o=0,s=n.length;o<s;o++){var r=n[o];if(r.ctx===e&&r.fn===i)return r.fn=a,this._firingCount&&(this._events[t]=n=n.slice()),void n.splice(o,1)}}else{for(o=0,s=n.length;o<s;o++)n[o].fn=a;delete this._events[t]}},fire:function(t,i,e){if(!this.listens(t,e))return this;var n=h({},i,{type:t,target:this,sourceTarget:i&&i.sourceTarget||this});if(this._events){var o=this._events[t];if(o){this._firingCount=this._firingCount+1||1;for(var s=0,r=o.length;s<r;s++){vaLine truncated
|
||||
//# sourceMappingURL=leaflet.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"dist/leaflet.js.map","sources":["../src/core/Util.js","../src/core/Class.js","../src/core/Events.js","../src/geometry/Point.js","../src/geometry/Bounds.js","../src/geo/LatLngBounds.js","../src/geo/LatLng.js","../src/geo/crs/CRS.js","../src/geo/projection/Projection.SphericalMercator.js","../src/geo/crs/CRS.Earth.js","../src/geometry/Transformation.js","../src/geo/crs/CRS.EPSG3857.js","../src/layer/vector/SVG.Util.js","../src/core/Browser.js","../src/dom/DomEvent.Pointer.js","../src/dom/DomEvent.DoubleTap.js","../src/dom/DomUtil.js","../src/dom/DomEvent.js","../src/dom/PosAnimation.js","../src/map/Map.js","../src/control/Control.js","../src/control/Control.Layers.js","../src/control/Control.Zoom.js","../src/control/Control.Scale.js","../src/control/Control.Attribution.js","../src/control/index.js","../src/core/Handler.js","../src/core/index.js","../src/geometry/LineUtil.js","../src/dom/Draggable.js","../src/geometry/PolyUtil.js","../src/geo/crs/CRS.EPSG3395.js","../src/geo/projection/Projection.LonLat.js","../src/geo/projection/Projection.Mercator.js","../src/geo/crs/CRS.EPSG4326.js","../src/geo/crs/CRS.Simple.js","../src/geo/crs/index.js","../src/layer/Layer.js","../src/layer/LayerGroup.js","../src/layer/FeatureGroup.js","../src/layer/marker/Icon.js","../src/layer/marker/Icon.Default.js","../src/layer/marker/Marker.Drag.js","../src/layer/marker/Marker.js","../src/layer/vector/Path.js","../src/layer/vector/CircleMarker.js","../src/layer/vector/Circle.js","../src/layer/vector/Polyline.js","../src/layer/vector/Polygon.js","../src/layer/GeoJSON.js","../src/layer/ImageOverlay.js","../src/layer/VideoOverlay.js","../src/layer/SVGOverlay.js","../src/layer/DivOverlay.js","../src/layer/Popup.js","../src/layer/Tooltip.js","../src/layer/marker/DivIcon.js","../src/layer/marker/index.js","../src/layer/tile/GridLayer.js","../src/layer/tile/TileLayer.js","../src/layer/tile/TileLayer.WMS.js","../src/layer/tile/index.js","../src/layer/vector/Renderer.js","../src/layer/vector/Canvas.js","../src/layer/vector/SVG.VML.js","../src/layer/vector/SVG.js","../src/layer/vector/Renderer.getRenderer.js","../src/layer/vector/Rectangle.js","../src/layer/vector/index.js","../src/layer/index.js","../src/map/handler/Map.BoxZoom.js","../src/map/handler/Map.DoubleClickZoom.js","../src/map/handler/Map.Drag.js","../src/map/handler/Map.Keyboard.js","../src/map/handler/Map.ScrollWheelZoom.js","../src/map/handler/Map.Tap.js","../src/map/handler/Map.TouchZoom.js","../src/map/index.js"],"names":["extend","dest","i","src","j","len","arguments","length","create","Object","proto","F","prototype","bind","fn","obj","slice","Array","apply","call","args","concat","lastId","stamp","_leaflet_id","throttle","time","context","lock","later","wrapperFn","setTimeout","wrapNum","x","range","includeMax","max","min","d","falseFn","formatNum","num","digits","pow","Math","undefined","round","trim","str","replace","splitWords","split","setOptions","options","hasOwnProperty","getParamString","existingUrl","uppercase","params","push","encodeURIComponent","toUpperCase","indexOf","join","templateRe","template","data","key","value","Error","isArray","toString","array","el","emptyImageUrl","getPrefixed","name","window","lastTime","timeoutDefer","Date","timeToCall","requestFn","requestAnimationFrame","cancelFn","cancelAnimationFrame","id","clearTimeout","requestAnimFrame","immediate","cancelAnimFrame","Class","props","NewClass","this","initialize","callInitHooks","parentProto","__super__","Util.create","constructor","statics","Util.extend","includes","L","Mixin","Util.isArray","Events","console","warn","stack","checkDeprecatedMixinEvents","_initHooks","_initHooksCalled","include","mergeOptions","addInitHook","init","on","types","type","_on","Util.splitWords","off","_off","_events","typeListeners","newListener","ctx","listeners","l","Util.falseFn","_firingCount","splice","fire","propagate","listens","event","target","sourceTarget","_propagateEvent","_eventParents","once","handler","Util.bind","addEventParent","Util.stamp","removeEventParent","e","layer","propagatedFrom","addEventListener","removeEventListener","clearAllEventListeners","addOneTimeEventListener","fireEvent","hasEventListeners","Evented","Point","y","trunc","v","floor","ceil","toPoint","Bounds","a","b","points","toBounds","LatLngBounds","corner1","corner2","latlngs","toLatLngBounds","LatLng","lat","lng","alt","isNaN","toLatLng","c","lon","clone","add","point","_add","subtract","_subtract","divideBy","_divideBy","multiplyBy","_multiplyBy","scaleBy","unscaleBy","_round","_floor","_ceil","_trunc","distanceTo","sqrt","equals","contains","abs","getCenter","getBottomLeft","getTopRight","getTopLeft","getBottomRight","getSize","intersects","bounds","min2","max2","xIntersects","yIntersects","overlaps","xOverlaps","yOverlaps","isValid","sw2","ne2","sw","_southWest","ne","_northEast","pad","bufferRatio","heightBuffer","widthBuffer","getSouthWest","getNorthEast","getNorthWest","getNorth","getWest","getSoLine truncated
|
||||