Ask anyone in Malta where they're actually allowed to park and you'll get a shrug and a story. I built StreetMapped to end the shrug — but the hardest part was never the geometry or the colours. It was deciding what a map like this is honestly allowed to say: where to draw the line between a rule I've read in the legislation and a street I've genuinely confirmed on the ground, and how to show a driver both the answer and how much to trust it. Get that wrong and a confident-looking map sends someone to a fine.
The challenge
Malta's controlled-parking schemes are real, legislated and enforced: residents and permit-holders of a zone park free, non-residents get a timed limit or are excluded, and some streets are reserved for a zone you don't live in. The catch for anyone building a map of it is that the source material is uneven. The rules are in statute (S.L. 363.80) and its legal notices; the street geometry has to be reconstructed from OpenStreetMap and won't always match; and controlled hours differ between winter and summer. So the real problem isn't just drawing a map — it's that any map will inevitably know some streets confidently and others only roughly, and it has to be honest about which is which without becoming useless.
- The rules are set in statute (S.L. 363.80) and on street signs, not in any single public map
- Whether you can park depends on which zone you're a resident of — a static map can't answer it
- Rules differ street by street, and controlled hours change between winter and summer
- Street geometry has to be reconstructed from OpenStreetMap, and some streets simply don't match
- A single wrong colour could send someone to a fine, so confidence has to be visible
- One person, no field-survey team — the map has to be honest about what it hasn't checked
Discovery & research
Before drawing anything, I treated StreetMapped as a data-provenance problem as much as a mapping one: what does Malta's parking law actually say, which of it can be tied to a real street on the ground, and how do you show a driver both the answer and how far to trust it? I read the controlled-parking scheme into structured data, matched it to OpenStreetMap geometry, and designed the honesty model — verified versus unverified, confident versus conflicting — before it ever became colours on a map.
The answer and the confidence are two different questions
A driver needs to know both 'can I park here' and 'how sure is this'. Collapsing them into one signal would either overstate thin data or bury the answer. So the parking colour and the geometry-confidence signal are kept decoupled in the engine.
EvidenceThe rule engine keeps the parking colour and the confidence signal separate, so uncertainty can't change the answer. Today every drawn street shares OpenStreetMap-approximate geometry and renders solid, while streets that can't be confidently placed are left off the map rather than approximated; a provisional line style is held in reserve for future geometry.
Missing data should stay missing, not be invented
When a street couldn't be matched to confident OpenStreetMap geometry, the honest move was to leave it undrawn rather than approximate a line that looks authoritative. Coverage is worth less than trust.
EvidenceStreets without a confident OSM match are kept in the data but flagged 'missing' and not drawn; the map shows 149 streets with mappable geometry rather than claiming the full record of restrictions.
Open data can carry a real product with no vendor lock-in
A basemap built on OpenStreetMap rather than a commercial provider removes the usual map-tile billing, API keys and lock-in — which, for a free civic tool, is the difference between sustainable and not.
EvidenceThe basemap is a Protomaps vector extract of Malta and Gozo (~8 MB) drawn with MapLibre GL — no Google, no Mapbox key, no per-request cost — with its fonts and icons served from the free Protomaps asset host, and the app installs as a PWA.
A civic map has to be honest about the law it's quoting
The parking rules are transcribed from legislation, not surveyed on the street, and enforcement details are set by the authorities. Presenting that as gospel would be irresponsible, so the product frames itself as guidance and points to the sign.
EvidenceEvery detail panel and the data-sources page carry a 'guidance only — follow the official signs' disclaimer; the rules are sourced to S.L. 363.80 and its legal notices, and the app never claims field verification.
Absence can be a finding, not a gap
Some localities genuinely operate no residents' scheme at all — showing them as empty is correct, not incomplete, as long as the reason is clear.
EvidenceResearch into the scheme confirmed that Bormla (Cospicua) and Isla (Senglea) are absent from the S.L. 363.80 First Schedule and correctly carry no resident-parking data — a deliberate 'no scheme here', not an unmapped gap.
How I approached it
I started with the law and the data, not the map. I transcribed the controlled-parking scheme from S.L. 363.80 into a structured set of zones and rule types, then pulled every named street's geometry from OpenStreetMap through Overpass and matched it by name — keeping the streets that matched confidently and leaving the ones that didn't off the map rather than faking a line. On top of that sits a rule engine that turns 'which zone are you a resident of' plus 'what governs this street' into a single verdict and colour, computed in the browser. The interface followed from the flow: a zone-first control panel over a full-screen MapLibre map that re-reads itself the moment you pick your zone. Later the same foundation grew two more modes — public transport and the outdoors — and the whole app runs on OpenStreetMap with no map API keys or per-request billing.
Transcribed Malta's controlled-parking scheme (S.L. 363.80) into structured zones and rule types
Pulled every named street from OpenStreetMap via Overpass and matched geometry by name
Kept confident matches; left unmatched streets off the map rather than faking geometry
Built a rule engine: resident zone + street rule → one park / can't-park / timed verdict, in-browser
Designed the zone-first control panel over a full-screen MapLibre map that recolours on selection
Grew the same foundation into three modes — parking, public transport and the outdoors
Shipped it on OpenStreetMap: bundled data, a Protomaps basemap, no map API keys, installable as a PWA
Trade-offs
The hard part was resisting the urge to look more complete than the data was. It would have been easy to draw every street solid, colour the whole island and let it read as authoritative. Instead the map holds two lines: a street with no confident OpenStreetMap match is left off rather than invented, and a rule lifted from legislation is shown as guidance, with the sign on the street always the authority. The rest of the difficulty was the unglamorous engineering a map app hides. Search engines and ad review saw a blank client-rendered page until I prerendered the content pages and gave the map homepage a static intro. The basemap went blank only in production until I traced it to the service worker corrupting the map tiles' byte-range requests. And a car park sitting 360 m out in the harbour taught me to add a check that validates every coordinate against a real OpenStreetMap feature before it ships.
- Holding the line on honesty — a street it can't place is left off the map, never faked
- A rule read in statute is shown as guidance, never a field-surveyed fact — the sign is the authority
- Search engines saw a blank client-rendered app until a prerender filled the content pages
- The basemap blanked only in production — a service worker was corrupting tile byte-ranges
- Coordinates drift: a verify script now checks every point against a real OpenStreetMap feature
- Going deeper in Malta and Gozo rather than sprawling wider or rebuilding bus timetables
Final direction
StreetMapped is a Vite and React app with a MapLibre map drawn over a Protomaps vector basemap cut from OpenStreetMap — so the map itself has no Google dependency, no Mapbox key and no per-request billing (its fonts and icons come from the free Protomaps asset host). Parking is the heart of it: pick your zone and read the colours, or hit 'Can I park here?' to have it check your location against the nearest street and give a plain verdict. Around that grew two more modes — public transport, with OpenStreetMap bus routes, roughly 2,100 stops and eight ferry routes plus a routes-not-timetables journey planner that hands off to Google Maps; and the outdoors, with cycling routes, hiking trails and nature areas. Eleven amenity layers — car parks, Park & Ride, EV charging, pharmacies, healthcare, public toilets and more — sit under one 'show on map' panel, and a multi-stop planner exports a route to Google, Apple or Bing Maps. It is theme-aware and installable as a PWA; it targets WCAG 2.2 AA, with the accessibility page candid that the text and controls conform but the map canvas doesn't yet; analytics and ads stay off until you opt in; and it's free.
Outcomes
For a resident or a visitor, StreetMapped turns a question that used to mean squinting at a time-plate — or risking it — into something you can read at a glance: pick your zone, look at the colour. It brings Malta's controlled-parking scheme into one place, 149 streets drawn from a scheme spanning 17 resident zones, each one carrying how confident its rule and position are rather than a flat, false certainty. It's built entirely on open data, which is what lets a free civic tool exist without map bills or vendor lock-in, and it has room to grow — the same map now reaches beyond parking into transport, ferries and the outdoors. Most of all it's candid about its own limits: the rules are transcribed from legislation, not surveyed on the street, and the map never pretends otherwise.
A parking map is easy to make look complete. The hard part — and the whole point — is making one you can trust, gaps and all.
The measure of a civic map isn't how much of the island it can colour in; it's whether you can trust the colour it shows you. StreetMapped is built so that trust is earned in the open — the answer and the confidence behind it are both on the map, and the gaps are labelled as gaps.