1

In QGIS both in line, point and polygon type layers (for rivers, settlements, lakes..) I created labels for the objects - I created a field X and Y (Decimal Number), so that I define their location (look at picture) - manually. Basically I move every label separately from one another, and that label has it's specific coordinates. This is 2 years work now, so the new QGIS easy-fast option for manually moving labels was not yet created.

Now the question is this:

I invested a lot time now and I can not find a solution, inside or outside GeoServer documentation - I use SLD style export for all of the layers in GeoServer, that I have no problems styling. However, I can not find a way to style the labels as such different positions, that they are visualized for every specific location with X and Y in GeoServer. So I can not get the same result that I have in QGIS - in GeoServer. I manage to use all of the other SLD styles - so that they are offset from the point in many different ways, but every single label is offest the same way as the others.

Here are 2 SLD examples for point type that is exported from QGIS where I use this manual placement of labels. . 1 Is the basic one, pure export from QGIS. But it won't load, because of map units. So >>2>> fixed one>> 2 Is modiffied with a line or two,so that it works - because of map units and projection.

And in the end, I show you a picture: How all 3 labels in GeoServer are on the right.

1 ORIGINAL ONE

<StyledLayerDescriptor xmlns="http://www.opengis.net/sld" version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:se="http://www.opengis.net/se" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ogc="http://www.opengis.net/ogc">
  <NamedLayer>
    <se:Name>LabelsTest</se:Name>
    <UserStyle>
      <se:Name>LabelsTest</se:Name>
      <se:FeatureTypeStyle>
        <se:Rule>
          <se:Name>Cities</se:Name>
          <se:Description>
            <se:Title>Cities</se:Title>
          </se:Description>
          <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>code</ogc:PropertyName>
              <ogc:Literal>1001</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:PointSymbolizer uom="http://www.opengeospatial.org/se/units/metre">
            <se:Graphic>
              <se:Mark>
                <se:WellKnownName>circle</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>4999.1999999999998181</se:Size>
            </se:Graphic>
          </se:PointSymbolizer>
        </se:Rule>
        <se:Rule>
          <se:Name>Capital</se:Name>
          <se:Description>
            <se:Title>Capital</se:Title>
          </se:Description>
          <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>fclass</ogc:PropertyName>
              <ogc:Literal>national_capital</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:PointSymbolizer uom="http://www.opengeospatial.org/se/units/metre">
            <se:Graphic>
              <se:Mark>
                <se:WellKnownName>circle</se:WellKnownName>
                <se:Fill>
                  <se:SvgParameter name="fill">#ea3600</se:SvgParameter>
                </se:Fill>
                <se:Stroke>
                  <se:SvgParameter name="stroke">#232323</se:SvgParameter>
                  <se:SvgParameter name="stroke-width">0.5</se:SvgParameter>
                </se:Stroke>
              </se:Mark>
              <se:Size>7000</se:Size>
            </se:Graphic>
          </se:PointSymbolizer>
        </se:Rule>
        <se:Rule>
          <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>fclass</ogc:PropertyName>
              <ogc:Literal>city</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:TextSymbolizer>
            <se:Label>
              <ogc:PropertyName>name_old</ogc:PropertyName>
            </se:Label>
            <se:Font>
              <se:SvgParameter name="font-family">Oranienbaum</se:SvgParameter>
              <se:SvgParameter name="font-size">10000</se:SvgParameter>
            </se:Font>
            <se:LabelPlacement>
              <se:PointPlacement>
                <se:AnchorPoint>
                  <se:AnchorPointX>0</se:AnchorPointX>
                  <se:AnchorPointY>0.5</se:AnchorPointY>
                </se:AnchorPoint>
                <se:Displacement>
                  <se:DisplacementX>3555</se:DisplacementX>
                  <se:DisplacementY>0</se:DisplacementY>
                </se:Displacement>
              </se:PointPlacement>
            </se:LabelPlacement>
            <se:Fill>
              <se:SvgParameter name="fill">#000000</se:SvgParameter>
            </se:Fill>
            <se:VendorOption name="conflictResolution">false</se:VendorOption>
          </se:TextSymbolizer>
        </se:Rule>
        <se:Rule>
          <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>fclass</ogc:PropertyName>
              <ogc:Literal>national_capital</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:TextSymbolizer>
            <se:Label>
              <ogc:Function name="strToUpperCase">
                <ogc:PropertyName>name_old</ogc:PropertyName>
              </ogc:Function>
            </se:Label>
            <se:Font>
              <se:SvgParameter name="font-family">Oranienbaum</se:SvgParameter>
              <se:SvgParameter name="font-size">12000</se:SvgParameter>
            </se:Font>
            <se:LabelPlacement>
              <se:PointPlacement>
                <se:AnchorPoint>
                  <se:AnchorPointX>0</se:AnchorPointX>
                  <se:AnchorPointY>0.5</se:AnchorPointY>
                </se:AnchorPoint>
              </se:PointPlacement>
            </se:LabelPlacement>
            <se:Fill>
              <se:SvgParameter name="fill">#000000</se:SvgParameter>
            </se:Fill>
            <se:VendorOption name="underlineText">true</se:VendorOption>
            <se:VendorOption name="conflictResolution">false</se:VendorOption>
          </se:TextSymbolizer>
        </se:Rule>
      </se:FeatureTypeStyle>
    </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

2 CHANGED ONE so it loads (of map units)

<StyledLayerDescriptor xmlns="http://www.opengis.net/sld" version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:se="http://www.opengis.net/se" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ogc="http://www.opengis.net/ogc">
  <NamedLayer>
    <se:Name>LabelsTest</se:Name>
    <UserStyle>
      <se:Name>LabelsTest</se:Name>
      <se:FeatureTypeStyle>
        <se:Rule>
          <se:Name>Cities</se:Name>
          <se:Description>
            <se:Title>Cities</se:Title>
          </se:Description>
          <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>code</ogc:PropertyName>
              <ogc:Literal>1001</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:PointSymbolizer uom="http://www.opengeospatial.org/se/units/metre">
            <se:Graphic>
              <se:Mark>
                <se:WellKnownName>circle</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>4999.1999999999998181</se:Size>
            </se:Graphic>
          </se:PointSymbolizer>
        </se:Rule>
        <se:Rule>
          <se:Name>Capital</se:Name>
          <se:Description>
            <se:Title>Capital</se:Title>
          </se:Description>
          <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>fclass</ogc:PropertyName>
              <ogc:Literal>national_capital</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:PointSymbolizer uom="http://www.opengeospatial.org/se/units/metre">
            <se:Graphic>
              <se:Mark>
                <se:WellKnownName>circle</se:WellKnownName>
                <se:Fill>
                  <se:SvgParameter name="fill">#ea3600</se:SvgParameter>
                </se:Fill>
                <se:Stroke>
                  <se:SvgParameter name="stroke">#232323</se:SvgParameter>
                  <se:SvgParameter name="stroke-width">0.5</se:SvgParameter>
                </se:Stroke>
              </se:Mark>
              <se:Size>7000</se:Size>
            </se:Graphic>
          </se:PointSymbolizer>
        </se:Rule>
        <se:Rule>
          <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>fclass</ogc:PropertyName>
              <ogc:Literal>city</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:TextSymbolizer uom="http://www.opengeospatial.org/se/units/metre">
            <se:Label>
              <ogc:PropertyName>name_old</ogc:PropertyName>
            </se:Label>
            <se:Font>
              <se:SvgParameter name="font-family">Oranienbaum</se:SvgParameter>
              <se:SvgParameter name="font-size">10000</se:SvgParameter>
            </se:Font>
            <se:LabelPlacement>
              <se:PointPlacement>
                <se:AnchorPoint>
                  <se:AnchorPointX>0</se:AnchorPointX>
                  <se:AnchorPointY>0.5</se:AnchorPointY>
                </se:AnchorPoint>
                <se:Displacement>
                  <se:DisplacementX>3555</se:DisplacementX>
                  <se:DisplacementY>0</se:DisplacementY>
                </se:Displacement>
              </se:PointPlacement>
            </se:LabelPlacement>
            <se:Fill>
              <se:SvgParameter name="fill">#000000</se:SvgParameter>
            </se:Fill>
            <se:VendorOption name="conflictResolution">false</se:VendorOption>
          </se:TextSymbolizer>
        </se:Rule>
        <se:Rule>
          <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>fclass</ogc:PropertyName>
              <ogc:Literal>national_capital</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:TextSymbolizer uom="http://www.opengeospatial.org/se/units/metre">
            <se:Label>
              <ogc:Function name="strToUpperCase">
                <ogc:PropertyName>name_old</ogc:PropertyName>
              </ogc:Function>
            </se:Label>
            <se:Font>
              <se:SvgParameter name="font-family">Oranienbaum</se:SvgParameter>
              <se:SvgParameter name="font-size">12000</se:SvgParameter>
            </se:Font>
            <se:LabelPlacement>
              <se:PointPlacement>
                <se:AnchorPoint>
                  <se:AnchorPointX>0</se:AnchorPointX>
                  <se:AnchorPointY>0.5</se:AnchorPointY>
                </se:AnchorPoint>
              </se:PointPlacement>
            </se:LabelPlacement>
            <se:Fill>
              <se:SvgParameter name="fill">#000000</se:SvgParameter>
            </se:Fill>
            <se:VendorOption name="underlineText">true</se:VendorOption>
            <se:VendorOption name="conflictResolution">false</se:VendorOption>
          </se:TextSymbolizer>
        </se:Rule>
      </se:FeatureTypeStyle>
    </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

I link a sample point lable file, styles and pictures.

QGIS visualization GeoServer WRONG visualization of label placements

[Sample point shapefile - styled. Same style is in SLD above](https://dox.abv.bg/download?id=35498f44f2# - Линк за сваляне)

1

You need to construct the point you would like the label to appear from your X and Y columns and then tell the TextSymbolizer to use that geometry to place the label.

I would use something like:

<se:TextSymbolizer>
  <se:Geometry>
    <ogc:Function name="geomFromWKT">
      <ogc:Function name="Concatenate">"Point(",ogc:PropertyName(X)," ", ogc:PropertyName(Y),")"</ogc:Function>
    </ogc:Function>
  </se:Geometry>
  <se:Label>
     <ogc:Function name="strToUpperCase">
       <ogc:PropertyName>name_old</ogc:PropertyName>
     </ogc:Function>
   </se:Label>

A full list and description of the available functions is here.

6
  • I am trying from hours now and I struggle with adding this or something similar to this. Maybe because I am trying to fit it in in an already built structure from the paste SLD - 2 - in the initial question. I have all the points constructed as you see. And I am adding the rule between the <TextSymbolizer> as it is written down in the functions/syntax, but I am doing something wrong. I already have the point built. So I tried both ways, and tell the Rule - but I am doing something wrong. Please, can you be a little more precise? I will continue to try of course, I must find a solution for this
    – Viktor
    Jan 12 at 14:25
  • I sometimes use the geometry function as the label to check it is being evaluated correctly
    – Ian Turton
    Jan 12 at 14:30
  • Ok, great news ! It turns out that I did almost the exact same thing! One of the tries! Bad news is - that I get the same main error of your corrected one: line 71: cvc-complex-type.2.3: Element 'ogc:Function' cannot have character [children], because the type's content type is element-only. about the <ogc:Function name="Concatenate">"Point(",ogc:PropertyName(X)," ", ogc:PropertyName(Y),")"</ogc:Function> I understand from this stackoverflow.com/questions/34493270/… THAT it is a special character issue..
    – Viktor
    Jan 12 at 14:41
  • You can (probably) ignore that if it is a validation error - see if it works anyway
    – Ian Turton
    Jan 12 at 14:50
  • I tried of course, but It did not work. I even tried several other things, but it still does not work. The labels do not appear. I added things like the parts of initial code: <se:Font>, <se:Fill>, does not work. With or without them. Current state of the cities that I can not visualize: prntscr.com/wlwldv Again, even with the other older options for Font, Fill and so on - it does not visualize it.
    – Viktor
    Jan 12 at 15:25
0

Found a solution! It is a bit long to explain, but here is the short explanation.

First, I needed to change the structure of the data/architecture - so I created another field in the attribute table - a new field was created ("geom1"), which combines the coordinate of the 2 fields and adds POINT.(it is text, not double like the previous 2 fields with coordinates)

It takes the text field with coordinates, however - if they are NULL (empty, those, that are not moved manually do not have coordinates in the X and Y fields) - the code does not work, so there is a function that gets one of the 2 fields.

        <se:Geometry>
          <ogc:Function name="geomFromWKT">
            <ogc:Function name="if_then_else">
                <ogc:Function name="isNull">
                    <ogc:PropertyName>geom1</ogc:PropertyName>
                </ogc:Function>
                <ogc:PropertyName>geom</ogc:PropertyName>   
                <ogc:PropertyName>geom1</ogc:PropertyName>
            </ogc:Function>
          </ogc:Function>
        </se:Geometry>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.