Andjelko Cvjetkovic
All work

Case study · Kamtřídit

Kamtřídit: a nationwide recycling map that stays fast

Rebuilding the map that helps people across Czechia find where to recycle, so 33,000+ collection points feel instant, and search, navigation and adding new places actually work.

Role
Frontend lead
Stack
React, TypeScript, MapLibre GL JS
Platforms
Web, iOS, Android
Status
In production
Kamtřídit web app: a list of collection points next to a map of Prague with clustered markers, 4,063 places in view
Prague with 4,063 collection points in view, grouped into clusters.

Context

Kamtřídit.cz helps people in Czechia find where to recycle: 33,000+ collection points, run by EKO-KOM, the national packaging authority.

The old site was built on WordPress. It loaded every location at once, it was slow, and both address search and navigation were broken.

From static screens to a working product

I received the new design as static screens: the map with a sidebar, the dialog, the location detail. How it should behave wasn’t defined: where things scroll, what happens after you pick an address, what clicking a pin opens.

I worked it out with the designer and agreed with the backend team on the API changes it needed. I also helped the backend team migrate the old WordPress data.

Rendering 33,000 locations

The alternative on the table was loading everything and filtering on the device. That was slow to download and slow to draw. I proposed loading only what’s on screen.

The app starts on a small area of central Prague, or around the user if they share their location. From there, every view follows the same path:

  1. 1 Map stops moving Requests wait until panning ends, and are skipped when the view hasn’t really changed.
  2. 2 Visible area in the URL The current view is saved in the address, so every view is a shareable link.
  3. 3 Server returns only that area Just the collection points you can see, not all 33,000.
  4. 4 Clusters and a virtual list MapLibre groups nearby points; the list only draws the rows on screen.
How the map loads collection points for the current view.

Clicking a cluster zooms in exactly far enough to split it, and the side list is virtualized, so only the visible rows are drawn.

The map now shows the nearby collection points almost instantly, instead of making people wait for every location in the country to load.

Location detail: the collection point Na Příkopě with its waste types and a Route button, next to individual pins in central Prague
Zoomed in, clusters split into individual pins. Picking one opens its detail with a route button.

Search and navigation

Address search uses Mapy.com suggestions, and the map fits to the chosen place. Navigation calculates a walking, car or bike route to the collection point and draws it on the map.

Address search with Mapy.com suggestions for Vinohradská in several cities
Address suggestions from Mapy.com
Walking route drawn on the map from the start point to the collection point, 7 minutes and 486 metres
A walking route to the collection point

Adding a location

I first built long-press to add a point, the way Google Maps does it. The client’s feedback was that it wasn’t obvious, so I added a visible + button with a fixed pin: you drag the map under the pin, and when you let go, that spot becomes the location and its address fills in automatically.

Zooming and tiny movements are ignored, so the point only moves when you mean it. Editing a location uses the same mode.

Kamtřídit on a phone: map with clusters and an orange plus button for adding a location
The + button on mobile
Pick mode: a red pin fixed in the middle of the map with the hint to move the map to set the pin
Pick mode: drag the map under the pin

Result

  • The map loads almost instantly, because it only loads the collection points you can actually see.
  • 33,000+ locations on web, iOS and Android.
  • 200+ active contributors adding and updating places.