geoserver – How to Specify Label Weight in GeoServer SLD to Control Label Priority

geoserverlabelingsld

I'm labelling a cities layer using GeoServer SLD. I need the larger city labels to draw first, then the smaller city labels to draw if there is enough room. There is a pop_band field which I'm using to distinguish between large and small cities.

In ArcMap this would be achieved by assigning a higher weight (or importance) to the larger city label class. Does this concept exist in GeoServer using SLD?

For example, the large cities like Sydney and Brisbane (in grey) should be labelled here before labelling the smaller cities like Toowoomba and Wollongong:

enter image description here

Here is a snippet of the relevant SLD:

<Rule>
  <Name>LargePop</Name>
  <Title>Large cities</Title>
  <ogc:Filter>
    <ogc:PropertyIsLessThan>
      <ogc:PropertyName>pop_band</ogc:PropertyName>
      <ogc:Literal>2</ogc:Literal>
    </ogc:PropertyIsLessThan>
  </ogc:Filter>
  <PointSymbolizer>
    <Graphic>
      <Mark>
        <WellKnownName>circle</WellKnownName>
        <Fill>
          <CssParameter name="fill">#727272</CssParameter>
        </Fill>
      </Mark>
      <Size>18</Size>
    </Graphic>
  </PointSymbolizer>
  <TextSymbolizer>
 <Label>
   <ogc:PropertyName>town_name</ogc:PropertyName>
 </Label>
 <Font>
   <CssParameter name="font-family">Arial</CssParameter>
   <CssParameter name="font-size">12</CssParameter>
   <CssParameter name="font-style">normal</CssParameter>
   <CssParameter name="font-weight">bold</CssParameter>
 </Font>
 <LabelPlacement>
   <PointPlacement>
     <AnchorPoint>
       <AnchorPointX>0.5</AnchorPointX>
       <AnchorPointY>0.0</AnchorPointY>
     </AnchorPoint>
   </PointPlacement>
 </LabelPlacement>
 <Fill>
   <CssParameter name="fill">#000000</CssParameter>
 </Fill>
</TextSymbolizer>
</Rule>
<Rule>
  <Name>MediumPop</Name>
  <Title>Medium cities</Title>
  <ogc:Filter>
    <ogc:And>
      <ogc:PropertyIsGreaterThanOrEqualTo>
        <ogc:PropertyName>pop_band</ogc:PropertyName>
        <ogc:Literal>3</ogc:Literal>
      </ogc:PropertyIsGreaterThanOrEqualTo>
      <ogc:PropertyIsLessThanOrEqualTo>
        <ogc:PropertyName>pop_band</ogc:PropertyName>
        <ogc:Literal>4</ogc:Literal>
      </ogc:PropertyIsLessThanOrEqualTo>
    </ogc:And>
  </ogc:Filter>
  <PointSymbolizer>
    <Graphic>
      <Mark>
        <WellKnownName>circle</WellKnownName>
        <Fill>
          <CssParameter name="fill">#0033CC</CssParameter>
        </Fill>
      </Mark>
      <Size>12</Size>
    </Graphic>
  </PointSymbolizer>
  <TextSymbolizer>
 <Label>
   <ogc:PropertyName>town_name</ogc:PropertyName>
 </Label>
 <Font>
   <CssParameter name="font-family">Arial</CssParameter>
   <CssParameter name="font-size">10</CssParameter>
   <CssParameter name="font-style">normal</CssParameter>
 </Font>
 <LabelPlacement>
   <PointPlacement>
     <AnchorPoint>
       <AnchorPointX>0.5</AnchorPointX>
       <AnchorPointY>0.0</AnchorPointY>
     </AnchorPoint>
   </PointPlacement>
 </LabelPlacement>
 <Fill>
   <CssParameter name="fill">#000000</CssParameter>
 </Fill>
</TextSymbolizer>
</Rule>

I'm aware that I can use <MaxScaleDenominator> to control whether the smaller cities draw at all, but this doesn't address the issue here since it doesn't assign a greater importance to the larger city label layer.

Best Answer

You need to provide a priority to the labels.

So add something like if you have an attribute to proxy priority:

<Priority>
    <ogc:PropertyName>population</ogc:PropertyName>
</Priority>

to your TextSymbolizer. Or, in your case you could just use a literal value for the 2 levels.