MCPcopy Index your code
hub / github.com/a0ax/fastgeotoolkit

github.com/a0ax/fastgeotoolkit @v0.4.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.4.1 ↗ · + Follow
275 symbols 696 edges 76 files 22 documented · 8% updated 8d agov0.4.1 · 2026-06-30★ 59
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

fastgeotoolkit npm PyPI - Version DOI Docs Demo

Rust Tests JavaScript Tests CodeQL License

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.

alt text

[!NOTE] Only Javascript/Typescript is fully supported at the moment. Rust and Python releases are experimental and may not work as expected

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.

However, beyond this primary usecase, this library helps you: - Analyze GPS tracks (distance, statistics, intersections) - 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`);
});

Working with Polylines

import { decodePolyline, processPolylines } from 'fastgeotoolkit';

// 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);

Track Analysis

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);
}

Data Conversion

import { coordinatesToGeojson, exportToGpx } 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:

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

The library includes full TypeScript definitions:

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';

JavaScript Utilities

For simple operations that don't rely on WebAssembly:

import { utils } from 'fastgeotoolkit';

// Basic coordinate validation
if (utils.isValidCoordinate(37.7749, -122.4194)) {
  console.log('Valid GPS coordinate');
}

// 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]

Browser vs Node.js

Works the same in both environments:

// Browser
import { processGpxFiles } from 'fastgeotoolkit';

// Node.js  
const { processGpxFiles } = require('fastgeotoolkit');
// or with ES modules:
import { processGpxFiles } from 'fastgeotoolkit';

Performance Notes

  • First function call initializes WebAssembly (adds ~100ms startup time)

Common Issues

"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.

File reading: Remember to convert File objects to Uint8Array:

const buffer = await file.arrayBuffer();
const uint8Array = new Uint8Array(buffer);

Development & Maintenance

This project consists of Rust code compiled to WebAssembly with JavaScript/TypeScript bindings.

Testing

# Run Rust tests
cargo test

# Run JavaScript tests
cd dist/javascript
npm test

Python tests are located in the github CI folder and are made to be ran after installing with pip

License

MIT

Extension points exported contracts — how you extend this code

StravaActivity (Interface)
(no doc)
demo/src/lib/strava.ts
StravaAthlete (Interface)
(no doc)
demo/src/lib/strava.ts
RWGPSTrip (Interface)
(no doc)
demo/src/lib/ridewithgps.ts
RWGPSUser (Interface)
(no doc)
demo/src/lib/ridewithgps.ts

Core symbols most depended-on inside this repo

skip
called by 15
core/src/lib.rs
haversine_distance
called by 14
core/src/lib.rs
read_u8
called by 11
core/src/lib.rs
simplify_coordinates_rust
called by 11
core/src/lib.rs
calculate_distance_between_points
called by 11
core/src/lib.rs
create_segment_key
called by 10
core/src/lib.rs
parse_record_message
called by 10
core/src/lib.rs
decode_polyline
called by 9
core/src/lib.rs

Shape

Function 212
Method 37
Class 22
Interface 4

Languages

Rust74%
TypeScript26%

Modules by API surface

core/src/lib.rs78 symbols
core/tests/additional_coverage_tests.rs38 symbols
core/tests/fit_parser_tests.rs29 symbols
core/tests/integration_tests.rs21 symbols
core/tests/core_functions_tests.rs21 symbols
demo/src/lib/ridewithgps.ts17 symbols
core/tests/advanced_functionality_tests.rs17 symbols
demo/src/lib/strava.ts15 symbols
demo/src/lib/components/ui/data-table/data-table.svelte.ts10 symbols
demo/src/lib/components/ui/data-table/render-helpers.ts8 symbols
demo/src/lib/components/ui/sidebar/context.svelte.ts6 symbols
demo/src/lib/hooks/is-mobile.svelte.ts3 symbols

For agents

$ claude mcp add fastgeotoolkit \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page