paint-brush
Местоположение, Расположение, Местоположение! PostGIS и Heroku Postgresк@josephcaudle
681 чтения
681 чтения

Местоположение, Расположение, Местоположение! PostGIS и Heroku Postgres

к Joseph Caudle9m2024/04/16
Read on Terminal Reader

Слишком долго; Читать

Недавно я узнал, что Heroku также включает поддержку PostGIS. Лично я никогда раньше не использовал PostGIS. Я знаю несколько проприетарных конкурентов этого продукта, поэтому решил, что сейчас самое время опробовать вариант с открытым исходным кодом.
featured image - Местоположение, Расположение, Местоположение! PostGIS и Heroku Postgres
Joseph Caudle HackerNoon profile picture

Расширение Postgres для поддержки запросов к геопространственным данным

Я потерял слишком много времени, возясь с конфигурациями и сервисами только для того, чтобы развернуть вычислительный экземпляр в AWS. Иногда мне просто нужна готовая к работе среда, с которой можно поиграться и протестировать приложения и идеи. С Heroku я могу добиться этого с помощью всего лишь нескольких простых команд в CLI.


Недавно я узнал, что Heroku также включаетподдержку PostGIS . Лично я никогда раньше не использовал PostGIS. Я знаю несколько проприетарных конкурентов этого продукта, поэтому решил, что сейчас самое время опробовать вариант с открытым исходным кодом.


В этой статье я покажу вам, как запустить экземпляр Postgres с поддержкой PostGIS, работающий на Heroku. Затем я выполню несколько примеров запросов к базе данных, просто чтобы вы почувствовали, как она работает. И лучшая часть? Вы можете следить за нами и проводить свои собственные исследования по ходу дела!

Что такое ПостГИС?

Даже если вы какое-то время использовали Postgres, возможно, вы не знакомы с PostGIS. ГИС означает географическую информационную систему . В космосе есть много решений. Но что делает PostGIS приятным, так это то, что он основан на всеми любимой базе данных PostgreSQL. В дополнение ко всей производительности, которую вы ожидаете от Postgres, мы получаем полнофункциональный инструмент для хранения геопространственных данных.


PostGIS не только обеспечивает хорошее решение для хранения данных такого типа, но и может быть легко интегрирован с несколькими приложениями, которые могут использовать эти данные (например, ArcGIS и Tableau).


ТЛ; DR. Если вам необходимо обработать, сохранить или запросить данные о местоположении, PostGIS — отличный вариант для этого. К счастью, это так же просто, как добавить дополнение к приложению Heroku, чтобы запустить новый экземпляр Postgres. Итак, давайте сделаем это сейчас.

Как мы можем использовать PostGIS?

Для начала вам понадобится приложение любого размера. Затем вы добавляете экземпляр Heroku Postgres в свое приложение.

Создайте приложение Heroku

Для своей демонстрации я собираюсь создать пустое приложение.

Прикрепите надстройку Heroku Postgres

После создания приложения я могу создать надстройку Heroku Postgres. Поскольку мой примерный набор данных слишком велик для экземпляра мини-плана , вместо этого мне нужно использовать базовый план. Я могу сделать это из командной строки:

 $ heroku login $ heroku addons:create heroku-postgresql:basic -a postgis-demo Creating heroku-postgresql:basic on ⬢ postgis-demo... ~$0.013/hour (max $9/month) Database has been created and is available ! This database is empty. If upgrading, you can transfer ! data from another database with pg:copy Created postgresql-fitted-78461 as DATABASE_URL

После того как я создал базу данных Postgres, мне осталось сделать всего несколько шаговдля настройки PostGIS .

Создайте расширение PostGIS

