Изучение дизайна специализированной геопространственной библиотеки

Я разрабатывал введение в структуры и алгоритмы геопространственных данных. Основным препятствием, с которым я столкнулся, было создание минималистской библиотеки, которая поможет с введением. Я хотел, чтобы введение было сосредоточено на изучении принципов геопространственных вычислений, минуя любые сложности форматов данных и картографических проекций. Хотя они важны, они не обязательны для изучения принципов структур данных или алгоритмов.

Мне также не удалось найти ни одного курса, созданного исключительно для образовательных целей. Учебники охватывают использование специальных и потрясающих инструментов… для производства. Мне нужна была минималистичная библиотека, предназначенная для изучения основных свойств геопространственной информации. Я думал, что мне нужно будет построить его самостоятельно. Я попытался реализовать первую библиотеку на Python, а вторую — на Golang. Задача оказалась слишком трудоемкой, чтобы делать ее с другими моими проектами.

Меня вновь представили Shapely на работе. Я использовал Shapely пару лет назад, еще до получения степени в области компьютерных наук. Прочитав ее описание, я был очень рад, что у меня есть библиотека, которая, казалось, полностью соответствовала моим потребностям.

Shapelyбыл разработан на основе 3 предпосылок

  1. Программисты Python должны иметь возможность выполнять операции с геометрией типа PostGIS вне СУБД.
  2. Постоянство, сериализация и картографические проекции не являются основой структур и алгоритмов геопространственных данных.
  3. Python, как язык, может быть предпочтительным инструментом для науки о геопространственных данных.

Прежде чем перейти к Shapely, я хотел немного глубже изучить варианты дизайна. Пользовательские документы отлично подходят для запуска и работы, но они редко дают обзор архитектуры. Документация Shapely не является исключением. Я рассмотрел, как Shapely вычисляет евклидово расстояние между двумя точками. Я пошел по кроличьей норе, пытаясь понять структуру библиотеки.

Совет. Большинство редакторов кода позволяют переходить к определению методов с помощью ярлыков. Наведя курсор на метод в Visual Studio Code, вы можете щелкнуть правой кнопкой мыши и перейти к определению (F12).

Для вычисления расстояния между двумя точками потребовалось менее 6 строк кода:

Используя вышеупомянутый быстрый совет, я перешел к определению точки, чтобы проверить алгоритм расстояния. Класс Point не определяет алгоритм расстояния. Я копал все глубже и глубже, чтобы, наконец, понять, где на самом деле определяется алгоритм расстояния. Вот посмотрите на класс Point, обратите внимание на отсутствие каких-либо методов, кроме инициализатора или геттеров и сеттеров:

Короткий ответ: Shapely не определяет никаких пространственных алгоритмов. Он опирается на привязки GEOS.

Прежде чем вдаваться в подробности, может быть полезно ознакомиться с диаграммами классов. Я визуал, и мне нужна диаграмма, чтобы понять смысл следующих объяснений. Номера соответствуют различным разделам диаграммы с их объяснением. Интересно, что Sпожалуйстаникогда не определяет ни один из используемых им пространственных алгоритмов.

  1. Класс Point не определяет метод расстояния напрямую.
  2. Класс Point является производным от класса BaseGeometry, в котором определен метод расстояния.
  3. BaseGeometry использует свою переменную реализации (impl), чтобы отложить определение конкретного алгоритма, который должен использоваться для вычисления расстояния.
  4. Переменная реализации — это инициированная переменная класса GEOSImpl, учитывающая версию GEOS текущей среды.
  5. Переменная реализации наследует карту значений от класса BaseImpl, карта состоит из кортежей формата (Предикат, имя)
  6. Предикаты определяют вызов функции с помощью метода __call__, и в этом методе вызова они ссылаются на элемент данных fn делегирования, своего абстрактного класса.
  7. Наконец, член данных fn на самом деле является функцией, которая вызывает lgeos.methods[name], которая фактически вызывает функцию GEOS DLL.

Несколько примечаний к диаграмме:

  • Абстрактные классы имеют имена классов, выделенные курсивом.
  • Конкретные классы имеют обычный шрифт
  • Полные стрелки и линии представляют наследование
  • Полные стрелки и пунктирные линии обозначают вызовы функций.
  • Пустые стрелки и полные строки представляют состав класса.
  • Перечисление методов и переменных класса не является исчерпывающим.
  • Некоторые детали будет легче понять, погрузившись в код.
  • Понимание фабричных методов помогает понять некоторые, казалось бы, сложные конструкции.

Большая картинка

Из диаграмм вы должны помнить, что Shapely предназначен для привязки Python к библиотеке geos. Он не определяет ничего, кроме уровней абстракции для эффективного вызова функций geos.

Протянуть руку

Если вам интересно пройти кураторский и логически последовательный курс, чтобы изучить принципы тех операционных геопространственных инструментов, которые вы используете каждый день, свяжитесь с LinkedIn или Twitter (@ geosimple1)