Point Stacker

The Point Stacker rendering transformation is a Vector-to-Vector transformation which displays a dataset with features that occur close together aggregated into a single point. This produces a more readable map in situations when there are many points to display. As the stacking is performed dynamically, it can be used to visualize changing data, and does not incur a performance overhead even when applied to very large datasets.

The stacked view is created by configuring a layer with an style which invokes the PointStacker rendering transformation.

../../_images/pointstacker-volcanoes.png

Point Stacker rendering transformation

Usage

As with all rendering transformations, the transformation is invoked by inserting a transform into a style. The style can then be applied to any layer which is backed by a suitable dataset.

The transformation function is called vec:PointStacker. Note that this is the same as the WPS process, as these functions can be invoked as either a WPS process or a rendering transformation.

The transformation parameters are as follows. The order of parameters is not significant.

Name Required? Description
data Yes Input FeatureCollection containing the features to transform
cellSize No Size of the cells in which to aggregate points (in pixels, default = 1)
outputBBOX Yes Georeferenced bounding box of the output. Not required with YSLD.
outputWidth Yes Output image width. Not required with YSLD.
outputHeight Yes Output image height. Not required with YSLD.

Environment variables as values

It is a common situation that the output image dimensions be determined by the client at rendering time, to allow for variable window sizes.

In these cases, it is possible to read in special environment variables to the rendering transformation.

There are three environment variables that will be useful to us, which can be used as values for the following input parameters:

Environment variable Description Input parameter
wms_bbox WMS request extent outputBBOX
wms_width Width of resulting image outputWidth
wms_height Height of resulting image outputHeight

The following YSLD syntax for employing environment variables is assumed by default and need not be added to the style:

outputBBOX: ${env(wms_bbox)}
outputWidth: ${env(wms_width)}
outputHeight: ${env(wms_height)}

The following SLD syntax for employing environment variables must be explictly declared:

<ogc:Function name="parameter">
  <ogc:Literal>outputBBOX</ogc:Literal>
  <ogc:Function name="env">
    <ogc:Literal>wms_bbox</ogc:Literal>
  </ogc:Function>
</ogc:Function>

<ogc:Function name="parameter">
  <ogc:Literal>outputWidth</ogc:Literal>
  <ogc:Function name="env">
    <ogc:Literal>wms_width</ogc:Literal>
  </ogc:Function>
</ogc:Function>

<ogc:Function name="parameter">
  <ogc:Literal>outputHeight</ogc:Literal>
  <ogc:Function name="env">
    <ogc:Literal>wms_height</ogc:Literal>
  </ogc:Function>
</ogc:Function>

Input

The PointStacker rendering transformation is applied to a dataset containing vector features. The features may be of any type, though point geometries are typically expected. If non-point geometries are used, the centroids of the features will be used. The dataset is supplied in the data parameter.

Output

The output of the transformation is a vector layer containing point features. Each feature has the following attributes:

Name Type Description
geom Point Point geometry representing the group of features
count Integer Count of all input features represented by this point
countUnique Integer Count of all different input points represented by this point

The output can be styled using a point symbolizer.

Examples

This example shows point stacking applied to a dataset of world volcanoes, displayed with a base map layer of continental topography.

The source data used in this example is the world:volcanoes layer (available for download on the Sample Data page).

Below are two examples showing how to perform this rendering transformation in both YSLD and SLD. You can adapt these examples to your data with minimal effort by adjusting the parameters.

YSLD

The PointStacker output, as seen in the figure at the top of the page, can be produced by the following YSLD:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
name: Default Styler
title: Stacked Point
abstract: Styles volcanoes using stacked points
feature-styles:
- name: name
  transform:
    name: vec:PointStacker
    params:
      cellSize: 30
  rules:
  - name: rule1
    title: Volcano
    filter: count <= '1'
    symbolizers:
    - point:
        size: 8
        symbols:
        - mark:
            shape: triangle
            fill-color: '#FF0000'
  - name: rule29
    title: 2-9 Volcanoes
    filter: count BETWEEN '2' AND '9'
    symbolizers:
    - point:
        size: 14
        symbols:
        - mark:
            shape: circle
            fill-color: '#AA0000'
    - text:
        label: ${count}
        fill-color: '#FFFFFF'
        halo:
          fill-color: '#AA0000'
          fill-opacity: 0.9
          radius: 2
        font-family: Arial
        font-size: 12
        font-style: normal
        font-weight: bold
        placement: point
        anchor: [0.5,0.8]
  - name: rule10
    title: 10 Volcanoes
    filter: count > '9'
    symbolizers:
    - point:
        size: 22
        symbols:
        - mark:
            shape: circle
            fill-color: '#AA0000'
    - text:
        label: ${count}
        fill-color: '#FFFFFF'
        halo:
          fill-color: '#AA0000'
          fill-opacity: 0.9
          radius: 2
        font-family: Arial
        font-size: 12
        font-style: normal
        font-weight: bold
        placement: point
        anchor: [0.5,0.8]

