@@ -16,6 +16,7 @@ import React, { useState, useEffect, useRef } from 'react'
1616import { Chart } from 'chart.js'
1717import { Line } from 'react-chartjs-2'
1818import zoomPlugin from 'chartjs-plugin-zoom'
19+ import * as moment from 'moment'
1920
2021import './MeasureTool.css'
2122
@@ -215,7 +216,7 @@ const Measure = () => {
215216 </ div >
216217 </ div >
217218 < div id = 'measureObserverHeight' >
218- < div > Observer Height</ div >
219+ < div > Observer Height</ div >
219220 < div className = 'flexbetween' >
220221 < input
221222 type = 'number'
@@ -230,7 +231,7 @@ const Measure = () => {
230231 </ div >
231232 </ div >
232233 < div id = 'measureTargetHeight' >
233- < div > Target Height</ div >
234+ < div > Target Height</ div >
234235 < div className = 'flexbetween' >
235236 < input
236237 type = 'number'
@@ -244,6 +245,31 @@ const Measure = () => {
244245 < div className = 'measureToolInputUnit' > m</ div >
245246 </ div >
246247 </ div >
248+ < div id = 'measureSpeed' >
249+ < div > Travel Speed</ div >
250+ < div className = 'flexbetween' >
251+ < input
252+ type = 'number'
253+ min = { 0 }
254+ defaultValue = { 0 }
255+ placeholder = { 0 }
256+ id = 'measureSpeedInput'
257+ onChange = { MeasureTool . changeSpeed }
258+ />
259+
260+ < select
261+ className = 'dropdown'
262+ defaultValue = '100'
263+ onChange = { MeasureTool . changeSpeedUnit }
264+ >
265+ < option value = 'm/s' > m/s</ option >
266+ < option value = 'km/h' > km/h</ option >
267+ < option value = 'mph' > mph</ option >
268+ < option value = 'kt' > kt</ option >
269+ < option value = 'ft/s' > ft/s</ option >
270+ </ select >
271+ </ div >
272+ </ div >
247273 </ div >
248274 < div
249275 id = 'measureGraph'
@@ -556,6 +582,24 @@ const Measure = () => {
556582 } `
557583 )
558584 . css ( { opacity : 1 } )
585+
586+ $ ( '#measureInfoSpeed > div:last-child' )
587+ . text (
588+ MeasureTool . speed != null &&
589+ MeasureTool . speed != 0
590+ ? `${ MeasureTool . speed } ${ MeasureTool . speedUnit } `
591+ : 'N/A'
592+ )
593+ . css ( { opacity : 1 } )
594+
595+ $ ( '#measureInfoArrives > div:last-child' )
596+ . text (
597+ MeasureTool . speed != null &&
598+ MeasureTool . speed != 0
599+ ? getArrivesStringFromDistance ( d [ 2 ] )
600+ : 'N/A'
601+ )
602+ . css ( { opacity : 1 } )
559603 }
560604 } ,
561605 } }
@@ -608,6 +652,14 @@ const Measure = () => {
608652 < div > Visible</ div >
609653 < div > --</ div >
610654 </ div >
655+ < div id = 'measureInfoSpeed' className = 'measure-info-elm' >
656+ < div > Speed</ div >
657+ < div > --</ div >
658+ </ div >
659+ < div id = 'measureInfoArrives' className = 'measure-info-elm' >
660+ < div > Arrives in</ div >
661+ < div > --</ div >
662+ </ div >
611663 </ div >
612664 < div id = 'measureToolBar' >
613665 < div
@@ -633,7 +685,7 @@ const Measure = () => {
633685}
634686
635687let MeasureTool = {
636- height : 217 ,
688+ height : 243 ,
637689 width : 'full' ,
638690 disableLayerInteractions : true ,
639691 vars : { } ,
@@ -644,6 +696,8 @@ let MeasureTool = {
644696 mapFocusMarker : null ,
645697 dems : [ ] ,
646698 activeDemIdx : 0 ,
699+ speed : null ,
700+ speedUnit : 'm/s' ,
647701 colorRamp : [
648702 '#e60049' ,
649703 '#0bb4ff' ,
@@ -1047,13 +1101,21 @@ let MeasureTool = {
10471101 makeMeasureToolLayer ( )
10481102 }
10491103 } ,
1104+ changeSpeed : function ( e ) {
1105+ MeasureTool . speed = e . target . value
1106+ } ,
1107+ changeSpeedUnit : function ( e ) {
1108+ MeasureTool . speedUnit = e . target . value
1109+ } ,
10501110 clearInfo : function ( ) {
10511111 $ ( '#measureInfoLng > div:last-child' ) . css ( { opacity : 0 } )
10521112 $ ( '#measureInfoLat > div:last-child' ) . css ( { opacity : 0 } )
10531113 $ ( '#measureInfoElev > div:last-child' ) . css ( { opacity : 0 } )
10541114 $ ( '#measureInfo2d > div:last-child' ) . css ( { opacity : 0 } )
10551115 $ ( '#measureInfo3d > div:last-child' ) . css ( { opacity : 0 } )
10561116 $ ( '#measureInfoVis > div:last-child' ) . css ( { opacity : 0 } )
1117+ $ ( '#measureInfoSpeed > div:last-child' ) . css ( { opacity : 0 } )
1118+ $ ( '#measureInfoArrives > div:last-child' ) . css ( { opacity : 0 } )
10571119 } ,
10581120 download : function ( e ) {
10591121 const header = [
@@ -1214,31 +1276,28 @@ function makeMeasureToolLayer() {
12141276 ) / rAm
12151277 if ( distAzimuth < 0 ) distAzimuth = 360 + distAzimuth //Map to 0 to 360 degrees
12161278 if ( i == clickedLatLngs . length - 1 ) {
1217- if ( distDisplayUnit == 'meters' ) {
1218- temp . bindTooltip (
1219- '' + roundedTotalDist + 'm ' + distAzimuth + '°' ,
1220- {
1221- permanent : true ,
1222- direction : 'right' ,
1223- className : 'distLabel' ,
1224- offset : [ 4 , 0 ] ,
1225- }
1226- )
1227- } else if ( distDisplayUnit == 'kilometers' ) {
1228- temp . bindTooltip (
1229- '' +
1230- ( roundedTotalDist / 1000 ) . toFixed ( 2 ) +
1231- 'km ' +
1232- distAzimuth +
1233- '°' ,
1234- {
1235- permanent : true ,
1236- direction : 'right' ,
1237- className : 'distLabel' ,
1238- offset : [ 4 , 0 ] ,
1239- }
1240- )
1279+ let dist = roundedTotalDist
1280+ let distUnit = 'm'
1281+
1282+ let timeToArrival = ''
1283+ if ( MeasureTool . speed != null && MeasureTool . speed != 0 ) {
1284+ timeToArrival = ` | Arrives in ${ getArrivesStringFromDistance (
1285+ dist
1286+ ) } (at ${ MeasureTool . speed } ${ MeasureTool . speedUnit } )`
1287+ }
1288+ if ( distDisplayUnit == 'kilometers' ) {
1289+ dist = ( roundedTotalDist / 1000 ) . toFixed ( 2 )
1290+ distUnit = 'km'
12411291 }
1292+ temp . bindTooltip (
1293+ `${ dist } ${ distUnit } | ${ distAzimuth } °${ timeToArrival } ` ,
1294+ {
1295+ permanent : true ,
1296+ direction : 'right' ,
1297+ className : 'distLabel' ,
1298+ offset : [ 4 , 0 ] ,
1299+ }
1300+ )
12421301 }
12431302 }
12441303 pointsAndPathArr . push ( temp )
@@ -1642,34 +1701,69 @@ function makeGhostLine(lng, lat) {
16421701 //distMousePoint.bindTooltip("" + roundedTotalDist + "m\n (+" + roundedDist + "m) " + distAzimuth + "°",
16431702 // {permanent: true, direction: 'right', className: "distLabel", className: "noPointerEvents", offset: [15,-15]})
16441703 //distMousePoint.addTo(Map_.map);
1645- if ( distDisplayUnit == 'meters' ) {
1646- CursorInfo . update (
1647- `${ roundedTotalDist } m ${
1648- mode === 'continuous' ? `(+${ roundedDist } m)` : ''
1649- } ${ distAzimuth } °`,
1650- null ,
1651- false ,
1652- null ,
1653- null ,
1654- null ,
1655- true
1656- )
1657- } else if ( distDisplayUnit == 'kilometers' ) {
1658- CursorInfo . update (
1659- `${ ( roundedTotalDist / 1000 ) . toFixed ( 2 ) } km ${
1660- mode === 'continuous'
1661- ? `(+${ ( roundedDist / 1000 ) . toFixed ( 2 ) } km)`
1662- : ''
1663- } ${ distAzimuth } °`,
1664- null ,
1665- false ,
1666- null ,
1667- null ,
1668- null ,
1669- true
1670- )
1704+
1705+ let distTotal = roundedTotalDist
1706+ let dist = roundedDist
1707+ let distUnit = 'm'
1708+
1709+ let timeToArrivalTotal = ''
1710+ let timeToArrival = ''
1711+ if ( MeasureTool . speed != null && MeasureTool . speed != 0 ) {
1712+ timeToArrival = `<span style="font-size: 12px; font-weight: unset; color: var(--color-a5); letter-spacing: 1px;"> (+${ getArrivesStringFromDistance (
1713+ dist
1714+ ) } )</span>`
1715+ timeToArrivalTotal = `
1716+ <span style="font-size: 13px; font-weight: unset; color: var(--color-h); letter-spacing: 1px;">Arrives in: ${ getArrivesStringFromDistance (
1717+ distTotal
1718+ ) } </span>`
1719+ }
1720+ if ( distDisplayUnit == 'kilometers' ) {
1721+ distTotal = ( roundedTotalDist / 1000 ) . toFixed ( 2 )
1722+ dist = ( roundedDist / 1000 ) . toFixed ( 2 )
1723+ distUnit = 'km'
1724+ }
1725+ CursorInfo . update (
1726+ `Distance: ${ distTotal } ${ distUnit } ${
1727+ mode === 'continuous'
1728+ ? `<span style="font-size: 12px; font-weight: unset; color: var(--color-a5); letter-spacing: 1px;">(+${ dist } ${ distUnit } )</span>`
1729+ : ''
1730+ }
1731+ <span style="font-size: 14px; font-weight: unset; color: var(--color-a6); ">Angle${
1732+ mode === 'continuous' ? ' (from start)' : ''
1733+ } : ${ distAzimuth } °</span>${ timeToArrivalTotal } ${
1734+ mode === 'continuous' ? timeToArrival : ''
1735+ } `,
1736+ null ,
1737+ false ,
1738+ null ,
1739+ null ,
1740+ null ,
1741+ true
1742+ )
1743+ }
1744+ }
1745+
1746+ function getArrivesStringFromDistance ( dist , abbreviated ) {
1747+ let speed = F_ . speedToMetersPerSeconds (
1748+ MeasureTool . speed ,
1749+ MeasureTool . speedUnit
1750+ )
1751+ let duration = moment . duration ( ( dist / speed ) * 1000 )
1752+ let dDays = duration . get ( 'days' )
1753+ let dHrs = duration . get ( 'hours' )
1754+ let dMins = duration . get ( 'minutes' )
1755+ let dSecs = duration . get ( 'seconds' )
1756+
1757+ if ( dDays === 0 ) {
1758+ if ( dHrs === 0 ) {
1759+ if ( dMins === 0 ) {
1760+ return `${ dSecs } s`
1761+ }
1762+ return `${ dMins } m ${ dSecs } s`
16711763 }
1764+ return `${ dHrs } h ${ dMins } m ${ dSecs } s`
16721765 }
1766+ return `${ dDays } D ${ dHrs } h ${ dMins } m ${ dSecs } s`
16731767}
16741768
16751769function totalDistToIndex ( l ) {
0 commit comments