首页 > 其他 > 详细

组件GIS 1 地图操作

时间:2020-06-11 20:10:51      阅读:41      评论:0      收藏:0      [点我收藏+]

1.1 纲要

技术分享图片

1.2 布局

利用TabControl、ToolStrip、SplitContainer、StatusStrip控件划分菜单区、图层管理区、视图区、状态栏。再加上ArcGIS的MapControl、PageLayoutControl、TOCControl、LicenseControl。最后在Program.cs内添加Runtime许可代码ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);

利用ArcObject自带的Icon给菜单栏添加图标。

技术分享图片

1.3 文件管理

1.3.1 数据加载

axMapControl控件提供axMapControl.AddLayer(); axMapControl.AddLayerFromFile(); axMapControl.AddShapeFile();三种方法。.shp .lyr文件可以直接调用方法传入路径即可,栅格数据需要调用IRasterLayer.CreateFromFilePath(FileName); 方法获取栅格图层,然后调用axMapControl.AddLayer()即可。

加载.shp矢量数据关键代码:

if (ofdAddShp.ShowDialog() == DialogResult.OK)
{
    string[] fileName = ofdAddShp.SafeFileNames;//无路径文件名
    string path = System.IO.Path.GetDirectoryName(ofdAddShp.FileName);//得到文件夹路径
    for (int i = 0; i < fileName.Length; i++)
        axMapControl.AddShapeFile(path, fileName[i]);
}

加载栅格数据关键代码:

if (ofdAddRaster.ShowDialog() == DialogResult.OK)
{
    IRasterLayer pRasterLayer = new RasterLayerClass();
    pRasterLayer.CreateFromFilePath(ofdAddRaster.FileName);
    axMapControl.AddLayer(pRasterLayer);
}

1.3.2 地图文档的新建、打开、保存

mxd打开关键代码

if (ofdOpenMxd.ShowDialog() == DialogResult.OK)
{
    IMapDocument mapDocument = new MapDocumentClass();
    mapDocument.Open(ofdOpenMxd.FileName);
    axMapControl.Map = mapDocument.ActiveView.FocusMap;
}

mxd保存关键代码

if (pSaveFileDialog.ShowDialog() == DialogResult.OK)
{
    IMapDocument pMapDocument = new MapDocumentClass();
    pMapDocument.New(pSaveFileDialog.FileName);
    pMapDocument.ReplaceContents(axMapControl.Map as IMxdContents);
    pMapDocument.Save();
    pMapDocument.Close();
    MessageBox.Show("保存地图文档成功!");
}

1.3.3 打开数据库

首先要理解工作空间的概念,一个数据库就是一个工作空间,工作空间内存储数据集,数据集内部存储要素类、关系类、栅格数据等。

技术分享图片 技术分享图片

将打开数据库内部数据封装成一个方法:

