Skip to content

Repository files navigation

LocalityMapper

Find a Helsinki neighbourhood that works for your whole household.

LocalityMapper visualising travel times and transit routes across Helsinki

LocalityMapper is an app for finding a place to live in Helsinki. It shows how long it takes to reach the places that matter to your household—work, school, or a partner's office.

Built with: React Native + Expo · MapLibre · offline GTFS transit data · FastAPI · r5py · H3

The problem

Looking for a home in an area you do not know well is hard when you use public transport. A map can show where a flat is, but not which areas have the best links to the places you need to get to. It gets even harder when there is more than one important trip to consider.

Urban planners use isochrones to study travel times. Most tools for everyone else only look at one destination or a direct journey. LocalityMapper lets you add several destinations, then shows the public-transport travel time for each area. It uses the longest trip as the score: green means shorter trips and red means longer ones.

I made it to make my own housing search easier. I hope it helps other people too.

How it works

  1. Search for and add one or more destinations.
  2. Pick a time of day, such as a weekday morning.
  3. Calculate a coloured travel-time grid across Helsinki.
  4. Tap an area to inspect the journey to each selected destination.

With several destinations, an area is scored by its longest journey. In other words, an area is only as handy as its hardest important trip.

App walkthrough

Searching for and adding transit destinations in LocalityMapper A Helsinki travel-time grid with a selected route A selected area showing routes and journey times to multiple destinations

Technical highlights

  • The mobile app works with a bundled Helsinki transit dataset, so it does not need a live routing or geocoding service.
  • Search covers bundled OSM-based addresses and HSL transit stops.
  • It reuses timetable searches and precomputed H3-cell-to-stop access to calculate the grid quickly.
  • It draws the H3 travel-time grid and route details with MapLibre. The map itself needs a network connection because its style comes from OpenFreeMap.
  • The repository also has a FastAPI grid API and a web development client. The API uses an r5py grid engine when one is configured, or static development data otherwise.
  • Code shared by the web and mobile apps lives in one package.

Refreshing bundled HSL data

The mobile app includes a saved copy of the HSL timetable, stops, route shapes, walking graph, and an OpenFreeMap Helsinki basemap. Update all of them before a release when HSL or OpenStreetMap data changes. Otherwise the app can show old routes, travel times, or map features. Prepare a MapLibre offline-regions database for the OpenFreeMap Liberty style over the Helsinki bounds at zooms 10–16, then run:

cd mobile
pnpm prepare:offline-bundle ~/Downloads/hsl.zip /path/to/helsinki.osm.pbf /path/to/openfreemap-helsinki.db 2026-08-11 2026-08-15

The command updates the bundled files and their shared version details in mobile/assets/offline/manifest.json. It rejects a missing or non-SQLite map database. Check data sources and attribution before you distribute the updated app.

Repository layout

backend/         # FastAPI grid API, managed with uv
web/             # Vite + React web client
mobile/          # Expo + React Native iOS-first app
shared/          # Shared API, tile, colour, and URL-state logic
fixtures/        # Recorded development data
docs/adr/        # Architecture decision records

Run locally

iOS app

Prerequisites: a Mac with Xcode and an iOS Simulator installed, plus Node.js and pnpm.

git clone https://github.com/maxvaisto/LocalityMapper.git
cd LocalityMapper
pnpm install
cd mobile
pnpm ios

pnpm ios builds, installs, and launches the native app in the iOS Simulator. For day-to-day JavaScript development, start the Expo development server with:

cd mobile
pnpm start

Native assets such as the app icon require another pnpm ios build; a Metro reload only updates JavaScript.

The repository also includes an Android native project. With an Android emulator or device configured, run pnpm android from mobile/.

Backend and web client

Prerequisites: Node.js and pnpm (installed from the repository root), plus uv, Python 3.13, and a JDK 21 or later for r5py.

cd backend
uv sync
uv run uvicorn app.main:app --reload

In a second terminal:

cd web
pnpm dev

The backend exposes POST /travel-time-grid. It forwards requests to the r5py grid engine when configured, or uses static development data when it is not. The web app is mainly a development client.

Tests

cd backend && uv run pytest
cd ../shared && pnpm test
cd ../web && pnpm test && pnpm build
cd ../mobile && pnpm test

Architecture decisions are recorded in docs/adr/.

Data and privacy

The mobile routing data is tied to specific dates. It does not include live disruptions or timetable changes made after the data was built. See data sources and attribution and the privacy note.

Contributing and security

See CONTRIBUTING.md for local development and pull-request guidance. To report a vulnerability privately, follow SECURITY.md.

License

MIT

About

Visualize HSL public transportation region travel times to multiple locations

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages