第四届全国大学生GIS应用技能大赛开发题答案(非官方)

第四届全国大学生GIS应用技能大赛开发题答案(非官方)

题目:

根据你的解决方案,开发一个应用型GIS系统,该系统需要具备加载数据、浏览数据、查询数据等基本功能,其它功能不需编写代码,但应在程序界面上体现。注:需提交GIS应用系统的源码文件和可执行应用程序。

答案:

此程序共涉及三个窗体:

在这里插入图片描述

主界面设计如下:

第四届全国大学生GIS应用技能大赛开发题答案(非官方)_第1张图片

主界面设计详情请看: https://blog.csdn.net/H48662654/article/details/102980068

主窗体代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.DataSourcesRaster;

namespace Ex2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            //获取权限
            ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);
            InitializeComponent();
            //控件绑定
            axTOCControl1.SetBuddyControl(axMapControl1);
        }
        #region 文件
		//打开文件部分详情查看:  https://blog.csdn.net/H48662654/article/details/102980563
        //定义路径为全局变量,方便后面使用
        string path = null;

        private void 打开文档ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.Title = "打开文档";
            openFileDialog1.Filter = "AceMap Document(*.mxd)|*.mxd";
            openFileDialog1.Multiselect = false;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                path = openFileDialog1.FileName;
                axMapControl1.LoadMxFile(path);
            }
            axMapControl1.Extent = axMapControl1.FullExtent;
            axMapControl1.Refresh();
        }

        //添加各种数据
        private void 添加数据ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.Title = "添加数据";
            openFileDialog1.Filter = "ShapeFiles(*.shp)|*.shp|RasterFiles(*.tif;*.img)|*.tif;*.img|Personal GeoDatabase(*.mdb)|*.mdb|LayerFile(*.lyr)|*.lyr";
            openFileDialog1.Multiselect = false;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string filePath = openFileDialog1.FileName;
                string extension = System.IO.Path.GetExtension(filePath).Replace(".", "").ToLower();
                string fileName = System.IO.Path.GetFileName(filePath);
                string directory = System.IO.Path.GetDirectoryName(filePath);
                switch(extension)
                {
                    case "shp":
                        OpenShapeFile(fileName, directory);
                        break;
                    case "mdb":
                        OpenPersoanalGDB(filePath);
                        break;
                    case "lyr":
                        OpenLayerFile(filePath);
                        break;
                    case "img":
                    case "tif":
                        OpenRasterFile(filePath);
                        break;
                    default:
                        MessageBox.Show("Error");
                        return;
                }
            }
        }

        private void OpenShapeFile(string fileName, string directory)
        {
            //打开工作空间
            IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactory();
            IFeatureWorkspace featureWorkspace = workspaceFactory.OpenFromFile(directory,0) as IFeatureWorkspace;
            IFeatureClass featureClass = featureWorkspace.OpenFeatureClass(fileName);
            IFeatureLayer layer = new FeatureLayerClass();
            //添加图层
            layer.FeatureClass = featureClass;
            layer.Name = featureClass.AliasName;
            axMapControl1.AddLayer(layer);
            axMapControl1.Refresh();
            axTOCControl1.Update();
            //最近找到一种更简单的方法, 如下
            //axMapControl1.AddShapeFile(directory, fileName);
        }
        private void OpenPersoanalGDB(string path)
        {
            IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactoryClass();
            IWorkspace workspace = workspaceFactory.OpenFromFile(path,0);
            //获取数据集,注意种类
            IEnumDataset enumFeatureClass = workspace.get_Datasets(esriDatasetType.esriDTFeatureClass);
            //循环添加图层
            IFeatureClass featureClass = enumFeatureClass.Next() as IFeatureClass;
            while (featureClass != null)
            {
                IFeatureLayer layer = new FeatureLayerClass();
                layer.FeatureClass = featureClass;
                layer.Name = featureClass.AliasName;
                axMapControl1.AddLayer(layer);
                featureClass = enumFeatureClass.Next() as IFeatureClass; ;
            }
            axMapControl1.Refresh();
            axTOCControl1.Update();
        }
        private void OpenLayerFile(string path)
        {
            axMapControl1.AddLayerFromFile(path);
            axMapControl1.Refresh();
            axTOCControl1.Update();
        }
        private void OpenRasterFile(string path)
        {
            IRasterLayer layer = new RasterLayerClass();
            layer.CreateFromFilePath(path);
            axMapControl1.AddLayer(layer);
            axMapControl1.Refresh();
            axTOCControl1.Update();
        }

        //保存文件部分查看: https://blog.csdn.net/H48662654/article/details/102981909
        private void 保存文档ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (path != null)
            {
                IMxdContents contexts = axMapControl1.Map as IMxdContents;
                IMapDocument mapDocument = new MapDocumentClass();
                mapDocument.Open(path);
                mapDocument.ReplaceContents(contexts);
                mapDocument.Save();
                MessageBox.Show("保存成功");
            }
            else
            {
                SaveAs();
            }
            
        }
        private void SaveAs()
        {
            openFileDialog1.Title = "保存文档";
            openFileDialog1.Filter = "ArcMap Document(*.mxd)|*.mxd";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                IMxdContents contexts = axMapControl1.Map as IMxdContents;
                IMapDocument mapDocument = new MapDocumentClass();
                mapDocument.New(openFileDialog1.FileName);
                mapDocument.ReplaceContents(contexts);
                mapDocument.Save();
                MessageBox.Show("保存成功");
            }
        }

        private void 导出图片ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //建议查看参考文档
            saveFileDialog1.Title = "导出图片";
            saveFileDialog1.Filter = "JPEG(*.jpg)|*.jpg|PDF(*.pdf)|*.pdf|PNG(*.png)|*.png|BMP(*.bmp)|*.bmp";
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string filePath = saveFileDialog1.FileName;
                string extension = System.IO.Path.GetExtension(filePath).Replace(".", "").ToLower();
                IExport export = new ExportAIClass();
                switch (extension)
                {
                    case "jpg":
                        export = new ExportJPEGClass();
                        break;
                    case "pdf":
                        export = new ExportPDFClass();
                        break;
                    case "png":
                        export = new ExportPNGClass();
                        break;
                    case "bmp":
                        export = new ExportBMPClass();
                        break;
                    default:
                        MessageBox.Show("Error");
                        return;
                }
                if(ExportImage(export,filePath))
                {
                    MessageBox.Show("导出成功");
                }
                else
                {
                    MessageBox.Show("导出失败");
                }
            }
        }
        private bool ExportImage(IExport export, string pathFileName)
        {
            export.ExportFileName = pathFileName;
            IActiveView activeView = axMapControl1.ActiveView;
            // Microsoft Windows default DPI resolution
            export.Resolution = 96;
            tagRECT exportRECT = activeView.ExportFrame;
            ESRI.ArcGIS.Geometry.IEnvelope envelope = new ESRI.ArcGIS.Geometry.EnvelopeClass();
            envelope.PutCoords(exportRECT.left, exportRECT.top, exportRECT.right, exportRECT.bottom);
            export.PixelBounds = envelope;
            System.Int32 hDC = export.StartExporting();
            activeView.Output(hDC, (System.Int16)export.Resolution, ref exportRECT, null, null);

            // Finish writing the export file and cleanup any intermediate files
            export.FinishExporting();
            export.Cleanup();

            return true;
        }
        #endregion

        #region 地图浏览
            
        //地图浏览和鹰眼部分查看:https://blog.csdn.net/H48662654/article/details/102980829
        private void 放大ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (axMapControl1.CurrentTool == null)
            {
                ICommand icc;
                ITool tool = new ControlsMapZoomInToolClass();
                axMapControl1.CurrentTool = tool;
                icc = tool as ICommand;
                icc.OnCreate(axMapControl1.Object);
                icc.OnClick();
            }
            else
            {
                axMapControl1.CurrentTool = null;
            }
        }

        private void 缩小ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (axMapControl1.CurrentTool == null)
            {
                ICommand icc;
                ITool tool = new ControlsMapZoomOutToolClass();
                axMapControl1.CurrentTool = tool;
                icc = tool as ICommand;
                icc.OnCreate(axMapControl1.Object);
                icc.OnClick();
            }
            else
            {
                axMapControl1.CurrentTool = null;
            }
        }

        private void 漫游ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (axMapControl1.CurrentTool == null)
            {
                ICommand icc;
                ITool tool = new ControlsMapPanToolClass();
                axMapControl1.CurrentTool = tool;
                icc = tool as ICommand;
                icc.OnCreate(axMapControl1.Object);
                icc.OnClick();
            }
            else
            {
                axMapControl1.CurrentTool = null;
            }
        }

        private void 全局ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ICommand icc = new ControlsMapFullExtentCommandClass();
            icc.OnCreate(axMapControl1.Object);
            icc.OnClick();
        }

        private void 指针ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            axMapControl1.CurrentTool = null;
        }


        //鹰眼
        private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
        {
            axMapControl2.ClearLayers();
            if (axMapControl1.Map.LayerCount != 0)
            {
                for (int i = axMapControl1.Map.LayerCount - 1; i >= 0; i--)
                {
                    ILayer layer = axMapControl1.get_Layer(i);
                    IObjectCopy copy = new ObjectCopyClass();
                    ILayer layerCopy = copy.Copy(layer) as ILayer;
                    axMapControl2.AddLayer(layerCopy);
                }
                axMapControl2.SpatialReference = axMapControl1.SpatialReference;
                axMapControl2.Extent = axMapControl1.FullExtent;
                axMapControl2.Refresh();
            }
        }

        private void axMapControl1_OnExtentUpdated(object sender, IMapControlEvents2_OnExtentUpdatedEvent e)
        {
            IEnvelope env = axMapControl1.Extent;
            IElement element = new RectangleElementClass();
            element.Geometry = env;
            ISimpleLineSymbol lineSymbol = new SimpleLineSymbolClass();
            IRgbColor color1 = new RgbColorClass();
            color1.Red = 255;
            color1.Green = 0;
            color1.Blue = 0;
            color1.Transparency = 255;
            lineSymbol.Color = color1;
            lineSymbol.Width = 2;
            ISimpleFillSymbol fillSymbol = new SimpleFillSymbolClass();
            IRgbColor color2 = new RgbColorClass();
            color2.Red = 255;
            color2.Green = 0;
            color2.Blue = 0;
            color2.Transparency = 0;
            fillSymbol.Color = color2;
            fillSymbol.Outline = lineSymbol;
            IFillShapeElement ele = element as IFillShapeElement;
            ele.Symbol = fillSymbol;
            IGraphicsContainer gra = axMapControl2.ActiveView.FocusMap as IGraphicsContainer;
            gra.DeleteAllElements();
            gra.AddElement(ele as IElement, 0);
            axMapControl2.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
        }

        private void axMapControl2_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            if (e.button == 1)
            {
                IPoint pt = new PointClass();
                pt.PutCoords(e.mapX, e.mapY);
                axMapControl1.CenterAt(pt);
                axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
            }
            else
            {
                IEnvelope env = axMapControl2.TrackRectangle();
                axMapControl1.Extent = env;
                axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
            }
        }

        private void axMapControl2_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
        {
            if (e.button == 1)
            {
                IPoint pt = new PointClass();
                pt.PutCoords(e.mapX, e.mapY);
                axMapControl1.CenterAt(pt);
                axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
            }
        }
        #endregion
        #region 属性查询
        
        //通过图层名获取地图上的对应图层
        private IFeatureLayer GetLayerByName(string name)
        {
            ILayer layer;
            for (int i = 0; i < axMapControl1.LayerCount; i++)
            {
                layer = axMapControl1.get_Layer(i);
                if (layer.Name.Equals(name))
                {
                    return layer as IFeatureLayer;
                }
            }
            return null;
        }

        private void 查询对话框ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            查询对话框 search = new 查询对话框(axMapControl1);
            //当在查询对话框中点击 “查询” 按钮
            if (search.ShowDialog() == DialogResult.OK)
            {
                //清除选择
                axMapControl1.Map.ClearSelection();
                //获取用户输入的查询条件(图层,字段,值)
                string[] value = search.Value;
                //根据条件获取图层和字段
                IFeatureLayer layer = GetLayerByName(value[0]);
                IField field = layer.FeatureClass.Fields.get_Field(layer.FeatureClass.Fields.FindField(value[1]));
                IQueryFilter filter = new QueryFilterClass();
                string whereClause = "";
                //根据查询的字段类型确定查询语句
                switch (field.Type)
                {
                        //文本类型支持模糊查询
                    case esriFieldType.esriFieldTypeString:
                        whereClause += field.Name + " LIKE " + "'" + value[2] + "'";
                        break;
                        //数值类型支持精确查询
                    case esriFieldType.esriFieldTypeSingle:
                    case esriFieldType.esriFieldTypeSmallInteger:
                    case esriFieldType.esriFieldTypeInteger:
                    case esriFieldType.esriFieldTypeDouble:
                        whereClause += field.Name + " = " + value[2];
                        break;
                    default:
                        MessageBox.Show("Error");
                        return;
                }
                filter.WhereClause = whereClause;
                //高亮选择
                IFeatureSelection featureSelection = layer as IFeatureSelection;
                featureSelection.SelectFeatures(filter, esriSelectionResultEnum.esriSelectionResultNew, false);
                axMapControl1.Refresh();
                ISelectionSet set = featureSelection.SelectionSet;
                IEnumIDs ids = set.IDs;
                //将选中的要素ID传给属性表的构造函数,显示属性
                属性表 attribute = new 属性表(ids,layer,axMapControl1.ActiveView);
                attribute.Show();
            }
        }

        private void 清除选择ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            axMapControl1.Map.ClearSelection();
        }
        
        #endregion
            
        #region 右击图层显示属性
        ILayer layer3 = null;
        private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
        {
            if (e.button == 2)//右键
            {
                //查看帮助文档有关HitTest方法的用法
                IBasicMap map = new MapClass();
                object unk = null;
                object data = null;
                esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemLayer;
                axTOCControl1.HitTest(e.x, e.y, ref item, ref map, ref layer3, ref unk, ref data);
                if (item == esriTOCControlItem.esriTOCControlItemLayer)
                {
                    contextMenuStrip1.Show(axTOCControl1, e.x, e.y);
                }
            }
        }
        #endregion

        private void 打开属性表ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //获取ID方便调用同一个构造函数
            IFeatureLayer layer4 = layer3 as IFeatureLayer;
           IFeatureSelection selection = layer4 as IFeatureSelection;
            selection.SelectFeatures(null, esriSelectionResultEnum.esriSelectionResultNew,false);
            ISelectionSet set = selection.SelectionSet;
            IEnumIDs ids = set.IDs;
            属性表 att = new 属性表(ids, layer4, axMapControl1.ActiveView);
            att.Show();
            selection.Clear();
        }
    }
}

属性表界面:

第四届全国大学生GIS应用技能大赛开发题答案(非官方)_第2张图片
属性表窗体代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;

namespace Ex2
{
    public partial class 属性表 : Form
    {
        IEnumIDs ids;
        IFeatureLayer layer;
        IActiveView act;
        public 属性表(IEnumIDs ids,IFeatureLayer layer,IActiveView act)
        {
            InitializeComponent();
            this.ids = ids;
            this.layer = layer;
            this.act = act;
        }

        //加载属性表
        private void 属性表_Load(object sender, EventArgs e)
        {
            IFeatureClass featureClass = layer.FeatureClass;
            int id = ids.Next();
            DataTable dt = new DataTable();
            DataColumn dc;
            //构造表的 列
            for (int i = 0; i < featureClass.Fields.FieldCount; i++)
            {
                dc = new DataColumn(featureClass.Fields.get_Field(i).Name);
                dt.Columns.Add(dc);
            }
            Application.UseWaitCursor = true;
            //添加每一行的数据
            while (id != -1)
            {
                IFeature feature = featureClass.GetFeature(id);
                DataRow dr = dt.NewRow();
                for (int i = 0; i < feature.Fields.FieldCount; i++)
                {
                    如果是Shape字段则需判断类型后赋值
                    if (feature.Fields.get_Field(i).Name.Equals("Shape"))
                    {
                        switch (feature.Shape.GeometryType)
                        {
                            case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
                                dr[i] = "Point";
                                break;
                            case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon:
                                dr[i] = "polygon";
                                break;
                            case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline:
                                dr[i] = "Polyline";
                                break;
                            default:
                                dr[i] = "Other";
                                break;
                        }
                        continue;
                    }
                    //其他直接赋值
                    dr[i] = feature.get_Value(i).ToString();
                }
                dt.Rows.Add(dr);
                id = ids.Next();
            }
            dataGridView1.DataSource = dt;
            Application.UseWaitCursor = false;
        }

