地图测距和测面积的简单实现

在silverlight api中测距和测面积有多种实现方式,

     第一种,使用GeometryServer服务;

     第二种,使用行为动作MeasureAction;

     第三种,使用ESRI.ArcGIS.Client.Geometry.Euclidian类;
我主要说说第三种实现方式,前两种网上已经有很多资料了。

代码如下:

	private Draw _DrawTool;
	private EventHandler<DrawEventArgs> _DrawComplete;

	//测距
        public void Ranging(EventHandler<DrawEventArgs> drawComplete = null)
        {
            if (drawComplete == null) drawComplete = Ranging_Complete;
            CreateFreeBursh(drawComplete);
            _DrawTool.DrawMode = DrawMode.Polyline;
            OpenFreeBursh();
        }
        private void Ranging_Complete(object sender, DrawEventArgs e)
        {
            double length = Math.Abs(ESRI.ArcGIS.Client.Geometry.Euclidian.Length(e.Geometry as Polyline));
            if (length > 0)
            {
                this.Graphics.Add(new Graphic()
                {
                    Geometry = e.Geometry,
                    Symbol = new SimpleLineSymbol() { Color = new SolidColorBrush(Colors.Red), Width = 2 },
                });
                this.Graphics.Add(new Graphic()
                {
                    Geometry = (e.Geometry as Polyline).Paths.LastOrDefault().LastOrDefault(),
                    Symbol = new TextSymbol() { Text = string.Format("{0:F} km", length / 1000), FontFamily = new FontFamily("SimSun"), FontSize = 13 },
                });
            }
        }

        //测面积
        public void Polygon(EventHandler<DrawEventArgs> drawComplete = null)
        {
            if (drawComplete == null) drawComplete = Polygon_Complete;
            CreateFreeBursh(drawComplete);
            _DrawTool.DrawMode = DrawMode.Polygon;
            OpenFreeBursh();
        }
        private void Polygon_Complete(object sender, DrawEventArgs e)
        {
            double area = Math.Abs(ESRI.ArcGIS.Client.Geometry.Euclidian.Area(e.Geometry as Polygon));
            if (area > 0)
            {
                this.Graphics.Add(new Graphic()
                {
                    Geometry = e.Geometry,
                    Symbol = new SimpleFillSymbol() { Fill = new SolidColorBrush(AppColorManager.HtmlToColor("#22FF0000")), BorderBrush = new SolidColorBrush(Colors.Red), BorderThickness = 2 }
                });
                this.Graphics.Add(new Graphic()
                {
                    Geometry = (e.Geometry as Polygon).Rings.LastOrDefault().FirstOrDefault(),
                    Symbol = new TextSymbol() { Text = string.Format("{0:F} km2", area / 1000000), FontFamily = new FontFamily("SimSun"), FontSize = 13 },
                });
            }
        }


客户最近打电话过来,说我们的软件在量距离的时候不能平移地图。我们的软件是使用ArcEngine来开发的,在网上输入关键字“arcengine 距离量”,可以搜索到一大堆内容基本相似的文章或代码,基本上都是采用INewLineFeedback来实现的,我们的软件也是使用此种方法。方法大致如下:写一个距离量工具,继承自BaseTool,在该类中使用INewLineFeedback动态绘制多段折线,最后转化为Element添加到地图上。如果要增加平移功能,我们仿造ArcMap使用鼠标中键平移,在OnMouseDown、OnMouseMove、OnMouseUp事件中增加判断鼠标中键的语句,然后分别使用PanStart、PanMoveTo、PanStop实现地图的平移。 此时,出现了一个新问题,一旦移动地图后,之前使用INewLineFeedback绘制的线完全乱了方寸,有一部分线丢失了。之后又发现一个更可笑的问题,在绘制的过程中,如果使用alt+tab键切换到其它窗口,然后再切换回地图窗口的时候,会多出一条线,INewLineFeedback把切换窗口前的鼠标位置记录了下来。 对于这个问题,我使用ArcMap的量工具检查了一下,发现不存在上述问题。但是INewLineFeedback为什么会产生这个bug,难道是本人的使用方法不对。在网上搜了一下其他类似代码进行试,都存在这个bug。ArcEngine的SDK文档上也没有特别强调INewLineFeedback的使用细节。 本来打算用gdi进行解决,最后发现INewLineFeedback有一个Refresh函数,那么应该在什么地方使用它呢?在ArcMapControl的诸多事件中,尝试了OnAfterDraw、OnAfterScreenDraw、OnViewRefresh等,发现OnAfterScreenDraw是OK的。具体是在OnAfterScreenDraw事件中使用Refresh函数刷新INewLineFeedback,完美解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值