From XastirWiki
Jump to: navigation, search

This document is the Wiki-fied version of the document at my personal web site I have not necessarily finished formatting it for the wiki.

DBFAWK is a powerful feature of Xastir that allows the user to specify the display properties of a shape file on a file-by-file or type-by-type basis. I found, though, that I needed to write down a procedure for producing new DBFAWK configuration files. I provide it here in the hopes that others find it useful.

What's a dbfawk file for?

The basic task of the DBFAWK file is to tell xastir how to display various shapes contained in the corresponding shapefile.

What's in a dbfawk file?

A dbfawk file contains pattern matching rules and variable assignments. When a dbf record (the attributes associated with a shapefile) has an attribute that matches a pattern in the dbfawk file, the code within braces is executed to set variables that xastir uses to determine how (or if) to display the associated shape (line, polygon, or point).

How are dbfawk files located and used?

There are two techniques used by xastir to figure out what dbfawk file to use with a given shapefile. The techniques allow Xastir to use a general dbfawk file for all maps that match a certain pattern, but also allow you to specify alternate rendering options for specific maps on a case-by-case basis.

If a file with the same base name as the map but with".dbfawk" at the end exists in the same directory as the map (e.g. "mymap.shp" and "mymap.dbfawk") then it is used by Xastir for rendering that one particular map. Otherwise, xastir scans the dbfawk files in the "/usr/local/share/xastir/config" directory for one with a matching "signature."

The dbf signature is the list of all the attribute names in the dbf file concatenated together with ":" separating them. Generally, when one obtains collections of shapefiles of a particular type from a single source (e.g., OpenStreetMaps road shapefiles, or U.S. National Map Hydrography Features), the signatures are usually the same for all the files in the collection. Thus, one could create a single DBFAWK file that renders all of these maps the same way by matching the signatures.

If you want to override the default rendering of a map for which Xastir already has an existing signature-matching dbfawk file, simply create a new dbfawk file in the same directory as the shapefile, and give it the same base name as the shapefile, but with a ".dbfawk" suffix.

What display functions can I tweak with dbfawk?

dbfawk variableuse
colorsets the color of lines drawn (see below)
lanessets width of lines drawn
namesets the text that will be used as the label for the feature
symbolsets the symbol that will be used for point data (using group/symbol/overlay specification)
fill_stylesets fill style per XSetFillStyle man page.

0=solid (default), 2=stippled (as used for weather alerts). 1 is "tiled"? and

3 is "Opaque Stippled"?
fill_colorsets color used to fill area features --- uses same numbers as color variable (below)
fill_stylechooses fill style. At this time only 0 and 2 are

worth using. 0 is "solid" and "2" is stippled, per XSetFillStyle. See below.

fill_stippleWhen fill_style is 2, chooses stipple pattern. 0 is a 13 percent stipple, 1 is 25%, 2 is 50%.
patternsets line pattern. 0=solid, 1=dashed, 2="double dash" (per XSetLineAttributes)
display_levelsets zoom above which the feature will be stop being displayed
label_levelsets zoom above which labels will be stop being displayed
label_colorsets color of labels. (see section on selecting colors, below)
font_sizechooses font size. (0="Tiny", 4="Huge", per settings in Map->Configure->Map label fonts menu)

This table of dbfawk variables above was taken from map_shp.c on 10 Oct 2004. I don't guarantee that it'll be accurate. Check README.MAPS and map_shp.c.

I have a new shapefile. How do I get it to display nicely in Xastir with DBFAWK enabled?

If its signature doesn't match an existing dbfawk file, you pretty much have to write your own. Here are the steps I go through when I need to do this.

Given a shapefile and associated DBF file with attributes:

  1. Use "dbfinfo" (it's part of the shapelib "contrib" directory, you need to build it separately from shapelib) to reveal the list of attributes in the DBF file. For example, I have a set of shapefiles converted from US Forest Service trails
        > dbfinfo /usr/local/share/xastir/maps/misc_vector/USFS_SandiaRD
    67 Columns,  544 Records in file
             FNODE_         integer  (11,0)
             TNODE_         integer  (11,0)
             LPOLY_         integer  (11,0)
             RPOLY_         integer  (11,0)
             LENGTH           float  (31,15)
             TRAIL_         integer  (11,0)
           TRAIL_ID         integer  (11,0)
               TYPE          string  (1,0)
               CODE          string  (2,0)
          CODE_MEMO          string  (80,0)
             METHOD          string  (2,0)
               MISC          string  (1,0)
            TE_UNIT          string  (1,0)
           EXISTVEG          string  (1,0)
             FS_OWN          string  (1,0)
              TRAIL          string  (1,0)
               ROAD          string  (1,0)
              WATER          string  (1,0)
             STREAM          string  (1,0)
               PLSS          string  (1,0)
           ADM_DIST          string  (1,0)
           ADM_UNIT          string  (1,0)
            PASTURE          string  (1,0)
           SPEC_MGT          string  (1,0)
           HRTGSRVY          string  (1,0)
          RD_RTE_NO          string  (35,0)
          TR_RTE_NO          string  (35,0)
          STRM_NAME          string  (80,0)
         SURVEY_NUM          string  (13,0)
               CFF1          string  (3,0)
               CFF2          string  (3,0)
               CFF3          string  (3,0)
               CFF4          string  (3,0)
               CFF5          string  (3,0)
               CFF6          string  (3,0)
               CFF7          string  (3,0)
               CFF8          string  (3,0)
               CFF9          string  (3,0)
              CFF10          string  (3,0)
             NUMBER          string  (35,0)
            NUMBER0          string  (35,0)
               LEVE          string  (20,0)
              TYPE0          string  (20,0)
          ROAD_TYPE          string  (20,0)
              LANES          string  (20,0)
            SURFACE          string  (20,0)
            PROBLEM          string  (20,0)
            CLOSURE          string  (20,0)
               DATE         integer  (8,0)
               TIME          string  (20,0)
           OPERATOR          string  (20,0)
           COMMENTS          string  (50,0)
           MAX_PDOP           float  (31,15)
           GPS_DATE         integer  (8,0)
           GPS_TIME          string  (20,0)
         GPS_LENGTH           float  (31,15)
          HORZ_PREC           float  (31,15)
          VERT_PREC           float  (31,15)
          HORZ_PRE0           float  (31,15)
          VERT_PRE0           float  (31,15)
           TRAIL_NO          string  (10,0)
             SOURCE          string  (10,0)
             MAPUSE          string  (25,0)
               NAME          string  (30,0)
             MILES2           float  (23,16)
              COOID          string  (10,0)
             STATUS         integer  (11,0)

    This list of attributes will be used in the DBFAWK file to recognize files to which the dbfawk file applies.

    It is also possible to use "testdbfawk" that is built in the xastir source tree when you compile xastir with DBFAWK enabled.

    Prior to Git versions of 24 September 2008, "testdbfawk" was called "testawk" and the Xastir install process didn't install the program, leaving it built but uninstalled in the "src" directory. Users of these older versions of Xastir will have to build the code and execute testawk from its non-system location in the build directory.

      > testdbfawk -D /usr/local/share/xastir/config -d /usr/local/share/xastir/maps/misc_vector/USFS_SandiaRD
      67 Columns,  544 Records in file
  2. Copy a dbfawk file for a type of map that is close (e.g. tgrlk.dbfawk is a reasonable starting point for line type shapefiles, but it is fairly complex and handles a lot of feature types).
  3. Replace the contents of the "dbfinfo" variable with the fields you found in step 0. e.g., for my USFS shapefiles above, the dbfinfo variable is:

    It is important to put a semicolon at the end of this. Xastir will be confused if you don't.

  4. Figure out which of the godzillion attributes you actually need to examine to get your rendering right. In my case I needed a concatenation of the "NAME" and "TRAIL_NO" fields to form line lables, and the CFF1 field to determine what type of feature I was dealing with. You then make sure the "dbffields" variable has those fields in it. It is best to keep this list to the smallest number of fields you really need to get your rendering right; the rendering code reads only these fields in from the shapefile, so the more fields you put here the more file IO Xastir will be doing for every shape it tries to render. In my case this minimum set was:

    This selects the feature code (CFF), name and trail number. Again, don't forget the semicolon at the end.

    NOTE: THE SEMICOLON AT THE END OF DBFFIELDS IS REQUIRED due to a bug in the dbfawk parser. Leaving it off will cause dbfawk to mis-parse the dbffields variable to include all characters up to the closing brace in the BEGIN block. This bug is hidden if there *are* no characters between the closing quote and brace, but mysteriously shows up if there is a newline. So just put a semicolon at the end for correctness.

  5. Create rules in your dbfawk file that match various patterns that can show up in the attributes. Here's where you set the "name" variable to the appropriate thing you want xastir to display as well as things like line type, color, label color, and how far out you can be zoomed and still see the labels. In my case, sometimes trails are listed in the dbf file as "UNK" and I don't want that name displayed, other times they're listed with a trail number only and I want it to show up as "Tr. #". So I do:
      # Use this rule to re-initialize variables between records.
      # These will be your defaults
      # My defaults are "1 lane, color brown, pattern "LineDoubleDash" (see the 
      #  XSetLineAttributes man page), always display the line, display labels if
      #  zoomed in to level 32 or smaller, black labels, large font) 
      # The defaults are overridden by specific rules below
      BEGIN_RECORD {key=""; lanes=1; color=4; name=""; filled=0; pattern=2; display_level=1; label_level=32; label_color=8; symbol=""; font_size=3}
      # Render hiking trails and unimproved roads
      # This sets the color of the line and pattern based on the feature type
      # Hiking trails are CFF 107.  We'll render these as "two lane" (so they get nice, thick lines), brown (color 69), dashed lines (pattern 1), and only display
      # them if we're zoomed in to levels lower than 128
      /^CFF1=107$/ {lanes=2; color=69; pattern=1;display_level=128;}
      # dashed steel blue lines for class 4 unimproved roads.  These have CFF that start with 106.
      /^CFF1=106*$/ {lanes=2; color=26; pattern=1;display_level=128;}
      # Now look for a name number and/or trail number
      # Never display "UNK" as a trail name
      /^NAME=[uU][nN][kK]$/ {skip;}
      /^TRAIL_NO=[uU][nN][kK]$/ {skip;}
      # Otherwise, select the name given in the record
      /^NAME=(.+)$/ {name="$1";}
      # and append the trail number to the name
      /^TRAIL_NO=(.+)$/ {name="$name (Tr. $1)";}

    In this example I set most variables to some default at the beginning of each DBF record, and then look for particular patterns. The USFS maps have an attribute called "CFF1" (CFF stands for Cartographic Feature File) that contains an ID code for the feature type of the corresponding shape. CFF=107 means it's a hiking trail, so I set the zoom level at which the trail will show up to 128, the color to 69 (which is mapped to "brown1" in main.c), and 2 "lanes" that last seems odd, but I found that at zoom level 128 my background rasters always seemed to make "one lane" trails invisible.

  6. Place your DBFAWK file somewhere where it'll be found. If you have a dbfawk file that applies to many shapefiles, name it something generic and put it in {base}/share/xastir/config. If it's specific to one shapefile, give it the same base name as the shapefile and a .dbfawk suffix and put it in the same directory as the shapefile.

There are one or two cases in the files on this web site where I don't properly initialize *all* the dbfawk variables in the BEGIN_RECORD line, and sometimes that results in defaults being taken from whatever was used last. The code has recently been updated so that each map begins with default values in all variables, but you can still wind up with wierd behavior if you fail to reinitialize variables in BEGIN_RECORD when some rule changes a value that isn't reinitialized --- all subsequent records will then have that changed value until another rule changes it again. I haven't had a chance to go back and fix them all. README.MAPS currently lists most of the DBFAWK variables that should be reset in BEGIN_RECORD, but sometimes a new one is added and README.MAPS doesn't get updated to reflect it --- you have to look at the dbfawk files that come with the distribution or at map_shp.c to pick that up. There are a few new ones since README.MAPS was updated (font_size, for example).

Where do I find out what number corresponds to what color?

Sadly, Xastir's color handling is rather old-school, and you can't just specify a color by giving its RGB values. That's because Xastir still has code designed to work on ancient 8-bit X displays that used a pseudocolor table. Xastir allocates a number of specific colors from the X server when it starts up, and these colors are accessed from an array by their index into that array. Xastir allocates the colors using the names that are defined in the "rgb.txt" file associated with your X server. If you really want to know what the RGB values of these colors are, find the color name in that file.

The only place you can find information about what index number corresponds to what color is in main.c. There is no rhyme or reason to the numbering --- colors are simply allocated in whatever order a developer added them, and the numbers are essentially random. Finding the right number for a color you want can be a challenge. For your convenience I've made the following table based on what was in main.c on the day I wrote this section, but main.c is the definitive source and I am not going to guarantee that this table will stay up-to-date:

Hex valuedecimalColor (as X11 calls it)
0x03 3cyan
0x04 4brown
0x05 5plum
0x06 6orange
0x07 7darkgray
0x08 8black
0x09 9blue
0x0a 10green
0x0b 11mediumorchid
0x0c 12red
0x0d 13magenta
0x0e 14yellow
0x0f 15white
0x10 16black
0x11 17black
0x12 18black
0x13 19black
0x14 20lightgray
0x15 21magenta
0x16 22mediumorchid
0x17 23lightblue
0x18 24purple
0x19 25orange2
0x1a 26SteelBlue
0x20 32white
0x21 33black
0x22 34blue
0x23 35green
0x24 36cyan3
0x25 37red
0x26 38magenta
0x27 39yellow
0x28 40gray35
0x29 41gray27
0x2a 42blue4
0x2b 43green4
0x2c 44cyan4
0x2d 45red4
0x2e 46magenta4
0x2f 47yellow4
0x30 48gray53
0x40 64yellow
0x41 65DarkOrange3
0x42 66purple
0x43 67gray80
0x44 68red3
0x45 69brown1
0x46 70brown3
0x47 71blue4
0x48 72DeepSkyBlue
0x49 73DarkGreen
0x4a 74red2
0x4b 75green3
0x4c 76MediumBlue
0x4d 77white
0x4e 78gray53
0x4f 79gray35
0x50 80gray27
0x51 81black
0x52 83LimeGreen
0x60 96HotPink
0x61 97RoyalBlue
0x62 98orange3
0x63 99yellow3
0x64 100ForestGreen
0x65 101DodgerBlue
0x66 102cyan2
0x67 103plum2
0x68 104MediumBlue
0x69 105gray86
0xfe 254pink