"Propago" questo documento molto interessante su come è strutturato un file legenda in ArcView...

 

'AVL' files are in ESRI's 'ODB' (object database) format. This format is not documented but it is easy to reverse-engineer, because it is an ASCII text representation of an Avenue object (a legend object in this case). If you know the full structure of an Avenue object, its attributes, and their data types, then you're all set.

Below is an informal quasi-BNF description of an ODB file. The conventions used include:

* Literals are enclosed in single quotes. (A newline literal is represented by "NL" without quotes.)

* Zero or more instances of an element are indicated by following it with a star *.

* Zero or one instances of an element are indicated by following it with a question mark.

* One or more instances of an element are indicated by following it with a plus sign.

* Whitespace (spaces and tabs) is indicated by "WS".

* Lines longer than 512 bytes are blocked into 512 bytes per line.

* Blank lines in between records and fields are allowed.

ArcView is fairly liberal in allowing whitespace and even line breaks in various locations, but I do not know the full extent of the rules it follows in this regard.

The semantics are:

'Class' is the name of an internal object class.

'Id' is a unique positive integer. Usually id values begin with 1 and increase successively, but this is not a requirement.

'Version' is a decimal number such as "3.2" indicating which version of ArcView produced the file.

'Attribute' is the name of a record attribute and usually matches the name given in the help system. Attributes of collection objects, such as lists, can appear multiple times, in the order in which they are contained in the collection.

Strings are escaped using C conventions (e.g., "\n" is a newline).

An 'XRef' is the id of another record in the same odb file. The target of an XRef *MUST* exist and be of the right type (any departure from this usually (always?) causes ArcView segmentation violations when AV tries to read the file). Most references are forward references, but they do not have to be and exceptions do occur.

'Char' is any ASCII character.

'Hex2' and 'Hex4' are two- and four-digit hexadecimal values, respectively. Hex2 and UInt values are also used to indicate enumerated data types (symbolic values beginning with "#" in Avenue). I suspect that usually 0x00 corresponds to the first enumerated value appearing on the help page, 0x01 to the second, etc., but it's best to reverse-engineer each case as needed.

Apparently, 'Hex2' values are also used for certain short bitmaps, such as collections of boolean flags.

A 'truth' encodes a boolean value: 0 for false, 1 for true.

A 'date' is a string representing a date, such as "
Tuesday, July 29, 2003 12:09:04 PM".

'Bitpiece' is a string of hex digits zero to eight bits long; 'Bitblock' is a string if eight hex digits. The bitblocks in bitmaps are separated by whitespace. Here is an example:

0123457 8a

This represents either the binary string (ArcView bitmap)

000000010010001101000101011110001010

or

00000001001000110100010101111000101

depending on how many bits it is supposed to have.

You might notice that an 'XRef' looks just like a 'UInt'. *** It is impossible to tell from the file structure alone whether an integral field value stands for that number or whether it is a reference to another object in the file. *** This is why you *have* to know the object structure in order to parse an odb file: you cannot separate syntax from semantics.

That being said, the syntax evidently is simple. Indeed, most people process ODB files without parsing them at all: they simply search for a record (using the 'Class' string) or an attribute (using the 'Attribute' string) and read the desired value. The standard example is to search for "Path:"; any object with this as attribute is referencing a filename and the corresponding value is, of course, that filename. This is how one discovers all external file references embedded within an ODB file. (This form of parsing leads to errors, of course, because any string value containing the sequence "Path:" will confuse this method, but most programmers either are unaware of this possibility or simply ignore it.)

In sum, then, you can easily parse an avl file, but to do anything with the information you need detailed understanding of the attributes of an Avenue legend object.

Here is a commented example of a small (but complete) avl file. (The comments, of course, are not a part of the original file, nor would they be recognized by AV as such.)
   

/3.2    ' The header record.  Version is AV 3.2.
(ODB.1  ' An 'ODB' object: Record 1.
        FirstRootClassName:    "Legend" ' A string attribute
        Roots:  2                        ' A reference to record 2.
        Version:       32               ' An integer, representing version 3.2.
)
 
(Legend.2 ' A legend object.  The target of ODB.1[Roots].
        SymType:       0x02 ' A type of symbol (a raster fill I believe)
        LegType:       0x01 ' The legend type
        ClassType:     0x03 ' The type of classification
        Symbols:       3    ' A reference to record 3 (a list containing one symbol)
        Class:  8            ' A reference to record 8, a Classification object
        StdDevs:       1.00000000000000 ' Unused (vestigial)
        NullSym:       9    ' A reference to record 9 (a transparent shade with white background)
        NullValues:    13   ' A reference to record 13 (an empty NameDictionary)
        StatValues:    14   ' A reference to record 14 (an empty NameDictionary)
        Precision:     -3   ' Rounding precision (3 decimal places)
)
 
(SymList.3 ' A SymbolList object.  (Note the difference between the internal name 
'            and the Avenue classname.)
        Child:  4            ' A reference to the only element of this collection.
)
 
(BShSym.4                    ' A shaded symbol
        Color:  5            ' A reference to record 5 (pale yellow)
        Outline:       1    ' Index of the outline style in the line type palette
        OutlineColor:  6    ' A reference to record 6 (a null color)
        OutlineWidth:  0.10000000000000 ' Width in points
        BgColor:       7    ' Background color; a reference to record 7 (color white)
)
 
(TClr.5  ' A color object (very pale yellow)
        Red:    0xfeff       ' Red intensity (16 bits!)
        Green:  0xfcdb
        Blue:   0xe618
)
 
(TClr.6 ' This is a NULL color.
)
 
(TClr.7 ' This is white: highest intensity of all three color channels.
        Red:    0xffff
        Green:  0xffff
        Blue:   0xffff
)
 
(LClass.8 ' A Classification object
        IsText: 1             ' A boolean value (true)
        Precision:     -3
)
 
(BShSym.9
        Color:  10
        Outline:       1
        OutlineColor:  11
        OutlineWidth:  0.10000000000000
        BgColor:       12
)
 
(TClr.10
        Name:   "Transparent"
)
 
(TClr.11
        Name:   "Transparent"
)
 
(TClr.12
        Red:    0xffff
        Green:  0xffff
        Blue:   0xffff
)
 
(NameDict.13 ' A NameDictionary object.  This one is empty.
)
 
(NameDict.14 ' Another empty NameDictionary object.
)
 
--------------------------------------
 
BNF for ODB files
 
ODB ::= Header Record*
Header ::= '/' Version
Record ::= NL '(' Class '.' Id Field* NL ')'
Id ::= UInt
Field ::= NL Attribute ':' WS Value
Value ::= Int | Float | XRef | String | Hex2 | Hex4 | Bitmap | Truth | Date
Int ::= '-'? UInt
UInt ::= Digit+
Digit ::= '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
Float ::= Int '.' UInt
XRef ::= UInt
String ::= '"' Char* '"'
Hex2 ::= '0x' HDigit HDigit
Hex4 ::= '0x' HDigit HDigit HDigit HDigit
HDigit ::= Digit | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
Bitmap ::= Bitblock? Bitblock? Bitblock? Bitpiece
Truth ::= '0' | '1'
Date ::= String
Class ::= Char+
Attribute ::= Char+
 
{end of BNF for ODB files}

 

powered by IMH0 1.1