From XastirWiki
Jump to: navigation, search

As much about dbfawk as you are likely to get anywhere else

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.

This wiki page has ended up being pretty much the only documentation there is about dbfawk. If you can't find the answer to your question here, please open an issue report on github at https://github.com/Xastir/Xastir/issues.

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
min_display_levelsets zoom below which the feature will 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)
label_methodselects how to choose label points for polygon maps. 0=default, 1="use specified lat/lon"
label_lonthe longitude at which to place the label if label_method=1 and this is a polygon map. Ignored otherwise.
label_latthe latitude for label placement (see label_lon)

This table of dbfawk variables above was taken from map_shp.c on 12 Dec 2025. I don't guarantee that it'll be accurate for long after that. Check map_shp.c for the definitive answer.

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.

In a nutshell:

  1. determine what fields the DBF file has
  2. create a dbfawk file to use, possibly copying an existing one and editing the copy
  3. use the list of fields you found in step 1 to set the "dbfinfo" variable in your new dbfawk
  4. decide which of those fields are relevant to your rendering needs and set the "dbffields" variable to include those few fields
  5. craft a dbfawk file that assigns rendering variables (as described above) based on field values it finds
  6. look at how your map renders in Xastir
  7. refine your dbfawk until it looks good

How that works out in detail is described below with an example of how I did it for a shapefile I obtained somewhere and wanted to use as a map.

Given a shapefile and associated DBF file with attributes:

  1. Use "testdbfawk" that is built in the xastir source tree when you compile xastir with DBFAWK enabled to list the fields. For example, I have a set of shapefiles converted from US Forest Service trails, and testdbfawk told me this:
      > testdbfawk -D /usr/local/share/xastir/config -d /usr/local/share/xastir/maps/misc_vector/USFS_SandiaRD
      67 Columns,  544 Records in file
     sig:  NODE_:TNODE_:LPOLY_:RPOLY_:LENGTH:TRAIL_:TRAIL_ID:TYPE:CODE:CODE_MEMO:METHOD:MISC:TE_UNIT:EXISTVEG:FS_OWN:TRAIL:ROAD:WATER:STREAM:PLSS:ADM_DIST:ADM_UNIT:PASTURE:SPEC_MGT:HRTGSRVY:RD_RTE_NO:TR_RTE_NO:STRM_NAME:SURVEY_NUM:CFF1:CFF2:CFF3:CFF4:CFF5:CFF6:CFF7:CFF8:CFF9:CFF10:NUMBER:NUMBER0:LEVE:TYPE0:ROAD_TYPE:LANES:SURFACE:PROBLEM:CLOSURE:DATE:TIME:OPERATOR:COMMENTS:MAX_PDOP:GPS_DATE:GPS_TIME:GPS_LENGTH:HORZ_PREC:VERT_PREC:HORZ_PRE0:VERT_PRE0:TRAIL_NO:SOURCE:MAPUSE:NAME:MILES2:COOID:STATUS  
    [etc.]
    

    The information following "sig:" that this produces is in a format that can be cut and pasted into your dbfawk file to set the dbfinfo value (don't include the "sig:" part!).


    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 "dbfinfo" (it's part of the shapelib install) to reveal the list of attributes

       in the DBF file. There's no real benefit do doing that, since the fields are not printed in a way that is easily copied into your dbfawk file, but, hey, you do you.
    
        > 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)
    


  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:
    dbfinfo="FNODE_:TNODE_:LPOLY_:RPOLY_:LENGTH:TRAIL_:TRAIL_ID:TYPE:CODE:CODE_MEMO:METHOD:MISC:TE_UNIT:EXISTVEG:FS_OWN:TRAIL:ROAD:WATER:STREAM:PLSS:ADM_DIST:ADM_UNIT:PASTURE:SPEC_MGT:HRTGSRVY:RD_RTE_NO:TR_RTE_NO:STRM_NAME:SURVEY_NUM:CFF1:CFF2:CFF3:CFF4:CFF5:CFF6:CFF7:CFF8:CFF9:CFF10:NUMBER:NUMBER0:LEVE:TYPE0:ROAD_TYPE:LANES:SURFACE:PROBLEM:CLOSURE:DATE:TIME:OPERATOR:COMMENTS:MAX_PDOP:GPS_DATE:GPS_TIME:GPS_LENGTH:HORZ_PREC:VERT_PREC:HORZ_PRE0:VERT_PRE0:TRAIL_NO:SOURCE:MAPUSE:NAME:MILES2:COOID:STATUS";
    
    

    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:
           dbffields="CFF1:NAME:TRAIL_NO";
    

    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.

    Some detail to note:

    • The "BEGIN_RECORD" section initializes variables that will apply to every shape in the file unless overriden by specific rules later
    • Lines that begin with a pattern starting and ending with "/" are pattern matching rules.
      • On the left side of the equal sign is a field name in your DBF file, on the right a pattern to match using regular expressions.
      • Stuff in the regular expression delimited by parentheses can be referenced in the rule by the strings "$1" through "$9", with "$1" referring to the first parenthesized match, and "$9" the ninth. So in my name-matching line, where I have
        /NAME=(.+)$/"
        "$0" refers to whatever value was matched by ".+" (one or more characters of any type).
    • the stuff in braces following the pattern match are actions to be taken. The only actions available are those that set dbfawk variables, or "next" or "skip".
      • "name=$1" means "set the dbfawk variable 'name' to the value of the string matched by the first parenthesized pattern"
      • "next" means "we're done processing this record", which you would use when a pattern match of this pattern means you should stop considering any other rules in the file for this shape.
      • "skip" means "we're done processing any rules for the field currently being tested, go get the next one". Use this when you don't want any other rules in the file that might also match to apply to this field.
  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 by calling "GetPixelByName" from color.c and storing them into a "colors" array, and these colors are accessed when needed by their index into that array.

Xastir allocates the colors using the names that are defined in the "xastir.rgb" file that is installed into the "config" directory along with other Xastir files. This file contains the RGB values in the first three columns and a name for that color in the fourth column. 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 into the color array 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 (14 Dec 2025 was the last update), 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 xastir.rgb calls it)
0x00 0 DarkGreen
0x01 1 purple
0x02 2 DarkGreen
0x03 3 cyan
0x04 4 brown
0x05 5 plum
0x06 6 orange
0x07 7 darkgray
0x08 8 black
0x09 9 blue
0x0a 10 green
0x0b 11 mediumorchid
0x0c 12 red
0x0d 13 magenta
0x0e 14 yellow
0x0f 15 white
0x10 16 black
0x11 17 black
0x12 18 black
0x13 19 black
0x14 20 lightgray
0x15 21 magenta
0x16 22 mediumorchid
0x17 23 lightblue
0x18 24 purple
0x19 25 orange2
0x1a 26 SteelBlue
0x20 32 white
0x21 33 black
0x22 34 blue
0x23 35 green
0x24 36 cyan3
0x25 37 red
0x26 38 magenta
0x27 39 yellow
0x28 40 gray35
0x29 41 gray27
0x2a 42 blue4
0x2b 43 green4
0x2c 44 cyan4
0x2d 45 red4
0x2e 46 magenta4
0x2f 47 yellow4
0x30 48 gray53
0x40 64 yellow
0x41 65 DarkOrange3
0x42 66 purple
0x43 67 gray80
0x44 68 red3
0x45 69 brown1
0x46 70 brown3
0x47 71 blue4
0x48 72 DeepSkyBlue
0x49 73 DarkGreen
0x4a 74 red2
0x4b 75 green3
0x4c 76 MediumBlue
0x4d 77 white
0x4e 78 gray53
0x4f 79 gray35
0x50 80 gray27
0x51 81 black
0x52 82 LimeGreen
0x60 96 HotPink
0x61 97 RoyalBlue
0x62 98 orange3
0x63 99 yellow3
0x64 100 ForestGreen
0x65 101 DodgerBlue
0x66 102 cyan2
0x67 103 plum2
0x68 104 MediumBlue
0x69 105 gray86
106-111 unset and used
0x70 112 RosyBrown2
0x71 113 gray81
0x72 114 tgr_park_1
0x73 115 tgr_city_1
0x74 116 tgr_forest_1
0x75 117 tgr_water_1
0x76 118 cividis_1
0x77 119 cividis_2
0x78 120 cividis_3
0x79 121 cividis_4
0x7a 122 cividis_5
0x7b 123 cividis_6
0x7c 124 cividis_7
0x7d 125 cividis_8
0x7e 126 cividis_9
0x7f 127 set1_1
0x80 128 set1_2
0x81 129 set1_3
0x82 130 set1_4
0x83 131 set1_5
0x84 132 set1_6
0x85 133 set1_7
0x86 134 set1_8
0x87 135 set1_9
136-253 unset and unused
0xfe 254 pink