Inspiration

Madison has strong public water reporting, but the data is scattered across PDFs, well reports, and technical documents that are hard to compare quickly. We wanted to make water quality understandable at the address level: where you live, which wells likely serve you, and what that means for risk in plain language.

What it does

Tap Map is a map-first water quality intelligence app for Madison, WI. Users can:

  • Search an address with autocomplete
  • See which wells likely supply that address (including multi-well mixes)
  • View a score snapshot, grade, and worst contaminant
  • Compare contaminant levels against EWG guidance (and optional legal limits)
  • Explore well-by-well risk on an interactive map with detailed popups
  • Read plain-language explainers on the Metrics and Scoring pages

At the core, we compute a weighted risk and convert it to a safety score:

[ R = \sum_{c \in C} w_c \, r_c,\qquad \text{Score} = 100(1 - R) ]

For address-level blends:

[ \text{Score}{addr} = \sum{i=1}^{n} \hat{\alpha_i}\,\text{Score}_{well_i},\qquad \hat{\alpha_i}=\frac{\alpha_i}{\sum_j \alpha_j} ]

How we built it

We built Tap Map as a full-stack app:

  • Frontend: React + Vite + TypeScript, TailwindCSS, Leaflet, Recharts
  • Backend: Flask API with a scoring engine and address-to-well mapping layer
  • Data: Madison well coordinates, service area GeoJSON, PFAS/inorganics snapshots, violations data
  • Integrations: Google Places (autocomplete + geocoding), City of Madison MyWells lookup
  • Deployment: Cloud Run backend + static frontend hosting with custom domain

We focused on explainability: every score is traceable to category values and guideline comparisons.

Challenges we ran into

  • Mapping addresses to realistic multi-well service mixes instead of assuming a single well
  • Handling missing/partial contaminant data without misleading users
  • Preventing one extreme contaminant from visually breaking chart interpretation
  • Making map overlays, popups, and scoring cards update consistently in real time
  • Hardening API key usage and deployment config under hackathon time pressure
  • Debugging full flow from local dev to live domain + backend connectivity

Accomplishments that we're proud of

  • Built a working end-to-end address-to-score pipeline
  • Added explainable scoring with category-level breakdowns
  • Implemented a polished map UX with light/dark mode and detailed well insights
  • Integrated city-based address-to-well mapping for more realistic local scoring
  • Shipped supporting documentation, testing artifacts, and demo-ready pages (/metrics, /scoring)

What we learned

  • Data quality and uncertainty handling matter as much as UI polish
  • “Simple score” products require careful modeling and communication choices
  • Great map UX depends on state synchronization and edge-case handling
  • Security basics (API restrictions, environment setup, deploy hygiene) are critical even for hackathons
  • Building for judges means balancing technical depth with fast, trustworthy storytelling

What's next for Tap Map

  • Expand to more cities and broader contaminant coverage
  • Add confidence intervals and clearer uncertainty labeling
  • Improve trend/history analytics per well and per address
  • Add community reporting with validation and moderation workflows
  • Introduce alerts and personalized monitoring subscriptions
  • Optimize payload size/performance and production observability

Built With

Share this project:

Updates