Как плавно менять координаты точки на карте?

0 голосов
спросил 07 Июнь, 10 от DevProSoftware (1,040 баллов) в категории Программные продукты Esri
Господа, наставьте, пожалуйста на путь истинный.
Нарисовал точку в точечном слое карты:

  pLayer := MapControl.Layer[0];

  pFeatLayer := pLayer as IFeatureLayer;
  pFeatClass := pFeatLayer.FeatureClass;

  pPoint := CoPoint.Create as IPoint;
  pPoint.X := 20;
  pPoint.Y := 20;

  pGeometry := pPoint as IGeometry;
  pFeature := pFeatClass.CreateFeature;

  pFeature.Shape := pGeometry;

  pFeature.Value[pFeatClass.FindField('Name')] := 'Точка';
  pFeature.Value[pFeatClass.FindField('POPULATION')] := '100';
  pFeature.Value[pFeatClass.FindField('CONTINENT')] := 'Asia';

  pFeature.Store;

  MapControl.ActiveView.PartialRefresh(esriViewGeography,nil,nil);

Мне нужно динамически менять координаты точки. Я делаю это в событиях компонентов TSpinEdit:
procedure TForm.SpinEditXChange(Sender: TObject);
begin
  pPoint.X := SpinEditX.Value;
  pFeature.Store;
  MapControl.ActiveView.PartialRefresh(esriViewGeography,nil,nil);
end;
procedure TForm.SpinEditYChange(Sender: TObject);
begin
  pPoint.Y := SpinEditY.Value;
  pFeature.Store;
  MapControl.ActiveView.PartialRefresh(esriViewGeography,nil,nil);
end;
Точка меняет свои координаты нормально, но при вызове PartialRefresh перерисовывается вся карта, что очень некрасиво, а если не вызывать PartialRefresh, то точка на карте не перерисовывается.
Как можно плавно перерисовывать точку?

29 Ответы

0 голосов
ответил 10 Июнь, 10 от DevProSoftware (1,040 баллов)
Сделал всё в точности, как Вы сказали. В результате изначально точка рисуется правильно по заданным координатам, маркер в совершенно другом месте (хотя у маркера XOffset и YOffset = 0). При изменении координат точка и маркер не двигаются, только маркер моргает на месте.
0 голосов
ответил 10 Июнь, 10 от pooperec (10,820 баллов)
Код задания координат точки ффстудию!
0 голосов
ответил 10 Июнь, 10 от DevProSoftware (1,040 баллов)
Изначально задаю как:
pPoint.X := 20;
pPoint.Y := 20;
А потом меняю по значениям из TSpinEdit (я присылал код в самом начале этой ветки форума)
И ещё я так уразумел, что точку и маркер вероятно надо как-то связать, только как?
0 голосов
ответил 10 Июнь, 10 от pooperec (10,820 баллов)
Разнесите pFeature.Store и методы спин эдита... так можно любую БД за...мучать запросами.

Меняйте координаты точки, и её же выводите...

Пример:
procedure TForm.SpinEditYChange(Sender: TObject);
begin
pPoint.Y := SpinEditY.Value;
MapControl.ActiveView.PartialRefresh(32,pPoint,nil);
end;

"Х" также...
0 голосов
ответил 11 Июнь, 10 от DevProSoftware (1,040 баллов)
Ничего при этом не изменилось
0 голосов
ответил 11 Июнь, 10 от pooperec (10,820 баллов)
И это печально... Ладно, короче вот Вам рабочий код:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, esriCarto_TLB, esriGeometry_TLB, esriDisplay_TLB, esriSystem_TLB,
StdCtrls, ComObj, Spin, esriControls_TLB, OleCtrls;

type
TForm1 = class(TForm, IActiveViewEvents)
    MapControl1: TMapControl;
    LicenseControl1: TLicenseControl;
    procedure FormShow(Sender: TObject);
    procedure MapControl1MouseMove(ASender: TObject; button, shift, X,
      Y: Integer; mapX, mapY: Double);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    protected
        procedure ContentsChanged; safecall;
    procedure ContentsCleared; safecall;
    procedure ItemAdded(Item: OleVariant); safecall;
    procedure ItemDeleted(Item: OleVariant); safecall;
    procedure ItemReordered(Item: OleVariant; toIndex: Integer); safecall;
    procedure SelectionChanged; safecall;
    procedure ViewRefreshed(const view: IActiveView; phase: esriViewDrawPhase; Data: OleVariant;
                            const envelope: IEnvelope); safecall;
    procedure AfterDraw(const Display: IDisplay; phase: esriViewDrawPhase); safecall;
    procedure AfterItemDraw(Index: Smallint; const Display: IDisplay; phase: esriDrawPhase); safecall;
    procedure FocusMapChanged; safecall;
    procedure SpatialReferenceChanged; safecall;
