Карты для всех, даром

Zverik 26 декабря 2013 в 17:48 45,9k
Программисты — редкие люди. Мы можем сделать абсолютно всё, но интернет отвечает на это зияющей пустотой, где нужно делать абсолютно всё. Особенно если живёшь в непрофильных сообществах. Запросы со всех сторон, тут нужно подлатать, там плагинчик дописать, и никто, кроме тебя. Эта история — про один из таких пробелов, который я надеялся закрыть за неделю, и та неделя всё продолжается. В программе: дорожное строительство и велосипедисты, сайт для обмена картами лучше яндекса, осмеры без осма, архитектура плагинов в форумных движках и интерактивные карты прямо в хабре.


Пятьдесят четвёртый километр

Я интересуюсь многим. Когда-то водил пятничные ночные велосипедные покатушки, сейчас помогаю людям понять, что OpenStreetMap — лучшая карта в мире, и попутно слежу на форуме «Проектов Петербурга» за дорожным строительством в городе и области. Федеральный бюджет означает новости каждый день: там перекрыли и раскопали, тут неудобный переход возвели, ВАД снова досрочно построил идеальную развязку. Участники форума быстро освоили OSM, поэтому на карте Ленинградской области дороги открываются ровно в день перерезания ленточки, и все планы настолько точны, что распечатки OpenStreetMap висят в офисах строительных компаний.

Одно неудобно: нет карт под рукой. В городе ещё можно на словах привязаться к улицам (все знают, где Солунская улица пересекается с Тбилисской), а за городом — либо «ограничат движение на трассе с 54 по 81 километр», либо «база строителей стоит за развязкой в Скотном, шесть километров на север и один на запад»: всё непонятно. Поэтому участники фотографируют Яндекс.Карты и прикрепляют картинку. Это в лучшем случае, иначе просто дают ссылку. Расставлять точки фотографирования на карте — это вообще особая уличная магия. Фотоотчёт со стройки железной дороги от Лосева до Каменногорска я сделал на отдельном сайте, чтобы карта была под рукой, но открытость и простота инструмента поможет никому: у многих даже своей страницы нет. Нужна настоящая карта, полнофункциональная и простая.

Весной я понял, что 1) библиотека Leaflet делает встраивание карты элементарным, 2) никто, кроме меня, не напишет нормального плагина карт. Потому что главный принцип open source: кому нужно — тот и пишет. Сразу придумал формат кода. Базовая предпосылка: карты неотделимы от текста, как картинки и ссылки, поэтому они должны выражаться в обычном bb-коде, разумеется, [map]. Внутри тега через точку с запятой перечисляются объекты, выражаемые последовательностью координат. Одна пара «широта, долгота» — будет маркер, две и более через пробел — линия, первая точка равна последней — многоугольник. После координат в скобках может идти подпись. Примерно вот так:

[map]59.939,30.316(Дворцовая); 59.937,30.3127 59.9312,30.36[/map]

Целевой форум работает на движке 2006 года (то было время IE 7 и Opera 9), поэтому завязываться на него неразумно. Я решил всю функциональность, включая парсер, вынести в библиотеку на JavaScript, чтобы потом подключать её к разным движкам. Благодаря Leaflet.draw, моя работа свелась к разработке API и плагина. Дело спорилось: комментарий к коммиту от 1 октября сообщает «almost final». Но технологическая демка — одно, а промэксплуатация требует доводки: причесать и разбить на модули исходник, проверить в куче браузеров, дописать важные функции, отполировать форматы и параметры. Спустя неделю после начала разработки исходники переехали из личного svn на гитхаб, и начался необычно длинный гитхабовский streak: аж 23 дня (до этого было 5). Игра в поддержание цепочки дней увлекает: после пары недель иногда хочется просто добавить тикет, чтобы участие зарегистрировалось.

28 октября плагин установили на форум, 31 октября вышел релиз 1.0.0.



После выпуска я понял, что хранить документацию на гитхабе — не дело: как её переводить? Появился mapbbcode.org с демонстрацией библиотеки, ссылкой на плагины и, на сегодня, 80 килобайтами документации на английском и 50 — на русском языках. Библиотека, тем временем, научилась подключать проприетарные слои гуглояндекса, потому что это был второй вопрос всех администраторов (первый — «почему слой не хранится в bb-коде?»). Сразу комментарий с форума OpenStreetMap: «начиналось как инструмент ОСМа, а получится очередной гуглоплагин». ЯРОСТЬ. Добавил в релевантные классы проверку, не как гуглоплагин ли библиотеку используют. Другой осмер: «по-моему, это как-то мелочно». Всё им не так.

Формат bb-кода предусматривает расширение через параметры, и это отозвалось в библиотеке. Обработку подписей и параметров цвета, подсчёт длины линий и прореживание точек ломаных — всё можно сделать через хэндлеры. С появлением задач их API быстро перерос API для пользователей библиотеки: там и модификация объектов, и управление картой, и тонкая настройка редактора. Через них вполне реально встроить в редактор ещё один редактор, или вырезать дырки из бубликов.

