Canvassing maps and the GoKrasiva field app
From a polygon-cutting script to a sun-readable map of 1.3 million+ Maricopa County addresses
Problem
Canvassers needed a fast map of every home in their territory and a way to log knocks from a phone in direct sun. Managers needed to draw territories, cut out parks and schools, and see results. The county's address export is one enormous single-line GeoJSON file.
Approach
A streaming converter turns the county file into one feature per line, tippecanoe builds PMTiles, and MapLibre draws them over OpenFreeMap basemaps, with no tile server and no API key. Turf.js handles territory geometry. In the CRM, a map_pins table resolves each record's location once through triggers, so the whole map loads from one query. The Expo app shares sign-in and a typed API client with the web CRM, reads the same PMTiles from Cloudflare R2, and follows written design rules: a light theme tuned for Arizona sun, 48 pt touch targets, 16 pt input text, skeletons instead of spinners, and motion limited to transform and opacity.
Process
10 dated steps, from the project’s history
-
GeoJSON Cutter
A Node and browser tool that subtracts parks, schools and excluded neighborhoods from a canvassing boundary with Turf.js, leaving one polygon ready to upload to eCanvasser. The README walks a non-developer through it step by step, and a web version runs on GitHub Pages.
GeoJSON Cutter input: a canvassing boundary with exclusion areas drawn on top. -
Holes cut, one shape out
The output is a single territory with every excluded area cut out as a hole. See Fig. 1, above.
-
Leaflet prototype
A first canvassing map with marker clustering, property tracking and a localStorage data layer.
-
MapLibre and PMTiles
A second prototype that draws 1.3 million+ Maricopa County addresses as pins in the browser, with list, report and settings views.
-
Canvassing moves into the CRM
Canvassing pages and a knock-tracking schema, a territory drawer for drawing, editing and removing polygons, a zone picker and a satellite toggle. Zones followed on March 9.
-
GoKrasiva, from scratch
A new Expo SDK 57 app, mock-first, with separate shells for canvassers, sales reps and installers, live clock-in and lead submission. The bottom tab bar went through about ten designs that day, from a floating pill to an oval indicator behind the icon with the label below.
Before: the first GoKrasiva app icon (August 5, 2026). -
Brand color, fewer layers
A teal login screen and a brand-colored icon replaced the white-on-black K. A heatmap and knock clusters below zoom 15 were added and removed the same day; the app shows plain pins from zoom 15 up.
After: the brand-teal icon and splash (August 6, 2026). -
Ready for the Play Store
Renamed the app GoKrasiva and pointed the build profiles at the production map tiles.
-
Precomputed pins
Rebuilt the CRM map on a pins table kept current by triggers. Every lead, appointment, job and applicant loads in a single fast query, with no viewport cap.
-
One API for knocks
Web and mobile now log door knocks through the same CRM endpoint.
Results
The CRM map and canvassing pages are in production. The field app was prepared for Play Store release in August 2026 and is not published in any store yet. GeoJSON Cutter is public and runs on GitHub Pages.
Lesson
I tried clustering on the web map and a heatmap in the app and took both out. The app now shows plain pins from zoom 15 up, and that rule is written into its design guide.