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.
Contents
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 variable | use |
---|---|
color | sets the color of lines drawn (see below) |
lanes | sets width of lines drawn |
name | sets the text that will be used as the label for the feature |
symbol | sets the symbol that will be used for point data (using group/symbol/overlay specification) |
fill_style | sets 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_color | sets color used to fill area features --- uses same numbers as color variable (below) |
fill_style | chooses fill style. At this time only 0 and 2 are
worth using. 0 is "solid" and "2" is stippled, per XSetFillStyle. See below. |
fill_stipple | When fill_style is 2, chooses stipple pattern. 0 is a 13 percent stipple, 1 is 25%, 2 is 50%. |
pattern | sets line pattern. 0=solid, 1=dashed, 2="double dash" (per XSetLineAttributes) |
display_level | sets zoom above which the feature will be stop being displayed |
label_level | sets zoom above which labels will be stop being displayed |
label_color | sets color of labels. (see section on selecting colors, below) |
font_size | chooses 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:
- 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 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.]
- 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).
- 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.
- 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.
- 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.
- 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 value | decimal | Color (as X11 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 | 83 | 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 |
0xfe | 254 | pink |