Re-engineering Land Blocks in the Crosscut App

When the Crosscut App goes to create a catchment area, it is actually aggregating land blocks. Each individual land block represents a parcel of land. All areas of a country are divided into land blocks. This is done each time our team refreshes a country's underlying datasets.
Creating "site-based" catchment areas in the Crosscut App involves matching every land block to its nearest service point, like a health center, school, or distribution hub, based on walking time. Where possible, land block edges are made up of real-world geographic features such as: Administrative boundaries (state, county, district, province); Road networks (highways, local roads, footpaths); Natural barriers (rivers, bodies of water); Settlement extents.
This blog post takes us through the technical details behind the land blocks concept.
Land blocks are the base layer
Traditional geospatial mapping systems often rely on uniform grids to split countries into thousands of square cells. That approach is easy for a computer to handle, but doesn’t reflect how people actually organize territory boundaries. These grids are efficient but often misrepresent settlement patterns and make it hard to work at a granular level. Field teams end up with boundaries that cut through rivers, ignore roads, or divide communities in ways that don’t make sense on the ground.
The Crosscut App takes a different approach to catchment maps. Land blocks are the smallest geographic units we use. They’re like pixels on your computer screen, but smarter. Instead of rigid squares, our polygons adapt to the world around them.
In populated areas, land block edges follow roads, rivers, and administrative lines to reflect the reality on the ground. In unpopulated space, we simplified the shapes into a clean 0.5 km grid to reduce file size and speed things up.

These land blocks don’t just define boundaries but shape how accessibility gets visualized across the map. When paired with population data and walking distances, they generate easy-to-read heatmaps that help teams see which areas are underserved or difficult to reach. That visualization is a key part of how the Crosscut app supports microplanning at scale.
All the heavy geospatial calculations happen ahead of time. Once a country is loaded, the app just needs to cache that land block layer once to calculate walking times and distances. The block-to-block friction surface is pre-created, so there's no need for extensive recalculation each time you drop a new pin.
A hybrid approach to catchment maps
Our first mapping engine traced every road and river, even in areas where nobody lives. The result was a nationwide layer of heavily detailed polygons. We have found this to be unnecessarily precise, heavy to load, and awkward to edit. Unpopulated rural areas had the same intricate geometry as cities.
We identified three main critical limitations:
This pre-computation makes the app load faster and is a core part of the Crosscut app’s speed. When users place points on the map, we can instantly determine which land parcels belong to which service points without having to recalculate anything. The issue we are addressing is our latest land blocks revision is that areas with no people used the same amount of compute power as densely populated ones.
Original landblocks_gdf

We fixed this by splitting the workflow into a dual-frame system, generating two GeoDataFrames that merge into one export layer:
The two layers turn into one layer when users export the final catchment map, keeping fine detail where people live and lean geometry where they don’t.
Hybrid landblocks_gdf / grid_gdf

Clipping to natural barriers

Re-engineered 12-step land block generation workflow
Here's a technical overview of our improved land block generation process:
- Setup and configuration - Load core geospatial libraries (GeoPandas, Rasterio, PyProj, OSMnx, Shapely) and define constants for buffer sizes and minimum areas. For example, 50 m buffers around settlements, 40,000 m² merge thresholds. Calculations are done on the WGS84 ellipsoid.
- Read inputs - Load country-specific administrative boundaries (vector) and WorldPop population raster data to establish our baseline.
- Generate Population and Grid Blocks - Convert non-zero population pixels into settlement polygons, buffering them by 50meters to merge nearby populated areas. These become landblocks_gdf. Then generate a regular 0.5 km grid (grid_gdf) to fill in the remaining areas with zero population. (See images below)
- For populated areas, we generate landblocks_gdf – irregular "population blocks" that also honor geography like lakes & rivers
- For unpopulated areas, we create grid_gdf – complementary cells filling the gaps with a simple grid
- Filtering Settlement Polygons - Settlement polygons are simplified by removing internal holes smaller than 250,000 m², retaining only meaningful open spaces such as large lakes or parks.
- Apply Natural Features - Snap both settlement and grid polygons to lakes, rivers, and district boundaries so block edges align with recognizable terrain without cutting features away. (see image below)
- Split Remaining Large or Irregular Blocks - After snapping block edges to natural features, we identify any unusually large or awkwardly shaped polygons and split them into smaller, more manageable units before continuing with road-aware slicing.
- Road-Aware Slicing - Within populated settlements, polygons are further divided along road networks to produce smaller, manageable blocks that reflect actual travel and access patterns.
- Merge Small Blocks - Recursively combine any polygon smaller than 40,000 m² with its largest neighbor to avoid tiny, impractical shapes for field workers.
- Hole Cleanup - Fix any geometric inconsistencies, such as small holes or invalid shapes, ensuring robust spatial merges in subsequent analyses.
- Population-Based Splitting - Split larger settlements with multiple high-density clusters into separate polygons using local raster peaks.
- Final Validation - Perform strict validation checks to validate that the total area matches our starting area (within 0.1%)
- Export Final Dataset - The final blocks are exported to FlatGeobuf for use in the app (optimized for streaming and indexing), plus GeoJSON for documentation. We first trialed this switch during Hack Week for better heat maps and have kept it ever since.
With this update, teams enjoy faster national map downloads with near-instant rendering, cleaner editing workflows without jagged rural shapes, and sharper urban analytics thanks to finer block sizes in populated areas.

Image: Step 3.1 - Generating landblocks_gdf

Image: Step 3.2 - Generating grid_gdf

Image: Step 5 - Clipping catchment map

Post-update testing
- Area parity old vs new ≤ 0.08 %
- No population loss in block reassignment
- Travel-time variance averages under 30 seconds, well inside planning tolerances
- Nation map files dropped by more than 60% in size, reducing load times
Reference table: Tools, languages, and key actions
Notes for technical teams
Here are a few key parameters we've refined during this update:
- .Coordinate system – We stick with WGS84 lat/long and geodesic area functions throughout the pipeline, avoiding UTM re-projections to keep our approach universal across countries.
- Buffer distances – 50m buffers on settlement polygons hit the sweet spot between merging nearby clusters and preserving distinct villages.
- Size thresholds – Our defaults (1 km² for filtering, 40,000 m² for merging) work well across African deployments but consider adjustments for extremely dense cities or small islands.
Before and after hybrid approach
Cities keep street-level polygons for precise heat maps and clear catchment edits. Empty terrain now ships as lightweight squares, letting national layers download in seconds and run smoothly even on basic hardware. And accuracy checks confirm no loss in area balance, population counts, or travel time.
- Rural areas – Blocks simplify into neat squares that fade into the background.
- Urban cores – Fine blocks reveal street-level density.
- Clipping - Adapt to rivers, roads, buildings, other features to determine accessibility.
Looking ahead
Most users won’t think twice about land blocks, and that’s exactly how it should be. They’re the foundational layer that quietly powers everything from travel-time maps to printable maps for field workers. This update makes the foundation faster, cleaner, and easier to work with.
Nothing changes for day-to-day users except that everything feels faster and cleaner. Land blocks stay in the background, doing the heavy lifting. If you need help adapting geospatial catchment maps to your own data or want to generate compatible blocks, get in touch.
Related Posts

July 2025 updates: From black boxes to easier data collection

Using settlement-based catchment territories in Crosscut
