opengeospatial / styles-and-symbology

OGC Styles & Symbology Standards
Other
11 stars 6 forks source link

Bivariate proportional symbol #23

Open ebocher opened 1 year ago

ebocher commented 1 year ago

Existing conformance classes required for this use case:

Example stylesheet:

Bivariate map is a technique in cartography to display two different thematic variables at the same time. One of the most commun technique to create a bivariate map is to combine of visual variables. For most cartographers it may better support different map reading tasks. The following map uses the same visual variable to represent two variables (Half Circle). It permits a cross-variable comparison between the number of permits in 2005 and 2014.

*{
  stroke: grey;
  stroke-width: 1px;
  [NB_PERMITS_2005>0] {
    geometry: centroid(the_geom);
    mark:   symbol(semicircle);
    mark-size: [Interpolate(
         NB_PERMITS_2005,
         0, 10,
         659, 100,
         'numeric',
         'linear')];
   :mark {
       fill: rgb(153, 153, 255);
       fill-opacity: 0.2;
       stroke: black;
       stroke-width : 1px;
     }
  };
    [NB_PERMITS_2014>0] {
      geometry: centroid(the_geom);
      mark:   symbol(semicircle);
      mark-size: [Interpolate(
           NB_PERMITS_2014,
           0, 10,
           659, 100,
           'numeric',
           'linear')];
     :mark {
         fill: rgb(102, 0, 204);
         fill-opacity: 0.2;
         stroke: black;
         stroke-width : 1px;
         rotation: 180deg;
       }
    }
}

Describe any capability not already addressed by existing conformance classes:

Example image illustrating the portrayal use case:

bivariate_proportional_symbol_map

Additional example

proportionnal_bivariate_2

ebocher commented 1 year ago

Below is an example with an SLD rendered with Geotools.

<?xml version="1.0" encoding="UTF-8"?>
<UserStyle xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld"
           xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc">
    <Name>Default Styler</Name>
    <FeatureTypeStyle>
    <Rule>
        <LineSymbolizer>
            <Stroke>
                <CssParameter name="stroke">
                    <ogc:Literal>#000000</ogc:Literal>
                </CssParameter>
                <CssParameter name="stroke-width">
                    <ogc:Literal>1</ogc:Literal>
                </CssParameter>
            </Stroke>
        </LineSymbolizer>
    </Rule>
    <Rule>
        <PointSymbolizer>
            <Graphic>
                <Mark>
                    <WellKnownName>semicircle</WellKnownName>
                    <Fill>
                        <CssParameter name="fill">#09324D</CssParameter>
                    </Fill>

                </Mark>
                <Size>
                    <ogc:Function name="Interpolate">
                        <ogc:PropertyName>POP_0_5_YEARS</ogc:PropertyName>
                        <ogc:Literal>0</ogc:Literal>
                        <ogc:Literal>10</ogc:Literal>
                        <ogc:Literal>10</ogc:Literal>
                        <ogc:Literal>50</ogc:Literal>
                        <ogc:Literal>100</ogc:Literal>
                        <ogc:Literal>100</ogc:Literal>
                        <ogc:Literal>numeric</ogc:Literal>
                        <ogc:Literal>linear</ogc:Literal>
                    </ogc:Function>
                </Size>
            </Graphic>
        </PointSymbolizer>
    </Rule>
    <Rule>
        <PointSymbolizer>
            <Graphic>
                <Mark>
                    <WellKnownName>semicircle</WellKnownName>
                    <Fill>
                        <CssParameter name="fill">#f44336</CssParameter>
                    </Fill>
                </Mark>
                <Size>
                    <ogc:Function name="Interpolate">
                        <ogc:PropertyName>POP_GREATER_65_YEARS</ogc:PropertyName>
                        <ogc:Literal>0</ogc:Literal>
                        <ogc:Literal>10</ogc:Literal>
                        <ogc:Literal>10</ogc:Literal>
                        <ogc:Literal>50</ogc:Literal>
                        <ogc:Literal>100</ogc:Literal>
                        <ogc:Literal>100</ogc:Literal>
                        <ogc:Literal>numeric</ogc:Literal>
                        <ogc:Literal>linear</ogc:Literal>
                    </ogc:Function>
                </Size>
                <Rotation>180.0</Rotation>
            </Graphic>
        </PointSymbolizer>
    </Rule>
</FeatureTypeStyle>
        </UserStyle>

