Данная статья, надеюсь, будет полезна людям, которые столкнулись с необходимостью написания SLD схем в Geoserver. SLD это язык разметки на основе XML. В данной статье я затрону только линейные объекты, возможно в дальнейшем будет время рассказать про площадные объекты. Сразу скажу, что данную информацию можно также прочитать в документации Geoserver, но есть нюансы, касающиеся новых версий Geoserver (здесь мы рассматриваем 2.23.2).
Прежде чем перейти непосредственно к самим SLD схемам, хотел бы сразу сказать, что Geoserver не дружит с кириллицей под Windows. В Linux такой проблемы нет. Использовать английский язык или ставить виртуальную машину с Linux - решать Вам.
Итак, у нас имеется некая линейная геометрия в Geoserver (допустим это геометрия для условного знака железная дорога).
Данный условный знак имеется как пример в документации Geoserver, но в последних версиях программа не распознает код, предоставленный в документации из-за того, что в новых версиях Geoserver используется версия SLD 1.1.0. Код предоставленный в документации к Geoserver подходит для версии SLD 1.0.0 и требует небольших изменений синтаксиса.
Код для старых версий:
<FeatureTypeStyle>
<Rule>
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#333333</CssParameter>
<CssParameter name="stroke-width">3</CssParameter>
</Stroke>
</LineSymbolizer>
<LineSymbolizer>
<Stroke>
<GraphicStroke>
<Graphic>
<Mark>
<WellKnownName>shape://vertline</WellKnownName>
<Stroke>
<CssParameter name="stroke">#333333</CssParameter>
<CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</Mark>
<Size>12</Size>
</Graphic>
</GraphicStroke>
</Stroke>
</LineSymbolizer>
</Rule>
</FeatureTypeStyle>
Рабочий код (для версии SLD 1.1.0) этого условного знака будет выглядеть так:
<se:Rule>
<se:LineSymbolizer>
<se:Stroke>
<se:SvgParameter name="stroke">#333333</se:SvgParameter>
<se:SvgParameter name="stroke-width">3</se:SvgParameter>
</se:Stroke>
</se:LineSymbolizer>
<se:LineSymbolizer>
<se:Stroke>
<se:GraphicStroke>
<se:Graphic>
<se:Mark>
<se:WellKnownName>shape://vertline</se:WellKnownName>
<se:SvgParameter name="stroke">#333333</se:SvgParameter>
<se:SvgParameter name="stroke-width">1</se:SvgParameter>
</se:Mark>
<se:Size>12</se:Size>
</se:Graphic>
</se:GraphicStroke>
</se:Stroke>
</se:LineSymbolizer>
</se:Rule>
Остановимся на значениях SvgParameter.
<se:SvgParameter name="stroke">#333333</se:SvgParameter> определяет цвет строки
<se:SvgParameter name="stroke-width">3</se:SvgParameter> определяет толщину строки
<se:WellKnownName>shape://vertline</se:WellKnownName> задает перпендикулярную линию
Для каждого элемента линии нужно указывать свой <se:LineSymbolizer>. Это можно рассмотреть на более сложном условном знаке.
<se:MinScaleDenominator>0</se:MinScaleDenominator>
<se:MaxScaleDenominator>5000</se:MaxScaleDenominator>
<se:LineSymbolizer>
<se:Stroke>
<se:SvgParameter name="stroke">#ccccfd</se:SvgParameter>
<se:SvgParameter name="stroke-width">5</se:SvgParameter>
<se:SvgParameter name="stroke-linejoin">bevel</se:SvgParameter>
<se:SvgParameter name="stroke-linecap">square</se:SvgParameter>
</se:Stroke>
</se:LineSymbolizer>
<se:LineSymbolizer>
<se:Stroke>
<se:SvgParameter name="stroke">#5860fc</se:SvgParameter>
<se:SvgParameter name="stroke-width">1.8</se:SvgParameter>
<se:SvgParameter name="stroke-linejoin">bevel</se:SvgParameter>
<se:SvgParameter name="stroke-linecap">square</se:SvgParameter>
</se:Stroke>
<se:PerpendicularOffset>4</se:PerpendicularOffset>
</se:LineSymbolizer>
<se:LineSymbolizer>
<se:Stroke>
<se:SvgParameter name="stroke">#5860fc</se:SvgParameter>
<se:SvgParameter name="stroke-width">1.8</se:SvgParameter>
<se:SvgParameter name="stroke-linejoin">bevel</se:SvgParameter>
<se:SvgParameter name="stroke-linecap">square</se:SvgParameter>
</se:Stroke>
<se:PerpendicularOffset>-4</se:PerpendicularOffset>
</se:LineSymbolizer>
<se:LineSymbolizer>
<se:Stroke>
<se:GraphicStroke>
<se:Graphic>
<se:Mark>
<se:WellKnownName>shape://vertline</se:WellKnownName>
<se:Stroke>
<se:SvgParameter name="stroke">#5860fc</se:SvgParameter>
<se:SvgParameter name="stroke-width">1.2</se:SvgParameter>
</se:Stroke>
</se:Mark>
<se:Size>8</se:Size>
</se:Graphic>
</se:GraphicStroke>
<se:SvgParameter name="stroke-dashoffset">5</se:SvgParameter>
</se:Stroke>
<se:PerpendicularOffset>8</se:PerpendicularOffset>
</se:LineSymbolizer>
<se:LineSymbolizer>
<se:Stroke>
<se:GraphicStroke>
<se:Graphic>
<se:Mark>
<se:WellKnownName>shape://vertline</se:WellKnownName>
<se:Stroke>
<se:SvgParameter name="stroke">#5860fc</se:SvgParameter>
<se:SvgParameter name="stroke-width">1.2</se:SvgParameter>
</se:Stroke>
</se:Mark>
<se:Size>8</se:Size>
</se:Graphic>
</se:GraphicStroke>
<se:SvgParameter name="stroke-dashoffset">5</se:SvgParameter>
</se:Stroke>
<se:PerpendicularOffset>-8</se:PerpendicularOffset>
</se:LineSymbolizer>
<se:MinScaleDenominator>0</se:MinScaleDenominator> <se:MaxScaleDenominator>5000</se:MaxScaleDenominator>
Данный параметр отвечает за масштаб отображения знака на карте, это можно использовать, когда нужны точные настройки.
Можно также использовать следующие настройки для масштаба отображения на карте:
http://www.opengeospatial.org/se/units/metre http://www.opengeospatial.org/se/units/foot http://www.opengeospatial.org/se/units/pixel
В код они вписываются следующим образом
<LineSymbolizer uom="http://www.opengeospatial.org/se/units/metre ">, задаются для каждого элемента отдельно при открытии LineSymbolizer
Строки 3-10 это характеристики голубой линии (средняя линия)
Строки 11-28 это характеристики боковых синих линий по краям от голубой основной.
Здесь имеется атрибут <se:PerpendicularOffset>4</se:PerpendicularOffset> который указывает на какое количество пикселей нужно сместить линию. Работает в обе стороны, число может быть положительным и отрицательным.
Строки 28-64 задают характеристики перпендикулярным линиям.
Прикрепляю сюда также ссылку на официал по стилизации линий.
Рассмотреть еще можно такой условный знак:
<se:LineSymbolizer>
<se:Stroke>
<se:GraphicStroke>
<se:Graphic>
<se:Mark>
<se:WellKnownName>triangle</se:WellKnownName>
<se:Fill>
<se:SvgParameter name="fill">#a85400</se:SvgParameter>
</se:Fill>
</se:Mark>
<se:Size>7</se:Size>
<se:Rotation>180</se:Rotation>
</se:Graphic>
</se:GraphicStroke>
<se:SvgParameter name="stroke">#000000</se:SvgParameter>
<se:SvgParameter name="stroke-dasharray">7 7</se:SvgParameter>
</se:Stroke>
</se:LineSymbolizer>
<se:LineSymbolizer>
<se:Stroke>
<se:GraphicStroke>
<se:Graphic>
<se:Mark>
<se:WellKnownName>triangle</se:WellKnownName>
<se:Fill>
<se:SvgParameter name="fill">#a85400</se:SvgParameter>
</se:Fill>
</se:Mark>
<se:Size>7</se:Size>
</se:Graphic>
</se:GraphicStroke>
<se:SvgParameter name="stroke">#000000</se:SvgParameter>
<se:SvgParameter name="stroke-dasharray">7 7</se:SvgParameter>
<se:SvgParameter name="stroke-dashoffset">7</se:SvgParameter>
</se:Stroke>
</se:LineSymbolizer>
В данном условном знаке у нас имеется 2 линии треугольников, которые повернуты друг к другу через расстояние.
<se:WellKnownName>triangle</se:WellKnownName> выводит нам треугольник, какие еще можно использовать функции - по этой ссылке.
<se:SvgParameter name="fill">#a85400</se:SvgParameter> отвечает за цвет заливки треугольника
<se:Rotation>180</se:Rotation> соответственно поворот на N градусов вокруг оси
<se:SvgParameter name="stroke-dasharray">7 7</se:SvgParameter> эти значения выставляют расстояния между треугольниками.
Также нам нужно будет смещение начала отрисовки линии, чтоб у нас треугольники не налагались друг на друга, за это отвечает <se:SvgParameter name="stroke-dashoffset">7</se:SvgParameter>
<se:LineSymbolizer>
<se:Stroke>
<se:GraphicStroke>
<se:Graphic>
<se:Mark>
<se:WellKnownName>wkt://MULTILINESTRING((0 1, 0 -1),(0 -1, 2 -1),(2 -1, 2 1),(2 1, 4 1))</se:WellKnownName>
<se:Fill>
<se:SvgParameter name="fill">#ffffff</se:SvgParameter>
</se:Fill>
<se:Stroke>
<se:SvgParameter name="stroke">#232323</se:SvgParameter>
<se:SvgParameter name="stroke-width">0.5</se:SvgParameter>
</se:Stroke>
</se:Mark>
<se:Size>6</se:Size>
</se:Graphic>
</se:GraphicStroke>
<se:SvgParameter name="stroke-dasharray">6 6</se:SvgParameter>
</se:Stroke>
</se:LineSymbolizer>
В Geoserver есть возможность создавать геометрию с помощью wkt://MULTILINESTRING. Вообще это тема для отдельной статьи, но немного зацепим. В данном случае такую ломаную линию мы создаем прописывая путь по пикселям (можно прописывать значения и смотреть что получается). С более полной информацией можно ознакомиться также на официальном портале.
Тема геоинформационных систем очень обширная и одной статьей тут не ограничиться, но надеюсь это поможет новичкам быстрее освоиться в основах создания SLD схем для линейных объектов.