Duckdb в браузере и карта Москвы на github

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

Как подготовить для этого данные я детально описывал в «Где 15 минут пешком от дома до метро в Москве» «Где в Москве жить «неплохо». А в публикации «Жилье в 500 м от сетевых продуктовых магазинов в Москве.» я столкнулся со специфичным трафиком GitHub Gist с желтушных публикаций. Сообщество OSMеров предложило мне отличный вариант, когда визуализация не требует чтения исходной статьи.

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

d84fb82f1a68a8a933516716ff36e115.jpg

Карты акварелью от Stamen watercolor смотрятся отлично, не отвлекая буквами и резкими линиями. Но у этого провайдера главная загвоздка — работает на localhost, а как размещаешь на сайте — то надо платить за карту. Не мой вариант для хобби, поэтому я продолжил поиски и нашел вектрные CARTO — positron-gl-style, которые отлично подходят для отображения данных.

ee0e6bdf46ac92e29b815b9278bda285.png

Также по совету хабровчанина ограничил область отображения только теми регионом, что анализирую.

Метро и магазинов шаговой доступности недостаточно

У меня завершился расчет пешеходных расстояний в Москве для 82768 объектов представляющих интерес (point of interest) от 47324 жилых зданий, расположенных в радиусе 2 км от входов в метро и МЦК. Расчеты делал без Apache Spark, пока не замахнулся на более масштабный анализ по всему миру. Расчеты учитывают подъезды и ближайшие входы в парк, если же информации для здания и POI недостаточно, то используется центры объектов на карте. В итоге выгрузил 35 984 392 пешеходных дитанций в parquet файлы общим объемом 198Мб.

Парки, кинотеатры, магазины, школы, театры, обзорные площадки итп. Это достаточно большой объем данных для отображения на карте, тем более для статического сайта без доступа к базе данных.

Если за хостинг базы на проприетарных данных нужно платить деньги, то в случае с OSM можно перенести данные в статические выгрузки на github pages, а базу внедрить в сам браузер.

Встречайте DuckDB Wasm

Это встраиваемая колоночная база данных, которая умеет многое из того что делает ClickHouse и PostgreSQL. Этот же проект сделал кросс компиляцию базы данных на JavaScript. Сайт проекта поможет вам разобраться что же это такое.

Для меня самое главное что эта база данных полнофункциональная, поддерживает чтение сжатых parquet файлов и распространяется по MIT лицензии. Это позволило мне начать разрабатывать логику фильтрации даннных карты прямо в браузере на JavaScript. И не платить за хостинг! Цена этого в том, что производительность произвольных запросов с карт зависит от времени доступа к данным по сети.

DuckDB Wasm — новая технология, по сравнению с SQLite это более приспособленная для аналитических запросов база данных, при этом обладающая почти всеми плюсами встриваемой базы данных.

Например так я извлекаю данные о негативных факторов для отображения как GeoJSON на карте:

const stmt = await conn.prepare(
`select distinct type||id id from 'https://igor-suhorukov.github.io/data/direct_distance.parquet' where (category='_air_quality' and distance<=?) or (category='_noisy_place' and distance<=?) or (category='_industrial' and distance<=?) or (category='_dangerous' and distance<=?) or (category='_mosquitoes' and distance<=?) or (category='_sad_place' and distance<=?)`
);

    const ecologyMetrics = await stmt.query(
        document.querySelector('#_air_quality').value,
        document.querySelector('#_noisy_place').value,
        document.querySelector('#_industrial').value,
        document.querySelector('#_dangerous').value,
        document.querySelector('#_mosquitoes').value,
        document.querySelector('#_sad_place').value
      );

    var newGeo ={"type": "FeatureCollection", "features": []};
    for(const id of ecologyMetrics.toArray().map((row) => row.toJSON().id)){
     const building= buildings[id];
     if(building){
         building.properties.fill='red';
         newGeo.features.push(building);
     }
    }

Как будем отображать информацию о детсадах, школах и поликлиниках?

Все POI разделены на категории. В выгрузках содержатся пути к школам, коледжам/техникумам и институтам, разным курсам и тренингам. Так же как и все что связано с детьми — детские сады, игровые площадки, панда парки, зоопарки есть в детальной информации.

Может кто нибудь из вас сталкивался с Open Source проектами на JS/HTML, отображающими карточки с детальной информцией из OSM для POI?

Поскольку целевая аудитория моих публикаций сейчас — это программисты и OSMры, то начнем с простого интерфейса, в виде запросов в поле «Что ищем:» amenity='school' and distance < 500 выводит жилые дома ближе 500 м пешком от территории школ. Как сформирую список типовых запросов, то сделаю выбор интересующей информации прямо в интерфейсе.

Итог

Интерфейс «Москва, где мне комфортно» позволяет регулировать дистанцию и отображать данные как по негативным факторам, так и по позитивным. Карта доступна по адресу https://igor-suhorukov.github.io и является моим субъективным методом поиска жилья в мегаполисе на основе открытых геоданных.

Благодаря OpenStreetMap + PostgreSQL живем во время, когда можно самостоятельно расчитать и перепроверить геоданные на ноутбуке. Раньше это требовало бигдаты и бюджетов на аналитику и доступа к API расчета маршрутов за деньги… Теперь хватает open data + open source. Уверен, что через пару лет ChatGPT сможет выдать ответ на любой вопрос пользователя по геоаналитике, сформировав и отправив SQL запрос к гео данным.

© Habrahabr.ru