OpenStreetMap logo OpenStreetMap

dkiselev's Diary

Recent diary entries

Конвертируем OSM в другие форматы

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

Выгрузки

Если вам нужна область среднебольших размеров, можно воспользоваться готовыми выгрузками гислаба, геофабрики.

Выгрузки - это отлично но, иногда вам нужен другой набор атрибутов или другой набор слоев данных. В общем что делать если возникло желание сделать выгрузку самому.

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

Qgis

В кугис есть возможность импортировать данные osm но с некоторыми оговорками. Основная проблема - отсутсвие поддержки мультиполигонов. Можно конечно импортровать границы как линии и полигонизировать их. Но это муторно.

Gdal

Следующий в списке - gdal. Если у вас стоит Qgis скорее всего у вас установлен и gdal. Среди поддерживаемых этой прекрасной библиотекой форматов есть и osm. http://www.gdal.org/drv_osm.html

У меня не получилось конвертировать osm сразу же в набор shape файлов или geojson, возможно это мжно сделать если отредактировать файл с настройками импорта osm для gdal. Но можно сделать и по другому.

geopackage

На первом этапе конвертируем osm в geopackage:

bzcat osm.xml.bz2 | ogr2ogr -f GPKG osm.geopackage /vsistdin/

Затем открываем его как источник данных в qgis, кнопка называется “добавить векторный слой”. Там просто выбираем наш osm.geopackage остальное qgis сделает сам. В сгенерированном geopackage’е будет 5 или 6 слоев. С полигонами/мультиполигонами, веями, точками, веями собранными из отношений маршрутов, и слой с прочей геометрией из других отношений.

Фильтрация и экспорт

Теперь отфильтруем данные, например домики с адресами. В слое с мультиполигонами есть поле building но нет addr:housenumber. Открываем свойства слоя, в источнике данных добавляем фильтрацию “building” = yes. Вообще geopackage это определенным образом структурированный файл spatiallite (sqlite) то-есть, можно работать с ним как с базой данных.

Остальные теги так же записаны, но простым текстом, поэтому придется их разбирать. Формат записи: "key"=>"value", "key2"=>"value2" (Это постгрешный hstore)

Чтобы получить например подписи к зданиям, можно использовать выражение

regexp_substr(more_tags, '"addr:housenumber"=>"([\\d]+)"')

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

Дальше полученный слой можно сохранить в любом понравившемся вам формате.

Итоги

Не сказать чтобы способ всем хорош, либо куча ручного труда, в прочем с постоянным визуальным контролем, либо надо писать конфиг для gdal либо скрипты. Это не так сложно но пока вы готовите данные придется постоянно перенарезать данные.

Тоесть постоянно запускать ogr2ogr ждать пока он перенарежет все слои, потом открыв это в qgis вы понимаете что что-то забыли и вам надо снова все повторять. Если импорт разовый и вы не планируете как-то это автоматизировать, то проще “нарезать” нужные слои с атрибутами в qgis.

Что нам делать с мультиполигонами

Posted by dkiselev on 18 January 2016 in Russian (Русский). Last updated on 22 January 2016.

По традиции, стоило бы конечно обсудить адреса, но займемся мультиполигонами.

