From a3e2d5a490bc93777ee6a703fdf64bd629f5b80f Mon Sep 17 00:00:00 2001 From: a0a7 Date: Mon, 18 Aug 2025 18:03:05 -0500 Subject: [PATCH 01/28] add favicon --- demo/static/favicon.png | Bin 0 -> 32624 bytes demo/static/img/icon/layer.svg | 7 +++++++ dist/javascript/favicon.ico | Bin 0 -> 4286 bytes 3 files changed, 7 insertions(+) create mode 100644 demo/static/favicon.png create mode 100644 demo/static/img/icon/layer.svg create mode 100644 dist/javascript/favicon.ico diff --git a/demo/static/favicon.png b/demo/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..ad836bf8d291199047921254b9c3bf97dc90fa1f GIT binary patch literal 32624 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 QRpTKSO|4C8&ZFc02U}bF$p8QV literal 0 HcmV?d00001 diff --git a/demo/static/img/icon/layer.svg b/demo/static/img/icon/layer.svg new file mode 100644 index 0000000..1745b95 --- /dev/null +++ b/demo/static/img/icon/layer.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/dist/javascript/favicon.ico b/dist/javascript/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a9ccefebccba63457dcd3d3a34e7414b9960e4a8 GIT binary patch literal 4286 zcmb`JU2IfE6vyxFQWj9##t$F?OF@xFBvE5bHMQH|gHWTsRHD9AgCJ@!g&5_nD>gj% zMNIst`T&WFsF09oBudZ%E`oJT#Y|p$L%3%WWDw;|AQ9weI(bIMbT2=q@$Zj_+@@{xNj-!r!2Ltc3IMKjeEY>rTNlpq&2!qxr2gw~sZh9&6}} zQTA?pOXo>o5S@f>&>60VU*U7u0m`{z+5+D|5z1pYgiJXUFF^;4kPDV4bBk$@gKFzx z(EZb#>gj6Gx!eKD?P0haw8wiud6(Re<0xa7yZ7kZ`&ym`Awd5fFFbU2jOP0x}N{g$)YaimDd9>)9UIxUIFbxZ41bbay|f7Pxg$R zi)dd5-@oFy&(3>}UDvErem}J9ygOs&GRR#HPtezyt1cdb25^R449dxV@MCz3aXTn? zv!Hyp$~Lk&d0O#TS4b`D|`xW&Tqd( zKCNWk_-{w1m^EkXxulWwj9vrtigg!A-?#fU$SV2QzZP_c%J<`7?N;(xE|V_LSMs+?Z?$63`}!PQ4^!}; zrd6GxY+{qX?oSseCe__3=z$BM+{qYY7jJYGYd3(qN2<-8pc+xF%g?)@IvW7pzd<+v zolpy7_!?n4b%qHO$0Sfn z%JWaK80rI~uR0pcZUpK`OT@o62=(gFK3PN+3U2 ulg`E2R3XlVg`UB%*w&glcVP?mnlcn>Pn-?oIG2v&LOraH<05TwR{S4`%0Gwz literal 0 HcmV?d00001 From ee2474b313f89ca099037f7ef8355a7cf73366fb Mon Sep 17 00:00:00 2001 From: a0a7 Date: Mon, 18 Aug 2025 18:04:40 -0500 Subject: [PATCH 02/28] update readme --- README.md | 232 +++++++++++++----- core/Cargo.toml | 2 +- core/README.md | 2 +- demo/src/app.html | 2 +- dist/javascript/README.md | 2 +- dist/javascript/dist/README.md | 2 +- dist/javascript/dist/package.json | 2 +- dist/javascript/package.json | 4 +- .../src/__tests__/package.node.test.ts | 10 - dist/javascript/wasm/package.json | 2 +- dist/python/Cargo.toml | 2 +- dist/python/README.md | 2 +- dist/rust/Cargo.toml | 2 +- dist/rust/README.md | 2 +- 14 files changed, 179 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index 517588d..0f3c041 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# fastgeotoolkit [![Crates.io](https://img.shields.io/crates/v/fastgeotoolkit)](https://crates.io/crates/fastgeotoolkit) [![PyPI](https://img.shields.io/pypi/v/fastgeotoolkit)](https://pypi.org/project/fastgeotoolkit/) [![npm](https://img.shields.io/npm/v/fastgeotoolkit)](https://www.npmjs.com/package/fastgeotoolkit) + +# fastgeotoolkit [![npm](https://img.shields.io/npm/v/fastgeotoolkit)](https://www.npmjs.com/package/fastgeotoolkit) [![codecov](https://codecov.io/gh/a0a7/fastgeotoolkit/branch/main/graph/badge.svg)](https://codecov.io/gh/a0a7/fastgeotoolkit) [![Rust Tests](https://github.com/a0a7/fastgeotoolkit/actions/workflows/rust-tests.yml/badge.svg)](https://github.com/a0a7/fastgeotoolkit/actions/workflows/rust-tests.yml) @@ -6,111 +7,210 @@ [![CodeQL](https://github.com/a0a7/fastgeotoolkit/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/a0a7/fastgeotoolkit/actions/workflows/github-code-scanning/codeql) ![License](https://img.shields.io/badge/license-MIT-blue) -GPS track processor for frequency-based route heatmaps from GPX, FIT, and polyline data. +fastgeotoolkit is a library for GPS data processing and route density mapping. The core of the library is written in Rust and it's compiled to webassembly for use in the browser and node. -## Installation +> [!NOTE] +> Only Javascript/Typescript is supported at the moment, despite the fact that the repo is set up for publishing Python and Rust versions of the package as well. These versions are not implemented properly, but will be at a later date. -| Language | Package Manager | Command | -|----------|----------------|---------| -| **Rust** | cargo | `cargo add fastgeotoolkit` | -| **Python** | pip | `pip install fastgeotoolkit` | -| **JavaScript/Node.js** | npm | `npm install fastgeotoolkit` | -| **JavaScript/Node.js** | GitHub Packages | `npm install @a0a7/fastgeotoolkit` | +## What it does -> **Note**: The JavaScript package is available on both npm and GitHub Packages with the same functionality. +The main use case is creating route heatmaps where you want to see which paths/routes are used most frequently. You can test this functionality at [https://activityheatmap.pages.dev/](https://activityheatmap.pages.dev/), using either your own data or sample data. This is an example of what a heatmap produced using fastgeotoolkit looks like: +![https://i.ibb.co/MxpHbVdp/image.png](https://i.ibb.co/MxpHbVdp/image.png) -## Features +However, beyond this primary usecase, this library helps you: +- Analyze GPS tracks (distance, statistics, intersections) +- Decode Google polylines +- Convert between GPS data formats -- GPX file parsing -- FIT file parsing -- Polyline decoding -- Route frequency analysis -- WebAssembly bindings -## Docs +## Installation -**[full docs](https://a0a7.github.io/fastgeotoolkit/)** +```bash +npm install fastgeotoolkit +# or +pnpm i fastgeotoolkit +``` -- [Rust API](https://docs.rs/fastgeotoolkit) -- [JS/TS API](https://a0a7.github.io/fastgeotoolkit/api/typescript) -- [Python API](https://a0a7.github.io/fastgeotoolkit/api/python) +## Basic Usage -## Installation -### JavaScript/TypeScript +```typescript +import { processGpxFiles } from 'fastgeotoolkit'; -```bash -# Install from npm (latest version) -npm install fastgeotoolkit +// Process GPX files into a heatmap +const gpxFile1 = new Uint8Array(/* your GPX file data */); +const gpxFile2 = new Uint8Array(/* another GPX file */); + +const result = await processGpxFiles([gpxFile1, gpxFile2]); -# Or install from GitHub Packages -npm install @a0a7/fastgeotoolkit --registry=https://npm.pkg.github.com +// Result contains tracks with frequency data +console.log(`Found ${result.tracks.length} unique track segments`); +console.log(`Maximum frequency: ${result.max_frequency}`); + +result.tracks.forEach(track => { + console.log(`Track with ${track.coordinates.length} points, used ${track.frequency} times`); +}); ``` -### Rust +## Working with Polylines + +```typescript +import { decodePolyline, processPolylines } from 'fastgeotoolkit'; -```toml -# Add to Cargo.toml -[dependencies] -fastgeotoolkit = "0.1.0" +// Decode a single polyline +const coords = await decodePolyline('_p~iF~ps|U_ulLnnqC_mqNvxq`@'); +console.log(coords); // [[lat, lng], [lat, lng], ...] + +// Process multiple polylines into a heatmap +const polylines = [ + '_p~iF~ps|U_ulLnnqC_mqNvxq`@', + 'another_encoded_polyline', + 'yet_another_one' +]; +const heatmap = await processPolylines(polylines); ``` -### Python +## Track Analysis -```bash -pip install fastgeotoolkit +```typescript +import { calculateTrackStatistics, validateCoordinates } from 'fastgeotoolkit'; + +const coordinates = [[37.7749, -122.4194], [37.7849, -122.4094]]; // [lat, lng] pairs + +// Get basic statistics +const stats = await calculateTrackStatistics(coordinates); +console.log(`Distance: ${stats.distance_km.toFixed(2)} km`); +console.log(`${stats.point_count} GPS points`); +console.log(`Bounds: ${stats.bounding_box}`); // [min_lat, min_lng, max_lat, max_lng] + +// Validate coordinates +const validation = await validateCoordinates(coordinates); +console.log(`${validation.valid_count} out of ${validation.total_count} coordinates are valid`); +if (validation.issues.length > 0) { + console.log('Issues found:', validation.issues); +} ``` -## Example Usage +## Data Conversion -### JavaScript/TypeScript +```typescript +import { coordinatesToGeojson, exportToGpx } from 'fastgeotoolkit'; -```javascript -import { processGpxFiles, decodePolyline } from 'fastgeotoolkit'; +// Convert to GeoJSON +const geojson = await coordinatesToGeojson(coordinates, { + name: 'My Route', + activity: 'cycling' +}); + +// Export multiple tracks as GPX +const tracks = [track1_coordinates, track2_coordinates]; +const gpxString = await exportToGpx(tracks, { + creator: 'My App', + name: 'Route Collection' +}); +``` + +## Real-world Example + +Here's an example of how you might use this in a web app to show route popularity: + +```typescript +import { processGpxFiles } from 'fastgeotoolkit'; + +async function createHeatmap(gpxFiles) { + // Convert files to Uint8Array + const fileBuffers = await Promise.all( + gpxFiles.map(file => file.arrayBuffer().then(buf => new Uint8Array(buf))) + ); + + // Process into heatmap + const heatmap = await processGpxFiles(fileBuffers); + + // Render on map (example with any mapping library) + heatmap.tracks.forEach(track => { + const intensity = track.frequency / heatmap.max_frequency; + const color = `hsl(${(1-intensity) * 240}, 100%, 50%)`; // blue to red + + drawLineOnMap(track.coordinates, { + color: color, + weight: Math.max(2, intensity * 8) + }); + }); +} + +// Usage +document.getElementById('file-input').addEventListener('change', async (e) => { + const files = Array.from(e.target.files); + await createHeatmap(files); +}); +``` + +## TypeScript Support -// Process GPX files -const gpxFiles = [/* ArrayBuffer[] */]; -const result = await processGpxFiles(gpxFiles); +The library includes full TypeScript definitions: -// Decode polyline -const decoded = decodePolyline("_p~iF~ps|U_ulLnnqC_mqNvxq`@"); +```typescript +import type { + Coordinate, // [number, number] - [lat, lng] + HeatmapResult, // { tracks: HeatmapTrack[], max_frequency: number } + HeatmapTrack, // { coordinates: Coordinate[], frequency: number } + TrackStatistics, // distance, bounds, point count, etc. + ValidationResult, // validation results with issues + FileInfo // file format information +} from 'fastgeotoolkit'; ``` -### Rust +## JavaScript Utilities -```rust -use heatmap_parse::{process_gpx_files, decode_polyline, process_polylines}; +For simple operations that don't rely on WebAssembly: -let files = vec![/* Vec file data */]; -let result = process_gpx_files(files); +```typescript +import { utils } from 'fastgeotoolkit'; -let coords = decode_polyline("_p~iF~ps|U_ulLnnqC_mqNvxq`@"); +// Basic coordinate validation +if (utils.isValidCoordinate(37.7749, -122.4194)) { + console.log('Valid GPS coordinate'); +} -let polylines = vec!["polyline1".to_string(), "polyline2".to_string()]; -let tracks = process_polylines(polylines); +// Calculate distance between two points +const distance = utils.haversineDistance(37.7749, -122.4194, 37.7849, -122.4094); +console.log(`Distance: ${distance.toFixed(2)} km`); + +// Get bounding box +const bounds = utils.getBoundingBox(coordinates); +console.log(`Bounds: ${bounds}`); // [min_lat, min_lng, max_lat, max_lng] ``` -### WebAssembly +## Browser vs Node.js + +Works the same in both environments: ```javascript -import init, { process_gpx_files, decode_polyline_string } from 'fastgeotoolkit'; +// Browser +import { processGpxFiles } from 'fastgeotoolkit'; -await init(); +// Node.js +const { processGpxFiles } = require('fastgeotoolkit'); +// or with ES modules: +import { processGpxFiles } from 'fastgeotoolkit'; +``` -const files = [/* Uint8Array buffers */]; -const result = process_gpx_files(files); +## Performance Notes -const coords = decode_polyline_string("_p~iF~ps|U_ulLnnqC_mqNvxq`@"); -``` +- WebAssembly provides near-native performance for GPS processing +- Large datasets (thousands of tracks) process quickly +- First function call initializes WebAssembly (adds ~100ms startup time) -## Building +## Common Issues -```bash -# Native Rust -cargo build --release +**"Cannot resolve module"** errors: Make sure your bundler supports WebAssembly. Modern bundlers (Vite, Webpack 5+, etc.) work out of the box. + +**TypeScript errors**: Ensure you're using TypeScript 4.0+ for proper WebAssembly typing support. -# js -wasm-pack build --target web +**File reading**: Remember to convert File objects to Uint8Array: +```javascript +const buffer = await file.arrayBuffer(); +const uint8Array = new Uint8Array(buffer); ``` ## License diff --git a/core/Cargo.toml b/core/Cargo.toml index 0dfe83c..ad4ce7e 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" description = "A fast and comprehensive geospatial toolkit for processing GPS tracks, trajectories, and coordinate data from GPX, FIT, and polyline formats" license = "MIT" repository = "https://github.com/a0a7/fastgeotoolkit" -authors = ["fastgeotoolkit contributors"] +authors = ["a0a7"] keywords = ["gps", "geospatial", "trajectory", "fast", "toolkit"] categories = ["wasm", "science", "visualization"] readme = "README.md" diff --git a/core/README.md b/core/README.md index 5950942..ea53090 100644 --- a/core/README.md +++ b/core/README.md @@ -168,7 +168,7 @@ If you use fastGeoToolkit in academic research, please cite: ```bibtex @software{fastgeotoolkit2024, title={fastGeoToolkit: A Novel High-Performance Geospatial Analysis Framework with Advanced Route Density Mapping}, - author={fastGeoToolkit Contributors}, + author={a0a7}, year={2024}, url={https://github.com/a0a7/fastgeotoolkit}, version={0.1.3} diff --git a/demo/src/app.html b/demo/src/app.html index 77a5ff5..6986738 100644 --- a/demo/src/app.html +++ b/demo/src/app.html @@ -2,7 +2,7 @@ - + %sveltekit.head% diff --git a/dist/javascript/README.md b/dist/javascript/README.md index 91d7cdb..3f6e9f4 100644 --- a/dist/javascript/README.md +++ b/dist/javascript/README.md @@ -3,7 +3,7 @@ [![npm](https://img.shields.io/npm/v/fastgeotoolkit.svg)](https://www.npmjs.com/package/fastgeotoolkit) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -fastgeotoolkit is a library for GPS data processing and route density mapping. The core of the library is written in Rust and compiled to webassembly for use in the browser and node. This makes it particularly fast. +fastgeotoolkit is a library for GPS data processing and route density mapping. The core of the library is written in Rust and it's compiled to webassembly for use in the browser and node. ## What it does diff --git a/dist/javascript/dist/README.md b/dist/javascript/dist/README.md index 4d90d23..e278966 100644 --- a/dist/javascript/dist/README.md +++ b/dist/javascript/dist/README.md @@ -168,7 +168,7 @@ If you use fastGeoToolkit in academic research, please cite: ```bibtex @software{fastgeotoolkit2024, title={fastGeoToolkit: A Novel High-Performance Geospatial Analysis Framework with Advanced Route Density Mapping}, - author={fastGeoToolkit Contributors}, + author={a0a7}, year={2024}, url={https://github.com/strava-tools/fastgeotoolkit}, version={0.1.3} diff --git a/dist/javascript/dist/package.json b/dist/javascript/dist/package.json index 3c4ad27..a4e8c1c 100644 --- a/dist/javascript/dist/package.json +++ b/dist/javascript/dist/package.json @@ -2,7 +2,7 @@ "name": "@fastgeotoolkit/fastgeotoolkit", "type": "module", "collaborators": [ - "fastgeotoolkit contributors" + "a0a7" ], "description": "A fast and comprehensive geospatial toolkit for processing GPS tracks, trajectories, and coordinate data from GPX, FIT, and polyline formats", "version": "0.1.3", diff --git a/dist/javascript/package.json b/dist/javascript/package.json index b7555ca..06f428a 100644 --- a/dist/javascript/package.json +++ b/dist/javascript/package.json @@ -1,6 +1,6 @@ { "name": "fastgeotoolkit", - "version": "0.2.0", + "version": "0.2.1", "description": "High-performance geospatial analysis framework for route density mapping", "main": "dist/index.js", "module": "dist/index.esm.js", @@ -38,7 +38,7 @@ "webassembly", "typescript" ], - "author": "fastGeoToolkit Contributors", + "author": "a0a7", "license": "MIT", "repository": { "type": "git", diff --git a/dist/javascript/src/__tests__/package.node.test.ts b/dist/javascript/src/__tests__/package.node.test.ts index 9375d9e..e789a59 100644 --- a/dist/javascript/src/__tests__/package.node.test.ts +++ b/dist/javascript/src/__tests__/package.node.test.ts @@ -37,16 +37,6 @@ describe('JavaScript Package Integration Tests (Node)', () => { expect(typeof processPolylinesNode).toBe('function'); }); - test('should attempt to initialize', async () => { - // Test that init doesn't crash even if WASM fails - try { - await initNode(); - // If it succeeds, great! - } catch (error) { - // If it fails, that's expected in Node.js without proper WASM setup - expect(String(error)).toContain('Failed to initialize'); - } - }); test('should handle basic polyline decoding', async () => { if (!wasmInitializedNode) { diff --git a/dist/javascript/wasm/package.json b/dist/javascript/wasm/package.json index 3c4ad27..a4e8c1c 100644 --- a/dist/javascript/wasm/package.json +++ b/dist/javascript/wasm/package.json @@ -2,7 +2,7 @@ "name": "@fastgeotoolkit/fastgeotoolkit", "type": "module", "collaborators": [ - "fastgeotoolkit contributors" + "a0a7" ], "description": "A fast and comprehensive geospatial toolkit for processing GPS tracks, trajectories, and coordinate data from GPX, FIT, and polyline formats", "version": "0.1.3", diff --git a/dist/python/Cargo.toml b/dist/python/Cargo.toml index d6f87f3..a7733c1 100644 --- a/dist/python/Cargo.toml +++ b/dist/python/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" description = "A fast and comprehensive geospatial toolkit for processing GPS tracks, trajectories, and coordinate data from GPX, FIT, and polyline formats" license = "MIT" repository = "https://github.com/a0a7/fastgeotoolkit" -authors = ["fastgeotoolkit contributors"] +authors = ["a0a7"] keywords = ["gps", "geospatial", "trajectory", "fast", "toolkit"] categories = ["wasm", "science", "visualization"] readme = "README.md" diff --git a/dist/python/README.md b/dist/python/README.md index 00ac1c3..8b52c5b 100644 --- a/dist/python/README.md +++ b/dist/python/README.md @@ -408,7 +408,7 @@ If you use fastGeoToolkit in research, please cite: ```bibtex @software{fastgeotoolkit2024, title={fastGeoToolkit: A Novel High-Performance Geospatial Analysis Framework with Advanced Route Density Mapping}, - author={fastGeoToolkit Contributors}, + author={a0a7}, year={2024}, url={https://github.com/a0a7/fastgeotoolkit}, version={0.1.3} diff --git a/dist/rust/Cargo.toml b/dist/rust/Cargo.toml index 1b17593..d1ad6a4 100644 --- a/dist/rust/Cargo.toml +++ b/dist/rust/Cargo.toml @@ -7,7 +7,7 @@ license = "MIT" repository = "https://github.com/a0a7/fastgeotoolkit" homepage = "https://github.com/a0a7/fastgeotoolkit" documentation = "https://docs.rs/fastgeotoolkit" -authors = ["fastgeotoolkit contributors"] +authors = ["a0a7"] keywords = ["gps", "geospatial", "trajectory", "route-density", "heatmap"] categories = ["science", "algorithms", "data-structures", "visualization"] readme = "README.md" diff --git a/dist/rust/README.md b/dist/rust/README.md index 7c353c2..efbe21c 100644 --- a/dist/rust/README.md +++ b/dist/rust/README.md @@ -143,7 +143,7 @@ If you use fastGeoToolkit in academic research, please cite: ```bibtex @software{fastgeotoolkit2024, title={fastGeoToolkit: A Novel High-Performance Geospatial Analysis Framework with Advanced Route Density Mapping}, - author={fastGeoToolkit Contributors}, + author={a0a7}, year={2024}, url={https://github.com/a0a7/fastgeotoolkit}, version={0.1.3} From 932dffc387b248ad0bb8e7e2540e3ca3f7385850 Mon Sep 17 00:00:00 2001 From: a0a7 Date: Mon, 18 Aug 2025 18:24:37 -0500 Subject: [PATCH 03/28] update docs --- dist/javascript/README.md | 6 +++++- .../docs/js-api/functions/calculateCoverageArea.html | 4 ++-- .../docs/js-api/functions/calculateDistance.html | 4 ++-- .../docs/js-api/functions/calculateTrackStatistics.html | 4 ++-- .../docs/js-api/functions/coordinatesToGeojson.html | 4 ++-- .../javascript/docs/js-api/functions/decodePolyline.html | 4 ++-- dist/javascript/docs/js-api/functions/exportToGpx.html | 4 ++-- .../docs/js-api/functions/findTrackIntersections.html | 4 ++-- dist/javascript/docs/js-api/functions/getFileInfo.html | 4 ++-- dist/javascript/docs/js-api/functions/init.html | 4 ++-- dist/javascript/docs/js-api/functions/initWithWasm.html | 4 ++-- dist/javascript/docs/js-api/functions/loadWasm.html | 4 ++-- .../docs/js-api/functions/loadWasmFromUrl.html | 4 ++-- .../docs/js-api/functions/processGpxFiles.html | 4 ++-- .../docs/js-api/functions/processPolylines.html | 4 ++-- dist/javascript/docs/js-api/functions/simplifyTrack.html | 4 ++-- .../docs/js-api/functions/validateCoordinates.html | 4 ++-- dist/javascript/docs/js-api/index.html | 9 +++++---- dist/javascript/docs/js-api/interfaces/FileInfo.html | 4 ++-- .../javascript/docs/js-api/interfaces/HeatmapResult.html | 4 ++-- dist/javascript/docs/js-api/interfaces/HeatmapTrack.html | 4 ++-- .../docs/js-api/interfaces/TrackStatistics.html | 4 ++-- .../docs/js-api/interfaces/ValidationResult.html | 4 ++-- dist/javascript/docs/js-api/modules.html | 4 ++-- dist/javascript/docs/js-api/types/Coordinate.html | 4 ++-- dist/javascript/docs/js-api/variables/utils.html | 4 ++-- dist/javascript/package.json | 2 +- 27 files changed, 59 insertions(+), 54 deletions(-) diff --git a/dist/javascript/README.md b/dist/javascript/README.md index 3f6e9f4..8866a9d 100644 --- a/dist/javascript/README.md +++ b/dist/javascript/README.md @@ -7,7 +7,7 @@ fastgeotoolkit is a library for GPS data processing and route density mapping. T ## What it does -The main use case is creating route heatmaps where you want to see which paths/routes are used most frequently. You can test this functionality at [https://activityheatmap.pages.dev/](https://activityheatmap.pages.dev/), using either your own data or sample data. This is an example of what a heatmap produced using fastgeotoolkit looks like: +The main use case is creating route heatmaps where you want to see which paths/routes are used most frequently. You can test this functionality at [https://fastgeotoolkit-demo.pages.dev/](https://fastgeotoolkit-demo.pages.dev/), using either your own data or sample data. This is an example of what a heatmap produced using fastgeotoolkit looks like: ![https://i.ibb.co/MxpHbVdp/image.png](https://i.ibb.co/MxpHbVdp/image.png) However, beyond this primary usecase, this library helps you: @@ -16,6 +16,10 @@ However, beyond this primary usecase, this library helps you: - Convert between GPS data formats +## Documentation + +Docs are available at [https://fastgeotoolkit.pages.dev/](https://fastgeotoolkit.pages.dev/). + ## Installation ```bash diff --git a/dist/javascript/docs/js-api/functions/calculateCoverageArea.html b/dist/javascript/docs/js-api/functions/calculateCoverageArea.html index a9f9868..33059fe 100644 --- a/dist/javascript/docs/js-api/functions/calculateCoverageArea.html +++ b/dist/javascript/docs/js-api/functions/calculateCoverageArea.html @@ -1,4 +1,4 @@ -calculateCoverageArea | fastgeotoolkit JavaScript API - v0.2.0

  • Calculate coverage area of tracks

    +calculateCoverageArea | fastgeotoolkit JavaScript API - v0.2.2
    • Calculate coverage area of tracks

      Parameters

      • tracks: Coordinate[][]

        Array of track coordinate arrays

      Returns Promise<{
          bounding_box: [number, number, number, number];
          area_km2: number;
          point_count: number;
      }>

      Coverage information including bounding box and area

      -
    \ No newline at end of file +
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/calculateDistance.html b/dist/javascript/docs/js-api/functions/calculateDistance.html index 68657a8..21dd599 100644 --- a/dist/javascript/docs/js-api/functions/calculateDistance.html +++ b/dist/javascript/docs/js-api/functions/calculateDistance.html @@ -1,7 +1,7 @@ -calculateDistance | fastgeotoolkit JavaScript API - v0.2.0
  • Calculate distance between two points using Haversine formula

    +calculateDistance | fastgeotoolkit JavaScript API - v0.2.2
    • Calculate distance between two points using Haversine formula

      Parameters

      • lat1: number

        First point latitude

      • lon1: number

        First point longitude

      • lat2: number

        Second point latitude

      • lon2: number

        Second point longitude

      Returns Promise<number>

      Distance in kilometers

      -
    \ No newline at end of file +
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/calculateTrackStatistics.html b/dist/javascript/docs/js-api/functions/calculateTrackStatistics.html index 5a8b194..784fbf8 100644 --- a/dist/javascript/docs/js-api/functions/calculateTrackStatistics.html +++ b/dist/javascript/docs/js-api/functions/calculateTrackStatistics.html @@ -1,4 +1,4 @@ -calculateTrackStatistics | fastgeotoolkit JavaScript API - v0.2.0
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/coordinatesToGeojson.html b/dist/javascript/docs/js-api/functions/coordinatesToGeojson.html index e24f78b..6fd2f30 100644 --- a/dist/javascript/docs/js-api/functions/coordinatesToGeojson.html +++ b/dist/javascript/docs/js-api/functions/coordinatesToGeojson.html @@ -1,5 +1,5 @@ -coordinatesToGeojson | fastgeotoolkit JavaScript API - v0.2.0
  • Convert coordinates to GeoJSON feature

    +coordinatesToGeojson | fastgeotoolkit JavaScript API - v0.2.2
    • Convert coordinates to GeoJSON feature

      Parameters

      • coordinates: Coordinate[]

        Track coordinates

      • properties: Record<string, any> = {}

        Optional properties object

      Returns Promise<any>

      GeoJSON feature

      -
    \ No newline at end of file +
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/decodePolyline.html b/dist/javascript/docs/js-api/functions/decodePolyline.html index e4411c0..f3ce178 100644 --- a/dist/javascript/docs/js-api/functions/decodePolyline.html +++ b/dist/javascript/docs/js-api/functions/decodePolyline.html @@ -1,4 +1,4 @@ -decodePolyline | fastgeotoolkit JavaScript API - v0.2.0
  • Decode Google polyline format to coordinates

    +decodePolyline | fastgeotoolkit JavaScript API - v0.2.2
    • Decode Google polyline format to coordinates

      Parameters

      • encoded: string

        Encoded polyline string

      Returns Promise<Coordinate[]>

      Array of coordinates

      -
    \ No newline at end of file +
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/exportToGpx.html b/dist/javascript/docs/js-api/functions/exportToGpx.html index fae47fb..d53fe2f 100644 --- a/dist/javascript/docs/js-api/functions/exportToGpx.html +++ b/dist/javascript/docs/js-api/functions/exportToGpx.html @@ -1,5 +1,5 @@ -exportToGpx | fastgeotoolkit JavaScript API - v0.2.0
  • Export tracks to GPX format

    +exportToGpx | fastgeotoolkit JavaScript API - v0.2.2
    • Export tracks to GPX format

      Parameters

      • tracks: Coordinate[][]

        Array of track coordinate arrays

      • metadata: Record<string, any> = {}

        Optional metadata

      Returns Promise<string>

      GPX file content as string

      -
    \ No newline at end of file +
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/findTrackIntersections.html b/dist/javascript/docs/js-api/functions/findTrackIntersections.html index 4518943..b493ea6 100644 --- a/dist/javascript/docs/js-api/functions/findTrackIntersections.html +++ b/dist/javascript/docs/js-api/functions/findTrackIntersections.html @@ -1,5 +1,5 @@ -findTrackIntersections | fastgeotoolkit JavaScript API - v0.2.0
  • Find intersections between multiple tracks

    +findTrackIntersections | fastgeotoolkit JavaScript API - v0.2.2
    • Find intersections between multiple tracks

      Parameters

      • tracks: Coordinate[][]

        Array of track coordinate arrays

      • tolerance: number

        Distance tolerance for intersection detection

      Returns Promise<{
          coordinate: Coordinate;
          track_indices: number[];
      }[]>

      Intersection points with track indices

      -
    \ No newline at end of file +
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/getFileInfo.html b/dist/javascript/docs/js-api/functions/getFileInfo.html index db1bca4..63ddfde 100644 --- a/dist/javascript/docs/js-api/functions/getFileInfo.html +++ b/dist/javascript/docs/js-api/functions/getFileInfo.html @@ -1,4 +1,4 @@ -getFileInfo | fastgeotoolkit JavaScript API - v0.2.0
  • Get file information from binary data

    +getFileInfo | fastgeotoolkit JavaScript API - v0.2.2
    • Get file information from binary data

      Parameters

      • fileData: Uint8Array

        File data as Uint8Array

      Returns Promise<FileInfo>

      File format information

      -
    \ No newline at end of file +
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/init.html b/dist/javascript/docs/js-api/functions/init.html index 741d030..56285c7 100644 --- a/dist/javascript/docs/js-api/functions/init.html +++ b/dist/javascript/docs/js-api/functions/init.html @@ -1,4 +1,4 @@ -init | fastgeotoolkit JavaScript API - v0.2.0
  • Initialize the WebAssembly module +init | fastgeotoolkit JavaScript API - v0.2.2

    • Initialize the WebAssembly module Must be called before using any WASM-based functions

      Parameters

      • wasmInit: any

        Pre-loaded WASM module (from loadWasm() helper)

        -

      Returns Promise<void>

    \ No newline at end of file +

Returns Promise<void>

\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/initWithWasm.html b/dist/javascript/docs/js-api/functions/initWithWasm.html index c93771a..9dfde99 100644 --- a/dist/javascript/docs/js-api/functions/initWithWasm.html +++ b/dist/javascript/docs/js-api/functions/initWithWasm.html @@ -1,3 +1,3 @@ -initWithWasm | fastgeotoolkit JavaScript API - v0.2.0
  • Initialize fastgeotoolkit with automatic WASM loading +initWithWasm | fastgeotoolkit JavaScript API - v0.2.2

    • Initialize fastgeotoolkit with automatic WASM loading This is a convenience function that handles WASM loading automatically

      -

      Returns Promise<any>

    \ No newline at end of file +

    Returns Promise<any>

\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/loadWasm.html b/dist/javascript/docs/js-api/functions/loadWasm.html index cdd8222..e02f330 100644 --- a/dist/javascript/docs/js-api/functions/loadWasm.html +++ b/dist/javascript/docs/js-api/functions/loadWasm.html @@ -1,3 +1,3 @@ -loadWasm | fastgeotoolkit JavaScript API - v0.2.0
  • Load the WASM module - users call this first, then pass result to init() +loadWasm | fastgeotoolkit JavaScript API - v0.2.2

    • Load the WASM module - users call this first, then pass result to init() This avoids module resolution issues by using a simple approach

      -

      Returns Promise<any>

    \ No newline at end of file +

    Returns Promise<any>

\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/loadWasmFromUrl.html b/dist/javascript/docs/js-api/functions/loadWasmFromUrl.html index 24ec542..0df982b 100644 --- a/dist/javascript/docs/js-api/functions/loadWasmFromUrl.html +++ b/dist/javascript/docs/js-api/functions/loadWasmFromUrl.html @@ -1,2 +1,2 @@ -loadWasmFromUrl | fastgeotoolkit JavaScript API - v0.2.0
  • Load WASM from URL

    -

    Parameters

    • wasmJsUrl: string
    • Optional wasmBgUrl: string

    Returns Promise<any>

\ No newline at end of file +loadWasmFromUrl | fastgeotoolkit JavaScript API - v0.2.2
  • Load WASM from URL

    +

    Parameters

    • wasmJsUrl: string
    • Optional wasmBgUrl: string

    Returns Promise<any>

\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/processGpxFiles.html b/dist/javascript/docs/js-api/functions/processGpxFiles.html index c7e392e..1325ce4 100644 --- a/dist/javascript/docs/js-api/functions/processGpxFiles.html +++ b/dist/javascript/docs/js-api/functions/processGpxFiles.html @@ -1,4 +1,4 @@ -processGpxFiles | fastgeotoolkit JavaScript API - v0.2.0
  • Process GPX files and generate route density heatmap

    +processGpxFiles | fastgeotoolkit JavaScript API - v0.2.2
    • Process GPX files and generate route density heatmap

      Parameters

      • files: Uint8Array[]

        Array of file data as Uint8Array

      Returns Promise<HeatmapResult>

      Heatmap result with frequency analysis

      -
    \ No newline at end of file +
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/processPolylines.html b/dist/javascript/docs/js-api/functions/processPolylines.html index bece950..5375d9a 100644 --- a/dist/javascript/docs/js-api/functions/processPolylines.html +++ b/dist/javascript/docs/js-api/functions/processPolylines.html @@ -1,4 +1,4 @@ -processPolylines | fastgeotoolkit JavaScript API - v0.2.0
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/simplifyTrack.html b/dist/javascript/docs/js-api/functions/simplifyTrack.html index 204aaca..bfdd5c1 100644 --- a/dist/javascript/docs/js-api/functions/simplifyTrack.html +++ b/dist/javascript/docs/js-api/functions/simplifyTrack.html @@ -1,5 +1,5 @@ -simplifyTrack | fastgeotoolkit JavaScript API - v0.2.0
  • Simplify track by reducing point density

    +simplifyTrack | fastgeotoolkit JavaScript API - v0.2.2
    • Simplify track by reducing point density

      Parameters

      • coordinates: Coordinate[]

        Track coordinates

      • tolerance: number

        Simplification tolerance

      Returns Promise<Coordinate[]>

      Simplified coordinate array

      -
    \ No newline at end of file +
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/functions/validateCoordinates.html b/dist/javascript/docs/js-api/functions/validateCoordinates.html index 8b3f0c4..013ad3b 100644 --- a/dist/javascript/docs/js-api/functions/validateCoordinates.html +++ b/dist/javascript/docs/js-api/functions/validateCoordinates.html @@ -1,4 +1,4 @@ -validateCoordinates | fastgeotoolkit JavaScript API - v0.2.0
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/index.html b/dist/javascript/docs/js-api/index.html index 0144348..ca2712a 100644 --- a/dist/javascript/docs/js-api/index.html +++ b/dist/javascript/docs/js-api/index.html @@ -1,7 +1,7 @@ -fastgeotoolkit JavaScript API - v0.2.0

fastgeotoolkit JavaScript API - v0.2.0

fastgeotoolkit

npm +fastgeotoolkit JavaScript API - v0.2.2

fastgeotoolkit JavaScript API - v0.2.2

fastgeotoolkit

npm License: MIT

-

fastgeotoolkit is a library for GPS data processing and route density mapping. The core of the library is written in Rust and compiled to webassembly for use in the browser and node. This makes it particularly fast.

-

What it does

The main use case is creating route heatmaps where you want to see which paths/routes are used most frequently. You can test this functionality at https://activityheatmap.pages.dev/, using either your own data or sample data. This is an example of what a heatmap produced using fastgeotoolkit looks like: +

fastgeotoolkit is a library for GPS data processing and route density mapping. The core of the library is written in Rust and it's compiled to webassembly for use in the browser and node.

+

What it does

The main use case is creating route heatmaps where you want to see which paths/routes are used most frequently. You can test this functionality at https://fastgeotoolkit-demo.pages.dev/, using either your own data or sample data. This is an example of what a heatmap produced using fastgeotoolkit looks like: https://i.ibb.co/MxpHbVdp/image.png

However, beyond this primary usecase, this library helps you:

    @@ -9,6 +9,7 @@
  • Decode Google polylines
  • Convert between GPS data formats
+

Documentation

Docs are available at https://fastgeotoolkit.pages.dev/.

Installation

npm install fastgeotoolkit
# or
pnpm i fastgeotoolkit

Basic Usage

import { processGpxFiles } from 'fastgeotoolkit';

// Process GPX files into a heatmap
const gpxFile1 = new Uint8Array(/* your GPX file data */);
const gpxFile2 = new Uint8Array(/* another GPX file */);

const result = await processGpxFiles([gpxFile1, gpxFile2]);

// Result contains tracks with frequency data
console.log(`Found ${result.tracks.length} unique track segments`);
console.log(`Maximum frequency: ${result.max_frequency}`);

result.tracks.forEach(track => {
console.log(`Track with ${track.coordinates.length} points, used ${track.frequency} times`);
}); @@ -42,4 +43,4 @@
const buffer = await file.arrayBuffer();
const uint8Array = new Uint8Array(buffer);

License

MIT

-
\ No newline at end of file +
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/interfaces/FileInfo.html b/dist/javascript/docs/js-api/interfaces/FileInfo.html index 04f342a..e5bc662 100644 --- a/dist/javascript/docs/js-api/interfaces/FileInfo.html +++ b/dist/javascript/docs/js-api/interfaces/FileInfo.html @@ -1,7 +1,7 @@ -FileInfo | fastgeotoolkit JavaScript API - v0.2.0

File format information

+FileInfo | fastgeotoolkit JavaScript API - v0.2.2

File format information

interface FileInfo {
    format: string;
    track_count: number;
    point_count: number;
    valid: boolean;
    file_size: number;
}

Properties

format: string
track_count: number
point_count: number
valid: boolean
file_size: number
\ No newline at end of file +

Properties

format: string
track_count: number
point_count: number
valid: boolean
file_size: number
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/interfaces/HeatmapResult.html b/dist/javascript/docs/js-api/interfaces/HeatmapResult.html index cdfbd23..dcaafcc 100644 --- a/dist/javascript/docs/js-api/interfaces/HeatmapResult.html +++ b/dist/javascript/docs/js-api/interfaces/HeatmapResult.html @@ -1,4 +1,4 @@ -HeatmapResult | fastgeotoolkit JavaScript API - v0.2.0

Result of heatmap generation with route density analysis

+HeatmapResult | fastgeotoolkit JavaScript API - v0.2.2

Result of heatmap generation with route density analysis

interface HeatmapResult {
    tracks: HeatmapTrack[];
    max_frequency: number;
}

Properties

Properties

tracks: HeatmapTrack[]
max_frequency: number
\ No newline at end of file +

Properties

tracks: HeatmapTrack[]
max_frequency: number
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/interfaces/HeatmapTrack.html b/dist/javascript/docs/js-api/interfaces/HeatmapTrack.html index ff54bce..ca1f1f5 100644 --- a/dist/javascript/docs/js-api/interfaces/HeatmapTrack.html +++ b/dist/javascript/docs/js-api/interfaces/HeatmapTrack.html @@ -1,4 +1,4 @@ -HeatmapTrack | fastgeotoolkit JavaScript API - v0.2.0

Track with frequency information for heatmap visualization

+HeatmapTrack | fastgeotoolkit JavaScript API - v0.2.2

Track with frequency information for heatmap visualization

interface HeatmapTrack {
    coordinates: Coordinate[];
    frequency: number;
}

Properties

coordinates: Coordinate[]
frequency: number
\ No newline at end of file +

Properties

coordinates: Coordinate[]
frequency: number
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/interfaces/TrackStatistics.html b/dist/javascript/docs/js-api/interfaces/TrackStatistics.html index 0504e3e..5d3df23 100644 --- a/dist/javascript/docs/js-api/interfaces/TrackStatistics.html +++ b/dist/javascript/docs/js-api/interfaces/TrackStatistics.html @@ -1,7 +1,7 @@ -TrackStatistics | fastgeotoolkit JavaScript API - v0.2.0

Track statistics including distance and bounding box

+TrackStatistics | fastgeotoolkit JavaScript API - v0.2.2

Track statistics including distance and bounding box

interface TrackStatistics {
    distance_km: number;
    point_count: number;
    bounding_box: [number, number, number, number];
    elevation_gain?: number;
    average_speed?: number;
}

Properties

distance_km: number
point_count: number
bounding_box: [number, number, number, number]
elevation_gain?: number
average_speed?: number
\ No newline at end of file +

Properties

distance_km: number
point_count: number
bounding_box: [number, number, number, number]
elevation_gain?: number
average_speed?: number
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/interfaces/ValidationResult.html b/dist/javascript/docs/js-api/interfaces/ValidationResult.html index af74e97..c8756da 100644 --- a/dist/javascript/docs/js-api/interfaces/ValidationResult.html +++ b/dist/javascript/docs/js-api/interfaces/ValidationResult.html @@ -1,5 +1,5 @@ -ValidationResult | fastgeotoolkit JavaScript API - v0.2.0

Validation result for coordinate arrays

+ValidationResult | fastgeotoolkit JavaScript API - v0.2.2

Validation result for coordinate arrays

interface ValidationResult {
    valid_count: number;
    total_count: number;
    issues: string[];
}

Properties

valid_count: number
total_count: number
issues: string[]
\ No newline at end of file +

Properties

valid_count: number
total_count: number
issues: string[]
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/modules.html b/dist/javascript/docs/js-api/modules.html index 91526ad..8c0d057 100644 --- a/dist/javascript/docs/js-api/modules.html +++ b/dist/javascript/docs/js-api/modules.html @@ -1,4 +1,4 @@ -fastgeotoolkit JavaScript API - v0.2.0

fastgeotoolkit JavaScript API - v0.2.0

Index

Interfaces

HeatmapTrack +fastgeotoolkit JavaScript API - v0.2.2

fastgeotoolkit JavaScript API - v0.2.2

Index

Interfaces

\ No newline at end of file +
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/types/Coordinate.html b/dist/javascript/docs/js-api/types/Coordinate.html index a7d00a9..5e426f2 100644 --- a/dist/javascript/docs/js-api/types/Coordinate.html +++ b/dist/javascript/docs/js-api/types/Coordinate.html @@ -1,2 +1,2 @@ -Coordinate | fastgeotoolkit JavaScript API - v0.2.0
Coordinate: [number, number]

GPS coordinate as [latitude, longitude]

-
\ No newline at end of file +Coordinate | fastgeotoolkit JavaScript API - v0.2.2
Coordinate: [number, number]

GPS coordinate as [latitude, longitude]

+
\ No newline at end of file diff --git a/dist/javascript/docs/js-api/variables/utils.html b/dist/javascript/docs/js-api/variables/utils.html index ed69f35..8d42b27 100644 --- a/dist/javascript/docs/js-api/variables/utils.html +++ b/dist/javascript/docs/js-api/variables/utils.html @@ -1,5 +1,5 @@ -utils | fastgeotoolkit JavaScript API - v0.2.0
utils: {
    isValidCoordinate(lat, lon): boolean;
    haversineDistance(lat1, lon1, lat2, lon2): number;
    getBoundingBox(coordinates): [number, number, number, number];
} = ...

Utilities for working with coordinates without WebAssembly

+utils | fastgeotoolkit JavaScript API - v0.2.2
utils: {
    isValidCoordinate(lat, lon): boolean;
    haversineDistance(lat1, lon1, lat2, lon2): number;
    getBoundingBox(coordinates): [number, number, number, number];
} = ...

Utilities for working with coordinates without WebAssembly

Type declaration

  • isValidCoordinate:function
    • Check if coordinates are valid (basic validation)

      Parameters

      • lat: number
      • lon: number

      Returns boolean

  • haversineDistance:function
    • Calculate simple distance using Haversine formula (JavaScript implementation)

      Parameters

      • lat1: number
      • lon1: number
      • lat2: number
      • lon2: number

      Returns number

  • getBoundingBox:function
    • Calculate bounding box for coordinate array

      -

      Parameters

      Returns [number, number, number, number]

\ No newline at end of file +

Parameters

Returns [number, number, number, number]

\ No newline at end of file diff --git a/dist/javascript/package.json b/dist/javascript/package.json index 06f428a..25b7148 100644 --- a/dist/javascript/package.json +++ b/dist/javascript/package.json @@ -1,6 +1,6 @@ { "name": "fastgeotoolkit", - "version": "0.2.1", + "version": "0.2.2", "description": "High-performance geospatial analysis framework for route density mapping", "main": "dist/index.js", "module": "dist/index.esm.js", From 8e2857c24754c69ef465ae2e525ee927764d96aa Mon Sep 17 00:00:00 2001 From: a0a7 Date: Mon, 18 Aug 2025 18:25:07 -0500 Subject: [PATCH 04/28] update auth handling --- demo/src/routes/api/rwgps-token/+server.ts | 15 +++++++++++---- demo/src/routes/api/strava-token/+server.ts | 15 +++++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/demo/src/routes/api/rwgps-token/+server.ts b/demo/src/routes/api/rwgps-token/+server.ts index 4b85b05..554e37a 100644 --- a/demo/src/routes/api/rwgps-token/+server.ts +++ b/demo/src/routes/api/rwgps-token/+server.ts @@ -1,11 +1,18 @@ import { json } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; -import { - RWGPS_CLIENT_ID, - RWGPS_CLIENT_SECRET -} from '$env/static/private'; +import { env } from '$env/dynamic/private'; export const POST: RequestHandler = async ({ request }) => { + const RWGPS_CLIENT_ID = env.RWGPS_CLIENT_ID; + const RWGPS_CLIENT_SECRET = env.RWGPS_CLIENT_SECRET; + + // Check if required environment variables are set + if (!RWGPS_CLIENT_ID || !RWGPS_CLIENT_SECRET) { + return json({ + error: 'RideWithGPS OAuth credentials not configured' + }, { status: 500 }); + } + try { const { code, redirectUri } = await request.json(); diff --git a/demo/src/routes/api/strava-token/+server.ts b/demo/src/routes/api/strava-token/+server.ts index 6d89298..5307017 100644 --- a/demo/src/routes/api/strava-token/+server.ts +++ b/demo/src/routes/api/strava-token/+server.ts @@ -1,11 +1,18 @@ import { json } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; -import { - STRAVA_CLIENT_ID, - STRAVA_CLIENT_SECRET -} from '$env/static/private'; +import { env } from '$env/dynamic/private'; export const POST: RequestHandler = async ({ request }) => { + const STRAVA_CLIENT_ID = env.STRAVA_CLIENT_ID; + const STRAVA_CLIENT_SECRET = env.STRAVA_CLIENT_SECRET; + + // Check if required environment variables are set + if (!STRAVA_CLIENT_ID || !STRAVA_CLIENT_SECRET) { + return json({ + error: 'Strava OAuth credentials not configured' + }, { status: 500 }); + } + try { const { code } = await request.json(); From 95efc30594c230df7ea3e06a19fa64c36bdd1f8c Mon Sep 17 00:00:00 2001 From: a0a7 Date: Mon, 18 Aug 2025 18:25:31 -0500 Subject: [PATCH 05/28] update readme --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f3c041..110df4f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ fastgeotoolkit is a library for GPS data processing and route density mapping. T ## What it does -The main use case is creating route heatmaps where you want to see which paths/routes are used most frequently. You can test this functionality at [https://activityheatmap.pages.dev/](https://activityheatmap.pages.dev/), using either your own data or sample data. This is an example of what a heatmap produced using fastgeotoolkit looks like: +The main use case is creating route heatmaps where you want to see which paths/routes are used most frequently. You can test this functionality at [https://fastgeotoolkit-demo.pages.dev/](https://fastgeotoolkit-demo.pages.dev/), using either your own data or sample data. This is an example of what a heatmap produced using fastgeotoolkit looks like: ![https://i.ibb.co/MxpHbVdp/image.png](https://i.ibb.co/MxpHbVdp/image.png) However, beyond this primary usecase, this library helps you: @@ -22,6 +22,9 @@ However, beyond this primary usecase, this library helps you: - Decode Google polylines - Convert between GPS data formats +## DOCS + +Docs are available at https://fastgeotoolkit.pages.dev/. ## Installation From ab665d56cac344fa3b0c35dfc52e31a0ed627a54 Mon Sep 17 00:00:00 2001 From: a0a7 Date: Mon, 18 Aug 2025 18:28:10 -0500 Subject: [PATCH 06/28] update release package workflow --- .github/workflows/release-package.yml | 100 +++++++++++++------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml index 9f0c923..03396ce 100644 --- a/.github/workflows/release-package.yml +++ b/.github/workflows/release-package.yml @@ -62,26 +62,26 @@ jobs: cd dist/python maturin build --release # Publish Rust package to crates.io - publish-rust: - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Setup Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - - - name: Sync packages - run: ./scripts/sync_packages.sh - - - name: Publish to crates.io - run: | - cd dist/rust - cargo publish --allow-dirty - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + #publish-rust: + # needs: build + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # + # - name: Setup Rust + # uses: actions-rs/toolchain@v1 + # with: + # toolchain: stable + # + # - name: Sync packages + # run: ./scripts/sync_packages.sh + # + # - name: Publish to crates.io + # run: | + # cd dist/rust + # cargo publish --allow-dirty + # env: + # CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} # Publish JavaScript package to NPM and GitHub Packages publish-javascript: @@ -148,33 +148,33 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Publish Python package to PyPI - publish-python: - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Setup Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: '3.8' - - - name: Install Python dependencies - run: | - python -m pip install --upgrade pip - pip install maturin build twine - - - name: Sync packages - run: ./scripts/sync_packages.sh - - - name: Build and publish Python package - run: | - cd dist/python - maturin publish - env: - MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} \ No newline at end of file + #publish-python: + # needs: build + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # + # - name: Setup Rust + # uses: actions-rs/toolchain@v1 + # with: + # toolchain: stable + # + # - name: Setup Python + # uses: actions/setup-python@v4 + # with: + # python-version: '3.8' + # + # - name: Install Python dependencies + # run: | + # python -m pip install --upgrade pip + # pip install maturin build twine + # + # - name: Sync packages + # run: ./scripts/sync_packages.sh + # + # - name: Build and publish Python package + # run: | + # cd dist/python + # maturin publish + # env: + # MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} \ No newline at end of file From 1bb7950a4420853ffe5fd1fdfa121dcf5665929b Mon Sep 17 00:00:00 2001 From: a0a7 Date: Mon, 18 Aug 2025 18:31:28 -0500 Subject: [PATCH 07/28] add draft pdf workflow --- .github/workflows/draft-pdf.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/draft-pdf.yml diff --git a/.github/workflows/draft-pdf.yml b/.github/workflows/draft-pdf.yml new file mode 100644 index 0000000..e189889 --- /dev/null +++ b/.github/workflows/draft-pdf.yml @@ -0,0 +1,28 @@ +name: Draft PDF +on: + push: + paths: + - paper/** + - .github/workflows/draft-pdf.yml + +jobs: + paper: + runs-on: ubuntu-latest + name: Paper Draft + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build draft PDF + uses: openjournals/openjournals-draft-action@master + with: + journal: joss + # This should be the path to the paper within your repo. + paper-path: paper/paper.md + - name: Upload + uses: actions/upload-artifact@v4 + with: + name: paper + # This is the output path where Pandoc will write the compiled + # PDF. Note, this should be the same directory as the input + # paper.md + path: paper/paper.pdf \ No newline at end of file From 873dbf6b27a71f1836a6f06b65725bc6bbf9a61f Mon Sep 17 00:00:00 2001 From: a0a7 Date: Mon, 18 Aug 2025 18:34:59 -0500 Subject: [PATCH 08/28] update lockfile --- demo/pnpm-lock.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/demo/pnpm-lock.yaml b/demo/pnpm-lock.yaml index ad5599a..9cb8df2 100644 --- a/demo/pnpm-lock.yaml +++ b/demo/pnpm-lock.yaml @@ -21,8 +21,8 @@ importers: specifier: ^7.2.0 version: 7.2.0 fastgeotoolkit: - specifier: ^0.1.14 - version: 0.1.14 + specifier: ^0.2.0 + version: 0.2.2 maplibre-gl: specifier: ^5.6.0 version: 5.6.0 @@ -1689,8 +1689,8 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fastgeotoolkit@0.1.14: - resolution: {integrity: sha512-a452x1vHNFYXIJsBGtXLw6diY/BIFHaUIsnIWC2CbQxGsH7ChesQJTduUY1/ywanb2oj1gp8B2OW147gWerNLw==} + fastgeotoolkit@0.2.2: + resolution: {integrity: sha512-nh8/9N8i/dFxJmdFs3xA8j+FuQdznj+Kii0LkrdmqVWBOzI69xvt0xmmFhlqhBxbRIK75UhthHfaBZ5VzIhWGQ==} engines: {node: '>=16.0.0'} fdir@6.4.6: @@ -4665,7 +4665,7 @@ snapshots: fast-deep-equal@3.1.3: {} - fastgeotoolkit@0.1.14: {} + fastgeotoolkit@0.2.2: {} fdir@6.4.6(picomatch@4.0.2): optionalDependencies: From 27b2817d79f6d1fcdb03276290a55f049b6c8fbb Mon Sep 17 00:00:00 2001 From: a0a7 Date: Mon, 18 Aug 2025 18:42:57 -0500 Subject: [PATCH 09/28] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 110df4f..160bf0e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# fastgeotoolkit [![npm](https://img.shields.io/npm/v/fastgeotoolkit)](https://www.npmjs.com/package/fastgeotoolkit) +# fastgeotoolkit [![npm](https://img.shields.io/npm/v/fastgeotoolkit)](https://www.npmjs.com/package/fastgeotoolkit) [![Open Docs](https://img.shields.io/badge/Documentation-skyblue?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDcuMC4wIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjUgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTQ4MCA1NzZMMTkyIDU3NkMxMzkgNTc2IDk2IDUzMyA5NiA0ODBMOTYgMTYwQzk2IDEwNyAxMzkgNjQgMTkyIDY0TDQ5NiA2NEM1MjIuNSA2NCA1NDQgODUuNSA1NDQgMTEyTDU0NCA0MDBDNTQ0IDQyMC45IDUzMC42IDQzOC43IDUxMiA0NDUuM0w1MTIgNTEyQzUyOS43IDUxMiA1NDQgNTI2LjMgNTQ0IDU0NEM1NDQgNTYxLjcgNTI5LjcgNTc2IDUxMiA1NzZMNDgwIDU3NnpNMTkyIDQ0OEMxNzQuMyA0NDggMTYwIDQ2Mi4zIDE2MCA0ODBDMTYwIDQ5Ny43IDE3NC4zIDUxMiAxOTIgNTEyTDQ0OCA1MTJMNDQ4IDQ0OEwxOTIgNDQ4ek0yMjQgMjE2QzIyNCAyMjkuMyAyMzQuNyAyNDAgMjQ4IDI0MEw0MjQgMjQwQzQzNy4zIDI0MCA0NDggMjI5LjMgNDQ4IDIxNkM0NDggMjAyLjcgNDM3LjMgMTkyIDQyNCAxOTJMMjQ4IDE5MkMyMzQuNyAxOTIgMjI0IDIwMi43IDIyNCAyMTZ6TTI0OCAyODhDMjM0LjcgMjg4IDIyNCAyOTguNyAyMjQgMzEyQzIyNCAzMjUuMyAyMzQuNyAzMzYgMjQ4IDMzNkw0MjQgMzM2QzQzNy4zIDMzNiA0NDggMzI1LjMgNDQ4IDMxMkM0NDggMjk4LjcgNDM3LjMgMjg4IDQyNCAyODhMMjQ4IDI4OHoiLz48L3N2Zz4=)](https://fastgeotoolkit.pages.dev/) -[![codecov](https://codecov.io/gh/a0a7/fastgeotoolkit/branch/main/graph/badge.svg)](https://codecov.io/gh/a0a7/fastgeotoolkit) + [![Rust Tests](https://github.com/a0a7/fastgeotoolkit/actions/workflows/rust-tests.yml/badge.svg)](https://github.com/a0a7/fastgeotoolkit/actions/workflows/rust-tests.yml) [![JavaScript Tests](https://github.com/a0a7/fastgeotoolkit/actions/workflows/javascript-tests.yml/badge.svg)](https://github.com/a0a7/fastgeotoolkit/actions/workflows/javascript-tests.yml) [![CodeQL](https://github.com/a0a7/fastgeotoolkit/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/a0a7/fastgeotoolkit/actions/workflows/github-code-scanning/codeql) @@ -10,7 +10,7 @@ fastgeotoolkit is a library for GPS data processing and route density mapping. The core of the library is written in Rust and it's compiled to webassembly for use in the browser and node. > [!NOTE] -> Only Javascript/Typescript is supported at the moment, despite the fact that the repo is set up for publishing Python and Rust versions of the package as well. These versions are not implemented properly, but will be at a later date. +> Only Javascript/Typescript is supported at the moment. Rust and Python releases are planned. ## What it does @@ -22,7 +22,7 @@ However, beyond this primary usecase, this library helps you: - Decode Google polylines - Convert between GPS data formats -## DOCS +## Documentation Docs are available at https://fastgeotoolkit.pages.dev/. @@ -218,4 +218,4 @@ const uint8Array = new Uint8Array(buffer); ## License -MIT \ No newline at end of file +MIT From 04c48d8c277ab5b0d476b4106f51dfcfcf369abd Mon Sep 17 00:00:00 2001 From: a0a7 Date: Mon, 18 Aug 2025 18:45:18 -0500 Subject: [PATCH 10/28] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 160bf0e..b4a5f93 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -# fastgeotoolkit [![npm](https://img.shields.io/npm/v/fastgeotoolkit)](https://www.npmjs.com/package/fastgeotoolkit) [![Open Docs](https://img.shields.io/badge/Documentation-skyblue?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDcuMC4wIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjUgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTQ4MCA1NzZMMTkyIDU3NkMxMzkgNTc2IDk2IDUzMyA5NiA0ODBMOTYgMTYwQzk2IDEwNyAxMzkgNjQgMTkyIDY0TDQ5NiA2NEM1MjIuNSA2NCA1NDQgODUuNSA1NDQgMTEyTDU0NCA0MDBDNTQ0IDQyMC45IDUzMC42IDQzOC43IDUxMiA0NDUuM0w1MTIgNTEyQzUyOS43IDUxMiA1NDQgNTI2LjMgNTQ0IDU0NEM1NDQgNTYxLjcgNTI5LjcgNTc2IDUxMiA1NzZMNDgwIDU3NnpNMTkyIDQ0OEMxNzQuMyA0NDggMTYwIDQ2Mi4zIDE2MCA0ODBDMTYwIDQ5Ny43IDE3NC4zIDUxMiAxOTIgNTEyTDQ0OCA1MTJMNDQ4IDQ0OEwxOTIgNDQ4ek0yMjQgMjE2QzIyNCAyMjkuMyAyMzQuNyAyNDAgMjQ4IDI0MEw0MjQgMjQwQzQzNy4zIDI0MCA0NDggMjI5LjMgNDQ4IDIxNkM0NDggMjAyLjcgNDM3LjMgMTkyIDQyNCAxOTJMMjQ4IDE5MkMyMzQuNyAxOTIgMjI0IDIwMi43IDIyNCAyMTZ6TTI0OCAyODhDMjM0LjcgMjg4IDIyNCAyOTguNyAyMjQgMzEyQzIyNCAzMjUuMyAyMzQuNyAzMzYgMjQ4IDMzNkw0MjQgMzM2QzQzNy4zIDMzNiA0NDggMzI1LjMgNDQ4IDMxMkM0NDggMjk4LjcgNDM3LjMgMjg4IDQyNCAyODhMMjQ4IDI4OHoiLz48L3N2Zz4=)](https://fastgeotoolkit.pages.dev/) +# fastgeotoolkit [![npm](https://img.shields.io/npm/v/fastgeotoolkit)](https://www.npmjs.com/package/fastgeotoolkit) [![Open Docs](https://img.shields.io/badge/Documentation-skyblue?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNjQwIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDcuMC4wIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjUgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTQ4MCA1NzZMMTkyIDU3NkMxMzkgNTc2IDk2IDUzMyA5NiA0ODBMOTYgMTYwQzk2IDEwNyAxMzkgNjQgMTkyIDY0TDQ5NiA2NEM1MjIuNSA2NCA1NDQgODUuNSA1NDQgMTEyTDU0NCA0MDBDNTQ0IDQyMC45IDUzMC42IDQzOC43IDUxMiA0NDUuM0w1MTIgNTEyQzUyOS43IDUxMiA1NDQgNTI2LjMgNTQ0IDU0NEM1NDQgNTYxLjcgNTI5LjcgNTc2IDUxMiA1NzZMNDgwIDU3NnpNMTkyIDQ0OEMxNzQuMyA0NDggMTYwIDQ2Mi4zIDE2MCA0ODBDMTYwIDQ5Ny43IDE3NC4zIDUxMiAxOTIgNTEyTDQ0OCA1MTJMNDQ4IDQ0OEwxOTIgNDQ4ek0yMjQgMjE2QzIyNCAyMjkuMyAyMzQuNyAyNDAgMjQ4IDI0MEw0MjQgMjQwQzQzNy4zIDI0MCA0NDggMjI5LjMgNDQ4IDIxNkM0NDggMjAyLjcgNDM3LjMgMTkyIDQyNCAxOTJMMjQ4IDE5MkMyMzQuNyAxOTIgMjI0IDIwMi43IDIyNCAyMTZ6TTI0OCAyODhDMjM0LjcgMjg4IDIyNCAyOTguNyAyMjQgMzEyQzIyNCAzMjUuMyAyMzQuNyAzMzYgMjQ4IDMzNkw0MjQgMzM2QzQzNy4zIDMzNiA0NDggMzI1LjMgNDQ4IDMxMkM0NDggMjk4LjcgNDM3LjMgMjg4IDQyNCAyODhMMjQ4IDI4OHoiLz48L3N2Zz4=)](https://fastgeotoolkit.pages.dev/) [![Demo](https://img.shields.io/badge/Try%20the%20demo-lightblue)](https://fastgeotoolkit-demo.pages.dev/) + [![Rust Tests](https://github.com/a0a7/fastgeotoolkit/actions/workflows/rust-tests.yml/badge.svg)](https://github.com/a0a7/fastgeotoolkit/actions/workflows/rust-tests.yml) From 77aa2539abb579f7edb329cef48ffc61dacdb201 Mon Sep 17 00:00:00 2001 From: a0a7 Date: Mon, 18 Aug 2025 19:08:30 -0500 Subject: [PATCH 11/28] update paper --- paper/heatmap.png | Bin 0 -> 1348680 bytes paper/paper.md | 89 +++++++++++++++++++--------------------------- 2 files changed, 37 insertions(+), 52 deletions(-) create mode 100644 paper/heatmap.png diff --git a/paper/heatmap.png b/paper/heatmap.png new file mode 100644 index 0000000000000000000000000000000000000000..5078804ed6fc6a7da35afb02a8a3afb6e68fe7be GIT binary patch literal 1348680 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