Introduction¶
When to Use GDAL Directly¶
Learning Objectives¶
Installation and Setup¶
conda install -c conda-forge gdal pygisSample Datasets¶
wget https://github.com/opengeos/datasets/releases/download/gdal/gdal_sample_data.zipunzip gdal_sample_data.zipUnderstanding Your Data¶
Examining Raster Data¶
gdalinfo dem.tifExamining Vector Data¶
ogrinfo buildings.geojsonogrinfo buildings.geojson -al -soCoordinate Transformation¶
Reprojecting Raster Data¶
gdalwarp -t_srs EPSG:4326 dem.tif dem_4326.tifReprojecting Vector Data¶
ogr2ogr -t_srs EPSG:3857 buildings_3857.gpkg buildings.geojsonFormat Conversion¶
Converting Raster Formats¶
gdal_translate dem.tif dem.imgConverting Vector Formats¶
ogr2ogr buildings.gpkg buildings.geojsonogr2ogr las_vegas_bbox.fgb las_vegas_bbox.geojsonClipping and Masking¶
Clipping Raster with Vector Boundaries¶
gdalwarp -cutline las_vegas_bbox.geojson -crop_to_cutline landsat.tif las_vegas.tifClipping Vector Data¶
ogr2ogr -clipsrc las_vegas_bbox.geojson las_vegas_roads_clipped.geojson las_vegas_roads.geojsonogrinfo las_vegas_bbox_4326.geojson -al -soogr2ogr -clipsrc -115.387634 35.943333 -114.883495 36.359161 las_vegas_roads_clipped.geojson las_vegas_roads.geojsonRaster Analysis and Calculations¶
Working with Individual Bands¶
gdal_translate -b 5 landsat.tif nir.tif
gdal_translate -b 4 landsat.tif red.tif
gdal_translate -b 3 landsat.tif green.tifPerforming Band Mathematics¶
gdal_calc.py \
-A nir.tif \
-B red.tif \
--outfile=ndvi.tif \
--calc="(A.astype(float) - B) / (A + B + 1e-6)" \
--type=Float32 \
--NoDataValue=-9999gdal_calc.py \
-A ndvi.tif \
--outfile=ndvi_clipped.tif \
--calc="(A < -1)*-1 + (A > 1)*1 + ((A >= -1) * (A <= 1))*A" \
--type=Float32 \
--NoDataValue=-9999 \
--overwritegdal_calc.py -A ndvi_clipped.tif --outfile=vegetation.tif --calc="A>0.3"gdal_translate -a_nodata 0 vegetation.tif vegetation_bin.tifgdal_edit.py -a_nodata 0 vegetation.tifConverting Between Raster and Vector¶
Vectorization¶
gdal_polygonize.py building_masks.tif building_masks.gpkgRasterization¶
gdal_rasterize -a uid -tr 0.6 0.6 -l buildings buildings_3857.gpkg buildings.tifgdal_rasterize -burn 1 -tr 0.6 0.6 -l buildings buildings_3857.gpkg buildings2.tifGeometry Processing¶
Simplifying Complex Geometries¶
ogr2ogr -f GPKG -t_srs EPSG:26911 -simplify 1 simplified.gpkg building_masks.gpkgDissolving Features by Attributes¶
ogrinfo -al -so us_states.geojsonogr2ogr -dialect sqlite -sql "SELECT ST_Union(geometry), country FROM us_states GROUP BY country" us_states_dissolved.gpkg us_states.geojsonExploding Multi-part Geometries¶
ogr2ogr -explodecollections hawaii_parts.geojson hawaii.geojsonManaging Fields and Layers¶
Selecting Specific Fields¶
ogr2ogr -select id,name us_states_select.geojson us_states.geojsonRenaming Layers¶
ogr2ogr -nln states us_states_rename.gpkg us_states_select.geojsonAdding New Fields¶
ogrinfo us_states_rename.gpkg -sql "ALTER TABLE states ADD COLUMN area DOUBLE"Tiling and Data Management¶
Creating Raster Tiles¶
mkdir -p tilesgdal_retile.py -targetDir tiles -ps 512 512 -co "TILED=YES" landsat.tifMerging Raster Data¶
gdal_merge.py -o landsat_merged.tif -of GTiff tiles/*.tifgdalwarp -of GTiff tiles/*.tif landsat_merged2.tifWorking with Multiple Vector Files¶
mkdir -p statesogrinfo -ro -al -geom=NO us_states.geojson | grep "id (" | awk '{print $4}' | while read id; do
ogr2ogr -f GeoJSON "states/${id}.geojson" us_states.geojson -where "id = '${id}'"
doneogr2ogr -f "ESRI Shapefile" us_states_merged.shp us_states.geojsonogr2ogr -f "ESRI Shapefile" -update -append \
us_states_merged.shp hawaii.geojson -nln us_states_mergedAdvanced Raster Processing¶
Resampling and Resolution Management¶
gdalwarp -tr 100 100 -r average dem.tif dem_100m.tifCreating Band Composites¶
gdal_merge.py -separate -o composite.tif nir.tif red.tif green.tifgdalbuildvrt -separate stack.vrt nir.tif red.tif green.tif
gdal_translate stack.vrt composite.tif -co COMPRESS=DEFLATEHandling Missing Data¶
gdal_fillnodata.py -md 5 -of GTiff dem.tif filled_dem.tifgdal_translate -a_nodata 0 dem.tif dem_nodata.tifCloud Optimized GeoTIFF¶
gdal_translate dem.tif dem_cog.tif -of COG -co COMPRESS=DEFLATETerrain Analysis¶
Computing Slope¶
gdaldem slope dem.tif slope.tif \
-of GTiff \
-compute_edgesgdaldem slope dem.tif slope_percent.tif \
-of GTiff \
-compute_edges \
-pComputing Aspect¶
gdaldem aspect dem.tif aspect.tif \
-of GTiff \
-compute_edgesCreating Hillshade Visualizations¶
gdaldem hillshade dem.tif hillshade.tifgdaldem hillshade dem.tif multidirectional_hillshade.tif -multidirectionalCreating Color Relief Maps¶
cat << EOF > colormap.txt
500,51,51,153
1000,3,147,249
1500,37,211,109
2000,181,240,138
2500,218,208,133
3000,146,115,94
4000,183,163,159
5000,255,255,255
EOFgdaldem color-relief dem.tif colormap.txt color_relief.tifCombining Hillshade and Color Relief¶
gdal_calc.py \
-A color_relief.tif \
-B hillshade.tif \
--outfile=shaded_relief.tif \
--calc="((A.astype(float) * 0.6) + (B.astype(float) * 0.4))" \
--type=Bytegdal_calc.py \
-A color_relief.tif \
-B hillshade.tif \
--outfile=color_hillshade.tif \
--calc="A * (B / 255.0)" \
--type=Bytegdal_calc.py -A color_relief.tif --A_band=1 -B hillshade.tif --outfile=r.tif --calc="A*(B/255.0)" --type=Byte
gdal_calc.py -A color_relief.tif --A_band=2 -B hillshade.tif --outfile=g.tif --calc="A*(B/255.0)" --type=Byte
gdal_calc.py -A color_relief.tif --A_band=3 -B hillshade.tif --outfile=b.tif --calc="A*(B/255.0)" --type=Bytegdal_merge.py -separate -o color_shaded_relief.tif r.tif g.tif b.tifGenerating Contour Lines¶
gdal_contour -i 100 dem.tif contours.shpKey Takeaways¶
References and Further Reading¶
Exercises¶
Exercise 1: Data Inspection and Understanding¶
Exercise 2: Coordinate Transformation Practice¶
Exercise 3: Format Conversion and Optimization¶
Exercise 4: Spatial Clipping and Analysis¶
Exercise 5: Raster Band Mathematics¶
Exercise 6: Terrain Analysis Workflow¶
Exercise 7: Raster-Vector Conversion¶
Exercise 8: Geometry Processing and Data Management¶