private
   pAVe : IInterface;
   pHWND : integer;
   pPoint : IPoint;
   pMarkerSymbol : IMarkerSymbol;
    { Private declarations }
public
    { Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.AfterDraw(const Display: IDisplay; phase: esriViewDrawPhase);
begin
    if phase<>32 then exit; //нам нужно только отрисовка "передника"
    try
    if (ppoint<>nil) then Begin
        if pMarkerSymbol<>nil then
             Display.SetSymbol(pMarkerSymbol as ISymbol);
        Display.Drawpoint(pPoint);
    End;
    except on E: Exception do Begin
       {$I-}
          ShowMessage('E_PREF'+'{569FBF7F-A686-491B-A4F6-A4F86CCFE807} '+E.Message);
       {$I+}
    End;
    end;
end;

procedure TForm1.AfterItemDraw(Index: Smallint; const Display: IDisplay;
phase: esriDrawPhase);
begin

end;

procedure TForm1.ContentsChanged;
begin

end;

procedure TForm1.ContentsCleared;
begin

end;

procedure TForm1.FocusMapChanged;
begin

end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
InterfaceDisconnect(pAVE,IActiveViewEvents,pHWND);
pAVe := nil;
end;

procedure TForm1.FormShow(Sender: TObject);
var
pColor : IRGBColor;
begin
pPOint:= CoPOint.Create as IPoint;
pMarkerSymbol := CoSimpleMarkerSymbol.Create as IMarkerSymbol;
pColor := CoRGBColor.Create as IRgbColor;
pColor.RGB := RGB(255,0,0);
pMarkerSymbol.Color := pColor as IColor;
pMarkerSymbol.Size :=8;
pAVe := MapControl1.ActiveView as IInterface;
InterfaceConnect(pAVE,IActiveViewEvents,(self as IActiveViewEvents),pHWND);
end;

procedure TForm1.ItemAdded(Item: OleVariant);
begin

end;

procedure TForm1.ItemDeleted(Item: OleVariant);
begin

end;

procedure TForm1.ItemReordered(Item: OleVariant; toIndex: Integer);
begin

end;

procedure TForm1.MapControl1MouseMove(ASender: TObject; button, shift, X,
Y: Integer; mapX, mapY: Double);
begin
if button=1 then Begin
   pPoint.PutCoords(mapX,mapY);
   MapControl1.ActiveView.PartialRefresh(32,pPoint,nil);
End;
end;

procedure TForm1.SelectionChanged;
begin

end;

procedure TForm1.SpatialReferenceChanged;
begin

end;

procedure TForm1.ViewRefreshed(const view: IActiveView;
phase: esriViewDrawPhase; Data: OleVariant; const envelope: IEnvelope);
begin

end;

end.
0 голосов
ответил 11 Июнь, 10 от pooperec (10,820 баллов)
Вот полный комплект, если уж совсем туго:
http://rapidshare.com/files/397720982/__________.rar.html
MD5: 5DD485DB7E334B98B67F470C547FFAE0
0 голосов
ответил 11 Июнь, 10 от DevProSoftware (1,040 баллов)
Вы просто монстер в программировании ArcGIS, да и в Delphi, наверное, вообще. Я уже более 10 программирую, но такой жжж как программирование в ArcGIS, не встречал, настолько всё запутано, непонятно и непредсказуемо и документации толковой даже на англ.  нет, в общем полній алес. Спасибо Вам !!!!!!!!!
0 голосов
ответил 11 Июнь, 10 от pooperec (10,820 баллов)
1. Незачто
2. По поводу документации - ну это конечно не MSDN, но EDN тоже неплохой ресурс, другой вопрос, что понимание как этой документацией пользоваться приходит со временем.
Документация по Вашему случаю, например, довольно полная.
3. Основная проблема в том что для Delphi необходимо самому изобретать велосипеды для комфортной работы с СОМ, и с ArcObjects в частности.
Добро пожаловать на сайт Вопросов и Ответов, где вы можете задавать вопросы по GIS тематике и получать ответы от других членов сообщества.
...