Markdown Converter
Agent skill for markdown-converter
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Sign in to like and favorite skills
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
SafeNSound is a data-driven public safety intelligence platform for the US. It computes and visualizes safety scores across 7 weighted factors using H3 hexagonal heatmaps, with specialized tools for school safety analysis and route safety planning. Built with Next.js 16 (App Router), React 19, Deck.gl, MapLibre GL, and an optional PostgreSQL backend.
npm run dev # Start dev server (turbopack) npm run build # Production build npm run start # Start production server npm run lint # ESLint (next/core-web-vitals + next/typescript)
pip install -r scripts/requirements.txt python scripts/normalize_csv.py # Clean raw CSVs from DATA/ → scripts/output/cleaned/ python scripts/extract_nibrs.py # Extract FBI NIBRS crime data from UnextractedData/ ZIPs python scripts/compute_scores.py # Compute weighted safety scores → JSON python scripts/export_geojson.py # Convert POIs to GeoJSON → src/data/geojson/ python scripts/seed_db.py # Optional: seed PostgreSQL with PostGIS
Pipeline order:
normalize_csv → extract_nibrs → compute_scores → export_geojson
Raw CSVs (DATA/, UnextractedData/) → Python scripts (scripts/) → Cleaned CSVs + JSON scores (scripts/output/cleaned/, src/data/) → Next.js API routes (src/app/api/) → React client components (src/components/)
Data is served from files, not the database. API routes lazy-load CSV/JSON files into memory on first request and cache them. The PostgreSQL schema exists in
scripts/seed_db.py but is not currently used at runtime.
7 factors with fixed weights defined in
src/lib/weights.ts (must stay in sync with scripts/compute_scores.py):
| Factor | Weight |
|---|---|
| Violent Crime (FBI NIBRS) | 30% |
| Sex Offender Density | 25% |
| Missing Persons | 15% |
| Poverty Rate | 10% |
| Youth Attraction (schools/parks) | 10% |
| Detention/Protest Sites | 5% |
| Commercial Density | 5% |
Score range: 0-100 where 0 = safest, 100 = most dangerous (internal). The UI displays a "Peace Index" (inverted: higher = safer). Normalization: min-max per factor, then weighted sum.
Time-of-day modifiers add +8 (evening) or +15 (night) to danger scores.
Zoom-to-resolution mapping in
src/lib/map-styles.ts:
The
/api/layers/h3data endpoint returns cells filtered by viewport bounding box. Client-side filter toggling re-scores cells without an API call.
Scoring logic:
src/lib/scoring.ts (normalization, composite), src/lib/weights.ts (weights/labels), src/lib/h3-scoring.ts (H3 aggregation, per-layer danger)
Spatial utilities:
src/lib/geo-utils.ts (haversine, bounding box, line sampling), src/lib/map-styles.ts (colors, zoom mapping)
Types:
src/types/index.ts — SafetyScore, SafetyFactors, FactorDetail, H3Cell, H3ApiResponse, RouteSafetyResult, RouteSegment, SchoolSafetyResult, SchoolInfo, FilterLayer
API routes:
/api/layers/h3data — Viewport-aware H3 cells/api/scores — Pre-computed state/county scores/api/schools/search — Full-text search ~44k schools/api/schools/[id]/safety — School radius safety analysis (loads 6 data sources, blends nearby counties)/api/route-safety — Route analysis via OSRM + H3 scoring with segment breakdown/api/layers/states — State boundary GeoJSON with scores/api/layers/pois — All POI GeoJSON filesPages: Home (
/), Map (/map), School Safety (/school-safety), Route Safety (/route-safety), Transparency (/transparency)
src/data/geojson/ — Pre-generated GeoJSON (POIs by category, state boundaries with scores)src/data/scores/ — Pre-computed JSON (state_scores.json, county_scores.json, fl_county_enhanced.json)scripts/output/cleaned/ — Processed CSVs consumed by API routes at runtime (schools, offenders by ZIP, NIBRS crime, county centroids, POIs)DATA/ — Raw source CSVs (not used at runtime)UnextractedData/ — 51 FBI NIBRS state ZIP files@/* maps to ./src/*h3-js is listed in serverExternalPackages in next.config.ts — it must run server-side only.next.config.ts outputFileTracingIncludes ensures src/data/ and scripts/output/cleaned/ are bundled for Vercel deployment.tailwind.config.ts (score.safe, score.caution, score.warning, score.danger) and hex colors in src/lib/map-styles.ts (purple-red to green gradient)."use client"). Heavy map libraries (RouteMap) use Next.js dynamic imports.Cache-Control: 5 min for H3 data, 1 hour for scores/POIs/states.