Когда за полтора месяца после релиза никто не перевёл ни слова на новые языки, я заподозрил, что перевод методом пул-реквестов бесперспективен. Стащив скрипт из репозитория редактора iD, я отправил все строки на Transifex, и скачиваю их перед сборкой релиза. «Ну офигеть заживём теперь» — потирая руки, удовлетворил чей-то запрос на добавление немецкого языка в проект. Затем ещё добавил французский язык. Я ещё много могу добавить — только толку, когда даже тот немец куда-то сбежал. Видимо, проблема была не в пул-реквестах.

Сделать хотел утюг — слон получился вдруг

Пользовательские карты — это обычные строки. А что если их хранить в базе данных? MapBBCode + БД = простой сервис для обмена картами, MapBBCode Share. Исходный код карты доступен — его можно скопировать на форум или в блог. Вдохновляясь openstreetmap.ru, я сделал выдачу двух ссылок после сохранения: на просмотр и на изменение. И тут на форуме организатор московской картовстречи выложил ссылку на редактирование плана, сломав мне шаблон. Внезапно оказалось, что я написал замечательный инструмент для совместного планирования маршрутов и встреч.



Сайт анонимен и ничего не требует: зашёл, нарисовал линии с маркерами, нажал «Сохранить», получил ссылку. Чтобы не захламлять закладки браузера ссылками на редактирование, сделал вход через OAuth: полученный идентификатор хэшируется, чтобы даже администратор не знал, кто рисует карты, а API не позволяет связать хэши и карты, поэтому даже косвенное узнавание исключено. Это не гугль, который записывает в базу каждый чих: в некотором роде я захотел сделать абсолютно безопасный сервис.

Затем — кнопки импорта и экспорта. Я обожаю обрабатывать данные, поэтому сайт поддерживает около 11 основных форматов, включая CSV, GPX, GeoJSON (куда ж без него), форматы OziExplorer и HTML. В отличие от всех остальных сайтов, MapBBCode Share выдаёт абсолютно самодостаточный HTML (не считая зависимости от Leaflet): никаких ссылок на MapBBCode, никаких условий. А учитывая остальные форматы, сервис можно использовать для преобразований: CSV→HTML для визуализации таблицы, или PLT→GPX.

Ну и API. Сделав ключ ?format=raw, меня осенило в очередной раз, какой эпичный сайт я написал. У класса MapBBCode появился новый метод: банальным вызовом showExternal('divid', 'код') можно загрузить и показать внешнюю карту. Например, увидев, как здорово в OSM прорисована олимпийская инфраструктура, сделал таким образом сайт-открытку про Сочи. Во всех форумных плагинах появился код [mapid], одну и ту же карту можно вставить везде, где поддерживается код, можно её совместно редактировать, и можно скачивать трек прямо кнопкой из форума. Безо всяких <iframe>. Разумеется, исходный код сервера открыт, и плагины позволяют администратору направить запросы к себе.

Ваш плагин очень важен для нас, оставайтесь на линии

Быстро пришло понимание, что несмотря на простоту API (реально, объект с двумя методами, show и editor) и подробное руководство по интеграции, плагины для форумов никто не напишет. Первый принцип open source, вы помните. А планы наполеоновские: захватить велопитер (FUDForum), велороад (местные марафонцы, phpBB 3), форум OSM (FluxBB), веломанию (vBulletin), псковский внедорожный клуб (SMF). Позже в них вписались форумы ситигида (IP.Board) и краснодарских джиперов (PunBB). Ёлки-палки, зачем столько разных движков? Это какой-то ад.

Процесс программирования неинтересен: ну сел, ну про… 4-5 дней, получил плагин и опыт. Расскажу про системы модификаций.

Форумы делятся на два типа: которые нужно менять построчно (плагины называются модификациями и являются облагороженными диффами) и которые истыканы хуками (плагины делятся на мелкие функции, вызываемые из разных точек). Первые — ужасны. Просто мрак. Это phpBB3, SMF и FluxBB — уникальный движок, превозносимый за свою скорость, а систему модификаций рецензенты тактично пропускают. Немудрено: её нет. Совсем. Движок концептуально минималистичен, даже без кнопок bb-кода в редакторе (а для MapBBCode кнопка открытия редактора важна: пользователь не будет писать координаты руками), при этом нет абсолютно никакого способа установки расширений, кроме как лезть в дебри кода и вручную править строки. Безумие.

При этом писать плагины под другую его ветвь, PunBB, — непрерывное удовольствие. Сотня хуков, всё чисто и ясно, из минимализма следует простота, из простоты — понимание, как всё работает, и куда встраиваться. Установка плагинов элементарна: распаковать архив, нажать в панели администратора кнопку «установить». И, конечно, есть кнопка удаления, с которой у форумов первого типа проблема. Но жизнь жестока: у PunBB последний релиз был два года назад, и он медленно умирает, а на форуме FluxBB жизнь бурлит. FUDForum, тоже быстрый и с хуками, еле дышит, поддерживаемый одним человеком.

