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