C#开发GIS应用简明教程(三)
第三章数据处理
在介绍数据处理之前,我们先在MapInfo中生成自己的地图,在本章中将全部使用自己生成的地图.这是因为MapX本身提供的地图和实际应用的地图在数据结构上有较大的差异.不适合用来介绍MapX的数据处理.
首先安装好MapInfo,最好能使用7.0以上的版本.以下操作在MapInfo Professional 7.0版本下完成.
打开MapInfo,界面如下图:
单击工具栏最左边的 按钮,新建一个图层数据表.如下图:
在"New Table"窗口中按照上图选择后单击"Create..."按钮,建立一个新的数据图层.MapInfo会弹出一个窗口,如下图:
在这个窗口中设置好数据表的字段属性.单击"Add Field"按钮将字段添加到表中,我们在这里将添加4个字段:ID,名称,月供年限和水电费.设置好的字段如下图:
设置好以后,单击"Create..."按钮,MapInfo将询问建立图层表的文件路径.将你的图层表文件名改为"HouseLayer.Tab",存放到合适的路径下.例如:" E:"Test"DataMap"".
保存完毕以后,得到一个空白的图层表文件,MapInfo打开了这个文件显示如下:
这个图层表上现在还没有任何图形,我们在图层上增加两个图元,并把数据添加上去.
在Drawing工具条上选择画矩形的工具,在HouseLayer Map上画一个矩形,然后使用拷贝粘贴的功能将其复制为另一个矩形.
选择图元后,对两个图元稍做修饰.如下图:
现在,简单的作图就完成了.
接着输入和图形相关的数据.选择如下图指示的按钮,在图层上点选图元,打开输入数据的窗口.
在输入数据的窗口中输入以下两条数据:
ID |
名称 |
月供年限 |
水电费 |
0001 |
A栋 |
25 |
18.77 |
0002 |
B栋 |
30 |
25.12 |
保存图层.MapInfo的画图工作就完成了.
你还需要在MapX 5.0自带的工具Geoset Manager里把刚刚画好的图层放到一个地图文件(.GST格式)里,才能被MapX调用,我们把这个文件命名为"小区.GST".
好,准备工作就绪,现在我们开始介绍MapX的数据处理.
1.数据读取 (Data Reading)
先对程序的功能作一些说明:把小区地图放在MapX控件上,并且在窗口的左边放置一个ListView,在这个ListView中显示所有的HouseLayer图层表中的图元数据.
和以往不同的是,我们的程序界面做了一些改动,以跟踪数据的变化.
下图是窗口设计界面:
可以看到,我们在窗口左边放置了一个ListView控件,并在ListView中增加了4列(Columns)来显示数据.同时,把MapX控件的地图换成了我们自己制作的"小区"地图.
在button1的单击事件button1_Click中编写如下代码:
MapXLib.Fields flds=new MapXLib.FieldsClass(); MapXLib.Layer lyr=axMap1.Layers._Item("HouseLayer"); MapXLib.Dataset dts=null;
flds.Add("ID","ID",MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeString); flds.Add("名称","名称",MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeString); flds.Add("月供年限","月供年限",MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeInteger); flds.Add("水电费","水电费",MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeFloat);
dts=axMap1.DataSets.Add(MapXLib.DatasetTypeConstants.miDataSetLayer,lyr,lyr.Name,0,0,0, flds,false); listView1.Items.Clear(); for(int i=1;i<=dts.RowCount;i++) { listView1.Items.Add( new ListViewItem(new string[]{dts[i,1].ToString(), dts[i,2].ToString(), dts[i,3].ToString(), dts[i,4].ToString()})); } axMap1.DataSets.RemoveAll(); |
代码依旧很短,是对以前所介绍知识的进一步深化.这里要注意的是对dts的应用.运行程序,可以看到程序把所有的图元数据都正确地读取出来了.
在程序末尾,我们将MapX控件中的DataSets全部移除,这是为了以后再使用DataSets方便.
2.添加数据(Data Adding)
在图层表上添加数据实际上就是添加图元,只不过这个图元是带有数据信息的.
仍然使用读取数据的例子,我们在窗口上增加一个按钮button2,编写它的单击事件代码button2_Click如下:
MapXLib.Feature ftr=new MapXLib.FeatureClass(); MapXLib.Points pts=new MapXLib.PointsClass(); MapXLib.Point pt=new MapXLib.PointClass(); MapXLib.RowValues rvs=new MapXLib.RowValuesClass(); MapXLib.Fields flds=new MapXLib.FieldsClass(); MapXLib.Layer lyr=axMap1.Layers._Item("HouseLayer"); MapXLib.Dataset dts=null; flds.Add("ID","ID",MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeString); flds.Add("名称","名称",MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeString); flds.Add("月供年限","月供年限",MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeInteger); flds.Add("水电费","水电费",MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeFloat);
dts=axMap1.DataSets.Add(MapXLib.DatasetTypeConstants.miDataSetLayer,lyr,lyr.Name, 0,0,0,flds,false);
rvs=dts.get_RowValues(0); rvs._Item("ID").Value="0003"; rvs._Item("名称").Value="C栋"; rvs._Item("月供年限").Value=20; rvs._Item("水电费").Value=21.73; ftr.Attach(axMap1.GetOcx()); ftr.Style=axMap1.Layers._Item("HouseLayer").Style; ftr.Style.RegionPattern=MapXLib.FillPatternConstants.miPatternSolid; ftr.Style.RegionColor=16711680; ftr.Type=MapXLib.FeatureTypeConstants.miFeatureTypeRegion; pt.Set(1,1); pts.Add(pt,1); pt.Set(2,1); pts.Add(pt,2); pt.Set(2,2); pts.Add(pt,3); pt.Set(1,2); pts.Add(pt,4);
ftr=axMap1.FeatureFactory.CreateRegion(pts,ftr.Style); ftr=axMap1.Layers._Item("HouseLayer").AddFeature(ftr,rvs); ftr.Update(ftr,rvs); axMap1.DataSets.RemoveAll(); |
在上面的程序中我们实现了将一个新的图元加入到图层表中,这个图元的数据信息如下表:
ID |
名称 |
月供年限 |
水电费 |
0003 |
C栋 |
20 |
21.73 |
应该要注意的是我们首先还是使用了DataSets.Add将数据读出来,再使用get_RowValues得到行数据结构,然后才是对行数据的赋值.
运行程序,单击button1,可以看到左边的ListView中只有两条记录,再单击button2,看到图层上增加了一个蓝色的矩形图元,这就是我们增加的带数据的图元,再单击button1,可以看到新增图元的数据信息出现在左边的ListView中.
3.修改数据(Data Modifying)
现在,要在窗口中添加另一个按钮button3了.这个按钮要实现的功能是将"A栋"的名称改成"A1栋".也就是说,我们要对A栋的数据进行修改.这个按钮的代码如下:
MapXLib.FindFeature ftrRes=null; MapXLib.Points pts=new MapXLib.PointsClass(); MapXLib.Point pt=new MapXLib.PointClass(); MapXLib.RowValues rvs=new MapXLib.RowValuesClass(); MapXLib.Fields flds=new MapXLib.FieldsClass(); MapXLib.Layer lyr=axMap1.Layers._Item("HouseLayer"); MapXLib.Dataset dts=null; ftrRes=axMap1.Layers._Item("HouseLayer").Find.Search("0001",""); if (ftrRes.FindRC % 10==1) { flds.Add("ID","ID",MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeString); flds.Add("名称","名称",MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeString); flds.Add("月供年限","月供年限",MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeInteger); flds.Add("水电费","水电费",MapXLib.AggregationFunctionConstants.miAggregationSum, MapXLib.FieldTypeConstants.miTypeFloat);
dts=axMap1.DataSets.Add(MapXLib.DatasetTypeConstants.miDataSetLayer,lyr,lyr.Name, 0,0,0,flds,false); for (int i=0;i<dts.RowCount;i++) { if (dts.get_Value(i,"ID").ToString().Trim()=="0001") { rvs=dts.get_RowValues(i); rvs._Item("名称").Value="A1栋"; ftrRes.Update(ftrRes,rvs); break; } } axMap1.DataSets.RemoveAll(); } |
可以看到,我们使用了前面章节所介绍的查找图元的技术.然而在给行数据赋值的时候仍然不得不在数据集中进行循环,以取得其它行数据,实际上,如果通过控件(例如DataGrid或ListView)取到了图元的数据,是不必进行这样的循环的,直接对RowValue的所有字段都进行赋值就可以了.
4.删除数据(Data Deletion)
删除数据其实就是删除图元,只要找到图元,直接删除就可以了.但是要注意的是,因为图元包含了数据,所以在删除数据以后还要紧缩表.好在紧缩表也十分简单.
仍然使用我们前面的例子,加一个button4,在它的单击事件中编写代码如下:
MapXLib.FindFeature ftrRes=null; ftrRes=axMap1.Layers._Item("HouseLayer").Find.Search("0003",""); if (ftrRes.FindRC % 10 ==1) { axMap1.Layers._Item("HouseLayer").DeleteFeature(ftrRes); }
//紧缩表 axMap1.Layers._Item("HouseLayer").Pack(MapXLib.LayerPackConstant.miPackAll); |
如果在删除图元以后没有紧缩表的话,单击button1,将会看到ListView中多了一条空白的数据.
本章讲述的数据处理技术重在活学活用.关于数据处理还有一些重要的内容,例如专题图等技术,将在后面更为深入的章节中讲述.
本人博客的文章大部分来自网络转载,因为时间的关系,没有写明转载出处和作者。所以在些郑重的说明:文章只限交流,版权归作者。谢谢