Heroku Postgres имеет множество возможных расширений, которые мы можем установить. Чтобы перечислить их, мы можем запросить наш экземпляр:

 $ heroku pg:psql -a postgis-demo --> Connecting to postgresql-fitted-78461 … postgis-demo::DATABASE=> \x on; Expanded display is on. postgis-demo::DATABASE=> show extwlist.extensions; … address_standardizer,address_standardizer_data_us,amcheck,autoinc,bloom,btree_gin,btree_gist,citext,cube,dict_int,earthdistance,fuzzystrmatch,hstore,insert_username,intarray,isn,lo,ltree,moddatetime,pg_partman,pg_stat_statements,pg_trgm,pgcrypto,pgrowlocks,postgis,postgis_raster,postgis_topology,refint,seg,sslinfo,tablefunc,tcn,tsm_system_rows,tsm_system_time,unaccent,uuid-ossp


В списке доступных расширений видим postgis . Оттуда мы можем создать расширение.

 postgis-demo::DATABASE=> CREATE EXTENSION postgis; CREATE EXTENSION


Мы можем подтвердить, что расширение установлено, и проверить версию:

 postgis-demo::DATABASE=> SELECT postgis_version(); -[ RECORD 1 ]---+-------------------------------------- postgis_version | 3.4 USE_GEOS=1 USE_PROJ=1 USE_STATS=1


Хорошо! Похоже, мы уже работаем с PostGIS 3.4.

Загрузите исходный набор данных

Теперь, когда у меня включено расширение PostGIS, мне нужно загрузить набор данных, чтобы с ним поиграться. Я использую набор данных, предоставленный книгой «Введение в PostGIS» . Загруженный пакет данных представляет собой zip-файл размером 21,5 МБ. В подпапке data извлеченного архива находится файл размером 9,5 МБ с именем nyc_data.backup .


Это файл со всеми данными переписи населения Нью-Йорка 2000 года, а также со всеми улицами, районами и станциями метро города.


Мы можем восстановить резервную копию данных непосредственно в нашем экземпляре Heroku Postgres , используя команду Heroku heroku pg:backups:restore . Это невероятно удобно. Однако имейте в виду следующие предостережения:


  • Файл резервной копии, из которого вы можете восстановить, не может быть загружен с вашего локального компьютера. Он должен быть доступен онлайн. К счастью, я нашел репозиторий GitHub , в котором доступен nyc_data.backup .


  • Восстановление базы данных начинается с полного сброса вашего экземпляра Heroku Postgres, включая установку расширения postgis . Итак, хотя выше мы показали, как установить расширение вручную, нам нужно будет добавить флаг при восстановлении нашей базы данных, чтобы предварительно установить расширение перед загрузкой данных.


Вот команда, которую мы будем использовать для восстановления резервной копии базы данных:

 $ heroku pg:backups:restore \ https://github.com/Giorgi/PostgresSamples/raw/main/nyc_data.backup \ -e postgis \ -a postgis-demo

Наш файл резервной копии указан через общедоступный URL-адрес. Вы всегда можете загрузить набор данных из руководства по PostGIS, извлечь файл nyc_data.backup и опубликовать его в Интернете в выбранном вами месте.


Флаг -e postgis указывает, что мы хотим установить расширение postgis до загрузки схемы и данных резервной копии.


Вот и все! Неплохо для нескольких простых команд. У нас есть база данных и данные.

Почему Хероку?

Если вы уже знаете, как настроить Postgres на локальном компьютере, вам может быть интересно, почему я выбрал Heroku. Для меня главная причина — простота. Помимо выбора достаточно большого плана Heroku Postgres для анализа, который я планирую выполнить, и установки расширения PostGIS, мне больше ничего не нужно делать, чтобы приступить к работе.


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


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

Работа с ПостГИС

Теперь давайте посмотрим, как работает PostGIS.

Работайте так же, как с Postgres

Первое, что следует помнить, это то, что PostGIS — это расширение Postgres. Это означает, что вы также можете выполнить любой стандартный запрос Postgres.


Допустим, я хотел узнать, сколько улиц в Нью-Йорке начинаются с буквы B. Простой запрос SQL скажет мне:

 postgis-demo::DATABASE=> SELECT count(*) postgis-demo::DATABASE-> FROM nyc_streets postgis-demo::DATABASE-> WHERE name LIKE 'B%'; count 1282 (1 row)


А как насчет количества кварталов в каждом районе? И снова простой SQL-запрос:

 postgis-demo::DATABASE=> SELECT boroname, count(*) postgis-demo::DATABASE-> FROM nyc_neighborhoods postgis-demo::DATABASE-> GROUP BY boroname; boroname | count ---------------+------- Queens | 30 Brooklyn | 23 Staten Island | 24 The Bronx | 24 Manhattan | 28 (5 rows)

До сих пор мы только что сделали стандартный PostgreSQL. Теперь давайте посмотрим, как использовать возможности PostGIS.

Примеры работы с геопространственной геометрией

Поскольку наш набор данных включает все улицы Нью-Йорка, мы можем узнать, сколько километров улиц в городе, с помощью этого запроса:

 postgis-demo::DATABASE=> SELECT Sum(ST_Length(geom)) / 1000 as street_length FROM nyc_streets; street_length -------------------- 10418.904717199996 (1 row)


Мы также можем вычислить площади, например, площадь всего Манхэттена:

 postgis-demo::DATABASE=> SELECT Sum(ST_Area(geom)) / 4047 as acreage FROM nyc_neighborhoods WHERE boroname = 'Manhattan'; acreage ------------------- 13965.32012239119 (1 row)

Обратите внимание, что эти расчеты основаны на геопространственных данных, а не на столбцах, связанных с агрегированными данными такого типа. Мало того, эти запросы выполняются чрезвычайно быстро.


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


На основе названия метро (в nyc_subway_stations ) мы запрашиваем район (в nyc_neighborhoods ), для которого значение ST_Contains истинно. Наш запрос выглядит следующим образом:

 postgis-demo::DATABASE=> SELECT subways.name AS subway_name, neighborhoods.name AS neighborhood_name, neighborhoods.boroname AS borough FROM nyc_neighborhoods AS neighborhoods JOIN nyc_subway_stations AS subways ON ST_Contains(neighborhoods.geom, subways.geom) WHERE subways.name = 'Broad St'; subway_name | neighborhood_name | borough -------------+--------------------+----------- Broad St | Financial District | Manhattan (1 row)

PostGIS предоставляет еще более продвинутые функции запроса местоположения с помощью геометрии , но это выходит за рамки нашей простой демонстрации.

Заключение

Никогда раньше не использовавший PostGIS, я действительно впечатлен тем, на что он способен. С этой базой данных я мог бы сделать гораздо больше, поскольку я прочел только половину официальной книги «Введение в PostGIS» . Мало того, я могу создавать и развертывать приложения поверх PostGIS, используя любое количество языков, поддерживаемых Heroku.


В частности, я думаю, что, возможно, мне захочется найти вариант использования для создания приложения Rails поверх PostGIS. Я уже нашел некоторую документацию о том, как мне начать.


Но на данный момент этот экземпляр мне больше не нужен, поэтому я собираюсь его очистить и удалить свое приложение. Из CLI мне нужно сделать следующее:

 $ heroku apps:destroy postgis-demo ▸ WARNING: This will delete ⬢ postgis-demo including all add-ons. ▸ To proceed, type postgis-demo or re-run this command with --confirm postgis-demo > postgis-demo Destroying ⬢ postgis-demo (including all add-ons)... done

Подожди, это все? Да, это все. Одной командой и подтверждением все сносится, и мне больше не нужно об этом беспокоиться.

 $ heroku apps You have no apps. $ heroku addons No add-ons.

Теперь, когда я удалил свое приложение, у вас появилась невероятная возможность: уникальное имя приложения postgis-demo доступно первому читателю, который захочет загрузить его на Heroku! Готовы ли вы создать свое следующее великолепное приложение PostGIS? Сегодня день!