中文说明 | English
An English and Simplified Chinese interactive web dashboard for exploring Philadelphia crime patterns and a browser-based Route Safety Diary prototype. Use the language button in the app bar to switch languages; the preference is saved in the current browser. The project uses vanilla JavaScript, MapLibre GL JS, Chart.js, Turf, and Vite.
Important
The Route Safety Diary currently uses demo data and local browser state. It does not provide production accounts, persistent community submissions, or a safety guarantee. Crime locations are approximate and should not be used as the sole basis for personal-safety decisions.
- Interactive district and census-tract maps.
- Configurable buffer analysis from 400 m to 3.2 km.
- Monthly comparisons, top-offense charts, and a 7 x 24 activity heatmap.
- Per-capita rates using ACS population data.
- Viewport filtering and clustering for larger result sets.
- English and Simplified Chinese UI, help, status, and error copy.
- Demo routes with segment-level safety styling and an optional alternative.
- Route ratings, tags, notes, and segment overrides stored locally.
- Live Route, My Routes, Community, and Insights views.
- Community-feedback simulations with session-level throttling.
- Deterministic demo-data generation and validation scripts.
- Node.js
^20.19.0or>=22.12.0. - npm 10 or later.
Install the locked dependencies and start the development server:
npm ci
npm run devThen open http://localhost:5173/?mode=diary for the Route Safety Diary or
http://localhost:5173/ for the crime dashboard.
Create .env.local if you want to use a MapTiler style:
VITE_MAPTILER_API_KEY=your_key_hereWithout a key, the app uses its OpenStreetMap fallback. Environment files are ignored by Git and must never be committed.
Run the same repository gate used by CI:
npm run validateThe gate runs:
npm run data:check— validates the checked-in demo GeoJSON.npm test— runs the complete unit and contract-test suite, including the bilingual UI contract.npm run build:manifest— creates the production bundle and Vite manifest indist/.npm run verify:bundle— checks the production entry and lazy-chunk budgets.
Individual commands remain available when working on a narrow area:
npm run test:diary:math
npm run test:diary:agg
npm run data:check
npm run buildRegenerate and validate the deterministic Route Safety Diary fixtures:
npm run data:gen
npm run data:checkThe street-network commands fetch external OpenStreetMap or Philadelphia data and are intentionally separate from the default validation gate:
npm run data:fetch:streets
npm run data:segment:streetssrc/
api/ External data access and normalization
charts/ Crime and diary visualizations
i18n/ English and Simplified Chinese message catalogs/runtime
map/ MapLibre layers and interactions
routes_diary/ Route Safety Diary state and UI
state/ Shared application state
scripts/
tests/ Lightweight regression scripts
*.mjs Data generation and validation tools
server/api/diary/ Prototype API handlers
data/ Checked-in demo GeoJSON
docs/ Design, data, and implementation notes
| Source | Use |
|---|---|
| Philadelphia CARTO | Crime incident queries |
| Philadelphia GIS | Police districts and local boundaries |
| US Census Bureau ACS | Population denominators |
| OpenStreetMap | Street-network inputs |
Crime points are rounded to the hundred block and remain approximate. External services can change availability, schema, or rate limits independently of this repository.
Create a static production build with:
npm run buildServe the generated dist/ directory with a static host. This repository does
not currently publish a package to npm or GitHub Packages. The checked-in Vite
configuration automatically uses the repository path during GitHub Actions,
and .github/workflows/deploy-pages.yml builds and deploys main to GitHub
Pages.
- Known issues
- Control specification
- Route Safety Diary specification
- Backend API draft
- Data and file map
See CONTRIBUTING.md. Bug reports and proposed improvements can be submitted through GitHub Issues.
Project-authored software is available under the MIT License. Third-party data remains subject to the terms of its respective provider.