首页 > 其他分享 >ArcEngien|实现拖框/圆/多边形放大缩小

ArcEngien|实现拖框/圆/多边形放大缩小

时间:2023-03-15 11:33:17浏览次数:32  
标签:多边形 ToolStripMenuItem 拖框 ArcEngien axMapControl1 OnMouseDown 缩小 Checked 放大

问题分析

加载地图文档

加载地图文档的过程:先点击“打开”按钮,自动弹出电脑文件夹目录,再从中选取“.mxd”类型的地图文档;选中后点击确定,即可加载;加载时,地图内容显示在Map界面(利用MapControl控件),图层索引显示在TOC界面(利用TOCControl控件)。

放大

放大分为三种方法:矩形放大(拉框放大)、圆形放大、多边形放大。这四种方法看似不一样,但是其本质上都有相同点:放大后的视图为四种geometry的Envelope。因此放大时需要算出画出的几何图形的最小外包矩形即可作为最终视图的一部分。

缩小

与放大相似,首先判断是哪种缩小方法,判断后求出geometry的Envelope,接着计算缩小的比例和缩小后的视图中X、Y坐标的最大值和最小值,最后更新显示界面即可得到缩小后的视图结果。

WinForm界面搭建

设计Windows 窗体应用程序

新建项目

新建一个MapControl窗体应用程序项目(Engine):

image-20230308162214628

窗体设计

MapControl窗体已经自带了很多常用的控件,包括TOCControl,MapControl,LicenseControl等,可以在此基础上添加或进行相应的修改。

image-20230308200351511

读入.xmd文件功能

地图放大功能

在View选项内添加放大选项,并且在放大后增加:按矩形框放大、按圆形放大、按多边形放大三个选项。

image-20230308192901623

地图缩小功能

在View选项内添加缩小选项,并且在缩小后增加:按矩形框缩小、按圆形缩小、按多边形缩小三个选项。

image-20230308192801134

为控件绑定事件

axMapControl1绑定OnMouseDown事件:

image-20230308165126626

为各个ToolStripMenuItem添加Click事件(以按矩形框缩小为例):

image-20230308165258205

添加功能

读入.xmd文件部分

使用OpenFileDialog来过滤并读入文件,代码如下:

private void openXmlFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            IMapDocument pMxdMapDocument = new MapDocumentClass();
            OpenFileDialog pMxdOpenFileDialog = new OpenFileDialog();
            pMxdOpenFileDialog.Filter = "地图文档(*.mxd)|*.mxd";
            if (pMxdOpenFileDialog.ShowDialog() == DialogResult.OK)
            {
                string xjmxdFilePath = pMxdOpenFileDialog.FileName;
                if (axMapControl1.CheckMxFile(xjmxdFilePath))
                {
                    axMapControl1.Map.ClearLayers();
                    axMapControl1.LoadMxFile(xjmxdFilePath);
                }
            }
            axMapControl1.ActiveView.Refresh();
        }

为了使TOCControl中的数据能显示出来,需要将TOCControl控件和MapControl控件通过接口连接,连接方法如下:

image-20230308184758368

绘制图形缩小/放大部分

放大编程思路

首先定义放大的三种方法;接着在各种放大方法的按钮对应的代码中调用放大方法;然后再在OnMouseDowen事件中添加一个switch函数,选择对应的方法应当返回的geometry;最后判断Envelope的边界是否超过View的范围,如果没有超过,则进行放大操作。

缩小编程思路

首先利用switch语句判断缩小方法属于矩形缩小、圆形缩小和多边形缩小中的哪种;接着判断所画geometry是否为空,若为空,则返回空值,若非空则进行如下缩小操作:先算出缩小后视图的长和宽,其计算方法为:当前视图长或宽(当前视图长或宽/geometry的Envelope的长或宽),其中括号中的为缩小系数;接着计算出缩小后视图的x、y最小值:当前视图最小值-(geometry.Envelope的最小值-当前视图最小值)缩小系数;最后计算缩小后视图的最大值:最小值+缩小后视图的长或宽;最终更新视图即可得到缩小后的视图。

编程实现

首先定义一个toolAction的变量来存储功能

private string toolAction;

在各个ToolStripMenuItem_Click事件下编写功能,首先更改toolAction变量的值,随后检查该功能是否被勾选,如果被勾选,则将axMapControl1_OnMouseDown事件加入事件队列之中。

private void 按矩形框放大ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        toolAction = "Rectangle Drag Zoom In";
        if(this.按矩形框放大ToolStripMenuItem.Checked)
        {
            按矩形框放大ToolStripMenuItem.Checked = false;
            this.axMapControl1.OnMouseDown -= new ESRI.ArcGIS.Controls.IMapControlEvents2_Ax_OnMouseDownEventHandler(this.axMapControl1_OnMouseDown);
        }
        else
        {
            按矩形框放大ToolStripMenuItem.Checked = true;
            this.axMapControl1.OnMouseDown += new ESRI.ArcGIS.Controls.IMapControlEvents2_Ax_OnMouseDownEventHandler(this.axMapControl1_OnMouseDown);
        }
    }

private void 按矩形框缩小ToolStripMenuItem_Click(object sender, EventArgs e)
{
    toolAction = "Rectangle Drag Zoom Out";
    if (this.按矩形框缩小ToolStripMenuItem.Checked)
    {
        按矩形框缩小ToolStripMenuItem.Checked = false;
        this.axMapControl1.OnMouseDown -= new ESRI.ArcGIS.Controls.IMapControlEvents2_Ax_OnMouseDownEventHandler(this.axMapControl1_OnMouseDown);
    }
    else
    {
        按矩形框缩小ToolStripMenuItem.Checked = true;
        this.axMapControl1.OnMouseDown += new ESRI.ArcGIS.Controls.IMapControlEvents2_Ax_OnMouseDownEventHandler(this.axMapControl1_OnMouseDown);
    }
}

private void 按多边形放大ToolStripMenuItem_Click(object sender, EventArgs e)
{
    toolAction = "Geometry Drag Zoom In";
    if (按多边形放大ToolStripMenuItem.Checked)
    {
        按多边形放大ToolStripMenuItem.Checked = false;
        this.axMapControl1.OnMouseDown -= new ESRI.ArcGIS.Controls.IMapControlEvents2_Ax_OnMouseDownEventHandler(this.axMapControl1_OnMouseDown);
    }
    else
    {
        按多边形放大ToolStripMenuItem.Checked = true;
        this.axMapControl1.OnMouseDown += new ESRI.ArcGIS.Controls.IMapControlEvents2_Ax_OnMouseDownEventHandler(this.axMapControl1_OnMouseDown);
    }
}

private void 按多边形缩小ToolStripMenuItem_Click(object sender, EventArgs e)
{
    toolAction = "Geometry Drag Zoom Out";
    if (按多边形缩小ToolStripMenuItem.Checked)
    {
        按多边形缩小ToolStripMenuItem.Checked = false;
        this.axMapControl1.OnMouseDown -= new ESRI.ArcGIS.Controls.IMapControlEvents2_Ax_OnMouseDownEventHandler(this.axMapControl1_OnMouseDown);
    }
    else
    {
        按多边形缩小ToolStripMenuItem.Checked = true;
        this.axMapControl1.OnMouseDown += new ESRI.ArcGIS.Controls.IMapControlEvents2_Ax_OnMouseDownEventHandler(this.axMapControl1_OnMouseDown);
    }
}

private void 按圆形放大ToolStripMenuItem_Click(object sender, EventArgs e)
{
    toolAction = "Circle Drag Zoom In";
    if (按圆形放大ToolStripMenuItem.Checked)
    {
        按圆形放大ToolStripMenuItem.Checked = false;
        this.axMapControl1.OnMouseDown -= new ESRI.ArcGIS.Controls.IMapControlEvents2_Ax_OnMouseDownEventHandler(this.axMapControl1_OnMouseDown);
    }
    else
    {
        按圆形放大ToolStripMenuItem.Checked = true;
        this.axMapControl1.OnMouseDown += new ESRI.ArcGIS.Controls.IMapControlEvents2_Ax_OnMouseDownEventHandler(this.axMapControl1_OnMouseDown);
    }
}

private void 按圆形缩小ToolStripMenuItem_Click(object sender, EventArgs e)
{
    toolAction = "Circle Drag Zoom Out";
    if (按圆形缩小ToolStripMenuItem.Checked)
    {
        按圆形缩小ToolStripMenuItem.Checked = false;
        this.axMapControl1.OnMouseDown -= new ESRI.ArcGIS.Controls.IMapControlEvents2_Ax_OnMouseDownEventHandler(this.axMapControl1_OnMouseDown);
    }
    else
    {
        按圆形缩小ToolStripMenuItem.Checked = true;
        this.axMapControl1.OnMouseDown += new ESRI.ArcGIS.Controls.IMapControlEvents2_Ax_OnMouseDownEventHandler(this.axMapControl1_OnMouseDown);
    }
}

