8

Using shapely package for Python how to export the resulting shapely objects such as buffer to a DXF file?

nmtoken
  • 13,355
  • 5
  • 38
  • 87
Developer
  • 3,387
  • 4
  • 29
  • 34

4 Answers4

10

BTW, if you appreciate Shapely, you may also appreciate Fiona. The Fiona example in https://gist.github.com/1886782 could be adapted to convert a shapefile to DXF.

with fiona.collection("file.shp", "r") as source:

    with fiona.collection(
            "file.dxf",
            "w",
            driver="DXF",
            schema=source.schema,
            ) as sink:

        # Do whatever you like to records
        results = some_function(source)

        sink.writerecords(results)

It coughs up a lot of warnings about mismatch between GIS simple feature and DXF data models but does write a file of entities.

sgillies
  • 9,056
  • 1
  • 33
  • 41
8

Shapely doesn't directly support exporting to DXF - it supports export to Well Known Text (WKT), Well Known Binary (WKB), Numpy arrays and GeoJSON objects (interoperation from the Shapely manual). As such you need a package that can transform from one of these formats to DXF.

I'd suggest OGR as the way to go for my money. The easiest method would be to simply export your shapely geometries to a GeoJSON file through Python using shapely.geometry.mapping(obj), e.g.

from shapely.geometry import mapping
import json
open("buffer.geojson", "wb").write(json.dumps(mapping(buffer_obj)))

Then simply use the ogr2ogr utility to transform the GeoJSON to a DXF file, e.g.

ogr2ogr -f DXF buffer.dxf buffer.geojson

Then, if you're keen you can look up the GDAL/OGR Python bindings and do it within a single script. Hope this helps!

Glorfindel
  • 1,096
  • 2
  • 9
  • 14
om_henners
  • 15,642
  • 2
  • 46
  • 86
  • Thanks a lot. You gave many ideas which are very useful. I would like to try OGR through Python. This a good answer. – Developer Feb 23 '12 at 13:37
  • 1
    As explained in http://gis.stackexchange.com/a/7744/390 there's a mismatch between the GeoJSON and DXF formats. Looks like you'll want to have a DXF template into which to stuff your lines. – sgillies Feb 23 '12 at 15:50
  • 1
    Just to mention in execution of the provided code an error come up: "write requires string/buffer". So I changed it as: write(str(mapping(buffer_obj))) and it is OK now. I use Python 2.72 BTW. – Developer Feb 23 '12 at 17:14
  • and I also had to replace () with [] in the produced GeoJSON file to bypass another error caused using ogr2ogr.exe. Those may be changes in software or I'm missing something obvious! Anyway, with these two tricks it produced a DXF file successfully. – Developer Feb 23 '12 at 17:33
  • However DXF file may have some issues since I could not open it by different software such as LibreCAD, SketchUp etc. – Developer Feb 23 '12 at 17:59
  • @Developer Sorry about the mistake in the code - I've updated it with a reference to the Python json library to dump the mapping. Sorry that the DXF doesn't work though. Are there any other formats that OGR supports and that you can open in your CAD software (DGN maybe? Maybe shapefiles at a stretch?) – om_henners Feb 23 '12 at 22:33
  • @om_henners Unfortunately only DXF and GDS files are importable! – Developer Feb 24 '12 at 02:34
1

You can do that using Geopandas and Fiona Libraries Here is the code to read a file using Geopandas and export it as a DXF File.

import geopandas as gpd
from geopandas import GeoDataFrame
import fiona

#Read file using geopandas x = gpd.read_file(filename with path)

#Save as DXF x.geometry.to_file(output file name, driver="DXF")

Also, check the answer in the below link. https://gis.stackexchange.com/a/377412/160313

Megastar
  • 11
  • 1
0

Nowadays new ways came along, thanks to the __geo_interface__ interface standard and the ezdxf library.

A sample code could be below were shapes holds your e.g. MultiPolygon

from shapely.geometry import mapping
import ezdxf
import ezdxf.addons.geo

doc = ezdxf.new() geoproxy = ezdxf.addons.geo.GeoProxy.parse(mapping(shapes))

msp = doc.modelspace()

Use LWPOLYLINE instead of hatch.

for entity in geoproxy.to_dxf_entities(polygon=2): msp.add_entity(entity)

doc.saveas("test.dxf")

gyger
  • 101
  • 1