📄 ezflashfilergis.pas
字号:
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 + -