В первой части статьи (https://zen.yandex.ru/media/id/5d0dba97ecd5cf00afaf2938/627a2666e71a825dbd453337) мы познакомились с библиотекой PROJ, входящей в пакет утилит GDAL. Эта библиотека для расчета преобразований между системами координат используется как базовая в среде QGIS.
P.S. Оригинальное название статьи было про NanoCAD но я меняю на универсальное "САПР", так как библиотека независима от него и на практике может применяться где угодно.
В этой части я расскажу в основном про порядок ее обновления и использования в составе свой библиотеки под .NET.
1. Немного про программную механику взаимодействия
Прошлую часть 1 я закончил на грустной ноте, что координаты не пересчитывались для группы значений; после разбирательств, оказалось что я не верно (некорректно) реализовал Platform Invoke функцию, передавая массив символов char (на этапе отладки обнаружил, что на концах строк появлялись странные рандомные символы). Сменив логику наименований СК на числовые коды (int) проблема ушла. Вообще, я удивлен что оно сработало с int ... поскольку я морально смотрел уже в сторону таких int 😢
К слову, часть 1 я поправил -- теперь она описана корректно.
2. Как устроена логика хранения информации о системах координат в PROJ
Согласно странице документации, если опустить непонятные места, в системе может быть несколько расположений базы данных определений. То есть мы можем забыть о необходимости подменять базу проекций для разных библиотек, а использовать их всех одновременно. (в теории)
Так, в зависимости от используемой операционной системы (Windows, Linux, MacOS) у нас есть фиксированные файловые пути, где PROJ "ищет" базу проекций. Эти пути появились с версии 7 (мы, напомню, используем версию 7.2.1, а последняя актуальная - 9.0.0).
- on Windows, ${LOCALAPPDATA}/proj
- on macOS, ${HOME}/Library/Application Support/proj
- on other platforms (Linux), ${XDG_DATA_HOME}/proj if XDG_DATA_HOME is defined. Else ${HOME}/.local/share/proj
Кроме того, в системе может быть определена переменная среды "PROJ_LIB", в которой прописаны дополнительные файловые пути, где лежит библиотека - именно этот подход позволяет держать несколько ее версий (в теории .. так как программа понимает среди различных дублирующихся кодов какой использовать вопрос).
Непосредственно сами определения хранятся в базе данных sqlite3 в proj.db по определенному выше одним из способов путей.
2.1. Как устроена таблица СК
Обратимся к самой базе проекций в среде БД sqlite3:
Для работы с менеджером баз данных sqlite нам понадобится "фирменное" приложение sqlite3.exe. На классической ОС он по умолчанию не установлен, поэтому его надо будет скачать отсюда.
Теперь обратимся к местонахождению файла БД проекций. Положим (для нашей библиотеки) что он расположен в пользовательской папке:
.open C:/Users/Georg/AppData/Local/proj/proj.db
Теперь давайте получим перечень всех таблиц, для чего введем команду
.tables
Среди перечисленных 98% из нас будут интересны проекции - projected_crs (кому-то может еще geodetic_srs).
Давайте получим спецификацию таблицы с именем колонок:
.schema projected_crs
Итак, здесь у нас 12 значимых полей, при этом их заполнение может происходить в режиме "конструктора" из уже доступных определений в БД, и в режиме пользовательского определения -- через строку PROJ.4 или WKT-формулировку.
В силу того, что работать предполагается с отечественными определениями, которые не базируются на стандартных, дело мы будем иметь со страданием именно c готовыми формулировками wkt2. Почему именно WKT2? Потому что год назад я делал их выгрузку из Civil3D -- то есть именно их я и планирую использовать для дополнения стандартной БД новыми определениями.
По какому принципу будет строиться добавление?
По принципу исполнения sql-файла со строками вида:
Чтобы случайно не дублировать существующий код, сперва найдем максимальное число code получением всех числовых значений (они в базовом случае хранятся в виде текста) и поиском максимального. Обычно начиная с 105000 будут уникальные номера, чем мы и воспользуемся.
"Прочитать" локальный sql-файл можно следующей командой:
.read C:/Users/Georg/Documents/RussianMSK_WKT_PROJ.sql
Среди ошибок можно заметить совпадающее code для двух тестовых внесенных раннее СК
Или, в более сокращенном виде исполняя:
select name from projected_crs where name like '%Russia%';
В общем случае вносить новые определения можно через файл запроса или запросами поодиночке из-под консольной утилиты sqlite3.exe. Я старательно обхожу стороной подробное комментирование, так как сам не очень владею материалом "как правильно".
3. Ещё раз, как устанавливать и использовать библиотеку
3.1 Установка базы проекций
Так как библиотеку PROJ я планирую распространять для использования в CAD-программах, и многие пользователи не захотят настраивать параметры вручную - в составе библиотеки будут отечественные СК (конечно, неофициальные).
Ссылка на профиль гитхаба с релизами:
3.2 Установка библиотеки для работы с библиотекой(программно) PROJ
Оттуда же, из Releases скачиваем другой архив -- это бинарная сборка, содержащая библиотеку (dll) с зависимыми библиотеками, где "главная" для программиста библиотека -- это файл proj_functions_x64.dll. Версию для 32-разрядной либы пока не делаю, и не хочу.
Этот архив можно распаковать где угодно, нам впоследствии нужен будет лишь файловый путь к нему -- для подключения через PInvoke (DllImport).
3.3 Обращение к библиотеке через .NET-wrapper class
В составе репозитория есть класс на c# реализующий механику обращения к библиотеке. Я его упростил до поддержки только 64-битной среды.
Вот и всё - само использование включает 3 этапа:
1. Выбор класса согласно разрядности (вернее, отсеивание случаев обращение из срезы x86):
ILibraryImport lib_getting = LibraryImport.Select();
2. Получение кодов исходной и целевой СК
int source_cs = 100564;
int target_cs = 4326;
3. Преобразование
point p = lib_getting.crs2crs_tranform(32636, 4326, 346744.4475, 6648123.4632, 0.0)
И вывод как p.x, p.y
Сам выбор к слову, будет сводится к анализу списка/словаря с кодом и наименованием СК, который я положу в состав архива с базой проекций. В общем случае -- этот словарь можно легко получить sql-запросом:
select code, name from projected_crs where name like '%Russia%';
и парсингом строки по разделителю '|':
Nuget-пакет для работы с sqlite3 есть.
4. Дальнейшее использование библиотеки PROJ
Теперь, как только я определился с логикой её обновления и вычисления - будем встраивать с ребятами из TBS-Software функции по работе с системами координат в NanoCAD.
У них как раз были классные наработки по генплану в Revit, но теперь всё это можно выбросить на свалку истории как и нереализованные идеи в других продуктах Autodesk.
Не пропускайте публикации, подписывайтесь на Telegram-канал с тизерами статей.
#proj #gis #bim #coorinates #sqlite3 #nanocad