UNPKG

fastgeotoolkit

Version:

High-performance geospatial analysis framework for route density mapping

215 lines (156 loc) 6.72 kB
# fastgeotoolkit [![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 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/](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: - Analyze GPS tracks (distance, statistics, intersections) - Decode Google polylines - Convert between GPS data formats ## Documentation Docs are available at [https://fastgeotoolkit.pages.dev/](https://fastgeotoolkit.pages.dev/). ## Installation ```bash npm install fastgeotoolkit # or pnpm i fastgeotoolkit ``` ## Basic Usage ```typescript 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 ```typescript 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 ```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); } ``` ## Data Conversion ```typescript 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: ```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 The library includes full TypeScript definitions: ```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'; ``` ## JavaScript Utilities For simple operations that don't rely on WebAssembly: ```typescript 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: ```javascript // Browser import { processGpxFiles } from 'fastgeotoolkit'; // Node.js const { processGpxFiles } = require('fastgeotoolkit'); // or with ES modules: import { processGpxFiles } from 'fastgeotoolkit'; ``` ## Performance Notes - WebAssembly provides near-native performance for GPS processing - Large datasets (thousands of tracks) process quickly - 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: ```javascript const buffer = await file.arrayBuffer(); const uint8Array = new Uint8Array(buffer); ``` ## License MIT