README.md

Geotools

Эта библиоткека для работы с координатами вынесена из кода репозитория Кропива-FireFly. Она же есть и в репозитории Кропива-Мапа (но переменные, которые пока еще не обфусцированы, имеют другие имена).

Задачи, которые еще предстоит решить, находятся здесь

На данный момент деобфускация кода до конца не завершена. Тем не менее минимально неоходимый функционал по конвертации координат между системами WGS84, УСК2000 и СК42 работоспособен.

Добавлена поддержка трансформационной сетки в формате NTv2 (файлы с расширением *.gsb). Реализованы несколько вариантов загрузки трансформационных сеток NTv2:

  • в виде предзагруженного сериализованного класса NTv2GridShiftFile в качестве ресурса jar-библиотеки (этот файл с данными моментально утяжеляет миниатюрную библиотеку на 61Мб, поэтому в процессе сборки создаются “тяжёлая” и “лёгкая” версии библиотеки - соответственно с трансформационной сеткой и без неё в ресурсах);
  • из любого внешнего потока (InputStream) - из файла на устройстве, SD-карты, базы данных и т.д.;
  • из внешнего RandomAccessFile файла

Перевод координат из системы координат УСК2000 в СК42 и обратно производится исключительно на основе трансформационной сетки. До тех пор, пока трансформационная сетка не загружена или за пределами загруженной сетки координаты УСК2000 и СК42 полностью совпадают, поскольку при отсутсвии данных по трансформации смещения принимаются нулевыми.

При сборке реализовано создание двух артефактов:

  • geotools-full-x.x.x.jar : “Тяжелая” (полная,full) версия может использоваться на устройствах, не имеющих проблем с доступными ресурсами - полная трансформационная сетка, покрывающая всю бывшую УССР, содержится в виде ресурсов внути jar файла. Данные трансформационной сетки загружаются в память автоматически и никаких дополнительных манипуляций для их инициализации не требуется. При этом данные сетки единовременно и полностью загружаются из ресурсов в память, тем самым расходуя не менее 61Мб.
  • geotools-x.x.x.jar : “Лёгкая” же версия может быть более подходящей для мобильных устройств, ресурсы которых ограничены. Она абсолютно идентична полной версии с точки зрения кода и отличается лишь отсутствием данных трансформационной сетки в ресурсах. Тем не менее есть возможность выбрать и загрузить трансформационные данные для любого, например, только для интересующего на данный момент участка, тем самым экономя место на SD-карте и в памяти устройства.

Git LFS

В репозиторий был добавлен исходный файл UA_and_Kiev_DZK_9m.gsb с трансформационной сеткой УСК2000<->СК42 от ГЗК (Государственный Земельный Кадастр) Украины. Файл занимает 149 224 312 байт поэтому для эффективной работы с репозиторием был добавлен Git Large File Storage (LFS), как рекомендует раздел помощи gitflic.

Внимание! Необходимо загрузить и установить это расширение для Git на вашей системе, если оно ещё не установлено. Детали установки по ссылке в разделе “Git LFS”

Уровень Java API

Java language Level (8 - Lambdas, type annotations etc.)

Обратите внимание: при сборке основанного на osmdroid пет-проекта в тестовых целях выяснилось, что некоторые использованные в коде библиотеки особенности языка из Java Level 8 (а именно лямбды) привели к необходимости использовать Android API 24 level минимум. Тем не менее, эти конструкции отсутствовали в исходном коде Крапивы и были привнесены в ходе деобфускации, чистки и рефакторинга кода для лучшего дизайна, читаемости и поддержки. При необходимости использования библиотеки в Android-приложениях, требующих более низкий уровень API это можно сделать самостоятельно самостоятельно клонировав и внеся изменения в код приложения, или обратившись с соответсвующим запросом к разработчикам данного проекта.

java {
        toolchain {
        languageVersion = JavaLanguageVersion.of(8)
        }
}

Сборка библиотеки

Для сборки требуется JDK1.8

Gradle 7.4+ испольуется в качестве сборщика

Собрать в Linux можно командой

./gradlew clean build

Собрать в Windows можно командой

gradlew clean build

Быстрый старт: примеры использования

Операции по конвертации координат между различными системами координат сосредоточены в утилитарном классе CoordTranslator. В нём же на данный момент неявно инициализируется трансформационная сетка из ресурсов jar-файла.

Для конвертации координат из WGS84 в десятичных углах (например из данных GPS) в СК42 нужно выполнить следующий код:

    // создаём объект с широтой, долготой и высотой
    // в системе координат WGS84:
    BLH blhWgs = new BLH(48.07068055555556d, 37.730361111111115d, 0);

    // получаем объект с координатами X и Y на плоскости и высотой
    // в системе координат СК42
    XYH xyhCk42 = CoordTranslator.wgsToCk42(blhWgs);
    

Если координаты WGS84 представлены в виде градусов, минут и секунд, то можно либо предварительно конвертировать углы в десятичное представление и воспользоваться кодом выше:

    // создаём объект с широтой и долготой в градусах, минутах и секундах,
    // а также высотой в системе координат WGS84:
    Degrees degreesWgs = new Degrees(
        new Latitude(48, 4, 14.45d),
        new Longitude(37, 43, 49.30d),
        0d);

    // конвертируем в десятичные углы
    BLH blhWgs = Conversions.degreesToDecimal(degreesWgs);

    // получаем объект с координатами X и Y на плоскости и высотой
    // в системе координат СК42:
    XYH xyhCk42 = CoordTranslator.wgsToCk42(blhWgs);
    

