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

📄 ezflashfilergis.pas

📁 很管用的GIS控件
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    finally
      TempTable.Free;
    end;
    if IsCachedSpatialIndex then FCachedRT := FRT else FRT.Free;

    FRT := TEzFlashFilerRTree.Create(Self, RTYPE, 66);    // 66=read/write mode open
    FRT.Open(Name, 66);

    WriteHeaders(True);
  End Else
    LocalLayer.RebuildTree;
end;

procedure TEzFlashFilerLayer.Open;
var
  Gis: TEzFlashFilerGis;
  Mode: Word;
  Temp: Boolean;
begin
  If Not FClientHasAllData Then
  Begin
    Close;
    if ((FFlashFilerHeader = nil) or
       not (FFlashFilerHeader.FieldByName('Visible').AsBoolean)) and (FRT <> nil) then
      FRT.Close;

    Gis := Layers.Gis as TEzFlashFilerGIS;
    Mode := Gis.OpenMode;

    if FFlashFilerHeader = nil then
    begin
      FFlashFilerHeader:= GIS.CreateFlashFilerTable;
      FFlashFilerHeader.TableName := 'LAY_' + Name;
    end;

    if FFlashFilerEntities = nil then
    begin
      FFlashFilerEntities:= GIS.CreateFlashFilerTable;
      FFlashFilerEntities.TableName := 'ENT_' + Name;
    end;

    // Check for minimum layer tables needed
{$IFDEF FALSE}
    if (not Gis.TableExists('LAY_' + Name)) or
       (not Gis.TableExists('ENT_' + Name)) then
       EzGisError('Tables for this layer missing!');
{$ENDIF}

    try
      FFlashFilerHeader.Open;
      //FFlashFilerHeader.IndexName := 'ixPrimary';
      FFlashFilerEntities.Open;
      FFlashFilerEntities.IndexName := 'ixPrimary';
    except
      MessageToUser( 'Tables for this layer missing!', smsgerror, MB_ICONERROR );
      FFlashFilerHeader.Close;
      FFlashFilerEntities.Close;
      raise;
    end;

    if Gis.MapInfo.CoordsUnits = cuDeg then
      CoordMultiplier := DEG_MULTIPLIER
    else
      CoordMultiplier := 1;
    // Open the R-Tree
    Temp:= True;
    FRT := Nil;
    try
      FRT := TEzFlashFilerRTree.Create(Self, RTYPE, Mode);
      FRT.Open(Name, Mode);
    except
      If FRT <> Nil then
        FreeAndNil(FRT);
      Temp:=False;
    end;
    if not Temp then
    begin
      RebuildTree;
      FRT := TEzFlashFilerRTree.Create(Self, RTYPE, Mode);
      FRT.Open(Name, Mode);
    end;
    if IsCachedSpatialIndex then
      BuildRTreeInMemory(FCachedRT);

    FIsOpen := True;
  End Else
    LocalLayer.Open;
end;

procedure TEzFlashFilerLayer.Close;
begin
  If Not FClientHasAllData Then
  Begin
    if FFlashFilerHeader <> nil then FreeAndNil(FFlashFilerHeader);
    if FFlashFilerEntities <> nil then FreeAndNil(FFlashFilerEntities);
    if FRT <> nil then FreeAndNil(FRT);
    if FCachedRT <> nil then FreeAndNil(FCachedRT);
    Modified := False;
    FIsOpen := False;
  End Else
    LocalLayer.Close;
end;

procedure TEzFlashFilerLayer.ForceOpened;
begin
  If Not FClientHasAllData Then
  Begin
    if not FIsOpen then Open;
  End Else
    LocalLayer.ForceOpened;
end;

procedure TEzFlashFilerLayer.WriteHeaders(FlushFiles: Boolean);
begin
  If Not FClientHasAllData Then
  Begin
    Modified := False;
  End Else
    LocalLayer.Writeheaders(FlushFiles);
end;

procedure TEzFlashFilerLayer.UpdateMapExtension(const R: TEzRect);
var
  MapExt: TEzRect;
begin
  // New map 閤tension
  if (Layers = nil) or (Layers.Gis = nil) then Exit;
  with Layers.Gis do
  begin
    MapExt := MapInfo.Extension;
    MaxBound(MapExt.Emax, R.Emax);
    MinBound(MapExt.Emin, R.Emin);
    MapInfo.Extension := MapExt;
    Modified := True;
  end;
end;

// This function will return the UID of the added entity

function TEzFlashFilerLayer.AddEntity(Entity: TEzEntity): Integer;
var
  Extents, LayExtents: TEzRect;
  TmpID: TEzEntityID;
  NewRecno: Integer;
  Stream: TMemoryStream;
  Gis: TEzFlashFilerGis;
begin
  Result := 0;
  ForceOpened;
  if Layers.Gis.ReadOnly or not FIsOpen then Exit;

  NormalizePolygon(Entity);

  TmpID := Entity.EntityID;

  Gis := Layers.Gis as TEzFlashFilerGIS;

  If GIS Is TEzFlashFilerGIS then
    with TEzFlashFilerGIS(GIS) do
      if WithTransactions then
        FFlashFilerDatabase.StartTransaction;
  try
    Extents := Entity.FBox;
    with FFlashFilerEntities do
    begin
      try
        Insert;
        FieldByName('Xmin').AsFloat := Extents.X1;
        FieldByName('Ymin').AsFloat := Extents.Y1;
        FieldByName('Xmax').AsFloat := Extents.X2;
        FieldByName('Ymax').AsFloat := Extents.Y2;
        FieldByName('ShapeType').AsInteger := Ord(TmpID);
        Stream := TMemoryStream.Create;
        try
          Entity.SaveToStream(Stream);
          {$IFDEF COMPRESSED_ENTITY}
          CompressMemStream(Stream, 1);
          {$ENDIF}
          Stream.Position := 0;
          (FieldByName('Geometry') as TBlobField).LoadFromStream(Stream);
        finally
          Stream.Free;
        end;
        Post;
        NewRecno := FieldByName('UID').AsInteger;
      except
        if State = dsInsert then
          Cancel;
        raise;
      end;
    end;
    // Add to the R-Tree
    Result := NewRecno;
    if not FBatchUpdate then
    begin
      // Calculate the extension for the header
      with FFlashFilerHeader do
      begin
        with LayExtents do
        begin
          x1 := FieldByName('Extension_X1').AsFloat;
          y1 := FieldByName('Extension_Y1').AsFloat;
          x2 := FieldByName('Extension_X2').AsFloat;
          y2 := FieldByName('Extension_Y2').AsFloat;
        end;
        MaxBound(LayExtents.Emax, Extents.Emax);
        MinBound(LayExtents.Emin, Extents.Emin);
        with LayExtents do
        begin
          try
            Edit;
            FieldByName('Extension_X1').AsFloat := x1;
            FieldByName('Extension_Y1').AsFloat := y1;
            FieldByName('Extension_X2').AsFloat := x2;
            FieldByName('Extension_Y2').AsFloat := y2;
            Post;
          except
            if State = dsEdit then
              Cancel;
            raise;
          end;
        end;
      end;
      if TmpID <> idNone then
      begin
        FRT.Insert(FloatRect2Rect(Extents), NewRecno);
        if IsCachedSpatialIndex then
          FCachedRT.Insert(FloatRect2Rect(Extents), NewRecno);
      end;
    end;
    UpdateMapExtension(Extents);
    If GIS Is TEzFlashFilerGIS then
      with TEzFlashFilerGIS(GIS) do
        if WithTransactions then
          FFlashFilerDatabase.Commit;
  except
    If GIS Is TEzFlashFilerGIS then
      with TEzFlashFilerGIS(GIS) do
        if WithTransactions then
          FFlashFilerDatabase.Rollback;
    raise;
  end;

  { ahora agregaselo a la capa local }
  If LocalLayer<>Nil Then
    LocalLayer.AddEntity( Entity );
end;

procedure TEzFlashFilerLayer.UndeleteEntity(RecNo: Integer);
var
  ShapeType: TEzEntityID;
  Extents: TEzRect;
begin
  SetRecNo(RecNo);
  // Check if it is deleted
  with FFlashFilerEntities do
  begin
    if not FieldByName('Deleted').AsBoolean then Exit;
    ShapeType := TEzEntityID(FieldByName('ShapeType').AsInteger);
    Extents.Emin.X := FieldByName('Xmin').AsFloat;
    Extents.Emin.Y := FieldByName('Ymin').AsFloat;
    Extents.Emax.X := FieldByName('Xmax').AsFloat;
    Extents.Emax.Y := FieldByName('Ymax').AsFloat;
    try
      Edit;
      FieldByName('Deleted').AsBoolean := False;
      Post;
    except
      if State = dsEdit then
        Cancel;
      raise;
    end;
  end;
  // Now update the R-Tree
  if ShapeType <> idNone then
  begin
    FRT.Insert(FloatRect2Rect(Extents), RecNo);
    if TEzFlashFilerGis(Layers.Gis).FCachedSpatialIndex then
      FCachedRT.Insert(FloatRect2Rect(Extents), RecNo);
  end;

  { actualiza la capa local }
  If LocalLayer<>Nil Then
    LocalLayer.UndeleteEntity( Recno );