На сегодня я выпустил плагины для phpBB 2, phpBB 3 (они сильно различаются), FUDForum, PunBB и FluxBB. Ожидание: «спасибо за плагин, мы его установили и все пользуемся!» Реальность: «спасибо, но не хочу ничего трогать», «внедрю, только чуть позже», «в Грузии надписи не переведены и у треков метки времени не сохраняются, лучше по-старинке». На одном из форумов на phpBB 3 администратор с энтузиазмом начал ставить, но AutoMOD внезапно сглючил, не сумев банально скопировать файлы, и больше вестей оттуда нет. Администратор форума OpenStreetMap не отзывается. Карты никому не нужны: на строительном форуме пригодились, а велосипедистам и джиперам проще GPSies и озик.



Все платят


Где-то на горизонте маячит грааль, форум, который придаст всей этой нескончаемой работе смысл. SkyscraperCity тоже посвящён строительству, но в масштабах всей планеты. Он входит во все десятки крупнейших форумов сети. Администратор заинтересован в плагине. Одно «но»: форум, как и первая сотня других крупнейших, работает на vBulletin. А этот движок кругом закрыт: никаких исходников, никакой документации, никакого кода на форуме пользователей (!), пока не купишь лицензию (от 250$). Даже если не собираешься его устанавливать, а хочешь лишь расширить каталог плагинов. Служба поддержки отвечает односложно:

— You would need a license to get access to the vBulletin code.
— We do not offer any sort of development license, sorry.

С другой стороны множатся просьбы окучить IP.Board. Который весь такой красивый, дружелюбный и с документацией, вот только тоже платный и «извините, до свидания». Полагаю, продавцы этих движков считают, что администраторы пускай и пишут плагины, а сторонних разработчиков так мало, что ими можно пренебречь. Хотя… Наверное, это правда.

Насильное проникновение

Наконец, движок моего новостного блога «ШТОСМ» намертво закрыт. Хватит это терпеть: к чёрту руководство по интеграции, у меня за плечами 100 килобайт кода, смогу обойти и эту проблему. И смог. MapBBCode Loader — маленький скрипт, который втихую рассматривает страницу, и едва завидит bb-код карты, подключает все нужные библиотеки и превращает коды (желательно, обёрнутые в <div class="mapbbcode">) в интерактивные карты, а на кнопки с class="mapbbcode_edit" вешает редактор. По сути, это плагин для чего угодно в одну строку.

Зачем объяснять, когда можно показать? Скопируйте следующую строку в поле адреса браузера. В IE и Chrome потребуется восстановить префикс «javascript:», в Firefox нужно нажать Shift+F4, скопировать в окно и нажать Ctrl+R. Спасибо jsDelivr за отзывчивый CDN.

javascript:(function(){document.body.appendChild(document.createElement('script')).src = '//cdn.jsdelivr.net/mapbbcode-loader/1.2.0/MapBBCodeLoader.plain.js';})();

[map]56.4077,40.44374(B); 56.12384,40.38076(R ); 57.61273,39.83042(R ); 57.75955,40.9372(A); 56.31796,38.12943(H); 57.18758,39.41592(B); 56.73446,38.85856(A); 57.51117,41.23761(H); 55.7574,37.6623 58.0721,40.5286 57.439,41.3635 56.0414,40.188 55.9247,39.4626(black|); 56.9995,40.9675(A)[/map]

И победа: в штосме появились карты, а модификация для FluxBB свелась к четырём правкам: одна на загрузчик, две на bb-код и одна на кнопку редактора. Добавить карту на сайт может любой, а некоторые движки позволяют это сделать, совсем не касаясь файлов (например, phpBB 3 и, теоретически, vBulletin).

Так близко, и так далеко


(рисунок восхитительной Тани Задорожной)

Проект изнуряющ. Три месяца я каждый день, по несколько часов вечерами, закрываю тикеты библиотеки, дописываю внезапно важные функции, бьюсь с форумными движками и IE, строчу документацию на английском и перевожу на русский. Проект отъедает время у остального: фильмов, картирования, друзей, секса. Закончил одну функцию — придумал две других, написал плагин к форуму — он никому не нужен, зато трое человек попросили другой движок. Помогают версионирование и milestones: когда закрыты 90% тикетов для очередной версии, нет стимулов добавлять себе работы. Всегда нужна цель, достижение которой осязаемо и не вызывает чувства незавершённости.

Это ночью вышел очередной релиз, MapBBCode 1.2. Все важные задачи, наконец, сделаны, документация почти полна: осталось пошаговое руководство разработчика (#нозачем). Transifex ждёт переводчиков, плагины ждут администраторов. Я безуспешно борюсь с желанием утонуть в программировании, закрыть абсолютно все тикеты, покрыть все движки, включая Joomla и Drupal (битрикс?..). Разработку нельзя завершить, можно лишь прекратить, и пора заняться другими идеями, ждущими на страницах записной книжки. MapBBCode никуда не денется: я в ответе за то, что написал, и минорные версии с исправленными ошибками неминуемы, да и vBulletin рано или поздно покорится.
Проголосовать:
+99
Сохранить: