ArcGIS Engine 10.0 for.NET开发学习笔记(九)

来源:互联网 发布:java怎么解析cad图纸 编辑:程序博客网 时间:2024/05/24 01:11
【地图基本操作】
一、地图导出
地图导出是将地图保存为图片,方便快速查看浏览。地图导出分为全域导出和区域导出两种。
导出窗体(FormExportMap)设计如下图所示,其中输出宽度与输出高度不允许进行编辑。


窗口核心代码如下:
private string pSavePath = "";        private IActiveView pActiveView;        private IGeometry pGeometry = null;        /// <summary>        /// 只读属性,地图导出空间图形        /// </summary>        public IGeometry GetGeometry        {            set            {                pGeometry = value;            }        }        private bool bRegion = true;        /// <summary>        /// 只读属性,是全域导出还是自由区域导出        /// </summary>        public bool IsRegion        {            set            {                bRegion = value;            }        }        public FormExportMap(AxMapControl mainAxMapControl)        {            InitializeComponent();            pActiveView = mainAxMapControl.ActiveView;        }

在窗口进行初始化时,首先读取当前数据视图的分辨率,并添加到cboResolution中。代码如下:
 private void FormExportMap_Load(object sender, EventArgs e)        {            InitFormSize();        }        private void InitFormSize()        {            cboResolution.Text = pActiveView.ScreenDisplay.DisplayTransformation.Resolution.ToString();            cboResolution.Items.Add(cboResolution.Text);            //......        }

当数据视图的分辨率改变时,输出图片像素的宽度和高度也会相应改变,计算公式为:输出图片的宽(高)=当前视图的宽(高)*输出图片的分辨率/当前数据视图显示的分辨率。
核心代码如下:

private void cboResolution_SelectedIndexChanged(object sender, EventArgs e)        {            double num = (int)Math.Round(pActiveView.ScreenDisplay.DisplayTransformation.Resolution);            if (cboResolution.Text == "")            {                txtWidth.Text = "";                txtHeight.Text = "";                return;            }            if (bRegion)            {                IEnvelope pEnvelope = pGeometry.Envelope;                tagRECT pRECT = new tagRECT();                pActiveView.ScreenDisplay.DisplayTransformation.TransformRect(pEnvelope, ref pRECT, 9);                if (cboResolution.Text != "")                {                    txtWidth.Text = Math.Round((double)(pRECT.right * (double.Parse(cboResolution.Text) / (double)num))).ToString();                    txtHeight.Text = Math.Round((double)(pRECT.bottom * (double.Parse(cboResolution.Text) / (double)num))).ToString();                }            }            else            {                txtWidth.Text = Math.Round((double)(pActiveView.ExportFrame.right * (double.Parse(cboResolution.Text) / (double)num))).ToString();                txtHeight.Text = Math.Round((double)(pActiveView.ExportFrame.bottom * (double.Parse(cboResolution.Text) / (double)num))).ToString();            }        }

在地图进行导出时根据bRegion进行判断是全域导出还是区域导出,核心代码如下:
private void InitFormSize()        {            cboResolution.Text = pActiveView.ScreenDisplay.DisplayTransformation.Resolution.ToString();            cboResolution.Items.Add(cboResolution.Text);            if (bRegion)            {                IEnvelope pEnvelope = pGeometry.Envelope;                tagRECT pRECT = new tagRECT();                pActiveView.ScreenDisplay.DisplayTransformation.TransformRect(pEnvelope, ref pRECT, 9);                if (cboResolution.Text != "")                {                    txtWidth.Text = pRECT.right.ToString();                    txtHeight.Text = pRECT.bottom.ToString();                }            }            else            {                if (cboResolution.Text != "")                {                    txtWidth.Text = pActiveView.ExportFrame.right.ToString();                    txtHeight.Text = pActiveView.ExportFrame.bottom.ToString();                }            }        }

全域导出和区域导出功能很类似,封装成ExportMap类,功能包括图片导出、视图窗口绘制几何图形元素、创建图形元素、获取RGB颜色等。类的核心代码如下:
class ExportMap    {        public static void ExportView(IActiveView view, IGeometry pGeo, int OutputResolution,int Width, int Height, string ExpPath, bool bRegion)        {            IExport pExport = null;            tagRECT exportRect = new tagRECT();            IEnvelope pEnvelope = pGeo.Envelope;            string sType = System.IO.Path.GetExtension(ExpPath);            switch (sType)            {                case ".jpg":                    pExport = new ExportJPEGClass();                    break;                case ".bmp":                    pExport = new ExportBMPClass();                    break;                case ".gif":                    pExport = new ExportGIFClass();                    break;                case ".tif":                    pExport = new ExportTIFFClass();                    break;                case ".png":                    pExport = new ExportPNGClass();                    break;                case ".pdf":                    pExport = new ExportPDFClass();                    break;                default:                    MessageBox.Show("没有输出格式,默认到JPEG格式");                    pExport = new ExportJPEGClass();                    break;            }             pExport.ExportFileName = ExpPath;            exportRect.left = 0; exportRect.top = 0;            exportRect.right = Width;            exportRect.bottom = Height;            if (bRegion)            {                view.GraphicsContainer.DeleteAllElements();                view.Refresh();            }            IEnvelope envelope = new EnvelopeClass();            envelope.PutCoords((double)exportRect.left, (double)exportRect.top, (double)exportRect.right, (double)exportRect.bottom);            pExport.PixelBounds = envelope;            view.Output(pExport.StartExporting(), OutputResolution, ref exportRect, pEnvelope, null);            pExport.FinishExporting();            pExport.Cleanup();        }        /// <summary>        /// 全域导出        /// </summary>        /// <param name="OutputResolution">输出分辨率</param>        /// <param name="ExpPath">输出路径</param>        /// <param name="view">视图</param>        public static void ExportActiveView(int OutputResolution, string ExpPath, IActiveView view)        {            IExport pExport = null;            tagRECT exportRect;            IEnvelope envelope2 = view.Extent;            int num = (int)Math.Round(view.ScreenDisplay.DisplayTransformation.Resolution);            string sType = System.IO.Path.GetExtension(ExpPath);            switch (sType)            {                case ".jpg":                    pExport = new ExportJPEGClass();                    break;                case ".bmp":                    pExport = new ExportBMPClass();                    break;                case ".gif":                    pExport = new ExportGIFClass();                    break;                case ".tif":                    pExport = new ExportTIFFClass();                    break;                case ".png":                    pExport = new ExportPNGClass();                    break;                case ".pdf":                    pExport = new ExportPDFClass();                    break;                default:                    MessageBox.Show("没有输出格式,默认到JPEG格式");                    pExport = new ExportJPEGClass();                    break;            }            pExport.ExportFileName = ExpPath;            exportRect.left = 0; exportRect.top = 0;            exportRect.right = (int)Math.Round((double)(view.ExportFrame.right * (((double)OutputResolution) / ((double)num))));            exportRect.bottom = (int)Math.Round((double)(view.ExportFrame.bottom * (((double)OutputResolution) / ((double)num))));            IEnvelope envelope = new EnvelopeClass();            envelope.PutCoords((double)exportRect.left, (double)exportRect.top, (double)exportRect.right, (double)exportRect.bottom);            pExport.PixelBounds = envelope;            view.Output(pExport.StartExporting(), OutputResolution, ref exportRect, envelope2, null);            pExport.FinishExporting();            pExport.Cleanup();        }        /// <summary>        /// 区域导出        /// </summary>        /// <param name="pGeo">几何图形</param>        /// <param name="OutputResolution">输出分辨率</param>        /// <param name="ExpPath">输出路径</param>        /// <param name="view">视图</param>        public static void ExportRegion(IGeometry pGeo, int OutputResolution, string ExpPath, IActiveView view)        {            IExport export = null;            IWorldFileSettings settings = null;            IEnvelope envelope2 = pGeo.Envelope;            string str = ExpPath.Substring(ExpPath.Length - 3, 3).ToUpper();            switch (str)            {                case "JPG":                    settings = new ExportJPEGClass();                    export = new ExportJPEGClass();                    settings = export as IWorldFileSettings; ;                    settings.MapExtent = envelope2;                    settings.OutputWorldFile = false;                    break;                case "BMP":                    settings = new ExportBMPClass();                    export = new ExportBMPClass();                    settings = export as IWorldFileSettings; ;                    settings.MapExtent = envelope2;                    settings.OutputWorldFile = false;                    break;                case "TIF":                    settings = new ExportTIFFClass();                    export = new ExportTIFFClass();                    settings = export as IWorldFileSettings; ;                    settings.MapExtent = envelope2;                    settings.OutputWorldFile = false;                    break;                case "PNG":                    settings = new ExportPNGClass();                    export = new ExportPNGClass();                    settings = export as IWorldFileSettings;                    settings.MapExtent = envelope2;                    settings.OutputWorldFile = false;                    break;                default:                    break;            }            if (settings == null) return;            export.ExportFileName = ExpPath;            int num = (int)Math.Round(view.ScreenDisplay.DisplayTransformation.Resolution);            tagRECT grect2 = new tagRECT();            IEnvelope envelope3 = new EnvelopeClass();            view.ScreenDisplay.DisplayTransformation.TransformRect(envelope2, ref grect2, 9);            grect2.left = 0;            grect2.top = 0;            grect2.right = (int)Math.Round((double)((grect2.right - grect2.left) * (((double)OutputResolution) / ((double)num))));            grect2.bottom = (int)Math.Round((double)((grect2.bottom - grect2.top) * (((double)OutputResolution) / ((double)num))));            envelope3.PutCoords((double)grect2.left, (double)grect2.top, (double)grect2.right, (double)grect2.bottom);            export.PixelBounds = envelope3;            view.GraphicsContainer.DeleteAllElements();            view.Output(export.StartExporting(), OutputResolution, ref grect2, envelope2, null);            export.FinishExporting();            export.Cleanup();            AddElement(pGeo, view);        }        /// <summary>        /// 视图窗口绘制几何图形元素        /// </summary>        /// <param name="pGeometry">几何图形</param>        /// <param name="activeView">视图</param>        public static void AddElement(IGeometry pGeometry, IActiveView activeView)        {            IRgbColor fillColor = GetRgbColor(204, 175, 235);            IRgbColor lineColor = GetRgbColor(0, 0, 0);            IElement pEle = CreateElement(pGeometry, lineColor, fillColor);            IGraphicsContainer pGC = activeView.GraphicsContainer;            if (pGC != null)            {                pGC.AddElement(pEle, 0);                activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pEle, null);            }        }        /// <summary>        /// 获取RGB颜色        /// </summary>        /// <param name="intR">红</param>        /// <param name="intG">绿</param>        /// <param name="intB">蓝</param>        /// <returns></returns>        private static IRgbColor GetRgbColor(int intR, int intG, int intB)        {            IRgbColor pRgbColor = null;            if (intR < 0 || intR > 255 || intG < 0 || intG > 255 || intB < 0 || intB > 255)            {                return pRgbColor;            }            pRgbColor = new RgbColorClass();            pRgbColor.Red = intR;            pRgbColor.Green = intG;            pRgbColor.Blue = intB;            return pRgbColor;        }        /// <summary>        /// 创建图形元素        /// </summary>        /// <param name="pGeometry">几何图形</param>        /// <param name="lineColor">边框颜色</param>        /// <param name="fillColor">填充颜色</param>        /// <returns></returns>        private static IElement CreateElement(IGeometry pGeometry, IRgbColor lineColor, IRgbColor fillColor)        {            if (pGeometry == null || lineColor == null || fillColor == null)            {                return null;            }            IElement pElem = null;            try            {                if (pGeometry is IEnvelope)                    pElem = new RectangleElementClass();                else if (pGeometry is IPolygon)                    pElem = new PolygonElementClass();                else if (pGeometry is ICircularArc)                {                    ISegment pSegCircle = pGeometry as ISegment;//QI                    ISegmentCollection pSegColl = new PolygonClass();                    object o = Type.Missing;                    pSegColl.AddSegment(pSegCircle, ref o, ref o);                    IPolygon pPolygon = pSegColl as IPolygon;                    pGeometry = pPolygon as IGeometry;                    pElem = new CircleElementClass();                }                else if (pGeometry is IPolyline)                    pElem = new LineElementClass();                if (pElem == null)                    return null;                pElem.Geometry = pGeometry;                IFillShapeElement pFElem = pElem as IFillShapeElement;                ISimpleFillSymbol pSymbol = new SimpleFillSymbolClass();                pSymbol.Color = fillColor;                pSymbol.Outline.Color = lineColor;                pSymbol.Style = esriSimpleFillStyle.esriSFSCross;                if (pSymbol == null)                {                    return null;                }                pFElem.Symbol = pSymbol;            }            catch (Exception ex)            {                MessageBox.Show(ex.Message);            }            return pElem;        }    }

1、全域导出
当全域导出按钮的事件触发时,赋值给控制全域输出的布尔型变量为true。核心代码如下:

private void btnExportMap_Click(object sender, EventArgs e)        {            if (frmExpMap == null || frmExpMap.IsDisposed)            {                frmExpMap = new FormExportMap(mainMapControl);            }            frmExpMap.IsRegion = false;            frmExpMap.GetGeometry = mainMapControl.ActiveView.Extent;            frmExpMap.Show();            frmExpMap.Activate();        }

2、区域导出

按钮单击事件代码:

private void btnExportRegion_Click(object sender, EventArgs e)        {            mainMapControl.CurrentTool = null;            mainMapControl.MousePointer = esriControlsMousePointer.esriPointerCrosshair;            pMouseOperate = "ExportRegion";        }

区域导出首先绘制出需要导出的多边形区域,主要使用IRubberBand接口。IRubberBand接口有TrackExisting和TrackNew两种方法。TrackExisting用于判断当鼠标点击时,是否移动或重绘选中的图形;TrackNew用于当鼠标点击时,在视图窗口中绘制一个新的图形。

对绘制多边形的方法进行封装,代码如下:
//绘制多边形        public IPolygon DrawPolygon(AxMapControl mapCtrl)        {            IGeometry pGeometry = null;            if (mapCtrl == null) return null;            IRubberBand rb = new RubberPolygonClass();            pGeometry = rb.TrackNew(mapCtrl.ActiveView.ScreenDisplay, null);            return pGeometry as IPolygon;        }

当鼠标点击时,绘制多边形,获取多边形的Geometry,对Geometry范围内的地图进行输出。在mainMapControl的OnMouseDown事件中,核心代码如下:

case "ExportRegion":  //区域导出                        //删除视图中数据                        mainMapControl.ActiveView.GraphicsContainer.DeleteAllElements();                        mainMapControl.ActiveView.Refresh();                        IPolygon pPolygon = DrawPolygon(mainMapControl);                        if (pPolygon == null) return;                        ExportMap.AddElement(pPolygon, mainMapControl.ActiveView);                        if (frmExpMap == null || frmExpMap.IsDisposed)                        {                            frmExpMap = new FormExportMap(mainMapControl);                        }                        frmExpMap.IsRegion = true;                        frmExpMap.GetGeometry = pPolygon as IGeometry;                        frmExpMap.Show();                        frmExpMap.Activate();                        break;

二、TOCControl控件的右键菜单
添加右键菜单需要使用ContextMenuStrip控件,这里以添加属性表、缩放到图层、移除图层、图层可选、图层不可选五个常用功能为例进行讲解。右键菜单如下图所示。

首先定义需要的变量,代码如下:
//TOC菜单        IFeatureLayer pTocFeatureLayer = null;            //点击的要素图层        private FormAtrribute frmAttribute = null;        //图层属性窗体        private ILayer pMoveLayer;                        //需要调整显示顺序的图层        private int toIndex;                              //存放拖动图层移动到的索引号

在TOCControl控件的OnMouseDown事件中添加如下代码:
private void axTOCControl_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)        {            try            {                if (e.button == 2)                {                    esriTOCControlItem pItem = esriTOCControlItem.esriTOCControlItemNone;                    IBasicMap pMap = null;                    ILayer pLayer = null;                    object unk = null;                    object data = null;                    axTOCControl.HitTest(e.x, e.y, ref pItem, ref pMap, ref pLayer, ref unk, ref data);                    pTocFeatureLayer = pLayer as IFeatureLayer;                    if (pItem == esriTOCControlItem.esriTOCControlItemLayer && pTocFeatureLayer != null)                    {                        btnLayerSel.Enabled = !pTocFeatureLayer.Selectable;                        btnLayerUnSel.Enabled = pTocFeatureLayer.Selectable;                        contextMenuStrip.Show(Control.MousePosition);                    }                }            }            catch (Exception ex)            {                MessageBox.Show(ex.Message);            }              }

1、查看图层属性表
实现思路如下:
(1)遍历矢量目标图层的所有字段,读取其别名赋值给表的列标题。
(2)查询图层的所有要素,根据要素字段的索引序号读取要素的字段值,并添加到列表中,依次循环。
(3)与DataGridView控件的数据源绑定。
属性表运行界面如下图所示:

添加一个DataGridView控件,命名为dataGridAttribute。核心代码如下:
 //要查询的属性图层        private IFeatureLayer _curFeatureLayer;        public IFeatureLayer CurFeatureLayer        {            get { return _curFeatureLayer; }            set { _curFeatureLayer = value; }        }        public void InitUI()        {            if (_curFeatureLayer == null) return;            IFeature pFeature = null;            DataTable pFeatDT = new DataTable(); //创建数据表            DataRow pDataRow = null; //数据表行变量            DataColumn pDataCol = null; //数据表列变量            IField pField = null;            for (int i = 0; i < _curFeatureLayer.FeatureClass.Fields.FieldCount; i++)            {                pDataCol = new DataColumn();                pField = _curFeatureLayer.FeatureClass.Fields.get_Field(i);                pDataCol.ColumnName = pField.AliasName; //获取字段名作为列标题                pDataCol.DataType = Type.GetType("System.Object");//定义列字段类型                pFeatDT.Columns.Add(pDataCol); //在数据表中添加字段信息            }            IFeatureCursor pFeatureCursor = _curFeatureLayer.Search(null, true);            pFeature = pFeatureCursor.NextFeature();            while (pFeature != null)            {                pDataRow = pFeatDT.NewRow();                //获取字段属性                for (int k = 0; k < pFeatDT.Columns.Count; k++)                {                    pDataRow[k] = pFeature.get_Value(k);                }                pFeatDT.Rows.Add(pDataRow); //在数据表中添加字段属性信息                pFeature = pFeatureCursor.NextFeature();            }            //释放指针            System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeatureCursor);            //dataGridAttribute.BeginInit();            dataGridAttribute.DataSource = pFeatDT;            //dataGridAttribute.EndInit();        }

在属性表按钮的单击事件中调用属性窗口,核心代码如下:
 //属性表窗口        private void btnAttribute_Click(object sender, EventArgs e)        {            if (frmAttribute == null || frmAttribute.IsDisposed)            {                frmAttribute = new FormAtrribute();            }            frmAttribute.CurFeatureLayer = pTocFeatureLayer;            frmAttribute.InitUI();            frmAttribute.ShowDialog();        }

2、缩放到图层
根据IFeatureLayer接口的AreaOfInterest属性获取图层的范围,并赋予数据视图的范围。在缩放到图层按钮的单击事件中,核心代码如下:
//缩放到图层        private void btnZoomToLayer_Click(object sender, EventArgs e)        {            if (pTocFeatureLayer == null) return;            (mainMapControl.Map as IActiveView).Extent = pTocFeatureLayer.AreaOfInterest;            (mainMapControl.Map as IActiveView).PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);        }

3、移除图层
一般情况下,对地图进行删除操作时需进行提示。在移除图层按钮的单击事件中,核心代码如下:
//移除图层        private void btnRemoveLayer_Click(object sender, EventArgs e)        {            try            {                if (pTocFeatureLayer == null) return;                DialogResult result = MessageBox.Show("是否删除[" + pTocFeatureLayer.Name + "]图层", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);                if (result == DialogResult.OK)                {                    mainMapControl.Map.DeleteLayer(pTocFeatureLayer);                }                mainMapControl.ActiveView.Refresh();            }            catch (Exception ex)            {                MessageBox.Show(ex.Message);            }        }

4、图层可选、不可选
设置图层是否可选,主要用到IFeatureLayer接口的Selectable属性,当图层设置不可选时,要素选择工具不能拾取该图层的要素。当右键菜单弹出时,设置图层可选、不可选按钮可用状态。
点击可选按钮时,设置图层可算,可选按钮不可用。核心代码如下:
//图层可选        private void btnLayerSel_Click(object sender, EventArgs e)        {            pTocFeatureLayer.Selectable = true;            btnLayerSel.Enabled = !btnLayerSel.Enabled;        }

点击不可选按钮时,设置图层不可选,不可选按钮不可用。核心代码如下:
//图层不可选        private void btnLayerUnSel_Click(object sender, EventArgs e)        {            pTocFeatureLayer.Selectable = false;            btnLayerUnSel.Enabled = !btnLayerUnSel.Enabled;        }

三、图层显示顺序调整
为实现使用鼠标将需要调整显示顺序的图层拖放到目标位置的功能,涉及TOCControl控件的OnMouseDown和OnMouseUp两个事件以及HitTest()方法。
实现思路:
(1)在TOCControl中,鼠标点击时即在OnMouseDown事件中,拾取需要调整显示顺序的图层,当鼠标弹起时即OnMouseUp事件中,获得图层移到位置的图层索引号。
(2)使用IMap接口提供的MoveLayer方法,将需要调整显示顺序的图层移到目标位置。
(3)使用TOCControl的Update()方法,更新TOCControl控件中的图层顺序。
需要声明的变量如下:
private ILayer pMoveLayer;                        //需要调整显示顺序的图层private int toIndex;                              //存放拖动图层移动到的索引号private Point pMoveLayerPoint = new Point();  //鼠标在TOC中左键按下时点的位置

在TOCControl的OuMouseDown事件中,核心代码如下:
private void axTOCControl_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)        {            try            {                if (e.button == 1)                {                    esriTOCControlItem pItem = esriTOCControlItem.esriTOCControlItemNone;                    IBasicMap pMap = null; object unk = null;                    object data = null; ILayer pLayer = null;                    axTOCControl.HitTest(e.x, e.y, ref pItem, ref pMap, ref pLayer, ref unk, ref data);                    if (pLayer == null) return;                    pMoveLayerPoint.PutCoords(e.x, e.y);                    if (pItem == esriTOCControlItem.esriTOCControlItemLayer)                    {                        if (pLayer is IAnnotationSublayer)                        {                            return;                        }                        else                        {                            pMoveLayer = pLayer;                        }                    }                }            }            catch (Exception ex)            {                MessageBox.Show(ex.Message);            }              }

在TOCControl的OuMouseUp事件中,核心代码如下:

private void axTOCControl_OnMouseUp(object sender, ITOCControlEvents_OnMouseUpEvent e)        {            try            {                if (e.button == 1 && pMoveLayer != null && pMoveLayerPoint.Y != e.y)                {                    esriTOCControlItem pItem = esriTOCControlItem.esriTOCControlItemNone;                    IBasicMap pBasicMap = null; object unk = null;                    object data = null; ILayer pLayer = null;                    axTOCControl.HitTest(e.x, e.y, ref pItem, ref pBasicMap, ref pLayer, ref unk, ref data);                    IMap pMap = mainMapControl.ActiveView.FocusMap;                    if (pItem == esriTOCControlItem.esriTOCControlItemLayer || pLayer != null)                    {                        if (pMoveLayer != pLayer)                        {                            ILayer pTempLayer;                            //获得鼠标弹起时所在图层的索引号                            for (int i = 0; i < pMap.LayerCount; i++)                            {                                pTempLayer = pMap.get_Layer(i);                                if (pTempLayer == pLayer)                                {                                    toIndex = i;                                }                            }                        }                    }                    //移动到最前面                    else if (pItem == esriTOCControlItem.esriTOCControlItemMap)                    {                        toIndex = 0;                    }                    //移动到最后面                    else if (pItem == esriTOCControlItem.esriTOCControlItemNone)                    {                        toIndex = pMap.LayerCount - 1;                    }                    pMap.MoveLayer(pMoveLayer, toIndex);                    mainMapControl.ActiveView.Refresh();                    axTOCControl.Update();                }            }            catch (Exception ex)            {                MessageBox.Show(ex.Message);            }        }

0 0
原创粉丝点击