Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Creating Maps in GeoServer using CSS and SLD (FOSS4G 2022 Edition)

Creating Maps in GeoServer using CSS and SLD (FOSS4G 2022 Edition)

The presentation aims to provide attendees with enough information to master GeoServer styling documents and most of GeoServer extensions to generate appealing, informative, readable maps that can be quickly rendered on screen. Examples will be provided from GeoSolutions training material, as well as from the OSM data directory we shared with the community.

Several topics will be covered, providing examples in CSS and SLD, including:
- Mastering common symbolization, filtering, multi-scale styling.
- Using GeoServer extensions to build common hatch patterns, line styling beyond the basics, cased lines, controlling symbols along a line and the way they repeat.
- Leveraging TTF symbol fonts and SVGs to generate good looking point thematic maps.
- Using the full power of GeoServer label lay-outing tools to build pleasant, informative maps on both point, polygon and line layers, including adding road plates around labels, leverage the labeling subsystem conflict resolution engine to avoid overlaps in stand alone point symbology.
- Dynamically transform data during rendering to get more explicative maps without the need to pre-process a large amount of views.
- Generating styles with external tools.

Simone Giannecchini
PRO

August 31, 2022
Tweet

More Decks by Simone Giannecchini

Other Decks in Technology

Transcript

  1. Creating stunning maps
    with GeoServer
    With SLD and CSS
    Ing. Andrea Aime
    GeoSolutions
    1

    View Slide

  2. GeoSolutions
    Enterprise Support
    Services
    Deployment
    Subscription
    Professional
    Training
    Customized
    Solutions
    GeoNode
    • Offices in Italy & US, Global Clients/Team
    • 40+ collaborators, 30+ Engineers
    • Our products
    • Our Offer

    View Slide

  3. Affiliations
    We strongly support Open
    Source, it Is in our core
    We actively participate in
    OGC working groups and
    get funded to advance new
    open standards
    We support standards
    critical to GEOINT

    View Slide

  4. Quick tour of styling languages
    4

    View Slide

  5. Languages
    SLD 1.0
    core
    SLD 1.1
    core
    YSLD
    extension
    MBStyles
    community
    GeoCSS
    extension
    SLD 1.0
    inspired
    object
    model, with
    extensions
    parse
    parse
    parse
    parse
    and translate
    parse
    and translate
    5
    Map
    rendering

    View Slide

  6. Shared concepts

    Layers (the styles applies to)

    Rules

    Filters/selectors (what should be painted)

    Scale dependencies (zoomed in, zoomed out?)

    Symbolizers (how should it be painted)

    Point

    Line

    Polygon

    Text
    6

    View Slide

  7. Styled Layer Descriptor 1.0 and 11

    OGC styling standard, XML based

    Was meant for machine export but ended
    up being edited a lot by hand

    Can be generated by external tools and
    imported (with some hand tweaking)
    7

    View Slide

  8. SLD 1.0 example





    type
    alpine_hut


    100000.0



    xlink:type="simple"
    xlink:href="symbols/alpinehut.p.16.png"/>
    image/png





    Filter
    Scale dep.
    Symbolizer

    View Slide

  9. YSLD

    SLD in YAML syntax

    Filtering by CQL

    Can define reusable variables and blocks

    Verbosity it’s between SLD and CSS

    Has a notion of zoom levels, if needed
    feature-styles:
    - rules:
    - filter: type = 'alpine_hut'
    scale: (,100000.0)
    symbolizers:
    - point:
    symbols:
    - external:
    url: symbols/alpinehut.p.16.png
    format: image/png
    9

    View Slide

  10. GeoCSS

    Compact syntax, familiar for web developers

    CQL based filtering, rule nesting and cascading
    keeps styling compact

    Does not get any more compact than this:

    Cons: some are confused by “rule cascading”
    🡪 can now be turned off
    [type = 'alpine_hut'][@sd < 100k] {
    mark: url('symbols/alpinehut.p.16.png');
    }
    10

    View Slide

  11. MBStyles (aka MapBox GL)

    Symbols as “sprites”
    (symbol collections)

    Can be applied both
    on the client side and
    the server side

    Online editors
    available, complex
    expressions still
    require writing JSON

    JSON based, designed for GUI editing (like
    SLD) instead of hand editing

    Scale control based only on Web Mercator
    zoom levels

    View Slide

  12. MBStyles (aka MapBox GL)
    {
    "version": 8,
    … boilerplate omitted here
    "name": "mountain huts" ,
    "sprite": "https://my.sever/sprite" ,
    "layers": [
    {
    "id": "huts",
    "type": "symbol",
    "minzoom": 9,
    "filter": [
    "==",
    "type",
    "alpine_hut"
    ],
    "layout": {
    "icon-image" : "alpinehut",
    "icon-size": 1,
    "icon-allow-overlap" : true
    }
    }
    ]
    }
    Filter (in postfix notation!)
    Scale dep.
    Symbolizer
    The sprint contains various images,
    like in videogames

    View Slide

  13. Styling concepts:
    Scale dependencies
    13

    View Slide

  14. Scale dependency Filters

    SLD:


    1000



    1000000


    CSS

    [@sd > 1k][@sd < 1M]
    Compact expression
    of large numbers
    makes them readable
    at a glance, e.g.,
    100k, 1M , 10M
    Show buildings
    as user zooms
    in

    View Slide

  15. Unit of Measure

    Real world measures, sizes grow as one zooms
    in



    #0000FF
    5


    ...

    stroke: blue;
    stroke-width: 5m;
    SLD
    CSS

    View Slide

  16. Transformation functions

    Use a different value depending on the current
    scale/zoom level

    For non linear scaling
    [class = 'highway’
    and type in ('motorway’,
    'motorway_link’)]
    [@sd < 25M] {
    stroke: #e66e89;
    stroke-width:
    categorize(@sd,
    2, 400k,
    1.9, 800k,
    1.4, 1.5M,
    1, 3M,
    0.8, 6M,
    0.5);

    Less than 400k 🡪 2px

    [400k, 800k] 🡪 1.9px

    [800k, 1.5M] 🡪 1.4px

    [1.5M, 3M] 🡪 1

    [3M, 6M] 🡪 0.8

    Above 6M -> 0.5
    CSS

    View Slide

  17. Transformation functions in SLD


    #e66e89



    wms_scale_denominator

    2
    400000
    1.9
    800000
    1.4
    1500000
    1
    3000000
    0.8
    6000000
    0.5




    SLD

    View Slide

  18. Point styling
    18

    View Slide

  19. Simple symbol
    [type = 'alpine_hut'][@sd < 100k] {
    mark: url('symbols/alpinehut.p.16.png');
    }



    type
    alpine_hut


    100000.0



    xlink:type="simple"
    xlink:href="symbols/alpinehut.p.16.png"/>
    image/png




    SLD
    CSS

    View Slide

  20. SVG as a scalable, fillable shape
    [type = 'bank'][@sd < 6k] {
    mark: symbol('file://symbols/bank.svg');
    :mark { fill: #734a08 };
    mark-size: 14;
    }



    type
    bank


    6000



    file://symbols/bank.svg

    #734a08


    14



    CSS
    bank.svg

    View Slide

  21. Marks composition and override
    [type = 'fountain’] {
    [@sd < 6k] {
    mark: symbol(circle), symbol(circle);
    :nth-mark(1) { fill: #b5d0d0 };
    :nth-mark(2) { fill: #576ddf };
    mark-size: 10, 3;
    };
    [@sd < 3k] {
    mark: symbol('file://symbols/fountain.svg');
    :mark { fill: #576ddf; };
    }
    }
    CSS

    View Slide


  22. Here are some examples:

    From TTF fonts using the name
    ttf://#charcode

    Windbarbs, e.g.:
    windbarbs://default(15)[kts]

    WKT specification, e.g.
    wkt://MULTIPOLYGON(((-0.25 -0.25, -0.125 -0.25), (0.125 -0.25,
    0.25 -0.25)), (-0.25 0.25, -0.125 0.25), (0.125 0.25, 0.25 0.25)
    …… )

    Build your own, pluggable system

    Full docs at:
    http://docs.geoserver.org/latest/en/user/styling/sld/exte
    nsions/pointsymbols.html
    Other mark options

    View Slide

  23. Filling polygons
    23

    View Slide

  24. Solid filling
    * {
    fill: lightgrey;
    stroke-width: 0.5;
    }


    #d3d3d3


    0.5

    SLD
    CSS

    View Slide

  25. Overlap solid fills with repeated icons
    fill
    [@sd < 800k][type in ('cemetery', 'grave_yard')] {
    fill: #aacbaf;
    [religion = 'jewish'] {
    fill: #aacbaf, url('symbols/grave_yard_jewish.png');
    };
    [religion = 'christian'] {
    fill: #aacbaf, url('symbols/grave_yard_christian.png');
    };
    [religion = 'INT-generic'] {
    fill: #aacbaf, url('symbols/grave_yard_generic.png');
    };
    }
    CSS

    View Slide

  26. Hatching





    shape://times

    #ADD8E6


    8





    [@scale < 10000] {
    fill: symbol('shape://times');
    fill-size: 8;
    :fill {
    stroke: #ADD8E6;
    }
    }
    SLD
    CSS

    View Slide

  27. Line symbology
    27

    View Slide

  28. Solid lines (OSM admin borders)
    [type = 'administrative'] {
    [admin_level <= 4],
    [admin_level = 5 or admin_level = 6][@sd <= 400k],
    [admin_level = 7 or admin_level = 8][@sd <= 200k],
    [admin_level = 9 or admin_level = 10][@sd <= 100k] {
    stroke: #ac46ac;
    stroke-opacity: 0.4;
    }
    }
    CSS

    View Slide

  29. Dashes/Marks/images along a line
    * {
    stroke: darkRed, symbol('circle');
    stroke-dasharray: 10 14, 6 18;
    stroke-dashoffset: 14, 0;
    :stroke {
    fill: darkRed;
    size: 6;
    }
    }

    Two coordinated dashed lines

    One made with lines

    One made with circles

    The offset shifts them to have
    one appear in the empty
    spaces of the other
    CSS

    View Slide

  30. Labeling
    30

    View Slide

  31. Vendor options
    • Priority labelling, static or attribute based
    • Deluge of vendor options to control in detail labelling:
    • group
    • labelAllGroup
    • spaceAround
    • followLine
    • maxDisplacement
    • repeat
    • maxAngleDelta
    • autoWrap
    • forceLeftToRight
    • conflictResolution
    • goodnessOfFit
    • polygonAlign
    • graphic-resize
    • graphic-margin
    • partials
    • underlineText
    • strikethroughText
    • charSpacing
    • wordSpacing

    View Slide

  32. Polygon labels


    FULLNAME


    Arial
    14.0
    bold




    0.5
    0.5




    #000000

    50000
    100
    200
    0.9

    SLD

    View Slide

  33. Point labels and obstacles
    [@sd < 200k] {
    label: [FULLNAME];
    label-anchor: 0.5 1.0;
    label-offset: 0.0 -14.0;
    font-fill: #000033;
    font-family: Arial;
    font-size: 12;
    halo-color: white;
    halo-radius: 1.5;
    label-priority: 200000;
    label-auto-wrap: 100;
    mark: url('./img/landmarks/${IMAGE}’);
    mark-label-obstacle: true;
    }
    «FULLNAME»
    attribute
    Auto wrapping
    label with halo.
    Data driven
    symbol URL
    Labels won’t overlap
    the symbol
    CSS

    View Slide

  34. Line labels
    [@sd < 200k] {
    label: [LABEL_NAME];
    font-fill: #000000;
    font-family: Arial;
    font-size: 13;
    font-style: normal;
    font-weight: bold;
    halo-color: #FFFFFF;
    halo-radius: 1;
    label-follow-line: true;
    label-repeat: 400;
    label-group: true;
    label-max-displacement: 200;
    }
    Draw «LABEL_NAME»,
    black, with white halo
    Draw them along lines,
    fuse segments with
    same label, repeat
    CSS

    View Slide

  35. Raster styling
    35

    View Slide

  36. A DEM and a color map

    SRTM from USGS

    Standard color map

    Also shaded relief (not
    shown in the css below)
    [@sd > 75000] {
    raster-channels: auto;
    raster-color-map:
    color-map-entry(#00BFBF, -100.0, 0)
    color-map-entry(#00FF00, 920.0, 0)
    color-map-entry(#00FF00, 920.0, 1.0)
    color-map-entry(#FFFF00, 1940.0, 1.0)
    color-map-entry(#FFFF00, 1940.0, 1.0)
    color-map-entry(#FF7F00, 2960.0, 1.0)
    color-map-entry(#FF7F00, 2960.0, 1.0)
    color-map-entry(#BF7F3F, 3980.0, 1.0)
    color-map-entry(#BF7F3F, 3980.0, 1.0)
    color-map-entry(#141514, 5000.0, 1.0);
    }
    CSS

    View Slide

  37. Contrast enhancement
    http://docs.geoserver.org/latest/en/user/styling/sld-reference/rastersymbolizer.
    html#contrastenhancement




    StretchToMinimumMaximum

    50
    800



    GeoServer
    vendor extension
    SLD

    View Slide

  38. Other assorted features
    38

    View Slide

  39. Color blending and alpha compositing
    multiply color-burn difference
    Source Destination
    https://docs.geoserver.org/latest/en/user/styling/sld/extensions/composite-blend/index.html
    More info at:
    Mask with alpha compositing

    multiply, 0.5

    View Slide

  40. Z ordering
    https://docs.geoserver.org/latest/en/user/styling/sl
    d/extensions/z-order/syntax.html#z-ordering-acros
    s-layers
    [class = 'motorways'] {
    stroke: #990000, #ff6666;
    stroke-width: 8, 6;
    stroke-linecap: round;
    z-index: 0, 2;
    }
    [class = 'railways'] {
    stroke: #333333;
    stroke-width: 3;
    z-index: 1;
    }
    [class = 'railways'] {
    stroke: #ffffff;
    stroke-width: 1.5;
    stroke-dasharray: 5 5;
    z-index: 2;
    }
    * {
    sort-by: "z_order";
    sort-by-group:
    "roadsGroup";
    } CSS
    40

    View Slide

  41. Rendering transformations
    • WPS + WMS +
    rendering optimizations
    • In this slide, on the fly
    contour extraction
    * {
    transform: ras:Contour(levels:
    1100 1200 1300 1400
    1500 1600 1700 1800);
    stroke: black;
    label: [GRAY-INDEX];
    font-fill: black;
    font-family: Sans;
    font-size: 12;
    halo-radius: 2;
    halo-color: white;
    label-follow-line: true
    } CSS
    41

    View Slide

  42. Jiffle map algebra
    * {
    transform: ras:Jiffle(script:
    ‘ nir = src[7];
    vir = src[3];
    dest = (nir-vir)/(nir+vir);’);
    raster-channels: auto;
    raster-color-map:
    color-map-entry(#00BFBF, -100.0, 0)
    color-map-entry(#00FF00, 920.0, 0)

    } CSS
    On the fly NDVI
    computation
    from Sentinel 2
    images

    View Slide

  43. Point and click editors
    43

    View Slide

  44. QGIS SLD export
    • Basic vector and raster
    styling covered
    • Much advanced bits missing
    though
    • Needs sponsoring on both ends
    (QGIS and GeoServer)

    View Slide

  45. GeoStyler
    https://geostyler.github.io/geostyler-demo/

    View Slide

  46. MapStore styler
    https://mapstore.readthedocs.io/en/latest/user-guide/layer-settings/#visual-editor-style

    View Slide

  47. That’s all folks!
    Questions?
    [email protected]
    47

    View Slide