This style defines the Point Stacker rendering transformation, providing values for the transformation parameters which are appropriate for the input dataset.

  • On line 9, cellSize specifies a cell size of 30 to aggregate the points by.

Rules are applied to the transformation output to produce the rendered layer.

  • Starting at line 11, the rule rule1 depicts a single (unstacked) point using a red triangle symbol.
  • Starting at line 21, the rule rule29 depicts a stacked point which has a count in the range 2 to 9. The points are styled as dark red circles of size 14 pixels, with a label showing the count inside them.
  • Starting at line 44, the rule rule10 depicts a stacked point which has a count of 10 or greater. The points are styled as dark red circles of size 22 pixels, with a label that includes the point count.

SLD

The PointStacker output can also be produced by the following SLD:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<?xml version="1.0" encoding="ISO-8859-1"?>
<StyledLayerDescriptor version="1.0.0"
 xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
 xmlns="http://www.opengis.net/sld"
 xmlns:ogc="http://www.opengis.net/ogc"
 xmlns:xlink="http://www.w3.org/1999/xlink"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <NamedLayer>
    <Name>vol_stacked_point</Name>
    <UserStyle>
    <!-- Styles can have names, titles and abstracts -->
      <Title>Stacked Point</Title>
      <Abstract>Styles volcanoes using stacked points</Abstract>
      <FeatureTypeStyle>
        <Transformation>
          <ogc:Function name="vec:PointStacker">
            <ogc:Function name="parameter">
              <ogc:Literal>data</ogc:Literal>
            </ogc:Function>
            <ogc:Function name="parameter">
              <ogc:Literal>cellSize</ogc:Literal>
              <ogc:Literal>30</ogc:Literal>
            </ogc:Function>
            <ogc:Function name="parameter">
              <ogc:Literal>outputBBOX</ogc:Literal>
              <ogc:Function name="env">
                <ogc:Literal>wms_bbox</ogc:Literal>
              </ogc:Function>
            </ogc:Function>
            <ogc:Function name="parameter">
              <ogc:Literal>outputWidth</ogc:Literal>
              <ogc:Function name="env">
                <ogc:Literal>wms_width</ogc:Literal>
              </ogc:Function>
            </ogc:Function>
            <ogc:Function name="parameter">
              <ogc:Literal>outputHeight</ogc:Literal>
              <ogc:Function name="env">
                <ogc:Literal>wms_height</ogc:Literal>
              </ogc:Function>
            </ogc:Function>
          </ogc:Function>
        </Transformation>
        <Rule>
          <Name>rule1</Name>
          <Title>Volcano</Title>
          <ogc:Filter>
            <ogc:PropertyIsLessThanOrEqualTo>
              <ogc:PropertyName>count</ogc:PropertyName>
             <ogc:Literal>1</ogc:Literal>
            </ogc:PropertyIsLessThanOrEqualTo>
          </ogc:Filter>
          <PointSymbolizer>
            <Graphic>
              <Mark>
                <WellKnownName>triangle</WellKnownName>
                <Fill>
                  <CssParameter name="fill">#FF0000</CssParameter>
                </Fill>
              </Mark>
              <Size>8</Size>
            </Graphic>
          </PointSymbolizer>
        </Rule>
        <Rule>
          <Name>rule29</Name>
          <Title>2-9 Volcanoes</Title>
          <ogc:Filter>
            <ogc:PropertyIsBetween>
              <ogc:PropertyName>count</ogc:PropertyName>
              <ogc:LowerBoundary>
                <ogc:Literal>2</ogc:Literal>
              </ogc:LowerBoundary>
              <ogc:UpperBoundary>
                <ogc:Literal>9</ogc:Literal>
              </ogc:UpperBoundary>
            </ogc:PropertyIsBetween>
          </ogc:Filter>
          <PointSymbolizer>
            <Graphic>
              <Mark>
                <WellKnownName>circle</WellKnownName>
                <Fill>
                  <CssParameter name="fill">#AA0000</CssParameter>
                </Fill>
              </Mark>
              <Size>14</Size>
            </Graphic>
          </PointSymbolizer>
          <TextSymbolizer>
            <Label>
              <ogc:PropertyName>count</ogc:PropertyName>
            </Label>
            <Font>
              <CssParameter name="font-family">Arial</CssParameter>
              <CssParameter name="font-size">12</CssParameter>
              <CssParameter name="font-weight">bold</CssParameter>
            </Font>
            <LabelPlacement>
              <PointPlacement>
              <AnchorPoint>
                <AnchorPointX>0.5</AnchorPointX>
                <AnchorPointY>0.8</AnchorPointY>
              </AnchorPoint>
              </PointPlacement>
            </LabelPlacement>
            <Halo>
              <Radius>2</Radius>
              <Fill>
                <CssParameter name="fill">#AA0000</CssParameter>
                <CssParameter name="fill-opacity">0.9</CssParameter>
              </Fill>
            </Halo>
            <Fill>
              <CssParameter name="fill">#FFFFFF</CssParameter>
              <CssParameter name="fill-opacity">1.0</CssParameter>
            </Fill>
          </TextSymbolizer>
        </Rule>
        <Rule>
          <Name>rule10</Name>
          <Title>10 Volcanoes</Title>
          <ogc:Filter>
            <ogc:PropertyIsGreaterThan>
              <ogc:PropertyName>count</ogc:PropertyName>
              <ogc:Literal>9</ogc:Literal>
            </ogc:PropertyIsGreaterThan>
          </ogc:Filter>
          <PointSymbolizer>
            <Graphic>
              <Mark>
                <WellKnownName>circle</WellKnownName>
                <Fill>
                  <CssParameter name="fill">#AA0000</CssParameter>
                </Fill>
              </Mark>
              <Size>22</Size>
            </Graphic>
          </PointSymbolizer>
          <TextSymbolizer>
            <Label>
              <ogc:PropertyName>count</ogc:PropertyName>
            </Label>
            <Font>
              <CssParameter name="font-family">Arial</CssParameter>
              <CssParameter name="font-size">12</CssParameter>
              <CssParameter name="font-weight">bold</CssParameter>
            </Font>
            <LabelPlacement>
              <PointPlacement>
                <AnchorPoint>
                  <AnchorPointX>0.5</AnchorPointX>
                  <AnchorPointY>0.8</AnchorPointY>
                </AnchorPoint>
              </PointPlacement>
            </LabelPlacement>
            <Halo>
               <Radius>2</Radius>
               <Fill>
                 <CssParameter name="fill">#AA0000</CssParameter>
                 <CssParameter name="fill-opacity">0.9</CssParameter>
               </Fill>
            </Halo>
            <Fill>
              <CssParameter name="fill">#FFFFFF</CssParameter>
              <CssParameter name="fill-opacity">1.0</CssParameter>
            </Fill>
          </TextSymbolizer>
        </Rule>
      </FeatureTypeStyle>
    </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>
  • Lines 15-43 define the Point Stacker rendering transformation, providing values for the transformation parameters which are appropriate for the input dataset.
  • Line 18 specifies the input dataset parameter name.
  • Line 21 specifies a cell size of 30 to aggregate the points by.
  • Lines 24-42 define the output parameters outputBBOX, outputWith and outputHeight, which are obtained from internal environment variables set during rendering, as described above.
  • Lines 44-169 define styling rules which are applied to the transformation output to produce the rendered layer.
  • Lines 44-64 define a rule rule1 for depicting a single (unstacked) point using a red triangle symbol.
  • Lines 65-119 define a rule rule29 for depicting a stacked point which has a count in the range 2 to 9. The points are styled as dark red circles of size 14 pixels, with a label showing the count inside them.
  • Lines 120-169 define a rule rule10 for depicting a stacked point which has a count of 10 or greater. The points are styled as dark red circles of size 22 pixels, with a label that includes the point count.