Case study | InCuencaEcuador.com

Turning messy public transit data into a map people can actually trust.

A data-driven transit and local-guide platform for Cuenca, Ecuador. It transforms inconsistent public sources — PDFs, municipal datasets, shapefiles, GTFS exports, and map data — into a public bus map, a place-based city Atlas, and a private review workspace for resolving uncertainty before publication.

Role: Designer, architect, and sole developer Stack: React, TypeScript, Vite, MapLibre, PMTiles, Node Status: Live and in active development at incuencaecuador.com

The problem

The sources disagree with each other — and most maps pretend they don't.

Cuenca's transit information lives in mixed-quality sources: route PDFs, municipal datasets, shapefiles, GTFS exports, public map data, and manual corrections. Those sources disagree on route names, directions, stop names, coordinates, and geometry. A naive approach would pick one source, draw the lines, and present the result as settled fact.

I designed the project around the opposite premise: normalize the data while preserving where each piece came from, make ambiguity visible to reviewers, give the public a clear browsing experience that never implies live arrivals or trip-planning accuracy the data can't support, and keep internal QA tooling strictly separate from public-facing content.

The system

One pipeline, three product surfaces.

Public

Cuenca Atlas

A map-led city guide for parishes, neighborhoods, places, landmarks, trails, stories, nearby context, and relevant transit access.

Public

Bus Map

A route-and-stop explorer with route search, directional display, stop context, route-density modes, and issue-reporting affordances.

Internal | noindex

Line Review

A private workspace for checking route geometry, stop order, distance anomalies, source evidence, and unresolved data-quality issues.

Data pipeline & quality model

The hard part wasn't drawing routes. It was building a path from uncertainty to publishable data.

Parse source files into structured data

Route PDFs and source files become structured lines, directions, stops, sequences, schedules — and parse warnings, kept rather than discarded.

Build canonical stops and aliases

Spelling and naming variations resolve to canonical stop records with tracked aliases, so inconsistent names don't silently fragment the data.

Match against geographic candidates

Stops match to coordinates with Cuenca-area prioritization, and questionable matches retain warnings instead of being promoted as fact.

Generate a review queue

Uncertain route and stop relationships surface in an explicit queue for human review — ambiguity is a first-class state, not an error to hide.

Promote validated, tracked payloads

Reviewed data becomes deterministic, checked-in payloads that the public map and internal review surface build from on a clean checkout.

38bus lines
76line directions
428canonical stops
1,237stop aliases tracked
412items in the review queue
3,501rendered stop records across line/direction contexts

Key design decisions

Decisions I'd defend in a design review.

Separate public exploration from internal review

Line Review is deliberately unindexed and unlinked from public navigation. Public users get useful route context; reviewers get diagnostic detail. Combining them creates both usability and publishing-risk problems.

Keep uncertainty visible

Route geometry, stop coordinates, and directional mappings carry provenance and fallback behavior rather than being treated as equally authoritative.

Generated, checked-in app payloads

The frontend builds from a clean checkout with no dependence on ignored local analysis output. Deterministic generation is part of the product contract, not a convenience script.

Deterministic URLs and route state

A canonical route parser covers guide pages, the Atlas, Bus Map, Line Review, directories, and explicit not-found behavior — every state is addressable and predictable.

Split map concerns by responsibility

Shared MapLibre/PMTiles initialization, interactions, sources, popups, route layers, Atlas layers, and diagnostics live in focused modules extracted from what began as large UI components.

Accessibility and responsive QA as product work

Keyboard focus states, Escape precedence, live-region feedback, mobile-sheet rules, and preview-first map interactions reduce accidental context switches — engineered, not bolted on.

What I learned

Lessons that transfer to any data-heavy product.

A map is only as trustworthy as its data lineage.

The hard problem wasn't rendering geo-data. It was knowing which source supplied a route or coordinate, what fallback was used, and when a result still needed human review.

Transit context is not trip planning.

The project deliberately avoids presenting route proximity as an arrival prediction, transfer guarantee, or live-service claim the underlying data can't support. Knowing what your product shouldn't say is a design skill.

Internal and public tools need different interaction models.

Public users need simple exploration; reviewers need warnings, raw evidence, and diagnostic layers. One interface serving both does both badly.

Large map apps become fragile when state lives in one component.

Early versions concentrated map lifecycle, URL state, overlays, Atlas content, and review logic in a few large files. Refactoring established boundaries around routing, browser access, MapLibre initialization, data adapters, and layer modules.

Generated data needs a product contract, not just a script.

Clean builds, deterministic output, validation thresholds, source precedence, and clear ownership are what make a data pipeline maintainable after the first month.

Responsive map UI deserves dedicated QA.

Sidebars, sheets, legends, controls, previews, and interaction modes collide fast on mobile. Screenshot matrices and accessibility checks are engineering practice, not cosmetic polish.

Current status

Core surfaces built. The next phase is quality, not features.

The three product surfaces, the data pipeline, a route/runtime refactor, and generated-payload contracts are in place. The deliberate choice for the next phase is to invest in quality engineering rather than greenfield feature creation — the kind of unglamorous work that determines whether a project survives contact with real users.

A note on honesty: this case study describes engineering work I can demonstrate. It makes no claims about user growth, adoption, accuracy percentages, or performance improvements — because I haven't independently measured them yet. When I do, they'll be here.

Planned next

Automated and manual accessibility audits
Responsive overlay collision testing
Canonical content source for Atlas editorial data
Deterministic A4 print-guide maps
Bundle-weight measurement and route-level loading boundaries
Line-by-line geometry/direction coverage reporting
Isolated validation of terrain and hillshade behavior

This is what my judgment looks like with no one assigning the tickets. Want it on your team?