OCAD file format

OCAD 5.00



File Format of the Map File


1. Introduction


This is a description of the OCAD file containing the digitized map. It's intended for
all those who want to use this data for purposes like statistics or transfer data from
other systems to the OCAD system.

2. Data types


4 basic data types are used in the OCAD files.

integer


Signed integer (2 Bytes). This type corresponds to the Pascal "integer" type.

longint


Signed long integer (4 Bytes). This type corresponds the Pascal "longint" type.

real


6-byte real consisting of a 5-byte significand and a 1-byte exponent. This type is
defined in Borland Pascal as "real".

tPoint

A structure consisting of an integer for the x-value and an integer for the y-value.
It corresponds to the Windows "Point" type.

tMapColors


Set of 32 bits, each bit representing one color. For most objects only one bit is
set and all others are 0. But for multicolor objects (like streets with filling) more
than one bit may be set.
The order of the bits follow the color numbers not their position in the color table.
The least significant bit corresponds to the color number 0. The size of this data
type is 4 byte.

3. Coordinates


OCAD uses the coordinate system as it apppers in overview magnification. The zero
coordinate is in the middle of the usable area, positive y-coordinates are going to
the north and positive x-coordinates to the east.

The unit of measure is 1/1440 inch. Coordinates are stored as signed integers (2
bytes).

4. File organisation


An OCAD file containes 3 sections, the index section, the element section and the
symbol section. The coordinates of the objects are stored in the element section.
The index section contains the "extent" of every object. This is a rectangle that
covers the whole object. If a screen has to be redrawn, the extend of every object is
checked. And only if the extent rectangle overlaps the actual window on the screen,
the object is read from the element section and then written to the screen. This way
the number of file accesses is reduced.

The index section is read into memory once and is then available for further redraw
operations. For large maps only part of the index section is hold in memory, but the
resident portion is updated like a cache. So even for very large maps you will not
remark a significant reduction of the speed. This sophisticated organisation of the
map data is the main reason for the speed of OCAD.

5. Index section


The index section is organized as records of 24 bytes, one for each object. In the
sample program a type is defined for such a record called "tIndex". The variable to
read a record is called "MainIndex".

5.1 Index Header



The first record of the index section is the index header. It identifies the file as an
OCAD file and indicates the OCAD version with which the file has been written. It
has the following structure:

OCADMark: integer SectionMark: integer Version: integer Subversion: integer EltStart: longint SymStart: longint Reserved1: longint Reserved2: longint

OCADMark


Always 3245. (hex 0cad)

SectionMark


Always 204 (hex cc).

Version


Number of the OCAD version. For OCAD 5 this is 5.

SubVersion


Number of the OCAD subversion. For OCAD 5.00 this is 0.

EltStart


Start of the Element Section in bytes from the beginning of the file. (Note that this
is different from OCAD 4 where this position was indicated in records.)

SymStart


Start of the Symbol Section in bytes from the beginning of the file.

When a map is loaded, OCAD checks OCADMark, SectionMark and Version. If one
of them is not correct an error "Format not correct." is issued.

5.2 Index Data


The rest of the index section contains the object records, one for each object of the
map. The records have the following structure:

x1: integer y1: integer x2: integer y2: integer Pos: longint Len: integer Reserved1: integer Sym: Integer Reserved2: integer Colors: tMapColors

x1


Coordinate of the left side of the extent rectangle

y1


Coordinate of the lower side of the extent rectangle

x2


Coordinate of the right side of the extent rectangle

y2


Coordinate of the upper side of the extent rectangle

Pos


Position of the object in the element section, measured in longwords (4 bytes)
and starting from the beginning of the element section

Len


Length of the object in the element section measured in longwords (4 bytes).
This is the total length occupied by the object and is equal to 3 + number of
polygon points.

Sym


Symbol number. This symbol number is 10 times the number displayed in the
OCAD program (a symbol number displayed as 101.1 is stored as 1011)

Cols


Colors contained in the object. For more description see "tMapColors".

If an object is deleted, all bytes of the objects record are set to 0.

6. Element Section


The coordinate information of the objects is stored in the element section. The
element section is divided into records of variable length.

6.1 Element Header


The first record is the element header. It consists of the first 1024 bytes and
contains general information like options settings or the state when the file was last
opened. The following variables are defined:

OCADMark: integer SectionMark: integer Version: integer Subversion: integer Zoom: integer OffsetX: integer OffsetY: integer rGridDist: real WorkMode: integer LineMode: integer EditMode: integer ActSym: integer PrOffsetX: integer PrOffsetY: integer PrSizeX: integer PrSizeY: integer PrGrid: integer PrGridColor: integer PrOverlapX: integer PrOverlapY: integer MapScale: real DraftScale: real PrintScale: real TempOffsetX: integer TempOffsetY: integer TemplateFileName: array [0..79] of char TemplateEnabled: integer TempResol: integer rTempAng: real DigOffsetX: integer DigOffsetY: integer rDigAng: real The rest of the element header is reserved for future use.

