Первая линия: насколько магазин стоит в проходном месте?

Первая линия: насколько магазин стоит в проходном месте?

Глеб

Коротко: код по расчёту betweenness centrality здесь, по индивидуальному расчёту взвешенных скоров здесь, под расчёт "как надо" пока виртуалку не выбил, поэтому беру замену из классов дорог ОСМ; карта, на которой можно посмотреть результаты трёх методов расчёта - здесь; скажите мне, какой из методов вам нравится больше и как бы вы его изменили / дополнили


Задача бьётся на 2 этапа:

  1. определить "центральность" графа улично-дорожной сети (дальше УДС)
  2. присудить точкам ПВЗ степень центральности в зависимости от того, как далеко она находится от рёбер графа + есть ли что-то (дом, "неважная" дорога) на её пути и т.д.


Этап 1 - определение центральности графа УДС

пробовал 2 подхода:

А. Расчёт betweenness centrality (в методике space syntax это называется choice) - это когда мы в грАфе строим кратчайшие пути изо всех рёбер во все и ранжируем "центральность" в зависимости от количества кратчайших путей, пролегающих через то или иное ребро - так в любом городе всегда подсвечиваются ключевые магистрали - они-то нам и нужны!

Б. Извлечение меры центральности из свойств графа в открытых данных OSM: в значительной части мира дороги из графа OSM размечены по классам - их можно использовать как прокси меры центральности

у нас здесь в основном: primary, service, footway


1А. Расчёт betweenness centrality


технические параметры (не геозадротам - пропустить до следующего пункта):

код лежит здесь, инструкция по запуску - здесь
пробовал выгружать весь граф через geofabrik и через osmnx (graph_from_polygon). Проблема и там и там - граф слишком большой, поэтому:
в первом случае я делил на сетку h3 6 разрешения (опытным путём выяснил что свойства графа не теряются именно на этом разрешении), делал буфер в x3 ребра гекса (10км) от центроида, клипал граф по этому буферу, и считал его edge_betweenness_centrality - таким образом мы считаем "локальную" центральность, но при этом даём графу контекст за пределами гекса (после подсчёта складываю рассчитанное только внутри гекса - не весь буфер)
во втором случае брал буферизованые на 10 км административные полигоны, polyfill-ил их гексами 6 разрешения, для каждого гекса от центроида также давал буфер и индивидуально выгружал через ox.graph_from_polygon. Да, есть оверхэд - у нас пересекаются выгружаемые части графов, но сразу загружать граф на, скажем, весь Казахстан было очень долго (если вообще возможно), а писать логику укрупнения гексов, чтобы загружать граф и потом их назад дробить - я и так уже перемудрил, решил тут не париться
считал через momepy.betweenness_centrality. Считал именно через edge (можно ещё через узлы - весь расчёт в momepy делается через networkx + есть прикрученная возможность для узлов считать по локальному радиусу, но когда попробовал усреднить значения узлов на рёбра - получилась каша:
network_type='drive' + усреднение с узлов по рёбрам == беее!
сэмплировать можно; на network_type='all' разницы между полным расчётом и сэмплом к=1000 разницы почти не увидел:
Полный расчёт
sub-sample 1000 рёбер
рассчитано по узлам, усреднено на рёбра; в целом выглядит ок, но часть деталей (важность набережной конкретно в этом примере) теряются
В итоге параметры такие: считаем edge_betweenness_centrality, network_type='all', k=1500


1Б. Извлечение меры центральности из OSM

здесь тупо делаю словарик, где каждому виду дорог экспертно присваиваю балл (чем выше - тем важнее дорога; детальное описание здесь):

от классов - к важности ("центральности") дорог


Этап 2 - от графа к точкам

С графом определились - супер; как нам от этой абстракции прийти к простому ответу - магазин в проходном месте или нет?

-- А в чём, собственно, проблема, шеф?

а проблемы могут быть вот какие:

  • стоит рядом с проходным местом, но фасад обращён от дороги во двор
  • стоит нормально, но точка ПВЗ проставлена неверно
  • то, что будет считаться второстепенной дорогой в крупном городе - будет главной в небольшом поселении
  • сравнивать центральность одного пвз с центральностью других пвз поблизости может быть опасно - что если они все хреново расположены, а наш чуть менее хреново чем остальные? метрика должна быть в этом смысле абсолютной

Попробовал 3 метода:

А. тупо дать точке меру центральности ближайшего ребра

красная дорога дальше, поэтому присуждаем пвз балл чёрной дороги


Б. нарезать вокруг точки 3 кольца, посчитать средний балл важности от длины всех рёбер и с затуханием (чем дальше дорога - тем меньше весит) посчитать взвешенное


В. найти в радиусе Х от пвз самую важную дорогу, построить до неё кратчайшую линию, посмотреть на 2 вещи: что мы пересекаем (дороги, здания) + насколько эта линия оказалась длинной

кружочек - пвз, красным - пересечение полигона дома, зелёным - пересечение линии дороги



2А. Центральность ближайшего ребра

частотное распределение: от низких (красных - проходных) к синим - непроходным
чё-то совсем не то
место - почти проходное, а мы ему самый низкий балл присуждаем

Короче, вердикт - первый вариант совсем не подходит


2Б. Нарезные кольца

плохо: мы в (относительно) проходном месте, а скор у точки средний
Хорошо: мы в удалении от дорог, и скор низкий
проходное место, скор высокий - всё в порядке

Вывод - ок, но можно лучше


2В. Линия к главной дороге поблизости

каждое кольцо - 100 метров: в итоге решил искать главную дорогу в радиусе 300м

I. В радиусе 300м нашли дороги с ближайшим скором

II. Построили до них одно кратчайшее ребро из ПВЗ

III. Посмотрели, как пересекается со зданиями и дорогами

IV. Присвоили финальный скор: без пересечений 1м = 1 балл, пересекает здание 1м = 3 балла, пересечение одного ребра дороги = 5 баллов

Раньше считал всё в equidistant projection (epsg:4087) - она сохраняет дистанции, но искажает направления - в итоге стал для каждого ПВЗ приводить к локальному UTM (epsg:326xx) - из-за этого кратчайшая линия ищется более точно
красным - старый кратчайший путь, чёрным - новый


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

частотное распределение: от низких (красных - хороших) к синим - плохим
пространственное распределение (напоминаю: синий - плохо, красный - хорошо): кое-где складываются кластеры
хороший пример: близко к красной дороге, почти без пересечения с домом, одно пересечение с дорогой
пример "плохой" точки: оранжевая дорога - ближайшая крупная, до неё переть очень долго

Какие тут потенциальные могут быть проблемы?

за пределом 300 метров у нас полная амнезия: если мы представим себе огромный квартал 600х600 только с "маленькими" дорогами (пешеходные, вело, автобусные), и наш пвз расположен в центре этого квартала - мы оценим этот ПВЗ как идеальный, потому что главной крупной дорогой будет скор 3, и мы будем очень близко к нему расположены


Выводы

Пока остановился на третьем - по взвешенной линии - но мне нужны ваши комментарии и предложения


Как смотреть и критиковать?

Идёшь на карту, включаешь разные слои и сравниваешь: где хорошо, а где плохо

управление слоями


Куда это идёт?

пойдёт в тарифы - есть два пути:

  • считать заранее (в гексах) и использовать как коэф для тарифа - ОЧЕНЬ дорого, не хотелось бы
  • считать постфактум - не должно быть супер-долго, но каждая точка может занимать секунду-две

Report Page