⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ezdgnlayer.pas

📁 很管用的GIS控件
💻 PAS
📖 第 1 页 / 共 5 页
字号:
        Break;
      End ;

      FDGNInputStream.Position := p + ( ( Elm_Hdr.Words + 2 ) * SizeOf( Word ) );
    End;
  End;

  Application.ProcessMessages;

  BadList:= TIntegerList.Create;
  OldCursor:= Screen.Cursor;
  Screen.Cursor:= crHourglass;
  Try

    { get offsets of elements }
    FDGNInputStream.Position := 0;
    While FDGNInputStream.Position < FDGNInputStream.Size Do
    begin
      p := FDGNInputStream.Position;

      FDGNInputStream.Read( Elm_hdr, SizeOf( Elm_Hdr ) );

      element_deleted := ( Elm_hdr.TypeDeleted And $80 ) = $80;
      element_Type := Elm_hdr.TypeDeleted And $7F;
      element_level := Elm_Hdr.LevelCmplx AND $3F;

      If Not element_deleted And // is deleted ?
         ( element_level in [0..63] ) And FIncludedLevels[element_level] And  // is in defined level ?
         ( element_Type In [3,4,6,11,15,16,17,21] ) Then  // only useful entities
      Begin
        { the offset }
        FOffsets.Add( p );
      end;

      FDGNInputStream.Position := p + ( 4 + Elm_Hdr.Words * SizeOf( Word ) );

    end;

    { get elements }
    Extents:= INVALID_EXTENSION;
    For I:= 0 to FOffsets.Count-1 do
    begin
      temp:= FMemoryLoaded;
      FMemoryLoaded:=false;
      TmpEntity:= GetElement( I, ele_type, ele_level, PlanOfEle, element_str, _3Dz ) ;
      FMemoryLoaded:=temp;
      If TmpEntity = Nil then
      begin
        BadList.Add( I );
        Continue;
      end;
      If FMemoryLoaded then
        FElements.Add( TmpEntity );
      CurExtents:= TmpEntity.FBox;
      MaxBound( Extents.Emax, CurExtents.Emax );
      MinBound( Extents.Emin, CurExtents.Emin );
    end;

    If FMemoryLoaded then
    begin
      FreeAndNil( FDGNInputStream );
      FOffsets.Clear;
      BadList.Clear;
    end Else
      For I:= BadList.Count-1 downto 0 do
      begin
        FOffsets.Delete( BadList[I] );
      end;

    Self.XMin:= Extents.Xmin;
    Self.YMin:= Extents.Ymin;
    Self.XMax:= Extents.Xmax;
    Self.YMax:= Extents.Ymax;
  Finally
    BadList.Free;
    Screen.Cursor:= OldCursor;
  end;
  FActive:= true;
end;

procedure TEzDGNFile.Close;
begin
  if not FActive then Exit;
  FOffsets.Clear;
  If Assigned( FDGNInputStream ) then
    FreeAndNil( FDGNInputStream );
  FElements.Clear;
  FActive:= False;
end;

Function TEzDGNFile.GetElement( n: Integer;
  Var element_type, element_level, PlanOfEle: Integer;
  Var element_str: string; Var _3Dz: Double ): TEzEntity ;
Var
  Elm_hdr: TElm_hdr; // Head
  Disp_hdr: TDisp_hdr; // Display Head
  p: Longint;
  si: Smallint;
  b: Byte;
  wrd: Word;
  l: Longint;
  byte8: Double;

  NextEleOfNode: integer;
  NodeLineSpc: Double;
  TextAlign: TAlignment;

  primary, secondary: Double;
  origin: TEzPoint;
  EllipRec: TEzRect;
  Startang, sweepang: double;

  lngthmult, hgntmult, rotation: double;
  RadRotation: Double;
  str: Array[0..255] Of Char;

  curPen: TEzPenStyle;
  curbrush: TEzBrushStyle;

  i: integer;
  P2D: TDGNPoint2D;
  P3D: TDGNPoint3D;

  Fp: TEzPoint;
  line1, line2: TEzPoint;
  align: byte;

  //MyDlg: TMifImportDlg;
  TextEntityHeight: Double;
  TextEntityPoint: TEzPoint;

  MinX: double;
  Miny: double;
  MaxX: double;
  Maxy: double;
  emin: TEzPoint;
  TheRecno: Integer;
  nSweepVal: Integer;
  tempInt: Integer;
  EntityCreated: Boolean;
  TmpClass: TEzEntityClass;
  TextWidth: Double;

  Function CompareBoundary( Const p: TEzPoint ): TEzPoint;
  Begin
    If p.x < minx Then
      minx := p.x;
    If p.y < miny Then
      miny := p.y;
    If p.x > maxx Then
      maxx := p.x;
    If p.y > maxy Then
      maxy := p.y;

    Result:= p;

    If Assigned( FOnConvertPoint ) then
      FOnConvertPoint( Self, Result );
  End;

  Function GetRect2DFromEllip( Const primary, secondary: double;
    Const origin: TEzPoint ): TEzRect;
  Var
    tmpRect: TEzRect;
  Begin
    tmpRect.Emin.X := origin.X - primary;
    tmpRect.Emax.X := origin.X + primary;
    tmpRect.Emin.Y := origin.Y - secondary;
    tmpRect.Emax.Y := origin.Y + secondary;

    Result := tmpRect;
  End;

