ezsystem.pas
来自「很管用的GIS控件」· PAS 代码 · 共 2,202 行 · 第 1/5 页
PAS
2,202 行
Entities[Cnt] := GetClassFromID( Cnt ).Create( 4 );
AvoidList := TIntegerList.Create;
Try
For Idx := 0 To Selection.Count - 1 Do
Begin
With Selection.Items[Idx] Do
Begin { TEzSelectionLayer }
AvoidList.Clear;
For K := 0 To SelList.Count - 1 Do
Begin
TmpEnt := Layer.LoadEntityWithRecno( SelList[K] );
If TmpEnt.Points.Parts.Count > 1 Then
Begin
TempL := GetListOfVectors( TmpEnt );
For J := 0 To TempL.Count - 1 Do
Begin
TmpEnt2 := Entities[TmpEnt.EntityID];
TmpEnt2.Assign( TmpEnt );
TmpEnt2.Points.Clear;
TmpEnt2.Points.Assign( TEzVector( TempL[J] ) );
{ Add this entity to the layer }
NewRecno := Layer.AddEntity( TmpEnt2 );
{ now copy the DBF record }
If Layer.DBTable <> Nil Then
Layer.CopyRecord( K, NewRecno );
End;
freelist( TempL );
End
Else
AvoidList.Add( SelList[K] );
TmpEnt.Free;
End;
For K := 0 To AvoidList.Count - 1 Do
Delete( AvoidList[K] );
End;
End;
If Not PreserveOriginals Then
DeleteSelection;
Finally
For Cnt := Low( TEzEntityID ) To High( TEzEntityID ) Do
Entities[Cnt].Free;
AvoidList.Free;
End;
End;
End;
{ CombineSelection }
Procedure CombineSelection( DrawBox: TEzBaseDrawBox; DeleteOriginals: Boolean );
Var
Combined, TmpEnt: TEzEntity;
I, K, n, Idx, cnt, NewRecno,
SourceRecnoClosed, SourceRecnoOpened: Integer;
TempL, LayerListClosed, LayerListOpened,
ListClosed, ListOpened: TList;
SourceLayerOpened,
SourceLayerClosed: TEzBaseLayer;
IsSame: Boolean;
V: TEzVector;
{ subject, clipping, result: TList; }
AvoidList: TIntegerList;
Begin
{ Combine all open entities
(TLine2D, TEzPolyline, TEzArc, TSpline2D) into one single entity }
{ Count all open entities }
With DrawBox Do
Begin
If Selection.Count = 0 Then Exit;
ListClosed := TList.Create;
ListOpened := TList.Create;
LayerListClosed := TList.Create;
LayerListOpened := TList.Create;
SourceLayerClosed := Nil;
SourceLayerOpened := Nil;
SourceRecNoClosed := 0;
SourceRecNoOpened := 0;
AvoidList := TIntegerList.Create;
Try
For cnt := 0 To Selection.Count - 1 Do
Begin
With Selection.Items[cnt] Do
Begin { TEzSelectionLayer }
AvoidList.Clear;
For K := 0 To SelList.Count - 1 Do
Begin
TmpEnt := Layer.LoadEntityWithRecno( SelList[K] );
If TmpEnt <> Nil Then
Begin
If TmpEnt.IsClosed Then
Begin
TempL := GetListOfVectors( TmpEnt );
For I := 0 To TempL.Count - 1 Do
ListClosed.Add( TEzVector( TempL[I] ) );
TempL.Free;
LayerListClosed.Add( Layer );
If SourceLayerClosed = Nil Then
Begin
SourceLayerClosed := Layer;
SourceRecnoClosed := K;
End;
End
Else
Begin
TempL := GetListOfVectors( TmpEnt );
For I := 0 To TempL.Count - 1 Do
ListOpened.Add( TEzVector( TempL[I] ) );
TempL.Free;
LayerListOpened.Add( Layer );
If ( SourceLayerOpened = Nil ) Then
Begin
SourceLayerOpened := Layer;
SourceRecnoOpened := K;
End;
End;
TmpEnt.Free;
End
Else
AvoidList.add( SelList[K] );
End;
For K := 0 To AvoidList.Count - 1 Do
Delete( AvoidList[K] );
End;
End;
If ListOpened.Count > 1 Then
Begin
(* combine them *)
Combined := TEzPolyLine.CreateEntity( [Point2D( 0, 0 )] );
Try
Idx := 0;
Combined.Points.Clear;
For cnt := 0 To ListOpened.Count - 1 Do
Begin
V := TEzVector( ListOpened[cnt] );
{if cnt=0 then
firstccw:= EzLib.IsCounterClockWise(V)
else
begin
if not (EzLib.IsCounterClockWise(V)=firstccw) then
begin
// revert direction to same
V.RevertDirection;
end;
end; }
n := V.Count;
Combined.Points.Parts.Add( Idx );
For K := 0 To n - 1 Do
Combined.Points.Add( V[K] );
Inc( Idx, n );
End;
If Combined.Points.Parts.Count = 1 Then
Combined.Points.Parts.Clear;
(* Now save this entity to the original layer or to the current layer
if not possible *)
IsSame := True;
For K := 1 To LayerListOpened.Count - 1 Do
// all selected are of same layer ?
If TEzBaseLayer( LayerListOpened[K] ) <> TEzBaseLayer( LayerListOpened[0] ) Then
Begin
IsSame := False;
Break;
End;
If IsSame Then
Begin
NewRecno := TEzBaseLayer( LayerListOpened[0] ).AddEntity( Combined );
SourceLayerOpened.CopyRecord( SourceRecNoOpened, NewRecno );
End
Else
DrawBox.AddEntity( GIS.CurrentLayerName, Combined );
Finally
Combined.Free;
End;
End;
If ListClosed.Count > 1 Then
Begin
// combine them
Combined := TEzPolygon.CreateEntity( [Point2D( 0, 0 )] );
Try
Idx := 0;
Combined.Points.Clear;
For cnt := 0 To ListClosed.Count - 1 Do
Begin
V := TEzVector( ListClosed[cnt] );
n := V.Count;
Combined.Points.Parts.Add( Idx );
For K := 0 To n - 1 Do
Combined.Points.Add( V[K] );
Inc( Idx, n );
End;
If Combined.Points.Parts.Count = 1 Then
Combined.Points.Parts.Clear;
(* Now save this entity to the original layer or to the current layer
if not possible *)
IsSame := True;
For k := 1 To LayerListClosed.Count - 1 Do
// all selected are of same layer ?
If TEzBaseLayer( LayerListClosed[k] ) <> TEzBaseLayer( LayerListClosed[0] ) Then
Begin
IsSame := False;
Break;
End;
If IsSame Then
Begin
NewRecno := TEzBaseLayer( LayerListClosed[0] ).AddEntity( Combined );
SourceLayerClosed.CopyRecord( SourceRecNoClosed, NewRecno );
End
Else
DrawBox.AddEntity( GIS.CurrentLayerName, Combined );
Finally
Combined.Free;
End;
End;
If ( ListOpened.Count > 1 ) Or ( ListClosed.Count > 1 ) And DeleteOriginals Then
DeleteSelection;
Finally
If ( ListClosed <> Nil ) Then
freelist( ListClosed );
If ( ListOpened <> Nil ) Then
freelist( ListOpened );
LayerListClosed.Free;
LayerListOpened.Free;
AvoidList.free;
End;
End;
End;
Function CreateDllList( FieldList: TStringList ): String;
Var
i: integer;
Begin
Result := '';
For i := 0 To pred( FieldList.Count ) Do
Result := Result + FieldList[i] + '\';
End;
{---------------------------------------------------------------------}
Procedure ReadFile( Const Path: String; FileList: TStrings );
Var
SearchRec: TSearchRec;
FindResult: integer;
Begin
FileList.Clear;
Try
FindResult := FindFirst( Path, faAnyFile, SearchRec );
While FindResult = 0 Do
Begin
FileList.Add( SearchRec.Name );
FindResult := FindNext( SearchRec );
End;
Finally
SysUtils.FindClose( SearchRec );
End;
End;
Function CreateIfNotExists( Const FileName: String ): TFileStream;
Begin
If FileExists( FileName ) Then
Result := TFileStream.Create( FileName, fmOpenReadWrite Or fmShareDenyNone )
Else
Result := TFileStream.Create( FileName, fmCreate );
End;
Procedure EzGISError( Const ErrStr: String );
Begin
Raise Exception.Create( ErrStr );
End;
Function HasAttr( Const FileName: String; Attr: Word ): Boolean;
Var
FileAttr: Integer;
Begin
FileAttr := FileGetAttr( FileName );
If FileAttr = -1 Then
FileAttr := 0;
Result := ( FileAttr And Attr ) = Attr;
End;
Procedure EzWriteStrToStream( Const TextToWrite: String; stream: TStream );
Var
n: Integer;
Begin
n := Length( TextToWrite );
stream.write( n, sizeof( Integer ) );
If n > 0 Then
stream.write( TextToWrite[1], n );
End;
Function EzReadStrFromStream( stream: TStream ): String;
Var
n: Integer;
Begin
stream.Read( n, sizeof( Integer ) );
If n > 0 Then
Begin
SetLength( Result, n );
stream.Read( Result[1], n );
End
Else
Result := '';
End;
Function WritePrivateProfileInt( Const Section, Entry: String;
iToWrite: word; Const FileName: String ): BOOL;
Var
Work: String;
Begin
Work := format( '%.6d', [iToWrite] );
WritePrivateProfileInt :=
WritePrivateProfileString( PChar( Section ), PChar( Entry ), PChar( Work ),
PChar( FileName ) );
End;
Procedure RestoreFormPlacement( const IniFileName: string;
Frm: TForm; ShwNormal: Boolean; Additional: TStrings );
Var
I,n: Integer;
wpPos: TWINDOWPLACEMENT;
ptPos: TPOINT;
rcPos: TRECT;
//hWindow: HWND;
SectionName: String;
SetMin: boolean;
Inifile: TInifile;
Begin
//hWindow := Frm.Handle;
SectionName := Frm.Name;
SetMin := false;
wpPos.length := sizeof( wpPos );
(* Flag to restore minimized position *)
If SetMin Then
wpPos.flags := WPF_SETMINPOSITION
Else
wpPos.flags := 0;
Inifile:= TIniFile.Create( IniFileName );
With Inifile Do
Try
ptPos.x := ReadIntFromIni( Inifile, SectionName, 'MinX', -65535 );
If ptPos.x = -65535 Then
Exit; // the record not yet exists
(* Get window state (max, min or restored) *)
wpPos.showCmd := ReadIntFromIni( Inifile, SectionName, 'ShowCmd', SW_SHOWNORMAL );
(* Minimized position *)
ptPos.x := ReadIntFromIni( Inifile, SectionName, 'MinX', -1 );
ptPos.y := ReadIntFromIni( Inifile, SectionName, 'MinY', -1 );
If ( ( ptPos.x = -1 ) Or ( ptPos.y = -1 ) ) Then
wpPos.flags := 0;
wpPos.ptMinPosition := ptPos;
(* Maximized position *)
ptPos.x := ReadIntFromIni( Inifile, SectionName, 'MaxX', 0 );
ptPos.y := ReadIntFromIni( Inifile, SectionName, 'MaxY', 0 );
wpPos.ptMaxPosition := ptPos;
(* Window position and size *)
rcPos.top := ReadIntFromIni( Inifile, SectionName, 'Top', GetSystemMetrics( SM_CYSCREEN ) Div 8 );
rcPos.left := ReadIntFromIni( Inifile, SectionName, 'Left', GetSystemMetrics( SM_CXSCREEN ) Div 8 );
If true{wpPos.flags <> 0} Then
Begin
rcPos.bottom := ReadIntFromIni( Inifile, SectionName, 'Bottom', rcPos.top * 7 );
rcPos.right := ReadIntFromIni( Inifile, SectionName, 'Right', rcPos.left * 7 );
End
Else
Begin
rcPos.Bottom := rcpos.Top + frm.Height;
rcPos.Right := rcpos.Left + frm.Width;
End;
if Additional <> Nil then
begin
Additional.Clear;
n:= ReadIntFromIni( Inifile, SectionName + 'AddInfo', 'Lines',0);
for I:= 0 to n-1 do
Additional.Add( ReadString( SectionName + 'AddInfo', 'Line' + IntToStr(I), '' ) );
end;
Finally
Free;
End;
wpPos.rcNormalPosition := rcPos;
(* Restore everything *)
{If ShwNormal And ( Frm.BorderStyle In [bsSizeable, bsSizeToolWin] ) Then
SetWindowPlacement( hWindow, @wpPos )
Else }
With rcPos Do
Begin
Frm.Top := Top;
Frm.Left := Left;
If Frm.BorderStyle In [bsSizeable, bsSizeToolWin] Then
Begin
Frm.Width := ( Right - Left );
Frm.Height := ( Bottom - Top );
End;
If wpPos.showCmd = SW_SHOWMAXIMIZED Then
Frm.WindowState := wsMaximized
Else If wpPos.showCmd = SW_SHOWMINIMIZED Then
Frm.WindowState := wsMinimized
Else
Frm.WindowState := wsNormal;
End;
End;
Procedure SaveFormPlacement( const IniFilename: string; Frm: TForm;
Additional: TStrings );
Var
I,n: Integer;
wpPos: TWINDOWPLACEMENT;
ptPos: TPOINT;
rcPos: TRECT;
hWindow: HWND;
SectionName: String;
Begin
hWindow := Frm.Handle;
SectionName := Frm.Name;
wpPos.length := sizeof( wpPos );
(* Save everything *)
GetWindowPlacement( hWindow, @wpPos );
With TInifile.Create( IniFileName ) Do
Try
(* Save current window state (maximized, minimized or restored) *)
WriteInteger( SectionName, 'ShowCmd', wpPos.showCmd );
(* Save Minimized position *)
ptPos := wpPos.ptMinPosition;
WriteInteger( SectionName, 'MinX', ptPos.x );
WriteInteger( SectionName, 'MinY', ptPos.y );
(* Save Maximized position *)
ptPos := wpPos.ptMaxPosition;
WriteInteger( SectionName, 'MaxX', ptPos.x );
WriteInteger( SectionName, 'MaxY', ptPos.y );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?