├── LICENSE ├── README.md └── demo_code ├── combinehillshade.py └── mdhs.sh /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 OSM2VectorTiles 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dem2vectorterrain 2 | 3 | > UPDATE: vector tiles made from a terrain are available at https://openmaptiles.com/contours/. The software for turning raster data into bezier curves and polygons is available as a service via https://octogeo.com/. 4 | 5 | This is an exploration of converting DEMs to vector hillshades and contours for inclusion into osm2vectortiles 6 | 7 | Thoughts: 8 | 9 | 1. Use ASTER DEMs. Superior to SRTM and openly available (but do see their license), see http://www.digital-geography.com/dem-comparison-srtm-3-vs-aster-gdem-v2/ for a comparison. 10 | 2. Export to hillshade with gdaldem (http://www.gdal.org/gdaldem.html) 11 | - Export the hillshade to contours using gdal_contour (http://www.gdal.org/gdal_contour.html) (See https://www.mapbox.com/vector-tiles/mapbox-terrain/ and https://github.com/mapbox/mapbox-gl-styles/blob/outdoors-v8/styles/outdoors-v8.json for an example of how to make compatible with existing styles) Use gdal_contour over gdalpolygonize as we don't need all the values in shapefiles, just general contours to match discrete hillshade values 12 | - Import these hillshade polygons into postgres 13 | - Convert contour lines to polygons in postgis (Dissolve on elevation and ST_MakePolygon) 14 | - Generalize for other layers (remove vertices and perhaps in between hillshades depending on density) 15 | 3. Export to contours with gdal_contour (http://www.gdal.org/gdal_contour.html) (what elevation resolution?) 16 | - Import these contours into postgres 17 | - Generalize for other layers (remove vertices and perhaps in between elevations depending on density) 18 | 6. Dockerize to the following stages: 19 | - export hillshade to vectors in postgres (import-hillshade), generalize vectors (generalize-hillshade) 20 | - export to contours in postgres (import-contours), generalize vectors (generalize-contours) 21 | - Both are done on a per-tile basis for imports 22 | - Exports integrated into osm2vectortiles 23 | - Undecided on whether to merge features in postgres so intersecting contours of same elevation are dissolved by elevation attribute 24 | 7. Need a tm2 source, integrated into osm2vectortiles? 25 | -------------------------------------------------------------------------------- /demo_code/combinehillshade.py: -------------------------------------------------------------------------------- 1 | # Do not use this for anything, it's garbage code. Just to demo merging multiple hillshades (8-directions) 2 | # Run this python script, with each of the 8 hillshades as input. This needs to be improved. 3 | from osgeo import gdal 4 | from osgeo.gdalnumeric import * 5 | from osgeo.gdalconst import * 6 | import sys 7 | 8 | F1 = sys.argv[1] 9 | F2 = sys.argv[2] 10 | F3 = sys.argv[3] 11 | F4 = sys.argv[4] 12 | F5 = sys.argv[5] 13 | F6 = sys.argv[6] 14 | F7 = sys.argv[7] 15 | F8 = sys.argv[8] 16 | 17 | outFile = "out.tiff" 18 | 19 | #Open the dataset 20 | ds1 = gdal.Open(F1, GA_ReadOnly ) 21 | ds2 = gdal.Open(F2, GA_ReadOnly ) 22 | ds3 = gdal.Open(F3, GA_ReadOnly ) 23 | ds4 = gdal.Open(F4, GA_ReadOnly ) 24 | ds5 = gdal.Open(F5, GA_ReadOnly ) 25 | ds6 = gdal.Open(F6, GA_ReadOnly ) 26 | ds7 = gdal.Open(F7, GA_ReadOnly ) 27 | ds8 = gdal.Open(F8, GA_ReadOnly ) 28 | 29 | band1 = ds1.GetRasterBand(1) 30 | band2 = ds2.GetRasterBand(1) 31 | band3 = ds3.GetRasterBand(1) 32 | band4 = ds4.GetRasterBand(1) 33 | band5 = ds5.GetRasterBand(1) 34 | band6 = ds6.GetRasterBand(1) 35 | band7 = ds7.GetRasterBand(1) 36 | band8 = ds8.GetRasterBand(1) 37 | 38 | #Read the data into numpy arrays 39 | data1 = BandReadAsArray(band1) 40 | data2 = BandReadAsArray(band2) 41 | data3 = BandReadAsArray(band3) 42 | data4 = BandReadAsArray(band4) 43 | data5 = BandReadAsArray(band5) 44 | data6 = BandReadAsArray(band6) 45 | data7 = BandReadAsArray(band7) 46 | data8 = BandReadAsArray(band8) 47 | 48 | #The actual calculation 49 | dataOut = data1*0.125+data2*0.125+data3*0.125+data4*0.125+data5*0.125+data6*0.125+data7*0.125+data8*0.125 50 | 51 | #Write the out file 52 | driver = gdal.GetDriverByName("GTiff") 53 | dsOut = driver.Create("out.tiff", ds1.RasterXSize, ds1.RasterYSize, 1, band1.DataType) 54 | CopyDatasetInfo(ds1,dsOut) 55 | bandOut=dsOut.GetRasterBand(1) 56 | BandWriteArray(bandOut, dataOut) 57 | -------------------------------------------------------------------------------- /demo_code/mdhs.sh: -------------------------------------------------------------------------------- 1 | # https://gis.stackexchange.com/questions/146296/how-to-create-composite-hillshade 2 | # Give the input DEM. 3 | # When combined with the combined_hillshade.py script, the output hillshade is really better to show texture. Can tune the formula in combined_hillshade.py to stretch the colors better but illuminating from all angles loses the sense of topography 4 | gdaldem hillshade $1 hillshades_0.tmp.tif -s 111120 -z 3 -az 0 -alt 45 -compute_edges 5 | gdaldem hillshade $1 hillshades_45.tmp.tif -s 111120 -z 3 -az 45 -alt 45 -compute_edges 6 | gdaldem hillshade $1 hillshades_90.tmp.tif -s 111120 -z 3 -az 90 -alt 45 -compute_edges 7 | gdaldem hillshade $1 hillshades_135.tmp.tif -s 111120 -z 3 -az 135 -alt 45 -compute_edges 8 | gdaldem hillshade $1 hillshades_180.tmp.tif -s 111120 -z 3 -az 180 -alt 45 -compute_edges 9 | gdaldem hillshade $1 hillshades_225.tmp.tif -s 111120 -z 3 -az 225 -alt 45 -compute_edges 10 | gdaldem hillshade $1 hillshades_270.tmp.tif -s 111120 -z 3 -az 270 -alt 45 -compute_edges 11 | gdaldem hillshade $1 hillshades_315.tmp.tif -s 111120 -z 3 -az 315 -alt 45 -compute_edges 12 | --------------------------------------------------------------------------------