QGIS displays data in a two-dimensions even if the data is three-dimensional. However, most modern browsers can display 3D data using the WebGL standard. In this recipe, we'll use the Qgis2threejs plugin to display QGIS data in 3D in a browser.
You will need to download some raster elevation data in the zipped directory and place it in your qgis_data
directory from the following:
https://geospatialpython.googlecode.com/svn/saveqml.zip
You will also need to install the Qgis2threejs plugin using the QGIS Plugin Manager.
We will set up a color ramp for a DEM draped over a hillshade image and use the plugin to create a WebGL page in order to display the data. To do this, we need to perform the following steps:
from PyQt4.QtCore import * from PyQt4.QtGui import * import Qgis2threejs as q23js
iface.mapCanvas().setCrsTransformEnabled(False) iface.mapCanvas().setMapUnits(0)
demPth = "/Users/joellawhead/qgis_data/saveqml/dem.asc" hillshadePth = "/Users/joellawhead/qgis_data/saveqml/hillshade.tif" dem = QgsRasterLayer(demPth, "DEM") hillshade = QgsRasterLayer(hillshadePth, "Hillshade")
algorithm = QgsContrastEnhancement.StretchToMinimumMaximum limits = QgsRaster.ContrastEnhancementMinMax dem.setContrastEnhancement(algorithm, limits) s = QgsRasterShader() c = QgsColorRampShader() c.setColorRampType(QgsColorRampShader.INTERPOLATED) i = [] qri = QgsColorRampShader.ColorRampItem i.append(qri(356.334, QColor(63,159,152,255), '356.334')) i.append(qri(649.292, QColor(96,235,155,255), '649.292')) i.append(qri(942.25, QColor(100,246,174,255), '942.25')) i.append(qri(1235.21, QColor(248,251,155,255), '1235.21')) i.append(qri(1528.17, QColor(246,190,39,255), '1528.17')) i.append(qri(1821.13, QColor(242,155,39,255), '1821.13')) i.append(qri(2114.08, QColor(165,84,26,255), '2114.08')) i.append(qri(2300, QColor(236,119,83,255), '2300')) i.append(qri(2700, QColor(203,203,203,255), '2700')) c.setColorRampItemList(i) s.setRasterShaderFunction(c) ps = QgsSingleBandPseudoColorRenderer(dem.dataProvider(), 1, s) ps.setOpacity(0.5) dem.setRenderer(ps)
QgsMapLayerRegistry.instance().addMapLayers([dem, hillshade])
d = q23js.qgis2threejsdialog.Qgis2threejsDialog(iface)
props = [None, None, {u'spinBox_Roughening': 4, u'checkBox_Surroundings': False, u'horizontalSlider_Resolution': 2, u'lineEdit_Color': u'', 'visible': False, 'dem_Height': 163, u'checkBox_Frame': False, u'lineEdit_ImageFile': u'', u'spinBox_Size': 5, u'spinBox_sidetransp': 0, u'lineEdit_xmax': u'', u'radioButton_MapCanvas': True, 'dem_Width': 173, u'radioButton_Simple': True, u'lineEdit_xmin': u'', u'checkBox_Sides': True, u'comboBox_DEMLayer': dem.id(), u'spinBox_demtransp': 0, u'checkBox_Shading': False, u'lineEdit_ymax': u'', u'lineEdit_ymin': u'', u'spinBox_Height': {5},{},{},{},{}]}
d.properties = props
d.ui.lineEdit_OutputFilename.setText('/qgis_data/3D/3d.html')
def sp(a,b): return d.saveProperties = sp
d.run()
This plugin is absolutely not designed for script-level access. However, Python is so flexible that we can even script the plugin at the GUI level and avoid displaying the GUI, so it is seamless to the user. The only glitch in this approach is that the save method overwrites the properties we set, so we must insert a dummy function that prevents this overwrite.
The following image shows the WebGL viewer in action: