利用TabControl、ToolStrip、SplitContainer、StatusStrip控件划分菜单区、图层管理区、视图区、状态栏。再加上ArcGIS的MapControl、PageLayoutControl、TOCControl、LicenseControl。最后在Program.cs内添加Runtime许可代码ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);
利用ArcObject自带的Icon给菜单栏添加图标。
axMapControl控件提供axMapControl.AddLayer(); axMapControl.AddLayerFromFile(); axMapControl.AddShapeFile();三种方法。.shp .lyr文件可以直接调用方法传入路径即可,栅格数据需要调用IRasterLayer.CreateFromFilePath(FileName); 方法获取栅格图层,然后调用axMapControl.AddLayer()即可。
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);
}
if (ofdOpenMxd.ShowDialog() == DialogResult.OK)
{
IMapDocument mapDocument = new MapDocumentClass();
mapDocument.Open(ofdOpenMxd.FileName);
axMapControl.Map = mapDocument.ActiveView.FocusMap;
}
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("保存地图文档成功!");
}
首先要理解工作空间的概念,一个数据库就是一个工作空间,工作空间内存储数据集,数据集内部存储要素类、关系类、栅格数据等。
![]() |
![]() |
将打开数据库内部数据封装成一个方法:
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());
}
}
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();
平移漫游操作:在菜单点击事件修改axMapControl.MousePointer属性,在axMapControl的鼠标按下事件内调用axMapControl.Pan();
缩放:自定义封装Tool类实现ITool和ICommad接口
历史视图:自定义封装Command类实现ICommand接口
书签:调用ArcGIS组件类库
注:ICommand实现命令,不需要与axMapControl交互;ITool需要与axMapControl交互,绑定了axMapControl的键盘、鼠标事件。
以“前一视图”为例,新建一个类继承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();
注:可以配合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;
"ControlXXXXX"(ESRI.ArcGIS.Controls)形式的类
用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();
“清除选择”、“定位选择”、“属性表”自己实现,其他调用组件库类。
每一个要素都有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();
}
利用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;
}
添加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);
}
}
IFeatureSelection pFeatureSelection = pFeaLyr as IFeatureSelection;
pFeatureSelection.SelectFeatures(null, esriSelectionResultEnum.esriSelectionResultNew, false);
axMapControl.ActiveView.Refresh();
将图层的“兴趣区”赋值给地图控件的视图属性,axMapControl.Extent = pFeaLyr.AreaOfInterest;
源码链接:组件GIS
原文:https://www.cnblogs.com/liuwenzhen/p/13095610.html