为了避免大量重复的代码块出现,因此需要写一个缩小外接矩形的方法,代码如下:

private IEnvelope zoom_out(IEnvelope pEnvelop2)
        {
            double x_scale = axMapControl1.Extent.Width / pEnvelop2.Width;//XY尺寸
            double y_scale = axMapControl1.Extent.Height / pEnvelop2.Width;
            //新窗口的高度宽度=原地图窗口*比例
            double width = axMapControl1.Extent.Width * x_scale;
            double height = axMapControl1.Extent.Width * y_scale;
            //找到窗口的最小值 即XY的最小值
            double x_min = pEnvelop2.XMin - (pEnvelop2.XMin - axMapControl1.Extent.XMin) * x_scale;
            double y_min = pEnvelop2.YMin - (pEnvelop2.YMin - axMapControl1.Extent.YMin) * y_scale;

            //取矩形框的取最大值
            double x_max = x_min + width;
            double y_max = y_min + height;

            //新的envelop
            pEnvelop2.PutCoords(x_min, y_min, x_max, y_max);
            return pEnvelop2;
        }

axMapControl1_OnMouseDown事件中,使用switch case语句来实现不同的功能:

private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            switch (toolAction)
            {
                case "Rectangle Drag Zoom In":
                    IEnvelope pEnvelop = axMapControl1.TrackRectangle();
                    if (pEnvelop == null | pEnvelop.IsEmpty || pEnvelop.Height == 0 || pEnvelop.Width == 0)//判断外接矩形是否为空
                    {
                        return;
                    }
                    axMapControl1.Extent = pEnvelop;
                    break;
                case "Rectangle Drag Zoom Out":
                    IEnvelope pEnvelop2 = axMapControl1.TrackRectangle();
                    if (pEnvelop2 == null || pEnvelop2.IsEmpty || pEnvelop2.Height == 0 || pEnvelop2.Width == 0)
                    {
                        return;
                    }
                    IEnvelope pEnvelop2_1 = zoom_out(pEnvelop2);
                    axMapControl1.Extent = pEnvelop2_1;
                    axMapControl1.Refresh();
                    break;
                case "Geometry Drag Zoom In":
                    IGeometry IG1 = axMapControl1.TrackPolygon();
                    IEnvelope pEnvelop3 = IG1.Envelope;
                    if (pEnvelop3 == null | pEnvelop3.IsEmpty || pEnvelop3.Height == 0 || pEnvelop3.Width == 0)//判断外接矩形是否为空
                    {
                        return;
                    }
                    axMapControl1.Extent = pEnvelop3;
                    break;
                case "Geometry Drag Zoom Out":
                    IGeometry IG2 = axMapControl1.TrackPolygon();
                    IEnvelope pEnvelop4 = IG2.Envelope;
                    if (pEnvelop4 == null | pEnvelop4.IsEmpty || pEnvelop4.Height == 0 || pEnvelop4.Width == 0)//判断外接矩形是否为空
                    {
                        return;
                    }
                    IEnvelope pEnvelop4_1 = zoom_out(pEnvelop4);
                    axMapControl1.Extent = pEnvelop4_1;
                    axMapControl1.Refresh();
                    break;
                case "Circle Drag Zoom In":
                    IGeometry IG3 = axMapControl1.TrackCircle();
                    IEnvelope pEnvelop5 = IG3.Envelope;
                    if (pEnvelop5 == null | pEnvelop5.IsEmpty || pEnvelop5.Height == 0 || pEnvelop5.Width == 0)//判断外接矩形是否为空
                    {
                        return;
                    }
                    axMapControl1.Extent = pEnvelop5;
                    break;
                case "Circle Drag Zoom Out":
                    IGeometry IG4 = axMapControl1.TrackCircle();
                    IEnvelope pEnvelop6 = IG4.Envelope;
                    if (pEnvelop6 == null | pEnvelop6.IsEmpty || pEnvelop6.Height == 0 || pEnvelop6.Width == 0)//判断外接矩形是否为空
                    {
                        return;
                    }
                    IEnvelope pEnvelop6_1 = zoom_out(pEnvelop6);
                    axMapControl1.Extent = pEnvelop6_1;
                    axMapControl1.Refresh();
                    break;
            }
        }

运行结果

读入.mxd文档

选择文件:

image-20230308200457835

读入.mxd文档的结果:

image-20230308200522576

按矩形框放大

拖拽一个矩形框:

image-20230308200634045

