Skip to content

Commit 1615b7c

Browse files
#664 MeasureTool - Speed/Arrival (#665)
* #664 MeasureTool Arrival 1 * #664 MeasureTool Arrival part 2 * Update tool configs
1 parent 2f98149 commit 1615b7c

File tree

3 files changed

+206
-54
lines changed

3 files changed

+206
-54
lines changed

src/essence/Basics/Formulae_/Formulae_.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,6 +2043,48 @@ var Formulae_ = {
20432043
document.getSelection().addRange(selected) // Restore the original selection
20442044
}
20452045
},
2046+
speedToMetersPerSeconds(speed, fromUnit) {
2047+
switch (fromUnit) {
2048+
case 'm/s':
2049+
case 'mps':
2050+
return speed / 1
2051+
case 'km/h':
2052+
case 'kph':
2053+
return speed / 3.6
2054+
case 'mi/h':
2055+
case 'mph':
2056+
return speed / 2.2369362921
2057+
case 'kt':
2058+
case 'kn':
2059+
return speed / 1.9438444924
2060+
case 'ft/s':
2061+
return speed / 3.280839895
2062+
default:
2063+
console.warn(`Unknown speed conversion unit: ${fromUnit}`)
2064+
return speed
2065+
}
2066+
},
2067+
metersPerSecondsToSpeed(speed, toUnit) {
2068+
switch (toUnit) {
2069+
case 'm/s':
2070+
case 'mps':
2071+
return speed * 1
2072+
case 'km/h':
2073+
case 'kph':
2074+
return speed * 3.6
2075+
case 'mi/h':
2076+
case 'mph':
2077+
return speed * 2.2369362921
2078+
case 'kt':
2079+
case 'kn':
2080+
return speed * 1.9438444924
2081+
case 'ft/s':
2082+
return speed * 3.280839895
2083+
default:
2084+
console.warn(`Unknown speed conversion unit: ${toUnit}`)
2085+
return speed
2086+
}
2087+
},
20462088
toHost() {
20472089
window.location = window.location.href.split('?')[0]
20482090
},

src/essence/Tools/Measure/MeasureTool.css

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
.MeasureTool #measureUnit,
3838
.MeasureTool #measureLOS,
3939
.MeasureTool #measureObserverHeight,
40-
.MeasureTool #measureTargetHeight {
40+
.MeasureTool #measureTargetHeight,
41+
.MeasureTool #measureSpeed {
4142
display: flex;
4243
justify-content: space-between;
4344
font-size: 14px;
@@ -78,6 +79,21 @@
7879
font-size: 13px;
7980
}
8081

82+
.MeasureTool #measureSpeed input {
83+
border: none;
84+
padding: 1px 5px 0px 6px;
85+
height: 25px;
86+
width: 80px;
87+
background: var(--color-a1-5);
88+
text-align: right;
89+
color: var(--color-a7);
90+
border-left: 1px solid var(--color-a);
91+
}
92+
.MeasureTool #measureSpeed select {
93+
width: 55px;
94+
border-left: 1px solid var(--color-a);
95+
}
96+
8197
.MeasureTool #measureLeft {
8298
width: 260px;
8399
height: 100%;

src/essence/Tools/Measure/MeasureTool.js

Lines changed: 147 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import React, { useState, useEffect, useRef } from 'react'
1616
import { Chart } from 'chart.js'
1717
import { Line } from 'react-chartjs-2'
1818
import zoomPlugin from 'chartjs-plugin-zoom'
19+
import * as moment from 'moment'
1920

2021
import './MeasureTool.css'
2122

@@ -215,7 +216,7 @@ const Measure = () => {
215216
</div>
216217
</div>
217218
<div id='measureObserverHeight'>
218-
<div>Observer Height</div>
219+
<div>&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;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

635687
let 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 + '&deg;',
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-
'&deg;',
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}&deg;${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 + "&deg;",
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}&deg;`,
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}&deg;`,
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}&deg;</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

16751769
function totalDistToIndex(l) {

0 commit comments

Comments
 (0)