История вопроса
На этой неделе у меня пошли гениальные идеи, как нам обустроить API. Ночная беседа с jekhor про проблемы отношений веломаршрутов утром понедельника конденсировалась в тикет в Rails Port, где я предложил добавить в возвращаемые объекты ссылки (тип и id) на содержащие их линии и отношения. Так редактор всегда будет знать, что точки и линии принадлежат неподгруженным объектам, и сможет предупредить пользователя перед разбиением или удалением. После обычных комментариев непонимания обсуждение перешло на технические проблемы и вопросы совместимости, и вечером на встрече рабочей группы по технологиям (EWG) мы согласились, что добавление нового тега в вывод API сломает какие-нибудь программы, вроде osmosis. Поэтому пора повышать номер версии OSM API.
В вечерней беседе после конференции промелькнула мысль, что если мы так и будем ждать от API 0.7 великого (см. список предложений и сокращённый список), он никогда не наступит. Поэтому нужно двигаться мелкими шажками: например, поправить бардак в статусах ошибок HTTP, добавить мелкие валидации, формат JSON, всё такое. На этой волне я составил список, выросший за неделю до 14 пунктов, большая часть которых решается парой запросов к базе данных (а то и вовсе парой строк кода). Задержав окончание собрания на час, мы с Мэттом Эймосом договорились, что пора делать форк, или как там добавляется новый API к серверу. Просто чтобы была площадка для экспериментов, и чтобы дать старт. Вполне вероятно, на следующей неделе будут сделаны первые запросы к ...dev.openstreetmap.org/api/0.7.
Конечно, согласившись, что изменения должны быть мелкими, я не продержался и часа, чтобы не взяться за вечную проблему API 0.6: тип объектов area. Подходов к нему было множество, хотя после ноября 2012 года, когда Jochen Topf написал заметку про области, копошение затихло. Что печально: ни один из вариантов не был идельным. Например, решение для береговых линий было только у совсем диких предложений. Не совместив в едином типе здания о четырёх стенах и береговую линию, нечего и думать о свержении статуса-кво. Пришлось подумать очень хорошо, и решение оказалось достаточно простым, похожим на предыдущие попытки, и одновременно отличающимся в деталях.
Предлагаемые области содержат списки точек для каждого из внешних и внутренних контуров: как линии, только вместо одного списка — несколько. По сути, это полигоны модели Simple Features, со всеми плюшками и ограничениями, и их преобразование в формат Shape / PostGIS будет элементарно. Недостатки — невозможность делить часть контура между областями и ограничения на количество точек — исправляет второй способ задания областей. Он похож на мультиполигоны, но наоборот: не область ссылается на линии, а линии на область. Так можно совместно одновременно редактировать одну и ту же область (привет трогавшим границу РФ), и не будет конфликтов, потому что сам объект не изменяется. Со стороны базы это не отличается от мультиполигона: всё то же отношение «многие ко многим», но без явного списка для потребителей данных. При этом все точки и линии, составляющие контуры, сортируются против часовой стрелки для внешних контуров и по часовой для внутренних: это позволяет правильно отобразить частично загруженные данные (у мультиполигонов с этим беда). В вики есть наглядный пример с картинкой, но если объяснить ещё проще, вместо полигонов будут костлайны. Вопрос «делать Онежское озеро мультиполигоном или костлайном» отпадёт автоматически.
Одного видения для внедрения типа area недостаточно: нужно продумать алгоритм миграции базы данных, написать новые api и страницы для Rails Port, обновить cgimap, сделать поддержку в каком-нибудь редакторе (и, боюсь, level0 недостаточно) и в каком-нибудь рендерере (хоть osmarender). Написать сотню тестов и убедить всех, что идея работает. Только после этого, когда мутный поток «а вот я бы сделал так» иссякнет, а форк будет готов к пул-реквесту, вопрос «а не сделать ли нам тип area вот так» приобретёт достаточный вес. Право, лучше не мучаться, а ограничиться для нового API правкой статусов ошибок, мелкими валидациями и парой новых запросов к базе данных.