На чём можно сделать карту плотности?

Я попробовал сделать вот такую вещь: плотность улично-дорожной сети, по данным ОСМ.
http://peshemove.org/uds/

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

В итоге хочу иметь карту, где на любом масштабе цвет в точке значит плотность N метров дорог на кв. километр (агрегированные или локальные, не так уж важно).

  • Есть ли хороший плагин heatmap чтобы сразу можно было шкалу задать, и не мучаться с настройкой размытия и прочим?
  • Какой самый простой способ сделать, допустим, тайловый слой с этим?
  • Если кто хочет владеть миром, запрос sql написан, можно слой для всего мира запустить.

В любой серьёзной ГИС делается растовая карта, удовлетворяющая требованиям.
Далее уже преобразовывается нужным образом в тайловый слой.

хм… только что увидел по теме статью Twitter визуализировал обсуждение событий на Украине
там пример: http://t.co/u1xwHuoxtT powered by http://cartodb.com/

Растр для размеров города уже многовато, я поэтому-то и спрашиваю.

За твиттер спасибо большое, поизучаю!

А как иначе?
Плотность дорожной сети можно подсчитать лишь по конкретному полигону, скажем квадрату 1 км на 1 км.
Нельзя сказать чему равна плотность дорожной сети в конкретной точке, только для полигона, в котором эта точка находится.

Размер полигона нужно подобрать оптимальным для конкретных условий (но делать его заметно меньше упомянутого выше 1 кв. км явно нет смысла).

Так что как не делай, получится растр. Можно, конечно, каждый пиксель превратитить в полигон, технически получится вектор, но, по сути, останется растр.

Даже для Москвы с окрестностями выходит не более 100*100 пикселей.

Так что размер выходит совсем небольшим.

siberiano, можно собрать все линии дорог, разбить их точками через равные промежутки, построить полигоны Вороного для точек, посчитать площади полигонов, точнее доли площади полигона ко всей площади области интереса. Это как я понимаю не совсем карта плотности - но нечто близкое. Это можно сделать в векторе. Строить полигоны вороного можно самому, можно используя JTS, на нем же можно и линии порезать/упростить.

Собрать линии из осмофайлика можно через osm2shp, osm2pgsql или ручками.

У нас же не стоит задача “получить карту с распределением просто чего-то”, а более конкретная стоит - “получить карту с распределением чего-то, имеющего смысл”. Так вот, карта с распределением прощадей таких полигонов (или произвольных функций одного аргумента от них) для дорожной сети смысла не имеет.

Как минимум это неплохое приближение к карте плотностей.

Карта плотностей отвечает на вопрос сколько точек на кв. км. в данной области пространсва. Площадь полигона диаграммы Вороного отвечает на вопрос сколько кв. км приходится на 1 точку (в том смысле что расстояние от любой точки внутри полигона Вороного до точки для которой он построен меньше чем до любой другой точки учвствовавшей в построении).

То, что это приближение, это верно.
Является ли оно неплохим - вопрос дискуссионный. По моему мнению, является не то что плохим, а вообще практически негодным приближением (в общем случае).

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

Еще добавлю, siberiano не сказал как он это использовать собирается, если нужна просто картинка - то с вектором морочится смысла нет. Описанный же способ позволяет для каждой точки дороги оценить какова площадь пространства вокруг точки, внутри которой рассматриваемая точка будет ближайшей. Просуммировав веса точек составляющих линию, можно получить оценку для линии, на сколько велика территория для которой эта линия является ближайшей (не точное значение но неплохое приближение);

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

100 пикселей для Москвы - это если считать квадратами по 1*1 км. Но от каждой точки пространства можно отмерить квадрат или круг площадью 1 кв.км и посчитать для него. А можно другой площади, и пересчитать на кв. км. Так что тут очень много интерпретаций.

Тайловый слой, пожалуй, делать не буду, попробую агрегировать точки до удобоваримого количества для веб-скетча, а для картинок сделаю растр на GRASS.

Диаграммы вороного - штука интересная, только очень хитро площади там будут делиться, и карта будет смотреться рубленной, с неестественными границами (скажем, если дорога торчит углом из плотного города в поля, то угловая точка захватит много площади, и в карте будет клин низкой плотности). Может и не так, но я думаю, генерировать эти диаграммы - пока что многовато работы :slight_smile:

Нужно просто определиться, с какой подробностью вам нужна эта карта (что должно следовать прямо из конечной задачи, которую вы хотите решить построением этой карты).
Действительно, теоретически можно построить псевдо-непрерывную (как противоположность дискретной) диаграмму распределения величины плотности, скажем, с разрешением 1 метр/пиксель, обойдя всю площадь с шагом, равным разрешению, и для каждой точки посчитав длину дорог в окрестности любого типа (хотите - квадратной, хотите - круглой) любого размера, например - площадью 1 км². Что, естественно, потребует нефиговых затрат вычислительной мощности.
Но вопрос в том, нафига такая подробность нужна. Я не представляю, какую практическую пользу топикстартер собирается извлечь из этой метрики, но для каких-то иллюстративных целей должно хватить куда большей дискретности. А для красоты можно эту величину сгладить интерполяцией.

Я в этом “не в зуб ногой”, но может поинтересоваться у Pascal Neis, который сделал эту штуку. Или это не то?

Это примерно то же самое, что делал я, то есть на JS и очень странная математика там. Сделал по-другому.

http://peshemove.org/uds/

И вот эти скрипты, которыми оно генерируется. Если немного довести, можно и тайлы генерировать.
https://bitbucket.org/siberiano/postgis-raster-heatmap

[edit] переделываю, чтобы выкладывала geotiff, который можно уже в png конвертировать

Снёс в Ubuntu старый QGIS и поставил новый (http://www.qgis.org/en/site/forusers/download.html)

Слой исходных данных (точек с весами) сохраняю в таблицу. Для удобства работы в QGIS регистрирую колонку в geometry_columns (http://postgis.net/docs/AddGeometryColumn.html) - тогда программа не будет сканировать все данные из таблицы.

В QGIS делаю новый проект. Проекция - pseudo merkaartor, id 3857. Импортирую слой, при этом сразу фильтрую (в списке колонок и таблиц - жму в правой колонке и вставляю что-то вроде

st_within(st_envelope('srid=4326;line(82.7 54.7 83.3 55.3)'::geometry), geom)

(geom - имя колонки, по которой фильтрую)

Точки появляются в слое. Проверяю, получилась ли нужная проекция. Если нет - приходится пересоздавать проект и слой, иначе я не смог получить правильную теплокарту (она будет диспропорциональной, и все круги станут эллипсами).

Теперь добавляю слой heatmap, в ней выбираю нужные параметры (что является полем для взвешивания, радиус размытия и размеры точек). Если размер точек бессмысленный (то есть в моих широтах явно многовато колонок), пересоздаю проект (была выбрана другая проекция, и почему-то поменяв на ходу не получается сделать нормальную размерность теплокарт).

Для цветовой карты выбираю псевдоцвет и спектр из разных вариантов.

Для верности можно посмотреть гистограмму и выбрать так, чтобы на важном разрыве цвет резко менялся. Скажем, ниже - синее и голубое, выше - сразу зелёное и жёлтое.

Чтобы узнать значение гисторгаммы, она считает сумму в радиусе (если выбрана функция uniform, то есть простое скользящее среднее - или другое значение функции при плавном взвешивании), делённая на количество пикселей (то есть (радиус / размер пикселя) ^ 2 * pi).

После того как карта настроена, сохраняю в виде отрисованного изображения, формат tiff, потом конвертирую в png.

Разобрался с проблемами пропорций слоя. Оказывается всё зависит от слоя точек. Если он в проекции 4326, то результат будет искажённым всегда. Если же точки в псевдо-меркаторе или 900913, то пропорции получаются нормальные.

Перегенерировал слой. Теперь думаю, как бы все наши крупные города посчитать.

И ещё одна тонкость: в проекции псевдомеркатор (3756 и он же 900913) если вы указываете метры, надо умножить на косинус широты, чтобы получить реальные. То есть мой радиус 300 на 55й параллели превращается в 172. На широтах, отличающихся на 5 градусов, отличие значительное. Написал скриптик чтобы получать размеры радиуса и пикселя в зависимости от широты:

искомый реальный размер / cos(широты)