        //双击表头缩放到该要素
        private void dataGridView1_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            //获取点击的行号,通过行号获取要素ID
            int i = e.RowIndex;
            int n = Convert.ToInt16(dataGridView1.Rows[i].Cells[0].Value);
            //通过ID获取要素
            IFeatureClass featureClass = layer.FeatureClass;
            IFeature feature = featureClass.GetFeature(n);
            IEnvelope env = new EnvelopeClass();
            IPoint pt = new PointClass();
            IGeometry geo = feature.Shape;
            IGeometry5 geo5 = geo as IGeometry5;
            //获取要素的坐标
            pt.X = geo5.CentroidEx.X;
            pt.Y = geo5.CentroidEx.Y;
            //以要素坐标为基础构造一个包络线
            env.XMax = pt.X + 15;
            env.XMin = pt.X - 15;
            env.YMax = pt.Y + 15;
            env.YMin = pt.Y - 15;
            env.CenterAt(pt);
            env.Expand(15, 15, false);
            //将地图的视图设置为包络线,即放缩到该要素
            act.Extent = env;
            act.Refresh();
        }
    }
}

查询对话框界面:

第四届全国大学生GIS应用技能大赛开发题答案(非官方)_第3张图片

查询对话框窗体代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;

namespace Ex2
{
    public partial class 查询对话框 : Form
    {
        AxMapControl map;
        //用来存储查询条件
        private string[] value;
        public string[] Value
        {
            get
            {
                return value;
            }
        }
        public 查询对话框(AxMapControl map)
        {
            InitializeComponent();
            this.map = map;
            value = new string[3];
        }