либо же сразу вызвать соответсвующий метод в классе утилите и тогда конвертация будет будет выполнена автомаически:

    // создаём объект с широтой и долготой в градусах, минутах и секундах,
    // а также высотой в системе координат WGS84:
    Degrees degreesWgs = new Degrees(
        new Latitude(48, 4, 14.45d),
        new Longitude(37, 43, 49.30d),
        0d);

    // сразу получаем объект с координатами X и Y на плоскости и высотой
    // в системе координа СК42
    XYH xyhCk42 = CoordTranslator.wgsToCk42(degreesWgs);
    

Аналогично выполняется конвертация в обратную сторону. Чтобы ковертировать координаты из системы координат СК42 в WGS84 можно выполнить следующий код:

    // создаем объект с плоскими координатами X и Y и высотой
    // в системе координат СК42:
    XYH xyhCk42 = new XYH(5327170.0d, 7405496.0d, 200.0d);

    // получаем координаты в виде десятичных углов в системе координат WGS84:
    BLH blhWgs84 = CoordTranslator.usk2000ToWGS(xyhCk42);
    
    // при необходимости можем конвертировать в форму
    // градусов, минут и секунд:
    Degrees degreesWgs84 = Conversions.decimalToDegrees(blhWgs84);
    

Для указания приблизительного местоположения по методу “улитки” можно выполнить следующий код:

    // создаем объект с плоскими координатами X и Y (XYZ или XYH)
    // в системе координат СК42:
    XY xyhCk42 = new XYH(5357462.123d, 7280307.345d, 0.0d);

    // получаем строку с координатми по методу "улитки": "5780-8"
    String snailStr = CoordTranslator.toSnail(xyhCk42);
    

Чтобы определить магнитное склонение в заданной точке по географическим координатам можно выолнить следующий код:

    // создаём объект координат в системе координат WGS84:
    BLH blh = new BLH(48.311970d, 36.036530d, 0.0d);

    // вычисляем магнитное склонение
    double magneticDeclination = Utils.INSTANCE.getMagneticDeclination(blh);

Данные по магнитному склонению описаны в классе DeclinationData. Покрывается область 44…53° с.ш. и 22…42° в.д. Сетка с шагом в 0,5 градуса. Вторая сетка содержит годовое изменение склонения. При вычислении актуального склонения используется текущая дата.

Для определения направления на магнитный север в заданной точке в системе координат WGS84 можно выполнить следующий код:

    // создаём объект координат в системе координат WGS84:
    BLH blh = new BLH(48.311970d, 36.036530d, 0.0d);

    // вычисляем магнитное склонение (в десятичных градусах)
    double magneticNorthDirection = Utils.INSTANCE.getMagneticNorthDirection(blh);

    // при необходимости можем конвертировать в форму
    // градусов, минут и секунд:
    Angle magneticNorthDirectionAngle = Conversions.degreeFromDecimal(magneticNorthDirection);

Для определения направления на магнитный север в заданной точке в системе координат СК42 можно выполнить аналогичный код:

    // создаём объект координат в системе координат WGS84:
    XYH xyhCk42 = new XYH(5327170.0d, 7405496.0d, 200.0d);

    // вычисляем магнитное склонение (в десятичных градусах)
    double magneticNorthDirection = Utils.INSTANCE.getMagneticNorthDirection(xyhCk42);

    // при необходимости можем конвертировать в форму
    // градусов, минут и секунд:
    Angle magneticNorthDirectionAngle = Conversions.degreeFromDecimal(magneticNorthDirection);

Для определения поправки буссоли в заданной точке в системе координат WGS84 можно выполнить следующий код:

    // создаём объект координат в системе координат WGS84:
    BLH blh = new BLH(48.311970d, 36.036530d, 0.0d);

    // вычисляем поправку буссоли (в десятичных градусах)
    double compassCorrection = Utils.INSTANCE.getCompassCorrection(blh);

    // конвертируем из градусов в тысячные:
    // особенность метода конвертации fromDegreesToCompassCorrectionMils в том, что он при необходимости автоматически
    // убирает "лишние обороты", а также в случае поворота более, чем на 180 градусов (3000 тыс) вычитает такой угол из
    // полного круга и меняет знак на противоположный        
    double compassCorrectionInMils = Utils.INSTANCE.fromDegreesToCompassCorrectionMils(compassCorrection);

    // форматируем тысячные в привычную строку:
    String compassCorrectionInMilsStr = FormatUtils.formatMils(compassCorrectionInMils);

Для определения поправки буссоли в заданной точке в системе координат СК42 можно выполнить следующий код:

    // создаём объект координат в системе координат WGS84:
    XYH xyhCk42 = new XYH(5327170.0d, 7405496.0d, 200.0d);

    // вычисляем поправку буссоли (в десятичных градусах)
    double compassCorrection = Utils.INSTANCE.getCompassCorrection(xyhCk42);

    // конвертируем из градусов в тысячные:
    // особенность метода конвертации fromDegreesToCompassCorrectionMils в том, что он при необходимости автоматически
    // убирает "лишние обороты", а также в случае поворота более, чем на 180 градусов (3000 тыс) вычитает такой угол из
    // полного круга и меняет знак на противоположный        
    double compassCorrectionInMils = Utils.INSTANCE.fromDegreesToCompassCorrectionMils(compassCorrection);

    // форматируем тысячные в привычную строку:
    String compassCorrectionInMilsStr = FormatUtils.formatMils(compassCorrectionInMils);
Описание

Библиотека для работы с координатами из "Кропивы"

Конвейеры
0 успешных
0 с ошибкой