按矩形框放大结果:

image-20230308200745822

按矩形框缩小

拖拽一个矩形框:

image-20230308200830643

按矩形框缩小结果:

image-20230308200839799

按圆形放大

拖拽一个圆形

image-20230308201139223

按圆形放大结果

image-20230308201201930

按圆形缩小

拖拽一个圆形

image-20230308201652819

按圆形缩小结果

image-20230308201703715

按多边形放大

绘制一个多边形:

image-20230308201748591

按多边形放大结果:

image-20230308201830886

按多边形缩小

绘制一个多边形:

image-20230308202332895

按多边形缩小结果:

image-20230308202341683

分析

MapControl和TOCControl之间的关系,通过那个接口实现关联?

TOCControl控件相当于ArcMap中左侧的目录树,需要与一个“伙伴控件”协同工作,可以是MapControl、PageLayoutControl、SceneControl或者GlobeControl,通过ITOCBuddy接口连接。

image-20230309122745759

伙伴控件的设置可通过TOCControl属性对话框或用SetBuddyControl方法通过编程设置,

private void Form1_Load(object sender, EventArgs e)
{
	axTOCControl1.SetBuddyControl(axMapControl1);
}

TOCControl控件支持BuddySetBuddyControl()将MapControl设置为伙伴控件,使得两者可以协同工作。

标签:多边形,ToolStripMenuItem,拖框,ArcEngien,axMapControl1,OnMouseDown,缩小,Checked,放大
From: https://www.cnblogs.com/tangjielin/p/17217867.html

相关文章

  • geotools之GeometryBuilder创建3D的多边形——面片
    说到3D,大家想到的都是物体。。但是如果3D的线和3D的面。。难道就不能创建吗?参考1:https://docs.geotools.org/stable/javadocs/org/geotools/geometry/jts/GeometryBuilde......
  • GJK算法计算凸多边形之间的距离
    GJK是空间距离检测算法,是由三位(Gilbert,Johnson,andKeerthi's )作者的首字母组成的代称。GJK算法首先要解决计算Minkowski和的问题。所谓Minkowski和,指A、B两个集......
  • python_opencv_画图_直线_矩形_圆_多边形_文字提示
    opencv绘图参数说明绘制形状的函数有一些共同的参数:img:要绘制形状的图片color:绘制的颜色彩色图就传入BGR的一组值,如蓝色就是(255,0,0)灰度图,传入一个灰度值就......
  • C# 多个矩形围成的多边形标注位置的问题
    如下图1,需要对各小块进行序号标注。如果按组合多边形的方式,则会出现图2的情况,序号不在块内或排列不美观。如图2,序号不在合适的美观位置。这种如何将带圈的序号绘制成如上图......
  • 【OpenCV】- 多边形将轮廓包围
    说明:实际应用中,常常会将检测到的轮廓用多边形表示出来的需求。1、返回外部矩形边界:boundingRect()函数说明:此函数计算并返回指定点集最外面的矩形边界Rectpoint=boundingRe......
  • 【CCCC】L3-006 迎风一刀斩 (30分),几何关系,找规律 (拼合多边形==斜边等价)
    problem题意:给出n对多边形,判断每一对多边形是否是由一块矩形一刀切下形成的。solution一个矩形被切,有4种情况切到0个顶点,三角形+五边形,或四边形+四边形切到1个顶点,三角形+......
  • leaflet多边形填充图片
    效果图: leaflet 有imageOverlay图层根据两个点坐标生成图像,但体验感不太好,设计上传一张图片后,常常不能对齐,就尝试自己封装个图层。如上图所示,图片有两种方式,一种方式......
  • geotools求多边形的面积 单位米(地理坐标系转投影坐标系)
    参考:根据wkt或geometry计算面积(平方米):https://blog.csdn.net/wuxiaowu123/article/details/118153835>>如何利用PostGIS正确计算距离和面积:https://blog.csdn.net/qq_3066......
  • Cesium:文字转图片,图片贴到多边形上
    JS前端文字转图片:link缺点:需要在网页中有一个canvas。canvas.toDataURL("image/png")后端文字转图片:text-to-svgsvg2pnghttps://www.cnblogs.com/duasonir/p/16700591......
  • hdu:Shape of HDU(判断多边形凹凸)
    ProblemDescription话说上回讲到海东集团推选老总的事情,最终的结果是XHD以微弱优势当选,从此以后,“徐队”的称呼逐渐被“徐总”所取代,海东集团(HDU)也算是名副其实了。创业......