@raruto/leaflet-elevation 1.9.4 → 1.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/leaflet-elevation.js +558 -407
- package/dist/leaflet-elevation.js.map +1 -1
- package/dist/leaflet-elevation.min.js +2 -2
- package/dist/leaflet-elevation.min.js.map +1 -1
- package/libs/leaflet-distance-marker.js +17 -18
- package/libs/leaflet-distance-marker.min.js +1 -1
- package/libs/leaflet-ruler.css +42 -0
- package/libs/leaflet-ruler.js +183 -0
- package/libs/leaflet-ruler.min.css +1 -0
- package/libs/leaflet-ruler.min.js +1 -0
- package/package.json +1 -1
- package/src/acceleration.js +56 -51
- package/src/altitude.js +78 -79
- package/src/chart.js +10 -0
- package/src/components.js +18 -11
- package/src/control.js +107 -44
- package/src/distance.js +31 -40
- package/src/index.js +1 -1
- package/src/options.js +5 -5
- package/src/slope.js +87 -71
- package/src/speed.js +57 -49
- package/src/summary.js +12 -1
- package/src/time.js +43 -42
|
@@ -114,13 +114,16 @@ L.DistanceMarker = L.CircleMarker.extend({
|
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
L.DistanceMarkers = L.LayerGroup.extend({
|
|
117
|
-
__arrowIcon: "data:image/svg+xml,%3Csvg transform='rotate(90)' xmlns='http://www.w3.org/2000/svg' width='560px' height='560px' viewBox='0 0 560 560'%3E%3Cpath stroke-width='35' fill='%23FFF' stroke='%23000' d='M280,40L522,525L280,420L38,525z'/%3E%3C/svg%3E",
|
|
118
117
|
options: {
|
|
119
118
|
cssClass: 'dist-marker',
|
|
120
119
|
iconSize: [12, 12],
|
|
120
|
+
arrowSize: [10, 10],
|
|
121
|
+
arrowUrl: "data:image/svg+xml,%3Csvg transform='rotate(90)' xmlns='http://www.w3.org/2000/svg' width='560px' height='560px' viewBox='0 0 560 560'%3E%3Cpath stroke-width='35' fill='%23000' stroke='%23FFF' d='M280,40L522,525L280,420L38,525z'/%3E%3C/svg%3E",
|
|
121
122
|
offset: 1000,
|
|
122
123
|
showAll: 12,
|
|
123
124
|
textFunction: (distance, i, offset) => i,
|
|
125
|
+
distance: true,
|
|
126
|
+
direction: true,
|
|
124
127
|
},
|
|
125
128
|
initialize: function (line, map, options) {
|
|
126
129
|
|
|
@@ -167,25 +170,21 @@ L.DistanceMarkers = L.LayerGroup.extend({
|
|
|
167
170
|
// Generate distance marker label
|
|
168
171
|
let text = options.textFunction.call(this, distance, i, options.offset);
|
|
169
172
|
|
|
170
|
-
// Grouping layer of
|
|
171
|
-
let marker = L.layerGroup();
|
|
172
|
-
|
|
173
|
-
// Grouping layer of visible layers (at zoom level)
|
|
173
|
+
// Grouping layer of visible layers at zoom level (arrow + distance)
|
|
174
174
|
let zoom = this._minimumZoomLevelForItem(i, showAll);
|
|
175
|
-
this._zoomLayers[zoom] = this._zoomLayers[zoom] || L.layerGroup()
|
|
176
|
-
this._zoomLayers[zoom].addLayer(marker);
|
|
175
|
+
let markers = this._zoomLayers[zoom] = this._zoomLayers[zoom] || L.layerGroup()
|
|
177
176
|
|
|
178
177
|
// create arrow markers
|
|
179
|
-
if (options.
|
|
178
|
+
if (options.direction && ((options.distance && i % 2 == 1) || !options.distance)) {
|
|
180
179
|
if (preferCanvas) {
|
|
181
|
-
|
|
180
|
+
markers.addLayer(
|
|
182
181
|
new L.DistanceMarker(p1, {
|
|
183
182
|
radius: 0,
|
|
184
183
|
icon: {
|
|
185
|
-
url:
|
|
186
|
-
size:
|
|
187
|
-
rotate: 0,
|
|
188
|
-
offset: { x: 0, y: 0 }
|
|
184
|
+
url: options.arrowUrl, //image link
|
|
185
|
+
size: options.arrowSize, //image size ( default [40, 40] )
|
|
186
|
+
rotate: 0, //image base rotate ( default 0 )
|
|
187
|
+
offset: { x: 0, y: 0 }, //image offset ( default { x: 0, y: 0 } )
|
|
189
188
|
},
|
|
190
189
|
rotation: angle,
|
|
191
190
|
interactive: false,
|
|
@@ -196,11 +195,11 @@ L.DistanceMarkers = L.LayerGroup.extend({
|
|
|
196
195
|
})
|
|
197
196
|
);
|
|
198
197
|
} else {
|
|
199
|
-
|
|
198
|
+
markers.addLayer(
|
|
200
199
|
L.marker(position.latLng, {
|
|
201
200
|
icon: L.icon({
|
|
202
|
-
iconUrl:
|
|
203
|
-
iconSize:
|
|
201
|
+
iconUrl: options.arrowUrl,
|
|
202
|
+
iconSize: options.arrowSize,
|
|
204
203
|
}),
|
|
205
204
|
// NB the following option is added by "leaflet-rotate"
|
|
206
205
|
rotation: angle * L.DomUtil.RAD_TO_DEG,
|
|
@@ -213,7 +212,7 @@ L.DistanceMarkers = L.LayerGroup.extend({
|
|
|
213
212
|
// create distance markers
|
|
214
213
|
if (options.distance && i % 2 == 0) {
|
|
215
214
|
if (preferCanvas) {
|
|
216
|
-
|
|
215
|
+
markers.addLayer(
|
|
217
216
|
new L.DistanceMarker(position.latLng, {
|
|
218
217
|
label: text, // TODO: handle text rotation (leaflet-rotate)
|
|
219
218
|
radius: 7,
|
|
@@ -226,7 +225,7 @@ L.DistanceMarkers = L.LayerGroup.extend({
|
|
|
226
225
|
})
|
|
227
226
|
);
|
|
228
227
|
} else {
|
|
229
|
-
|
|
228
|
+
markers.addLayer(
|
|
230
229
|
L.marker(position.latLng, {
|
|
231
230
|
title: text,
|
|
232
231
|
icon: L.divIcon({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
L.DistanceMarker=L.CircleMarker.extend({_updatePath:function(){let ctx=this._renderer._ctx,p=this._point;if(this.options.rotation=this.options.rotation||0,this.options.radius&&this._renderer._updateCircle&&this._renderer._updateCircle(this),this.options.icon&&this.options.icon.url)if(this.options.icon.element){const icon=this.options.icon;let cx=p.x+icon.offset.x,cy=p.y+icon.offset.y;ctx.save(),icon.rotate&&(ctx.translate(p.x,p.y),ctx.rotate(icon.rotate),cx=0,cy=0),ctx.drawImage(icon.element,cx-icon.size[0]/2,cy-icon.size[1]/2,icon.size[0],icon.size[1]),ctx.restore()}else{const icon=document.createElement("img");this.options.icon=L.extend({rotate:0,size:[40,40],offset:{x:0,y:0}},this.options.icon),this.options.icon.rotate+=this.options.rotation,this.options.icon.element=icon,icon.src=this.options.icon.url,icon.onload=()=>this.redraw(),icon.onerror=()=>this.options.icon=null}if(this.options.label){let cx=p.x,cy=p.y;ctx.save(),ctx.font=this.options.font||'normal 7pt "Helvetica Neue", Arial, Helvetica, sans-serif',ctx.textAlign="center",ctx.textBaseline="middle",ctx.fillStyle=this.options.fillStyle||"black",this.options.rotation&&(ctx.translate(p.x,p.y),ctx.rotate(this.options.rotation),cx=0,cy=0),this._map.getZoom()>17&&(ctx.fillStyle=this.options.strokeStyle||"black"),ctx.fillText(this.options.label,cx,cy),this.options.strokeStyle&&this._map.getZoom()<=17&&(ctx.strokeStyle=this.options.strokeStyle,ctx.strokeText(this.options.label,cx,cy)),ctx.restore()}}}),L.DistanceMarkers=L.LayerGroup.extend({
|
|
1
|
+
L.DistanceMarker=L.CircleMarker.extend({_updatePath:function(){let ctx=this._renderer._ctx,p=this._point;if(this.options.rotation=this.options.rotation||0,this.options.radius&&this._renderer._updateCircle&&this._renderer._updateCircle(this),this.options.icon&&this.options.icon.url)if(this.options.icon.element){const icon=this.options.icon;let cx=p.x+icon.offset.x,cy=p.y+icon.offset.y;ctx.save(),icon.rotate&&(ctx.translate(p.x,p.y),ctx.rotate(icon.rotate),cx=0,cy=0),ctx.drawImage(icon.element,cx-icon.size[0]/2,cy-icon.size[1]/2,icon.size[0],icon.size[1]),ctx.restore()}else{const icon=document.createElement("img");this.options.icon=L.extend({rotate:0,size:[40,40],offset:{x:0,y:0}},this.options.icon),this.options.icon.rotate+=this.options.rotation,this.options.icon.element=icon,icon.src=this.options.icon.url,icon.onload=()=>this.redraw(),icon.onerror=()=>this.options.icon=null}if(this.options.label){let cx=p.x,cy=p.y;ctx.save(),ctx.font=this.options.font||'normal 7pt "Helvetica Neue", Arial, Helvetica, sans-serif',ctx.textAlign="center",ctx.textBaseline="middle",ctx.fillStyle=this.options.fillStyle||"black",this.options.rotation&&(ctx.translate(p.x,p.y),ctx.rotate(this.options.rotation),cx=0,cy=0),this._map.getZoom()>17&&(ctx.fillStyle=this.options.strokeStyle||"black"),ctx.fillText(this.options.label,cx,cy),this.options.strokeStyle&&this._map.getZoom()<=17&&(ctx.strokeStyle=this.options.strokeStyle,ctx.strokeText(this.options.label,cx,cy)),ctx.restore()}}}),L.DistanceMarkers=L.LayerGroup.extend({options:{cssClass:"dist-marker",iconSize:[12,12],arrowSize:[10,10],arrowUrl:"data:image/svg+xml,%3Csvg transform='rotate(90)' xmlns='http://www.w3.org/2000/svg' width='560px' height='560px' viewBox='0 0 560 560'%3E%3Cpath stroke-width='35' fill='%23000' stroke='%23FFF' d='M280,40L522,525L280,420L38,525z'/%3E%3C/svg%3E",offset:1e3,showAll:12,textFunction:(distance,i,offset)=>i,distance:!0,direction:!0},initialize:function(line,map,options){this._layers={},this._zoomLayers={},options=L.setOptions(this,options);let preferCanvas=map.options.preferCanvas,showAll=Math.min(map.getMaxZoom(),options.showAll);preferCanvas||map.options.rotate||console.warn('Missing dependency: "leaflet-rotate"');let coords="function"==typeof line.getLatLngs?line.getLatLngs():line,accumulated=L.GeometryUtil.accumulatedLengths(line),length=accumulated.length>0?accumulated[accumulated.length-1]:0;for(let i=1,count=Math.floor(length/options.offset),j=0;i<=count;++i){let distance=options.offset*i;for(;j<accumulated.length-1&&accumulated[j]<distance;)++j;let p1=coords[j-1],p2=coords[j],m_line=L.polyline([p1,p2]),ratio=(distance-accumulated[j-1])/(accumulated[j]-accumulated[j-1]),position=L.GeometryUtil.interpolateOnLine(map,m_line,ratio),delta=map.project(p2).subtract(map.project(p1)),angle=Math.atan2(delta.y,delta.x),text=options.textFunction.call(this,distance,i,options.offset),zoom=this._minimumZoomLevelForItem(i,showAll),markers=this._zoomLayers[zoom]=this._zoomLayers[zoom]||L.layerGroup();options.direction&&(options.distance&&i%2==1||!options.distance)&&(preferCanvas?markers.addLayer(new L.DistanceMarker(p1,{radius:0,icon:{url:options.arrowUrl,size:options.arrowSize,rotate:0,offset:{x:0,y:0}},rotation:angle,interactive:!1})):markers.addLayer(L.marker(position.latLng,{icon:L.icon({iconUrl:options.arrowUrl,iconSize:options.arrowSize}),rotation:angle*L.DomUtil.RAD_TO_DEG,interactive:!1}))),options.distance&&i%2==0&&(preferCanvas?markers.addLayer(new L.DistanceMarker(position.latLng,{label:text,radius:7,fillColor:"#fff",fillOpacity:1,fillStyle:"black",color:"#777",weight:1,interactive:!1})):markers.addLayer(L.marker(position.latLng,{title:text,icon:L.divIcon({className:options.cssClass,html:text,iconSize:options.iconSize}),interactive:!1})))}const updateMarkerVisibility=()=>{let oldZoom=this._lastZoomLevel||0,newZoom=map.getZoom();if(newZoom>oldZoom)for(let i=oldZoom+1;i<=newZoom;++i)void 0!==this._zoomLayers[i]&&this.addLayer(this._zoomLayers[i]);else if(newZoom<oldZoom)for(let i=oldZoom;i>newZoom;--i)void 0!==this._zoomLayers[i]&&this.removeLayer(this._zoomLayers[i]);this._lastZoomLevel=newZoom};map.on("zoomend",updateMarkerVisibility),updateMarkerVisibility()},_minimumZoomLevelForItem:function(i,zoom){for(;i>0&&i%2==0;)--zoom,i=Math.floor(i/2);return zoom}}),L.Polyline.include({_originalOnAdd:L.Polyline.prototype.onAdd,_originalOnRemove:L.Polyline.prototype.onRemove,addDistanceMarkers:function(){this._map&&this._distanceMarkers&&this._map.addLayer(this._distanceMarkers)},removeDistanceMarkers:function(){this._map&&this._distanceMarkers&&this._map.removeLayer(this._distanceMarkers)},onAdd:function(map){this._originalOnAdd(map);let opts=this.options.distanceMarkers||{};this.options.distanceMarkers&&(this._distanceMarkers=this._distanceMarkers||new L.DistanceMarkers(this,map,opts)),void 0!==opts.lazy&&!1!==opts.lazy||this.addDistanceMarkers()},onRemove:function(map){this.removeDistanceMarkers(),this._originalOnRemove(map)}});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
.leaflet-ruler {
|
|
2
|
+
height: 35px;
|
|
3
|
+
width: 35px;
|
|
4
|
+
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAACx0lEQVRIS52VWahOURTHXRSJzBkiJcpYxgeS4oUi90GR4VK6DzcUD3gQIQ8UCXkwlCJRkjJEpqT7oGTMeHONmacyRRl/v9ve2n2d7/vOtevXPmefff5r7bXXXruiSf42gKkToTu0hY/wEk7CnWIyFWX0B/N9OkyF1tANdsEz6AIL4Sl8h8NwEK6nmsUMNGPSalgePFxLfwl2hrG39O1hM8yFobAKpsAGWAE/NJRloBfj++ErnIYesDj1qsjzRsYN2VhwdTPgUaGBkUF0e/D0TxDrRD8ehsFw6AcP4FrgCL17EpsrWAKDUgNtwuQP9FehJsyeSb8FbsOV8O0efVeYHOZV0h8N8w3dWXBOVWpgDwO/oBqc1BxciV7Pg3OJhz66ivPB+PoM8TnqRQPTeNkKfeALtAQ39QYsgE85xNsFz+voFe8AldFALS8DYU3waAd9b5gAv3OKn2HefagK4q64VgPm9k0we0wtN9pN6w+mY9qywqLnWeKXGa/WwHwYFSwrZtw/w9Ic4p5oxesLPG8Qd/UacMf13IE38ArGwN3EQJbnintOHsJsMOaG5Z+4/2vAY282eALd4FvQqoj4Aca3gQfPw1hSPBr4xoNH3bz1EO0D428r9LwpY3vB+nSolOfRQVeg1yOCgXH01pu+GeL+Y1hOwWOYBZlhieJxBU94eA2Lwo9WRw+X8fUEx0PUaPFowKW6Cg+UBc6M6AzrMsR1xtJR1vO4CkNk1TMLJoXBlcHQpvAePW+0eFyBRe45jAbL7fskhqm4MbdGmYruUU94l8zNfIyl4hhfLQteHqaiLYq7J4YlipvnXkgWRotgyRYNWB4st6bpizLiHsiO4H1gMrhnRVtarpcxy0vd+9eLPMvzhuMf1E7QmyC78xrQmDk+BC6Am98CLoKXi/dvWll1xjvjeAkD9YVXpkJ6ae7/BOPus4b+p9X9BdB/zv8zawwXAAAAAElFTkSuQmCC"); /* <div>Icons made by <a href="http://www.freepik.com" title="Freepik">Freepik</a> from <a href="http://www.flaticon.com" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div> */
|
|
5
|
+
background-repeat: no-repeat;
|
|
6
|
+
background-position: center;
|
|
7
|
+
}
|
|
8
|
+
.leaflet-ruler-clicked,
|
|
9
|
+
.leaflet-ruler:hover {
|
|
10
|
+
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAE/ElEQVRIS6WVeWwUVRzHfzOzs7Pdi+7Rdq/ubrH0sNaKBFMCSEvBQLivFkhAE8GDYAyHATWgETUoMZ7BGCMBNKYiQbTKpYQKBqKlWmBbadmW7bbbFjv0mu2eM298M5SlpS3U+LL/zL6Zz/f7vr/3e4+AsQ6j80EgxTkKhGwkQRqQiLp5UtEOSDwOXf660TDEPfkGR75RTT8VF1EpJRJ6LsbrVuaZg2YtrWND8WD5FVajV9IcTyCOoYhv2QgcgE5fzWDmaAKU0eHa3RMStszNMqIdM+zUY3YdPFvRCG+VOCFFQ0N3mIfNJ3ywb3Em/BHgYNeZFnTc20OOU1Efd7eZtwBUxyWh4QLJGS6jFv04MU2bNWeCQRnoi8L7czPuG+RLJ31g0Smhsqk3dqGVa7wZZOZBb/31oQKm8ZMZRbxyU6FV9XaJmyQGZsNxBD/Ud8FXNWy/rzci9ER4Spqa5tYrit3jmNI8M2DnCRNvnm1Bu35tjcR4lH1HIDtbp+2NNuSmqCyTrBr4dMEDuH4A754LCLvOtQo44zouKp7hQagGIK+CIFgoipqPEHru6OocWJhtlAWk6GZ8cSXs64sd49qbSxMCaenu7+ZkGuftW5JJSy/FBARlh+vDF1tDfWEerYWullNDcjK5c9Q0Or/jcad++3SbbP8ueBn+S7glkOIsNTDUQf+mRxmtkoIIj6Bgb024hYtVhGPK9dDl7RsJvhPDtw3AcWzYuSd8vTcqOS8DrcUIKsUiWcDgyKghRLFgZ1E6vFhohfXfN8YP1bFVfW3N0/E0Ggu8CMNxfY9z7b5SCU4o6dMkhc4RYM61aulwU8fWSSqaIqEqEIRZBzzBSCg+HoIdncPglHgBG9ENdj4inEAXhZuBdQSYXBuWZOnfOLI61yTB1ld4Y1/+xe6Ndvo33Q+ON5Rc0GHOB+DS6gmF2XF6dkZy0eeLM8lU3EDGd6qiQRAnQnvz3wkBXFANdr5jkHMJXrS/NtTIRk5yN3wrErEMgsuNpkp13ViRZ0zdOtUOWiUJ2R/WxPibfmYk+Mp8E/XCT01y4y0/1HBfuCygMDljVzYW0DnmJKhuC8Lsg7WB7kCzQxa4y7nUF08euQblHlZMoqij93J+2yBBpzgjlzcUMJLAmeu9sOjrq+1cR7PtNvzVYrv+5WkOUvpAiqUYx+JlI6cwfPlosQyuHcGYnYECq9r2AV62O5mB9PcuItxjj2ho6uz/hcsRESbH4TX5qQv3LsigNbjJ7Huq+tkIT75enM4Mdx76mbvhXzYW54mIwOBeNd2l+eTs03nyYYIPqrhaSVGbC213xfLf4fIKAB9yqp4IW/VMvtKqVYJJrUhEeCdzGS5lbki22Wu5btYg0IwV2hrYIb0ywoN8VCTbXadDUTRz/9IJsCrfLL82CP7LQCyGcVab56HColQkCKL3ctWxTs/5+WMSAHwPGBih0rNxotqGL42R4DqLpebhKTNta7fvgWBfN7yybIoQjYdzoLPVey+RxHFtdrhfy05J2laxKjep5EAd3oqhhHNtqrm6YOoT6RKcIOXSwEdb1ojXLv35fDRQ99mYBKR6GOyu3zBhcowXTvR3+JdCWhqjVhk9FEW7Z5Wtw1vuFlwatb9XQmuD51J/MFQ+qgAheIdemSl5FoDgOuhs3o0/4vWOKcZkh/4bEJFKxAMA/6QhgsjzAvrH3+SXn0YZAinU/wuTosgK53+p+wAAAABJRU5ErkJggg=="); /* <div>Icons made by <a href="http://www.freepik.com" title="Freepik">Freepik</a> from <a href="http://www.flaticon.com" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div> */
|
|
11
|
+
}
|
|
12
|
+
.leaflet-ruler-clicked {
|
|
13
|
+
height: 35px;
|
|
14
|
+
width: 35px;
|
|
15
|
+
background-repeat: no-repeat;
|
|
16
|
+
background-position: center;
|
|
17
|
+
border-color: chartreuse !important;
|
|
18
|
+
}
|
|
19
|
+
.leaflet-bar.leaflet-ruler {
|
|
20
|
+
background-color: #ffffff;
|
|
21
|
+
}
|
|
22
|
+
.leaflet-control.leaflet-ruler {
|
|
23
|
+
cursor: pointer;
|
|
24
|
+
}
|
|
25
|
+
.result-tooltip {
|
|
26
|
+
background-color: white;
|
|
27
|
+
border-width: medium;
|
|
28
|
+
border-color: #de0000;
|
|
29
|
+
font-size: smaller;
|
|
30
|
+
}
|
|
31
|
+
.moving-tooltip {
|
|
32
|
+
background-color: rgba(255, 255, 255, .7);
|
|
33
|
+
background-clip: padding-box;
|
|
34
|
+
opacity: 0.5;
|
|
35
|
+
border: dotted;
|
|
36
|
+
border-color: red;
|
|
37
|
+
font-size: smaller;
|
|
38
|
+
}
|
|
39
|
+
.plus-length {
|
|
40
|
+
padding-left: 45px;
|
|
41
|
+
}
|
|
42
|
+
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2022, GPL-3.0+ Project, Raruto
|
|
3
|
+
*
|
|
4
|
+
* This file is free software: you may copy, redistribute and/or modify it
|
|
5
|
+
* under the terms of the GNU General Public License as published by the
|
|
6
|
+
* Free Software Foundation, either version 2 of the License, or (at your
|
|
7
|
+
* option) any later version.
|
|
8
|
+
*
|
|
9
|
+
* This file is distributed in the hope that it will be useful, but
|
|
10
|
+
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
+
* General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU General Public License
|
|
15
|
+
* along with this program. If not, see .
|
|
16
|
+
*
|
|
17
|
+
* This file incorporates work covered by the following copyright and
|
|
18
|
+
* permission notice:
|
|
19
|
+
*
|
|
20
|
+
* Copyright (c) 2017 Goker Tanrisever
|
|
21
|
+
*
|
|
22
|
+
* Permission to use, copy, modify, and/or distribute this software
|
|
23
|
+
* for any purpose with or without fee is hereby granted, provided
|
|
24
|
+
* that the above copyright notice and this permission notice appear
|
|
25
|
+
* in all copies.
|
|
26
|
+
*
|
|
27
|
+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
28
|
+
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
29
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
|
30
|
+
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
|
31
|
+
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
32
|
+
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
|
33
|
+
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
34
|
+
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
L.Control.Ruler = L.Control.extend({
|
|
38
|
+
options: {
|
|
39
|
+
position: 'topright',
|
|
40
|
+
circleMarker: {
|
|
41
|
+
color: 'red',
|
|
42
|
+
radius: 2,
|
|
43
|
+
},
|
|
44
|
+
lineStyle: {
|
|
45
|
+
color: 'red',
|
|
46
|
+
dashArray: '1,6'
|
|
47
|
+
},
|
|
48
|
+
lengthUnit: {
|
|
49
|
+
display: 'km',
|
|
50
|
+
decimal: 2,
|
|
51
|
+
factor: 0.001, // meters -> kilometers
|
|
52
|
+
label: 'Distance:'
|
|
53
|
+
},
|
|
54
|
+
angleUnit: {
|
|
55
|
+
display: '°',
|
|
56
|
+
decimal: 2,
|
|
57
|
+
factor: 360,
|
|
58
|
+
label: 'Bearing:'
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
initialize: function (options) {
|
|
62
|
+
L.setOptions(this, options);
|
|
63
|
+
this._layers = L.layerGroup();
|
|
64
|
+
this._enabled = false;
|
|
65
|
+
},
|
|
66
|
+
onAdd: function (map) {
|
|
67
|
+
this._defaultCursor = map._container.style.cursor;
|
|
68
|
+
this._map = map;
|
|
69
|
+
let container = L.DomUtil.create('div', 'leaflet-bar');
|
|
70
|
+
container.classList.add('leaflet-ruler');
|
|
71
|
+
L.DomEvent.disableClickPropagation(container);
|
|
72
|
+
L.DomEvent.on(container, 'click', this._toggleMeasure, this);
|
|
73
|
+
return this._container = container;
|
|
74
|
+
},
|
|
75
|
+
onRemove: function () {
|
|
76
|
+
L.DomEvent.off(this._container, 'click', this._toggleMeasure, this);
|
|
77
|
+
},
|
|
78
|
+
_attachMouseEvents: function () {
|
|
79
|
+
let map = this._map;
|
|
80
|
+
map.doubleClickZoom.disable();
|
|
81
|
+
L.DomEvent.on(map._container, 'keydown', this._escape, this);
|
|
82
|
+
L.DomEvent.on(map._container, 'dblclick', this._closePath, this);
|
|
83
|
+
map._container.style.cursor = 'crosshair';
|
|
84
|
+
map.on('click', this._addPoint, this);
|
|
85
|
+
map.on('mousemove', this._moving, this);
|
|
86
|
+
},
|
|
87
|
+
_removeMouseEvents: function () {
|
|
88
|
+
let map = this._map;
|
|
89
|
+
map.doubleClickZoom.enable();
|
|
90
|
+
L.DomEvent.off(map._container, 'keydown', this._escape, this);
|
|
91
|
+
L.DomEvent.off(map._container, 'dblclick', this._closePath, this);
|
|
92
|
+
map._container.style.cursor = this._defaultCursor;
|
|
93
|
+
map.off('click', this._addPoint, this);
|
|
94
|
+
map.off('mousemove', this._moving, this);
|
|
95
|
+
},
|
|
96
|
+
_disable: function () {
|
|
97
|
+
this._enabled = false;
|
|
98
|
+
this._container.classList.remove("leaflet-ruler-clicked");
|
|
99
|
+
this._layers.remove().clearLayers();
|
|
100
|
+
this._latlngs = [];
|
|
101
|
+
this._totalLength = 0;
|
|
102
|
+
this._removeMouseEvents();
|
|
103
|
+
},
|
|
104
|
+
_enable: function () {
|
|
105
|
+
this._enabled = true;
|
|
106
|
+
this._container.classList.add("leaflet-ruler-clicked");
|
|
107
|
+
this._circles = L.featureGroup().addTo(this._layers);
|
|
108
|
+
this._polyline = L.polyline([], this.options.lineStyle).addTo(this._layers);
|
|
109
|
+
this._layers.addTo(this._map);
|
|
110
|
+
this._latlngs = [];
|
|
111
|
+
this._totalLength = 0;
|
|
112
|
+
this._attachMouseEvents();
|
|
113
|
+
},
|
|
114
|
+
_toggleMeasure: function () {
|
|
115
|
+
this._enabled ? this._disable() : this._enable();
|
|
116
|
+
},
|
|
117
|
+
_drawTooltip: function (latlng, layer, incremental) {
|
|
118
|
+
let lastClick = this._latlngs[this._latlngs.length - 1] ?? latlng;
|
|
119
|
+
let bearing = this._calculateBearing(lastClick, latlng);
|
|
120
|
+
let distance = lastClick.distanceTo(latlng) * this.options.lengthUnit.factor;
|
|
121
|
+
let accumulated = this._totalLength + distance;
|
|
122
|
+
let totalLength = accumulated.toFixed(this.options.lengthUnit.decimal);
|
|
123
|
+
let plusLength = incremental ? '<br><div class="plus-length">(+' + distance.toFixed(this.options.lengthUnit.decimal) + ')</div>' : '';
|
|
124
|
+
this._totalLength = incremental ? this._totalLength : accumulated;
|
|
125
|
+
if (!layer.getTooltip()) layer.bindTooltip('', incremental ? { direction: "auto", sticky: true, offset: L.point(0, -40), className: 'moving-tooltip' } : { permanent: true, className: 'result-tooltip' }).openTooltip();
|
|
126
|
+
layer.setLatLng(latlng).setTooltipContent('<b>' + this.options.angleUnit.label + '</b> ' + bearing.toFixed(this.options.angleUnit.decimal) + ' ' + this.options.angleUnit.display + '<br><b>' + this.options.lengthUnit.label + '</b> ' + totalLength + ' ' + this.options.lengthUnit.display + plusLength);
|
|
127
|
+
},
|
|
128
|
+
_addPoint: function (e) {
|
|
129
|
+
let latlng = e.latlng || e;
|
|
130
|
+
let point = L.circleMarker(latlng, this.options.circleMarker).addTo(this._circles);
|
|
131
|
+
this._polyline.addLatLng(latlng);
|
|
132
|
+
if(this._latlngs.length && !latlng.equals(this._latlngs[this._latlngs.length - 1])){
|
|
133
|
+
this._drawTooltip(latlng, point, false);
|
|
134
|
+
}
|
|
135
|
+
this._latlngs.push(latlng);
|
|
136
|
+
},
|
|
137
|
+
_moving: function (e) {
|
|
138
|
+
if (this._latlngs.length) {
|
|
139
|
+
let lastCLick = this._latlngs[this._latlngs.length - 1];
|
|
140
|
+
if (!this._tempLine) this._tempLine = L.polyline([], this.options.lineStyle).addTo(this._map);
|
|
141
|
+
if (!this._tempPoint) this._tempPoint = L.circleMarker(e.latlng, this.options.circleMarker).addTo(this._map);
|
|
142
|
+
this._tempLine.setLatLngs([lastCLick, e.latlng]);
|
|
143
|
+
this._drawTooltip(e.latlng, this._tempPoint, true);
|
|
144
|
+
L.DomEvent.off(this._container, 'click', this._toggleMeasure, this);
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
_escape: function (e) {
|
|
148
|
+
if (e.keyCode === 27) {
|
|
149
|
+
if (this._latlngs.length) {
|
|
150
|
+
this._closePath();
|
|
151
|
+
} else {
|
|
152
|
+
this._enabled = true;
|
|
153
|
+
this._toggleMeasure();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
_calculateBearing: function (start, end) {
|
|
158
|
+
const toRad = L.DomUtil.DEG_TO_RAD;
|
|
159
|
+
const toDeg = (this.options.angleUnit.factor / 2) / Math.PI;
|
|
160
|
+
let y = Math.sin((end.lng - start.lng) * toRad) * Math.cos(end.lat * toRad);
|
|
161
|
+
let x = Math.cos(start.lat * toRad) * Math.sin(end.lat * toRad) - Math.sin(start.lat * toRad) * Math.cos(end.lat * toRad) * Math.cos((end.lng - start.lng) * toRad);
|
|
162
|
+
return (Math.atan2(y, x) * toDeg + this.options.angleUnit.factor) % this.options.angleUnit.factor;
|
|
163
|
+
},
|
|
164
|
+
_closePath: function () {
|
|
165
|
+
if (this._tempLine) {
|
|
166
|
+
this._tempLine.remove();
|
|
167
|
+
this._tempLine = null;
|
|
168
|
+
}
|
|
169
|
+
if (this._tempPoint) {
|
|
170
|
+
this._tempPoint.remove();
|
|
171
|
+
this._tempLine = null;
|
|
172
|
+
}
|
|
173
|
+
if (this._latlngs.length <= 1) {
|
|
174
|
+
this._circles.remove();
|
|
175
|
+
}
|
|
176
|
+
this._enabled = false;
|
|
177
|
+
L.DomEvent.on(this._container, 'click', this._toggleMeasure, this);
|
|
178
|
+
this._toggleMeasure();
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
L.control.ruler = function (options) {
|
|
182
|
+
return new L.Control.Ruler(options);
|
|
183
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.leaflet-ruler{height:35px;width:35px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAACx0lEQVRIS52VWahOURTHXRSJzBkiJcpYxgeS4oUi90GR4VK6DzcUD3gQIQ8UCXkwlCJRkjJEpqT7oGTMeHONmacyRRl/v9ve2n2d7/vOtevXPmefff5r7bXXXruiSf42gKkToTu0hY/wEk7CnWIyFWX0B/N9OkyF1tANdsEz6AIL4Sl8h8NwEK6nmsUMNGPSalgePFxLfwl2hrG39O1hM8yFobAKpsAGWAE/NJRloBfj++ErnIYesDj1qsjzRsYN2VhwdTPgUaGBkUF0e/D0TxDrRD8ehsFw6AcP4FrgCL17EpsrWAKDUgNtwuQP9FehJsyeSb8FbsOV8O0efVeYHOZV0h8N8w3dWXBOVWpgDwO/oBqc1BxciV7Pg3OJhz66ivPB+PoM8TnqRQPTeNkKfeALtAQ39QYsgE85xNsFz+voFe8AldFALS8DYU3waAd9b5gAv3OKn2HefagK4q64VgPm9k0we0wtN9pN6w+mY9qywqLnWeKXGa/WwHwYFSwrZtw/w9Ic4p5oxesLPG8Qd/UacMf13IE38ArGwN3EQJbnintOHsJsMOaG5Z+4/2vAY282eALd4FvQqoj4Aca3gQfPw1hSPBr4xoNH3bz1EO0D428r9LwpY3vB+nSolOfRQVeg1yOCgXH01pu+GeL+Y1hOwWOYBZlhieJxBU94eA2Lwo9WRw+X8fUEx0PUaPFowKW6Cg+UBc6M6AzrMsR1xtJR1vO4CkNk1TMLJoXBlcHQpvAePW+0eFyBRe45jAbL7fskhqm4MbdGmYruUU94l8zNfIyl4hhfLQteHqaiLYq7J4YlipvnXkgWRotgyRYNWB4st6bpizLiHsiO4H1gMrhnRVtarpcxy0vd+9eLPMvzhuMf1E7QmyC78xrQmDk+BC6Am98CLoKXi/dvWll1xjvjeAkD9YVXpkJ6ae7/BOPus4b+p9X9BdB/zv8zawwXAAAAAElFTkSuQmCC);background-repeat:no-repeat;background-position:center}.leaflet-ruler-clicked,.leaflet-ruler:hover{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAE/ElEQVRIS6WVeWwUVRzHfzOzs7Pdi+7Rdq/ubrH0sNaKBFMCSEvBQLivFkhAE8GDYAyHATWgETUoMZ7BGCMBNKYiQbTKpYQKBqKlWmBbadmW7bbbFjv0mu2eM298M5SlpS3U+LL/zL6Zz/f7vr/3e4+AsQ6j80EgxTkKhGwkQRqQiLp5UtEOSDwOXf660TDEPfkGR75RTT8VF1EpJRJ6LsbrVuaZg2YtrWND8WD5FVajV9IcTyCOoYhv2QgcgE5fzWDmaAKU0eHa3RMStszNMqIdM+zUY3YdPFvRCG+VOCFFQ0N3mIfNJ3ywb3Em/BHgYNeZFnTc20OOU1Efd7eZtwBUxyWh4QLJGS6jFv04MU2bNWeCQRnoi8L7czPuG+RLJ31g0Smhsqk3dqGVa7wZZOZBb/31oQKm8ZMZRbxyU6FV9XaJmyQGZsNxBD/Ud8FXNWy/rzci9ER4Spqa5tYrit3jmNI8M2DnCRNvnm1Bu35tjcR4lH1HIDtbp+2NNuSmqCyTrBr4dMEDuH4A754LCLvOtQo44zouKp7hQagGIK+CIFgoipqPEHru6OocWJhtlAWk6GZ8cSXs64sd49qbSxMCaenu7+ZkGuftW5JJSy/FBARlh+vDF1tDfWEerYWullNDcjK5c9Q0Or/jcad++3SbbP8ueBn+S7glkOIsNTDUQf+mRxmtkoIIj6Bgb024hYtVhGPK9dDl7RsJvhPDtw3AcWzYuSd8vTcqOS8DrcUIKsUiWcDgyKghRLFgZ1E6vFhohfXfN8YP1bFVfW3N0/E0Ggu8CMNxfY9z7b5SCU4o6dMkhc4RYM61aulwU8fWSSqaIqEqEIRZBzzBSCg+HoIdncPglHgBG9ENdj4inEAXhZuBdQSYXBuWZOnfOLI61yTB1ld4Y1/+xe6Ndvo33Q+ON5Rc0GHOB+DS6gmF2XF6dkZy0eeLM8lU3EDGd6qiQRAnQnvz3wkBXFANdr5jkHMJXrS/NtTIRk5yN3wrErEMgsuNpkp13ViRZ0zdOtUOWiUJ2R/WxPibfmYk+Mp8E/XCT01y4y0/1HBfuCygMDljVzYW0DnmJKhuC8Lsg7WB7kCzQxa4y7nUF08euQblHlZMoqij93J+2yBBpzgjlzcUMJLAmeu9sOjrq+1cR7PtNvzVYrv+5WkOUvpAiqUYx+JlI6cwfPlosQyuHcGYnYECq9r2AV62O5mB9PcuItxjj2ho6uz/hcsRESbH4TX5qQv3LsigNbjJ7Huq+tkIT75enM4Mdx76mbvhXzYW54mIwOBeNd2l+eTs03nyYYIPqrhaSVGbC213xfLf4fIKAB9yqp4IW/VMvtKqVYJJrUhEeCdzGS5lbki22Wu5btYg0IwV2hrYIb0ywoN8VCTbXadDUTRz/9IJsCrfLL82CP7LQCyGcVab56HColQkCKL3ctWxTs/5+WMSAHwPGBih0rNxotqGL42R4DqLpebhKTNta7fvgWBfN7yybIoQjYdzoLPVey+RxHFtdrhfy05J2laxKjep5EAd3oqhhHNtqrm6YOoT6RKcIOXSwEdb1ojXLv35fDRQ99mYBKR6GOyu3zBhcowXTvR3+JdCWhqjVhk9FEW7Z5Wtw1vuFlwatb9XQmuD51J/MFQ+qgAheIdemSl5FoDgOuhs3o0/4vWOKcZkh/4bEJFKxAMA/6QhgsjzAvrH3+SXn0YZAinU/wuTosgK53+p+wAAAABJRU5ErkJggg==)}.leaflet-ruler-clicked{height:35px;width:35px;background-repeat:no-repeat;background-position:center;border-color:#7fff00!important}.leaflet-bar.leaflet-ruler{background-color:#fff}.leaflet-control.leaflet-ruler{cursor:pointer}.result-tooltip{background-color:#fff;border-width:medium;border-color:#de0000;font-size:smaller}.moving-tooltip{background-color:rgba(255,255,255,.7);background-clip:padding-box;opacity:.5;border:dotted;border-color:red;font-size:smaller}.plus-length{padding-left:45px}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
L.Control.Ruler=L.Control.extend({options:{position:"topright",circleMarker:{color:"red",radius:2},lineStyle:{color:"red",dashArray:"1,6"},lengthUnit:{display:"km",decimal:2,factor:.001,label:"Distance:"},angleUnit:{display:"°",decimal:2,factor:360,label:"Bearing:"}},initialize:function(options){L.setOptions(this,options),this._layers=L.layerGroup(),this._enabled=!1},onAdd:function(map){this._defaultCursor=map._container.style.cursor,this._map=map;let container=L.DomUtil.create("div","leaflet-bar");return container.classList.add("leaflet-ruler"),L.DomEvent.disableClickPropagation(container),L.DomEvent.on(container,"click",this._toggleMeasure,this),this._container=container},onRemove:function(){L.DomEvent.off(this._container,"click",this._toggleMeasure,this)},_attachMouseEvents:function(){let map=this._map;map.doubleClickZoom.disable(),L.DomEvent.on(map._container,"keydown",this._escape,this),L.DomEvent.on(map._container,"dblclick",this._closePath,this),map._container.style.cursor="crosshair",map.on("click",this._addPoint,this),map.on("mousemove",this._moving,this)},_removeMouseEvents:function(){let map=this._map;map.doubleClickZoom.enable(),L.DomEvent.off(map._container,"keydown",this._escape,this),L.DomEvent.off(map._container,"dblclick",this._closePath,this),map._container.style.cursor=this._defaultCursor,map.off("click",this._addPoint,this),map.off("mousemove",this._moving,this)},_disable:function(){this._enabled=!1,this._container.classList.remove("leaflet-ruler-clicked"),this._map.removeLayer(this._layers),this._layers=L.layerGroup(),this._latlngs=[],this._totalLength=0,this._removeMouseEvents()},_enable:function(){this._enabled=!0,this._container.classList.add("leaflet-ruler-clicked"),this._circles=L.featureGroup().addTo(this._layers),this._polyline=L.polyline([],this.options.lineStyle).addTo(this._layers),this._layers.addTo(this._map),this._latlngs=[],this._totalLength=0,this._attachMouseEvents()},_toggleMeasure:function(){this._enabled?this._disable():this._enable()},_drawTooltip:function(latlng,layer,incremental){let clickCount=this._latlngs.length,lastClick=clickCount?this._latlngs[clickCount-1]:latlng,bearing=this._calculateBearing(lastClick,latlng),distance=lastClick.distanceTo(latlng)*this.options.lengthUnit.factor,totalLength,plusLength;incremental?(totalLength=(clickCount?distance+this._totalLength||0:distance).toFixed(this.options.lengthUnit.decimal),plusLength=clickCount?'<br><div class="plus-length">(+'+distance.toFixed(this.options.lengthUnit.decimal)+")</div>":""):(this._totalLength+=distance,totalLength=(clickCount?this._totalLength:distance).toFixed(this.options.lengthUnit.decimal),plusLength="");var text="<b>"+this.options.angleUnit.label+"</b> "+bearing.toFixed(this.options.angleUnit.decimal)+" "+this.options.angleUnit.display+"<br><b>"+this.options.lengthUnit.label+"</b> "+totalLength+" "+this.options.lengthUnit.display+plusLength;layer.setLatLng(latlng);let tooltip=layer.getTooltip();return tooltip?tooltip.setTooltipContent(text):layer.bindTooltip(text,incremental?{direction:"auto",sticky:!0,offset:L.point(0,-40),className:"moving-tooltip"}:{permanent:!0,className:"result-tooltip"}).openTooltip(),layer},_addPoint:function(e){let latlng=e.latlng||e,point=L.circleMarker(latlng,this.options.circleMarker).addTo(this._circles);this._polyline.addLatLng(latlng),this._latlngs.length&&!latlng.equals(this._latlngs[this._latlngs.length-1])&&this._drawTooltip(latlng,point,!1),this._latlngs.push(latlng)},_moving:function(e){if(this._latlngs.length){let lastCLick=this._latlngs[this._latlngs.length-1];this._tempLine||(this._tempLine=L.polyline([],this.options.lineStyle).addTo(this._map)),this._tempPoint||(this._tempPoint=L.circleMarker(e.latlng,this.options.circleMarker).addTo(this._map)),this._tempLine.setLatLngs([lastCLick,e.latlng]),this._drawTooltip(e.latlng,this._tempPoint,!0),L.DomEvent.off(this._container,"click",this._toggleMeasure,this)}},_escape:function(e){27===e.keyCode&&(this._latlngs.length?this._closePath():(this._enabled=!0,this._toggleMeasure()))},_calculateBearing:function(start,end){const toRad=L.DomUtil.DEG_TO_RAD,toDeg=this.options.angleUnit.factor/2/Math.PI;let y=Math.sin((end.lng-start.lng)*toRad)*Math.cos(end.lat*toRad),x=Math.cos(start.lat*toRad)*Math.sin(end.lat*toRad)-Math.sin(start.lat*toRad)*Math.cos(end.lat*toRad)*Math.cos((end.lng-start.lng)*toRad);return(Math.atan2(y,x)*toDeg+this.options.angleUnit.factor)%this.options.angleUnit.factor},_closePath:function(){this._tempLine&&(this._map.removeLayer(this._tempLine),this._tempLine=null),this._tempPoint&&(this._map.removeLayer(this._tempPoint),this._tempLine=null),this._latlngs.length<=1&&this._map.removeLayer(this._circles),this._enabled=!1,L.DomEvent.on(this._container,"click",this._toggleMeasure,this),this._toggleMeasure()}}),L.control.ruler=function(options){return new L.Control.Ruler(options)};
|
package/package.json
CHANGED
package/src/acceleration.js
CHANGED
|
@@ -13,6 +13,48 @@ Elevation.addInitHook(function() {
|
|
|
13
13
|
acceleration.label = opts.accelerationLabel || L._(opts.imperial ? 'ft/s²' : 'm/s²');
|
|
14
14
|
opts.accelerationFactor = opts.accelerationFactor || 1;
|
|
15
15
|
|
|
16
|
+
this._registerDataAttribute({
|
|
17
|
+
name: 'acceleration',
|
|
18
|
+
init: () => {
|
|
19
|
+
// this.track_info.acceleration_max = -Infinity; // Acceleration Max
|
|
20
|
+
// this.track_info.acceleration_min = +Infinity; // Acceleration Min
|
|
21
|
+
// this.track_info.acceleration_avg = 0; // Acceleration Avg
|
|
22
|
+
},
|
|
23
|
+
fetch: (i) => {
|
|
24
|
+
let data = this._data;
|
|
25
|
+
let dv = (data[i].speed - data[i > 0 ? i - 1 : i].speed) * (1000 / opts.timeFactor);
|
|
26
|
+
let dt = (data[i].time - data[i > 0 ? i - 1 : i].time) / 1000;
|
|
27
|
+
return dt > 0 ? Math.abs((dv / dt)) * opts.accelerationFactor : 0;
|
|
28
|
+
},
|
|
29
|
+
update: (acceleration, i) => {
|
|
30
|
+
this.track_info.acceleration_max = this.track_info.acceleration_max || -Infinity; // Acceleration Max
|
|
31
|
+
this.track_info.acceleration_min = this.track_info.acceleration_min || +Infinity; // Acceleration Min
|
|
32
|
+
this.track_info.acceleration_avg = this.track_info.acceleration_avg || 0; // Acceleration Avg
|
|
33
|
+
|
|
34
|
+
let data = this._data;
|
|
35
|
+
let track = this.track_info;
|
|
36
|
+
|
|
37
|
+
// Try to smooth "crazy" acceleration values.
|
|
38
|
+
if (this.options.accelerationDeltaMax) {
|
|
39
|
+
let delta = acceleration - data[i > 0 ? i - 1 : i].acceleration;
|
|
40
|
+
let deltaMax = this.options.accelerationDeltaMax;
|
|
41
|
+
if (Math.abs(delta) > deltaMax) {
|
|
42
|
+
acceleration = data[i - 1].acceleration + deltaMax * Math.sign(delta);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Range of acceptable acceleration values.
|
|
47
|
+
acceleration = _.clamp(acceleration, this.options.accelerationRange);
|
|
48
|
+
|
|
49
|
+
if (acceleration > track.acceleration_max) track.acceleration_max = acceleration;
|
|
50
|
+
if (acceleration < track.acceleration_min) track.acceleration_min = acceleration;
|
|
51
|
+
|
|
52
|
+
track.acceleration_avg = (acceleration + track.acceleration_avg) / 2.0;
|
|
53
|
+
|
|
54
|
+
return L.Util.formatNum(acceleration, 2);
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
16
58
|
if (this.options.acceleration != "summary") {
|
|
17
59
|
|
|
18
60
|
this._registerAxisScale({
|
|
@@ -26,16 +68,16 @@ Elevation.addInitHook(function() {
|
|
|
26
68
|
label : acceleration.label,
|
|
27
69
|
labelX : 25,
|
|
28
70
|
labelY : -8,
|
|
29
|
-
name : 'acceleration'
|
|
71
|
+
name : 'acceleration',
|
|
30
72
|
});
|
|
31
73
|
|
|
32
74
|
this._registerAreaPath({
|
|
33
|
-
name
|
|
34
|
-
label
|
|
35
|
-
yAttr
|
|
36
|
-
scaleX
|
|
37
|
-
scaleY
|
|
38
|
-
color
|
|
75
|
+
name : 'acceleration',
|
|
76
|
+
label : 'Acceleration',
|
|
77
|
+
yAttr : 'acceleration',
|
|
78
|
+
scaleX : 'distance',
|
|
79
|
+
scaleY : 'acceleration',
|
|
80
|
+
color : '#050402',
|
|
39
81
|
strokeColor : '#000',
|
|
40
82
|
strokeOpacity: "0.5",
|
|
41
83
|
fillOpacity : "0.25",
|
|
@@ -43,65 +85,28 @@ Elevation.addInitHook(function() {
|
|
|
43
85
|
|
|
44
86
|
}
|
|
45
87
|
|
|
46
|
-
this.on('elepoint_added', function(e) {
|
|
47
|
-
let data = this._data;
|
|
48
|
-
let i = e.index;
|
|
49
|
-
|
|
50
|
-
let currT = data[i].time;
|
|
51
|
-
let prevT = i > 0 ? data[i - 1].time : currT;
|
|
52
|
-
|
|
53
|
-
let deltaT = (currT - prevT) / 1000;
|
|
54
|
-
|
|
55
|
-
let track = this.track_info;
|
|
56
|
-
let sMax = track.acceleration_max || -Infinity; // Acceleration Max
|
|
57
|
-
let sMin = track.acceleration_min || +Infinity; // Acceleration Min
|
|
58
|
-
let sAvg = track.acceleration_avg || 0; // Acceleration Avg
|
|
59
|
-
let acceleration = 0;
|
|
60
|
-
|
|
61
|
-
if (deltaT > 0) {
|
|
62
|
-
let curr = data[i].speed;
|
|
63
|
-
let prev = i > 0 ? data[i - 1].speed : curr;
|
|
64
|
-
let delta = (curr - prev) * (1000 / opts.timeFactor);
|
|
65
|
-
acceleration = Math.abs((delta / deltaT)) * opts.accelerationFactor;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Try to smooth "crazy" acceleration values.
|
|
69
|
-
if (this.options.accelerationDeltaMax) {
|
|
70
|
-
let deltaA = i > 0 ? acceleration - data[i - 1].acceleration : 0;
|
|
71
|
-
let maxDeltaS = this.options.accelerationDeltaMax;
|
|
72
|
-
if (Math.abs(deltaA) > maxDeltaS) {
|
|
73
|
-
acceleration = data[i - 1].acceleration + maxDeltaS * Math.sign(deltaA);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Range of acceptable acceleration values.
|
|
78
|
-
acceleration = _.clamp(acceleration, this.options.accelerationRange);
|
|
79
|
-
|
|
80
|
-
track.acceleration_max = acceleration > sMax ? acceleration : sMax;
|
|
81
|
-
track.acceleration_min = acceleration < sMin ? acceleration : sMin;
|
|
82
|
-
track.acceleration_avg = (acceleration + sAvg) / 2.0;
|
|
83
|
-
|
|
84
|
-
data[i].acceleration = L.Util.formatNum(acceleration, 2);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
88
|
this._registerTooltip({
|
|
88
89
|
name : 'acceleration',
|
|
89
90
|
chart: (item) => L._("a: ") + item.acceleration + " " + acceleration.label,
|
|
90
91
|
marker: (item) => Math.round(item.acceleration) + " " + acceleration.label,
|
|
92
|
+
order: 60,
|
|
91
93
|
});
|
|
92
94
|
|
|
93
95
|
this._registerSummary({
|
|
94
96
|
"minacceleration" : {
|
|
95
97
|
label: "Min Acceleration: ",
|
|
96
|
-
value: (track) => Math.round(track.acceleration_min || 0) + ' ' + acceleration.label
|
|
98
|
+
value: (track) => Math.round(track.acceleration_min || 0) + ' ' + acceleration.label,
|
|
99
|
+
order: 60
|
|
97
100
|
},
|
|
98
101
|
"maxacceleration" : {
|
|
99
102
|
label: "Max Acceleration: ",
|
|
100
|
-
value: (track) => Math.round(track.acceleration_max || 0) + ' ' + acceleration.label
|
|
103
|
+
value: (track) => Math.round(track.acceleration_max || 0) + ' ' + acceleration.label,
|
|
104
|
+
order: 60
|
|
101
105
|
},
|
|
102
106
|
"avgacceleration": {
|
|
103
107
|
label: "Avg Acceleration: ",
|
|
104
|
-
value: (track) => Math.round(track.acceleration_avg || 0) + ' ' + acceleration.label
|
|
108
|
+
value: (track) => Math.round(track.acceleration_avg || 0) + ' ' + acceleration.label,
|
|
109
|
+
order: 60
|
|
105
110
|
}
|
|
106
111
|
});
|
|
107
112
|
|