private void AddLayersFromDataset(IWorkspace pWorkspace, AxMapControl axMapControl)
{
    try
    {
        IEnumDataset pEnumDataset = pWorkspace.get_Datasets(esriDatasetType.esriDTAny);
        pEnumDataset.Reset();
        IDataset pDataset = pEnumDataset.Next();
        while (pDataset != null)
        {
            switch (pDataset.Type)
            {
                case esriDatasetType.esriDTFeatureClass:
                    {
                        IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)pWorkspace;
                        IFeatureClass pFeaCls = pFeatureWorkspace.OpenFeatureClass(pDataset.Name);
                        IFeatureLayer pFeaLyr = new FeatureLayerClass();
                        pFeaLyr.FeatureClass = pFeaCls;
                        axMapControl.Map.AddLayer(pFeaLyr);
                    }
                    break;
                case esriDatasetType.esriDTFeatureDataset:
                    {
                        IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)pWorkspace;
                        IFeatureDataset pFeaDataset = pFeatureWorkspace.OpenFeatureDataset(pDataset.Name);
                        IEnumDataset pEnumFeatureDataset = pFeaDataset.Subsets;
                        pEnumFeatureDataset.Reset();
                        IDataset pDatasetNew = pEnumFeatureDataset.Next();
                        while (pDatasetNew != null)
                        {
                            if (pDatasetNew is IFeatureClass)
                            {
                                IFeatureClass pFeaCls = pFeatureWorkspace.OpenFeatureClass(pDatasetNew.Name);
                                IFeatureLayer pFeaLyr = new FeatureLayerClass();
                                pFeaLyr.FeatureClass = pFeaCls;
                                axMapControl.Map.AddLayer(pFeaLyr);
                            }
                            pDatasetNew = pEnumFeatureDataset.Next();
                        }
                    }
                    break;
                case esriDatasetType.esriDTRasterDataset:
                    MessageBox.Show("还没写哦!");
                    break;
                case esriDatasetType.esriDTTable:
                    MessageBox.Show("还没写哦!");
                    break;
                case esriDatasetType.esriDTTopology:
                    MessageBox.Show("还没写哦!");
                    break;
                default:
                    MessageBox.Show("还没写哦!");
                    break;
            }
            pDataset = pEnumDataset.Next();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

1.3.4 导出图片

axMapControl.ActiveView.Output()需要导出导出设备、导出分辨率、矩形范围、导出视图范围等参数,使用IExport(ESRI.ArcGIS.Output)接口。

IExport pExport = null;
if (sfdOutPicture.FileName.EndsWith(".jpg"))
    pExport = new ExportJPEGClass();
else if (sfdOutPicture.FileName.EndsWith(".png"))
    pExport = new ExportPNGClass();
else
    pExport = new ExportTIFFClass();
pExport.ExportFileName = sfdOutPicture.FileName;
pExport.Resolution = axMapControl.ActiveView.ScreenDisplay.
    DisplayTransformation.Resolution;//分辨率
tagRECT rect = axMapControl.ActiveView.ExportFrame;//矩形范围
IEnvelope pEnv = new EnvelopeClass();
pEnv.PutCoords(rect.left, rect.bottom, rect.right, rect.top);
pExport.PixelBounds = pEnv;
axMapControl.ActiveView.Output(pExport.StartExporting(),
                               (int)pExport.Resolution, ref rect,
                               axMapControl.ActiveView.Extent, null);
pExport.FinishExporting();

1.4 地图浏览

平移漫游操作:在菜单点击事件修改axMapControl.MousePointer属性,在axMapControl的鼠标按下事件内调用axMapControl.Pan();

缩放:自定义封装Tool类实现ITool和ICommad接口

历史视图:自定义封装Command类实现ICommand接口

书签:调用ArcGIS组件类库

注:ICommand实现命令,不需要与axMapControl交互;ITool需要与axMapControl交互,绑定了axMapControl的键盘、鼠标事件。

1.4.1 ICommand接口实现

以“前一视图”为例,新建一个类继承ICommand(ESRI.ArcGIS.SystemUI)接口,显式实现接口,OnCreate(object Hook)传入axMapControl控件Object属性,OnClick()实现功能,历史视图是通过IActiveView.ExtentStack视图堆栈实现的。

public void OnCreate(object Hook)
{
    hookHelper = new HookHelperClass();
    hookHelper.Hook = Hook;
    extentStack = hookHelper.ActiveView.ExtentStack;
    if (hookHelper.ActiveView == null)
        hookHelper = null;
}

public void OnClick()
{
    if (extentStack.CanUndo())
        extentStack.Undo();
    else
        enabled = false;
}

//调用
ICommand cmd = new ExtentBackCommand();
cmd.OnCreate(axMapControl.Object);
cmd.OnClick();

1.4.2 ITool接口实现

注:可以配合ICommand使用

放大功能关键代码:

public void OnMouseDown(int button, int shift, int x, int y)
{
    if (button == 2) return;
    //框选
    IEnvelope pEnv = mapControl.TrackRectangle();
    //点选
    if (pEnv.IsEmpty || pEnv.Width == 0 || pEnv.Height == 0)
    {
        pEnv = mapControl.Extent;
        pEnv.Expand(0.5, 0.5, true);
    }
    mapControl.Extent = pEnv;
    mapControl.Refresh();
}
//调用
ICommand tool = new MapZoomInTool();
tool.OnCreate(axMapControl.Object);
axMapControl.CurrentTool = tool as ITool;
axMapControl.MousePointer = esriControlsMousePointer.esriPointerZoomIn;

1.4.3 组件库类调用

"ControlXXXXX"(ESRI.ArcGIS.Controls)形式的类

1.4.4 视图同步

用IDisplayTransformation装axMapControl.Extent视图,用IObjectCopy拷贝地图

IActiveView pActiveView = (IActiveView)axPageLayoutControl.ActiveView.FocusMap;
IDisplayTransformation displayTransformation = pActiveView.ScreenDisplay.DisplayTransformation;
displayTransformation.VisibleBounds = axMapControl.Extent;
IObjectCopy pObjectCopy = new ObjectCopyClass();
object copyMap = pObjectCopy.Copy(axMapControl.Map);//复制地图到copiedMap中
object copyToMap = axPageLayoutControl.ActiveView.FocusMap;
pObjectCopy.Overwrite(copyMap, ref copyToMap); //复制地图
axPageLayoutControl.Refresh();

1.5 选择查询

“清除选择”、“定位选择”、“属性表”自己实现,其他调用组件库类。

1.5.1 定位选择

每一个要素都有Envelope属性,把选择集里面的Feature的包围盒Union起来,然后赋值给axMapControl.Extent

if (axMapControl.Map.SelectionCount == 0)
{
    MessageBox.Show("请先选择要素!", "提示");
}
else
{
    ISelection pSelection = axMapControl.Map.FeatureSelection;
    IEnumFeature pEnumFea = pSelection as IEnumFeature;
    pEnumFea.Reset();
    IFeature pFea = pEnumFea.Next();
    IEnvelope pEnv = new EnvelopeClass();
    while (pFea != null)
    {
        pEnv.Union(pFea.Extent);
        pFea = pEnumFea.Next();
    }
    axMapControl.Extent = pEnv;
    axMapControl.Refresh();
}

1.5.2 属性表

利用ListBox、ToolStrip、DataGridView完成布局,封装方法传入IMap返回结果作为ListBox的数据源,封装方法传入IFeatureLayer返回结果作为DataGridView的数据源。ListBox的SelectedIndexChanged事件中更新属性表,DataGridView的RowHeaderMouseDoubleClick事件中选中要素并定位。

private List<string> GetLayersName(IMap map)
{
    List<string> layersName = new List<string>();
    for (int i = 0; i < map.LayerCount; i++)
        layersName.Add(map.get_Layer(i).Name);
    return layersName;
}

private DataTable GetAttributeTable(IFeatureLayer pFeaLyr)
{
    DataTable pDataTable = new DataTable();
    ITable pAttributeTable = pFeaLyr.FeatureClass as ITable;
    IFields pFields = pAttributeTable.Fields;
    for (int i = 0; i < pFields.FieldCount; i++)
        pDataTable.Columns.Add(pFields.get_Field(i).Name);
    //数据源填充要素
    IFeatureCursor pFeaCur = pFeaLyr.Search(null, false);
    IFeature pFea = pFeaCur.NextFeature();
    while (pFea != null)
    {
        object[] rowValue = new object[pFields.FieldCount];
        for (int i = 0; i < pFields.FieldCount; i++)
        {
            object fieldValue;
            if (pFea.Fields.get_Field(i).Name == "Shape")
            {
                switch (pFeaLyr.FeatureClass.ShapeType)
                {
                    case esriGeometryType.esriGeometryLine:
                        fieldValue = "线";
                        break;
                    case esriGeometryType.esriGeometryPoint:
                        fieldValue = "点";
                        break;
                    case esriGeometryType.esriGeometryPolygon:
                        fieldValue = "面";
                        break;
                    case esriGeometryType.esriGeometryPolyline:
                        fieldValue = "线";
                        break;
                    default:
                        fieldValue = "未知";
                        break;
                }
            }
            else
                fieldValue = pFea.get_Value(i);
            rowValue[i] = fieldValue;
        }
        pDataTable.LoadDataRow(rowValue, true);
        pFea = pFeaCur.NextFeature();
    }
    return pDataTable;
}

技术分享图片

1.6 图层管理

1.6.1 右键菜单

添加contextMenuStrip控件,在axTOCControl的OnMouseDown事件内写代码

if (e.button == 2)//右键
{
    esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemNone;
    IBasicMap pBasicMap = null;
    ILayer pLyr = null;
    object unk = null;
    object data = null;
    axTOCControl.HitTest(e.x, e.y, ref item, ref pBasicMap, ref pLyr, ref unk, ref data);
    pFeaLyr = pLyr as IFeatureLayer;
    if (item == esriTOCControlItem.esriTOCControlItemLayer)
    {
        图层可选ToolStripMenuItem.Enabled = !pFeaLyr.Selectable;
        图层不可选ToolStripMenuItem.Enabled = pFeaLyr.Selectable;
        图层选择ToolStripMenuItem.Enabled = pFeaLyr.Selectable;
        contextMenuStrip.Show(Control.MousePosition);
    }
}

技术分享图片

1.6.2 图层选择

IFeatureSelection pFeatureSelection = pFeaLyr as IFeatureSelection;
pFeatureSelection.SelectFeatures(null, esriSelectionResultEnum.esriSelectionResultNew, false);
axMapControl.ActiveView.Refresh();

1.6.3 图层定位

将图层的“兴趣区”赋值给地图控件的视图属性,axMapControl.Extent = pFeaLyr.AreaOfInterest;

源码链接:组件GIS

组件GIS 1 地图操作

原文:https://www.cnblogs.com/liuwenzhen/p/13095610.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!