Created
March 14, 2017 14:47
-
-
Save Elektordi/76235dc28a892e768306a52b6acff342 to your computer and use it in GitHub Desktop.
Mass convert of lines from Lambert2 DXF to WKT CSV
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import sys | |
import ezdxf | |
import re | |
from osgeo import gdal,ogr,osr | |
import math | |
def reproject(x, y, inputEPSG, outputEPSG): | |
inSpatialRef = osr.SpatialReference() | |
inSpatialRef.ImportFromEPSG(inputEPSG) | |
outSpatialRef = osr.SpatialReference() | |
outSpatialRef.ImportFromEPSG(outputEPSG) | |
coordTransform = osr.CoordinateTransformation(inSpatialRef, outSpatialRef) | |
point = ogr.Geometry(ogr.wkbPoint) | |
point.AddPoint(x, y) | |
point.Transform(coordTransform) | |
return (point.GetX(), point.GetY()) | |
def lambert2_to_wgs84(x, y): | |
return reproject(x, y, 27572, 4326) | |
def wgs84_to_lambert2(x, y): | |
return reproject(x, y, 4326, 27572) | |
def near(p0,p1): | |
if p0==p1: # Optimize! | |
return True | |
d = math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2) | |
#print "%f,%f - %f,%f = %f"%(p0[0], p0[1], p1[0], p1[1], d) | |
return d<0.00001 | |
def __main__(): | |
if len(sys.argv)<2: | |
print "Usage: %s file.dxf ..."%(sys.argv[0]) | |
return | |
files = sys.argv[1:] | |
print "fci;geom" | |
for file in files: | |
fci = None | |
dwg = ezdxf.readfile(file) | |
layername = re.compile("^[RF]C[BC]_(F[0-9]{11})$") | |
mylayer = None | |
for layer in dwg.layers: | |
r = layername.match(layer.dxf.name) | |
if not r is None: | |
if mylayer is None: | |
mylayer = layer.dxf.name | |
fci = r.group(1) | |
else: | |
print "!!! Too many GCBLO layers." | |
return | |
if mylayer is None: | |
print "!!! No GCBLO layer." | |
return | |
#print "File %s: Found layer %s (Order %s)"%(file, mylayer, fci) | |
modelspace = dwg.modelspace() | |
lines = [] | |
index = [] | |
for e in modelspace.query('LWPOLYLINE POLYLINE LINE[layer=="%s"]'%(mylayer)): | |
line = ogr.Geometry(ogr.wkbLineString) | |
if e.dxftype() != 'LINE': | |
for p in e: | |
(x,y) = lambert2_to_wgs84(p[0], p[1]) | |
#print "%f,%f"%(x,y) | |
line.AddPoint(x,y) | |
else: | |
(x,y) = lambert2_to_wgs84(e.dxf.start[0], e.dxf.start[1]) | |
line.AddPoint(x,y) | |
(x,y) = lambert2_to_wgs84(e.dxf.end[0], e.dxf.end[1]) | |
line.AddPoint(x,y) | |
#print line.ExportToWkt() | |
lines.append(line) | |
firstpoint=line.GetPoint(0) | |
lastpoint=line.GetPoint(line.GetPointCount()-1) | |
index.append((line,firstpoint,lastpoint)) | |
firstline = firstpoint = None | |
for l,fp,lp in index: | |
for p in [fp,lp]: | |
found = True | |
for l2,fp2,lp2 in index: | |
if l==l2: | |
continue | |
if near(p,fp2) or near(p,lp2): | |
found = False | |
if found: | |
firstline = l | |
firstpoint = p | |
if found: | |
break | |
if firstline is None: | |
print "!!! Cannot find line start." | |
return | |
#print "Start found: %f,%f"%(firstpoint[0], firstpoint[1]) | |
geom = ogr.Geometry(ogr.wkbLineString) | |
while True: | |
lines.remove(firstline) | |
if firstline.GetPoint(0) == firstpoint: | |
for p in firstline.GetPoints(): | |
if lastpoint == p: | |
continue | |
geom.AddPoint(p[0], p[1]) | |
lastpoint=p | |
else: | |
for p in reversed(firstline.GetPoints()): | |
if lastpoint == p: | |
continue | |
geom.AddPoint(p[0], p[1]) | |
lastpoint=p | |
if not lines: | |
break | |
found = False | |
for l,fp,lp in index: | |
if not l in lines: | |
continue | |
if near(lastpoint,fp) or near(lastpoint,lp): | |
firstline = l | |
firstpoint = lastpoint | |
found = True | |
if not found: | |
print "!!! Discontinuity error at %f,%f"%(lastpoint[0], lastpoint[1]) | |
print geom.ExportToWkt() | |
return | |
geom.FlattenTo2D() | |
print "%s;%s"%(fci,geom.ExportToWkt()) | |
__main__() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
pip install ezdxf osgeo --user
if
osgeo
fails to install with that command, use the following