== GDAL DWG file format support == == Short description == An implementation of new OGR Driver with capability to read DWG file format. Driver will be based on a newly written open-source library under X/MIT license. == Introduction == Current state of GDAL: There is DWG support, which contradicts with GDAL ideology: 1. It depends on third-party library (Teigha), which is not OpenSource. 2. Current DWG Driver is not built-in in GDAL 2.0 by default, and is not maintained for years. 3. There are a few external libraries, that can provide abilities to work with DWG, but they can’t be used in GDAL for a variety of reasons: * libdwg - abandoned project * libredwg - GPLv3 incompatible with GDAL X/MIT * libdxfrw - GPLv2 incompatible with GDAL X/MIT. To sum up, there is a real need in creating a driver without any third-party dependencies, which can go forward with X/MIT ideology. == Main ideas == '''Write a new library to read DWG files''' * Library should be written in an easy-to-extend style, so every DWG/DXF version can be handled easily. * Library should provide a clear API how to interact with it, and an easy method to write OGR Driver based on it. * Library should has an abstract data model for all DWG/DXF files of any version (so, DXF format also could be added to the library). '''GDAL Driver''' Implement a new DWG driver for OGR, which will work with libopencad. The driver should support some options, i.e. explode blocks, etc. All DWG/DXF header variables should be mapped to driver metadata. Reading the DWG/DXF files should be organised via GDAL VSI/CPL functions. The libopencad sources needed for driver will be merged to GDAL sources. '''Plan & Timeline''' 1. Before May 28: Complete creating File Map of DWG R2000, which will allow to easily get Geometries from specific layer. Reading Layers attributes. Write google tests for file opening errors handling, reading geometries of each type. 2. May 28 - June 4: Write google tests for correct opening of large files with big amount of geometries and layers. 3. June 5 - June 12: Implement doxygen, start working on library API and internal methods description. 4. June 13 - June 20: Implement reading of attributes for geometries and objects, as they are separated from geometries/objects data structures. 5. June 21 - June 28: Start writing OGR Driver (DXF driver will be as an example) for DWG file format handling and integrating libopencad in it. Add basic OGR style support. 6. June 29 - July 6: Start adding DWG R13-14 formats support to libopencad. Working on last week tasks. 7. July 7 - July 14: End of adding DWG R13-14 formats support to libopencad. Start testing new OGR DWG Driver for its capabilities to Identify DWG files, reading features from it. 8. July 15 - July 22: Implement Valgrind to find actual memory leaks in libopencad, as well as in OGR Driver and fix them. 9. July 23 - 30: Start writing documentation for new OGR Driver. Start code refactoring of libopencad codebase for production level. 10. July 31 - August 7: End code refactoring. End writing documentation. Write GDAL Autotests for new driver. 11. August 8 - August 15: Fix possible errors found by autotests. Sumbit a pull request to GDAL Trunk. == Future ideas == Support for writing ability - creating CAD files is more complicated than reading, but with good library/driver architecture it will be possible without any painful refactoring. Not all DWG format versions will be handled during GSoC, so adding support to them will also be a good extension. == Project progress == The project separated into 2 parts: CAD formats support library (named libopencad), and GDAL driver, which uses it. Library can be used by itself for any reason. === Libopencad (GDAL CAD Driver engine) === ==== Overview ==== Libopencad is a library written in C++11, which provides a way to read/write CAD (DWG/DXF/DXFB) files. It was designed to have a uniformal API to work with any CAD files. It has a base class - CADFile. Inheriting this class it’s possible to create a ‘driver’ for any CAD format, all you need to do - is to overwrite interface functions like ‘GetGeometry(index)’, and others. Now it has an implementation for DWG2000 (R15), but only for read. Library comes with ‘cadinfo’ utility, which prints out everything library can get from file - header variables, CAD custom classes, presented layers and geometries with their attributes. ==== Internal structure ==== Library presents CAD objects in different ways - base class CADObject and other CAD...Object classes are exact analogues of how DWG format stores information about its objects. CADGeometry, and other classes which inherits it, are done for API access to CAD...Object classes. Library supports 3 modes of reading - READ_ALL (means everything which can be extracted from CAD file will be read) READ_FAST (skipping some kind of meanless information - linetypes, CRC check, etc), READ_FASTEST (only geometries reading, additional info is skipped). When parsing the file, library does not store any information it does not need. First, it reads file meta-information, and creates a file map. It only stores some info about presented layers, and header variables. Then, when calling application uses CADLayer.GetGeometry(index), it actually reads a geometry from file, using prepared file map. Sometimes it will be slower than having everything you have read in cache, but gives you more flexibility what you want to store in memory, and what you wont. Library also has special classes which incapsulates I/O functions, so it’s possible to reimplement them for your needs - by default it uses std::fstream, but you can make it possible to work with network by make a class inherited from CADFileIO. Supported geometries list: Point, Circle, Ellipse, Arc, Text, Solid, Spline, Line, Polyline 2D, Polyline 3D, LWPolyline, Ray, Raster (Images), MText, MLine, XLine, Polyface Mesh, 3DFace. === GDAL CAD Driver === ==== Overview ==== GDAL CAD Driver uses libopencad as a datasource. Not everything that libopencad can read from file is mapped into OGR infrastructure, but it will be done in near future. Current features are: 1. OpenOptions are presented with 2 options: - MODE - READ_ALL/READ_FAST/READ_FASTEST (means the same as library OpenOptions). - ADD_UNSUPPORTED_GEOMETRIES_DATA (YES/NO) - unstable feature, if some of the objects cannot be mapped into OGR representation (or its just not implemented yet), it will be presented as a CADUnknown object - OGRFeature without geometric representation, but with basic info - geometry type, some additional params. 2. CAD header variables are mapped into metadata. 3. Unlike DXF driver, CAD driver stores vector data in the appropriate layers (not all entities in single layer). 4. Raster subdatasets are also supported. 5. Coordinate system is extracted from DWG file (if it is presented in accordance with ESRI Docs for DWG files), or from %FILENAME%.prj file in the same directory. 6. CAD Geometry attributes mapping is completely done into OGRLayerDefn. So, any ACAD BlockReference attributes will be seen in OGRLayerDefn. === Images === [[Image(https://pbs.twimg.com/media/Cm2N_-nVIAA8jBn.jpg, 320px)]] ''Raster and vector layers by the same driver (left - ArcGIS, right - QGIS).'' [[Image(https://pbs.twimg.com/media/CmwXIBnWcAAz22X.jpg, 320px)]] ''A little comparison between original data source (ACAD) and QGIS with new DWG driver.'' == Links == CAD support library: ​https://github.com/sandyre/libopencad Libopencad + GDAL fork: https://github.com/sandyre/gdal_libopencad Blog: http://gsoc2016gdaldwg.blogspot.ru/ Pull request: https://github.com/OSGeo/gdal/pull/145