|
阅读:1704回复:4
MapInfo注记的数据库存放解决方案
<P><b>【摘要】</b> 自从MapInfo5.5支持Oracle Spatial以来,极大的方便了地理空间数据的共享、管理和维护,同时也促进了自身在GIS各行业中的应用。但MapInfo从开始的5.5版本到现在的7.0版本都没能实现注记的数据库存放,这一缺陷给MapInfo用户在系统应用和开发方面带来了极大的不便。本文正是基于此原因,利用MapInfo的二次开发语言MapBasic较好的解决了这一难题。</P>
<P><b>【关键词】</b> MapBasic , Oracle Spatial , 空间数据库 , 文字注记 </P> <P> 一、 问题的提出</P> <P>MapInfo是一个简单易用、大众化的GIS桌面软件,它具有地理空间数据的存贮、管理、显示、查询、分析和制图等基本的GIS功能,在国内具有比较大的用户群。MapInfo主要采用传统的文件方式管理GIS空间数据,无法满足GIS数据的多用户共享与并发操作,难以实现企业级的GIS应用。随着Oracle Spatial的发展,MapInfo从5.5开始支持利用Oralce Spatial管理空间数据,这样可以较好地解决企业应用问题。由于在MapInfo与Oracle之间不再象低版本那样使用ODBC,空间数据的处理建立在功能强大的服务器上,同时又实现了非常高效的空间索引技术(R-tree),所以能轻松地处理海量数据;利用Oracle可建立一种真正的Client/Server、Browser/ Server结构的空间信息系统,不仅解决了海量数据的存储、管理,以及海量数据存取速度问题,也解决了多用户编辑,数据完整性,数据安全机制等许多问题。</P> <P>然而,由于Oracle Spatial和MapInfo空间数据模型不完全一致,影响到基于Oracle Spatial的MapInfo企业GIS应用解决方案,最为突出的问题是注记的问题。由于Oracle Spatial自身不支持注记这种数据类型,所以MapInfo从5.5版本开始就只支持点、线、面空间数据的数据库存放,直到最新版本7.0也没实现注记的数据库存放。众所周知,地理空间数据除了点、线、面等地物特征之外还应包括注记。注记具有标识各种地物,指示地物属性和翻译的功能,在地理空间数据中占有非常重要的地位。没有注记的地图不能表达事物的空间概念,不能表示事物的名称和某些质量和数量特征。MapInfo不能在数据库中存放注记的缺陷不仅给注记信息的分布式应用、更新、一致性维护和数据安全等方面带来不便,同时也影响了其它点、线、面地理空间数据应用的整体效果。</P> <P>二、 解决方案</P> <P>既然MapInfo没有提供对注记的数据库存放的支持,那有没有别的办法来解决这一问题呢?答案显然是有的,本文在此提出三种解决方案并给出其各自的优缺点。</P> <P>第一种方案利用沌属性进行还原。具体做法是先用程序读取MapInfo图形文件中注记对象的属性,包括注记的坐标、注记的文本内容以及注记的字体、大小、颜色、样式等,然后将其存放到服务器的Oracle关系数据库中。在客户端应用时再根据这些属性将注记还原显示出来。这种方法的好处是可以将注记的相关属性信息直接存放到关系数据库中,而不需要空间数据库的支持。缺点是不能利用空间数据库的空间分析能力来对注记进行空间查询和拓扑分析等操作。</P> <P>第二种方法是通过标注点的属性的方式来显示注记。具体做法是以注记的中心点为定位点为每一个注记建立一个对应的点要素,然后将注记的文本内容作为点的一个属性字段值存放到相应的点中,最后将这些点空间数据上载(UpLoad)到Oracle Spatial空间数据库中。在客户端应用时,可以利用图层控制工具中的标注选项对点的注记属性字段进行标注,以达到显示注记的目的。这种方法的好处是在客户端应用时不需要做任何的编程处理,而且还可以利用空间数据强大的管理分析功能象其它点、线、面要素的一样进行空间查询和分析。因为这些注记都跟随一个相应的点要素,对这些点要素进行空间查询和拓扑分析的同时也就近似于对其所对应的注记进行空间查询和拓扑分析。这种方法的缺点是注记的样式受标注自身功能的限制而显得比较单一,同一图层的注记样式必须一致。</P> <P>第三种方法是前两种方法的一个综合。首先将注记的属性(包括注记的坐标、注记的文本内容以及注记的字体、大小、颜色、样式等)同样存放到以注记的中心点为坐标建立的点的属性字段中,然后将这些点空间数据上载(UpLoad)到Oracle Spatial空间数据库中。在客户端应用时,注记的显示由其存放在点属性中的信息进行还原显示,而不是通过标注来进行显示;另一方面又可以利用这些生成的点对注记进行近似的空间分析。这种方法吸取了前面两种方法的优点,既实现了注记显示多样化,又充分利用了空间数据库的功能可以对注记进行空间查询和分析。正因为这种方法综合了前面两种方法的优点,因此本文的下文将重点叙述用MapInfo的二次开发语言MapBasic来实现的这一种方法。</P> <P> 三、 MapBasic编程实现源码</P> <P>在进行编程之前首先介绍两个非常重要的MapBasic函数,一个是在读取注记属性用的,另一个是在客户端应用时还原注记用的。在MapBasic中可以用ObjectGeography (object ,attribute)来读取注记对象的属性信息,如ObjectInfo(objTXT.obj, OBJ_INFO_TEXTSTRING)可以读取objTXT(为注注对对象)对象中的字符串信息。在MapBasic中最完整的创建注记的语句如下:</P> <P>Create Text </P> <P>[ Into { Window window_id | Variable var_name } ] </P> <P>text_string </P> <P>( x1, y1 ) ( x2, y2 ) </P> <P>[ Font . . . ] </P> <P>[ Label Line { Simple | Arrow } ( label_x , label_y ) ] </P> <P>[ Spacing { 1.0 | 1.5 | 2.0 } ] </P> <P>[ Justify { Left | Center | Right } ] </P> <P>[ Angle text_angle ]</P> <P>在这个句子中,有[]标识的表示这些参数是可选择的,(x1,y1)和(x2,y2)分别指定注记的左下及右上角的位置,将来显示出来的注记的实际大小只由(x,y)来控制与MakeFont中定义的字体大小无关。例如在当前窗口创建一个注记的实例如下:</P> <P>Create Text into Window Frontwindow() "中国万里长城" (10,10)(20,20) </P> <P>Font MakeFont("宋体", 1, 12, BLACK, WHITE)</P> <P>上句中,12指所要创建的字体的大小,而将来显示出来的字符的实际大小只由(x,y)来控制,实际上12可以设为任何一个不等于0的值。</P> <P>在介绍完这两个重要的MapBasic函数之后,下面给出了应用实例的完整源程序代码,共两个程序,一个是将注记属性读取出来并存入临时文件(这个临时文件可以用MapInfo的easy upload工具直接上载到Oracle Spatial进行存贮管理)的转换程序,一个是客户端还原程序。本源程序在Windows2000、MapInfo6.5中文版和MapBasic6.5英文版调试通过。</P> <P><1>读取注记属性的源程序:在服务器端的程序最主要的功能就是要将注记在客户端还原时用到的参数读取出来,并存放到所对应的点的属性字段中。这个存有注记属性信息的点空间数据可以直接通过MapInfo的Upload工具上载到Oracle Spatial数据库中进行管理和分布式应用。</P> <P> '本程序用于将Mapinfo图层中的文字以属性的方式存放到另一个新的图层,</P> <P>'然后可将新的图层上转到Oracle数据库中,以解决Mapinfo数据库不支持文字对象的缺陷.</P> <P>'开发人:余应刚 时间:2002.9.5</P> <P>Declare Sub Txt2NewFile(ByVal oldFileName As String, ByVal newFileName As String)</P> <P>Declare Sub Main</P> <P> Sub main()</P> <P>Dim strOldFile As String</P> <P>Dim strNewFile As String</P> <P>strOldFile = "c:\temp\data\oldzj"</P> <P>strNewFile = "c:\temp\data\tempzj"</P> <P> Call Txt2NewFile(strOldFile, strNewFile)</P> <P>note "注记转换成功!" </P> <P>End Program </P> <P>End Sub</P> <P> Sub Txt2NewFile(ByVal oldFileName As String, ByVal newFileName As String)</P> <P>'oldFileName ,需要存贮到Oracle Spatial的注记文件名</P> <P>'newFileName ,用于存放属性的临时新文件名</P> <P> Include "MAPBASIC.DEF"</P> <P>Dim obj_Type As Integer '对象的类型</P> <P>Dim strTXT As String '文字注记字符串</P> <P>Dim obj_font as Font '字体</P> <P>Dim fnt_name As String '字体的名字</P> <P>Dim fnt_style As Integer '字体风格</P> <P>Dim fnt_pointsize As Integer '字体大小</P> <P>Dim fnt_forecolor As Integer '字体前影色</P> <P>Dim fnt_backcolor As Integer '字体背影色</P> <P>Dim f_x, f_y As Float '文字的中心坐标(x,y)</P> <P>Dim f_minx,f_miny,f_maxx,f_maxy As Float '文字的外接矩形坐标</P> <P>Dim f_angle As Float '角度</P> <P> '创建新的表存放文字注记的属性</P> <P>Create Table newTXT(txt char(50),fontname char(20),fontstyle Integer,fontpointsize Integer,</P> <P>fontforecolor Integer,fontbackcolor Integer,minx Decimal(9,5),miny Decimal(9,5),</P> <P>maxx Decimal(9,5),maxy Decimal(9,5), fangle Decimal(6,2))</P> <P>File newFileName Type DBF</P> <P> Commit Table newTXT</P> <P>Close Table newTXT</P> <P> '打开需要存贮到Oracle Spatial的注记文件</P> <P>Open Table oldFileName as oldTXT</P> <P>Set Paper Units "cm"</P> <P>'打开用于存放注记属性的临时文件</P> <P>Open Table newFileName as newTXT</P> <P>Create map for newTXT</P> <P> Fetch First From oldTXT</P> <P>Do While Not EOT(oldTXT)</P> <P>obj_Type = ObjectInfo(oldTXT.obj, OBJ_INFO_TYPE)</P> <P>Do Case obj_type</P> <P>Case OBJ_TYPE_TEXT '只对文本对象进行处理</P> <P>strTXT = ObjectInfo(oldTXT.obj, OBJ_INFO_TEXTSTRING)</P> <P>obj_font = ObjectInfo(oldTXT.obj, OBJ_INFO_TEXTFONT)</P> <P>fnt_name = StyleAttr( obj_font , FONT_NAME ) </P> <P>fnt_style= StyleAttr( obj_font , FONT_STYLE )</P> <P>fnt_pointsize = StyleAttr( obj_font , FONT_POINTSIZE )</P> <P>fnt_forecolor = StyleAttr( obj_font , FONT_FORECOLOR )</P> <P>fnt_backcolor = StyleAttr( obj_font , FONT_BACKCOLOR )</P> <P>f_x = ObjectGeography(oldTXT.obj, OBJ_GEO_TEXTLINEX)</P> <P>f_y = ObjectGeography(oldTXT.obj, OBJ_GEO_TEXTLINEy) </P> <P>f_minx = ObjectGeography(oldTXT.obj, OBJ_GEO_MINX)</P> <P>f_miny = ObjectGeography(oldTXT.obj, OBJ_GEO_MINY) </P> <P>f_maxx = ObjectGeography(oldTXT.obj, OBJ_GEO_MAXX)</P> <P>f_maxy = ObjectGeography(oldTXT.obj, OBJ_GEO_MAXY) </P> <P>f_angle = ObjectGeography(oldTXT.obj, OBJ_GEO_TEXTANGLE)</P> <P> '插入点要素,并将注记信息存放到属性字段中</P> <P>Insert Into newTXT(obj,txt, fontname, fontstyle, fontpointsize, </P> <P>fontforecolor,fontbackcolor,minx,miny,maxx,maxy,fangle)</P> <P>Values(CreatePoint(f_x,f_y), strTXT, fnt_name, fnt_style, fnt_pointsize,</P> <P>fnt_forecolor, fnt_backcolor, f_minx, f_miny, f_maxx,f_maxy,f_angle)</P> <P>End Case</P> <P>Fetch Next From oldTXT</P> <P>Loop</P> <P>Commit Table newTXT</P> <P> End Sub</P> <P><1>客户端还原源程序:本程序主要用于将存有注记信息的点文件还原为注记的显示形式。要得到这个文件,可以用MapInfo直接打开先前上载到Oracle Spatial中的点要素图层,MapInfo会自动将其下载到本地。</P> <P> '本程序根据注记的属性信息还原为文字显示</P> <P>'开发人:余应刚 时间:2002.9.5</P> <P> Declare Sub File2NewTXT(ByVal oldFileName As String, ByVal newFileName As String)</P> <P>Declare Sub Main</P> <P> Sub main()</P> <P>Dim strOldFile As String</P> <P>Dim strNewFile As String</P> <P>strOldFile = "c:\temp\data\tempzj"</P> <P>strNewFile = "c:\temp\data\newzj"</P> <P> Call File2NewTXT(strOldFile, strNewFile)</P> <P>note "注记还原成功!" </P> <P>End Program </P> <P>End Sub</P> <P> Sub File2NewTXT(ByVal oldFileName As String, ByVal newFileName As String)</P> <P>'oldFileName ,存放有注记属性的注记文件名</P> <P>'newFileName ,用于存放文字注记对象的临时新文件名</P> <P> Include "MAPBASIC.DEF"</P> <P>Dim obj_Type As Integer '对象的类型</P> <P>Dim strTXT As String '文字注记字符串</P> <P>Dim obj_font as Font '字体</P> <P>Dim fnt_name As String '字体的名字</P> <P>Dim fnt_style As Integer '字体风格</P> <P>Dim fnt_pointsize As Integer '字体大小</P> <P>Dim fnt_forecolor As Integer '字体前影色</P> <P>Dim fnt_backcolor As Integer '字体背影色</P> <P>Dim f_minx,f_miny,f_maxx,f_maxy As Float '文字的外接矩形坐标</P> <P>Dim f_angle As Float '角度</P> <P>Dim selnum As Integer '选择的记录数</P> <P> '创建新的表存放文字注记对象</P> <P>Create Table newTXT(txt char(30))</P> <P>File newFileName Type DBF</P> <P>Commit Table newTXT</P> <P>Close Table newTXT</P> <P> '打开需要存有注记属性的文件</P> <P>Open Table oldFileName as oldTXT</P> <P> '打开用于存放注记对象的临时文件</P> <P>Open Table newFileName as newTXT</P> <P>create map for newTXT</P> <P>Map From newTXT</P> <P>Set Map Layer 1 Editable On</P> <P> Select * from oldTXT</P> <P>selnum = SelectionInfo(SEL_INFO_NROWS)</P> <P>If selnum < 1 Then</P> <P>Exit Sub</P> <P>End If</P> |
|
|
|
1楼#
发布于:2004-12-30 11:37
<img src="images/post/smile/dvbbs/em08.gif" />
|
|
|
2楼#
发布于:2005-01-02 14:51
毕业论文准备选择mapinfo的二次开发设计!晕啊!
|
|
|
3楼#
发布于:2005-01-05 10:39
<img src="images/post/smile/dvbbs/em05.gif" />
|
|
|
|
4楼#
发布于:2005-01-09 15:32
Great!<img src="http://www.gisempire.com/bbs/Skins/Default/emot/em02.gif"><img src="http://www.gisempire.com/bbs/Skins/Default/emot/em08.gif"><img src="http://www.gisempire.com/bbs/Skins/Default/emot/em01.gif">
|
|