ArcEngine -- 窗口缩放到几何图形并闪烁

缩放到要素以及闪烁形状是非常常规的操作,用处很广泛。单一的来看这两个通常都不会有什么问题,但是当将他们放在一起时,稍不注意就会达不到目的。

其实比较容易引起的问题就是:尽管缩放到要素的代码放在闪烁代码的前面,也刷新了视图,但是执行的时候,却是先闪烁,再缩放。执行顺序不对其实是牵涉到一个非常关键的要点。

要点:IActiveView.Refresh()并不会立刻启动 redraw 方法来重新绘制窗口,要想立刻绘制,需要显式调用ScreenDIsplay.UpdateWindow()方法。

这个要点同样适用于其他需要刷新后立刻执行屏幕操作的地方。

下面分别来讲实现。

移动缩放

public static void ZoomToGeometry(IGeometry geometry, IActiveView activeView)
{
IEnvelope env = geometry.Envelope;
IGeometry5 geo = geometry as IGeometry5;

    if (env.Width == 0 || env.Height == 0)
    {
        IPoint centerPoint = new PointClass();
        centerPoint.X = geo.CentroidEx.X;
        centerPoint.Y = geo.CentroidEx.Y;

        //IDisplayTransformation displayTrans = activeView.ScreenDisplay.DisplayTransformation;
        //displayTrans.SpatialReference = activeView.FocusMap.SpatialReference;

        env.XMin = centerPoint.X - 0.001;
        env.XMax = centerPoint.X + 0.001;
        env.YMin = centerPoint.Y - 0.001;
        env.YMax = centerPoint.Y + 0.001;

        env.CenterAt(centerPoint);
    }
    env.Expand(0.5, 0.5, true);
    activeView.Extent = env;
    activeView.Refresh();
    activeView.ScreenDisplay.UpdateWindow(); 
}

闪烁形状

闪烁主要有三种方式:

第一种方式使用IMapControlDefault接口的FlashShape方法,非常直观,但是仅能在ArcEngine环境下才行,做Arcgis的Addin开发由于获取不到IMapControlDefault对象,不能使用此方式;
第二种是在当前地图展示窗口绘制临时的形状,这种方式的优点是闪烁的形状不一定是要素,也可以是某个不存在的点或者多边形,只要有坐标就可以;
第三种方式是采用识别要素的方式,这种方式代码实现比较直观,调用Arcgis本身的接口实现闪烁,但采用这种方式的话,要求闪烁的图形必须是存在的几何要素(Feature)。

直接调用FlashShape方法

在ArcEngine开发环境中,获取到IMapControlDefault对象,直接调用FlashShape方法就可以了,这种方法比较直观

IMapControlDefault.FlashShape(IGeometry geometry);

绘制图形的方式

其实这个代码在Arcgis的Code Snippets里面是有的,直接粘贴过来。

public static void FlashGeometry(IGeometry geometry, IRgbColor color, IDisplay display, System.Int32 delay)
{
if (geometry == null || color == null || display == null)
{
return;
}

    display.StartDrawing(display.hDC, (System.Int16)esriScreenCache.esriNoScreenCache); // Explicit Cast

    switch (geometry.GeometryType)
    {
        case esriGeometryType.esriGeometryPolygon:
            {
                //Set the flash geometry's symbol.
                ISimpleFillSymbol simpleFillSymbol = new SimpleFillSymbolClass();
                simpleFillSymbol.Color = color;
                ISymbol symbol = simpleFillSymbol as ISymbol; // Dynamic Cast
                symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;

                //Flash the input polygon geometry.
                display.SetSymbol(symbol);
                display.DrawPolygon(geometry);
                System.Threading.Thread.Sleep(delay);
                display.DrawPolygon(geometry);
                break;
            }

        case esriGeometryType.esriGeometryPolyline:
            {
                //Set the flash geometry's symbol.
                ISimpleLineSymbol simpleLineSymbol = new SimpleLineSymbolClass();
                simpleLineSymbol.Width = 4;
                simpleLineSymbol.Color = color;
                ISymbol symbol = simpleLineSymbol as ISymbol; // Dynamic Cast
                symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;

                //Flash the input polyline geometry.
                display.SetSymbol(symbol);
                display.DrawPolyline(geometry);
                System.Threading.Thread.Sleep(delay);
                display.DrawPolyline(geometry);
                break;
            }

        case esriGeometryType.esriGeometryPoint:
            {
                //Set the flash geometry's symbol.
                ISimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbolClass();
                simpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
                simpleMarkerSymbol.Size = 12;
                simpleMarkerSymbol.Color = color;
                ISymbol symbol = simpleMarkerSymbol as ISymbol; // Dynamic Cast
                symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;

                //Flash the input point geometry.
                display.SetSymbol(symbol);
                display.DrawPoint(geometry);
                System.Threading.Thread.Sleep(delay);
                display.DrawPoint(geometry);
                break;
            }

        case esriGeometryType.esriGeometryMultipoint:
            {
                //Set the flash geometry's symbol.
                ISimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbolClass();
                simpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
                simpleMarkerSymbol.Size = 12;
                simpleMarkerSymbol.Color = color;
                ISymbol symbol = simpleMarkerSymbol as ISymbol; // Dynamic Cast
                symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;

                //Flash the input multipoint geometry.
                display.SetSymbol(symbol);
                display.DrawMultipoint(geometry);
                System.Threading.Thread.Sleep(delay);
                display.DrawMultipoint(geometry);
                break;
            }
    }
    display.FinishDrawing();
}

识别要素的方式

这种方式使用IFeatureIdentifyObj接口当中的Flash方法来达到闪烁的目的,代码如下。

public static void identifyFlash(IActiveView activeView, IFeature feature)
{
IFeatureIdentifyObj featIdentify = new FeatureIdentifyObject();
featureIdentify.Feature = feature;
IIdentifyObj identify = featIdentify as IIdentifyObj;
identify.Flash(activeView.ScreenDisplay);
}

调用

注意到上面的ZoomToGeometry方法中,最后一句

activeView.ScreenDisplay.UpdateWindow();
这句非常关键,它会让地图显示窗口立刻重新绘制,更新显示。如果没有这一句,在调用ZoomToGeometry之后紧接着使用FlashGeometry方法就起不到效果,地图窗口会先闪烁一个形状,然后再缩放过去,顺序是不对的。但是加上上面这一句,强制地图窗口重新绘制以后,也就是缩放就立马见效了,这个时候闪烁的形状就是正确的。

arcobjects

  • 3
    点赞
  • 7
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MrJGao

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值