Prev Up Top Next Contents

7.4 Symbols

A symbol is a function to make a drawing. To define a symbol one needs to specify what this function does. To assign a symbol (for example when you write a map file in xtherion) amounts to write the name of this function in the data file, the one with extension ".th2", so that when processed by therion the symbol function is invoked.
A new symbol can be inserted in a layout with the "code metapost" command, or it can be compiled in the therion program.
Every symbol has a name, composed by
The newly defined symbol must be registered with the command "initsymbol( symbol_name )", unless it is compiled in in therion.
The therion language has four predefined pens, differing by the thickness of the lines: "PenA" (thick), "PenB", "PenC", and "PenD" (thin). There are two commands to draw lines: "thdraw" and "thfill". The first draws a line. The second fills also the area enclosed by the line. Do not use the MetaPost commands "draw" and "fill": "thdraw" and "thfill" take care of the symbol tranformation (ie, they apply the transformation "T" before drawing).

7.4.1 Points

The point symbols have usually four parameters The exceptions are "section" (no display), "label" (handled in a special way) and "station" (has only the position parameter). The four parameters define the transformation applyed to the symbol drawing when it is added to the map. The result of the symbol function (ie, the drawing of the symbol) is transformed by
    T = identity aligned A rotated R scaled S shifted P
Symbols are drawn in local coordinates, in which the drawing of the symbol is referred to the origin (0,0), and the units of length is u. The recommended range for the drawing is (-0.5u,0.5u) both in the X and Y axes. The symbol size is the variable U = (width/2, height/2). The symbol transformation maps a point (x,y) into
X = Px + S ( R00 (Ax Ux + x) + R01 (Ay Uy + y) )
Y = Py + S ( R10 (Ax Ux + x) + R11 (Ay Uy + y) )
As an example we define a symbol made of a square, rotated 45 degrees, with an exclamation point inside. The figure below is the result.
  code metapost
    def p_entrance_MY (expr P,R,S,A)=
      T:=identity aligned A rotated R scaled S shifted P;
      thfill (0,-u)--(u,0)--(0,u)--(0,.9u)--(.9u,0)--(0,-.9u)--cycle;
      thfill (0,-u)--(-u,0)--(0,u)--(0,.9u)--(-.9u,0)--(0,-.9u)--cycle;
      thfill (.1u,-.45u)..(0,-.35u)..(-.1u,-.45u)..(0,-.55u)..cycle;
      thfill (0,-.2u)..(.1u,-.1u)--(.2u,.4u)..(0,.6u)..(-.2u,.4u)--(-.1u,-.1u)..cycle;
    enddef;
    initsymbol("p_entrance_MY");
    let p_entrance = p_entrance_MY;
  endcode


A MetaPost symbol
Fig. 89. A MetaPost symbol

7.4.2 Lines

Line symbols have only one argument, the path of the line, expressed in absolute coordinates. Therefore the T trasformation must always be the identity: it is necessary to reset it to the identity before drawing the line symbol.
For example [thbook 59],
  def l_wall_bedrock_MY (expr P)=
    T:=identity;
    pickup PenB;
    thdraw P;
  enddef;
  initsymbol("l_wall_bedrock_MY");
Some line symbols have aditional arguments:

7.4.3 Areas

The area symbols, like the line symbols, have only one argument, the path of the area contour, expressed in absolute coordinates. The areas are region of the drawing and can be filled in three ways,
A pattern is specified using Metapost commands. You have to include the layout with the definition in the export command and to assign the new symbol using the symbol-assign command. For example,
layout water
  code metapost
    beginpattern(pattern_water_MY);
      draw origin..(.2u,-.1u)..(.4u,0)..(.6u,-.1u)..(.8u,0);
      patternxstep( 2u );
      patternystep( 0.5u );
      patterntransform( identity );
    endpattern;

    def a_water_MY (expr P)=
      T:=identity;
      thclean P;
      thfill P withpattern pattern_water_MY;
    enddef;
    initsymbol("a_water_MY");
  endcode

export map -proj plan \\
  -layout water \\
  -layout-symbol-assign area water MY

To fill the area with a color, say blue, use "thfill P withcolor (0, 0, 1);" in the definition of your water area symbol.

Area water custom symbol
Fig. 90. Area water custom symbol

7.4.4 Examples

If you want to draw a symbol using metapost you can start with an existing symbol and edit it. You need to remember a few points:

7.4.4.1 Example 1

This is an example of point symbol.
  code metapost
     def p_gradient_MY (expr P,R,S,A) =
        U:=(.15u, .4u);    
        T:=identity aligned A rotated R scaled S shifted P;
        pickup PenC;

        #Left Hand side
        thdraw (-.3u, -.2u) -- (-.7u, .1u);
        thdraw (-.2u, -.1u) -- (-.4u, .6u);

        #Centerline
        thdraw (0u, 0u) -- (0u, .9u);

        #Right side
        thdraw (.3u, -.2u) -- (.7u, .1u);
        thdraw (.2u, -.1u) -- (.4u, .6u);

     enddef;
     initsymbol ("p_gradient_MY");
  endcode

7.4.4.2 Example 2

It is convenient to define the code for symbols (and other things) in a data file which will then be included in the configuratin file, using the input command. Therefore the configuration file has something like
   input layout.th
   source main.th

   export map -layout plan -output ABC.pdf
   export map -layout print -output ABC_Printable.pdf
The "layout.th" file contains the layout commands and the definitions of the new symbols. The following code is by Ph. Schuchardt. Notice that

layout plan scale 1 200 #PDF DOCUMENTION code tex-map \cavename={nome della grotta} \comment{testo del commento} endcode code metapost def l_wall_bedrock_MY (expr P) = T:=identity; pickup PenA; thdraw P; enddef; def p_gradient_MY (expr P,R,S,A) = U:=(.15u, .4u); T:=identity aligned A rotated R scaled S shifted P; pickup PenC; # thdraw and thfill commands ... enddef; def a_sand_MY (expr p) = T:=identity; % thclean p; pickup PenC; path q; q = bbox p; picture tmp_pic; tmp_pic := image( for i = xpart llcorner q step .3u until xpart urcorner q: for j = ypart llcorner q step .3u until ypart urcorner q: draw origin shifted ((i,j) randomized 0.2u) withpen PenC; endfor; endfor; ); clip tmp_pic to p; draw tmp_pic; enddef; def a_debris_MY (expr p) = T:=identity; pickup PenC; path q, qq; q = bbox p; picture tmp_pic; tmp_pic := image( for i = xpart llcorner q step u until xpart urcorner q: for j = ypart llcorner q step u until ypart urcorner q: qq := punked( ( (-.2u,-.2u)--(.2u,-.2u)--(.2u,.2u)--(-.2u,.2u)--cycle ) randomized (u/2) ) rotated uniformdeviate(360) shifted ((i,j) randomized u); if xpart (p intersectiontimes qq) < 0: thclean qq; thdraw qq; fi; endfor; endfor; ); clip tmp_pic to p; draw tmp_pic; enddef; initsymbol ("a_sand_MY"); initsymbol ("a_debris_MY"); initsymbol ("p_gradient_MY"); initsymbol ("l_wall_bedrock_MY"); endcode symbol-assign area sand MY symbol-assign area debris MY symbol-assign line wall:bedrock MY symbol-assign point gradient MY endlayout
The layout command symbol-assign is used to set the way a symbol should be drawn. The syntax is symbol-assign category type set, where the category is one of "point", "line", "area", "group" and "special". The type is the type of the symbol you want to draw differently. For the category "group" the type can be "all", "centerline", "sections", "water", "speleothems", "passage-fills", and "equipment". The set is the symbol-set you want to use for the symbol. For example, to use the NSS symbol for the low-end point (the default is the UIS symbol),
   -layout-symbol-assign point low-end NSS

7.4.5 User defined symbols

Wookey wrote
It looks like we need to add the snippet provided to the symbols in mpost/thPoint.mp file and then rebuild therion.
Guys - how do we add new symbols like this? If the answer is 'rebuild therion from source' then something is wrong in the design... Maybe an extrernal path is checked as well as the internal library?
It must be possible to have an external symbols library. I know you built everything in to avoid people having problems with paths, but it is a horrible hack. At least for the debian version I would really like to move the metpost and tex stuff back into the places it should be, then I hope adding new symbols would be something that could be by users.

This mail snippet shows that there was the need for user-defined symbols, loadable by therion at run time, and not just compiiled in the program. User defines symbols have type u, and can be either point, line or area. They must have a subtype: an arbitrary string used to distinguish among different user defined symbols. For example, the syntax for a user defined point symbol is
	point X Y u:subtype
Therefore, when you add a point of type u you must give its subtype as well. The same requirement applies to lines and areas of type u.
The metapost code for the symbol must be inserted in the layout command. More precisely the following metacode functions must be defines,
        def p_u( expr position, angle, scale, alignment, subtype )
        def l_u( expr path, subtype )
	def a_u( expr path, subtype )
User defined symbols, for which no metapost code is given, are rendered in red. Points are red dots, lines are red, and areas are filled with red. Symbols that have been defined are rendered in black, unless a specific color is not defined (with the withcolor metapost option).
A nice example of user defined symbol, a bat, is provided in the samples/u-symbols subdirectory of the therion distribution.

7.4.6 The examples

Area custom symbol

therion users - Thu Mar 4 22:15:10 2010
Prev Up Top Next Contents

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License.