Back to RasterLite2 doc index
Dynamic SLD/SE Vector Styling (based on DB column values)
SLD/SE Vector Styles natively support the capability to apply different symbolizers to the same layer (aka Vector Coverage) depending on some opportune classification criterion.The standard mechanism defined by SLD/SE is based on a chain of multiple <Rule><Filter> tags, each one of them defining a single class and its corresponding styling rules.
It's a really powerful and flexible mechanism, but it could easily become overly complex (and not very efficient) when too many different styles have to be applied at the same time, because in such a case it will require to deploy a very long and rather intricate XML style definition.
Rasterlite2 introduces an extended mechanism intended to make easier, simpler and faster applying highly dynamic styles; let's see how it practically works.
<Fill> <SvgParameter name="fill">#ff0000</SvgParameter> <SvgParameter name="fill-opacity">0.50</SvgParameter> </Fill>The above one is a canonical SLD/SE directive requesting to apply an half-transparent (fill-opacity=0.50) solid red (fill=#ff0000) internal filling.
The corresponding extended dynamic styling directive has a strictly similar syntax:
<Fill> <SvgParameter name="fill">@stroke_color@</SvgParameter> <SvgParameter name="fill-opacity">$stroke_opacity$</SvgParameter> </Fill>
- Constant values #ff0000 and 0.5 are now replaced by the special markers @stroke_color@ and $stroke_opacity$.
Note: a special marker can be indifferently delimited between a couple of @ or $ characters; @name@ and $name$ are exactly the same. - Any special marker is intended to match the name of a column within the layer being currently styled.
- For each feature to be styled the actual value of the corresponding column will be dynamically applied.
Where dynamic styling is supported
Rasterlite2 supports all dynamic styling special markers defined within the context of any SLD/SE VectorSymbolizer:- <PointSymbolizer> ... </PointSymbolizer>
- <LineSymbolizer> ... </LineSymbolizer>
- <PolygonSymbolizer> ... </PolygonSymbolizer>
- <TextSymbolizer> ... </TextSymbolizer>
There are just two exceptions to the above general rule:
- <TextSymbolizer><LabelPlacement><LinePlacement><IsRepeated>true</IsRepeated></LinePlacement></LabelPlacement></TextSymbolizer>
- <TextSymbolizer><LabelPlacement><LinePlacement><IsAligned>true</IsAligned></LinePlacement></LabelPlacement></TextSymbolizer>
- Short rationale: both <IsRepeated> and <IsAligned> strictly require boolean values accordingly to the formal XML schema definition, and consequently cannot accept special markers (that are string literals).
Expected values, exceptions and defaults
- Any special marker must exactly match a valid column name.
If this condition isn't satisfied nasty SQL errors will probably be triggered causing failures or unexpected result. - All column names referenced by special markers will be automatically masked (double-quoted), so you are never required to bother about illegal characters, reserver keywords and alike.
- The actual datatype of column values must match the Style context (see the following table for more details).
Mismatching values will be considered to be NULL.
Side note: all BLOB values will be always considered to be NULL. - All NULL values will be replaced by the appropriate default value defined by SLD/SE rules.
SLD/SE tag(s) | Expected value | Default value |
---|---|---|
<AnchorPointX> <DisplacementX> <PerpendicularOffset> <SvgParameter name="stroke-width"> ... and many others (the majority of Tags requires a numeric value). |
|
depending on the specific context, as defined by SLD/SE rules |
<SvgParameter name="fill"> <SvgParameter name="stroke"> |
Text: HTML Hex RGB color Examples: #4ba7fc or #4BA7FC |
|
<SvgParameter name="stroke-linejoin"> | Text - one between:
|
round |
<SvgParameter name="stroke-linecap"> | Text - one between:
|
round |
<SvgParameter name="stroke-dasharray"> | Text - list of Integer or Double values separated by spaces. e.g. 10 5.0 7 15.0 |
none (solid line) |
<Label> |
|
none (no label will be printed). |
<OnlineResource xlink:type="simple" xlink:href="@name@" /> | Text - simple name of the ExternalGraphics resource, as e.g. bitmap.png or symbol.svg. Note: the pseudo-URL prefix http://www.utopia.gov/ must not be declared. (it will be automatically added). |
none (no graphic symbol will be rendered). |
A quick practical example
We'll start first by creating a Spatial Table ...CREATE TABLE polygs ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, fill TEXT, stroke TEXT, stroke_width DOUBLE, font TEXT, font_size DOUBLE, rotation DOUBLE); SELECT AddGeometryColumn('polygs', 'geom', 4326, 'POLYGON', 'XY');... then we'll insert few features into the table ...
INSERT INTO polygs VALUES (NULL, 'alpha', '#ff0000', '#00ff00', 3, 'serif', 20, 45, ST_GeomFromText('POLYGON((-170 80, -70 80, -70 10, -170 10, -170 80))', 4326)); INSERT INTO polygs VALUES (NULL, 'beta', '#ffff00', '#0000ff', 5, 'sans-serif', 30, -45, ST_GeomFromText('POLYGON((-170 -10, -70 -10, -70 -80, -170 -80, -170 -10))', 4326)); INSERT INTO polygs VALUES (NULL, 'gamma', '#00ff00', '#ff0000', 1, 'serif', 32, 0, ST_GeomFromText('POLYGON((70 80, 170 80, 170 10, 70 10, 70 80))', 4326)); INSERT INTO polygs VALUES (NULL, 'delta', '#0000ff', '#ff8000', 10, 'monospace', 24, 90, ST_GeomFromText('POLYGON((70 -80, 170 -80, 170 -10, 70 -10, 70 -80))', 4326)); INSERT INTO polygs VALUES (NULL, 'epsilon', NULL, NULL, NULL, NULL, NULL, NULL, ST_GeomFromText('POLYGON((-60 80, 60 80, 60 -80, -60 -80, -60 80))', 4326));... and finally we'll register a Vector Coverage based on the Spatial Table we've just created.
SELECT CreateStylingTables(); SELECT SE_RegisterVectorCoverage('test', 'polygs', 'geom'); SELECT SE_UpdateVectorCoverageExtent('test');All right, it's now time to define a (simple) Vector Symbolizer fully based on dynamic styling ...
(we'll save this XML document into a disk file named test_pg.xml)
<?xml version="1.0" encoding="UTF-8"?> <FeatureTypeStyle xmlns="http://www.opengis.net/se" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd"> <Name>test_pg</Name> <Rule> <PolygonSymbolizer> <Fill> <SvgParameter name="fill">@fill@</SvgParameter> </Fill> <Stroke> <SvgParameter name="stroke">@stroke@</SvgParameter> <SvgParameter name="stroke-width">@stroke_width@</SvgParameter> </Stroke> </PolygonSymbolizer> <TextSymbolizer> <Label>@name@</Label> <Font> <SvgParameter name="font-family">@font@</SvgParameter> <SvgParameter name="font-size">@font_size@</SvgParameter> </Font> <LabelPlacement> <PointPlacement> <Rotation>@rotation@</Rotation> </PointPlacement> </LabelPlacement> </TextSymbolizer> </Rule> </FeatureTypeStyle>... now we simply have to load this XML file into the DB and associate it with the Vector Coverage.
SELECT SE_RegisterVectorStyle(XB_Create(XB_LoadXML('test_pg.xml'), 1, 1)); SELECT SE_RegisterVectorStyledLayer('test', 'test_pg');Final step: we are ready to test our dynamic style.
SELECT BlobToFile(RL2_GetMapImageFromVector(NULL, 'test', ST_GeomFromText('LINESTRING(-180 -90, 180 90)', 4326), 2048, 1024, 'test_pg', 'image/png'), 'test.png');
Back to RasterLite2 doc index