OCADMark


Always 3245. (hex 0cad)

SectionMark


Always 255 (hex ff).

Version


Number of the OCAD version. For OCAD 5 this is 5.

SubVersion

Number of the OCAD subversion. For OCAD 5.00 this is 0.

Zoom


The zoom when the file was last opened. 0 means 16X, 1 means 8X etc.

OffsetX


The horizontal offset when the file file was last opened. The offset indicates the
center of the screen in OCAD coordinates.

OffsetY


The vertical offset when the file was last opened. The offset indicates the center
of the screen in OCAD coordinates.

rGridDist


Grid distance measured in millimeters

WorkMode


The working mode when the file was last opened. It corresponds to the
numbering of the toolbar buttons from the left. Freehand mode is stored as 5,
straight line mode as 6 etc.

LineMode


The last drawing mode is stored here. Used when switching between drawing
and editing with the right mouse button. The same numbering applies as for the
work mode.

EditMode


The last editing mode is stored here. Used when switching between drawing and
editing with the right mouse button. The same numbering applies as for the work
mode. Editing with moving points is stored as 11 and editing with moving objects
as 12.

ActSym


The selected symbol when the file was last opened. The symbols are numbered
from 0 starting with the top left symbol in the symbol box.

PrOffsetX


Horizontal offset of the print window. The OCAD coordinate of the center of the
print window is stored here.

PrOffsety


Vertical offset of the print window. The OCAD coordinate of the center of the
print window ist stored here.

PrSizeX


Width of the print window. Half the width is stored here in OCAD units (storing
the full width would exceed the integer range).

PrSizeY


Height of the print window. Half the hight is stored here in OCAD units (storing
the full height would exceed the integer range).

PrGrid


Indicates if printing the grid was switched on. 0 means switched off and 1 means
switched on.

PrGridColor


The color of the printed grid. Indicates the color number, not the position in the
color table.

PrOverlapX


Horizontal overlap when printing to several pages. Measured in 1/2880 inches
(twice the OCAD resolution).

PrOverlapY


Vertical overlap when printing to several pages. Measured in 1/2880 inches
(twice the OCAD resolution).

MapScale


Divisor of the map scale (for 1:10'000 this number is 10'000)

DraftScale


Divisor of the draft scale (for 1:5'000 this number is 5'000)

PrintScale


Divisor of the print scale (for 1:10'000 this number is 10'000)

TempOffsetX


Offset of the left side of the template in OCAD coordinates

TempOffsetY


Offset of the upper side of the template in OCAD coordinates

TemplateFileName


File name of the template as a zero terminated string

TemplateEnabled


Indicates if the template is enabled. 0 means disabled, 1 means enabled.

TempResol


Resolution of the template in dots per inch

rTempAng


Rotation of the template measured in arcs (1 degree is stored as pi/180)

DigOffsetX


Offset of the left side of the digitizer measured in OCAD coordinates

DigOffsetY


Offset of the lower side of the digitizer measured in OCAD coordinates

rDigAng


Rotation of the digitizer measured in arcs (1 degree is stored as pi/180)

When proucing an OCAD file this section may be filled with 0. It will the be initialized
to default values when the file is opened in OCAD.

6.2 Element Data



The rest of the element section contains the coordinate information for each objects.
Each object consists of a header and of the coordinate information. For texts the
text string is stored after the coordinates.

To find an object in the element section, you must use the position and length
information in the index section. For the exact procedure see sample program. This
is the structure of a record:

Sym: integer Otp: integer nItem: integer Reserved1: integer Ang: integer Reserved2: integer Poly: array [1..2000] of tPoint

Sym


Symbol number. This symbol number is 10 times the number displayed in the
OCAD program (a symbol number displayed as 101.1 is stored as 1011)

Otp


Object type. The following object types are used:
1 point object
2 line object
3 area object
4 text object
5 rectangle object

nItem


Number of coordinates of the object

Ang


Angle of rotated objects measures in tenth of a degree

Poly


The coordinates of the object. Only the number of coordinates defined in nItem
are stored in the file. For compatibility with earlier versions and for future use you
should reserve 2000 coordinates in your internal structure. However to avoid
problems with the Postscript output it is strongly recommended not to create
objects with more than 512 points (including the marks described below).

6.3 Element Coordinates


The coordiates in the Poly structure represent OCAD coordinates as described
above. However the most negative x-coordinates are used to put a mark for the
following coordinate(s). They are not used as real coordinates. Such marks are
used for:

- Holes in areas
- Corner points
- Gaps in sidelines
- BŐzier points

The table shows the use of these marks:

