Skip to content

Commit

Permalink
Bug Fix in JS 3D Distance calc and Admin GPX statistics
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinvonBerg committed Nov 22, 2024
1 parent c58bbcd commit cb64389
Show file tree
Hide file tree
Showing 6 changed files with 1,311 additions and 1,603 deletions.
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["@babel/preset-env"]
}
12 changes: 6 additions & 6 deletions admin_rust_wasm/www/distance.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
* @returns {number} - The distance between the two coordinates in km.
*/
export function calcdistance(lat1, lon1, lat2, lon2) {
const r = 12742; // 6371 * 2
const r = 12742; // 6371 * 2 earth diameter in km
const toRadians = (degrees) => degrees * (Math.PI / 180);

const dLat = Math.sin((toRadians(lat2) - toRadians(lat1)) / 2);
const dLon = Math.sin((toRadians(lon2) - toRadians(lon1)) / 2);

const a = dLat * dLat + Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) * dLon * dLon;
const d = r * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const d = r * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); // in km

return d;
}
Expand All @@ -32,16 +32,16 @@ export function calcdistance(lat1, lon1, lat2, lon2) {
* @returns {number} - The distance between the two coordinates in km.
*/
export function calc3DDistance(lat1, lon1, alt1=0, lat2, lon2, alt2=0) {
const r = 12742000; // 6371 * 2
const r = 12742; // 6371 * 2
const toRadians = (degrees) => degrees * (Math.PI / 180);

const dLat = Math.sin((toRadians(lat2) - toRadians(lat1)) / 2);
const dLon = Math.sin((toRadians(lon2) - toRadians(lon1)) / 2);

const a = dLat * dLat + Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) * dLon * dLon;
const d = r * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); // m
const d = r * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); // in km

const distance = Math.sqrt( Math.pow(d, 2) + Math.pow(alt2 - alt1, 2) );
const distance = Math.sqrt( Math.pow(d, 2) + Math.pow( (alt2 - alt1)/1000, 2) ); // calc with identical units!

return distance / 1000.0;
return distance;
}
146 changes: 90 additions & 56 deletions admin_rust_wasm/www/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ import { fromHTML} from "./fromHTML";
})

// ---------- listeners for filter Value inputs
/*
esmsel.addEventListener("input", () => { // update the selected file. Use the preloaded content from the fakepath as xml-string
esm = esmsel.value;
esmStore = esm;
Expand Down Expand Up @@ -324,6 +325,33 @@ import { fromHTML} from "./fromHTML";
// filter the file and return as xml-string to global variable newFile
filterEventListener();
})
*/
// Generic function to handle input events
function handleInputEvent(selector, valueMultiplier, defaultValue, valueElement, enableCheckbox, storeVariable, globalVariableName) {
selector.addEventListener("input", () => {
let value = selector.value;
if (valueMultiplier !== undefined) {
value = value / valueMultiplier;
}
window[storeVariable] = value;

if (enableCheckbox.checked) {
window[globalVariableName] = window[storeVariable];
} else {
window[globalVariableName] = defaultValue;
}
valueElement.innerHTML = (valueMultiplier ? window[globalVariableName] * valueMultiplier : window[globalVariableName]) + " m";

// filter the file and return as xml-string to global variable newFile
filterEventListener();
});
}

// Apply the generic function for each element
handleInputEvent(esmsel, undefined, 0.0, esmval, esmenable, "esmStore", "esm");
handleInputEvent(dsmsel, 1000, 0.0, dsmval, dsmenable, "dsmStore", "dsm");
handleInputEvent(filtsel, undefined, 100.0, filtval, filterenable, "filterStore", "filter");
handleInputEvent(simplsel, undefined, 0.0, simplval, simplenable, "simplTolStore", "simplTol");

// ---------- listeners for esm, dsm, filter, simplTol enable inputs
function handleEnableClick(storedValue, enableCheckbox, globalValue) {
Expand Down Expand Up @@ -371,6 +399,7 @@ import { fromHTML} from "./fromHTML";
}
// End: define all Event listeners --------------------

