Обновить

Морские карты S-57 в браузере: открытый парсер на TypeScript и что в нём сломали и починили первые пользователи

Уровень сложностиСредний
Время на прочтение4 мин
Охват и читатели8.3K
Всего голосов 3: ↑3 и ↓0+7
Комментарии17

Комментарии 17

Сильно ли отличается s101 от s57? Когда то делал на qt/opengl вьювер карт s57 со стилем s52(по крайней мере, той версией, что доступна в сети, 3.0 вроде бы). Символы там описывались векторной графикой на HPGL. Тоже рисовал всë в атлас и рендерил все символы одним батчем. Самая сложная часть s52 это conditional rules, т.е. отображение, зависящее от множества факторов, типа пересекается ли данная геометрия с областью такого-то типа с таким-то атрибутом и тд.

Спасибо, приятно встретить человека, который это уже проходил))

Контейнер тот же: S-101 тоже кодируется в ISO 8211, поэтому бинарный парсер у меня общий на оба формата. А вот модель данных вроде другая. S-101 построен на S-100: каталог объектов машиночитаемый (XML), а не зашит в спецификацию; атрибуты бывают составными и вложенными; есть отдельные типы информации; геометрия описывается кривыми и поверхностями вместо узлов и ребер chain-node.

Но, кжется, для вашей боли главное отличие в отображении. В S-52 условные процедуры описаны в спецификации псевдокодом, и каждый производитель переписывал их у себя руками, как вы и делали. В S-101 их заменил Portrayal Catalogue: правила отображения написаны на луа и поставляются вместе с каталогом, символы в SVG вместо HPGL, палитры отдельно. короче есть conditional rules теперь не нужно реализовывать, их нужно исполнять. IHO выкладывает этот каталог открыто на GitHub.

Ну а у меня условных процедур почти нет. Есть заливка DEPARE по DRVAL1/DRVAL2, пока с фиксированными порогами, а не от safety contour, и цвета и секторы огней. Проверок вроде “лежит ли OBSTRN над областью глубин меньше безопасной” нет совсем. Как раз обсуждаем в Discussions на GitHub переход на символы и правила из каталога S-101 с атласом, по той же схеме, что вы описали.

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

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

Спасибо, по вашему совету уже поправил. Символы и подписи площадных объектов теперь ставятся в центр видимой части: на каждой смене вьюпорта полигон обрезается по экрану, центр считается по обрезанной фигуре, а если он выпадает наружу (вогнутый полигон или дырка), то берется середина самого широкого внутреннего отрезка. Для больших полигонов считаю по упрощенной геометрии, копия под каждый уровень масштаба с погрешностью около пикселя, и все это дело кэшируется. Лукап и приоритеты тоже теперь считаются один раз при загрузке ячейки. Правда сами условные процедуры у меня пока упрощенные, полноценные CSP с пересечениями (DEPCNT, OBSTRN, WRECKS, SOUNDG) ещё впереди, и тут ваш опыт очень пригодился бы.

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

В целом даже получается, но совсем не просто

О, круто, что кто-то этим занимается вживую))

Навионикс в S-57 это прям боль, там же своя модель данных, и все приходится перекладывать в объекты и chain-node топологию S-57. Самое неприятное, по моему опыту, это как раз топология и DDR в ISO 8211: файл вроде собирается, а читалка молча показывает пустоту.

Если хотите быстро проверить, что получилось, киньте свой .000 в демо: https://devladpopov.github.io/s57-parser/ Там сразу видно, собираются ли полигоны и не разъехались ли ссылки на геометрию. А если парсер на вашем файле сломается, пришлите, пожалуйста, мне такие кейсы как раз очень нужны для тестов.

Я тут не хотел связываться с навиониксом из-за лицензии: для себя на лодке ок, а выкладывать сконвертированные карты вроде уже нельзя.

А чем конвертируете? Через GDAL или пишете свой экспорт? И что пока самое сложное?

