qgis / QGIS-Enhancement-Proposals

QEP's (QGIS Enhancement Proposals) are used in the process of creating and discussing new enhancements for QGIS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Export expression based symbology to SLD

geraldo opened this issue · comments

QGIS Enhancement: Export expression based symbology to SLD

Date 2021/10/29

Author Gerald Kogler (@geraldo)

Contact geraldo at servus dot at

maintainer @geraldo

Version QGIS 3.22

Summary

Currently QGIS doesn't export expression based symbology to SLD, it simply ignores it. This limits the use of SLD, for example when serving QGIS layers on the web as WFS using QGIS Server, GeoServer, Openlayers and similar. That's why this proposal limits the development to vector layers as it seems priority for web development.

It would therefore be necessary enhance the write to SLD function by detecting expressions and converting them to valid SLD code. It seems important to add tests including expressions.

As expressions in QGIS have huge possibilities, in a first step only certain functions and cases should be included and all the others silently ignored. Working with scale ranges and fields fulfilling conditions seem to be important, mainly to apply changes to styles. Supporting special keywords (e.g. $geometry) and functions (e.g. buffer()) is of course a completely different topic, and they should be ignored.

Proposed Solution

I would therefore suggest the following developments:

  • Added SLD write support for vector layers
  • Added tests to SLD write support for vector layers

Example(s)

A simple expressions to change size of symbols depending on map scale could look like that in QGIS:

CASE 
WHEN @map_scale < 1500 
THEN  8
WHEN @map_scale >= 1500 and  @map_scale < 3500 
THEN 6
ELSE 4
END

This then should be converted to scale based symbology with SLD using <MinScaleDenominator> and <MaxScaleDenominator>:

<UserStyle>
  <se:Name>Layer Name</se:Name>
  <se:FeatureTypeStyle>
    <se:Rule>
      <se:Name>Large Symbol</se:Name>
      <MaxScaleDenominator>1500</MaxScaleDenominator>
      <se:PointSymbolizer>
        <se:Graphic>
          <se:Mark>
            <se:WellKnownName>square</se:WellKnownName>
            <se:Fill>
              <se:SvgParameter name="fill">#ffffff</se:SvgParameter>
            </se:Fill>
            <se:Stroke>
              <se:SvgParameter name="stroke">#000000</se:SvgParameter>
              <se:SvgParameter name="stroke-width">0.5</se:SvgParameter>
            </se:Stroke>
          </se:Mark>
          <se:Size>8</se:Size>
        </se:Graphic>
      </se:PointSymbolizer>
    </se:Rule>
    <se:Rule>
      <se:Name>Medium Symbol</se:Name>
      <MinScaleDenominator>1500</MinScaleDenominator>
      <MaxScaleDenominator>3500</MaxScaleDenominator>
      <se:PointSymbolizer>
        <se:Graphic>
          <se:Mark>
            <se:WellKnownName>square</se:WellKnownName>
            <se:Fill>
              <se:SvgParameter name="fill">#ffffff</se:SvgParameter>
            </se:Fill>
            <se:Stroke>
              <se:SvgParameter name="stroke">#000000</se:SvgParameter>
              <se:SvgParameter name="stroke-width">0.5</se:SvgParameter>
            </se:Stroke>
          </se:Mark>
          <se:Size>6</se:Size>
        </se:Graphic>
      </se:PointSymbolizer>
    </se:Rule>
    <se:Rule>
      <se:Name>Small Symbol</se:Name>
      <MinScaleDenominator>3500</MinScaleDenominator>
      <se:PointSymbolizer>
        <se:Graphic>
          <se:Mark>
            <se:WellKnownName>square</se:WellKnownName>
            <se:Fill>
              <se:SvgParameter name="fill">#ffffff</se:SvgParameter>
            </se:Fill>
            <se:Stroke>
              <se:SvgParameter name="stroke">#000000</se:SvgParameter>
              <se:SvgParameter name="stroke-width">0.5</se:SvgParameter>
            </se:Stroke>
          </se:Mark>
          <se:Size>4</se:Size>
        </se:Graphic>
      </se:PointSymbolizer>
    </se:Rule>
  </se:FeatureTypeStyle>
</UserStyle>

Affected Files

  • qgsvectorlayer.h
  • qgsvectorlayer.cpp
  • qgssymbollayerutils.h
  • qgssymbollayerutils.cpp

Performance Implications

Unknown

Further Considerations/Improvements

In this QEP we talk about writing to SLD but the next logical step to apply it also to reading SLD. Converting SLD denominators to expressions when importing SLD so should be kept in mind while developing the export. So base functions should be written in a abstract way so later on the can be used in both directions.

Probably the overall code quality of SLD in QGIS does affect this issue. As described in #187 code for reading and writing SLD is divided into 3 classes and should be centralized in one class. It's necessary to analyze if this has to be done before implementing this QEP.

Backwards Compatibility

(required)

Issue Tracking ID(s)

qgis/QGIS#23356

Votes

(required)