A common geospatial workflow is to assign raster values to a coincident vector layer so that you can style or perform further analysis on the vector layer. This recipe will use this concept to illustrate the steepness of a road using color by mapping values to the road vector from a slope raster.
You will need to download a zipped directory from https://geospatialpython.googlecode.com/svn/road.zip and place the directory, named road
, in your qgis_data
directory.
We'll start with a DEM and compute its slope. Then, we'll load a road vector layer and break it into interval lengths of 500 meters. Next, we'll load the layer and style it using green, yellow, and red values for each segment to show the range of steepness. We'll overlay this layer on a hillshade of the DEM for a nice visualization. To do this, we need to perform the following steps:
from qgis.core import * from PyQt4.QtGui import * import processing
myCrs = QgsCoordinateReferenceSystem(26910, QgsCoordinateReferenceSystem.EpsgCrsId) iface.mapCanvas().mapRenderer().setDestinationCrs(myCrs) iface.mapCanvas().setMapUnits(QGis.Meters) iface.mapCanvas().refresh()
src_dir = "/Users/joellawhead/qgis_data/road/" dem = os.path.join(src_dir, "dem.asc") road = os.path.join(src_dir, "road.shp") slope = os.path.join(src_dir, "slope.tif") segRoad = os.path.join(src_dir, "segRoad.shp") steepness = os.path.join(src_dir, "steepness.shp") hillshade = os.path.join(src_dir, "hillshade.tif")
demLyr = QgsRasterLayer(dem, "DEM") roadLyr = QgsVectorLayer(road, "Road", "ogr")
ext = demLyr.extent() xmin = ext.xMinimum() ymin = ext.yMinimum() xmax = ext.xMaximum() ymax = ext.yMaximum() demBox = "%s,%s,%s,%s" % (xmin,xmax,ymin,ymax)
processing.runalg("grass:r.slope",dem,0,0,1,0,True, demBox,0,slope)
ext = roadLyr.extent() xmin = ext.xMinimum() ymin = ext.yMinimum() xmax = ext.xMaximum() ymax = ext.yMaximum() roadBox = "%s,%s,%s,%s" % (xmin,xmax,ymin,ymax)
processing.runalg("grass:v.split.length",road,500, roadBox,-1,0.0001,0,segRoad)
False
option in the addMapLayers
method:slopeLyr = QgsRasterLayer(slope, "Slope") segRoadLyr = QgsVectorLayer(segRoad, "Segmented Road", "ogr") QgsMapLayerRegistry .instance().addMapLayers([ segRoadLyr,slopeLyr], False)
processing.runalg("saga:addgridvaluestoshapes", segRoad,slope,0,steepness)
steepLyr = QgsVectorLayer(steepness, "Road Gradient", "ogr")
roadGrade = ( ("Rolling Hill", 0.0, 20.0, "green"), ("Steep", 20.0, 40.0, "yellow"), ("Very Steep", 40.0, 90.0, "red")) ranges = [] for label, lower, upper, color in roadGrade: sym = QgsSymbolV2.defaultSymbol(steepLyr.geometryType()) sym.setColor(QColor(color)) sym.setWidth(3.0) rng = QgsRendererRangeV2(lower, upper, sym, label) ranges.append(rng) field = "slope" renderer = QgsGraduatedSymbolRendererV2(field, ranges) steepLyr.setRendererV2(renderer)
processing.runalg("saga:analyticalhillshading",dem, 0,315,45,4,hillshade) hs = QgsRasterLayer(hillshade, "Terrain") QgsMapLayerRegistry.instance().addMapLayers([steepLyr, hs])
For each of our 500-meter line segments, the algorithm averages the underlying slope values. This workflow is fairly simple and also provides all the building blocks you need for a more complex version. While performing calculations that involve measurements over a relatively small area, using projected data is the best option. The following image shows how the output looks: