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

Creating Stunning Maps in GeoServer: mastering SLD and CSS styles

Creating Stunning Maps in GeoServer: mastering SLD and CSS styles

Various software can style maps and generate a proper SLD document for OGC compliant WMS like GeoServer to use. However, in most occasions, the styling allowed by the graphical tools is pretty limited and not good enough to achieve good looking, readable and efficient cartographic output. For those that like to write their own styles CSS also represents a nice alternatives thanks to its compactness and expressiveness.

Several topics will be covered, providing examples in both SLD and CSS for each, including: mastering multi-scale styling, using GeoServer extensions to build common hatch patterns, line styling beyond the basics, such as 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, blending charts into a map, dynamically transform data during rendering to get more explicative maps without the need to pre-process a large amount of views.

The presentation aims to provide the attendees with enough information to master SLD/CSS documents and most of GeoServer extensions to generate appealing, informative, readable maps that can be quickly rendered on screen.

Simone Giannecchini
PRO

September 02, 2018
Tweet

More Decks by Simone Giannecchini

Other Decks in Programming

Transcript

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

    View Slide

  2. GeoSolutions

    Founded in Italy in late 2006

    Expertise
    • Image Processing, GeoSpatial Data Fusion
    • Java, Java Enterprise, C++, Python
    • JPEG2000, JPIP, Advanced 2D visualization

    Supporting/Developing FOSS4G projects

    GeoServer, MapStore

    GeoNetwork, GeoNode, Ckan

    Clients

    Public Agencies

    Private Companies

    http://www.geo-solutions.it
    2 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  3. Quick tour of styling languages
    3

    View Slide

  4. 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
    4
    Map
    rendering
    FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  5. Shared concepts

    Layer (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
    5 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  6. Styled Layer Descriptor 1.0 and 11

    The only OGC standard

    XML based, verbose, hard to hand edit,
    was meant for machine export but ended
    up being edited a lot by hand

    Can be generated by external tools and
    imported

    However interoperability is limited

    Often needs to be hand tweaked
    6 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  7. 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
    7 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  8. 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
    8 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  9. GeoCSS

    Compact syntax, familiar for web developers

    CQL based filtering, rule nesting and cascading
    keeps complex styling compact (you just
    express the overrides to the base)

    The only style language with auto-complete in
    the style editor

    Does not get any more compact than this:

    Cons: some are confused by “rule cascading”
    [type = 'alpine_hut'][@sd < 100k] {
    mark: url('symbols/alpinehut.p.16.png');
    }
    9 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  10. MBStyles (aka MapBox GL)

    Whole different beast

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

    Only zoom level based scale control

    Symbols coming from “sprites” (symbol
    collections)

    Pro: can be applied both on the client side and
    the server side
    10 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  11. 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
    11 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  12. What’s next

    Going to explore styling concepts

    Languages used in examples

    SLD 1.0 + GS extensions

    YSLD

    GeoCSS
    YSLD
    SLD
    CSS
    12 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  13. Scale dependencies
    13

    View Slide

  14. Types of Scale dependency

    Decide whether to symbolize based on the scale or not

    E.g., at lower scales/lower zoom levels do not show buildings

    Symbolize in a different way depending on the scale

    E.g., different thickness based on the current zoom
    14 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  15. Expressing 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

    YSLD:

    scale: (1000, 1000000)

    scale: (1e3, 1e6)

    zoom: (8, 16)
    grid:
    name: WGS84
    15 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  16. Unit of Measure

    Useful if you have real world measures of line
    thicknesses and the like



    #0000FF
    5


    ...

    stroke: blue;
    stroke-width: 5m;

    line:
    stroke-color: '#0000FF'
    uom: metre;
    stroke-width: '5';
    SLD
    YSLD
    CSS
    16 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  17. Transformation functions

    Another way of setting a different value
    depending on the current scale/zoom level

    Useful if the scaling is not linear
    [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
    17 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  18. Transformation functions in SLD


    #e66e89



    wms_scale_denominator

    2
    400000
    1.9
    800000
    1.4
    1500000
    1
    3000000
    0.8
    6000000
    0.5




    SLD
    18 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  19. Point styling
    19

    View Slide

  20. Simple image
    [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
    20 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  21. Marks (SVG in this case)
    [type = 'bank'][@sd < 6k] {
    mark: symbol('file://symbols/bank.svg');
    :mark { fill: #734a08 };
    mark-size: 14;
    }
    feature-styles:
    - rules:
    - filter: type = 'bank'
    scale: (,6000.0)
    symbolizers:
    - point:
    symbols:
    - mark:
    shape: file://symbols/bank.svg
    fill-color: ! '#734a08'
    size: 14 YSLD
    CSS
    21 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  22. 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
    22 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide


  23. Many other options!

    Built-in symbol names (well known marks): circle,
    square, triangle, …

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

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

    WKT specification, e.g.
    wkt://MULTILINESTRING((-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))

    See more here:
    http://docs.geoserver.org/latest/en/user/styling/sld/exte
    nsions/pointsymbols.html
    Other mark options
    23 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  24. Filling polygons
    24

    View Slide

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


    #d3d3d3


    0.5

    SLD
    CSS
    25 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  26. Filling with repeating images
    fill
    [@sd < 800k][type in ('cemetery', 'grave_yard')] {
    fill: #aacbaf;
    [@sd < 50k] {
    [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
    26 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  27. Filling with repeating images (YSLD)
    feature-styles:
    - rules:
    - filter: type IN ('cemetery','grave_yard')
    scale: (,800000.0)
    symbolizers:
    - polygon:
    fill-color: ! '#aacbaf'
    - filter: (type IN ('cemetery','grave_yard')) AND religion =
    'jewish'
    scale: (,50000.0)
    symbolizers:
    - polygon:
    fill-graphic:
    symbols:
    - external:
    url: symbols/grave_yard_jewish.png
    format: image/png
    # continues in the next slide
    First uniform background fill
    Then foreground symbols for
    various religions
    YSLD
    27 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  28. Filling with repeating images (YSLD)
    - filter: (type IN ('cemetery','grave_yard')) AND religion =
    'christian'
    scale: (,50000.0)
    symbolizers:
    - polygon:
    fill-graphic:
    symbols:
    - external:
    url: symbols/grave_yard_christian.png
    format: image/png
    - filter: (type IN ('cemetery','grave_yard')) AND religion =
    'INT-generic'
    scale: (,50000.0)
    symbolizers:
    - polygon:
    fill-graphic:
    symbols:
    - external:
    url: symbols/grave_yard_generic.png
    format: image/png YSLD
    28 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  29. Hatching





    shape://times

    #ADD8E6


    8





    [@scale < 10000] {
    fill: symbol('shape://times');
    fill-size: 8;
    :fill {
    stroke: #ADD8E6;
    }
    }
    SLD
    CSS
    29 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  30. Painting lines
    30

    View Slide

  31. 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
    31 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  32. Dashes



    #6B4900
    0.1
    2 2



    stroke: #6B4900;
    stroke-width: 0.1;
    stroke-dasharray: 2 2;

    SLD
    CSS
    32 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  33. Alternating dashes with marks
    * {
    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
    33 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  34. Labeling
    34

    View Slide

  35. Vendor options
    35 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  36. 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
    36 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  37. 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
    37 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  38. Polygon labels


    FULLNAME


    Arial
    14.0
    bold




    0.5
    0.5




    #000000

    50000
    100
    200
    0.9

    38 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  39. Raster styling
    39

    View Slide

  40. A DEM and a color map

    SRTM from USGS

    Standard color map

    In 2.14.x we’ll also be able
    to add shaded relief (not
    shown here)
    [@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
    40 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

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




    StretchToMinimumMaximum

    50
    800



    GeoServer
    vendor extension
    SLD
    41 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  42. Other assorted features
    42

    View Slide

  43. Color blending and alpha compositing
    http://docs.geoserver.org/stable/user/styling/sld-extensions/composite-blend/index.html
    More info
    at:
    43 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  44. Z ordering
    http://docs.geoserver.org/latest/en/user/styling/sld-
    extensions/z-order/example.html
    [class = 'motorways'] {
    stroke: #990000, #ff6666;
    stroke-width: 8, 6;
    stroke-linecap: round;
    z-index: 0, 3;
    }
    [class = 'railways'] {
    stroke: #333333;
    stroke-width: 3;
    z-index: 2;
    }
    [class = 'railways'] {
    stroke: #ffffff;
    stroke-width: 1.5;
    stroke-dasharray: 5 5;
    z-index: 3;
    }
    * {
    sort-by: "z_order";
    sort-by-group:
    "roadsGroup";
    } CSS
    44 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  45. Geometry transformations
    [@scale < 10000] {
    fill-geometry: [offset(the_geom, 6, -6)];
    fill: darkgray;
    z-index: 0;
    }
    [@scale < 10000] {
    fill: #b3b3b3;
    z-index: 1;
    } CSS
    45 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  46. Rendering transformations
    * {
    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
    46 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  47. New transform in 2.14: 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
    47 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  48. QGIS export
    48

    View Slide

  49. QGIS SLD export work

    In QGIS 2.18, Bonn code sprint improvements

    In QGIS 3.0 support for label exports (thanks for
    OpenGeoGroep sponsoring)
    49 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  50. More to come

    OSGeo UK sponsorship

    The GeoServer PSC looks for proposals

    E.g., we could have basic raster symbolizer
    export
    50 FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide

  51. That’s all folks!
    Questions?
    [email protected]
    51
    FOSS4G 2018, August 29th/31st, Dar Es Salaam

    View Slide