        private void 查询对话框_Load(object sender, EventArgs e)
        {
            //将地图中所有矢量图层添加进ComboBox1
            for (int i = 0; i < map.LayerCount; i++)
            {
                ILayer layer = map.get_Layer(i);
                if(layer is IFeatureLayer)//判断是否为矢量图层
                {
                    comboBox1.Items.Add(layer.Name.ToString());
                }
            }
            comboBox1.SelectedIndex = 0;
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            //将选中图层所有文本型和数值型字段添加到ComboBox2
            comboBox2.Items.Clear();
            IFeatureLayer layer1 = map.get_Layer(comboBox1.SelectedIndex) as IFeatureLayer;
            IFeatureClass featureClass = layer1.FeatureClass;
            for (int i = 0; i < featureClass.Fields.FieldCount; i++)
            {
                IField field = featureClass.Fields.get_Field(i);
                //判断类型
                if (field.Type == esriFieldType.esriFieldTypeDouble || field.Type == esriFieldType.esriFieldTypeInteger || field.Type == esriFieldType.esriFieldTypeString||field.Type== esriFieldType.esriFieldTypeSmallInteger||field.Type == esriFieldType.esriFieldTypeSingle)
                {
                    comboBox2.Items.Add(field.Name.ToString());
                }
            }
            comboBox2.SelectedIndex = 0;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //点击查询  赋值查询条件
            value[0] = comboBox1.SelectedItem.ToString();
            value[1] = comboBox2.SelectedItem.ToString();
            value[2] = textBox1.Text;
            this.DialogResult = DialogResult.OK;
        }
    }
}

历届GIS应用技能大赛开发题答案点这里,尚在不定期更新中

你可能感兴趣的:(ArcGIS二次开发,AE+C#)