From d784918d2b7665819a55084cd8bf9b976498ce3c Mon Sep 17 00:00:00 2001 From: Dan Howe Date: Wed, 18 Apr 2018 17:32:52 +1000 Subject: [PATCH] Convert to command line tool --- dxf_to_csv/__init__.py | 1 + dxf_to_csv/dxf_to_csv.py | 138 +++++++++++++++++++++++++++++++++++++++ scripts/dxf_to_csv.py | 4 -- setup.py | 10 +++ 4 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 dxf_to_csv/__init__.py create mode 100644 dxf_to_csv/dxf_to_csv.py create mode 100644 setup.py diff --git a/dxf_to_csv/__init__.py b/dxf_to_csv/__init__.py new file mode 100644 index 0000000..476a8a7 --- /dev/null +++ b/dxf_to_csv/__init__.py @@ -0,0 +1 @@ +from .dxf_to_csv import main diff --git a/dxf_to_csv/dxf_to_csv.py b/dxf_to_csv/dxf_to_csv.py new file mode 100644 index 0000000..cfd77e5 --- /dev/null +++ b/dxf_to_csv/dxf_to_csv.py @@ -0,0 +1,138 @@ +"""Extract points from a dxf file, and save in csv format + +Usage: + dxf_to_csv.py [-h] [-n LAYER_NAME] [-l] dxf_name + +Positional arguments: + dxf_name path to dxf file + +Optional arguments: + -h, --help show this help message and exit + -n LAYER_NAME name of layer + -l show list of layers + +Examples: + +Show available layers: +> python dxf_to_csv.py drawing.dxf -l + +Convert all layers: +> python dxf_to_csv.py drawing.dxf + +Convert specific layer: +> python dxf_to_csv.py drawing.dxf -n LAYER_NAME + +""" + +__author__ = "D. Howe" +__version__ = "0.2.0" +__email__ = "d.howe@wrl.unsw.edu.au" + +import os +import sys +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt +import argparse +import dxfgrabber + + +def point_to_row(point, layer, dxf_type, dxf_id): + """Create a dict from a point with layer and e properties""" + row = {key: val for key, val in zip(['x', 'y', 'z'], [*point])} + row['layer'] = layer + row['type'] = dxf_type + row['id'] = dxf_id + + return row + + +def print_layers(dxf_name): + dxf = dxfgrabber.readfile(dxf_name) + + # Get data from DTM + print('Available layers in {}'.format(dxf_name)) + layers = sorted([layer.name for layer in dxf.layers]) + for layer in layers: + print(layer) + + +def convert(dxf_name, layer_name): + # Read dxf file + dxf = dxfgrabber.readfile(dxf_name) + + if layer_name: + print("\nExtracting data from layer '{}'".format(layer_name)) + entities = [ + e for e in dxf.entities if e.layer.lower() == layer_name.lower() + ] + else: + # Take all layers if no layer name given + print('\nExtracing data from all layers') + entities = [e for e in dxf.entities] + + # Get coordinates of entities + data = [] + for e in entities: + if e.dxftype == 'POINT': + point = e.point + row = point_to_row(point, e.layer, e.dxftype, e.handle) + data.append(row) + elif e.dxftype == 'LINE': + points = [e.start, e.end] + for point in points: + row = point_to_row(point, e.layer, e.dxftype, e.handle) + data.append(row) + elif e.dxftype == 'POLYLINE': + for vertex in e.vertices: + point = vertex.location + row = point_to_row(point, e.layer, e.dxftype, e.handle) + data.append(row) + elif e.dxftype == 'LWPOLYLINE': + for point in e.points: + row = point_to_row(point, e.layer, e.dxftype, e.handle) + data.append(row) + + # Add to dataframe + points = pd.DataFrame(data) + + # Check if there are z coordinates + if 'z' not in points.columns: + points['z'] = np.nan + + # Reorder columns + points = points[['layer', 'type', 'id', 'x', 'y', 'z']] + + # Export points + if layer_name: + csv_name = dxf_name.replace('.dxf', '-{}.csv'.format(layer_name)) + else: + csv_name = dxf_name.replace('.dxf', '.csv') + points.to_csv(csv_name, index=False) + + +def main(): + # Set up command line arguments + parser = argparse.ArgumentParser() + parser.add_argument('dxf_name', help='path to dxf file', default=None) + parser.add_argument( + '-n', metavar='LAYER_NAME', help='name of layer', default=None) + parser.add_argument( + '-l', action='store_true', help='show list of layers', default=False) + args = parser.parse_args() + + # Parse arguments + dxf_name = args.dxf_name + layer_name = args.n + show_layers_only = args.l + + if show_layers_only: + # Print list of layers only + print_layers(dxf_name) + else: + # Convert to csv + convert(dxf_name, layer_name) + + +if __name__ == '__main__': + main() diff --git a/scripts/dxf_to_csv.py b/scripts/dxf_to_csv.py index cfd77e5..e6d5b6a 100644 --- a/scripts/dxf_to_csv.py +++ b/scripts/dxf_to_csv.py @@ -24,10 +24,6 @@ Convert specific layer: """ -__author__ = "D. Howe" -__version__ = "0.2.0" -__email__ = "d.howe@wrl.unsw.edu.au" - import os import sys import numpy as np diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..9de6e21 --- /dev/null +++ b/setup.py @@ -0,0 +1,10 @@ +from setuptools import setup + +setup( + name='dxf_to_csv', + version='0.3.0', + packages=['dxf_to_csv'], + entry_points={'console_scripts':['dxf_to_csv = dxf_to_csv:main']}, + author='Dan Howe', + author_email='d.howe@wrl.unsw.edu.au', + description='Extract points from a dxf file, and save in csv format')