Track popup
This commit is contained in:
@@ -88,9 +88,9 @@ const ICONS = {
|
||||
map: faMapLocationDot,
|
||||
marker: faLocationPin,
|
||||
footprint: faShoePrints,
|
||||
'track-off-track': faPersonHiking,
|
||||
'track-main': faPersonHiking,
|
||||
'track-hitchhiking': faCarSide,
|
||||
'off-track': faPersonHiking,
|
||||
'main': faPersonHiking,
|
||||
'hitchhiking': faCarSide,
|
||||
'track-start': faPersonHiking,
|
||||
'track-end': faPersonHiking,
|
||||
layers: faLayerGroup,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { LngLat } from 'maplibre-gl';
|
||||
|
||||
export default class Projects {
|
||||
|
||||
constructor(asProjects = {}) {
|
||||
@@ -14,4 +16,83 @@ export default class Projects {
|
||||
const sCodeName = this.getDefaultCodeName();
|
||||
return this[this.getDefaultCodeName()];
|
||||
}
|
||||
|
||||
getTrackInfo(oFeature, oTrack, oLang) {
|
||||
const iTrackId = Number(oFeature.properties.track_id);
|
||||
const oTrackFeature = oTrack.features[iTrackId] || oFeature;
|
||||
const aoCoords = oTrackFeature.geometry.coordinates;
|
||||
|
||||
if(oTrackFeature.properties.type == 'hitchhiking') {
|
||||
return {
|
||||
type: 'track',
|
||||
subtype: oTrackFeature.properties.type,
|
||||
name: oTrackFeature.properties.name
|
||||
};
|
||||
}
|
||||
|
||||
const asStats = this.getTrackStats(aoCoords);
|
||||
return {
|
||||
type: 'track',
|
||||
subtype: oTrackFeature.properties.type,
|
||||
name: oTrackFeature.properties.name,
|
||||
description: oTrackFeature.properties.description,
|
||||
distance: Math.round(asStats.distance / 100) / 10,
|
||||
elev_gain: Math.round(asStats.elevGain),
|
||||
elev_drop: Math.abs(Math.round(asStats.elevDrop)),
|
||||
duration: this.getNaturalDuration(asStats.time, oLang)
|
||||
};
|
||||
}
|
||||
|
||||
getNaturalDuration(iHours, oLang) {
|
||||
let iTimeMinutes = 0, iTimeHours = 0, iTimeDays = Math.floor(iHours/8); //8 hours a day
|
||||
if(iTimeDays > 1) iTimeDays = Math.round(iTimeDays * 2) / 2; //Round down to the closest half day
|
||||
else {
|
||||
iTimeDays = 0;
|
||||
iTimeHours = Math.floor(iHours);
|
||||
iHours -= iTimeHours;
|
||||
|
||||
iTimeMinutes = Math.floor(iHours * 4) * 15; //Round down to the closest 15 minutes
|
||||
}
|
||||
return '~'
|
||||
+(iTimeDays>0?(iTimeDays+(iTimeDays%2==0?'':'\u00bd')+' '+oLang.get(iTimeDays>1?'unit.days':'unit.day')):'') //Days
|
||||
+((iTimeHours>0 || iTimeDays==0)?iTimeHours+oLang.get('unit.hour'):'') //Hours
|
||||
+((iTimeDays>0 || iTimeMinutes==0)?'':iTimeMinutes); //Minutes
|
||||
|
||||
}
|
||||
|
||||
getTrackStats(aoCoords) {
|
||||
let iDistance = 0, iElevDrop = 0, iElevGain = 0, iTime = 0;
|
||||
|
||||
for(let i = 1; i < aoCoords.length; i++) {
|
||||
const oCurrPoint = new LngLat(aoCoords[i][0], aoCoords[i][1]);
|
||||
const oPrevPoint = new LngLat(aoCoords[i - 1][0], aoCoords[i - 1][1]);
|
||||
const iCurrElev = Number(aoCoords[i][2]);
|
||||
const iPrevElev = Number(aoCoords[i - 1][2]);
|
||||
const iElevDelta = (Number.isFinite(iCurrElev) && Number.isFinite(iPrevElev))?(iCurrElev - iPrevElev):0;
|
||||
const iSegDistance = oCurrPoint.distanceTo(oPrevPoint);
|
||||
if(iSegDistance <= 0) continue;
|
||||
|
||||
iDistance += iSegDistance;
|
||||
iElevDrop += Math.min(iElevDelta, 0);
|
||||
iElevGain += Math.max(iElevDelta, 0);
|
||||
|
||||
let iSpeedCorrecRatio = 0;
|
||||
const iAngle = iElevDelta / iSegDistance;
|
||||
if(iAngle < -1) iSpeedCorrecRatio = 0.5;
|
||||
else if(iAngle < -0.2) iSpeedCorrecRatio = 1.25;
|
||||
else if(iAngle < 0.1) iSpeedCorrecRatio = 1;
|
||||
else if(iAngle < 0.25) iSpeedCorrecRatio = 0.85;
|
||||
else if(iAngle < 0.5) iSpeedCorrecRatio = 0.6;
|
||||
else if(iAngle < 1) iSpeedCorrecRatio = 0.5;
|
||||
else iSpeedCorrecRatio = 0.25;
|
||||
iTime += iSegDistance / 1000 * iSpeedCorrecRatio / 3.5;
|
||||
}
|
||||
|
||||
return {
|
||||
distance: iDistance,
|
||||
elevDrop: iElevDrop,
|
||||
elevGain: iElevGain,
|
||||
time: iTime
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user