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 + -
显示快捷键?