Begin
  Result:= Nil;

  If FMemoryLoaded And ( n >= 0 ) And ( n <= FElements.Count - 1) then
  begin
    TmpClass := GetClassFromID( FElements[ n ].EntityID );
    Result := TmpClass.Create( 1 );
    Result.Assign( FElements[ n ] );
    Exit;
  end;

  // don't move from here
  If (FDGNInputStream = Nil) Or (FOffsets.Count = 0) Or (n < 0) or (n > FOffsets.Count - 1) then Exit;

  FDGNInputStream.Seek( FOffsets[n], soFromBeginning );

  FDGNInputStream.Read( Elm_hdr, SizeOf( Elm_Hdr ) );

  element_Type := Elm_hdr.TypeDeleted And $7F;
  element_level := Elm_Hdr.LevelCmplx AND $3F;

  { the element is supposed not to be deleted because it was already checked
    in Open method }

  element_str := '';
  PlanOfEle := 2;
  _3Dz := 0.0;

  MinX := 1E+10;
  Miny := 1E+10;
  MaxX := -1E+10;
  Maxy := -1E+10;

  EntityCreated:= False;

  Result := Nil;
  Case element_Type Of
    3: { Line }
      Begin
        FDGNInputStream.Read( Disp_hdr, SizeOf( Disp_Hdr ) );
        EvaluateDisp_Hdr( Disp_Hdr, curPen, curbrush );
        If ( Disp_Hdr.props And $2000 ) = 0 Then
          PlanOfEle := 2
        Else
          PlanOfEle := 3;

        If FDGN_TCB.Dimension = 2 Then
        Begin
          FDGNInputStream.Read( P2D, SizeOf( P2D ) );
          line1.X := LSwap( p2d.X );
          line1.Y := LSwap( p2d.Y );
          line1.X := line1.X * FScale;
          line1.Y := line1.Y * FScale;
          FDGNInputStream.Read( P2D, SizeOf( P2D ) );
          line2.X := LSwap( p2d.X );
          line2.Y := LSwap( p2d.Y );
          line2.X := line2.X * FScale;
          line2.Y := line2.Y * FScale;
        End Else If FDGN_TCB.Dimension = 3 Then
        Begin
          FDGNInputStream.Read( P3D, SizeOf( P3D ) );
          line1.X := LSwap( p3d.X );
          line1.Y := LSwap( p3d.Y );
          line1.X := line1.X * FScale;
          line1.Y := line1.Y * FScale;
          FDGNInputStream.Read( P3D, SizeOf( P3D ) );
          line2.X := LSwap( p3d.X );
          line2.Y := LSwap( p3d.Y );
          line2.X := line2.X * FScale;
          line2.Y := line2.Y * FScale;
        End
        Else
          Exit;

        If ( ( line1.X = line2.X ) And ( line1.Y = line2.Y ) ) Then
        Begin
          element_str := 'Line(Equal Start and End)';
          line1 := CompareBoundary( line1 );
          Result := TEzPointEntity.CreateEntity( line1, curpen.Color );
          EntityCreated := True;
          //cursymbol := Ez_Preferences.DefSymbolStyle.FSymbolStyle;
          //TEzPointEntity( Result ).Color := curpen.Color;
        End
        Else
        Begin
          // line
          element_str := 'Line';
          line1 := CompareBoundary( line1 );
          line2 := CompareBoundary( line2 );
          Result := TEzPolyLine.CreateEntity( [line1, line2] );
          EntityCreated := True;
        End;
      End; { end of case 3 }

    4, 6, 11, 21: { Line string, Shape, Curve, B-spline Pole Element }
      Begin
        FDGNInputStream.Read( Disp_hdr, SizeOf( Disp_Hdr ) );
        EvaluateDisp_Hdr( Disp_Hdr, curPen, curbrush );
        If ( Disp_Hdr.props And $2000 ) = 0 Then {Check for Planar, 乞搁牢啊? 0 = 乞搁, 1 = 厚乞搁 }
          PlanOfEle := 2
        Else
          PlanOfEle := 3;

        FDGNInputStream.Read( si, SizeOf( si ) );

        Case element_Type Of
          4:
            Begin
              element_str := 'Line String';
              Result := TEzPolyLine.Create( si );
              EntityCreated := True;
            End;
          6:
            Begin
              element_str := 'Shape';
              Result := TEzPolygon.Create( si );
              EntityCreated := True;
            End;
          11:
            Begin
              element_str := 'Curve';
              // Result := TSpline2D.Create(si);
              Result := TEzPolyLine.Create( si );
              EntityCreated := True;
            End;
          21:
            Begin
              element_str := 'B-spline Pole';
              Result := TEzSpline.Create( si );
              EntityCreated := True;
            End;

        End;

        For i := 1 To si Do {Number of vertices}
        Begin
          If FDGN_TCB.Dimension = 2 Then
          Begin
            FDGNInputStream.Read( p2d, SizeOf( p2d ) );
            Fp.X := LSwap( P2D.X );
            Fp.Y := LSwap( P2D.Y );
          End
          Else If FDGN_TCB.Dimension = 3 Then
          Begin
            FDGNInputStream.Read( p3d, SizeOf( p3d ) );
            Fp.X := LSwap( P3D.X );
            Fp.Y := LSwap( P3D.Y );
          End
          Else
            Exit;

          Fp.X := Fp.X * FScale;
          Fp.Y := Fp.Y * FScale;

          If element_Type = 11 Then
          Begin
            If (i=1) Or (i=2) Or (i=si-1) Or (i=si) Then
              Continue;
          End;

          Fp := Compareboundary( Fp );
          Result.Points.Add( Fp );
        End; { end of for i }
      End; { end of case 4, 6, 11, 21 }

    7: //Text Node Header,  Ignoring causes no harm
      Begin
        FDGNInputStream.Read( Disp_hdr, SizeOf( Disp_Hdr ) );
        EvaluateDisp_Hdr( Disp_Hdr, curPen, curbrush );
        If ( Disp_Hdr.props And $2000 ) = 0 Then //Check for Planar, 乞搁牢啊? 0 = 乞搁, 1 = 厚乞搁
          PlanOfEle := 2
        Else
          PlanOfEle := 3;

        //
        FDGNInputStream.Read( wrd, SizeOf( wrd ) );
        NextEleOfNode := p + SizeOf( Elm_hdr ) + SizeOf( Disp_hdr ) + 1 + ( wrd * SizeOf( Word ) );

        FDGNInputStream.Read( wrd, SizeOf( wrd ) );

        FDGNInputStream.Read( wrd, SizeOf( wrd ) );

        FDGNInputStream.Read( b, SizeOf( b ) );

        FDGNInputStream.Read( b, SizeOf( b ) );

        FDGNInputStream.Read( b, SizeOf( b ) );

        FDGNInputStream.Read( b, SizeOf( b ) );

        FDGNInputStream.Read( l, SizeOf( l ) );
        NodeLineSpc := lswap( l ) * FScale;

        {
                      FDGNInputStream.Read(l, SizeOf(l));
                      lngthmult := abs(LSwap(l) * FScale);

                      FDGNInputStream.Read(l, SizeOf(l));
                      hgntmult := abs(LSwap(l) * FScale);

                      FDGNInputStream.Read(l, SizeOf(l)) <> SizeOf(l);
                      rotation := DegToRad(LSwap(l) / 360000);

                      FDGNInputStream.Read(p2d, SizeOf(p2d));
                      Fp.X := LSwap(P2D.X);
                      Fp.Y := LSwap(P2D.Y);
                      Fp.X := Fp.X * FScale;
                      Fp.Y := Fp.Y * FScale;

                      TextEntityHeight := hgntmult * HeightQuotient;

                      TextEntityPoint.X := Fp.X;
                      TextEntityPoint.Y := Fp.Y + TextEntityHeight;

                      TextEntityPoint:=Compareboundary(TextEntityPoint);

                      Result := TText2D.CreateEntity(nil, TextEntityPoint, str, TextEntityHeight, rotation);
                      TText2d(Result).FontColor := curpen.Color;
        //                  EntityCreated := True;
                    }
      End; // end of case 7

    17:
      Begin
        element_str := 'Text';
        rotation := 0;
        FDGNInputStream.Read( Disp_hdr, SizeOf( Disp_Hdr ) );
        EvaluateDisp_Hdr( Disp_Hdr, curPen, curbrush );
        If ( Disp_Hdr.props And $2000 ) = 0 Then { Check for Planar }
          PlanOfEle := 2
        Else
          PlanOfEle := 3;

        {  }
        FDGNInputStream.Read( b, SizeOf( b ) );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -