Spatial Manipulation of a Autocad DXF File with Python3 and GeoPandas - Tutorial

Geopandas.PNG

In GIS the objects are related to a spatial location. Usually there is no need to modify a location since spatial data comes from field work or other surveys. When we work with CAD files as DXF (Autocad Drawing Exchange Format) files, sometimes the spatial data is available as a layout view and not as a model view. The layout data is on local coordinates, and at specific scale therefore we need to scale and translate the spatial data to “return” it to its original spatial location and extension.

We tried to make this job with Inkscape and QGIS3, but we were unsuccessful to complete the scale and translation. While working with the DXF in Inkscape, each object selection, layer order combination, object ungrouping took several minutes and the results were poor. At the lowest motivational stage of this spatial request, we thought that it might me something in Python that can be useful for this.

On a internet search, we found that the spatial version of the Pandas data analysis library: Geopandas was capable not only to open the DXF files, but also to scale, translate, and filter spatial data according to specific criteria. Geopandas is capable to export spatial data in different formats and to plot data interactively on a Jupyter Notebook.

This tutorial shows the procedure to open a DXF file in Python pandas, perform scale and translation to place the spatial features on their original position, filter unwated objects on the layout view and export results to QGIS3 as shapefile.

Tutorial

Python code

%matplotlib inline
import geopandas as gpd
#open the DXF file
plano = gpd.read_file('../Dxf/Plano_Ccamacmayo.dxf')
plano.plot()
#scale the DXF to spatial extend
geometryScaled = plano.scale(6.618133,6.618133,1,origin=(0,0,0))
#translate the geometry to WGS84 UTM 18S
geometryTranslated = geometryScaled.translate(247041.856,8347561.054,0)
#apply the new geometry to the geopandas dataframe and apply the EPSG cpde
plano = gpd.GeoDataFrame(plano, geometry=geometryTranslated)
plano.crs = {'init':'epsg:32719'}
plano.plot()
#filter only the line elements
planoLines = plano[plano.geometry.type=='LineString']
#export the spatial as shapefile
planoLines.to_file('../Shps/Dxf_Total.shp')
#get the statistics form the elements length
planoLines.geometry.length.describe()
#filter the lines to get lines longer than 10m
longLines = planoLines[planoLines.geometry.length > 25.0]
longLines.head()
#export long lines as shapefiles
longLines.to_file('../Shps/Dxf_longLines.shp')
for index, row in longLines.iterrows():
    row = row.copy()
    lenVertex = len(row.geometry.xy[0])
    if lenVertex>50:
        print(lenVertex)
        longLines.loc[index,'long'] = 1
    else:
        longLines.loc[index,'long'] = 0
#filter curved lines
curvedLines = longLines[longLines['long']==1]
curvedLines.head()
#export curved lines as shapefiles
curvedLines.to_file('../Shps/Dxf_curvedLines.shp')

Input data

You can download the input files for this tutorial here.

Saul Montoya

Saul Montoya es Ingeniero Civil graduado de la Pontificia Universidad Católica del Perú en Lima con estudios de postgrado en Manejo e Ingeniería de Recursos Hídricos (Programa WAREM) de la Universidad de Stuttgart con mención en Ingeniería de Aguas Subterráneas y Hidroinformática.

Smiley face

Subscribe to our free e-newsletter for tutorials, articles, webminars, courses and more.