问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

通俗易懂的ArcGis开发快速入门

发布网友 发布时间:2024-09-26 06:48

我来回答

1个回答

热心网友 时间:2024-11-02 22:33

前言

本文主要介绍ArcGis的ArcEngine开发,学习时,我们需要放下心里障碍,那就是Gis开发只是普通的软件开发,并不需要专业的GIS知识,就是非常普通的,调用相关的C++开发的COM组件。

开发环境:VS2017。

ArcEngine版本:10.1。

基础学习

正式使用ArcGis之前,需要先学习ArcGis一些基础概念。

工作空间(IWorkspace):

存储ArcGis数据的对象,他可以从多种数据库中读取ArcGis数据,如oracle,mdb等等。

普通表(ITable):

跟我们常用的表一样,又称对象类。由于ArcGis是C++写的,所以读取表数据的时候,要使用游标一行一行的读取;普通表(ITable)默认第一个字段是主键,名称为OBJECTID。

要素表(IFeatureClass):

要素表有两部分组成,一部分是图像,一部分是普通表,他在代码中是一个对象,但在数据中是以两个表存在的,如下图(test2和test2_SHAPE_Index)。

但我们要注意的是,要素表(FeatureClass)存储图像的字段是表test2的SHAPE,而不是在test2_SHAPE_Index表中;要素表(FeatureClass)默认第一个字段是主键,名称为OBJECTID,第二个字段是图像字段,默认名称为SHAPE。

要素表的图形(SHAPE字段):

要素表的图形就是第二个字段,默认名称为SHAPE的图像字段;图像字段有很多种类型,其对应枚举为esriGeometryType,枚举值如下:

esriGeometryType.esriGeometryAny://"任何类型(Anyvalidgeometry)"esriGeometryType.esriGeometryBag://"任意几何类型的集合(GeometryBag)"esriGeometryType.esriGeometryBezier3Curve://"贝兹曲线(BezierCurve)"esriGeometryType.esriGeometryCircularArc://"圆弧(CircularArc)"esriGeometryType.esriGeometryEllipticArc://"椭圆弧(EllipticArc)"esriGeometryType.esriGeometryEnvelope://"外包(Envelope)"esriGeometryType.esriGeometryLine://"线段(Line)"esriGeometryType.esriGeometryMultiPatch://"表面几何(MultiPatch)"esriGeometryType.esriGeometryMultipoint://"多点(Multipoint)"esriGeometryType.esriGeometryNull://"未知类型(Unknown)"esriGeometryType.esriGeometryPath://"路径(Path)"esriGeometryType.esriGeometryPoint://"点(Point)"esriGeometryType.esriGeometryPolygon://"多边形(Polygon)"esriGeometryType.esriGeometryPolyline://"多段线(Polyline)"esriGeometryType.esriGeometryRay://"射线(Ray)"esriGeometryType.esriGeometryRing://"环(Ring)"esriGeometryType.esriGeometrySphere://"球体(Sphere)"esriGeometryType.esriGeometryTriangleFan://"三角扇形(TriangleFan)"esriGeometryType.esriGeometryTriangleStrip://"三角带(TriangleStrip)"esriGeometryType.esriGeometryTriangles://"三角形(Triangles)"

我们最常用的就是点(esriGeometryPoint),线(esriGeometryPolyline),面(esriGeometryPolygon)。

要素集(IFeatureDataset):

要素集,顾名思义就是要素表的集合,创建要素集的时候要提供空间参考(SpatialReference),常规使用时,可以直接将地图的空间参考提供给要素集,创建代码如下:

IFeatureWorkspacefeatureWorkspace=workspaceasIFeatureWorkspace;ISpatialReferencespatialReference=axMapControl1.ActiveView.FocusMap.SpatialReference;//创建要素集featureWorkspace.CreateFeatureDataset("Data2",spatialReference);

空间参考(SpatialReference)可以简单理解为横纵坐标系,因为世界上有很多种坐标系(如:北京54,西安80),所以在创建地图的时候,要指明使用哪种坐标系。

栅格数据(IRasterDataset):

栅格数据虽然是以Dataset存在,但他并不是类似要素集的存在,而是一个是独立存在的图像的文件。比如,我们可以通过IRasterDataset.OpenFromFile(filePath)来打开一个物理文件。

注意事项

注1:非空间数据:非空间数据就是可以在地图上展示或使用的业务数据;要素集中的非图形字段都是,普通表(ITable)存储的全是非空间数据。