Что вообще не так с мультиполигонами и зачем с ними что-то делать?

  1. У нас невозможно определить попадает точка внутрь полигона или нет не скачав весь полигон и не восстановив его геометрию. Для shp например это возможно, т.к. задан порядок обхода точек. Соответсвенно если вы загрузили кусочек границы в некотором прямоугольнике, то в зависимости от направления границы полигона из шейпа, вы можете сказать какая часть прямоугольника лежит в полигоне, а какая снаружи. Соответсвенно можете делать соответсвующую заливку или отрисовать границу с отступом вовне полигона. Можете более ли менее уверено сказать лежит ли у вас свеженарисованый домик внутри полигона. Напоминаю что все это для частичнозагруженого полигона. Тоесть если в осм вы скачаете кусочек границы крупного озера, вы не сможете сказать с какой стороны от линии вода а с какой суша, а в классических гео-форматах это делается легко, т.к. для всех линий действует простое правило: Если построить вектор из точки N к точке N+1, то точки принадлежащие внутренней части полгона будут лежать слева. (Для некоторых форматов справа, но направление обхода не меняется в рамках формата) http://gis.stackexchange.com/questions/119150/order-of-polygon-vertices-in-general-gis-clockwise-or-counterclockwise#119156

  2. Хорошо, допустим мы скачали весь мульти-полигон. И хотим построить его представление укладывющееся в SimpleFeatures https://en.wikipedia.org/wiki/Simple_Features (А если мы хотим использовать опыт накопленый другими поколениями программистов - мы обязательно захотим это сделать). Какие проблемы у нас возникнут:

    2.1. Мы не можем заранее сказать уложится ли наш объект в SimpleFeatures Polygon или нам понядобится SimpleFeatures Multypoligon. Напомню что SimpleFeatures Polygon это многоугольник с n дырок, где n >= 0. А мультиполигон в SF это коллекция полигонов. Т.е. если у вас 1 внешний контур и много дырок в SF достаточно полигона, если же у вас несколько внешних контуров а внутренних нет совсем, в SF понадобится мультиполигон. В принципе это не доставляет прям больших неприятностей, но стоит об этом помнить.

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

    2.3. Собраные кольца приходится сортировать, чтобы посчитатькакой из инеров в какой из аутеров попадает. Тут еще могут попадаться аутер островки внутри иннеров.

    2.4. Теперь то что мы слепили из отношения надо проверить на валидность (желательно сразу допилив до валидного состояния). Например надо объединить пересекающиеся иннеры. Вырезать иннеры если они пересекаются с внешней границей. и т.п.

    2.5. Ура, теперь мы можем сказать валиден ли полигон, попадает ли точка внутрь, тесселировать полигон и сделать что хотели. Но в следующий раз всю процедуру надо повторить.

Что хотелось бы сохранить (не сломать)

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

Дальше, хотелось бы сохранить ссылочную природу отношений в OSM. Тоесть если сейчас outer это ссылка на вей и то что два мультиполигона ссылаются на один вей однозначно говорят о том что у этих полигонов общая граница и эта общая граница включает этот вей.

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

Что выходит за рамки этой оптимизации.

Мы никак не упрощаем разрешение ссылок. Т.е. мы не упрощаем поиск ноды по ее id при получении геометрии линии и получение линии по id.

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

Я напомню что у нас osm.xml упорядочен по типу, id т.е. в начале идут все ноды упорядоченные по id потом все веи потом все релейшены. pbf который считают спасением от всех бед связанных с чтением osm ничем не лучше. id lat и lon напомню хранятся в osm.pbf в condensed записи, это значит что вы должны прочитать знать значение предыдущего id lat и lon чтобы вычислить текущий. Т.к. кодируется смещение относительно предыдущей координаты. Так что xml в некоторых случаях будет прочитать проще и быстрее чем pbf.

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

Второй способ читаем файл как привыкли, строим индекс id ноды - координаты для всех точек потом ищем сред них при построении линий. Естественно быстрее всего выходит когда этот индекс влезает в память.

Что уже предлагалось:

  1. Multyring
  2. Писать в роль отношения сразу координаты

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

Второй вариант так же не поддерживает ссылочность хотя и позволяет обрабатывать мультиполигоны быстрее при чтении из файлика. Правда такой полигон будет очень тяжело загрузить из OSM API DB всего-то надо будет распарсить текстовые роли для всех отношений мультиполигонов и посчитать попадают ли они в ббокс. Мжно использовать функциональный индекс на это дело но меинтенеры базы всеравно будут недовольны отношениями по 40 000 участников (число нод в границе РФ). А, да, еще одна приятная мелочь - построить полигон из облака точек.

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

Нам надо дополнить текущие мпшники информацией 1. о кольцах, веях в них входящих, и о порядке вея в кольце 2. о правости и левости веев

Так же нам необходимо знать, актуальна ли эта информация. Актуальность поддержать довольно легко. При сохранении дополнительной информации нам надо записать версии веев и самого отношения. Соответсвенно при обработке мультика можно будет проверить совпадают ли версии объектов или нет.

Как дополнить схему

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

Правые и левые веи, проверка актуальности дополнения.

Участники будут входить в отношение дважды:

  • Первый раз как раньше с ролью inner или outer.
  • Второй раз как outer:ring0:rp4:right:v5 где

  • ring0 - номер кольца (0 используем для наибольшего из колец)
  • rp4 - позиция в кольце (четвертый в нулевом кольце)
  • right - правый/левый
  • v5 - использованная версия вея (должна записываться с учетом того будет ли версия обновлена при записи коммита)