end;

procedure TEzFlashFilerLayer.DeleteEntity(RecNo: Integer);
var
  Extents: TEzRect;
begin
  if Layers.Gis.ReadOnly or not FIsOpen then Exit;
  // Retrieve the record extension for R-Tree update
  SetRecNo(RecNo);
  with FFlashFilerEntities do
  begin
    Extents.X1 := FieldByName('Xmin').AsFloat;
    Extents.Y1 := FieldByName('Ymin').AsFloat;
    Extents.X2 := FieldByName('Xmax').AsFloat;
    Extents.Y2 := FieldByName('Ymax').AsFloat;
    // Now Delete the record
    try
      Edit;
      FieldByName('Deleted').AsBoolean := True;
      Post;
    except
      if State = dsEdit then
        Cancel;
      raise;
    end;
  end;
  // Delete from R-Tree
  if not EqualRect2D(Extents, INVALID_EXTENSION) then
  begin
    FRT.Delete(FloatRect2Rect(Extents), RecNo);
    if TEzFlashFilerGis(Layers.Gis).FCachedSpatialIndex then
      FCachedRT.Delete(FloatRect2Rect(Extents), RecNo);
  end;

  { actualiza la capa local }
  If LocalLayer<>Nil Then
    LocalLayer.DeleteEntity( Recno );

end;

function TEzFlashFilerLayer.InternalLoadEntity: TEzEntity;
var
  TmpClass: TEzEntityClass;
  Stream: TMemoryStream;
begin
  TmpClass := GetClassFromID(TEzEntityID(FFlashFilerEntities.FieldByName('ShapeType').AsInteger));
  Result := TmpClass.Create(1);
  Stream := TMemoryStream.Create;
  try
    (FFlashFilerEntities.FieldByName('Geometry') as TBlobField).SaveToStream(Stream);
    {$IFDEF COMPRESSED_ENTITY}
    DeCompressMemStream(Stream);
    {$ENDIF}
    Stream.Position := 0;
    Result.LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

function TEzFlashFilerLayer.QuickUpdateExtension: TEzRect;
var
  Gis: TEzFlashFilerGis;
  Extents: TEzRect;
begin
  If Not FClientHasAllData Then
  Begin
    Gis := Layers.Gis as TEzFlashFilerGis;
    if Gis.ReadOnly then Exit;
    ForceOpened;
    Result := INVALID_EXTENSION;
    CancelFilter;   // Ensure no filter
    with Gis.CreateFlashFilerQuery do
      try
        Close;
        Sql.Text :=
          Format('SELECT MIN(Xmin),MIN(Ymin),MAX(Xmax),MAX(Ymax) FROM ent_%S', [Self.Name]);
        Open;
        Extents.X1 := Fields[0].AsFloat;
        Extents.Y1 := Fields[1].AsFloat;
        Extents.X2 := Fields[2].AsFloat;
        Extents.Y2 := Fields[3].AsFloat;
        Close;
      finally
        Free;
      end;
    with FFlashFilerHeader do
    begin
      try
        Edit;
        FieldByName('Extension_X1').AsFloat := Extents.X1;
        FieldByName('Extension_Y1').AsFloat := Extents.Y1;
        FieldByName('Extension_X2').AsFloat := Extents.X2;
        FieldByName('Extension_Y2').AsFloat := Extents.Y2;
        Post;
      except
        if State = dsEdit then
          Cancel;
        raise;
      end;
    end;
    Modified := True;
  End Else
    Result:= LocalLayer.QuickUpdateExtension;
end;

function TEzFlashFilerLayer.UpdateExtension: TEzRect;
const
  RecordsPerTransaction = 100;
var
  Entity: TEzEntity;
  Gis: TEzFlashFilerGis;
  Extents: TEzRect;
  RecordsPosted: Integer;
begin
  If Not FClientHasAllData Then
  Begin
    Gis := Layers.Gis as TEzFlashFilerGIS;
    if Gis.ReadOnly then Exit;

    ForceOpened;
    Result := INVALID_EXTENSION;
    try
      with FFlashFilerEntities do
      begin
        First;
        try
          // The transaction handling is only there to speed things up at the server
          RecordsPosted := 0;
          If Gis Is TEzFlashFilerGIS then
            TEzFlashFilerGIS(Gis).FlashFilerDatabase.StartTransactionWith([FFlashFilerEntities]);
          while not Eof do
          begin
            Entity := InternalLoadEntity;
            try
              Extents := Entity.FBox;
              Edit;
              FieldByName('Xmin').A

⌨️ 快捷键说明

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