开发GIS应用简明教程.docx
- 文档编号:13186319
- 上传时间:2023-06-11
- 格式:DOCX
- 页数:23
- 大小:29.79KB
开发GIS应用简明教程.docx
《开发GIS应用简明教程.docx》由会员分享,可在线阅读,更多相关《开发GIS应用简明教程.docx(23页珍藏版)》请在冰点文库上搜索。
开发GIS应用简明教程
开发GIS应用简明教程
关于C#开发GIS应用简明教程的说明
Web上的GIS,我个人觉得C#+MAPX并不是一个好的解决办法,因为有许多的GIS工具更适合于WEB环境和C#语言,只是我自己在这方面也没什么研究。
所以只能对大家说抱歉了。
第一章准备
使用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的工具箱中.
现在,所有的准备工作都已经完成了,为了测试安装是否正确,我们做个简单的地图放大程序.
在刚刚打开的项目中,从工具栏中选择MapinfoMapXV5控件,把它画到项目中的Form1窗口上,如下图:
增加一个Button控件button1,将它的Text属性改为”放大”,如下图:
在设计窗口中双击按钮并编写代码如下:
privatevoidbutton1_Click(objectsender,System.EventArgse)
{
axMap1.CurrentTool=MapXLib.ToolConstants.miZoomInTool;
}
编译,运行程序.如果没有什么错误的话,准备工作就已经完成了.
练习:
1.完成应用程序,在窗口中实现放大,缩小,漫游功能.
2.熟悉MapInfoMapX中的GeoSetManager程序.
3.了解GIS的有关知识.(推荐到"程序员资源大联盟"网站查看相关版块的内容.
第二章入门
1.工具(ToolConstants)
在上一章里我们试着做了一个将地图放大的应用程序.在这章里,我们将接触到更多的工具,并介绍自定义工具.
MapX为开发人员提供一系列的工具,这些工具的作用各有不同,我们通过开发一个应用程序来了解这些工具的作用,至于这些工具的具体说明,可
以在MapX的帮助文档中,通过查找"AvailableStandardTools"看到相应的解释.一些MapX的相关资料也有介绍.
在.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);
ToolsList.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工具集的强大功能.
实际上,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事件处理代码如下:
privatevoidbutton1_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;
///
///必需的设计器变量。
///
privateSystem.ComponentModel.Containercomponents=null;
privatedoubleDis=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;
break;
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;
接着,还要注意的是e.points的点数据保存方式,e.points首先是一个object,当在画多义线的时候,它被初试化为一个MapXLib.PointsClass的变
量,并以二维数组的方式保存点集.这个数组是从1开始的,而不是从0开始的.它保存了多义线上每个转折点的坐标,鼠标每点一下,就增加一个新
的数据到点集,我们计算最后一条直线长度,应该从这个数组的末尾往前取.计算好距离以后再加入到总距中.许多测距的程序例子都要做一个循
环,其实是不必要的.
最后,请注意数字转换到字符串的格式问题.在这个例子中我们保留两位小数.
补充一点,因为没有设置地图的地理坐标系统,所以测出来的距离单位是英里,如果要改为公里,把MapX控件的MapUnit属性改为miUnitKilometer
就可以了.要提高测量精度,除了可以通过转换格式的时候增加小数位,还应该注意到地图的测绘精度.否则,再多的小数位也是没有意义的.
练习
1.建立一个应用程序,加入MapX控件和一个ComboBox控件,两个:
Label控件,在ComboBox中加入第一个例子中的所有工具和测距工具,在ComboBox
中选择测距工具时实现测距功能.
2.将测距工具的光标改成箭头光标.并以米为单位显示测距数据.
2.图层和图元(LayersandFeatures)
有关图层和图元的概念,请参照相关资料.
图层的应用分为几个方面,我们分别加以介绍.
1)图层的创建:
创建永久图层:
在C#中,使用以下方法创建永久图层:
MapXLib.Layerlyr;
lyr=axMap1.Layers.CreateLayer("MyLayer","D:
\\MapTest\\MyLayer.Tab",0,32,axMap1.DisplayCoordSys);
当执行这两句程序时,在指定的路径生成了一系列文件.它们是:
MyLayer.Dat:
图层的数据文件,它保存的是图层的数据库数据;
MyLayer.ID:
图层数据的唯一的,自动生成的编码,用以区分不同的图元;
MyLayer.IND:
图层数据的索引文件,以实现图层上图元的快速查找;
MyLaer.MAP:
图层上图元的图形数据;
MyLaer.TAB:
这是一个文本文件,它的作用是将图层的有关信息保存起来,供GST地图文件或其它程序调用图层.
用记事本打开MyLayer.TAB文件,看到如下内容:
!
table
!
version450
!
charsetWindowsSimpChinese
DefinitionTable
Description"MyLayer"
TypeNativecharset"WindowsSimpChinese"
Fields1
GEONAMEchar(32)Index1;
第一行总是"!
table",说明这是一个图层表的文件;
第二行指出图层文件的版本号,MapInfoMapX5.0生成的图层版本号是450;
第三行指出生成图层的操作系统;
接着是对图层的定义段:
首先指出图层的描述,就是我们上面程序代码中的"Mylayer".
接着说明了字符集类型是简体中文;
然后指出表格中只有一个字段,这个字段的名称是"GEONAME",是长度为32的字符类型字段,在表中的列索引为1.
2)添加现有的图层:
添加现有图层的方法和一般的程序语言没有很大的区别,我们在当前图层上添加刚才创建的永久图层,程序代码如下:
MapXLib.LayerInfoli;
li=newMapXLib.LayerInfoClass();
li.Type=MapXLib.LayerInfoTypeConstants.miLayerInfoTypeTab;
li.AddParameter("FileSpec","D:
\\MapTest\\MyLayer.tab");
li.AddParameter("Visible",false);
li.AddParameter("AutoCreateDataset",true);
li.AddParameter("DatasetName","MyLayer");
axMap1.Layers.Add(li,0);
axMap1.Layers.LayersDlg("","");
axMap1.SaveMapAsGeoset("测试","D:
\\MapTest\\MyMap.GST");
在程序的最后,我们显示了图层信息对话框,以观察图层是否已经添加到当前的地图中.可以看到,地图中添加了我们创建的图层"MyLayer".放在
第0层.
然后,将地图保存在一个MyMap.GST的地图文件中,这个地图的标题是"测试".
3)移除图层:
好,接着我们上面做的工作,将工程的axMap1的GeoSet属性设置为刚刚生成的地图文件:
"D:
\MapTest\MyMap.GST".现在我们将MyLayer从地图中
移除.
添加一个按钮,在按钮的Click事件中编写如下代码:
axMap1.Layers.LayersDlg("","");
axMap1.Layers.Remove
(1);
axMap1.Layers.LayersDlg("","");
我们使用两次显示图层对话框的方式查看程序的效果,应该注意的是在Remove第0层的时候使用的是Remove
(1),如果不清楚图层的位置,就要作一
个循环,将图层的位置取出来再移除,如下:
intlyrind=0;
axMap1.Layers.LayersDlg("","");
for(inti=1;i { if(axMap1.Layers[i]._Name.Trim()=="MyLayer") { lyrind=i; break; } } axMap1.Layers.Remove(lyrind); axMap1.Layers.LayersDlg("",""); 移除操作只在内存中进行,也就是说,程序并不删除任何文件,也没有将图层真正地从地图集合中去掉,当程序重新启动的时候,MyLayer图层仍然 在地图中. 3)移除所有图层: 使用axMap1.Layers.RemoveAll();就可以移除所有图层,用法和Remove相似. 4)图层定位: 和其它编程语言一样,使用axMap1.Move(1,2)函数就可以将图层的位置改变. 5)创建临时图层 临时图层和永久图层不同,它只存放在内存中,当关闭程序以后该图层将不存在. 在这里我们将使用LayerInfo对象来创建临时图层,这和传统的MAPX程序相近,但是引入了C#编程的一些特色: MapXLib.LayerInfoClassli=newMapXLib.LayerInfoClass(); MapXLib.Featuresftrs=null; MapXLib.FieldsClassflds=newMapXLib.FieldsClass(); MapXLib.FieldsMyflds=null; MapXLib.Datasetdts=null; flds.Add("State","State_Name", MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeString); dts=axMap1.DataSets.Add(MapXLib.DatasetTypeConstants.miDataSetLayer, axMap1.Layers._Item (1),"MyLayer",0,0,0,flds,false); Myflds=dts.Fields; ftrs=axMap1.Layers._Item("USA").Selection.Clone(); li.Type=MapXLib.LayerInfoTypeConstants.miLayerInfoTypeTemp; li.AddParameter("Name","USATempLayer"); li.AddParameter("Fields",Myflds); li.AddParameter("Features",ftrs); axMap1.Layers.Add(li,1); axMap1.Layers.LayersDlg("",""); 这段程序有两个关键的地方: 一个是在C#中DataSets.Add的用法,在许多编程语言中,都可以使用空的参数或者干脆不用参数来调用这个函数,但是在C#中是不行的,必须8个参 数全部指定.而且,还应该事先初始化Fields参数.这个函数的使用涉及到许多方面的知识,包括对MAPX相关概念的理解和C#编程的认识,是一个很 重要,也比较难掌握的技术.后面的章节中我们还会作进一步的探讨. 另一个是li.AddParameter和li.Type的配合使用问题,这在许多的MAPX书籍中都有论述,此处不再重复. 以上程序最好能自己多琢磨琢磨.才能更好地掌握C#开发GIS的要领. 6)缩放图层: 所谓的缩放图层,并不是指将单个图层缩放.而是指定图层的可见范围比例,例如,设置一个图层在缩小显示大于5英里的时候隐藏.小于5英里的时 候显示.和其它编程语言一样,只要设置Layer的ZoomMin和ZoomMax就可以了. 7)显示整个图层: 这里要提及的一个技巧是在C#下面怎样显示整个图层.众所周知,在VB下面只要: Map1.Bounds=Map1.Layers("USA").Bounds 一句程序就可以轻松实现.但是要是在C#中这样写的话,百分百会出错.其实,这里有一个小小的技巧,聪明的你一定能看出来: axMap1.CtlBounds=axMap1.Layers._Item("USA").Bounds; 8)在图层上绘制永久图形: 我们在介绍工具的时候,有一些工具没有介绍,这些工具其实是用来在图层上创建永久图形对象的(图元).当在图层上绘制了图形以后,这些图形 将以数据记录的形式保存在图层表中,也就是创建了一个图元.如果不想保存图元,可以在临时图层里绘制. axMap1.Layers._Item("USATempLayer").Editable=true; axMap1.Layers.InsertionLayer=axMap1.Layers._Item("USATempLayer"); axMap1.CurrentTool=MapXLib.ToolConstants.miAddLineTool; 上面的程序使用了画线的工具,在地图上拖动鼠标就可以在临时图层上画线了.这些工具使用的前提是必须指定axMap1的插入图层 (InsertionLayer).才能在图层表中插入数据. 关于图层的关键技术就介绍到这里,掌握了这些技术以后,在作进一步的研究时,例如动画图层和绘制图层的开发,遇到的困难应该不大. 下面我们介绍C#对MAPX图元的编程技术. 9)在图层上创建图元: 根据MAPInfo提供的MapX5.0开发手册,创建图元有两种方法,用两段代码说明这两种代码在C#的实现方法: 第一种实现方法: 直接使用Feature类创建图元 MapXLib.Style
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 开发 GIS 应用 简明 教程