尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗A web application for trail planning and GPX file processing. Features both client-side tools and serverless API endpoints for route enrichment with POI data and elevation information.
/tools/splitter.html)/tools/planner.html)/tools/enrich.html)around:), not a bounding box, so a long or dog-legged trail does not drag in POIs hundreds of kilometres off-routenwr), so features mapped as areas — a supermarket building, a campsite polygon — are found and reduced to their centre point/tools/compare.html)/tools/daylight.html)/tools/combiner.html)/tools/optimizer.html)# Install dependencies
npm install
# Start dev server (static site only)
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
# Run with serverless functions (requires Vercel CLI)
vercel dev
npm run dev serves the client-side tools at http://localhost:5173. Tools that call the serverless API (e.g. POI Enrichment) also need vercel dev running on port 3000; with both running, the Vite dev server proxies /api requests to vercel dev automatically.
The project uses Vitest with jsdom for testing. Tests cover the core library modules.
# Run all tests
npm test
# Run tests in watch mode
npm test -- --watch
# Run tests with UI
npm test -- --ui
# Run a specific test file
npm test -- src/lib/distance.test.ts
| File | Coverage |
|---|---|
distance.test.ts | Haversine distance calculations, waypoint filtering |
gpx-parser.test.ts | GPX XML parsing and generation |
csv-processor.test.ts | CSV parsing, unit conversion, resupply detection |
gpx-splitter.test.ts | Track splitting, waypoint association |
sample-test-gpx.test.ts | Integration test with real sample GPX file |
The samples/ directory can contain test data files:
npm run devThe application includes serverless API endpoints for POI and elevation data:
| Endpoint | Description |
|---|---|
POST /api/overpass | Query OpenStreetMap for POIs along a route corridor ({corridor, radiusMeters, types}, max 400 vertices and 10 km radius) or, as a fallback, within a bounding box ({bounds, types}, max 1.5° per side). types must be a non-empty subset of water, camping, resupply, restaurant, transport, emergency. Returns the raw Overpass JSON. |
POST /api/elevation | Get elevation data for a list of coordinates |
GET /api/health | Health check for all external services |
Request bodies for /api/overpass (corridor vertices travel as compact [lat, lon] pairs):
{ "corridor": [[-37.8136, 144.9631], [-37.9, 145.0]], "radiusMeters": 2000, "types": ["water", "resupply"] }
{ "bounds": { "south": -37.9, "north": -37.8, "west": 144.9, "east": 145.0 }, "types": ["water"] }
Features:
X-RateLimit-Remaining)X-Cache: HIT / MISS / BYPASS)503 with Retry-After; other upstream errors as 502Vercel supports both the static site and serverless API functions.
# Install Vercel CLI
npm install -g vercel
# Deploy preview
vercel
# Deploy production
vercel --prod
Create project: Run vercel and follow prompts
Set up Redis: Dashboard → Storage → Create → Upstash for Redis → Connect to project (this provisions KV_REST_API_URL / KV_REST_API_TOKEN; native Upstash UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN are also accepted)
Add environment variables:
vercel env add ALLOWED_ORIGINS # Required: comma-separated allowed origins
vercel env add RATE_LIMIT_PER_MINUTE # Optional, default: 10
vercel env add CACHE_TTL_SECONDS # Optional, default: 604800 (7 days)
Security Note: Always configure
ALLOWED_ORIGINSin production (e.g.,https://yourdomain.com,https://www.yourdomain.com). Without this, cross-origin API requests will be denied.
Enable auto-deploy: Dashboard → Settings → Git → Connect repository
curl https://your-url/api/health
# Expected: {"status":"healthy","checks":{"kv":true,"overpass":true,"elevation":true}}