Hypsometric area fun
Step 0: Get yourself a DEM
If you don’t have one, there are plenty of online resources.
Step 1: Recode with GRASS
We want polygons out of this thing, but if we let every pixel have a different value our polygon output will be a furious ball of nothing. I used GRASS r.recode, through QGIS, with a recode text file created with this bit of Python:
1 | minele = 200 |
which output this:
1 | 200:210:61.0 |
Step 2: Majority Filter with SAGA
r.recode
helped clean up our DEM for polygon creation, but we can do better. SAGA’s Majority Filter takes areas too tiny to be useful and changes their value to the largest adjacent value. This will run for many hours. For our data (3.1’ pixels), I gave it a threshold of 0 and a kernel radius of 10, but adjust for your data as necessary. SAGA can be run via the SAGA GUI, the command line, or through QGIS. If running through the SAGA GUI or command line, note it creates a SAGA grid, which you’ll need to convert back to a TIFF.
Step 3: Hypsometric Areas with GRASS
We’re ready to make polygons. I used GRASS r.to.vect to convert to vector polygons, making sure to check the Smooth corners of area features
option for non-pixel-art polygon boundaries.
Step 4: Vectors to GeoJSON
In QGIS, right-click your polys and Save As
to GeoJSON, making sure to convert to WGS84 if necessary.
Step 5: GeoJSON to Mapbox Vector Tiles
Tippecanoe to the rescue. Here’s the command I used, YMMV:
1 | tippecanoe -o contours.mbtiles -P -y elev -E elev:mean -Z11 -z14 --drop-densest-as-needed contours.geojson |
This created a 32MB MBTiles file. From a 2,300MB GeoJSON file. Gotta love vector tiles.
Step 6: Visual
I used a GeoJSON polygon (in this case a county boundary) to be the water. The base tiles were served by mbtiles-server. Here be code:
1 |
|