Финальный отчет по GSoC (перевод).
Краткое описание идеи.
Цель моего проекта была в добавлении поддержки DWG в GDAL.
Состояние проекта (GDAL) до моей работы.
Поддержка DWG была, однако она не была встроенной по умолчанию, а зависела от проприетарной third-party библиотеки Teigha, которую нужно было приобретать и подключать самостоятельно.
Какие возможности привнес мой проект в ПО (GDAL).
Libopencad (GDAL CAD Driver engine)
Обзор
Libopencad это библиотека написанная на C++11, которая позволяет читать и писать CAD (DWG/DXF/DXFB) файлы. Она была спроектирована для того, чтобы иметь общий API для работы с любыми CAD файлами. В ней присутствует базовый абстрактный класс CADFile. Создавая классы-наследники от CADFile становится возможным написание ‘драйвера’ для любого CAD формата, все что для этого нужно - это переопределить интерфейсные функции вида ‘CADFile::GetGeometry(index)’ для чтения конкретного формата и версии. Сейчас реализован драйвер для DWG2000 (R15), однако только для чтения.
В комплект поставки библиотеки идет утилита 'cadinfo', которая выводит на экран все, что библиотека может извлечь из файла - переменные ACAD, представленные слои и их атрибуты, а так же геометрии.
Внутренняя структура
Библиотека представляет объекты CAD двумя различными способами - базовый класс CADObject и классы наследующие его (CAD...Object) являются точными аналогами того, как CAD формат хранит эти объекты (те же типы данных, и другие тонкости); класс CADGeometry и другие классы наследующие его (например, CADLine, CADArc и тд) сделаны для API доступа к CAD...Object классам. Другими словами, библиотека оперирует CAD...Object, и при запросе вызывающей программы преобразует их к CADGeometry (и не только, существуют классы вида CADDictionary, которые предоставляют доступ к Named Object Dictionary).
Библиотека поддерживает 3 вида чтения (OpenOptions) - READ_ALL (все, что может быть "изъято" из CAD файла будет вычитано), READ_FAST (пропускается некоторая "бесполезная" информация - не идет подсчет CRC, LineTypes пропускаются), READ_FASTEST (только геометрия будет вычитана, все остальное пропущено).
При парсинге файла, библиотека не сохраняет никакую информацию, которая ей не нужна. Сначала, она вычитывает мета-информацию (переменные окружения, различные ObjectMap и Classes-секции), и строит карту файла (file map). Она сохраняет только некоторую информацию о слоях (их атрибуты, вида имя слоя, "заморожен", "невидим" и тд), и переменные ACAD. Затем, когда вызывающее приложение использует CADLayer.GetGeometry(index), она на самом деле вычитывает запрашиваемую геометрию, используя заготовленную file map. Конечно, иногда это будет медленнее чем кешировать все, что она вычитывает - однако это дает гибкость в использовании библиотеки - вы сами решаете, что нужно кешировать, а что нет.
Библиотека так же имеет специальные классы которые инкапсулируют функции чтения/записи, так что становится возможным переопределить их под ваши нужды - по умолчанию они используют std::fstream, однако возможно заставить библиотеку работать и с сетью, создав класс-наследник CADFileIO и передав его в функцию OpenCADFile(CADFileIO, OpenOptions).
Библиотека поддерживает чтение следующих геометрий (для остальных не реализован маппинг CAD...Object -> CADGeometry):
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
Обзор
GDAL CAD Driver использует libopencad как источник данных. Не все, что умеет libopencad, уже отмапплено в OGR-представление. Текущие "фичи":
OpenOptions представляет из себя 2 опции:
- MODE - READ_ALL/READ_FAST/READ_FASTEST (означает то же самое, что и библиотечный OpenOptions, параметр просто пробрасывается в библиотеку).
- ADD_UNSUPPORTED_GEOMETRIES_DATA (YES/NO) - нестабильная фича, если какие либо объекты не могут быть отмапплены в OGR-представление (или они просто не реализованы), они будут представлены как CADUnknown объекты и отмапплены в OGRFeature которое не имеет геометрического представления (поведение, например, QGIS при работе с объектами без геометрического представления неизвестно) однако с базовой информацией - тип геометрии, и некоторые другие параметры.
CAD переменные отмапплены в metadata.
В отличии от DXF driver, CAD driver поддерживает послойность векторных данных (а не все объекты попадают на один слой entities).
Растровые subdatasets так же поддержаны.
Системы координат извлекаются напрямую из CAD файла (если они представлены в соответствии с ESRI Docs for DWG files), или, если изъять их не удалось, из %FILENAME%.prj файла в той же директории.
Атрибуты CADGeometry полностью отмапплены в OGRLayerDefn. Таким образом, все атрибуты блоков будут видны в OGRLayerDefn.
Все полезные ссылки.
Libopencad repository (installation is described in REAME.MD)
Libopencad + GDAL fork
Blog with all reports and notices
PR with my work into GDAL-trunk.
GDAL Wiki driver page
Скриншоты работы.
Поддержка растра и вектора одним и тем же драйвером (слева - ArcGIS, справа - QGIS):
Небольшое сравнение оригинала (ACAD) и QGIS с новым DWG driver:
Маппинг атрибутов блока в OGRLayerDefn:
