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

Если из окна видна труба завода из которой валит дым "кислотного" цвета, под другим окном оживленная автотрасса/железная дорога и летом не открыть окно из-за гари и громких сигналов транспорта, рядом с этим прелестным пейзажем видны дымок от крематория и кладбище. Когда решите выйти на балкон летом, то комары напомнят что совсем рядом есть заболоченный участок. Поздравляю, вы оказались в том самом месте!!!
Что общего во всех этих факторах, кроме того что я сгустил краски StableDiffusion? В описаном примере для многих людей есть не только экологическая, но психологически дискомфортная составляющая. В студенчестве в части диплома, связанной с экологией, были расчеты уровня шума в жилых помещениях от трассы/индустриальных объектов. Главный параметр был - расстояние по прямой от жилья.
К сожалению, объективная и структурированная информации про экологию и безопасность нового для нас места обычно не доступна. Скорее всего эти данные есть у префектуры, полиции и бизнеса которые с вами ей не поделятся. Все это уменьшит шанс на осознанный выбор нового места жительства.
Но даже без статистики по правонарушениям и без информации о реальном загрязнении воздуха мы все равно сможем избегать заведомо дискомфортных мест. К счастью, доступны геоданные OpenStreetMap.
Давайте напишем прототип запроса, по которому сможете понять где вероятнее всего вы бы не захотели жить. Хоть он основан на факторах, выбранных по моему личному мнению и они могут не совпадать с вашими предпочтениями. Можете изменять SQL запрос так, чтобы геоаналитика была больше похожа на ваш кошмар! И конечно же применим его к доступным для столицы геоданным и визуализируем их на карте.
Перед тем как начнем
Если не планируете воспроизводить процесс подготовки данных самостоятельно, то смело пропускайте следующий текст и пролистывайте до заголовка "Анализ данных для Москвы".
Подготавливаем данные для анализа
Этот раздел предполагает что вы знаете как работать с PostgreSQL и Linux. Я выполнял следующие шаги на Ubuntu, где установлены git, wget, docker.io
Скачиваем OSM геоданные сайта geofabric и извлекаем данные Москвы по полигону Russia_Moscow.poly.
mkdir moscow && cd moscow
wget https://download.geofabrik.de/russia/central-fed-district-latest.osm.pbf
wget https://raw.githubusercontent.com/mapsme/omim/master/data/borders/Russia_Moscow.poly
docker run -rm -it -w /wkd -v $(pwd):/wkd mschilde/osmium-tool osmium extract --polygon Russia_Moscow.poly central-fed-district-latest.osm.pbf -o moscow.osm.pbfГотовых выгрузок, к сожалению, не нашел
Данные с сайта https://download.openstreetmap.fr/extracts/russia/central_federal_district/ для столицы оказались не полные, что приводило к ошибке location for one or more nodes not found in node location index.
Загружаем утилиту openstreetmap_h3 подготовки данных OpenStreetMap для аналитики в PostGIS. Про нее я рассказывал в серии публикаций на Хабре.
Все как и раньше, с небольшими дополнениями
Во время подготовки этой статьи, я разобрался как запускать Docker in Docker для случая с openstreetmap_h3 и теперь не надо устанавливать JDK, maven. Все зависимости и сборка упакованы в докер образ. Не самое красивое решение конечно, но поскольку osmium используется сейчас как утилита командной строки в виде Docker образа, а не библиотека, то оставлю как есть.
git clone https://github.com/igor-suhorukov/openstreetmap_h3.git
cd openstreetmap_h3 && docker build -t openstreetmap_h3 .
cd postgis_docker-master && docker build -t postgres15_postgis .Заходим в директорию, где подготовили moscow.osm.pbf и запускаем:
cd moscow
docker run -it --rm -w $(pwd) -v $(pwd):/$(pwd) -v /var/run/docker.sock:/var/run/docker.sock openstreetmap_h3:latest -source_pbf $(pwd)/moscow.osm.pbf -result_in_tsv trueДанные из moscow.osm.pbf будут готовы для загрузки в PostGIS в директории "moscow_loc_ways"
docker run -it --rm -w $(pwd) -v $(pwd):/$(pwd) -v /var/run/docker.sock:/var/run/docker.sock openstreetmap_h3:latest -source_pbf $(pwd)/moscow.osm.pbf -result_in_tsv true
[ 0:00] Started osmium add-locations-to-ways
[ 0:00] osmium version 1.14.0
[ 0:00] libosmium version 2.18.0
[ 0:00] Command line options and default settings:
[ 0:00] input options:
[ 0:00] file names:
[ 0:00] moscow.osm.pbf
[ 0:00] file format:
[ 0:00] output options:
[ 0:00] file name: moscow_loc_ways.pbf
[ 0:00] file format: pbf,pbf_compression=none
[ 0:00] generator: osmium/1.14.0
[ 0:00] overwrite: no
[ 0:00] fsync: no
[ 0:00] other options:
[ 0:00] index type (for positive ids): sparse_mem_array
[ 0:00] index type (for negative ids): flex_mem
[ 0:00] keep untagged nodes: no
[ 0:00] keep nodes that are relation members: yes
[ 0:00]
[ 0:00] Getting all nodes referenced from relations...
[ 0:00] Found 40919 nodes referenced from relations.
[ 0:00] Copying input file 'moscow.osm.pbf'...
[ 0:02] About 78 MBytes used for node location index (in main memory or on disk).
[ 0:02] Peak memory used: 809 MBytes
[ 0:02] Done.
0
188 time 14295
diff between total and processing 12765
total thread time 57059
total processing time 44294
total save time 4074
total waiting for save time 4120
thread max time 1024
processing max time 767
nodes 419908
ways 991744
relations 85883
relation members 875942
multipolygon count 54309
0 [-32768,4520) 10044611 37288
1 [4520,32695) 151011380 28175
2 10 80.5279955
[ 0:00] Started osmium export
[ 0:00] osmium version 1.14.0
[ 0:00] libosmium version 2.18.0
[ 0:00] Command line options and default settings:
[ 0:00] input options:
[ 0:00] file name: moscow.osm.pbf
[ 0:00] file format:
[ 0:00] output options:
[ 0:00] file name: moscow_loc_ways/multipolygon/source.tsv
[ 0:00] file format: pg
[ 0:00] overwrite: no
[ 0:00] fsync: yes
[ 0:00] attributes:
[ 0:00] type: @type
[ 0:00] id: @id
[ 0:00] version: (omitted)
[ 0:00] changeset: (omitted)
[ 0:00] timestamp: (omitted)
[ 0:00] uid: (omitted)
[ 0:00] user: (omitted)
[ 0:00] way_nodes: (omitted)
[ 0:00] output format options:
[ 0:00] tags_type = hstore
[ 0:00] linear tags: none
[ 0:00] area tags: one of the following:
[ 0:00] @type=relation
[ 0:00] other options:
[ 0:00] index type: sparse_mem_array
[ 0:00] add unique IDs: no
[ 0:00] keep untagged features: no
[ 0:00]
[ 0:00] Create table with something like this:
[ 0:00] CREATE EXTENSION IF NOT EXISTS hstore;
[ 0:00] CREATE TABLE osmdata (
[ 0:00] geom GEOMETRY, -- or GEOGRAPHY
[ 0:00] osm_type TEXT,
[ 0:00] osm_id BIGINT,
[ 0:00] tags hstore
[ 0:00] );
[ 0:00] Then load data with something like this:
[ 0:00] \copy osmdata FROM 'moscow_loc_ways/multipolygon/source.tsv'
[ 0:00]
[ 0:00] First pass (of two) through input file (reading relations)...
[ 0:00] First pass done.
[ 0:00] Second pass (of two) through input file...
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
Geometry error: Could not build area geometry
[ 0:03] About 78 MBytes used for node location index (in main memory or on disk).
[ 0:03] Second pass done.
[ 0:03] Wrote 55341 features.
[ 0:03] Encountered 39 errors.
[ 0:03] Peak memory used: 828 MBytes
[ 0:03] Done.
cat /home/user/dev/map/moscow/moscow_loc_ways/multipolygon/source.tsv | grep $'\trelation\t' | split -l 13578 - /home/user/dev/map/moscow/moscow_loc_ways/multipolygon/multipolygon_
Осталось эти данные в PostGIS. Я это cделаю в той же директории с помощью Docker, а параметры контейнера будут зависеть от конфигурации вашей системы:
docker run --name postgis15-moscow --memory=12g --memory-swap=12g --memory-swappiness 0 --shm-size=1g -v $(pwd)/database:/var/lib/postgresql/data -v $(pwd)/moscow_loc_ways:/input -e POSTGRES_PASSWORD=osmworld -d -p 5432:5432 postgres15_postgis:latest -c checkpoint_timeout='15 min' -c checkpoint_completion_target=0.9 -c shared_buffers='4096 MB' -c wal_buffers=-1 -c bgwriter_delay=200ms -c bgwriter_lru_maxpages=100 -c bgwriter_lru_multiplier=2.0 -c bgwriter_flush_after=0 -c max_wal_size='32768 MB' -c min_wal_size='16384 MB'Теперь можно подключаться любым клиентом, пароль у вас указан в POSTGRES_PASSWORD команды создания. Посмотреть статистику по таблицам, например:
PSQL_PAGER="pspg" psql -h 127.0.0.1 -p 5432 -U postgres -d osmworld
Password for user postgres:
