home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 March
/
Chip_1998-03_cd.bin
/
tema
/
MINICAD
/
MC7DEMO
/
MINICAD.1
/
IMPORTS.MPC
< prev
next >
Wrap
Text File
|
1997-04-30
|
13KB
|
463 lines
PROCEDURE ImportSurveyFile;
{
⌐1997, Diehl Graphsoft, Inc.
Developed by Frank Brault
Based on original work by Erez Anzel
Last modified: 04/18/97
For importing 3D coordinate data from a text file,
then creating 3D loci from that data.
Usually done for digitial terrain modeling.
The imported data must be in 3, or 5 columns which are delimited,
followed by a carriage return at the end of each line.
The data file must be in the same folder as the MiniCad program.
This macro was written to import data in the following order:
X, Y, Z (= E, N, Z) , Y, X, Z (= N, E, Z) ,
pt.#, X, Y, Z, description , or pt.#, Y, X, Z, description
The second two formats incorporate the point number and point description,
with the additional option of assigning these definitions to a database.
Before running this macro, you should probably create a new layer
or activate an empty layer which is to be used as a data layer for a terrain model.
This macro was written to work in Minicad
for both Macintosh and Windows, version 7 or later.
This macro will read Mac, Windows, and Unix data files.
}
CONST
kMaxStrLen = 256;
kMaxArray = 6;
kEmptyString = '';
kZeroStr = '0.0';
kBiggestReal = 1.7E+308;
kSmallestReal = 5.0E-324;
kMaxCoord = 536870912.0; { MaxLongInt = (2**31) / 4 }
kTabChar = 9; {the ASCII value for a tab stop}
kLineFeedChar = 10; {the ASCII value for a line feed}
kCarriageReturnChar = 13; {the ASCII value for a carriage return}
kCommaChar = 44; {the ASCII value for a comma}
kColonChar = 58; {the ASCII value for a colon}
kBackslashChar = 92; {the ASCII value for a backslash}
kRecName = 'Survey Data';
kFld1 = 'Point #';
kFld2 = 'X';
kFld3 = 'Y';
kFld4 = 'Z';
kFld5 = 'Desc';
kTextFlag = 4;
kDimensionFlag = 9;
kDecPlaces = 9;
VAR
han : HANDLE;
x, y, z : REAL;
dataFileName : TEXT;
gX, gY, gZ : INTEGER;
frac,dispAcc : LONGINT;
ver1, ver2, ver3, ver4, format : INTEGER;
i, item, dLog1Width,dLog1Height : INTEGER;
bR,bT,bL,bB : INTEGER; {** dialog <B>ox bounds}
cR,cT,cL,cB : INTEGER; {** <C>ancel button }
dR,dT,dL,dB : INTEGER; {** <D>efault Button }
cancel, finished, outOfBounds : BOOLEAN;
tryTabs, tryCommas : BOOLEAN;
unitMrk ,sqrUnitMrk, pathNameDelimiter : STRING;
counter, totalLines : LONGINT;
xFactor, yFactor, zFactor, upi : REAL;
minX, maxX, minY, maxY, minZ, maxZ : REAL;
xFirst, has5Flds, attachDB, centerData : BOOLEAN;
str1, str2, error, separator, fileNameText : STRING;
tabChar, lineFeedChar, carriageReturnChar : STRING;
commaChar, colonChar, backslashChar : STRING;
column : ARRAY[1..kMaxArray] OF STRING;
PROCEDURE SetUpDialog(wth,ht : INTEGER);
{
This procedure returns the bounding box coordinates
of a dialog box and it's default and cancel buttons.
}
VAR
scrR,scrT,scrL,scrB : INTEGER;
Procedure Swap(VAR p1,p2 : INTEGER);
VAR
temp : INTEGER;
BEGIN
temp := p1;
p1 := p2;
p2 := temp;
END;
BEGIN
GetScreen(scrL,scrT,scrR,scrB);
{** Determine the bounding box of the dialog}
bT := (scrB - ht)/3;
bB := bT + ht;
bR := (scrR DIV 2) - (wth DIV 2);
bL := bR + wth;
{** Determine both button X values}
cR := (wth DIV 2) - 80;
cL := (wth DIV 2) - 10;
dR := (wth DIV 2) + 10;
dL := (wth DIV 2) + 80;
{** Determine both button Y values}
cT := ht - 40;
cB := ht - 20;
dT := cT;
dB := cB;
{** If we're running on Windows, then
swap the cancel and default locations}
IF ver4 = 2 THEN
BEGIN
SWAP(cR,dR);
SWAP(cL,dL);
END;
END;
PROCEDURE Toggle(first, second:INTEGER);
BEGIN
SetItem(first,TRUE);
SetItem(second,FALSE);
END;
PROCEDURE ToggleOn(first, second:INTEGER);
BEGIN
SetItem(first,TRUE);
SetItem(second,FALSE);
SelField(10);
END;
FUNCTION ValidStr(str : STRING) : BOOLEAN;
BEGIN
IF (str = kEmptyString) THEN ValidStr := FALSE ELSE ValidStr := TRUE;
END;
PROCEDURE MyReadLn(fileName : TEXT; VAR str, error : STRING);
VAR
done : BOOLEAN;
counter : INTEGER;
chr1 : CHAR;
BEGIN
done := FALSE;
counter := 0;
str := kEmptyString;
error := kEmptyString;
WHILE NOT(EOLN(fileName) | EOF(fileName)) DO
BEGIN
READ(chr1);
str := CONCAT(str, chr1);
END;
counter := LEN(str);
IF counter = kMaxStrLen THEN error := CONCAT(error,'OVERFLOW!');
END;
PROCEDURE ParseStr(delimiter, str : STRING);
VAR
item,n,a : INTEGER;
BEGIN
{** Initialize row array}
FOR n:=1 TO kMaxArray DO column[n]:= kEmptyString;
n := 1;
WHILE (POS(delimiter,str) <> 0) DO
BEGIN
item:= POS(delimiter,str);
column[n]:= COPY(str,1,item-1);
n := n + 1;
IF (POS(delimiter,str) <> 0) THEN DELETE(str,1,item);
END;
{** Delete line terminator at last position of str
This takes into account Unix, DOS and Macintosh file formats}
IF ((Copy(str,LEN(str),1)) = lineFeedChar) THEN DELETE(str,LEN(str),1);
IF ((Copy(str,LEN(str),1)) = carriageReturnChar) THEN DELETE(str,LEN(str),1);
{** Load remainder of str into next element of array}
column[n]:= str;
END;
{********* MAIN *********}
BEGIN
{** Prompt the user for the desired data file:}
MESSAGE('Please select a survey file to import...');
GETFILE(dataFileName);
CLRMESSAGE;
{** Check if there was an error in finding the file, or if the user canceled:}
IF NOT(FndError OR DidCancel) THEN
BEGIN
OPEN(dataFileName);
MyReadLn(dataFileName, str1, error);
CLOSE(dataFileName);
str2 := dataFileName;
{** get Minicad version and platform info}
GetVersion(ver1,ver2,ver3,ver4);
{** load string variables with constant ASSCI character values}
tabChar := Chr(kTabChar);
lineFeedChar := Chr(kLineFeedChar);
carriageReturnChar := Chr(kCarriageReturnChar);
commaChar := Chr(kCommaChar);
colonChar := Chr(kColonChar);
backslashChar := Chr(kBackslashChar);
{** Determine the name of the file for display in dialog}
IF ver4 = 1 THEN pathNameDelimiter := colonChar ELSE pathNameDelimiter := backslashChar;
i := 1;
WHILE (POS(pathNameDelimiter,str2) <> 0) DO
BEGIN
item:= POS(pathNameDelimiter,str2);
fileNameText:= COPY(str2,1,item-1);
i := i + 1;
IF (POS(pathNameDelimiter,str2) <> 0) THEN DELETE(str2,1,item);
END;
{** Load remainder of str into fileNameText}
fileNameText:= str2;
str2 := CONCAT('1st line from ''',fileNameText,''' :');
{** Initialize selector flag variables}
xFirst := TRUE;
has5Flds := FALSE;
attachDB := FALSE;
centerData := FALSE;
tryTabs := FALSE;
tryCommas := FALSE;
{** If the first line has a tab char then we can test for number of fields, etc.}
IF (POS(tabChar,str1) <> 0) THEN
BEGIN
ParseStr(tabChar,str1);
IF ((column[4] <> kEmptyString) AND (column[5] <> kEmptyString)) THEN has5Flds := TRUE;
tryTabs := TRUE;
END;
{** If the first line has a comma char then we can test for number of fields, etc.}
IF NOT(tryTabs) AND (POS(commaChar,str1) <> 0) THEN
BEGIN
ParseStr(commaChar,str1);
IF ((column[4] <> kEmptyString) AND (column[5] <> kEmptyString)) THEN has5Flds := TRUE;
tryCommas := TRUE;
END;
{** Check if there was an error in opening the file:}
IF NOT(FndError) THEN
BEGIN
dLog1Width := 300;
dLog1Height := 346;
SetupDialog(dLog1Width,dLog1Height);
BeginDialog(1,1,bR,bT,bL,bB);
AddButton('OK',1,1,dR,dT,dL,dB);
AddButton('Cancel',2,1,cR,cT,cL,cB);
AddField(str2,3,1,4,20,316,38);
AddField(str1,4,1,4,44,316,65);
AddField('Select File Format:',5,1,5,80,137,100);
AddButton('Easting, Northing, Elevation (X, Y, Z)',6,3,15,102,290,120);
AddButton('Northing, Easting, Elevation (Y, X, Z)',7,3,15,120,290,138);
AddButton('Tab Delimited',8,3,15,153,290,171);
AddButton('Other Character╔',9,3,15,171,150,189);
AddField(commaChar,10,2,100,196,120,212);
AddButton('Data Contains Point # and Description',11,2,15,227,290,245);
AddButton('Attach Database Info to Loci',12,2,15,245,290,263);
AddButton('Center Data at Origin',13,2,15,263,290,278);
ENDDIALOG;
GetDialog(1);
SetTitle('Survey File Import Setup Dialog');
finished := FALSE;
cancel:= FALSE;
SetItem(6,xFirst);
IF tryCommas THEN SetItem(9,TRUE) ELSE SetItem(8,TRUE);
SetItem(11,has5Flds);
SetItem(12,attachDB);
SetItem(13,centerData);
REPEAT DialogEvent(item);
IF item = 6 THEN Toggle(6,7);
IF item = 7 THEN Toggle(7,6);
IF item = 8 THEN Toggle(8,9);
IF item = 9 THEN ToggleOn(9,8);
IF item = 11 THEN SetItem(11, not(ItemSel(11)));
IF item = 12 THEN SetItem(12, not(ItemSel(12)));
IF item = 13 THEN SetItem(13, not(ItemSel(13)));
IF item = 2 THEN
BEGIN
finished := TRUE;
cancel := TRUE;
END;
IF item = 1 THEN
BEGIN
IF NOT(ValidStr(GetField(10))) THEN
BEGIN
SysBeep;
SetField(10,' ');
SelField(10);
WAIT(1);
SetField(10,'');
SelField(10);
END
ELSE
finished := TRUE;
END;
UNTIL finished;
xFirst := ItemSel(6);
has5Flds := ItemSel(11);
attachDB := ItemSel(12);
centerData := ItemSel(13);
IF itemSel(8) THEN separator := TabChar ELSE separator := GetField(10);
CLRDIALOG;
IF NOT (Cancel) THEN
BEGIN
{** The user did not cancel, so open the file:}
Open(dataFileName);
{** Check if there was an error in opening the file:}
IF NOT (fndError) THEN
BEGIN
{** Initialize variables}
xFactor := 0;
yFactor := 0;
zFactor := 0;
IF has5Flds THEN
BEGIN
gX := 2;
gY := 3;
gZ := 4;
END
ELSE
BEGIN
gX := 1;
gY := 2;
gZ := 3;
END;
IF attachDB THEN
BEGIN
NewField(kRecName,kFld1,kZeroStr,kTextFlag,kDecPlaces);
NewField(kRecName,kFld2,kZeroStr,kDimensionFlag,kDecPlaces);
NewField(kRecName,kFld3,kZeroStr,kDimensionFlag,kDecPlaces);
NewField(kRecName,kFld4,kZeroStr,kDimensionFlag,kDecPlaces);
NewField(kRecName,kFld5,kZeroStr,kTextFlag,kDecPlaces);
END;
{** This part determines the offset factors if the user has asked for the data to be centered}
IF CenterData THEN
BEGIN
MESSAGE('One moment please...');
SetCursor(WATCHC);
counter := 0;
minX:= kBiggestReal;
maxX:= kSmallestReal;
minY:= kBiggestReal;
maxY:= kSmallestReal;
minZ:= kBiggestReal;
maxZ:= kSmallestReal;
WHILE NOT EOF(dataFileName) DO
BEGIN
MyReadLn(dataFileName, str1, error);
IF NOT(EOF(dataFileName)) THEN
BEGIN
ParseStr(separator,str1);
IF STR2NUM(column[gX]) < minX THEN minX := STR2NUM(column[gX]);
IF STR2NUM(column[gX]) > maxX THEN maxX := STR2NUM(column[gX]);
IF STR2NUM(column[gY]) < minY THEN minY := STR2NUM(column[gY]);
IF STR2NUM(column[gY]) > maxY THEN maxY := STR2NUM(column[gY]);
IF STR2NUM(column[gZ]) < minZ THEN minZ := STR2NUM(column[gZ]);
IF STR2NUM(column[gZ]) > maxZ THEN maxZ := STR2NUM(column[gZ]);
END;
counter := counter + 1;
END;
totalLines := counter - 1;
xFactor := maxX-((maxX - minX)/2);
yFactor := maxY-((maxY - minY)/2);
zFactor := maxZ-((maxZ - minZ)/2);
CLOSE(dataFileName);
OPEN(dataFileName);
SetCursor(ARROWC);
CLRMESSAGE;
END;
{** Check the largest coordinates against the drawing space limits. }
outOfBounds := FALSE;
IF CenterData THEN
BEGIN
GetUnits(frac,dispAcc,format,upi,unitMrk,sqrUnitMrk);
IF ABS(minX * frac) > kMaxCoord THEN outOfBounds := TRUE;
IF ABS(maxX * frac) > kMaxCoord THEN outOfBounds := TRUE;
IF ABS(minY * frac) > kMaxCoord THEN outOfBounds := TRUE;
IF ABS(maxY * frac) > kMaxCoord THEN outOfBounds := TRUE;
IF ABS(minZ * frac) > kMaxCoord THEN outOfBounds := TRUE;
IF ABS(maxZ * frac) > kMaxCoord THEN outOfBounds := TRUE;
END;
IF outOfBounds THEN BEGIN
SYSBEEP;
ALRTDIALOG('Change the scale to a higher ratio to enter these points within the drawing bounds.');
END;
IF NOT OutOfBounds THEN
BEGIN
{** Keep reading lines until the end of file or until there's an error:}
counter := 0;
WHILE NOT EOF(dataFileName) DO
BEGIN
SetCursor(WATCHC);
MyReadLn(dataFileName, str1, error);
IF NOT(EOF(dataFileName)) THEN
BEGIN
ParseStr(separator,str1);
IF xFirst THEN
BEGIN
x := STR2NUM(column[gX])-xFactor;
y := STR2NUM(column[gY])-yFactor;
END
ELSE
BEGIN
x := STR2NUM(column[gY])-yFactor;
y := STR2NUM(column[gX])-xFactor;
END;
z := STR2NUM(column[gZ])-zFactor;
Locus3D(x, y, z);
counter := counter + 1;
IF centerData THEN
MESSAGE('Line ',counter,' of ',totalLines,' completed╔')
ELSE
MESSAGE('Line ',counter,' completed╔');
{** Load the fields with information if the user has asked to do so.}
IF attachDB THEN
BEGIN
SetRecord(LObject,kRecName);
IF has5Flds THEN SetRField(LObject,kRecName,kFld1,column[1]);
SetRField(LObject,kRecName,kFld2,column[gX]);
SetRField(LObject,kRecName,kFld3,column[gY]);
SetRField(LObject,kRecName,kFld4,column[gZ]);
IF has5Flds THEN SetRField(LObject,kRecName,kFld5,column[5]);
END;
END;
END;
CLRMESSAGE;
END;
IF error <> '' THEN MESSAGE(error);
CLOSE(dataFileName);
END;
END;
END;
END;
END;
RUN(ImportSurveyFile);