Winform+ArcEngine二次开发学习笔记
ArcEngine二次开发
初识ArcEngine,个人笔记留档
引入主程序
//表示绑定的arcgis产品类型,即绑定arcgis engine。
ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);
文件操作
加载文件进MapDocument
private IMapDocument pMapDocument;
private bool GetMapDocument(string type)
{
bool flag = false;
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = type;
if (ofd.ShowDialog() == DialogResult.OK)
{
pMapDocument = new MapDocument();
pMapDocument.Open(ofd.FileName);
flag = true;
}
return flag;
}
在AxMapControl控件中打开地图文件
public void OpenFile(AxMapControl axMapControl, string type)
{
if (GetMapDocument(type))
{
for (int i = 0; i < pMapDocument.MapCount; i++)
{
axMapControl.Map = pMapDocument.get_Map(i);
}
axMapControl.Refresh();
}
}
保存文件
public void SaveDocument()
{
try
{
pMapDocument.Save(true);
MessageBox.Show("保存成功", "提示");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
另存文件
public void SaveAsDocunemt(string type)
{
SaveFileDialog pSaveFileDialog = new SaveFileDialog();
pSaveFileDialog.Title = "请选择另存路径";
pSaveFileDialog.Filter = "mxd|*.mxd";
if (pSaveFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
pMapDocument.SaveAs(pSaveFileDialog.FileName);
MessageBox.Show("另存文件成功!");
}
catch (Exception e)
{
MessageBox.Show("文件保存异常" + e.Message);
Console.WriteLine(e);
}
}
}
基础功能
放大
ICommand pCommand = new ControlsMapZoomInTool();
ITool pTool = pCommand as ITool;
pCommand.OnCreate(axMapControl1.Object);
axMapControl1.CurrentTool = pTool;
缩小
ICommand pCommand = new ControlsMapZoomOutTool();
ITool pTool = pCommand as ITool;
pCommand.OnCreate(axMapControl1.Object);
axMapControl1.CurrentTool = pTool;
漫游
ICommand pCommand = new ControlsMapPanTool();
ITool pTool = pCommand as ITool;
pCommand.OnCreate(axMapControl1.Object);
axMapControl1.CurrentTool = pTool;
其他方法
//配合AxMapControl点击事件
axMapControl1.Pan();
全图
ICommand pCommand = new ControlsMapFullExtentCommand();
pCommand.OnCreate(axMapControl1.Object);
pCommand.OnClick();
其他方法
axMapControl1.Extent = axMapControl1.FullExtent;
清除选中
ICommand pCommand = new ControlsClearSelectionCommand();
pCommand.OnCreate(axMapControl1.Object);
pCommand.OnClick();
点选
pPoint = axMapControl1.ToMapPoint(e.x, e.y);
axMapControl1.Map.SelectByShape(pPoint, null, false);
axMapControl1.Refresh();
框选
IMap pMap = axMapControl.Map;
IActiveView pActiveView = pMap as IActiveView;
IEnvelope pEnv = axMapControl.TrackRectangle();
pMap.SelectByShape(pEnv, null, false);
pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
多边形选
pPolygon = axMapControl.TrackPolygon() as IPolygon;
axMapControl.Map.SelectByShape(pPolygon, null, false);
axMapControl.Refresh();
获取地图中文单位
public static string GetMapUnits(esriUnits esriUnits)
{
string MapUnits = "";
switch (esriUnits)
{
case esriUnits.esriUnknownUnits:
MapUnits = "未知单位";
break;
case esriUnits.esriInches:
MapUnits = "英寸";
break;
case esriUnits.esriPoints:
MapUnits = "点";
break;
case esriUnits.esriFeet:
MapUnits = "尺";
break;
case esriUnits.esriYards:
MapUnits = "码";
break;
case esriUnits.esriMiles:
MapUnits = "万里";
break;
case esriUnits.esriNauticalMiles:
MapUnits = "海里";
break;
case esriUnits.esriMillimeters:
MapUnits = "毫米";
break;
case esriUnits.esriCentimeters:
MapUnits = "厘米";
break;
case esriUnits.esriMeters:
MapUnits = "米";
break;
case esriUnits.esriKilometers:
MapUnits = "公里";
break;
case esriUnits.esriDecimalDegrees:
MapUnits = "十进制";
break;
case esriUnits.esriDecimeters:
MapUnits = "分米";
break;
case esriUnits.esriUnitsLast:
MapUnits = "UnitsLast";
break;
}
return MapUnits;
}
传入几何对象,返回带样式的ISymbol
public ISymbol GetSymbolByShape(IGeometry pGeometry)
{
//esriGeometryType通常用来表示数据的几何形状,即表现层。
//https://blog.csdn.net/u011170962/article/details/38562841?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163827147616780366519005%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163827147616780366519005&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-38562841.first_rank_v2_pc_rank_v29&utm_term=GeometryType&spm=1018.2226.3001.4187
ISymbol pSymbol = null;
ISimpleFillSymbol pSimpleFillSymbol = null;
ISimpleLineSymbol pSimpleLineSymbol = null;
ISimpleMarkerSymbol pSimpleMarkerSymbol = null;
switch (pGeometry.GeometryType)
{
//未知类型(Unknown)
case esriGeometryType.esriGeometryNull:
break;
//点(Point)
case esriGeometryType.esriGeometryPoint:
pSimpleMarkerSymbol = new SimpleMarkerSymbol() { Color = GetRgbColor(255, 0, 0), Style = esriSimpleMarkerStyle.esriSMSCircle };
pSymbol = pSimpleMarkerSymbol as ISymbol;
break;
//多点(Multipoint)
case esriGeometryType.esriGeometryMultipoint:
break;
//线段(Line)
case esriGeometryType.esriGeometryLine:
pSimpleLineSymbol = new SimpleLineSymbol() { Color = GetRgbColor(255, 0, 0), Width = 4 };
pSymbol = pSimpleLineSymbol as ISymbol;
break;
//圆弧(CircularArc)
case esriGeometryType.esriGeometryCircularArc:
break;
//椭圆弧(EllipticArc)
case esriGeometryType.esriGeometryEllipticArc:
break;
//贝兹曲线(BezierCurve)
case esriGeometryType.esriGeometryBezier3Curve:
break;
//路径(Path)
case esriGeometryType.esriGeometryPath:
break;
//多段线(Polyline)
case esriGeometryType.esriGeometryPolyline:
break;
//环(Ring)
case esriGeometryType.esriGeometryRing:
break;
//多边形(Polygon)
case esriGeometryType.esriGeometryPolygon:
//简单填充符号
pSimpleFillSymbol = new SimpleFillSymbol();
//设置颜色
pSimpleFillSymbol.Color = GetRgbColor(255, 0, 0);
//设置样式
pSimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSSolid;
pSymbol = pSimpleFillSymbol as ISymbol;
break;
//外包(Envelope)包络线
case esriGeometryType.esriGeometryEnvelope:
//用来作图案边框
pSimpleLineSymbol = new SimpleLineSymbol()
{
Color = GetRgbColor(255, 0, 0),
Width = 1
};
//填充符号
pSimpleFillSymbol = new SimpleFillSymbol()
{
Color = GetRgbColor(255, 255, 255, 0),
Outline = pSimpleLineSymbol,//设置边框
Style = esriSimpleFillStyle.esriSFSDiagonalCross
};
pSymbol = pSimpleFillSymbol as ISymbol;
break;
//任何类型(Any valid geometry)
case esriGeometryType.esriGeometryAny:
break;
//任意几何类型的集合(GeometryBag)
case esriGeometryType.esriGeometryBag:
break;
//表面几何(MultiPatch)
case esriGeometryType.esriGeometryMultiPatch:
break;
//三角带(TriangleStrip)
case esriGeometryType.esriGeometryTriangleStrip:
break;
//三角扇形(TriangleFan)
case esriGeometryType.esriGeometryTriangleFan:
break;
//射线(Ray)
case esriGeometryType.esriGeometryRay:
break;
//球体(Sphere)
case esriGeometryType.esriGeometrySphere:
break;
//三角形(Triangles)
case esriGeometryType.esriGeometryTriangles:
break;
default:
throw new ArgumentOutOfRangeException();
}
return pSymbol;
}
简单绘图
axMapControl1.DrawShape(pPoint as IGeometry, ref obj);//暂存,屏幕不能刷新,一般用在查询
绘制点
//新建点
IPoint pPoint = new Point();
pPoint.X = e.mapX;
pPoint.Y = e.mapY;
//设置点样式
ISimpleMarkerSymbol pSimpleMarkerSymbol = new SimpleMarkerSymbol();
pSimpleMarkerSymbol.Color = new RgbColor() { Red = 255, Green = 5, Blue = 6 };
pSimpleMarkerSymbol.Size = 5;
pSimpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
ISymbol pSymbol = pSimpleMarkerSymbol as ISymbol;
object obj = pSymbol;
axMapControl1.DrawShape(pPoint as IGeometry, ref obj);//在mapControl上绘制点,暂存
break;
绘制线
IPolyline pLine = axMapControl1.TrackLine() as IPolyline;
SimpleLineSymbol pSimpleLineSymbol = new SimpleLineSymbol();
pSimpleLineSymbol.Color = new RgbColor() { Red = 255, Green = 5, Blue = 6 };
pSimpleLineSymbol.Style = esriSimpleLineStyle.esriSLSSolid;
object pSymbolLine = pSimpleLineSymbol as ISymbol as object;
axMapControl1.DrawShape(pLine as IGeometry, ref pSymbolLine);
绘制多边形
绘制矩形
查询
简单查询
public static void AttrSearch1(AxMapControl axMapControl1, int layerid, string sql)
{
//获取查询的图层
ILayer pLayer = axMapControl1.Map.get_Layer(layerid);
//要素图层
IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer;
//要素类
IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass as IFeatureClass;
//定义过滤器
IQueryFilter pQueryFilter = new QueryFilter();
//在过滤器设定属性条件
pQueryFilter.WhereClause = sql;
//要素游标
IFeatureCursor pFeatureCursor = pFeatureClass.Search(pQueryFilter, true);
//要素(找到第一个要素)
IFeature pFeature = pFeatureCursor.NextFeature();
while (pFeature != null)
{
//axMapControl1.FlashShape(pFeature.Shape);
//pFeature = pFeatureCursor.NextFeature(); //选择下一个要素
ISymbol pSymbol;
IGeometry pGeometry = pFeature.Shape;
pSymbol = GetSymbol(pGeometry);
object obj;
obj = pSymbol;
axMapControl1.FlashShape(pGeometry, 10, 30, obj);
axMapControl1.Map.SelectFeature(pLayer, pFeature);
axMapControl1.Refresh();
pFeature = pFeatureCursor.NextFeature();
}
}
复杂查询
可以在查询结果加样式,进行二次查询
public static void AttSearch2(AxMapControl axMapControl1, int layerid, string sql)
{
ILayer player = axMapControl1.get_Layer(layerid);
IFeatureLayer pFeatureLayer = player as FeatureLayer;
IQueryFilter pQueryFilter = new QueryFilter();
pQueryFilter.WhereClause = sql;
//IFeatureSelections
IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
//一次查询
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
pFeatureSelection.SelectionColor = new RgbColor(){Blue = 255,};
//结果集
ISelectionSet pSelectionSet = pFeatureSelection.SelectionSet;
//游标
ICursor pCursor = null;
//二次查询
pSelectionSet.Search(null, true, out pCursor);
//要素游标
IFeatureCursor pFeatureCursor = pCursor as IFeatureCursor;
//要素
IFeature pFeature = pFeatureCursor.NextFeature();
while (pFeature != null)
{
ISymbol pSymbol;
IGeometry pGeometry = pFeature.Shape;
pSymbol = GetSymbol(pGeometry);
object obj;
obj = pSymbol;
axMapControl1.FlashShape(pGeometry, 10, 30, obj);
axMapControl1.Map.SelectFeature(player, pFeature);
axMapControl1.Refresh();
pFeature = pFeatureCursor.NextFeature();
}
}
空间查询
几何图形作为条件进行查询
public static void AttSearch2(AxMapControl axMapControl1, int layerid, string sql)
{
ILayer player = axMapControl1.get_Layer(layerid);
IFeatureLayer pFeatureLayer = player as FeatureLayer;
IQueryFilter pQueryFilter = new QueryFilter();
pQueryFilter.WhereClause = sql;
//IFeatureSelections
IFeatureSelection pFeatureSelection = pFeatureLayer as IFeatureSelection;
//一次查询
pFeatureSelection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
pFeatureSelection.SelectionColor = new RgbColor()
{
Blue = 255,
};
//结果集
ISelectionSet pSelectionSet = pFeatureSelection.SelectionSet;
//游标
ICursor pCursor = null;
//二次查询
pSelectionSet.Search(null, true, out pCursor);
//要素游标
IFeatureCursor pFeatureCursor = pCursor as IFeatureCursor;
//要素
IFeature pFeature = pFeatureCursor.NextFeature();
while (pFeature != null)
{
ISymbol pSymbol;
IGeometry pGeometry = pFeature.Shape;
pSymbol = GetSymbol(pGeometry);
object obj;
obj = pSymbol;
axMapControl1.FlashShape(pGeometry, 10, 30, obj);
axMapControl1.Map.SelectFeature(player, pFeature);
axMapControl1.Refresh();
pFeature = pFeatureCursor.NextFeature();
}
}
识别查询
public static void Identify(AxMapControl axMapControl, IGeometry geometry, int layerId, DataGridView dgv)
{
ILayer pLayer = axMapControl.get_Layer(layerId);
IIdentify pIdentify = pLayer as IIdentify;
IArray pArray = pIdentify.Identify(geometry);
DataTable dt = new DataTable();
dt.Columns.Add("名称");
dt.Columns.Add("面积");
IIdentifyObj pIdentifyObj;
if (pArray != null)
{
for (int i = 0; i < pArray.Count; i++)
{
pIdentifyObj = pArray.get_Element(i);
//pIdentifyObj.Flash(axMapControl.ActiveView.ScreenDisplay);
IRowIdentifyObject pRowIdentifyObject = pIdentifyObj as IRowIdentifyObject;
IFeature pFeature = pRowIdentifyObject.Row as IFeature;
DataRow dr = dt.NewRow();
dr["名称"] = pFeature.get_Value(pFeature.Fields.FindField("NAME"));
dr["面积"] = pFeature.get_Value(pFeature.Fields.FindField("面积"));
dt.Rows.Add(dr);
}
dgv.DataSource = dt;
}
else
{
MessageBox.Show("查询结果为空");
}
}
容器绘图
图形可以保存,*mxd
1
构建几何图形
2
几何图形添加符号ISymbol样式、颜色、大小、宽度、边框(对象)
3
IGrahpicsContainer.AddElement();
绘点
case "绘点":
//设置容器
IGraphicsContainer pGraphicsContainer = axMapControl1.Map as IGraphicsContainer;
//造点
IPoint pPoint = new ESRI.ArcGIS.Geometry.Point();
pPoint.X = e.mapX;
pPoint.Y = e.mapY;
//点元素
IMarkerElement pMarkerElement = new MarkerElement() as IMarkerElement;
pMarkerElement.Symbol = Tool.GetSymbol(pPoint as IGeometry) as IMarkerSymbol;
//定义元素接口
pElement = pMarkerElement as IElement;
pElement.Geometry = pPoint as IGeometry;
//绘图
pGraphicsContainer.AddElement(pElement, 0);
axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
break;
绘线
case "绘线":
//设置容器
pGraphicsContainer = axMapControl1.Map as IGraphicsContainer;
//造几何线
pPolyline = axMapControl1.TrackLine() as IPolyline;
//线元素
ILineElement pLineElement = new LineElement() as ILineElement;
//线符号
pLineElement.Symbol = Tool.GetSymbol(pPolyline as IGeometry) as ILineSymbol;
//定义元素接口
pElement = pLineElement as IElement;
pElement.Geometry = pPolyline as IGeometry;
//绘图
pGraphicsContainer.AddElement(pElement, 0);
axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
break;
绘矩形
case "矩形":
pGraphicsContainer = axMapControl1.Map as IGraphicsContainer;
pEnvelope = axMapControl1.TrackRectangle() as IEnvelope;
IRectangleElement pRectangleElement = new RectangleElement() as IRectangleElement;
pFillShapeElement = pRectangleElement as IFillShapeElement;
pFillShapeElement.Symbol = Tool.GetSymbol(pEnvelope as IGeometry) as IFillSymbol;
pElement = pRectangleElement as IElement;
pElement.Geometry = pEnvelope as IGeometry;
pGraphicsContainer.AddElement(pElement, 0);
axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
break;
绘多边形
case "多边形":
pGraphicsContainer = axMapControl1.Map as IGraphicsContainer;
pPolygon = axMapControl1.TrackPolygon() as IPolygon;
//pPolygon = new PolygonElement() as IPolygon;
IPolygonElement pPolygonElement = new PolygonElement() as IPolygonElement;
pFillShapeElement = pPolygonElement as IFillShapeElement;
pFillShapeElement.Symbol = Tool.GetSymbol(pPolygon as IGeometry) as IFillSymbol;
pElement = pFillShapeElement as IElement;
pElement.Geometry = pPolygon as IGeometry;
pGraphicsContainer.AddElement(pElement, 0);
axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
break;
鹰眼
围绕比例尺、AxMapControl视野变化,实现类似游戏中小地图的功能
private void Form3_Load(object sender, EventArgs e)
{
//禁止滚轮,使小地图比例固定
axMapControl2.AutoMouseWheel = false;
}
//主地图Map发生变化时候
private void axMapControl1_OnMapReplaced(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMapReplacedEvent e)
{
//倒序加载图层
for (int i = axMapControl1.LayerCount - 1; i >= 0; i--)
{
axMapControl2.AddLayer(axMapControl1.get_Layer(i));
}
//鹰眼永远保持全图
axMapControl2.Extent = axMapControl1.FullExtent;
axMapControl2.Refresh();
}
//视野发生变化时更新
private void axMapControl1_OnExtentUpdated(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnExtentUpdatedEvent e)
{
//绘制主窗体的视野
IEnvelope pEnvelope = e.newEnvelope as IEnvelope;
//在小地图定义图形容器
IGraphicsContainer pGraphicsContainer = axMapControl2.Map as IGraphicsContainer;
//清空图层(每次变化清空上一次的框)
pGraphicsContainer.DeleteAllElements();
//矩形元素
IRectangleElement pReaRectangleElement = new RectangleElement() as IRectangleElement;
//符号
IFillShapeElement pFillShapeElement = new RectangleElement() as IFillShapeElement;
pFillShapeElement.Symbol = Tool.GetSymbol(pEnvelope as IGeometry) as ISimpleFillSymbol;
//元素
IElement pElement = pFillShapeElement as IElement;
pElement.Geometry = pEnvelope;
pGraphicsContainer.AddElement(pElement, 0);
axMapControl2.Refresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
private void axMapControl2_OnMouseMove(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseMoveEvent e)
{
if (e.button != 1)
{
return;
}
IPoint pPoint = axMapControl2.ToMapPoint(e.x, e.y);
axMapControl1.CenterAt(pPoint);
}
private void axMapControl2_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e)
{
//鼠标左键拖动
if (e.button == 1)
{
IPoint pPoint = new ESRI.ArcGIS.Geometry.Point();
pPoint.PutCoords(e.mapX, e.mapY);//设置 x 和 y 坐标
IEnvelope pEnvelope = axMapControl1.Extent;
pEnvelope.CenterAt(pPoint);//CenterAt(Point)以指定地图坐标作为中心点坐标重定位地图
axMapControl1.Extent = pEnvelope;
}
else if (e.button == 2)
{
IEnvelope pEnvelope = axMapControl2.TrackRectangle();
axMapControl1.Extent = pEnvelope;
}
}
IElement
AE中绘制图形元素的方法
Element元素对象是一个非常庞杂的对象集合,主要分为两大部分:图形元素(Graphic Element)和框架元素(Frame Element);
图形元素包括GroupElement、MarkerElement、LineElement、TextElement、DataElement、PictureElement、和FillShapeElement等对象,它们都是作为图形的形式而存在的。
IElement是所有图形元素和框架元素都实现的接口,它可以确定元素的Geometry属性,Element是一个抽象类,IElement和ILineElement、ITextElement并不是父子关系,后者没有Geometry属性。
AxMapControl
基本
AxMapControl控件提供显示和操作地图文档的功能
属性 | 描述 |
---|---|
Extent | 当前的显示范围 |
FullExtent | 全域 |
ActiveView | 当前的活动窗口 |
MousePointer | 控件上的鼠标样式 |
方法 | 描述 |
---|---|
TrackPolygon() | 检测鼠标多边形绘制 |
TrackRectangle() | 检测鼠标长方形绘制事件 |
TrackCircle() | 检测鼠标圆形绘制事件 |
TrackLine() | 检测鼠标线条绘制事件 |
事件 | 描述 |
---|---|
OnMapReplaced | 当AxMapControl中的Document发生改变时执行 |
OnMouseDown | 鼠标控件上按下 |
OnMouseMove | 鼠标在控件上移动 |
视野发生变化时 | 视野发生变化时 |
AxMapControl刷新方法
ArcGIS Engine中的刷新方法主要有:
IActiveView.Refresh
全局刷新,即重绘地图中的所有内容,是效率最低的一种刷新方法。当数据量大时非常耗时。所以除非绝对必要,一般推荐使用IActiveView.PartialRefresh方法。当然如果是涉及全部显示范围的更新就需要使用Refresh,比如平移、缩放、全图等操作。
IActiveView.PartialRefresh
部分刷新,可以人为指定重绘地图中的部分内容,该方法效率高,推荐使用。
//刷新所有图层使用:
activeView.PartialRefresh(esriViewGeography, null, null);
//刷新单个图层使用:
activeView.PartialRefresh(esriViewDrawPhase.esriViewGeography, layer,null);
//刷新单个图层中的某个区域使用:
activeView.PartialRefresh(esriViewDrawPhase.esriViewGeography, layer, envelope);
//刷新图层中的选中要素使用:
activeView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
//Tips: 测试只执行一次刷新即可,而ArcObjects帮助中说需要调用两次,一次在选择前,一次在选择后。
//刷新整个Element图层或者label使用:
activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
//刷新一个Element使用:
activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, element, null);
//刷新选中的Element使用:
activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphicSelection, null, null);
IScreenDisplay.Invalidate
Invalidate方法允许刷新显示中的指定区域,该方法不推荐用户使用,因为需要手动控制绘图缓存,对用户来说该方法不是最优的,推荐使用PartialRefresh