How to interpolate geospatial points to contours with Python and GDAL - Tutorial

howToInterpolateGeospatialPointsToContoursPythonGDAL.jpg

We have developed an alternative to a common procedure in GIS that is to create contours from a point shapefile but just with Python commands. By the use of Python and the GDAL library we can store this process into a function and perform contours from several point sets or different point queries.

The tutorial covers two steps:

Step 1: Creating an interpolated raster

Step2: Create contours from raster

Two options are presented to perform the contours: As a detailed description of all the involved steps and a compiled version of the script on a funcion that is called from a Jupyter notebook.

More infomation on the Gdal tools to perform rasters: https://gdal.org/programs/gdal_grid.html

Tutorial

Code

This is the whole Python

import fiona
import numpy as np
from osgeo import osr
from osgeo import ogr
from osgeo import gdal

Step 1: Creating an interpolated raster

# open point shapefile
gwShp = fiona.open('../Shp/gwWells.shp')
# get spatial bounds
gwBounds = gwShp.bounds
gwBounds
(-74.8156722, 40.2675333, -74.8083056, 40.27368889)
# review attribute table for first row
gwShp[0]
{'type': 'Feature',
 'id': '0',
 'properties': OrderedDict([('SiteNo', 401603074485301.0),
              ('Latitude', 40.2675333),
              ('Longitude', -74.8143306),
              ('LatLonDatu', 'NAD83'),
              ('SurfaceEle', 150.02),
              ('ElevationD', 'NAVD88'),
              ('HoleDepth', 48.0)]),
 'geometry': {'type': 'Point', 'coordinates': (-74.8143306, 40.2675333)}}
# create geospatial raster  
rasterDs = gdal.Grid('../Rst/interpolatedElevations.tif', '../Shp/gwWells.shp', format='GTiff',
               algorithm='invdist', zfield='SurfaceEle')
rasterDs.FlushCache()

Step2: Create contours from raster

# get raster system of reference
proj = osr.SpatialReference(wkt=rasterDs.GetProjection())
proj.ExportToWkt()
'GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4269"]]'
# get raster band
rasterBand = rasterDs.GetRasterBand(1)
# get elevation as numpy array
elevArray = rasterBand.ReadAsArray()
print(elevArray[:4,:4])
[[153.22245789 153.19668579 153.1703949  153.15008545]
 [153.222229   153.19682312 153.17120361 153.15127563]
 [153.22180176 153.19685364 153.17160034 153.15223694]
 [153.22125244 153.19676208 153.17181396 153.15299988]]
# define not a number
demNan = -32768
# get dem max and min
demMax = elevArray.max()
demMin = elevArray[elevArray!=demNan].min()
print("Maximun dem elevation: %.2f, minimum dem elevation: %.2f"%(demMax,demMin))
Maximun dem elevation: 175.56, minimum dem elevation: 143.39
# define output shapefile
contourPath = '../shp/contoursIncremental.shp'
contourDs = ogr.GetDriverByName("ESRI Shapefile").CreateDataSource(contourPath)
# define layer name and coordinate system
contourShp = contourDs.CreateLayer('contour', proj)

# define fields of id and elev
fieldDef = ogr.FieldDefn("ID", ogr.OFTInteger)
contourShp.CreateField(fieldDef)
fieldDef = ogr.FieldDefn("elev", ogr.OFTReal)
contourShp.CreateField(fieldDef)
0
#define number of contours and range
conNum = 10
conList =[int(x) for x in np.linspace(demMin,demMax,conNum)]
# write shapefile using noDataValue
#ContourGenerate(Band srcBand, double contourInterval, double contourBase, int fixedLevelCount, int useNoData, double noDataValue, 
#                Layer dstLayer, int idField, int elevField
gdal.ContourGenerate(rasterBand, 0, 0, conList, 1, -32768., 
                     contourShp, 0, 1)

contourDs.Destroy()

And this is the function version of the code

from workingTools import createContours
createContours('../Shp/gwWells.shp',                #point shapefile
               'SurfaceEle',                        #column name
              '../Rst/interpolatedElevations2.tif', #raster file
              '../Shp/contoursIncremental2.shp',    #contour shapefile
              20)

Maximun dem elevation: 175.56, minimum dem elevation: 143.39

Input files

You can download the input files from this link.

2 Comments

Saul Montoya

Saul Montoya es Ingeniero Civil graduado de la Pontificia Universidad Católica del Perú en Lima con estudios de postgrado en Manejo e Ingeniería de Recursos Hídricos (Programa WAREM) de la Universidad de Stuttgart con mención en Ingeniería de Aguas Subterráneas y Hidroinformática.

 

Suscribe to our online newsletter

Subscribe for free newsletter, receive news, interesting facts and dates of our courses in water resources.