[Qgis-user] 3D dxf files
gene
martin.laloux at gmail.com
Thu Dec 19 09:28:05 PST 2013
Looking at the awk script of Siki Zoltan, I made Python scripts using
regular expressions that works :
In the dxf file, A 3D face polygon is located between the two delimiters:
*3DFace*
.....
* 0*
(the spaces before the 0 are important here, because there are also
coordinates equal to 0, without spaces)
I use the solution of Brent Newey in Repeatedly extract a line between two
delimiters in a text file, Python
<http://stackoverflow.com/questions/7098530/repeatedly-extract-a-line-between-two-delimiters-in-a-text-file-python>
re.findall('DELIMITER1(.*?)DELIMITER2'
I had to try many many regular expressions to extract the polygons but this
one works with all my examples:
re.findall(''3DFACE(.*?)\s{3}0'')
The main drawback of this approach is that the dxf file must be read in
memory entirely before it's used (but no problem with the 33.3 Mo of
Otway_Basin_Granites-gravity.dxf)
The scripts:
1) if you want a 3D shapefile as a result, you can use pyshp
<http://code.google.com/p/pyshp/> , Fiona
<http://toblerity.org/fiona/manual.html> and shapely
<http://toblerity.org/shapely/manual.html> or osgeo.ogr (PyQGIS does not
support 3D)
With pyshp:
import shapefile
import re
w = shapefile.Writer(shapeType=shapefile.POLYGONZ)
with open("tokaj.dxf") as fp:
w.field("NAME")
for result in re.findall('3DFACE(.*?)\s{3}0', fp.read(), re.S):
a = result.split()
name,x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4 = a[1::2]
w.poly([[[float(x1),float(y1),float(z1)],
[float(x2),float(y2),float(z2)], [float(x3),float(y3),float(z3)]]])
w.record(name)
w.save("tokaj.shp")
With Fiona and shapely:
import fiona
from shapely.geometry import Polygon, mapping
import re
schema = {'geometry': '3D Polygon','properties': {'name': 'str'}}
with open("tokaj.dxf") as fp:
with fiona.open('tokaj2.shp','w','ESRI Shapefile', schema) as e:
for result in re.findall('3DFACE(.*?)\s{3}0', fp.read(),
re.S):
a = result.split()
name,x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4 = a[1::2]
geom = Polygon([(float(x1),float(y1),float(z1)),
(float(x2),float(y2),float(z2)), (float(x3),float(y3),float(z3))])
e.write({'geometry':mapping(geom),
'properties':{'name':name}})
2) if you want directly a 2D shapefile in QGIS, you can use the Python
console:
from PyQt4.QtCore import *
import re
fields = QgsField("name", QVariant.String)
layer = QgsVectorLayer("Polygon", "tokaj", "memory")
pr = layer.dataProvider()
pr.addAttributes([QgsField("name", QVariant.String)])
with open("tokaj.dxf") as fp:
for result in re.findall('3DFACE(.*?)\s{3}0', fp.read(), re.S):
a = result.split()
name,x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4 = a[1::2]
fet = QgsFeature()
fet.setAttributes([name])
geom =
QgsGeometry.fromPolygon([[QgsPoint(float(x1),float(y1)),
QgsPoint(float(x2),float(y2)), QgsPoint(float(x3),float(y3))]])
fet.setGeometry(geom)
pr.addFeatures([fet])
layer.updateExtents()
QgsMapLayerRegistry.instance().addMapLayers([layer])
Result:
<http://osgeo-org.1560.x6.nabble.com/file/n5095133/tokaj.jpg>
The main drawback of this approach is that the dxf file must be read in
memory entirely before it's used. I am trying with generators/iterators.
--
View this message in context: http://osgeo-org.1560.x6.nabble.com/3D-dxf-files-tp5093449p5095133.html
Sent from the Quantum GIS - User mailing list archive at Nabble.com.
More information about the Qgis-user
mailing list