Example image illustrating the portrayal use case:

face_to_face_proportional_symbol

Data :

https://github.com/orbisgis/POC-Carto/blob/main/data/rsu_lcz.geojson

ebocher commented 1 year ago

The following map displays a bivariate map applied on road types and width. This king map combine a proportional line on the size of the roads and a unique values classification based on the road types.

Geotools SLD

<?xml version="1.0" encoding="UTF-8"?>
<UserStyle xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld"
           xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc">
    <Name>Default Styler</Name>
      <Name>road</Name>
      <FeatureTypeStyle>
        <Rule>
          <Name>highway_link</Name>
          <Description>
            <Title>highway_link</Title>
          </Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>TYPE</ogc:PropertyName>
              <ogc:Literal>highway_link</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <LineSymbolizer>
            <Stroke>
              <CssParameter name="stroke">#0e43cb</CssParameter>
              <CssParameter name="stroke-width">
                  <ogc:Function name="Interpolate">
                      <ogc:PropertyName>WIDTH</ogc:PropertyName>
                      <ogc:Literal>0</ogc:Literal>
                      <ogc:Literal>1</ogc:Literal>
                      <ogc:Literal>3</ogc:Literal>
                      <ogc:Literal>5</ogc:Literal>
                      <ogc:Literal>16</ogc:Literal>
                      <ogc:Literal>10</ogc:Literal>
                      <ogc:Literal>numeric</ogc:Literal>
                      <ogc:Literal>linear</ogc:Literal>
                  </ogc:Function>
              </CssParameter>
            </Stroke>
          </LineSymbolizer>
        </Rule>
        <Rule>
          <Name>pedestrian</Name>
          <Description>
            <Title>pedestrian</Title>
          </Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>TYPE</ogc:PropertyName>
              <ogc:Literal>pedestrian</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <LineSymbolizer>
            <Stroke>
              <CssParameter name="stroke">#d8265b</CssParameter>
              <CssParameter name="stroke-width">
                <ogc:Function name="Interpolate">
                  <ogc:PropertyName>WIDTH</ogc:PropertyName>
                  <ogc:Literal>0</ogc:Literal>
                  <ogc:Literal>1</ogc:Literal>
                  <ogc:Literal>3</ogc:Literal>
                  <ogc:Literal>5</ogc:Literal>
                  <ogc:Literal>16</ogc:Literal>
                  <ogc:Literal>10</ogc:Literal>
                  <ogc:Literal>numeric</ogc:Literal>
                  <ogc:Literal>linear</ogc:Literal>
                </ogc:Function>
              </CssParameter>
            </Stroke>
          </LineSymbolizer>
        </Rule>
        <Rule>
          <Name>primary</Name>
          <Description>
            <Title>primary</Title>
          </Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>TYPE</ogc:PropertyName>
              <ogc:Literal>primary</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <LineSymbolizer>
            <Stroke>
              <CssParameter name="stroke">#ff6011</CssParameter>
              <CssParameter name="stroke-width"><ogc:Function name="Interpolate">
                <ogc:PropertyName>WIDTH</ogc:PropertyName>
                <ogc:Literal>0</ogc:Literal>
                <ogc:Literal>0.1</ogc:Literal>
                <ogc:Literal>3</ogc:Literal>
                <ogc:Literal>5</ogc:Literal>
                <ogc:Literal>16</ogc:Literal>
                <ogc:Literal>10</ogc:Literal>
                <ogc:Literal>numeric</ogc:Literal>
                <ogc:Literal>linear</ogc:Literal>
              </ogc:Function></CssParameter>
            </Stroke>
          </LineSymbolizer>
        </Rule>
        <Rule>
          <Name>residential</Name>
          <Description>
            <Title>residential</Title>
          </Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>TYPE</ogc:PropertyName>
              <ogc:Literal>residential</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <LineSymbolizer>
            <Stroke>
              <CssParameter name="stroke">#000000</CssParameter>
              <CssParameter name="stroke-width"><ogc:Function name="Interpolate">
                <ogc:PropertyName>WIDTH</ogc:PropertyName>
                <ogc:Literal>0</ogc:Literal>
                <ogc:Literal>1</ogc:Literal>
                <ogc:Literal>3</ogc:Literal>
                <ogc:Literal>5</ogc:Literal>
                <ogc:Literal>16</ogc:Literal>
                <ogc:Literal>10</ogc:Literal>
                <ogc:Literal>numeric</ogc:Literal>
                <ogc:Literal>linear</ogc:Literal>
              </ogc:Function></CssParameter>
            </Stroke>
          </LineSymbolizer>
        </Rule>
        <Rule>
          <Name>secondary</Name>
          <Description>
            <Title>secondary</Title>
          </Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>TYPE</ogc:PropertyName>
              <ogc:Literal>secondary</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <LineSymbolizer>
            <Stroke>
              <CssParameter name="stroke">#db1e2a</CssParameter>
              <CssParameter name="stroke-width"><ogc:Function name="Interpolate">
                <ogc:PropertyName>WIDTH</ogc:PropertyName>
                <ogc:Literal>0</ogc:Literal>
                <ogc:Literal>0.1</ogc:Literal>
                <ogc:Literal>3</ogc:Literal>
                <ogc:Literal>5</ogc:Literal>
                <ogc:Literal>16</ogc:Literal>
                <ogc:Literal>10</ogc:Literal>
                <ogc:Literal>numeric</ogc:Literal>
                <ogc:Literal>linear</ogc:Literal>
              </ogc:Function></CssParameter>
            </Stroke>
          </LineSymbolizer>
        </Rule>
        <Rule>
          <Name>tertiary</Name>
          <Description>
            <Title>tertiary</Title>
          </Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>TYPE</ogc:PropertyName>
              <ogc:Literal>tertiary</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <LineSymbolizer>
            <Stroke>
              <CssParameter name="stroke">#711671</CssParameter>
              <CssParameter name="stroke-width"><ogc:Function name="Interpolate">
                <ogc:PropertyName>WIDTH</ogc:PropertyName>
                <ogc:Literal>0</ogc:Literal>
                <ogc:Literal>1</ogc:Literal>
                <ogc:Literal>3</ogc:Literal>
                <ogc:Literal>5</ogc:Literal>
                <ogc:Literal>16</ogc:Literal>
                <ogc:Literal>10</ogc:Literal>
                <ogc:Literal>numeric</ogc:Literal>
                <ogc:Literal>linear</ogc:Literal>
              </ogc:Function></CssParameter>
            </Stroke>
          </LineSymbolizer>
        </Rule>
        <Rule>
          <Name>track</Name>
          <Description>
            <Title>track</Title>
          </Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>TYPE</ogc:PropertyName>
              <ogc:Literal>track</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <LineSymbolizer>
            <Stroke>
              <CssParameter name="stroke">#711671</CssParameter>
              <CssParameter name="stroke-width"><ogc:Function name="Interpolate">
                <ogc:PropertyName>WIDTH</ogc:PropertyName>
                <ogc:Literal>0</ogc:Literal>
                <ogc:Literal>1</ogc:Literal>
                <ogc:Literal>3</ogc:Literal>
                <ogc:Literal>5</ogc:Literal>
                <ogc:Literal>16</ogc:Literal>
                <ogc:Literal>10</ogc:Literal>
                <ogc:Literal>numeric</ogc:Literal>
                <ogc:Literal>linear</ogc:Literal>
              </ogc:Function></CssParameter>
            </Stroke>
          </LineSymbolizer>
        </Rule>
        <Rule>
          <Name>trunk</Name>
          <Description>
            <Title>trunk</Title>
          </Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>TYPE</ogc:PropertyName>
              <ogc:Literal>trunk</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <LineSymbolizer>
            <Stroke>
              <CssParameter name="stroke">#c2ec1c</CssParameter>
              <CssParameter name="stroke-width"><ogc:Function name="Interpolate">
                <ogc:PropertyName>WIDTH</ogc:PropertyName>
                <ogc:Literal>0</ogc:Literal>
                <ogc:Literal>1</ogc:Literal>
                <ogc:Literal>3</ogc:Literal>
                <ogc:Literal>5</ogc:Literal>
                <ogc:Literal>16</ogc:Literal>
                <ogc:Literal>10</ogc:Literal>
                <ogc:Literal>numeric</ogc:Literal>
                <ogc:Literal>linear</ogc:Literal>
              </ogc:Function></CssParameter>
            </Stroke>
          </LineSymbolizer>
        </Rule>
      </FeatureTypeStyle>
    </UserStyle>

Example image illustrating the portrayal use case:

bivariate_proportional_roads

Data :

https://github.com/orbisgis/POC-Carto/blob/main/data/roads.geojson