1C#开发GIS应用简明教程[一](2006-06-0516:43:56)转载标签:cgis教程分类:GIS技术转载(MapInfo)第一篇准备使用C#开发GIS应用,你应该首先在系统中安装VisualStudio.Net(建议使用2003版本),然后还需要安装MapInfo公司开发的MapX5.0版本.MapX的4.X版本和.Net的兼容有一些问题.可能无法实现本教程介绍的某些功能.另外,你还应该尽可能地收集所有关于.NET,C#和MapX有关的资料,教程非常实用,专门解决技术问题,而不打算列举资料,所以,最好手头上有一些备查的资料.如果实在找不到,最起码要求能看懂MSDN.Met和MapX的帮助.关于.Net的安装很多教程都有涉及,此处不再赘述.MapX5.0的安装很容易,按照提示一步步就可以安装,和一般的软件安装没什么区别,安装完控件以后千万别忘了同时安装附带的地图数据.安装好以上软件后,还需要在.Net编程环境中加入MapX5.0控件.在.Net编程环境中新建一个WindeosApplication(Windows应用程序)项目,然后在菜单中选择”项目/添加引用”,打开如下图的窗口,在窗口中选择COM标签,在组件名称列表中双击MapInfoMapXV5.单击确认按钮,即可将Map5控件加入到.Net的工具箱中.现在,所有的准备工作都已经完成了,为了测试安装是否正确,我们做个简单的地图放大程序.2在刚刚打开的项目中,从工具栏中选择MapinfoMapXV5控件,把它画到项目中的Form1窗口上,如下图:增加一个Button控件button1,将它的Text属性改为”放大”,如下图:在设计窗口中双击按钮并编写代码如下:privatevoidbutton1_Click(objectsender,System.EventArgse){axMap1.CurrentTool=MapXLib.ToolConstants.miZoomInTool;}编译,运行程序.如果没有什么错误的话,准备工作就已经完成了.第二章入门1.工具(ToolConstants)在上一章里我们试着做了一个将地图放大的应用程序.在这章里,我们将接触到更多的工具,并介绍自定义工具.MapX为开发人员提供一系列的工具,这些工具的作用各有不同,我们通过开发一个应用程序来了解这些工具的作用,至于这些工具的具体说明,可以在MapX的帮助文档中,通过查找AvailableStandardTools看到相应的解释.一些MapX的相关资料也有介绍.3在.Net编程环境中新建一个C#的WindeosApplication(Windows应用程序)项目,然后在菜单中选择”项目/添加引用”,打开如下图的窗口,在窗口中选择COM标签,在组件名称列表中双击MapInfoMapXV5.单击确认按钮,将Map5控件加入到.Net的工具箱中.接着,将MapInfoMapXV5控件画到窗体上,再在窗体上画一个ComboBox控件comboBox1.如下图:双击设计窗体,编写Form1_Load代码如下:privatevoidForm1_Load(objectsender,System.EventArgse){ArrayListToolsList=newArrayList();ToolsList.Add(MapXLib.ToolConstants.miArrowTool);ToolsList.Add(MapXLib.ToolConstants.miCenterTool);ToolsList.Add(MapXLib.ToolConstants.miLabelTool);ToolsList.Add(MapXLib.ToolConstants.miPanTool);ToolsList.Add(MapXLib.ToolConstants.miPolygonSelectTool);ToolsList.Add(MapXLib.ToolConstants.miRadiusSelectTool);ToolsList.Add(MapXLib.ToolConstants.miSymbolTool);4ToolsList.Add(MapXLib.ToolConstants.miTextTool);ToolsList.Add(MapXLib.ToolConstants.miZoomInTool);ToolsList.Add(MapXLib.ToolConstants.miZoomOutTool);comboBox1.DataSource=ToolsList;}以上代码通过一个数组ToolsList,将MapXLib的工具加入到comboBox1中.MapX还有一些其它的工具,它们的作用是往地图上加上点,线,多边型和圆.因为这些工具要求有操作图层,一并在介绍图层的时候介绍.关于ArrayList的用法,请参考C#的有关资料.接着,双击comboBox1,并编写代码如下privatevoidcomboBox1_SelectedIndexChanged(objectsender,System.EventArgse){axMap1.CurrentTool=(MapXLib.ToolConstants)comboBox1.SelectedItem;}应注意,在C#中必须要显式地把comboBox1的选择项目SelectedItem(数据类型为object)转换为MapXLib.ToolConstants.因为ToolConstants是MapX自己定义的一个枚举数据类型,C#不能自动完成这种枚举成员变量到object的数据转换.编译执行程序,从comboBox1中选择不同的工具,在地图上进行操作,你可以了解到MapX工具集的强大功能.5实际上,MapX提供的工具集就好像Photoshop,AutoCAD的工具栏一样,为你提供了一些控制地图的工具.但是,在开发GIS的时候,这些工具是不能完全满足要求的.所以,还应该学会自定义工具.下面,通过一个在地图上测距的例子,来介绍一下如何在C#下自定义MapX工具如前所述建立一个C#的Windows应用程序并将MapinfoMapXV5控件加到窗体上.并加入一个Button控件button1.将button1的Text属性改为测距,再在窗口中放上两个Label控件label1,label2,将它们的Text属性设置为空字符串,如下图:双击设计窗体,编写Form1_Load代码如下:privatevoidForm1_Load(objectsender,System.EventArgse){axMap1.CreateCustomTool(100,MapXLib.ToolTypeConstants.miToolTypePoly,MapXLib.CursorConstants.miCrossCursor,null,null,null);}在加载窗口的时候,我们定义了一个工具.它的编号是100(不要和MapX本身的工具编号重复),它的类型是一个多义线,采用十字光标.关于此函数的用法,建议查看MapX的开发手册和相关资料.现在我们定义了一个编号为100的工具,可以在程序中使用它了.双击设计窗体中的button1,编写它的Click事件处理代码如下:6privatevoidbutton1_Click(objectsender,System.EventArgse){axMap1.CurrentTool=(MapXLib.ToolConstants)100;}现在编译运行,单击button1,就可以在地图上使用这个工具了.但是还有一部分重要的代码没有完成:测距!完成测距功能的代码在C#使用MapX开发GIS中非常具有代表性,也比较有难度.我在首次使用C#+MapX开发GIS的时候,被这个问题困扰了很久.项目经理也来研究,过两天说有结果了,但他给出的例子根本就行不通.当然,会了就不难了.其实,也很简单.首先,在窗口类中声明两个私有全局变量以保存测出的距离和总距,注意声明代码的位置:publicclassForm1:System.Windows.Forms.Form{privateAxMapXLib.AxMapaxMap1;privateSystem.Windows.Forms.Buttonbutton1;privateSystem.Windows.Forms.Labellabel1;privateSystem.Windows.Forms.Labellabel2;///summary///必需的设计器变量。////summaryprivateSystem.ComponentModel.Containercomponents=null;7privatedoubleDis=0,DisSum=0;......现在来编写工具的事件.注意,在MapX画多义线的时候,它触发消息的方式和一般的工具是不同的,首先,它并不是用鼠标一点击就完成了的,还可以继续画下去,所以,不应该在MapX控件的ToolUsed事件中编写,而应该在PolyToolUsed事件中实现测距.代码如下:privatevoidaxMap1_PolyToolUsed(objectsender,AxMapXLib.CMapXEvents_PolyToolUsedEvente){MapXLib.PointsClasspts=newMapXLib.PointsClass();switch(e.flags){case(int)MapXLib.ToolFlagConstants.miToolInProgress:pts=(MapXLib.PointsClass)e.points;Dis=axMap1.Distance(pts._Item(pts.Count-1).X,pts._Item(pts.Count-1).Y,pts._Item(pts.Count).X,pts._Item(pts.Count).Y);DisSum+=Dis;8break;default:Dis=0;DisSum=0;break;}label1.Text=距离:+Dis.ToString(#.00);label2.Text=总距+DisSum.ToString(#.00);}这段代码虽短.但要注意的地方很多.首先,定义一个MapXLib.PointsClass类型的变量pts,注意,是PointsClass,不是PointClass.前者是点集,后者是点.为什么要增加那么一个变量呢?因为MapX的PolyToolUsed事件的返回参数e的成员points不是MapXLib.PointsClass类型,而是object.类型.所以需要这么一个变量来转换它,当然,你也可以在程序使用pts的地方直接使用(MapXLib.PointsClass)e.points,但那样一来程序就比较难懂了;其次,要判断事件的标识e.flags的值,它指出工具当前的状态,是刚开始画多义线呢,还是正在画多义线,或者已经结束了,或者结束退出.我们只要在画的时候测距就可以了.其它时候将距离和总距都设置为0;9接着,还要注意的是e.points的点数据保存方式,e.points首先是一个object,当在画多义线的时候,它被初试化为一个MapXLib.PointsClass的变量,并以二维数组的方式保存点集.这个数组是从1开始的,而不是从0开始的.它保存了多义线上每个转折点的坐标,鼠标每点一下,就增加一个新的数据到点集,我们计算最后一条直线长度,应该从这个数组的末尾往前取.计算好距离以后再加入到总距中.许多测距的程序例子都要做一个循环,其实是不必要的.最后,请注意数字转换到字符串的格式问题.在这个例子中我们保留两位小数.补充一点,因为没有设置地图的地理坐标系统,所以测出来的距离单位是英里,如果要改为公里,把MapX控件的MapUnit属性改为miUnitKilometer就可以了.要提高测量精度,除了可以