2

I have a style on GeoServer where lines have arrows at the end. I need to move arrow head back to make it end exactly on the line. Not after.

enter image description here

SLD style look style this:

I was trying too add an offset, but it doesn't work. Either because function clearly says "endPoin" or I was writing it incorrectly. I think it also can be resolved by another symbol, from Wingdings or another library, but I can't find the one where center of the icon will be on the arrow top.

<Rule>
      <Name>rule 1</Name>
      <Title>Symbol = 1</Title>
      <Abstract>a single arrow (right side)</Abstract>
      <ogc:Filter>
        <ogc:PropertyIsEqualTo>
          <ogc:PropertyName>symbol</ogc:PropertyName>
          <ogc:Literal>1</ogc:Literal>
        </ogc:PropertyIsEqualTo>
      </ogc:Filter>
      <LineSymbolizer>
        <Stroke>
          <CssParameter name="stroke">#000000</CssParameter>
          <CssParameter name="stroke-width">0.1</CssParameter>
        </Stroke>
      </LineSymbolizer>
      <PointSymbolizer>
                    <Geometry>
                        <ogc:Function name="endPoint">
                            <ogc:PropertyName>geom</ogc:PropertyName>
                        </ogc:Function>
                    </Geometry>
                    <Graphic>
                        <Mark>
                            <WellKnownName>ttf://Wingdings 3#0x0075</WellKnownName>
                            <Fill>
                            <CssParameter name="fill">#000000</CssParameter>
                            </Fill>
                            <Stroke>
                                <CssParameter name="stroke">#000000</CssParameter>
                                <CssParameter name="stroke-width">0.5</CssParameter>
                            </Stroke>
                        </Mark>
                        <Size>3</Size>
                        <Rotation>
                            <ogc:Function name="endAngle">
                                <ogc:PropertyName>geom</ogc:PropertyName>
                            </ogc:Function>
                        </Rotation>
                    </Graphic>
                 </PointSymbolizer>          
    </Rule>     
    
    <Rule>
      <Name>rule 2</Name>
      <Title>Symbol = 3</Title>
      <Abstract>a single arrow (left side)</Abstract>
      <ogc:Filter>
        <ogc:PropertyIsEqualTo>
          <ogc:PropertyName>symbol</ogc:PropertyName>
          <ogc:Literal>3</ogc:Literal>
        </ogc:PropertyIsEqualTo>
      </ogc:Filter>
      <LineSymbolizer>
        <Stroke>
          <CssParameter name="stroke">#000000</CssParameter>
          <CssParameter name="stroke-width">0.1</CssParameter>
        </Stroke>
      </LineSymbolizer>
      <PointSymbolizer>
                    <Geometry>
                        <ogc:Function name="endPoint">
                            <ogc:PropertyName>geom</ogc:PropertyName>
                        </ogc:Function>
                    </Geometry>
                    <Graphic>
                        <Mark>
                            <WellKnownName>shape://oarrow</WellKnownName>
                            <Fill>
                            <CssParameter name="fill">#000000</CssParameter>
                            </Fill>
                            <Stroke>
                                <CssParameter name="stroke">#000000</CssParameter>
                                <CssParameter name="stroke-width">0.5</CssParameter>
                            </Stroke>
                        </Mark>
                        <Size>3</Size>
                        <Rotation>
                            <ogc:Function name="startAngle">
                                <ogc:PropertyName>geom</ogc:PropertyName>
                            </ogc:Function>
                        </Rotation>
                    </Graphic>
                </PointSymbolizer>
    </Rule>
    
    <Rule>
      <Name>rule 3</Name>
      <Title>Symbol in nor equal 1 or 3 </Title>
      <Abstract>a double arrow</Abstract>
      <ogc:Filter>
        
        <ogc:And>
          
        <ogc:PropertyIsNotEqualTo>
          <ogc:PropertyName>symbol</ogc:PropertyName>
          <ogc:Literal>1</ogc:Literal>
        </ogc:PropertyIsNotEqualTo>
          
        <ogc:PropertyIsNotEqualTo>
          <ogc:PropertyName>symbol</ogc:PropertyName>
          <ogc:Literal>3</ogc:Literal>
        </ogc:PropertyIsNotEqualTo>
        </ogc:And> 
        
      </ogc:Filter>
      <LineSymbolizer>
        <Stroke>
          <CssParameter name="stroke">#000000</CssParameter>
          <CssParameter name="stroke-width">0.1</CssParameter>
        </Stroke>
      </LineSymbolizer>
      <PointSymbolizer>
                    <Geometry>
                        <ogc:Function name="endPoint">
                            <ogc:PropertyName>geom</ogc:PropertyName>
                        </ogc:Function>
                    </Geometry>
                    <Graphic>
                        <Mark>
                            <WellKnownName>shape://oarrow</WellKnownName>
                            <Fill>
                            <CssParameter name="fill">#000000</CssParameter>
                            </Fill>
                            <Stroke>
                                <CssParameter name="stroke">#000000</CssParameter>
                                <CssParameter name="stroke-width">0.5</CssParameter>
                            </Stroke>
                        </Mark>
                        <Size>3</Size>
                        <Rotation>
                            <ogc:Function name="endAngle">
                                <ogc:PropertyName>geom</ogc:PropertyName>
                            </ogc:Function>
                        </Rotation>
                    </Graphic>
                </PointSymbolizer>
                <PointSymbolizer>
                    <Geometry>
                        <ogc:Function name="startPoint">
                            <ogc:PropertyName>geom</ogc:PropertyName>
                        </ogc:Function>
                    </Geometry>
                    <Graphic>
                        <Mark>
                            <WellKnownName>ttf://Wingdings 3#0x0074</WellKnownName>
                            <Fill>
                            <CssParameter name="fill">#000000</CssParameter>
                            </Fill>
                            <Stroke>
                                <CssParameter name="stroke">#000000</CssParameter>
                                <CssParameter name="stroke-width">0.5</CssParameter>
                            </Stroke>
                        </Mark>
                        <Size>3</Size>
                        <Rotation>
                            <ogc:Function name="startAngle">
                                <ogc:PropertyName>geom</ogc:PropertyName>
                            </ogc:Function>
                        </Rotation>
                    </Graphic>
                </PointSymbolizer>
    </Rule>

I saw this question Drawing arrow on line using SLD of GeoServer? , but it doesn't cover my question about offset.

Can you help, please?

0

1 Answer 1

3

One possibility is to use the shape://oarrow "well known mark" which does place itself at the end of the line.

enter image description here

Alternatively, there is an AnchorPoint element in Symbology Encoding that can adjust your point.

<StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:se="http://www.opengis.net/se">

....
    <se:Graphic>
          <se:Mark>
            <se:WellKnownName>ttf://OpenSymbol#0x2227</se:WellKnownName>
            <se:Fill>
              <se:SvgParameter name="fill">#060505</se:SvgParameter>
            </se:Fill>
            <se:Stroke>
              <se:SvgParameter name="stroke">#130101</se:SvgParameter>
              <se:SvgParameter name="stroke-width">2</se:SvgParameter>
            </se:Stroke>
          </se:Mark>
          <se:Size>15</se:Size>
          <se:Rotation>
            <ogc:Add>
            <ogc:Function name="endAngle">
              <ogc:PropertyName>the_geom</ogc:PropertyName>
            </ogc:Function>
              <ogc:Literal>90</ogc:Literal>
            </ogc:Add>
          </se:Rotation>
          <se:AnchorPoint>
            <se:AnchorPointX>0.5</se:AnchorPointX>
            <se:AnchorPointY>0.6</se:AnchorPointY>
            </se:AnchorPoint>
        </se:Graphic>

Ignore the 90 in the rotation, I didn't have windings so I used a vertical arrow from a maths font.

enter image description here

7
  • Thank you Ian, shape://oarrow works perfectly for Function name="startPoint"! I forgot to say that I also have "endPoint". For lines with arrows from both sides. For endPoint it is placed incorrectly. Need the mirrored symbol. Jun 27, 2023 at 13:40
  • 1
    Can you provide a complete SLD that shows the problem, there shouldn't be a difference between start and end points like that
    – Ian Turton
    Jun 27, 2023 at 13:45
  • Modified the description. Added all three rules. Right sided arrow, Left sided and lines with 2 arrows both sides. Jun 27, 2023 at 13:52
  • Sorry, did you have a chance to check? Jun 29, 2023 at 20:25
  • Sorry no, most of the GeoServer team are at the FOSS4G conference in Kosovo this week.
    – Ian Turton
    Jun 29, 2023 at 22:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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