Convert 3D WKT to 2D Shapely Geometry

I have the WKT of many linestrings which contains three dimensions, however my script only requires a two dimensional linestring and I therefore want to discard the third dimension.

My current code, using Shapely, does flatten from 3D to 2D, but it relies on the geometry's wkt method outputting as 2D (even if it is 3D). As this Shapely behaviour may change in the future, can anyone recommend a more robust method of flattening to 2D?

• Python 2.7.13
• Shapely 1.2.17
• Ubuntu 12.10
``````>>> from shapely.geometry import LineString
>>> line_3d_wkt = "LINESTRING (1 2 0, 4 3 0, 8 9 0)"
>>> line_3d.has_z
True
>>> list(line_3d.coords)
[(1.0, 2.0, 0.0), (4.0, 3.0, 0.0), (8.0, 9.0, 0.0)]
>>> line_3d.wkt  # outputs as 2D even if 3D geometry
'LINESTRING (1.0000000000000000 2.0000000000000000, 4.0000000000000000 3.0000000000000000, 8.0000000000000000 9.0000000000000000)'
``````

My current technique to flatten the 3D geometry to 2D is:

``````>>> line_2d = loads(line_3d.wkt)
>>> line_2d.has_z
False
>>> list(line_2d.coords)
[(1.0, 2.0), (4.0, 3.0), (8.0, 9.0)]
``````
-

With the new Shapely version of mwtoews following your link Set default WKB output dimensions to 3 for geometries with Z-dimension

``````>>> line_3d_wkt = "LINESTRING (1 2 0, 4 3 0, 8 9 0)"
>>> line_3d.wkt
'LINESTRING Z (1 2 0, 4 3 0, 8 9 0)'
>>> line_2d = LineString([xy[0:2] for xy in list(line_3d.coords)])
>>> line_2d.wkt
'LINESTRING (1 2, 4 3, 8 9)'
``````
-

In addition, this operation is not necessary, since:

A third z coordinate value may be used when constructing instances, but has no effect on geometric analysis. All operations are performed in the x-y plane.

``````>>> line_3d.has_z
True
>>> buf = line_3d.buffer(5)
>>> buf.has_z
False
``````
-
Primarily I a want to remove the third dimension as my application will be storing many thousands of geometry objects for later processing and I am presuming that the removal of this third dimension will be beneficial in terms of performance and memory consumption. It appears from the Shapely gitgub site link, that the technique I am currently using may well not be available in the future. – Rusty Magoo Jul 28 '13 at 10:06
Then, use list slicing: p= LineString([x[0:2] for x in list(line_3d.coords)]) – gene Jul 28 '13 at 10:25