I have a dataset of lines with a start and end elevation value in the attribute table. I want to apply this value to the Z coordinate of the start/end vertex respectively to create a 3D line. The lines themselves do not represent a single Z value like a contour; each line represents a sloped downward and thus has a different elevation at its start vertex than at its end vertex. I did this once in Arc Desktop using 3D Analyst tools by exporting all the start and end nodes to point shapefiles, converted the 2D points to 3D point using the start/end elevation for each shapefile, assigning all start points with a sequence of "0" and all end points with sequence "1", then merged the 2 shapefiles into one to get a "from to" array of points, finally ran points to lines to get 3D lines. I need to do this in QGIS because I do not have access to 3D analyst anymore. Anyone out there done this and willing to share the procedure?
if you are familar with scripting, you can use a python script to create 3D features. Inside the following example i assume to have a layer loaded inside qgis containing line string features and two fields named "from" and "to" which store the elevetion values for the first and the last vertice.
layer = iface.activeLayer() iter = layer.getFeatures() for feature in iter: # retrieve every feature with its geometry and attributes # fetch geometry geom = feature.geometry() # assume z values are stored in fields "from" and "to" p0z = feature["from"] p1z = feature["to"] # access Points, assuming each line has to vertices oldp0, oldp1 = geom.asPolyline(), geom.asPolyline() # creating a new LineString with PointZ-vertices newp0 = QgsPointV2( QgsWKBTypes.PointZ, oldp0, oldp0, p0z ) newp1 = QgsPointV2( QgsWKBTypes.PointZ, oldp1, oldp1, p1z ) linez = QgsLineStringV2() linez.setPoints([newp0, newp1]) # output print linez.asWkt()
this is just quick and dirty and you'll want to add code to store the new geometry into a new layer, but i left that out. The pyqgis developer cookbook describes, how to do that (http://docs.qgis.org/2.14/en/docs/pyqgis_developer_cookbook/vector.html).
As discussed in the comments, the data is stored inside a postgis database, so i can give a solution using SQL. I assume to have a table called linxyz with a geometry column "geom" along with "from" and "to" as z-values for the first/last point of a linestring geometry.
First add a second geometry column, it should have the same SRS as the original one (for me its SRID 4326 aka WGS84):
SELECT AddGeometryColumn ('linxyz','geomz', 4326, 'LINESTRING', 3);
Then use update to fill this new geometry column with a 3D linestring:
update linxyz set geomz = ST_GeomFromText('LINESTRING(' || ST_X(ST_StartPoint(geom)) || ' ' || ST_Y(ST_StartPoint(geom)) || ' ' || "from" || ',' || St_X(St_EndPoint(geom)) || ' ' || St_Y(St_EndPoint(geom)) || ' ' || "to" || ')' , 4326)
I used sql's string contatening operator || here to "build" the geometry from a WKT-String. Checking the result with select, shows the z-Dimension is present in the new column "geomz"
select ST_AsText(geomz) from linxyz
I'm not sure if this is the simplest way to accomplish this task, but it works in my little example :-)