4

I have some big DWG files, with 5 to 50 layers, which I draw and geolocated using AutoCAD (with some external modules). I need to convert them to KML or geoJSON so that the JS library can load them and display them on the map.

I used AutoCAD to export my .DWG into .DXF, then I installed GDAL and used ogr2ogr to convert those DXFs into geoJSON. It works, but the generated geoJSON is very big (more than 10 megabytes) and it loads forever once I try to display it into a google map or a leaflet map.

What I would like to do, is to have a separated geoJSON/KML for every layer of my DWG/DXF file, so that I can load and display each layer separately which hopefully would increase performance.

I am trying to have an automated workflow, because as I have a lot of files, it would take too much time to take every one of them and split layers manually.

Any idea ?

  • the link to the code is no longer working. Would you please update it. BTW in case others hit the same issue, I first had to convert my AutoCAD DWG to DXF using the free tool you can find here. – Erik Vullings Apr 15 '16 at 8:34
  • the gist seems to be gone. But the OGR thing still works. You could pack multiple DXF layers in one output file by changing the SQL to something like select * from entities where LAYER in (…) and not have to muck around with js. – scruss Oct 22 '16 at 15:06
3

I ended up making a node.js script which uses ogr2ogr through the command line.

It calls ogr2ogr through a spawned child process to keep it async.

ogr2ogr -f GeoJSON -s_srs epsg:2154 -t_srs epsg:4326 dest_file.json source_file.dxf

Then it reads the new geoJSON file into node, groups features in featureCollection by Layer name, wraps each group into a geoJSON container, and writes each wrapped group to a separate ".json" file.

Code is available here

2

It should be quite easy by using DXF, ogr2ogr, and GDAL SQLite SQL dialect http://www.gdal.org/ogr_sql_sqlite.html.

Demo:

Download some sample data, for example http://justcad.com/jcsample.dxf

Use ogrinfo with SQLite dialect for getting a list of layers:

ogrinfo -dialect SQLite -sql "select distinct LAYER  from entities" jcsample.dxf
INFO: Open of `jcsample.dxf'
      using driver `DXF' successful.

Layer name: SELECT
Geometry: None
Feature Count: 5
Layer SRS WKT:
(unknown)
Layer: String (0.0)
OGRFeature(SELECT):0
  Layer (String) = PAPER

OGRFeature(SELECT):1
  Layer (String) = FRELEV

OGRFeature(SELECT):2
  Layer (String) = LSELEV

OGRFeature(SELECT):3
  Layer (String) = RRELEV

OGRFeature(SELECT):4
  Layer (String) = RSELEV

Convert the layer "PAPER" into GeoJSON. I will assign epsg:3857 as a dummy projection because otherwise GDAL would assume EPSG:4326 which would make no sense because coordinate values in this data are out of the valid range.

ogr2ogr -f GeoJSON -a_srs epsg:3857 -dialect SQLite -sql "select * from entities where LAYER='PAPER'" paper.json jcsample.dxf

Check the result:

ogrinfo -ro -al paper.json
INFO: Open of `paper.json'
      using driver `GeoJSON' successful.

Layer name: OGRGeoJSON
Geometry: Unknown (any)
Feature Count: 56
Extent: (-174.786500, -1163.622000) - (1769.214000, 204.378100)
Layer SRS WKT:
PROJCS["WGS 84 / Pseudo-Mercator",
    GEOGCS["WGS 84",
        DATUM["WGS_1984",
            SPHEROID["WGS 84",6378137,298.257223563,
                AUTHORITY["EPSG","7030"]],
            AUTHORITY["EPSG","6326"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4326"]],
    PROJECTION["Mercator_1SP"],
    PARAMETER["central_meridian",0],
    PARAMETER["scale_factor",1],
    PARAMETER["false_easting",0],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    AXIS["X",EAST],
    AXIS["Y",NORTH],
    EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.
x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs"],
    AUTHORITY["EPSG","3857"]]
Layer: String (0.0)
SubClasses: String (0.0)
ExtendedEntity: String (0.0)
Linetype: String (0.0)
EntityHandle: String (0.0)
Text: String (0.0)
OGRFeature(OGRGeoJSON):0
  Layer (String) = PAPER
  SubClasses (String) = (null)
  ExtendedEntity (String) = (null)
  Linetype (String) = CONTINUOUS
  EntityHandle (String) = (null)
  Text (String) = (null)
  LINESTRING (1644.348 -1051.956 0,1763.214 -1051.956 0)

OGRFeature(OGRGeoJSON):1
  Layer (String) = PAPER
  SubClasses (String) = (null)
  ExtendedEntity (String) = (null)
  Linetype (String) = CONTINUOUS
  EntityHandle (String) = (null)
  Text (String) = (null)
  LINESTRING (1644.348 -1066.961 0,1763.214 -1066.961 0)

OGRFeature(OGRGeoJSON):2
  Layer (String) = PAPER
  SubClasses (String) = (null)
  ExtendedEntity (String) = (null)
  Linetype (String) = CONTINUOUS
  EntityHandle (String) = (null)
  Text (String) = (null)
  LINESTRING (1644.348 -1081.244 0,1763.214 -1081.244 0)
...
  • I forgot to mention that my DXFs are in Lambert93 (EPSG:2154). Can I do the projection to target coordinate system (WGS 84) directly ? Anyway, thanks a lot, I didn't know at all about the SQLite feature of GDAL. Will give it a shot – Rayjax Sep 8 '15 at 9:44
  • Sure, ogr2ogr -f GeoJSON -s_srs epsg:2154 -t_srs epsg:4326 ... . It is documented in gdal.org/ogr2ogr.html. SQLite dialect is very powerful because you can use all these functions with it gaia-gis.it/gaia-sins/spatialite-sql-latest.html. – user30184 Sep 8 '15 at 9:51
  • It does work :) . I was wondering if I could make a command that would make a file for every layer, without having to specify layer names manually. It would make a select distinct on layers as a subquery, and use the result layers names in a loop and extract each one of them using the second query you gave me. Any idea of how to do this without using third party tools ? – Rayjax Sep 8 '15 at 11:49
  • That sounds like scripting. Let's hope somebody comes to rescue with a Python script. – user30184 Sep 8 '15 at 12:54
  • I made a JS script (with node.js) to achieve this, and it works. At first, I used the mysql way, querying layer names and then looping over them, but I has problems with exotic layer names not passing in the queries. I ended up using simple conversion to geoJSON, then splitting the geoJSON itself into several geoJSONs.Will had an answer with it. Thanks for your help – Rayjax Sep 10 '15 at 8:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.