给你一下吧,DLL在delphi中写,调用在VC中。<br><br>library BuildYard;<br><br>{ Important note about DLL memory management: ShareMem must be the<br> first unit in your library's USES clause AND your project's (select<br> Project-View Source) USES clause if your DLL exports any procedures or<br> functions that pass strings as parameters or function results. This<br> applies to all strings passed to and from your DLL--even those that<br> are nested in records and classes. ShareMem is the interface unit to<br> the BORLNDMM.DLL shared memory manager, which must be deployed along<br> with your DLL. To avoid using BORLNDMM.DLL, pass string information<br> using PChar or ShortString parameters. }<br><br>uses<br> SysUtils, Classes,Math;<br><br>type<br> TGeoPt = record<br> dX,dY,dZ : double;<br> end;<br><br> TRefPt = record<br> Origin : TGeoPt;<br> X_Axe,Y_Axe : TGeoPt;<br> ATN : double; //angle relative to north<br> end;<br><br> TBlock = class;<br> TStack = class;<br> TGeoRectEx = record<br> LeftTop,RightTop,RightBottom,LeftBottom : TGeoPt;<br> end;<br><br> //码头,可以包含多个Terminal<br> TYard = class<br> sDate : array [0..15] of Char; //时间<br> nTrackWidth : integer; //精确到毫米<br> nLaneWidth : integer; //毫米<br> TerminalList : TList;<br><br> LaneDefList : TList; //代表的是Yard中的所有LaneDef类型<br> constructor Create;<br> destructor Destroy;override;<br> procedure MatchLDI(Stack : TStack);<br> end;<br><br> TTerminal = class<br> sCoor : string; //坐标系统定义,如'HK80'<br> sName : array[0..1] of Char; // 'T7'<br> ID : Word;<br> BlockList : TList;<br> TerminalRect : TGeoRectEx;<br> RefPt : TRefPt;<br> constructor Create;<br> destructor Destroy;override;<br> function FindBlock(Block : TBlock) : TBlock;<br> function GetBlock(sKey : string) : TBlock;<br> function GetBlockSize : integer;<br> end;<br><br> TGeoRect = record<br> Left,Top,Right,Bottom : Integer;<br> end;<br><br> TRec = class(TObject)<br> Rect : TGeoRect;<br> Name : array[0..7] of Char;<br> YardMapId : Word;<br> Atl : Byte;<br> Size : Word;<br> StackID : string;<br> end;<br><br> TLaneDef = class;<br><br> TStack = class(TObject)<br> Rect : TGeoRect;<br> ID : array[0..3] of Char;<br> RecList : TList;<br> MinX,MaxX : LongWord;<br> nSpread : integer;<br> LDI : integer; //Lane Definition Indicator<br><br> LaneDef : TLaneDef;<br><br> constructor Create;<br> destructor Destroy;override;<br> procedure CalcRect;<br> end;<br><br> TLaneDef = class<br> LDI : integer;<br> LaneList : TList;<br> constructor Create;<br> destructor Destroy;override;<br> end;<br><br> TLane = class<br> Name : array[0..9] of Char;<br> MinY,MaxY : double;<br> TLD : Byte;<br> end;<br><br> TBlock = class(TObject)<br> public<br> ID : array[0..3] of Char;<br> nTrackLane : integer;<br> StackList : TList;<br> Rect : TGeoRect; //第一版参数,第二版中已经不用<br><br> nRecCount : integer;<br> StackIndexList : TList;<br><br> constructor Create;<br> destructor Destroy;override;<br> procedure CalcRect;<br> //本Block中所有记录<br> function GetRecCount : integer;<br> function FindRec(Rec : TRec) : TStack;<br> function FindStack(Stack : TStack) : TStack;<br><br> function GetInvalidLaneCount : integer;<br> end;<br><br>{$R *.res}<br><br>const LANE_COUNT = 7;<br>const DATA_FILE_HEAD_SIZE = 16; //数据文件头部长度<br>const INDEX_FILE_HEAD_SIZE = 78; //索引文件的头部长度<br><br>var<br> MapVer : array[0..15] of Char;<br> Yard : TYard;<br><br>//计算从X1,Y1到NX,NY的方向,X1,Y1一定为第一点}<br>function GetAngle(X1,Y1,NX,NY : double)
ouble;<br>var<br> BufLen,Direction : Double;<br>begin<br> BufLen := Sqrt(Sqr(X1-NX)+Sqr(Y1-NY));<br> if (Abs(NX-X1)< 10e-300) then begin<br> if (Abs(Y1-NY)< 10e-300) then begin<br> //等于没有移动}<br> end<br> else begin<br> if (Y1-NY)>0 then Direction := PI/2<br> else Direction := 3*PI/2;<br> end;<br> end<br> else begin<br> if ArcTan((Y1-NY)/(NX-X1))>0 then begin<br> if (Sin((Y1-NY)/BufLen)>0) then<br> Direction := ArcTan((Y1-NY)/(NX-X1))<br> else<br> Direction := ArcTan((Y1-NY)/(NX-X1))+PI;<br> end<br> else begin<br> if (Sin((Y1-NY)/BufLen)>0) then<br> Direction := ArcTan((Y1-NY)/(NX-X1))+PI<br> else begin<br> Direction := ArcTan((Y1-NY)/(NX-X1));<br> if (Direction = 0) and (X1 > NX) then Direction := PI;<br> end;<br> end;<br> end;<br> Direction := - Direction;<br> if Direction < 0 then Direction := 2 * PI + Direction;<br> Result := Direction;<br>end;<br><br>function GetStrItem(SourStr : string;Border : Char;Index : integer):string;<br>var<br> TempStr : string;<br> I : integer;<br>begin<br> TempStr := SourStr;<br> if Pos(Border,SourStr)=0 then Result := ''<br> else begin<br> try<br> for I := 1 to Index - 1 do begin<br> if Pos(Border,TempStr) = 0 then begin<br> Result := '';<br> Exit;<br> end;<br> Delete(TempStr,1,Pos(Border,TempStr));<br> TempStr := Trim(TempStr);<br> end;<br> except<br> result := '';<br> Exit;<br> end;<br> if Pos(Border,TempStr)=0 then<br> Result := TempStr<br> else<br> Result := Copy(TempStr,1,Pos(Border,TempStr) - 1);<br> end;<br>end;<br><br>function GetDMSR(sBuf : string) : Double;<br>begin<br> result := result + StrToFloat(GetStrItem(sBuf,'D',1));<br> Delete(sBuf,1, Pos('D',sBuf));<br> if Pos('M', sBuf) > 0 then begin<br> result := result + StrToFloat(GetStrItem(sBuf, 'M',1))/60;<br> Delete(sBuf,1, Pos('M',sBuf));<br> end;<br> if Pos('S', sBuf) > 0 then begin<br> result := result + StrToFloat(GetStrItem(sBuf,'S',1))/60/60;<br> Delete(sBuf,1, Pos('S',sBuf));<br> end;<br><br>end;<br><br>//写数据文件<br>procedure WriteRecFileEx(FileName: string);<br>var<br> F : File;<br> I, J, K, L, nBuf : integer;<br> uBuf8 : Byte;<br> uBuf16 : Word;<br> uBuf32 : LongWord;<br><br> Block : TBlock;<br> Lane : TLane;<br> Stack : TStack;<br> dAngle : double;<br> Terminal : TTerminal;<br><br>begin<br> AssignFile(F,FileName);<br> Rewrite(F,1);<br><br> //写文件头<br> uBuf32 := 0;<br> for I := 0 to Yard.TerminalList.Count - 1 do begin<br> Terminal := TTerminal(Yard.TerminalList.Items
);<br> for J := 0 to Terminal.BlockList.Count - 1 do begin<br> Block := TBlock(Terminal.BlockList.Items[J]);<br> for K := 0 to Block.StackList.Count - 1 do begin<br> Stack := TStack(Block.StackList.Items[K]);<br> if Assigned(Stack.LaneDef) then begin<br> if Stack.LaneDef.LDI <> 0 then begin<br> Inc(uBuf32, Stack.LaneDef.LaneList.Count);<br> end;<br> end;<br> end;<br> end;<br> end;<br> BlockWrite(F,uBuf32,SizeOf(LongWord)); //reccount<br> nBuf := 2;<br> BlockWrite(F,nBuf,SizeOf(LongWord)); //版本2<br> BlockWrite(F,Yard.sDate,16);<br> nBuf := 0;<br> BlockWrite(F,nBuf,64);<br><br> //写Terminal<br> for I := 0 to Yard.TerminalList.Count - 1 do begin<br> Terminal := TTerminal(Yard.TerminalList.Items);<br> for J := 0 to Terminal.BlockList.Count - 1 do begin<br> Block := TBlock(Terminal.BlockList.Items[J]);<br> for K := 0 to Block.StackList.Count - 1 do begin<br> Stack := TStack(Block.StackList.Items[K]);<br> if Assigned(Stack.LaneDef) and (Stack.LaneDef.LDI <> 0) then begin<br> for L := 0 to Stack.LaneDef.LaneList.Count - 1 do begin<br> Lane := TLane(Stack.LaneDef.LaneList.Items[L]);<br> uBuf32 := Trunc(Lane.MaxY * 1000);<br> BlockWrite(F, uBuf32, SizeOf(LongWord));<br> uBuf32 := Trunc(Lane.MinY * 1000);<br> BlockWrite(F, uBuf32, SizeOf(LongWord));<br> if Pos('LANE', UpperCase(String(Lane.Name))) > 0 then<br> uBuf16 := StrToInt(Copy(String(Lane.Name),5, Length(String(Lane.Name)) - 1))<br> else<br> uBuf16 := 10; //表示是错误的ID<br><br> BlockWrite(F, uBuf16, SizeOf(WORD));<br> end;<br> end;<br> end;<br> end;<br> end;<br> CloseFile(F);<br>end;<br>//写索引文件<br>//写索引文件<br>procedure WriteIndexFileEx(FileName: string);<br>var<br> I, J, K, nBuf: integer;<br> uBuf32 : LongWord;<br> uBuf16 : Word;<br> Buf8 : Byte;<br> F : File;<br><br> Block : TBlock;<br> Stack : TStack;<br> dAngle : Double;<br> Terminal : TTerminal;<br> nAccuBlockBytes : LongWORD; //Block的编移<br> nAccuLaneBytes : LongWORD; //累计的Lane偏移<br> nAccuStackBytes : LongWORD; //累计的Stack偏移<br>begin<br> AssignFile(F,FileName);<br> Rewrite(F,1);<br> //写头文件<br> uBuf32 := 0;<br> for I := 0 to Yard.TerminalList.Count - 1 do begin<br> Terminal := TTerminal(Yard.TerminalList.Items);<br> Inc(uBuf32, Terminal.BlockList.Count);<br> end;<br> BlockWrite(F, uBuf32, SizeOf(LongWord));<br> uBuf32 := 2;<br> BlockWrite(F, uBuf32, SizeOf(LongWord)); //Version = 2<br> BlockWrite(F, Yard.sDate, 16);<br> BlockWrite(F, Yard.TerminalList.count, SizeOf(WORD));<br> uBuf32 := 0;<br> BlockWrite(F, uBuf32, SizeOf(WORD)); //新加的<br><br> BlockWrite(F, Yard.nTrackWidth, SizeOf(LongWord));<br> BlockWrite(F, Yard.nLaneWidth, SizeOf(LongWord));<br> Buf8 := 0;<br> BlockWrite(F, Buf8, 52);<br> //写入所有Terminal的所有Block<br> nAccuBlockBytes := 0;<br> for I := 0 to Yard.TerminalList.Count - 1 do begin<br> Terminal := TTerminal(Yard.TerminalList.Items);<br> BlockWrite(F,Terminal.BlockList.Count, SizeOf(Word)); //该Yard中的Block数目<br><br> BlockWrite(F, nAccuBlockBytes, SizeOf(Word)); //Block起始索引<br><br> BlockWrite(F, Terminal.sName,2); //YardMap ID<br><br> nBuf := 0;<br> if Terminal.sCoor = 'WGS84' then nBuf := 1<br> else if Terminal.sCoor = 'BJ54' then nBuf := 2<br> else if Terminal.sCoor = 'HKG80' then nBuf := 3;<br> BlockWrite(F,nBuf,SizeOf(WORD)); //wFormat<br><br> BlockWrite(F, Terminal.RefPt.Origin.dX, SizeOf(Double));<br> BlockWrite(F, Terminal.RefPt.Origin.dY, SizeOf(Double));<br><br> if (Terminal.sCoor = 'WGS84') then begin<br> dAngle := GetAngle(Terminal.RefPt.Origin.dY, Terminal.RefPt.Origin.dX, Terminal.RefPt.X_Axe.dY, Terminal.RefPt.X_Axe.dX);<br> BlockWrite(F, dAngle, SizeOf(Double)); //X轴的夹角<br><br> dAngle := GetAngle(Terminal.RefPt.Origin.dY, Terminal.RefPt.Origin.dX, Terminal.RefPt.Y_Axe.dY, Terminal.RefPt.Y_Axe.dX) - PI/2;<br> BlockWrite(F, dAngle, SizeOf(Double)); //Y轴的夹角<br><br> end<br> else if (Terminal.sCoor = 'BJ54') or (Terminal.sCoor = 'HKG80') then begin<br> dAngle := GetAngle(Terminal.RefPt.Origin.dX, Terminal.RefPt.Origin.dY, Terminal.RefPt.X_Axe.dX, Terminal.RefPt.X_Axe.dY);<br> BlockWrite(F, dAngle, SizeOf(Double)); //X轴的夹角<br><br> dAngle := GetAngle(Terminal.RefPt.Origin.dX, Terminal.RefPt.Origin.dY, Terminal.RefPt.Y_Axe.dX, Terminal.RefPt.Y_Axe.dY) - PI/2;<br> BlockWrite(F, dAngle, SizeOf(Double)); //Y轴的夹角<br> end;<br><br> BlockWrite(F, Terminal.TerminalRect.LeftTop.dX,SizeOf(Double));<br> BlockWrite(F, Terminal.TerminalRect.LeftTop.dY,SizeOf(Double));<br> BlockWrite(F, Terminal.TerminalRect.RightTop.dX,SizeOf(Double));<br> BlockWrite(F, Terminal.TerminalRect.RightTop.dY,SizeOf(Double));<br> BlockWrite(F, Terminal.TerminalRect.RightBottom.dX,SizeOf(Double));<br> BlockWrite(F, Terminal.TerminalRect.RightBottom.dY,SizeOf(Double));<br> BlockWrite(F, Terminal.TerminalRect.LeftBottom.dX,SizeOf(Double));<br> BlockWrite(F, Terminal.TerminalRect.LeftBottom.dY,SizeOf(Double));<br><br> Inc(nAccuBlockBytes, Terminal.BlockList.Count);<br> end;<br> //以下写Block信息<br> nAccuLaneBytes := 0; <br> for I := 0 to Yard.TerminalList.Count - 1 do begin<br> Terminal := TTerminal(Yard.TerminalList.Items);<br> //写Block<br> for J := 0 to Terminal.BlockList.Count - 1 do begin<br> Block := TBlock(Terminal.BlockList.Items[J]);<br><br> BlockWrite(F, Block.Rect.Right,SizeOf(LongWord));<br> BlockWrite(F, Block.Rect.Left,SizeOf(LongWord));<br> BlockWrite(F, Block.Rect.Bottom,SizeOf(LongWord));<br> BlockWrite(F, Block.Rect.Top,SizeOf(LongWord));<br><br> //Lane在数据文件中的起始索引<br> uBuf32 := Block.GetInvalidLaneCount;<br> if (uBuf32 > 0) then begin<br> BlockWrite(F, nAccuLaneBytes, SizeOf(LongWord));<br> Inc(nAccuLaneBytes, uBuf32);<br><br> BlockWrite(F, uBuf32, SizeOf(LongWord));<br> end<br> else begin<br> //规则Block<br> BlockWrite(F, uBuf32, SizeOf(LONGWORD));<br> BlockWrite(F, uBuf32, SizeOf(LONGWORD));<br> end;<br><br> BlockWrite(F, Block.ID, 4);<br> //写Stack 索引<br> BlockWrite(F, nAccuStackBytes, SizeOf(LongWord));<br> BlockWrite(F, Block.StackList.Count, SizeOf(Word));<br> Inc(nAccuStackBytes, Block.StackList.Count); //16为StackIndex结构的长度<br> BlockWrite(F, Block.nTrackLane, SizeOf(Word)); //大车道方向<br> end;<br> end;<br> //以下写Stack记录<br> nAccuLaneBytes := 0;<br> for I := 0 to Yard.TerminalList.Count - 1 do begin<br> Terminal := TTerminal(Yard.TerminalList.Items);<br> for J := 0 to Terminal.BlockList.Count - 1 do begin<br> Block := TBlock(Terminal.BlockList.Items[J]);<br> //写Stack<br> for K := 0 to Block.StackList.Count - 1 do begin<br> Stack := TStack(Block.StackList.Items[K]);<br> BlockWrite(F, Stack.MaxX, SizeOf(LongWord));<br> BlockWrite(F, Stack.MinX, SizeOf(LongWord));<br> BlockWrite(F, Stack.ID,4);<br> if Stack.LDI <> 0 then begin<br> BlockWrite(F, nAccuLaneBytes, SizeOf(WORD));<br> BlockWrite(F, Stack.LaneDef.LaneList.Count, SizeOf(Word));<br> Inc(nAccuLaneBytes, Stack.LaneDef.LaneList.Count); //LaneLocation的尺寸<br> end<br> else begin<br> uBuf16 := 0;<br> BlockWrite(F, uBuf16, SizeOf(WORD));<br> BlockWrite(F, uBuf16, SizeOf(WORD));<br> end;<br> end;<br> end;<br> end;<br><br> CloseFile(F);<br>end;<br><br>procedure TBlock.CalcRect;<br>var<br> I : integer;<br> Stack : TStack;<br>begin<br> Rect.Left := MaxInt;<br> Rect.Right := Low(Integer);<br> Rect.Top := MaxInt;<br> Rect.Bottom := Low(Integer);<br><br> for I := 0 to StackList.Count - 1 do begin<br> Stack := TStack(StackList.Items);<br> Inc(nRecCount,Stack.RecList.Count);<br> if Stack.Rect.left < Rect.Left then Rect.Left := Stack.Rect.Left;<br> if Stack.Rect.Right > Rect.Right then Rect.Right := Stack.Rect.Right;<br> if Stack.Rect.Top < Rect.Top then Rect.Top := Stack.Rect.Top;<br> if Stack.Rect.Bottom > Rect.Bottom then Rect.Bottom := Stack.Rect.Bottom;<br> end;<br>end;<br><br>constructor TBlock.Create;<br>begin<br> StackList := TList.Create;<br> StackIndexList := TList.Create;<br>end;<br><br>destructor TBlock.Destroy;<br>var<br> I : integer;<br>begin<br> for I := 0 to StackList.Count - 1 do begin<br> TStack(StackList).Free;<br> end;<br> StackList.Free;<br> for I := 0 to StackIndexList.Count - 1 do begin<br> FreeMem(StackIndexList.Items,SizeOf(Integer));<br> end;<br> StackIndexList.Free;<br> inherited;<br>end;<br><br>procedure Process(FileName: string);<br>var<br> InF : TextFile;<br><br> Buf : string;<br> Block : TBlock;<br> Rec : TRec;<br><br> CurYardID : integer;<br><br> CurStackID : string;<br> pStackIndex : PInteger;<br> Stack : TStack;<br><br> I, J, K : integer;<br> Terminal : TTerminal;<br><br> LaneDef : TLaneDef;<br> Lane : TLane;<br>begin<br> AssignFile(Inf,FileName);<br> Reset(InF);<br><br> Block := nil;<br> Stack := nil;<br><br> Terminal := nil;<br> Yard := TYard.Create;<br> while not Eof(InF) do begin<br> ReadLn(Inf,Buf);<br> Buf := Trim(Buf);<br> if (Length(Buf) > 0) and (Buf[1] <> '*') then begin //跳过注示行<br> if Pos('[DATE]',UpperCase(Buf)) > 0 then begin<br> while not Eof(Inf) do begin<br> ReadLn(Inf,Buf);<br> if Pos('[END OF DEFINITION]',UpperCase(Buf)) > 0 then begin<br> Break;<br> end<br> else if (Length(Buf) > 0) and (Buf[1] <> '*') then begin<br> StrPCopy(Yard.sDate,Buf);<br> end;<br> end;<br> end<br> else if Pos('[CSD]', UpperCase(Buf)) > 0 then begin<br> while not Eof(Inf) do begin<br> ReadLn(Inf,Buf);<br> if Pos('[END OF DEFINITION]',UpperCase(Buf)) > 0 then begin<br> Break;<br> end<br> else if (Length(Buf) > 0) and (Buf[1] <> '*') then begin<br> Terminal := TTerminal.Create;<br> StrPCopy(Terminal.sName, GetStrItem(Buf,'/',1));<br> Terminal.sCoor := GetStrItem(Buf,'/',2);<br> Yard.TerminalList.Add(Terminal);<br> end;<br> end;<br> end<br> else if Pos('[RPD]', UpperCase(Buf)) > 0 then begin<br> while not Eof(Inf) do begin<br> ReadLn(Inf,Buf);<br> if Pos('[END OF DEFINITION]',UpperCase(Buf)) > 0 then begin<br> Break;<br> end<br> else if (Length(Buf) > 0) and (Buf[1] <> '*') then begin<br> for I := 0 to Yard.TerminalList.Count - 1 do begin<br> Terminal := TTerminal(Yard.TerminalList.Items);<br> if Terminal.sName = GetStrItem(Buf, '/', 1) then Break;<br> Terminal := nil;<br> end;<br> if Assigned(Terminal) then begin<br> if (Terminal.sCoor = 'HKG80') or (Terminal.sCoor = 'BJ54') then begin<br> Terminal.RefPt.Origin.dX := StrToFloat(GetStrItem(Buf,'/',2));<br> Terminal.RefPt.Origin.dY := StrToFloat(GetStrItem(Buf,'/',3));<br> Terminal.RefPt.X_Axe.dX := StrToFloat(GetStrItem(Buf,'/',4));<br> Terminal.RefPt.X_Axe.dY := StrToFloat(GetStrItem(Buf,'/',5));<br> Terminal.RefPt.Y_Axe.dX := StrToFloat(GetStrItem(Buf,'/',6));<br> Terminal.RefPt.Y_Axe.dY := StrToFloat(GetStrItem(Buf,'/',7));<br> end<br> else if (Terminal.sCoor = 'WGS84') then begin<br> Terminal.RefPt.Origin.dY := GetDMSR(GetStrItem(Buf,'/',2));<br> Terminal.RefPt.Origin.dX := GetDMSR(GetStrItem(Buf,'/',3));<br> Terminal.RefPt.X_Axe.dY := GetDMSR(GetStrItem(Buf,'/',4));<br> Terminal.RefPt.X_Axe.dX := GetDMSR(GetStrItem(Buf,'/',5));<br> Terminal.RefPt.Y_Axe.dY := GetDMSR(GetStrItem(Buf,'/',6));<br> Terminal.RefPt.Y_Axe.dX := GetDMSR(GetStrItem(Buf,'/',7));<br> end<br> end;<br> end;<br> end;<br> end<br> else if Pos('[TD]', UpperCase(Buf)) > 0 then begin<br> while not Eof(Inf) do begin<br> ReadLn(Inf,Buf);<br> if Pos('[END OF DEFINITION]',UpperCase(Buf)) > 0 then begin<br> Break;<br> end<br> else if (Length(Buf) > 0) and (Buf[1] <> '*') then begin<br> for I := 0 to Yard.TerminalList.Count - 1 do begin<br> Terminal := TTerminal(Yard.TerminalList.Items);<br> if Terminal.sName = GetStrItem(Buf, '/', 1) then Break;<br> Terminal := nil;<br> end;<br> if Assigned(Terminal) then begin<br> if (Terminal.sCoor = 'HKG80') or (Terminal.sCoor = 'BJ54') then begin<br> with Terminal.TerminalRect do begin<br> LeftTop.dX := StrToFloat(GetStrItem(Buf, '/',2));<br> LeftTop.dY := StrToFloat(GetStrItem(Buf, '/',3));<br> RightTop.dX := StrToFloat(GetStrItem(Buf, '/',4));<br> RightTop.dY := StrToFloat(GetStrItem(Buf, '/',5));<br> RightBottom.dX := StrToFloat(GetStrItem(Buf, '/',6));<br> RightBottom.dY := StrToFloat(GetStrItem(Buf, '/',7));<br> LeftBottom.dX := StrToFloat(GetStrItem(Buf, '/',8));<br> LeftBottom.dY := StrToFloat(GetStrItem(Buf, '/',9));<br> end;<br> end<br> else if (Terminal.sCoor = 'WGS84') then begin<br> with Terminal.TerminalRect do begin<br> LeftTop.dY := GetDMSR(GetStrItem(Buf, '/',2));<br> LeftTop.dX := GetDMSR(GetStrItem(Buf, '/',3));<br> RightTop.dY := GetDMSR(GetStrItem(Buf, '/',4));<br> RightTop.dX := GetDMSR(GetStrItem(Buf, '/',5));<br> RightBottom.dY := GetDMSR(GetStrItem(Buf, '/',6));<br> RightBottom.dX := GetDMSR(GetStrItem(Buf, '/',7));<br> LeftBottom.dY := GetDMSR(GetStrItem(Buf, '/',8));<br> LeftBottom.dX := GetDMSR(GetStrItem(Buf, '/',9));<br> end;<br> end;<br> end;<br> end;<br> end;<br> end<br> else if Pos('[BD]', UpperCase(Buf)) > 0 then begin<br> while not Eof(Inf) do begin<br> Terminal := nil;<br> ReadLn(Inf,Buf);<br> if Pos('[END OF DEFINITION]',UpperCase(Buf)) > 0 then begin<br> Break;<br> end<br> else if (Length(Buf) > 0) and (Buf[1] <> '*') then begin<br> if (not Assigned(Terminal)) or (Terminal.sName <> GetStrItem(Buf, '/', 1)) then begin<br> for I := 0 to Yard.TerminalList.Count - 1 do begin<br> Terminal := TTerminal(Yard.TerminalList.Items);<br> if Terminal.sName = GetStrItem(Buf, '/', 1) then Break;<br> Terminal := nil;<br> end;<br> end;<br> if Assigned(Terminal) then begin<br> Block := TBlock.Create;<br> StrPCopy(Block.ID,GetStrItem(Buf, '/',2));<br> Block.Rect.Left := Trunc(1000 * StrToFloat(GetStrItem(Buf, '/', 3)));<br> Block.Rect.Right := Trunc(1000 * StrToFloat(GetStrItem(Buf, '/', 4)));<br> Block.Rect.Top := Trunc(1000 * StrToFloat(GetStrItem(Buf, '/', 5)));<br> Block.Rect.Bottom := Trunc(1000 * StrToFloat(GetStrItem(Buf, '/', 6)));<br> Block.nTrackLane := StrToInt(GetStrItem(Buf, '/',7));<br> Terminal.BlockList.Add(Block);<br> end;<br> end;<br> end;<br> end<br> else if Pos('[SD]', UpperCase(Buf)) > 0 then begin<br> Block := nil;<br> while not Eof(Inf) do begin<br> ReadLn(Inf,Buf);<br> Terminal := nil;<br> if Pos('[END OF DEFINITION]',UpperCase(Buf)) > 0 then begin<br> Break;<br> end<br> else if (Length(Buf) > 0) and (Buf[1] <> '*') then begin<br> if (not Assigned(Terminal)) or (Terminal.sName <> GetStrItem(Buf, '/', 1)) then begin<br> for I := 0 to Yard.TerminalList.Count - 1 do begin<br> Terminal := TTerminal(Yard.TerminalList.Items);<br> if Terminal.sName = GetStrItem(Buf, '/', 1) then Break;<br> Terminal := nil;<br> end;<br> end;<br> if (Assigned(Terminal)) then begin<br> if (not Assigned(Block)) or (String(Block.ID) <> GetStrItem(Buf, '/', 2)) then begin<br> Block := Terminal.GetBlock(GetStrItem(Buf, '/', 2));<br> end;<br> if Assigned(Block) then begin<br> Stack := TStack.Create;<br> StrPCopy(Stack.ID, GetStrItem(Buf, '/', 3));<br> Stack.nSpread := StrToInt(GetStrItem(Buf, '/', 4));<br> Stack.MinX := Trunc(1000 * StrToFloat(GetStrItem(Buf, '/', 5)));<br> Stack.MaxX := Trunc(1000 * StrToFloat(GetStrItem(Buf, '/', 6)));<br> Stack.LDI := StrToInt(GetStrItem(Buf, '/', 7));<br><br> Block.StackList.Add(Stack);<br> end;<br> end;<br> end;<br> end;<br> end<br> else if Pos('[LD]', UpperCase(Buf)) > 0 then begin<br> LaneDef := nil;<br> while not Eof(Inf) do begin<br> ReadLn(Inf,Buf);<br> if Pos('[END OF DEFINITION]',UpperCase(Buf)) > 0 then begin<br> Break;<br> end<br> else if (Length(Buf) > 0) and (Buf[1] <> '*') then begin<br> if Pos('TYPE OF DEFINITION', UpperCase(Buf)) > 0 then begin<br> end<br> else begin<br> if (not Assigned(LaneDef)) or (LaneDef.LDI <> StrToInt(GetStrItem(Buf,'/',1))) then begin<br> LaneDef := TLaneDef.Create;<br> LaneDef.LDI := StrToInt(GetStrItem(Buf,'/',1));<br> Yard.LaneDefList.Add(LaneDef);<br> end;<br> Lane := TLane.Create;<br> StrPCopy(Lane.Name, GetStrItem(Buf, '/', 2));<br> Lane.MinY := StrToFloat(GetStrItem(Buf, '/', 3));<br> Lane.MaxY := StrToFloat(GetStrItem(Buf, '/', 4));<br> Lane.TLD := StrToInt(GetStrItem(Buf, '/', 5));<br> LaneDef.LaneList.Add(Lane);<br> end<br> end;<br> end;<br> end;<br> //读完后,建立Stack和Lane的关系<br>{ for I := 0 to Yard.TerminalList.Count - 1 do begin<br> Terminal := TTerminal(Yard.TerminalList.Items);<br> for J := 0 to Terminal.BlockList.Count - 1 do begin<br> Block := TBlock(Terminal.BlockList.Items[J]);<br> for K := 0 to Block.StackList.Count - 1 do begin<br> Stack := TStack(Block.StackList.Items[K]);<br> Yard.MatchLDI(Stack);<br> end;<br> end;<br> end;<br>}<br> end;<br> end;<br><br> //读完后,建立Stack和Lane的关系<br> for I := 0 to Yard.TerminalList.Count - 1 do begin<br> Terminal := TTerminal(Yard.TerminalList.Items);<br> for J := 0 to Terminal.BlockList.Count - 1 do begin<br> Block := TBlock(Terminal.BlockList.Items[J]);<br> for K := 0 to Block.StackList.Count - 1 do begin<br> Stack := TStack(Block.StackList.Items[K]);<br> Yard.MatchLDI(Stack);<br> end;<br> end;<br> end;<br><br><br> CloseFile(Inf);<br> WriteRecFileEx('binyard.lch');<br> WriteIndexFileEx('binindex.lch');<br> Yard.Free;<br>end;<br><br>{ TYard }<br><br>constructor TTerminal.Create;<br>begin<br> BlockList := TList.Create;<br>end;<br><br>destructor TTerminal.Destroy;<br>var<br> I : integer;<br>begin<br> for I := 0 to BlockList.Count - 1 do begin<br> TBlock(BlockList.Items).Free;<br> end;<br> BlockList.Free;<br> inherited;<br>end;<br><br>function TTerminal.FindBlock(Block: TBlock): TBlock;<br>var<br> I : integer;<br>begin<br> result := nil;<br> for I := 0 to BlockList.Count - 1 do begin<br> if Block.ID = TBlock(BlockList.Items).ID then begin<br> result := Block;<br> Exit;<br> end;<br> end;<br>end;<br><br>function TTerminal.GetBlock(sKey: string): TBlock;<br>var<br> I : integer;<br> B : TBlock;<br>begin<br> result := nil;<br> for I := 0 to BlockList.Count - 1 do begin<br> B := TBlock(BlockList.Items);<br> if String(B.ID) = sKey then begin<br> result := B;<br> Break;<br> end;<br> end;<br>end;<br><br>procedure TYard.MatchLDI(Stack: TStack);<br>var<br> I : integer;<br> LaneDef : TLaneDef;<br>begin<br> for I := 0 to LaneDefList.Count - 1 do begin<br> LaneDef := TLaneDef(LaneDefList.Items);<br> if LaneDef.LDI = Stack.LDI then begin<br> Stack.LaneDef := LaneDef;<br> Break;<br> end;<br> end;<br>end;<br><br>{ TStack }<br><br>procedure TStack.CalcRect;<br>var<br> I : integer;<br> Rec : TRec;<br>begin<br> Rect.Left := MaxInt;<br> Rect.Right := Low(Integer);<br> Rect.Top := MaxInt;<br> Rect.Bottom := Low(Integer);<br><br> for I := 0 to RecList.Count - 1 do begin<br> Rec := TRec(RecList.Items);<br> if Rec.Rect.left < Rect.Left then Rect.Left := Rec.Rect.Left;<br> if Rec.Rect.Right > Rect.Right then Rect.Right := Rec.Rect.Right;<br> if Rec.Rect.Top < Rect.Top then Rect.Top := Rec.Rect.Top;<br> if Rec.Rect.Bottom > Rect.Bottom then Rect.Bottom := Rec.Rect.Bottom;<br> end;<br>end;<br><br>function TBlock.FindRec(Rec: TRec): TStack;<br>var<br> I, J : integer;<br> Stack : TStack;<br>begin<br> result := nil;<br> for I := 0 to StackList.Count - 1 do begin<br> Stack := TStack(StackList.Items);<br> if Rec.StackID = String(Stack.ID) then begin<br> result := Stack;<br> Exit;<br> end;<br> end;<br>end;<br><br>function TBlock.FindStack(Stack: TStack): TStack;<br>var<br> I : integer;<br>begin<br> result := nil;<br> for I := 0 to StackList.Count - 1 do begin<br> if Stack.ID = TStack(StackList.Items).ID then begin<br> result := TStack(StackList.Items);<br> Exit;<br> end;<br> end;<br>end;<br><br>function TBlock.GetInvalidLaneCount: integer;<br>var<br> I : integer;<br> Stack : TStack;<br>begin<br> result := 0;<br> for I := 0 to StackList.Count - 1 do begin<br> Stack := TStack(StackList.Items);<br> if Assigned(Stack.LaneDef) then begin<br> if Stack.LaneDef.LDI <> 0 then begin<br> Inc(Result,Stack.LaneDef.LaneList.Count);<br> end;<br> end;<br> end;<br>end;<br><br><br>function TBlock.GetRecCount: integer;<br>var<br> I, J : integer;<br>begin<br> result := 0;<br> for I := 0 to StackList.Count - 1 do begin<br> Result := result + TStack(StackList.Items).RecList.Count;<br> end;<br>end;<br><br>constructor TStack.Create;<br>begin<br> RecList := TList.Create;<br> LaneDef := nil;<br>end;<br><br>destructor TStack.Destroy;<br>var<br> I : integer;<br>begin<br> for I := 0 to RecList.Count - 1 do begin<br> TRec(RecList.Items).Free;<br> end;<br> RecList.Free;<br> inherited;<br>end;<br><br>constructor TYard.Create;<br>begin<br> TerminalList := TList.Create;<br> LaneDefList := TList.Create;<br> nTrackWidth := 3780;<br> nLaneWidth := 2440 + 43;<br>end;<br><br>destructor TYard.Destroy;<br>var<br> I : integer;<br>begin<br> for I := 0 to LaneDefList.Count - 1 do begin<br> TLaneDef(LaneDefList.Items).Free;<br> end;<br> LaneDefList.Free;<br> for I := 0 to TerminalList.Count - 1 do begin<br> TTerminal(TerminalList.Items).Free;<br> end;<br> TerminalList.Free;<br> inherited;<br>end;<br><br>function TTerminal.GetBlockSize: integer;<br>begin<br> result := 36; //在索引文件中一个Block记录长度为36<br>end;<br><br><br>{ TLaneDef }<br><br>constructor TLaneDef.Create;<br>begin<br> LaneList := TList.Create;<br>end;<br><br>destructor TLaneDef.Destroy;<br>var<br> I : integer;<br>begin<br> for I := 0 to LaneList.Count - 1 do begin<br> TLane(LaneList.Items).Free;<br> end;<br> LaneList.Clear;<br> LaneList.Free;<br> inherited;<br>end;<br><br>function GeoRect(X1,Y1,X2,Y2 : Integer) : TGeoRect;<br>var<br> Rect : TGeoRect;<br>begin<br> with Rect do begin<br> Left := Min(X1,X2);<br> Right := Max(X1,X2);<br> Top := Min(Y1,Y2);<br> Bottom := Max(Y1,Y2);<br> end;<br> result := Rect;<br>end;<br><br>{<br>返回值<br> 1 - 正确<br> -1 - 文件不存在<br>}<br>function TransferYardMap(pszFileName : PChar) : integer;stdCall;<br>var<br> I : integer;<br>begin<br> result := 0;<br> if not FileExists(pszFileName) then begin<br> result := 1;<br> Exit;<br> end;<br> try<br> Process(pszFileName);<br> except<br> result := 2;<br> end;<br>end;<br><br>exports<br> TransferYardMap;<br><br>begin<br>end.<br><br>*******************************************************************<br>VC中调用:<br> HINSTANCE hDLL;<br> PROCESS_DATA Process_Data = NULL;<br><br> if (NULL == (hDLL = LoadLibrary("BuildYard.dll"))){<br> AfxMessageBox("Error to load BuildYard.dll!");<br> return;<br> }<br> Process_Data = (PROCESS_DATA)GetProcAddress(hDLL,"TransferYardMap");<br> if (NULL == Process_Data){<br> AfxMessageBox("Error to get procedure's address!");<br> return; <br> }<br> int nRet = Process_Data("yardmap.txt");<br> switch (nRet){<br> case 2 : AfxMessageBox("Error on calling dll library!"); break; <br> case 1 : AfxMessageBox("YardMap file not found!"); break;<br> case 0 : AfxMessageBox("Successful!"); break;<br> }<br> FreeLibrary(hDLL);<br> return;<br>