Найти тему
Хроники Георга

GDAL PROJ - готовим библиотеку к использованию в САПРах. Обновление базы определений

В первой части статьи (https://zen.yandex.ru/media/id/5d0dba97ecd5cf00afaf2938/627a2666e71a825dbd453337) мы познакомились с библиотекой PROJ, входящей в пакет утилит GDAL. Эта библиотека для расчета преобразований между системами координат используется как базовая в среде QGIS.

P.S. Оригинальное название статьи было про NanoCAD но я меняю на универсальное "САПР", так как библиотека независима от него и на практике может применяться где угодно.

В этой части я расскажу в основном про порядок ее обновления и использования в составе свой библиотеки под .NET.

Для заставки. Источник: https://en.wikipedia.org/wiki/PROJ#/media/File:PROJ_logo.svg
Для заставки. Источник: https://en.wikipedia.org/wiki/PROJ#/media/File:PROJ_logo.svg

1. Немного про программную механику взаимодействия

Прошлую часть 1 я закончил на грустной ноте, что координаты не пересчитывались для группы значений; после разбирательств, оказалось что я не верно (некорректно) реализовал Platform Invoke функцию, передавая массив символов char (на этапе отладки обнаружил, что на концах строк появлялись странные рандомные символы). Сменив логику наименований СК на числовые коды (int) проблема ушла. Вообще, я удивлен что оно сработало с int ... поскольку я морально смотрел уже в сторону таких int 😢

Варианты int по заветам C99
Варианты int по заветам C99

К слову, часть 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. На классической ОС он по умолчанию не установлен, поэтому его надо будет скачать отсюда.

Выбираем эту позицию и после скачивания распаковываем архив
Выбираем эту позицию и после скачивания распаковываем архив
Запускаем утилиту sqlite3.exe
Запускаем утилиту 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-битной среды.

В аргумент DllImport надо лишь передать директорию, куда распакована моя библиотека работающая с PROJ
В аргумент DllImport надо лишь передать директорию, куда распакована моя библиотека работающая с PROJ

Вот и всё - само использование включает 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