Привет! У меня сугубо утилитарная задача - сделать для себя навигацию по ветру для Рыбинского водохранилища для qtVlm. Это старый французский софт чтобы прокладывать навигацию по ветру, получать прогнозы погоды, AIS и тд. Похож на SAS-Planet по концепции. Разобраться в нем нет шансов сходу, интерфейс дикий, но в нем есть всеm он настраивается и работает хорошо. И отличная документация и форум, поэтому чатгпт прекрасно отвечает на все вопросы. Он работает в том числе с картами s57 (s63). Так как навионикс у меня уже есть, подумал, что бы из него не вытащить.

Мне казалось что карты должны быть зашифрованы, и я зашел издалека ))

Поставил эмулятор андроида на винду, запустил навайбкодил скрип чтоб тот ходил по карте навионикса и делал скриншоты. И в целом даже заработало, но очень долго, дня три все заняло с исправлениями и векторизацией. И это только на одно Рыбинское водохранилище.

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

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

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

Я попробовал в вашем просмотрщике посмотреть тайлы - в целом нормально видно, но местами много лишних линий, такое ощущение что он сам закрывает контуры незакрытые. У меня они норм выглядят. Могу в ТГ отправить тайлы

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

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

Файлы из Навионикса, пожалуйста, не присылайте: их лицензия запрещает извлекать и передавать данные карт, и тащить такое в открытый проект не хочу ни себе, ни вам 🙏🏻. Если лишние линии у вас останутся, пришлите просто скриншот и скажите, какие это объекты, этого хватит, чтобы разобраться.

Про qtVlm и тормоза на большом количестве ячеек: почти наверняка в сконвертированных данных нет атрибута SCAMIN, это минимальный масштаб, с которого объект показывается. Без него программа рисует все изобаты на любом зуме. В официальных картах ещё помогает разбивка ячеек по назначению (третий символ в имени ячейки, от 1 обзорной до 6 причальной): на мелком масштабе берется обзорная ячейка с редкими изобатами, на крупном подробная. Если проставить SCAMIN хотя бы изобатам и мелким объектам, qtVlm должен начать прятать их сам, тогда, по идее, и вычищать руками не придется.

Так как Навионикс не продается теперь официально, мне кажется, что на лицензию в целом можно положить.

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

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

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

Помогло сделать три комплекта карт с разным масштабом, на самой мелкой глубина и изобаты вообще убраны, только контуры берегов и островов. На средней знаки, судовой ход и только 3 м глубина. На мелкой все которые были.

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

Насколько я вижу, пока остается ошибка в просмотрщике. Таких треугольников не должно быть. Карты Навионикса хороши тем, что там можно сравнить с оригиналом, как оно правильно должно быть

Спасибо за скриншот, нашел благодаря вам еще одну ошибку (хорошо, что тут обычная карта NOAA, её легко воспроизвести). Треугольники были багом в самом парсере: в двоичных данных иногда встречается байт, который формат ISO 8211 использует как конец поля, и парсер на нём останавливался. Из-за этого пропадала часть записей и обрывались списки координат, контуры замыкались длинными хордами. На этой карте терялась примерно треть объектов. Исправил, проверил на двух десятках карт NOAA разного масштаба, после обновления страницы (Ctrl+F5) залив должен выглядеть нормально, заодно появились глубины, которые раньше терялись.

Про масштабы вы пришли ровно к тому, как устроены официальные карты: ячейки делятся по назначению, от обзорных до причальных, и программа берет ту, что подходит к текущему зуму, а не отбирает объекты из одной огромной. Так что три комплекта это правильное решение, а не костыль 💪🏻

Пс: про навионикс - ваше дело, я просто не беру такие данные в сам проект.

Проверил на своих картах - показывает и изобаты и сушу правильно теперь!

красота!

В теме абсолютно не подкован, хотел полюбопытствовать. Однако спешу сообщить, при загрузке демо-проекта (Boston Harbor) карта ужасно лагает, и каждое действие (перетаскивание, зум) сопровождается пролагом в 15-20 секунд. Оперировать такой картой просто невозможно онлайн, максимум вывести на печать. Скачивание PNG & PDF работает как надо.
Надеюсь такая проблема только с демо.

Просмотр через Open из раздела "в один клик" (catalog.html) не работает, после долгой загрузки просит скачать архив и уже открывать его.
Скачивание из блока "в один клик" (catalog.html) работает по 15кб, потом прерывается. Учитывая, что архив весит 39кб, пришлось ждать таймаута и "возобновлять скачивание" дважды. После второго таймаута загрузка повисла минут на 7, и терпения уже не хватило. Загрузку я отменил.

Не чтобы докопаться, а дабы указать на факт.
Браузер Google Chrome, геолокация МСК, без VPN.

Спасибо за подробный репорт, обе проблемы подтвердились и уже исправлены, можно проверить на том же демо (обновите страницу с очисткой кэша).

Были лаги из-за того, что вьюер перерисовывал всю карту на каждое движение мыши и каждый щелчок колеса, события копились в очередь, отсюда отставание на 15-20 секунд. Теперь во время перетаскивания и зума двигается готовый снимок карты, а полная перерисовка идёт один раз после того, как отпустили мышь. Сам рендер тоже ускорил примерно в два-три раза: объекты за краем экрана больше не рисуются, подготовка данных кэшируется, подписи раскладываются быстрее. Вроде должно лучше работать теперь.

И загрузку из каталога поправил: карты NOAA идут через прокси на Cloudflare, а его у части российских провайдеров режут, поэтому загрузка и вставала на 15 KB. Поднял второе зеркало вне Cloudflare. Если загрузка стоит 6 секунд без прогресса, вьюер сам переключается на него, а если не помогло и это, предложит скачать zip напрямую с NOAA и перетащить в окно. Прогресс теперь видно в килобайтах. Хотя вообще я не планировал делать браузер, но теперь вот придется допиливать))

Если что-то все ещё тормозит или не открывается, напишите, какая карта и что показывает строка статуса внизу, посмотрю. Спасибо!

Теперь Бостон работает, и можно его подвигать и позумить. При первом приближении катастрофически не хватает "Легенды". То есть хотя бы базового списка с условными обозначениями на карте. Также не хватает кратности зума, и ещё при зуме жёлтые круглые точки (извините, я не знаю что это) иногда смещаются от места, куда ты приближаешь, резко в сторону. Либо зум не всегда идёт в курсор, либо я чего-то не понимаю. Опять же зум - бесконечный. Я бы это ограничил. Свыше 1м на масштаб 1 к 1 - это бессмысленно, однако тут можно продолжить увеличение.


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

Спасибо! Жёлтые точки, которые прыгали при зуме - действительно проблема. В таблице кодов объектов S-57 часть кодов была сдвинута, и кабельные зоны рисовались как буи, а символ площадного объекта ставится в центр видимой части, поэтому и скакал. Заодно нашлась такая же ошибка в кодах атрибутов, из-за неё все глубины красились одним цветом, а подводные камни не показывались. Сверил обе таблицы с каталогом IHO и закрепил тестами, теперь на Бостоне видны мели, осушки и камни.

Что ещё добавил по вашим замечаниям: легенду со знаками, которые есть на открытой карте (кнопка Legend или клавиша L), масштаб 1:N с линейкой и кратностью зума внизу слева, ограничение зума на 1:1000 и предупреждение, когда карта показана крупнее масштаба, в котором её снимали.

Кнопка Download в каталоге теперь тоже качает через зеркало, как Open, так что зависать на 16 КБ не должна. Обновите страницу с Ctrl+F5 и напишите, если что-то всё ещё не так.

Так победим 8)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации