Opened 12 years ago

Closed 12 years ago

#4117 closed enhancement (fixed)

POLAROFFSET (was SYMBOLTRANSFORMORDER) for special symbols rendering

Reported by: aboudreault Owned by: aboudreault
Priority: normal Milestone: 6.2 release
Component: Documentation - MapServer Version: svn-trunk (development)
Severity: normal Keywords:
Cc: dmorissette, tbonfort, sdlime, havatv, aboudreault

Description (last modified by aboudreault)

This ticket is to track the new keyword of symbol transform order.

A while ago, it has been discussed about a new way to render a symbol, which in this case is an arrow. The need is to be able to draw the body arrow (a line) scaled depending of a value (ie, the magnitude in vector field) but to not scale the arrow head.

Mike, Daniel and Thomas discussed this problem in Denver during FOSS4G and they came up with the concept of ARROWBODY and ARROWHEAD. Those concepts are essentially to determine what need to be scaled. After some discussions and reviews, we realized that the the functionality is not only related to an arrow but can be applied to other cases. The main issue about this is about the translation and rotation of the 2 symbols... to get them properly rendered. Since MapServer rotate, scale then translate, which is not appropriate for this case... we need a mechanism to inverse that order. That what SYMBOLTRANSFORMORDER is for: to inverse to order of the operations

- RST: Rotate, scale, translate (default)                                                                                           
- TSR: Translate, scale, rotate                                                              

Here's the approach we would like to use:

  • We define two symbols: ie. an arrow body and an arrow head.
  • The arrow head symbol needs to have the ANCHORPOINT set to the left-middle point.
  • We define 2 styles: one for the body and the other for the head.
  • The arrow head must specify: SYMBOLTRANSFORMORDER TSR (for the arrow case, we do not need to specify this option for the arrow body style... but it might be required for some rendering case)
  • For the arrow case, to position the arrow head properly, we need to set the X offset with (size_of_arrow_body/2): for this need, we added the attribute binding [uv_length_2] (uv layers only).

Here's is a concrete example:

# My symbols
SYMBOL
  NAME "arrowbody"
  TYPE VECTOR
  POINTS
     0 0
     1 0
  END
END

SYMBOL
  NAME "arrowhead"
  TYPE vector
  FILLED true
  ANCHORPOINT 0 0.5 # left(x)-middle(y). (See documentation)
  POINTS
    0 2
    2 1
    0 0
  END
END

# UV Layer example (vector field)
LAYER
  NAME uv
  TYPE POINT
  STATUS default
  CONNECTIONTYPE UVRASTER
  DATA /mnt/data/raster/grib/wind.vrt
  PROJECTION
    "init=epsg:4326"
  END
  PROCESSING "BANDS=1,2"
#  PROCESSING "RESAMPLE=AVERAGE" # default
#  PROCESSING "UV_SPACING=32" #default
#  PROCESSING "UV_SIZE_SCALE=1" #default is 1

  CLASS
    STYLE
      WIDTH 3
      SIZE [uv_length]
      ANGLE [uv_angle]
      SYMBOL "arrowbody"
      COLOR 100 255 0
    END

    STYLE
      ANGLE [uv_angle]
      SYMBOL "arrowhead"
      SYMBOLTRANSFORMORDER TSR
      SIZE 10
      COLOR 255 0 0
      OFFSET [uv_length_2] 0
    END
  END
END

Attachments (1)

symboltransform.patch (13.0 KB ) - added by aboudreault 12 years ago.

Download all attachments as: .zip

Change History (13)

comment:1 by aboudreault, 12 years ago

Description: modified (diff)

comment:2 by tbonfort, 12 years ago

Cc: tbonfort sdlime havatv added
  • If I understand correctly, TSR only applies to the specified OFFSET, right ?
  • Where in the code do you plan to make the changes required for this ?
  • Why do you need [uv_length_2] (which I suppose is half the length of the [uv_length]) ?

comment:3 by havatv, 12 years ago

I am probably on thin ice here...

As far as I can see, what we want to do here is to specify offset as polar coordinates instead of cartesian coordinates.

Another way to do this could be to allow for more mathematics in the OFFSET parameter. An equivalent way of specifying the symbol above could then be:

    STYLE
      SYMBOL "arrowhead"
      ANGLE [uv_angle]
      SIZE 10
      COLOR 255 0 0
      OFFSET ([uv_length]*cos([uv_angle])) ([uv_length]*sin([uv_angle]))
    END

If that is too heavy, it could also be possible to introduce a new STYLE parameter:

  POLAROFFSET <radius> <angle>

Specifies an offset for the symbol using polar coordinates.
radius is the offset distance.
angle is the offset angle (counter clockwise, reference direction to the right(?)).

Anyway, just some new ideas / thoughs.

in reply to:  2 comment:4 by aboudreault, 12 years ago

Replying to tbonfort:

  • If I understand correctly, TSR only applies to the specified OFFSET, right ?
  • Where in the code do you plan to make the changes required for this ?
  • Why do you need [uv_length_2] (which I suppose is half the length of the [uv_length]) ?

tbonfort, you are right, the TSR only applies to the specified offset. The code for this modification is mostly in maprendering.c. It's a simple patch. Since I don't what size is my symbol, I have to put the anchor point to left-middle.. so I need [uv_length_2] to move the symbol half the length of the line. I would be glad to avoir that attribute though. I'm going to attach my patch... feel free to review it you want.

by aboudreault, 12 years ago

Attachment: symboltransform.patch added

comment:5 by aboudreault, 12 years ago

ah.. this patch is missing && s.rotation!=0 at line 871.

comment:6 by tbonfort, 12 years ago

I very much prefer havard's polaroffset keyword, as I find it much less misleading than the tsr notation.

I was initally thinking of using something like

ANGLE [orientation]
OFFSET [radius] -99

as we do for line symbol. In this case (i.e., applied to a marker symbol) it would be treated as a polar offset with radius [radius] and angle [orientation]. This is less flexible as in that case the orientation of the symbol is tied to the orientation of the offset.

comment:7 by aboudreault, 12 years ago

Cc: aboudreault added
Component: MapServer C LibraryMapServer Documentation

Thanks havatv! We liked your idea of POLAROFFSET. It's a way more representative. It's committed in r12875. Here's a complete example:

SYMBOL
  NAME "arrowbody"
  TYPE VECTOR
  POINTS
     0 0
     1 0
  END
END

SYMBOL
  NAME "arrowhead"
  TYPE vector
  FILLED true
  ANCHORPOINT 0 0.5
  POINTS
    0 2
    2 1
    0 0
  END
END

LAYER
  NAME uv
  TYPE POINT
  STATUS default
  CONNECTIONTYPE UVRASTER
  DATA /mnt/data/raster/grib/wind.vrt
  PROJECTION
    "init=epsg:4326"
  END
  PROCESSING "BANDS=1,2"
#  PROCESSING "RESAMPLE=AVERAGE" # default
#  PROCESSING "UV_SPACING=32" #default
#  PROCESSING "UV_SIZE_SCALE=1" #default is 1

  CLASS
    STYLE
      WIDTH 3
      SIZE [uv_length]
      ANGLE [uv_angle]
      SYMBOL "arrowbody"
      COLOR 100 255 0
    END

    STYLE
      ANGLE [uv_angle]
      SYMBOL "arrowhead"
      SIZE 10
      COLOR 255 0 0
      POLAROFFSET [uv_length_2] [uv_angle]
    END
  END
END

To be documented:

  • An example of this use case (with the symbol and anchorpoint setting etc..)
  • the new POLAROFFSET option
  • OFFSET option now supports attribute binding.

comment:8 by havatv, 12 years ago

Are you planning to document it, aboudreault?

I have tested POLAROFFSET (without the UVRASTER connection type), and found that it works as expected. I understand that UVRASTER provides uv_length_2, so the UVRASTER case seems to be OK.

For non-UVRASTER layers it is a bit awkward to have to have both an attribute for the length and the halflength in order to create arrow symbols.

Would it be extremely complicated to allow calculations (expressions?) with attribute bindings? For example:

  POLAROFFSET (0.5*[length]) [angle]

Such a feature would be very useful for attribute bindings in many contexts, especially for users who do not use PostGIS. It could for example be used to render arrow tails (uv_angle+180)...

Here is the Mapfile I have used for testing (ANCHORPOINT can be used or not - a matter of taste):

MAP
  SIZE 300 200
  IMAGETYPE png   # gif|png|jpeg|wbmp]
  EXTENT 0 0 300 200
  UNITS meters
  SYMBOL
    NAME "circlef"
    TYPE ellipse
    FILLED true
    POINTS
      1 1
    END
  END
  SYMBOL
    NAME "line"
    TYPE vector
    POINTS
      0 0
      1 0
    END
  END
  SYMBOL
    NAME "arrowhead"
    TYPE vector
    POINTS
      0 2
      4 1
      0 0
    END
    #ANCHORPOINT 0 0.5
  END
###########################################################
  LAYER  # Points - vectors
    STATUS DEFAULT
    TYPE POINT
    PROCESSING "ITEMS=length,rotation,length_2"
    FEATURE
      POINTS
        20 20
      END # Points
      ITEMS "10;45;5"
    END # Feature
    FEATURE
      POINTS
        160 20
      END # Points
      ITEMS "20;30;10"
    END # Feature
    FEATURE
      POINTS
        100 100
      END # Points
      ITEMS "40;120;20"
    END # Feature
    CLASS
      STYLE  # right offset rel. to line direction
        SYMBOL "line"
        COLOR 0 0 0 # black
        SIZE [length]
        ANGLE [rotation]
        WIDTH 2
      END # STYLE
      STYLE  # polaroffset
        SYMBOL "arrowhead"
        COLOR 0 0 0   # black
        ANGLE [rotation]
        SIZE 8
        #POLAROFFSET [length] [rotation]
        POLAROFFSET [length_2] [rotation]
        #POLAROFFSET [0] [rotation]
      END # STYLE
      STYLE  # red dot at the point's location
        SYMBOL "circlef"
        COLOR 255 0 0   # red
        SIZE 4
      END # STYLE
      STYLE  # green dot at the polaroffset point
        SYMBOL "circlef"
        COLOR 0 255 0   # green
        SIZE 4
        #POLAROFFSET [length_2] [rotation]
        POLAROFFSET [length] [rotation]
      END # STYLE
    END # CLASS
  END # LAYER
END # MAP

comment:9 by tbonfort, 12 years ago

I've added your test mapfile to msautotest in r12877, thanks

comment:10 by aboudreault, 12 years ago

I'm afraid that yes... it would require a lot of work to modify the lexer to add this. Perhaps you could start a thread about this as an enhancement on the dev list... maybe steve has the better idea of what it would need. btw for the vector field, I also added a binding [uv_minus_angle] for the arrow tail (angle+180). I have no plan to document this at the moment... but I will certainly do it if nobody from the documentation team can do it.

comment:11 by havatv, 12 years ago

I have attempted to document POLAROFFSET and uvraster in r12879. Please check! I have assumed that nothing needs to be done for mapscript.

comment:12 by havatv, 12 years ago

Resolution: fixed
Status: newclosed
Summary: SYMBOLTRANSFORMORDER for special symbols renderingPOLAROFFSET (was SYMBOLTRANSFORMORDER) for special symbols rendering

I have changed the title. I close the ticket.

If there is a need to do something with the Mapscript documentation, please re-open the ticket and provide instructions.

Note: See TracTickets for help on using tickets.