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

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 голосов
ответил 07 Июнь, 10 от pooperec (10,820 баллов)
Зайти в описание метода PartialRefresh и внимательно прочитать.

1. Вторым параметром передавать слой где живет точка.
2. Заставлять перерисовывать только область ограниченную старым и новым положением. (для этого можно вызывать дважды).
0 голосов
ответил 07 Июнь, 10 от DevProSoftware (1,040 баллов)
Вы правы, надо было почитать сначала про PartialRefresh.

Map:

Refresh layer          pActiveView.PartialRefresh esriViewGeography, pLayer, Nothing 
Refresh all layers     pActiveView.PartialRefresh esriViewGeography, Nothing, Nothing
Refresh selection      pActiveView.PartialRefresh esriViewGeoSelection, Nothing, Nothing
Refresh labels         pActiveView.PartialRefresh esriViewGraphics, Nothing, Nothing

PageLayout:

Refresh element        pActiveView.PartialRefresh esriViewGraphics, pElement, Nothing
Refresh all elements   pActiveView.PartialRefresh esriViewGraphics, Nothing, Nothing
Refresh selection      pActiveView.PartialRefresh esriViewGraphicSelection, Nothing, Nothing
Почитал, делаю как в описании:
MapControl.ActiveView.PartialRefresh(esriViewGeography,MapControl.Layer[0],nil);
всё-равно перерисовываются все слои
Я так понял, что надо ещё выполнить Ваш пункт 2, но как это сделать, не понял, а в описании этого нет
0 голосов
ответил 07 Июнь, 10 от pooperec (10,820 баллов)
Предположим, что:
1. У вас есть старая точка с координатами 10 11 (pPoint1)
2. и новая с координатами 20 21 (pPoint2)
3. Все точки в слое pFeatureLayer (в примере все точки это отдельные геометрии)

Тогда код для плавной смены может выглядеть так:
{Первый вариант}
...
var
pEnv : IEnvelope;

Begin
pEnv:= pFeature.Envelope;
pEnv.Expand(5,5,false); //Искусственно увеличиваем размер области обновления, для того чтобы правильно перерисовать символ
MapControl.ActiveView.PartialRefresh(esriViewGeography,pPoint1,pEnv);

pEnv:= pPoint2.Envelope;
pEnv.Expand(5,5,false); //Искусственно увеличиваем размер области обновления, для того чтобы правильно перерисовать символ
MapControl.ActiveView.PartialRefresh(esriViewGeography,pPoint2,pEnv);
End;

{А вот тут все точки и в правду хранятся в pFeatureLayer}

var
pEnv : IEnvelope;

Begin
pEnv:= pFeature.Extent;
pEnv.Expand(5,5,false); //Искусственно увеличиваем размер области обновления, для того чтобы правильно перерисовать символ
MapControl.ActiveView.PartialRefresh(esriViewGeography,pFeatureLayer,pEnv);

pEnv:= pFeature.Extent;
pEnv.Expand(5,5,false); //Искусственно увеличиваем размер области обновления, для того чтобы правильно перерисовать символ
MapControl.ActiveView.PartialRefresh(esriViewGeography,pFeatureLayer,pEnv);
End;
0 голосов
ответил 08 Июнь, 10 от DevProSoftware (1,040 баллов)
1. Спасибо, у меня получилось плавно перерисовывать точку только при условии, когда я в ArcMAP для карты в окне Data Frame Properties в закладке MapCache в Auto-Chache отмечаю галочкой поле Automatically build cache when current map extent changes.
Однако, метки (label) как у перемещаемой точки, так и у точек, которые находятся в другом слое при перемещении всё-равно перерисовываются. Это можно как-то побороть?

2. И, если, можно, параллельно ещё вопрос: если нужно нарисовать в одном и том же слое две точки разного цвета, это возможно (если возможно, намекните, пожалуйста как)? Или каждую точку нужно рисовать в отдельном слое?

0 голосов
ответил 08 Июнь, 10 от pooperec (10,820 баллов)
1. Для достижения более плавного эффекта, Вам необходимо реализовывать событие Draw, IActiveViewEvents, и рисовать там на этапе отрисовки переднего плана.

2. Конечно можно, либо вручную (если у Вас конечное количество объектов и они динамически меняются), либо по полю если количество не ограничено.
0 голосов
ответил 08 Июнь, 10 от TDenis (42,620 баллов)
Если вдруг планируете переходить на 10-ку, то можно будет воспользоваться специальной штуковиной - IGraphicTracker.
http://help.arcgis.com/en/sdk/10.0/ArcObjects_NET/ConceptualHelp/index.html#//0001000009z7000000
http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//0001000004tv000000
0 голосов
ответил 08 Июнь, 10 от pooperec (10,820 баллов)
TDenis
Вы уже работаете с пре-релиз SDKшкой?
0 голосов
ответил 08 Июнь, 10 от TDenis (42,620 баллов)
Не, я просто видео с девсаммита 2010 смотрю, когда совсем скучно становится :)
http://proceedings.esri.com/library/userconf/devsummit10/tech.html

Мне лень и не к спеху :) Это ж надо звонить дистрибьютору, просить/умолять чтоб прислали бетку. Да ещё и багов там пока богато, на девсаммите падало не раз. Зарелизят - поставим.
0 голосов
ответил 08 Июнь, 10 от DevProSoftware (1,040 баллов)
1. Для достижения более плавного эффекта, Вам необходимо реализовывать событие Draw, IActiveViewEvents, и рисовать там на этапе отрисовки переднего плана.

2. Конечно можно, либо вручную (если у Вас конечное количество объектов и они динамически меняются), либо по полю если количество не ограничено.

Ярослав, спасибо, правда до конца не понял как это сделать, можете, если не затруднит, прислать ссылки на какие-то примеры по 1 и 2 случаям. Искал на русских и английских форумах, не могу ничего токового найти.
0 голосов
ответил 08 Июнь, 10 от pooperec (10,820 баллов)
Блин, я ж писал уже тысячу раз.
Вы это читали (1 ссылка)
http://tinyurl.com/383npzk
???
Добро пожаловать на сайт Вопросов и Ответов, где вы можете задавать вопросы по GIS тематике и получать ответы от других членов сообщества.
...