Heading

Re-engineering Land Blocks in the Crosscut App

By
James McKinnon
August 11, 2025

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:

Issue Effect
Over-detailed in empty zones Oddly shaped, highly detailed blocks in regions with zero population created distracting borders and larger file sizes.
Under-detailed in cities In dense settlements, bigger blocks blurred population hotspots and made it challenging to edit borders.
Slower loads More vertices meant larger datasets, longer download times, and slower browser performance on low-power devices.

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:

Layer Description
landblocks_gdf Irregular polygons that follow streets, rivers, and boundaries in populated areas, giving field teams realistic borders they can trust.
grid_gdf The more traditional approach of simple one-kilometre squares that fill the open spaces, trimming file size, and speeding up edits.

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:

  1. 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.

  2. Read inputs - Load country-specific administrative boundaries (vector) and WorldPop population raster data to establish our baseline.

  3. 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

  4. 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.

  5. 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)
  6. 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.
  7. 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.

  8. Merge Small Blocks - Recursively combine any polygon smaller than 40,000 m² with its largest neighbor to avoid tiny, impractical shapes for field workers.

  9. Hole Cleanup - Fix any geometric inconsistencies, such as small holes or invalid shapes, ensuring robust spatial merges in subsequent analyses.

  10. Population-Based Splitting - Split larger settlements with multiple high-density clusters into separate polygons using local raster peaks.
  11. Final Validation - Perform strict validation checks to validate that the total area matches our starting area (within 0.1%)
  12. 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

Step Description Key Libraries
1Setup & constantsPyProj, SciPy
2Read boundaries + rasterGeoPandas, Rasterio
3Generate landblocks_gdf + grid_gdfShapely, GeoPandas
4Hole removal in settlementsGeoPandas
5Clip to rivers, lakes, admin bordersOSMnx, Shapely
6Slice by roadsNetworkX, Shapely
7Merge sliversSciPy KD-Tree
8Clean up geometryShapely
9Density-based splitsRasterio, NumPy
10Hex tilingh3-py
11Area validationGeoPandas, SciPy
12Output (FlatGeobuf, GeoJSON)Fiona, GDAL

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.

BEFORE AFTER
Chaotic boundaries everywhere Smart detailed polygons where people live
Large, messy areas Clean 1 km grid in empty areas
Access heatmap looks "off" Access heatmap matches planning reality (green = good access)
  • 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

App Development

July 2025 updates: From black boxes to easier data collection

In July, we shipped several improvements that came directly from user feedback. These new features address email issues, file validation headaches, and workflow friction.
Dan Politz
August 4, 2025
Case Studies

Using settlement-based catchment territories in Crosscut

Settlement-based catchment territories help place your facilities, service centers, or mobile teams based on where people live and gather.
James McKinnon
July 28, 2025
App Development

Understanding site-based catchment areas in Crosscut

Site-based catchment areas make it easier for planning teams to allocate resources more efficiently.
James McKinnon
July 21, 2025

Let's get started

The Crosscut App is and always will be free to use. It takes less than a minute to register and get started.

© 2024 Crosscut. All rights reserved.
Crosscut
6707 4th St NW
Washington DC 20012
USA
Social