// add inline CSS to make the page scrollable and to stop scrolling when overlay is visible
function updateCSS() {
// add inline CSS

Expand Down Expand Up @@ -781,41 +810,38 @@ import { fromHTML} from "./fromHTML";
let lastConsideredElevation = 0;
let lastConsideredPoint = [0, 0];

//tracks.forEach(element => {

lastConsideredElevation = element.points[0].elevation;
lastConsideredPoint = [element.points[0].latitude, element.points[0].longitude];
lastConsideredElevation = element.points[0].elevation;
lastConsideredPoint = [element.points[0].latitude, element.points[0].longitude];

element.points.forEach(point => {
// ignore / skip points with zero elevation and go to next point
if (!('elevation' in point) || (ignoreZeroElevs && (Math.abs(point.elevation) < 0.01))) {
return; // is practically the same as continue
}

let curPoint = [point.latitude, point.longitude];
let curDist = 1000 * calcdistance(lastConsideredPoint[0], lastConsideredPoint[1], curPoint[0], curPoint[1]);
let curDist3D = 1000 * calc3DDistance(lastConsideredPoint[0], lastConsideredPoint[1], lastConsideredElevation, curPoint[0], curPoint[1], point.elevation);

// save the original values
origelevs.push(point.elevation);
origlats.push(point.latitude);
origlons.push(point.longitude);
origdists.push(curDist);
//origtdelta.push(tDelta);

let SpeedH = Math.abs(point.elevation - lastConsideredElevation); // /tDelta ? Math.abs(point.elevation - lastConsideredEleStats)/tDelta : 0.0;
origSpeedH.push(SpeedH);
sumOrigSpeedH += SpeedH;

let Speed3D = curDist3D; // /tDelta ? curDist3D/tDelta : 0.0;
origSpeed3D.push(Speed3D);
sumOrigSpeed3D += Speed3D;

lastConsideredElevation = point.elevation;
lastConsideredPoint = curPoint;
//lastConsideredTime = point.time;
});
//});
element.points.forEach(point => {
// ignore / skip points with zero elevation and go to next point
if (!('elevation' in point) || (ignoreZeroElevs && (Math.abs(point.elevation) < 0.01))) {
return; // is practically the same as continue
}

let curPoint = [point.latitude, point.longitude];
let curDist = 1000 * calcdistance(lastConsideredPoint[0], lastConsideredPoint[1], curPoint[0], curPoint[1]);
let curDist3D = 1000 * calc3DDistance(lastConsideredPoint[0], lastConsideredPoint[1], lastConsideredElevation, curPoint[0], curPoint[1], point.elevation);

// save the original values
origelevs.push(point.elevation);
origlats.push(point.latitude);
origlons.push(point.longitude);
origdists.push(curDist);
//origtdelta.push(tDelta);

let SpeedH = Math.abs(point.elevation - lastConsideredElevation); // /tDelta ? Math.abs(point.elevation - lastConsideredEleStats)/tDelta : 0.0;
origSpeedH.push(SpeedH);
sumOrigSpeedH += SpeedH;

let Speed3D = curDist3D; // /tDelta ? curDist3D/tDelta : 0.0;
origSpeed3D.push(Speed3D);
sumOrigSpeed3D += Speed3D;

lastConsideredElevation = point.elevation;
lastConsideredPoint = curPoint;
//lastConsideredTime = point.time;
});

return [
origelevs,
Expand Down Expand Up @@ -901,29 +927,12 @@ import { fromHTML} from "./fromHTML";
(point.meta?.ele ?? point.elevation) :
point;

// Calculate elevation changes
if (typeof currentElevation === 'number') {
const elevationDelta = currentElevation - lastElevation;

if (Math.abs(elevationDelta) > eleSmoothing) {
if (elevationDelta > 0) {
cumulativeElevationGain += elevationDelta;
} else {
cumulativeElevationLoss -= elevationDelta;
}
lastElevation = currentElevation;
}
}

// Calculate distance
const currentPoint = Array.isArray(points) ?
[point.lat ?? point.latitude, point.lng ?? point.longitude] :
[points.lats[idx], points.lons[idx]];

const distance = 1000 * calcdistance(
lastPoint[0], lastPoint[1],
currentPoint[0], currentPoint[1]
);
const distance = 1000 * calc3DDistance(lastPoint[0], lastPoint[1], lastElevation, currentPoint[0], currentPoint[1], currentElevation);

if (Math.abs(distance) > distSmoothing) {
cumulativeDistance += distance;
Expand All @@ -935,6 +944,20 @@ import { fromHTML} from "./fromHTML";
points.lats.splice(idx, 1);
points.lons.splice(idx, 1);
}

// Calculate elevation changes
if (typeof currentElevation === 'number') {
const elevationDelta = currentElevation - lastElevation;

if (Math.abs(elevationDelta) > eleSmoothing) {
if (elevationDelta > 0) {
cumulativeElevationGain += elevationDelta;
} else {
cumulativeElevationLoss -= elevationDelta;
}
lastElevation = currentElevation;
}
}
};

// Process points based on input type
Expand Down Expand Up @@ -1119,7 +1142,6 @@ import { fromHTML} from "./fromHTML";
* @returns {string} The information string.
*/
function generateFileInfoHtml(parsedFile, NTrkPts, NRtePts, NWayPts, fileName, fileSize) {
let html = "";

if (NTrkPts == 0) {
parsedFile.tracks.forEach(element => {
Expand All @@ -1137,20 +1159,32 @@ import { fromHTML} from "./fromHTML";
NWayPts += parsedFile.waypoints.length;
}

html = "<strong>File: " + fileName + "</strong>" + " / Size: " + fileSize.toFixed(1) + " kB"
return "<strong>File: " + fileName + "</strong>" + " / Size: " + fileSize.toFixed(1) + " kB"
+ "<br>Stats in File: " + parsedFile.metadata.description
+ "<br>N Tracks: " + parsedFile.tracks.length + " / with N Points: " + NTrkPts
+ "<br>N Routes: " + parsedFile.routes.length + " / with N Points: " + NRtePts
+ "<br>N Waypoints: " + NWayPts;

return html;
}

/**
* Retrieves the current filter settings from the UI and updates the `pageVarsForJs` object.
*
* @global {object} pageVarsForJs[0]['tracks']['track_0']['info']
* @global {object} pageVarsForJs[0]['sw_options']['gpx_distsmooth' / 'gpx_elesmooth']
* @global {boolean} gpx_reduce
* @global {boolean} ignoreZeroElevs
* @global {number} dsm
* @global {number} esm
* @global {number} filter
* @global {number} simplTol
* @global {object} dsmsel
* @global {object} dsmenable
* @global {object} esmsel
* @global {object} esmenable
* @global {object} filtsel
* @global {object} filterenable
* @global {object} simplsel
* @global {object} simplenable
*
* @return {void}
*/
Expand Down
19 changes: 19 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
export default {
transform: {
"^.+\\.[tj]sx?$": "babel-jest",
},
};
*/
module.exports = {
testMatch: ["**/__tests__/**/*.js?(x)", "**/?(*.)+(spec|test).js?(x)"],
};

module.exports = {
transform: {
"^.+\\.[t|j]sx?$": "babel-jest", // Transpile .js, .jsx, .ts, and .tsx files
"^.+\\.mjs$": "babel-jest", // Transpile .mjs files
},
moduleFileExtensions: ["js", "mjs", "jsx", "ts", "tsx", "json"], // Include all possible file types
//extensionsToTreatAsEsm: [".ts", ".tsx", ".mjs", ".jsx"], // Treat these as ES Modules
};
Loading

0 comments on commit cb64389

Please sign in to comment.