mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-19 09:22:12 +00:00
88 lines
3.5 KiB
TypeScript
88 lines
3.5 KiB
TypeScript
/**
|
|||
|
|
* Computes the statistics of `assets/example.gpx` with the engine, and writes them to
|
||
|
|
* `assets/example-data.ts`, where the pages that show an example (the home page, the
|
||
|
|
* documentation) take them from. Run it when the example, or the way the engine computes the
|
||
|
|
* statistics, changes:
|
||
|
|
*
|
||
|
|
* npm run generate:example
|
||
|
|
*
|
||
|
|
* The engine has to be built (`wasm-pack build wasm --target bundler --out-dir ../pkg`, in
|
||
|
|
* `gpx-rs`).
|
||
|
|
*/
|
||
|
|
import fs from 'fs';
|
||
|
|
import path from 'path';
|
||
|
|
import { fileURLToPath, pathToFileURL } from 'url';
|
||
|
|
import prettier from 'prettier';
|
||
|
|
|
||
|
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
||
|
|
const assets = path.resolve(here, '../assets');
|
||
|
|
const packageDirectory = path.resolve(here, '../../../../gpx-rs/pkg');
|
||
|
|
|
||
|
|
export const exampleGPX = path.join(assets, 'example.gpx');
|
||
|
|
export const exampleData = path.join(assets, 'example-data.ts');
|
||
|
|
|
||
|
|
/** Whether the engine is built. */
|
||
|
|
export function engineIsBuilt() {
|
||
|
|
return fs.existsSync(path.join(packageDirectory, 'gpx_rs_bg.wasm'));
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Loads the engine in Node: the package is made for bundlers, which import the wasm file. */
|
||
|
|
async function loadEngine() {
|
||
|
|
const glue = await import(pathToFileURL(path.join(packageDirectory, 'gpx_rs_bg.js')).href);
|
||
|
|
const { instance } = await WebAssembly.instantiate(
|
||
|
|
fs.readFileSync(path.join(packageDirectory, 'gpx_rs_bg.wasm')),
|
||
|
|
{ './gpx_rs_bg.js': glue }
|
||
|
|
);
|
||
|
|
glue.__wbg_set_wasm(instance.exports);
|
||
|
|
(instance.exports.__wbindgen_start as () => void)();
|
||
|
|
return glue as typeof import('gpx-rs');
|
||
|
|
}
|
||
|
|
|
||
|
|
type Values = Float64Array | BigInt64Array | undefined;
|
||
|
|
|
||
|
|
/** The arrays that the engine has for the example, which are all the pages need. */
|
||
|
|
export async function computeExampleData() {
|
||
|
|
const engine = await loadEngine();
|
||
|
|
engine.start();
|
||
|
|
const data = fs.readFileSync(exampleGPX);
|
||
|
|
engine.load_files(new Uint8Array(data), Uint32Array.from([data.length]), ['example']);
|
||
|
|
|
||
|
|
// numbers are enough for the times, which are milliseconds
|
||
|
|
const numbers = (values: Values) =>
|
||
|
|
values && Array.from(values as ArrayLike<number | bigint>, (value) => Number(value));
|
||
|
|
return {
|
||
|
|
global: engine.selection_statistics(),
|
||
|
|
totalDistance: numbers(engine.total_distance()),
|
||
|
|
movingDistance: numbers(engine.moving_distance()),
|
||
|
|
totalTime: numbers(engine.total_time()),
|
||
|
|
movingTime: numbers(engine.moving_time()),
|
||
|
|
elevationGain: numbers(engine.elevation_gain()),
|
||
|
|
elevationLoss: numbers(engine.elevation_loss()),
|
||
|
|
slope: numbers(engine.slope()),
|
||
|
|
slopeSegmentSlope: numbers(engine.slope_segment_slope()),
|
||
|
|
slopeSegmentDistance: numbers(engine.slope_segment_distance()),
|
||
|
|
lng: numbers(engine.lng()),
|
||
|
|
lat: numbers(engine.lat()),
|
||
|
|
ele: numbers(engine.ele()),
|
||
|
|
timestamps: numbers(engine.timestamps()),
|
||
|
|
speed: numbers(engine.speed()),
|
||
|
|
atemp: numbers(engine.atemp()),
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
async function generate() {
|
||
|
|
const data = await computeExampleData();
|
||
|
|
const source = `// Generated by src/lib/scripts/example-statistics.ts from example.gpx: do not edit.
|
||
|
|
export const exampleData = ${JSON.stringify(data)};
|
||
|
|
`;
|
||
|
|
const options = (await prettier.resolveConfig(exampleData)) ?? {};
|
||
|
|
fs.writeFileSync(
|
||
|
|
exampleData,
|
||
|
|
await prettier.format(source, { ...options, parser: 'typescript' })
|
||
|
|
);
|
||
|
|
console.log(`Wrote ${path.relative(process.cwd(), exampleData)}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (process.argv[1] && pathToFileURL(process.argv[1]).href === import.meta.url) {
|
||
|
|
generate();
|
||
|
|
}
|