NB: Эти роли заполняются ботом/джосмом/id. Можно отказаться от дублирования и менять оригинальную роль, но тогда схема перестанет быть полностью обратносовместимой.

В теги самого мультиполигона записываем:

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

Иерархия колец

Остается вопрос как записать иерархию колец (какой из инеров в какой из аутеров попал).

Можно записать в теги (сразу оговорюсь что выглядеть это будет как тарабарщина)

ring0inners=2;3;4;5;6;7

где ring0 одно из колец мультиполигона, а 2;3;4;5;6;7 остальные кольца попавшие внутрь кольца 0. Для колец не имеющих иннеров - не пишем ничего. Тут возможна ситуация когда иннеров слишком много (больше 60-70 к примеру) они просто не влезут в 250 символов значения тега.

Можно через роли учстников:

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

Получится что-то вроде: outer:ring8:rp4:right:v5:up0,2 тут нам поможет то, что в большинстве случаев в аперы попадет 1 или 0 колец. В примере у меня кольцо номер 8 находится внутри колец 0 и 2. Тоесть кольцо 8 - островок внутри иннера 2.

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

Это относительно просто реализовать т.к. любой наш инструмент который умеет работать с мультиполигонами большинство вышеописаных шагов проделывет но каждый раз по новой. Так что добавить поддержку в josm и создание бота - дело пары дней.

О недостатках:

  1. Я не уверен что это вообще нужно.
  2. Мне не нравятся человеконечитаемые роли. Точнее роли и теги читаемы, но отредактировать их вручную - практически невозможно. В контексте мультиполигонов это не так уж и страшно, т.к. мультики редактируются в основном через плагинчик к джосму (или встроеный экшен для создания мультиполигона). Но всеравно это плохо.

Гуглмапс

Posted by dkiselev on 17 March 2015 in Russian (Русский).

Готовлю слайды к презенташке, заглянул на гуглокарты в моем околотке.

Капец, кто это рисовал? https://www.google.com/maps/@56.8396279,60.6433669,18z

Я даже не говорю что дороги нафантазированы. Они же кривущие, пересекают здания, проезды (дворовые) не отличимы от улиц (Малышева - так то весьма не маленькая улица).

Я конечно догадываюсь что индусы рисовали, но как этим вообще пользоваться то?

Пропозалы

Posted by dkiselev on 19 January 2015 in Russian (Русский).

Fuuuuuuu

И почему это все предпочитают обсуждать схемы тегирования тихонечко в локальном комьюнити?

Ведь это так увлекательно подбирать примеры, разрабатывать возможные варианты реализации тех или иных алгоритмов, подбирать фотки и примеры уже затегированых объектов и получать в ответ:

– Это никому не нужно.

– Я посмотрел, в моем околотке и так все хорошо.

– Твоя схема дерьмо потомучто, потомучто я так сказал!

На новый год зашла речь у кого длиннее список правок, благодаря чему я заметил на hdyc графу которую раньше не замечал. Общее количество изменений сделанных в ОСМ. Оказывается я таки миллионер.

Группы

Posted by dkiselev on 18 December 2014 in Russian (Русский).

Кстати, продолжаю хотеть группы на глагне. Даже то что называлось как альтернативы группам не изменилось[1], пулл реквест как я понимаю просто похерили.

1: Более лучшая интеграция списков рассылок, хотя как это можно назвать заменой группам я не пойму никогда

Конечно же, Паб, Бар, Biergarten принципиально отличаются дург от друга и должны обозначаться отдельно. Так же как Кафе и Ресторан, а вот детские игровые комнаты - это такая детская площадка, только в помещении и с присмотром, my ass.

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

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

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

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

osm.org

Posted by dkiselev on 1 December 2013 in Russian (Русский).

— Привет, мы хотим группы, вот пул реквест даже готов.

— Нормальные группы сделать не возможно, ваши — говно. Лучше посмотрите какой тулбар мы забубенили на главную!


— Hi, we want groups! Here is pull request.

— It’s very difficult to make a good groups. Those you have maded are sucs. Better look at the new leftside toolbar!