注2:空间数据:空间数据即图形元素,又地图对象;几何数据类,要素类,关系类都是空间数据;空间数据可以被图层加载,形成图层对象,如:IFeatureLayer有个IFeatureClass属性,只要为该属性赋值要素类的对象,就成功加载了空间数据,此时,该图层也可称为要素图层。(要素表(IFeatureClass)包含空间数据和非空间数据两部分)。

ArcMap中各种元素展示如下:

注3:ArcGIS专用的mdb会有一些表存储Arcgis的专有数据,在数据库中的展示,如下图所示:

准备开发

首先安装ArcGisEngine和ArcObjects Sdk,然后创建一个普通的Winform项目。

然后在Program.cs中添加如下代码:

staticvoidMain(){ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProctCode.Engine);IAoInitializeaoInit=newAoInitializeClass();aoInit.Initialize(esriLicenseProctCode.esriLicenseProctCodeEngine);Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);Application.Run(newForm1());}

注:Bind和Initialize函数要使用统一的Code,这里我都使用的是ProctCode.Engine的Code。

因为是使用VS2017,所以在工具箱中我们看不到ArcGis的工具;需要我们手动引入ArcGis工具,工具箱—选择项—.NET Framework组件,找到ESRI程序集下的工具,引入即可。

然后把引入的类库的嵌入互操作类型熟悉修改为false,不然编译的时候会提示错误——无法嵌入互操作类型。

特定版本也改为false

如果我们在开发中发现有些ArcGis的类抛异常,那可以通过引用的方式,将ArcGis的Com组件引入进来,如,我们要打开SDE数据库,要使用ESRI.ArcGIS.DataSourcesGDB命名空间,就要添加Esri DataSourcesGDB OBJECT Library 10.1这个Com组件。

功能开发

在导入Arcgis的类库后,我们会在工具栏总看到如下控件:

AxMapControl 就是 Map 地图控件

AxPageLayouControl 是布局地图控件

AxTOCControl 是目录控件

AxToolbarControl 是 GIS 工具栏控件

AxSceneControl 是 Scene 三维场景控件

AxGlobeControl 是 Globe 控件

AxLicenseControl 是许可控件

AxSymbologyControl 是符号选择器控件

AxArcReaderControl 是 ArcReader 控件

AxArcReaderGlobeControl 是 ArcReaderGlobe 控件

如下图:

本文主要使用AxMapControl (Map 地图控件),AxPageLayouControl (是布局地图控件),AxTOCControl (目录控件)。

首先向窗体里添加这三个控件,然后设置控件AxPageLayouControl 和AxTOCControl 的buddy属性为AxMapControl ,目的是AxPageLayouControl 和AxTOCControl成为AxMapControl 的伙伴控件,实现数据的同步和共享。

设置buddy属性,需要右键控件,在下拉菜单中选择属性,如下图:

然后我们创建一个按钮,导入mdb数据库,并实现读取Mdb的要素集,要素类,表格数据,栅格数据等数据,并把名称显示在Listbox中。

代码编写思路介绍:

首先通过AccessWorkspaceFactoryClass实例化一个IWorkspaceFactory接口,然后用他打开一个mdb文件,并返回一个IWorkspace对象;然后通过IWorkspace的get_Datasets方法获取全部数据,(传递参数esriDatasetType.esriDTAny为获取全部数据),get_Datasets方法返回IEnumDataset,是一个枚举Dataset,这个对象不能for循环,只能使用Next函数获取下一个,这个也是C++的特点;然后我们通过while循环,取出所有数据,并显示在Listbox上;同时也做判断如果数据是要素类IFeatureClass ,则定义一个FeatureLayerClass对象,并将他的FeatureClass属性赋值,FeatureLayerClass添加进地图,这样就实现了将mdb的数据挂载进地图的操作。

代码如下:

#region读取Mdb的要素集,要素类,表格数据,栅格数据等数据,并把名称显示在Listbox中privatevoidbtnImportMDB_Click(objectsender,EventArgse){stringWsName=SelectMdb();List<string>listBoxSource=newList<string>();if(WsName!=""){IWorkspaceFactoryworkspaceFactory=newAccessWorkspaceFactoryClass();workspace=workspaceFactory.OpenFromFile(WsName,0);IEnumDatasetenumDataset_workspace=workspace.get_Datasets(esriDatasetType.esriDTAny);IDatasetdataset_Parent=enumDataset_workspace.Next();datalistBox.DataSource=null;while(dataset_Parent!=null){if(dataset_Parent.Type==esriDatasetType.esriDTFeatureClass)//要素类{listBoxSource.Add(dataset_Parent.Name+"-要素类-parent");IFeatureClassfeatureClass=dataset_ParentasIFeatureClass;//将IDataset强转为IFeatureClass(要素对象)AddLayer(featureClass);//将要素对象挂载在要素图层上,并显示在地图上}elseif(dataset_Parent.Type==esriDatasetType.esriDTFeatureDataset)//要素集{stringparentName=dataset_Parent.Name;listBoxSource.Add(parentName+"-要素集-parent");IFeatureDatasetfeatureDataset_workspace=dataset_ParentasIFeatureDataset;IEnumDatasetenumDataset_Child=dataset_Parent.Subsets;//取出要素对象的集合IDatasetdataset_item=enumDataset_Child.Next();intindex=0;while(dataset_item!=null){listBoxSource.Add(dataset_item.Name+"-要素对象-父:"+parentName+"-"+dataset_item.Type);Console.WriteLine("dataset_item.Type:"+dataset_item.Type);IGeoDatasetgeoDataset=dataset_itemasIGeoDataset;//也可以这样强转IFeatureClassfeatureClass=dataset_itemasIFeatureClass;//将IDataset强转为IFeatureClass(要素对象)AddLayer(featureClass);//将要素对象挂载在要素图层上,并显示在地图上index++;dataset_item=enumDataset_Child.Next();}}elseif(dataset_Parent.Type==esriDatasetType.esriDTTable)//数据表{stringparentName=dataset_Parent.Name;listBoxSource.Add(parentName+"-数据表-parent");ITabletable11_workspace=dataset_ParentasITable;varcount=table11_workspace.RowCount(newQueryFilterClass());Console.WriteLine("数据行数:"+count);}elseif(dataset_Parent.Type==esriDatasetType.esriDTRasterDataset)//栅格数据{stringparentName=dataset_Parent.Name;listBoxSource.Add(parentName+"-栅格数据-parent");}else{stringparentName=dataset_Parent.Name;listBoxSource.Add(parentName+"-parent-"+dataset_Parent.Type.ToString());}dataset_Parent=enumDataset_workspace.Next();}}datalistBox.DataSource=listBoxSource;datalistBox.Refresh();#region刷新地图axMapControl1.ActiveView.Refresh();//全图刷新//axMapControl1.Map.MapScale=axMapControl1.Map.MapScale;//axMapControl1.Map.MapScale=25000;Application.DoEvents();#endregion}//添加图层publicvoidAddLayer(IFeatureClassfeatureClass){IFeatureLayerfeatureLayer=newFeatureLayerClass();featureLayer.Name=featureClass.AliasName;featureLayer.FeatureClass=featureClass;ILayerEffectslayerEffects=featureLayerasILayerEffects;layerEffects.Transparency=1;//透明度设置IGeoFeatureLayergeoFeatureLayer=featureLayerasIGeoFeatureLayer;IFeatureRendererfeatRender=geoFeatureLayer.Renderer;#region样式设置if(featRenderisISimpleRenderer){ISimpleRenderersimple=featRenderasISimpleRenderer;//Symbol一般不会为空,因为有默认值,这里的图层layer是新建的,这里将IFeatureLayer转换为IGeoFeatureLayer,然后取他的Renderer,而Renderer里的Symbol就已经有值了。IFillSymbolsymbolFill=simple.SymbolasIFillSymbol;#region获取和设置图层的符号的颜色if(symbolFill!=null)//可以强转为IFillSymbol,即为填充符号,即面符号{RgbColorrgbColor=newRgbColor();rgbColor.RGB=symbolFill.Color.RGB;ColorpSymbolColor=Color.FromArgb(rgbColor.Red,rgbColor.Green,rgbColor.Blue);symbolFill.Color=ConvertToArcGisColor(Color.Green);//设置图层的符号的颜色//设置图层的符号的边框的颜色,这里直接symbolFill.Outline.Color不好使,必须重新new一个线对象symbolFill.Outline=newSimpleLineSymbolClass(){Color=ConvertToArcGisColor(Color.Purple),Width=1};}else{IMarkerSymbolsymbolMarker=simple.SymbolasIMarkerSymbol;if(symbolMarker!=null)//可以强转为IMarkerSymbol,即为标记符号,即点符号{RgbColorrgbColor=newRgbColor();rgbColor.RGB=symbolMarker.Color.RGB;ColorpSymbolColor=Color.FromArgb(rgbColor.Red,rgbColor.Green,rgbColor.Blue);symbolMarker.Color=ConvertToArcGisColor(Color.Red);//设置图层的符号的颜色}else{ILineSymbolsymbolLine=simple.SymbolasILineSymbol;if(symbolLine!=null)//可以强转为ILineSymbol,即为线符号{RgbColorrgbColor=newRgbColor();rgbColor.RGB=symbolLine.Color.RGB;ColorpSymbolColor=Color.FromArgb(rgbColor.Red,rgbColor.Green,rgbColor.Blue);symbolLine.Color=ConvertToArcGisColor(Color.Blue);//设置图层的符号的颜色}}}#endregion}#endregionaxMapControl1.Map.AddLayer(featureLayer);}//选择文件数据库publicstringSelectMdb(){stringWsFileName="";OpenFileDialogOpenFile=newOpenFileDialog();OpenFile.Filter="文件数据库(MDB)|*.mdb";DialogResultDialogR=OpenFile.ShowDialog();if(DialogR==DialogResult.Cancel){}else{WsFileName=OpenFile.FileName;}returnWsFileName;}#endregion

