На прошлой неделе я решал проблему отрисовки дорог шириной более 1 пикселя. Вот как оно выглядело изначально:
Очевидные проблемы:
- Отрисовка перекрестков. На перекрестках дорог видно не соединенные между собой окончания сегментов.
- Взаимное наложение дорог. При слишком близком расположении, дороги хаотически взаимно перекрываются. Особенно это заметно, опять же, на перекрестках. Кроме того, в левом верхнем углу заметно, что сегменты двух дорог (со стрелочками) также поочередно перекрываются.
SLD обеспечивает настройку правил для отрисовки дорог с помощью LineSymbolizer:
<sld:LineSymbolizer>
<sld:Stroke>
<sld:CssParameter name="stroke">#00ff00</sld:CssParameter>
<sld:CssParameter name="stroke-opacity">1</sld:CssParameter>
<sld:CssParameter name="stroke-width">1</sld:CssParameter>
<sld:CssParameter name="stroke-linejoin">round</sld:CssParameter>
<sld:CssParameter name="stroke-linecap">round</sld:CssParameter>
</sld:Stroke>
</sld:LineSymbolizer>
Предполагается, что, управляя параметрами linejoin (miter, round, bevel) и linecap (butt, square, round), можно добиться желаемого эффекта. Например, в статье "GeoServer render OpenStreetMap" приводится реальный SLD-стиль, использующийся для отрисовки OSM. Как видно из примеров, хороших результатов удалось добиться только для мелких масштабов; при приближении становятся видны артефакты перекрестков и назойливые "сосисочные" окончания дорожных сегментов.
Продолжив поиски и поэкспериментировав с параметрами LineSymbolizer, я сделал вывод, что возможностей SLD для отрисовки таких "толстых" дорог, какие у нас были изначально (8-14 пикс.) попросту недостаточно. Уменьшив ширину до 2-6 пикселей и выставив linecap = butt, linejoin = miter, я получил такой результат:
Цвета я поменял на более близкие к Google Maps, но это не принципиально.
Кроме этого, заметил следующее:
- Для отрисовки направлений движения GeoServer в стиле tiger.sld использует TextSymbolizer, печатающий "стрелочку":
<sld:Label>
<ogc:Literal>←</ogc:Literal>
</sld:Label>
Однако, я столкнулся с тем, что стрелочка у меня непредсказуемо переворачивается (очевидно, это зависит от направления вектора, представляющего дорогу, относительно базовой точки). Поэтому направление движения я задаю с помощью LineSymbolizer, отрисовывающего стрелочку попиксельно. - Управлять порядком отрисовки дорог с помощью разных Rule внутри одного FeatureTypeStyle толком нельзя, поскольку GeoTools применяет эти правила в непредсказуемом порядке. Я вынес правило для отрисовки каждого из типа дорог в отдельный FeatureTypeStyle, после чего они стали отрисовываться в порядке, указанном в моем SLD.
На этом я пока что и остановился.