x y Function --------------------------------------------------------------------------------------------------------------- -32768 -32768 The next coordinate is the first coordinate of a hole in an area. -32767 -32767 The next coordinate is a corner point. -32767 1 At the next coordinate a gap in the left sideline starts. -32767 2 At the next coordinate a gap in the left sideline ends. -32767 3 At the next coordinate a gap in the right sideline starts. -32767 4 At the next coordinate a gap in the right sideline ends. -32767 5 At the next coordinate a gap in the left sideline and a gap in the right sideline start. -32767 6 At the next coordinate a gap in the left sideline starts and a gap in the right sideline ends. -32767 7 At the next coordinate a gap in the left sideline ends and a gap in the right sideline starts. -32767 8 At the next coordinate a gap in the left sideline and a gap in the right sideline end. -32766 -32766 The next 2 coordinates are BŐzier points (positionned outside the curve) -32766 -32767 The next 2 coordinates are BŐzer points (positionned outside the curve) and the previous point is a corner point -32765 x Reserved for future use.

Note: Only one mark is allowed for one coordinate. No mark is allowed for the first
coordinate of an object and for the coordinate after the 2 BŐzier points. No marks
are allowed for text objects and rectangle objects.
For texts, only the first 5 coordinates are real coordinates where the first coordinate
is the starting point (on the baseline) of the text and the 4 following points build a
rectangle around the text (starting at the lower left corner and going CCW around
the text). After the 5 coordinates follows the text string as a null-terminated string.

For rectangles the coordinates of the 4 corners are stored (starting at the lower left
corner and going CCW around the rectangle).

7. Symbol Section



The symbol section contains all color and symbol definitions including the icons in
the symbol box. The start position in the file is definied by SymStart of the index
header structure and goes until the end of the file. It is not described here. You
should leave the symbol section unchanged or copy it from an existing OCAD file.

8. Sample program


The following is a sample program in Borland Pascal to illustrate the format. This
program moves the specified map 1 inch (2.54 cm) to the north in the OCAD
coordinate system. For simplicity reasons the program is a DOS program and the
name of the map has to be specified as a commandline parameter like:

sample mapxy
If you are programming in Borland Pascal, you may take this program as a skeleton
for your own application.

program Sample; uses Dos; type tMapColors = set of 0..31; tPoint = record x, y: integer; end; tElement = record Sym, Otp, {object type, 1 = Point object 2 = Line object 3 = Area object 4 = Text object 5 = Rectangle object} nItem, {number of Polygon Points} Reserved1, {Set of Colors of the object} Ang, {angle of rotatable symbols} Reserved2: integer; Poly: array [1..2000] of tPoint; {Polygon Points resolution 1/1440 inch, zero point in the center positive coordinates to the right and to the top} end; tIdxHeader = record OCADMark: integer; SectionMark: integer; Version: integer; Subversion: integer; EltStart: longint; SymStart: longint; Reserved1: longint; Reserved2: longint; end; tIndex = record x1, y1, x2, y2: integer;{a Rectangle around the object} Pos: longint; {Position in the Element section measured in longwords (4 bytes)} Len: integer; {length in the Element section measured in longwords (4 bytes)} Reserved: integer; Sym: Integer; {Symbol number} Reserved2: integer; Colors: tMapColors; {Colors of the object} end; var i, nCoords: integer; l: longint; WorkFile: File; Main: tElement; IdxHeader: tIdxHeader; MainIndex: tIndex; FName: string; procedure Error (istr: string); begin Writeln (istr); halt (1); end; begin writeln ('OCAD sample program, version 5.0'); FName := paramstr (1); {command Line parameter} if FName = '' then error ('FileName missing.'); if Pos ('.', FName) = 0 then FName := FName + '.ocd'; {default extension is .OCD} for i := 1 to length (FName) do FName [i] := upcase (FName [i]); assign (WorkFile, FName); {$I-} reset (WorkFile, 1); {$I+} if ioresult 0 then error ('File ' + FName + ' not Found.'); blockread (WorkFile, IdxHeader, 24); {Read the File header} with IdxHeader do if (OCADMark $0cad) or (SectionMark $cc) or (Version 5) then error ('Format of ' + FName + ' not correct.'); writeln ('Moving the map...'); for l := 1 to IdxHeader.EltStart div 24 - 1 do begin seek (WorkFile, 24 * l); blockread (WorkFile, MainIndex, 24); if MainIndex.Len > 3 then {jump over deleted objects} begin seek (WorkFile, IdxHeader.EltStart + 4 * MainIndex.Pos); blockread (WorkFile, Main, 4 * MainIndex.Len); case Main.otp of 1..3: nCoords := Main.nItem; 4: nCoords := 5; 5: nCoords := 4; end; for i := 1 to nCoords do if Main.Poly [i].x > -32765 then {except special coordinates} inc (Main.Poly [i].y, 1440); inc (MainIndex.y1, 1440); inc (MainIndex.y2, 1440); seek (WorkFile, 24 * l); blockwrite (WorkFile, MainIndex, 24); seek (WorkFile, IdxHeader.EltStart + 4 * MainIndex.Pos); blockwrite (WorkFile, Main, 4 * MainIndex.Len); end; end; Close (WorkFile); end.
Back