结果如下下图所示:

BUG:您必须有许可证才能使用此 ActiveX 控件

首先打卡License Server Adm

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
什么牌子洗发水香味好闻持久 有哪些留香久的香氛洗发水值得入手? 香味持久的洗发水有哪些? 洗发水香味最持久排行 家装适合什么地板 客厅地板装修什么地板好 我家装修是北欧风格,想选一款与家里装修风格相匹配的地板,有何推荐? 什么样的装修用什么样的地板好 镇域 村镇 集体建设用地的区别 农村宅基地的升值之路:农民的生存保障还是财富陷阱? ILayer 强制转换 IFeatureLayer 失败? EVC++ 实现shape文件读写 急急急~~ 心理医生免费咨询? 青岛旅游几月份去合适 青岛什么时候去旅游最合适 几月份去青岛合适 多少月份去青岛合适 青岛淡季旅游是几月份,青岛淡季旅游路线 青岛旅游最佳时间 什么时候去青岛旅游 ...觉醒教派和刃牙追猎者)怎么开启?本人想解锁德拉诺飞行 杭州有什么包吃包住的厂子 ...请问哪里招铆焊工。长期的,月月工资打卡的厂子最好。 广东那边在厂子里打工一月能给多少钱? 天津电子厂怎么样啊,薪资待遇,管吃住吗 在厂子里一个月五千多、管一顿饭管住、压一个月工资、工地上不管吃住... (高分悬赏)�新华保险公司 是国营还是私营? 太平洋保险公司埃森哲考试如何得高分 中医助理医师中医助理医师证书的注册程序 助理医师注册流程和费用 什么是UPS系列??? ups电源有三种工作状态是什么意思啊? 请教李正封诗"国色朝酣酒,天香夜染衣,丹景春醉容,明月问归期"的具体... 有没有催泪的影视?最好是动漫。表示未闻花名无感。air平静。倒是大剑... ...7101型在测量血压值时总是出现E型符号后就降至0,如何解决?_百度知... 如何输入声调在一声、二声、四声的拼音? 眼睛的声调是第几声? 如何在不改变图案的情况下,改变图片的颜色? cad如何关闭全部的图层? RGB模式的图片怎么转换成CMYK模式? 怎么用ps抠白底图? ...就会忙着包粽子,还有看划龙舟...那端午节是怎么由来的呢?_百度... 黄喉拟水龟是国家保护动物吗黄喉拟水龟属于保护动物吗 黄喉拟水龟是国家保护动物吗黄喉拟水龟是否是国家保护动物 绝地求生刺激战场改名卡在哪里买?改名卡免费获取攻略 养黄喉拟水龟犯法吗 ...昨晚见面了去吃饭,然后还给我报销车费,我不要,偷偷给我发了红包... 去相亲认识的男友家里,故意没买东西,他买的水果并告诉他父母那是我 小米手机3 一定要贴膜吗,贴了膜划起来就不太灵活了 小米3屏幕是什么材 ... 小米3不贴贴膜那屏幕质量是怎样的 会不会很容易沾指纹 很容易刮花? 小米3可不可以去掉手机膜,贴手机膜好模糊 。有没有什么影响 小米3可以不贴膜吗,你们有没贴的吗弄啦张膜没有贴好 牛市来了什么股票涨幅最大