第十六章表图层与工作空间.docx
《第十六章表图层与工作空间.docx》由会员分享,可在线阅读,更多相关《第十六章表图层与工作空间.docx(14页珍藏版)》请在冰豆网上搜索。
第十六章表图层与工作空间
第十六章表、图层与工作空间
表的管理可分为对表结构的管理和对表中数据的管理。
有关表、图层与工作空间,前面章节已有所述。
本章重点介绍怎样使用MapBasic语句和函数打开、创建、修改、维护和管理表、图层和工作空间。
16.1表的打开、创建与维护
16.1.1打开表
MapBasic应用程序在进行许多操作之前,首先必须打开表以获取数据,如建立地图窗口、浏览窗口等。
MapBasic提供OpenTable语句来打开一个已经存在的表。
下例表示以别名AllCapital打开表worldcap。
OpenTable"c:
\MapInfoProfessional\Data\World\worldcap"AsAllCapital
在OpenTable语句中可以包含As、Hide、ReadOnly、Interactive等关键字。
As子句表示以一个别名打开这个表,当As子句缺省时,MapBasic以表不带扩展名的文件名作为别名;Hide表示这个表对于任意一个打开表对话框是隐藏的;ReadOnly设置该表为只读的;可选的Interactive子句表示当打开的表在指定目录中找不到时,MapInfoProfessional会显示一对话框,让用户定位该表,否则,当指定表在指定目录中无法定位时,就会出现出错信息。
当用户以缺省别名方式打开两个同名的表时,MapInfoProfessional会为第二个表重新创建一个别名,而不能用缺省别名。
如当打开表"C:
\1993\SITES.TAB"和表"C:
\1994\SITES.TAB"时,MapInfoProfessional为表"C:
\1993\SITES.TAB"创建别名"Sites",为表"C:
\1994\SITES.TAB"创建别名"Sites_2"以示区别。
如果OpenTable语句中包含Interactive子句,MapInfoProfessional提醒用户为第二个表选择一个名字。
以别名打开一个表时,并不能改变这个表真正的名字,当关闭以别名命名的表时,这个别名随之注销。
若要更改表的名字,应该使用RenameTable语句。
执行下面语句,将表CASANFRA重新命名为C:
\MAPINFOPROFESSIONAL文件夹下的表SF_HIWAY。
OpenTable"C:
\DATA\CASANFRA.TAB"
RenameTableCASANFRAAs"C:
\MAPINFOPROFESSIONAL\SF_HIWAY"
表打开后,可用TableInfo()函数获得已打开的表的信息,函数可根据获得信息的类
型返回相应的逻辑、整型、字符串型等值。
TableInfo()函数可以获取表的多种信息,信息类型由函数的第二个参数表示。
如下面语句表示获取表“CASANFRA”的字段数。
DiminforAsInteger
OpenTable"C:
\DATA\CASANFRA.TAB"
infor=TableInfo("CASANFRA",TAB_INFO_NCOLS)
MapBasic也可打开其它文件格式的表,如Dbase、Foxbase、Excel、Lotus文件及文本文件,但在打开这些文件之前必须把它们转换为MapInfo表(.tab文件),这种转换在MapBasic中称为“注册”。
非MapInfo表格式的文件只有在注册后,才能当作MapInfo表。
MapBasic提供Register语句对非MapInfo表格式的文件进行注册。
下例是将一个Excle文件注册为名字为"Report23"的表,并打开这个表。
RegisterTable"c:
\MapInfoProfessional\data\rpt23.xls"
Type"XLS"
Into"Report23"
OpenTable"c:
\MapInfoProfessional\data\Report23"
使用完一个表后,可以用CloseTable语句关闭表。
如果一个表用于多个统计窗口或浏览窗口,关闭时这些窗口会自动关闭,如果关闭地图窗口中仅有的一个表,则这个地图窗口也会关闭,CloseAll语句可以关闭所有正在使用的表。
如下例:
OpenTable"world"
……
CloseTableworld
16.1.2创建表
MapBasic提供CreateTable语句来创建一个新表,表最多只能有250个字段。
CreateIndex语句为表创建索引,CreateMap语句使表可以显示在地图窗口中,但不能打开地图窗口,若要打开地图窗口应该用Map语句。
在程序示例16-1中,创建了一个DBF类型的新表Towns。
程序示例16-1
CreateTableTowns
(townnameChar(30),‘第一个字段的字段名为townname,数据类型为字符串数组
populationSmallInt,‘第二个字段的字段名为population,数据类型为SmallInt
median_incomeDecimal(9,2))‘第三个字段的字段名为median_income,数据类型为Decimal(9,2)
File"C:
\MAPINFOPROFESSIONAL\DATA\TOWNS"‘表的存放目录
TypeDBF‘表为DBF型文件
CreateMapForTowns‘使表Towns可以地图化
CreateIndexOnTowns(townname)‘为字段townname创建索引
DropTable语句用于删除一个已经打开的表,这里的删除是指将表从磁盘上完全删除,不仅可以删除MapInfoProfessional中的表,而且可以删除已经注册为MapInfoProfessional格式的数据库源文件或电子表格源文件。
用DropTable语句删除的表不能用“撤消”命令恢复,同样,MapBasic也不能用Rollback语句撤消该命令,所以,使用DropTable语句时要谨慎。
OpenTable"clients"‘打开表clients
……
DropTableclients‘删除表clients
16.1.3修改表结构
表结构是指对表和构成表的字段的定义等。
在MapInfoProfessional中用户可以使用“表>维护>表结构”命令来改变表的结构,MapBasic提供了相应的一些语句如AlterTable、CreateIndex等来修改表的结构,但MapBasic语句不能修改由电子表格或ASCII文件注册生成的表,也不能修改由Select语句生成的临时表的结构。
如程序示例16-2所示。
程序示例16-2
OpenTable"gcpop"‘打开表gcpop
AlterTablegcpop
(Renamepop_88population‘将字段population重新命名为pop_88
Dropmetsize,fipscode,utmcode‘删除字段metsize、fipscode和utmcode
AddschoolcodeSmallint,federalaidFloat‘添加字段schoolcode和federalaid,
‘类型分别为Smallint和Float
Orderschoolcode,population,federalaid)‘规定字段的顺序
在使用AlterTable语句修改表结构之前,必须保存或放弃所有对表进行的编辑,添加的字段类型只能是Integer、SmallInt、Float、Decimal(size,decplaces)、Char(size)、Date或Logical中的一种。
当使用AlterTable语句修改一个带有备注栏的表时,会丢失这个备注栏。
同许多MapBasic语句一样,AlterTable语句也可以带有Interactive关键字。
建立字段的索引有利于MapInfoProfessional查询,MapBasic提供CreateIndex语句建立索引,DropIndex删除索引,在建立和删除索引前也必须保存或放弃所有对表进行的编辑。
下例是用表World的"Capital"字段建立索引的例子:
OpenTable"world"Interactive
CreateIndexonWorld(Capital)‘建立索引
DropIndexWorld(Capital)‘删除索引
当在表中添加一个临时字段或用另一个表中的数据更新一个已经有字段的列时,可以使用AddColumn语句。
该语句只是创建一个临时的字段,并不能将这个字段保存在磁盘中。
但如果这个字段来源于数据库表,并且保存了包含这个字段的工作空间时,就可以在打开工作空间时看到这个字段。
如果在表中添加一个永久性的字段,可以使用上面介绍的AlterTable语句。
AddColumn
stores(countychar(20))‘在表stores中添加字段"county",字段类型为char(20)
Fromcounties‘从表counties中获取数据
Settocname‘将新添加的字段放入表counties中的"cname"字段
16.1.4无缝表
由几个表组合在一起并且可以当作一张表来处理的表称为无缝表。
使用无缝表可以一次将整组表添加到地图窗口中,就好象添加一张表一样。
无缝表的每一条记录对应组成无缝表的基表,第一个字段为每一张基表的表名,第二个字段为对基表的描述。
在表名字段中可以包含表的目录,若所有表与无缝表在同一目录下则可缺省目录。
MapBasic提供SetTable语句设置无缝表的开关,关闭无缝表后,可以对组成无缝表的基表进行编辑。
SetTableDCMetroASeamlessOn‘打开无缝表DCMetroA
SetTableDCMetroASeamlessOff‘关闭无缝表DCMetroA
所有组成无缝表的基表的结构应该一致,如具有相同的字段数,具有相同的字段名等。
无缝表对作为地图矢量背景数据的显示极为有用,但MapBasic对其使用仍然有一些限制:
•不能同时选择同在一张无缝表的不同基表中的对象;
•Find语句每次只能对一张基表进行操作,而不能对整个无缝表进行操作;
•地图窗口中的无缝表不能编辑;
•不能为无缝表生成专题地图。
用SetTable语句还可以设定表的其它属性,如表是否可编辑、表是否只读、表是否显示在一个建立新窗口的对话框中等。
下面语句表示表World不会出现在关闭表对话框中。
SetTableWorld
UserCloseOff
16.2表的数据维护
16.2.1从表中读写数据
对地图进行分析时必然需要使用表中的数据。
MapBasic获取表数据通常有两步:
首先用Fetch语句去指定欲查询的行,然后用表达式引用如“表名.字段名”的方法去访问当前行的某一列。
函数EOT()测定指针是否已经超过表的结束符,若指针还指着一条有实际内容的记录,函数返回FALSE;若它已超过了记录的最后一条,则返回TRUE。
如下所示。
OpenTable"states"
FetchRec3Fromstates‘选择表states的第三行记录
Notestates.state_name‘显示第三行的state_name字段
DoWhileNotEOT(world)‘判断是否已经选中了一行
i=i+1
FetchNextFromworld
Loop
使用不同的Fetch…语句,可以定位不同的记录,如表16-1。
访问字段也有几种方法,如表16-2。
表16-1Fetch…语句功能
语句
功能
FetchFirst
光标定位在表的第一行记录
FetchLast
光标定位在表的最后一行记录
FetchNext
移动光标到表的下一行记录
FetchPrev
移动光标到表的前一行记录
FetchRecn
将光标放置在特定的一行记录上,n代表第n行记录
表16-2访问字段方法
形式
例子
功能
表名.字段名
World.Country
‘选取表World的Country字段
表名.Coln
World.Col1
‘选取表World的第一个字段
表名.col(number)
World.col(i)
‘选取表World的第i个字段
用Insert语句可以向表中添加记录,添加记录的方法有两种:
一是一次只添加一条记录;一是通过Select语句添加另一张表的一组数据到该表中,每次插入的记录的字段数必须与字段列表中的字段数一致。
如果在Insert语句中没有指定字段列表,则Mapbasic认为是所有的字段。
使用Commit语句可以将插入字段保存,否则这个字段只能是一个临时字段。
下例是向表customer中添加一条记录,记录为字段Name,赋值为SteveHarris,其它字段的值均为空值,保存所作修改。
InsertIntocustomers(Name)
Values("SteveHarris")
CommitTablecustomers
若已经知道了一张表的所有字段名,要在表中添加一条完整的记录,则不必指明字段名。
如下面的例子中,已知表customers中有四个字段,分别是姓名、住址、所在省市、电话号码,添加一条记录如下所示:
InsertIntocustomers
Values("张三","珞喻路129号","湖北省武汉市","87654321")
有时需要将两张表合并,下例说明了如何合并两张表:
将表NJ_ZIPS添加到表NY_ZIPS中。
需要注意的是,合并的两张表的表结构必须相同,即字段定义和字段类型应该是相同的,若只是添加另一张表中的个别字段,则应该在语句中指明字段名。
InsertIntoNY_ZIPS
Select*FromNJ_ZIPS
更新已有记录中的某个字段的值用Update语句,该语句可以与Select语句、Commit语句、RollBack语句等组合使用。
下例将表employee中的字段salary增加7个百分点,而后放弃所作修改。
Select*Fromemployees
Wheredepartment="marketing"Andsalary<20000
UpdateSelection
Setsalary=salary*1.07
RollBackTableemployees
16.2.2从表中选择数据
MapBasic的Select语句的语法类似于SQL(StructureQueryLanguage)中的Select语句,该语句具有强大的查询功能,可以从一个或多个表中选取需要的记录或者字段,并将选取的记录或字段当作一个临时表对待,Select语句具体执行功能要看它所包含的子句。
例如,若建立一个过滤器,可以包含Where子句;若求部分数据的和,可以包含GroupBy子句;若要对选择的数据进行排序,可以包含OrderBy子句。
Select语句的具体应用将在第十九章地图对象及其查询、分析中叙述。
16.2.3从表中查找数据
Find语句用于在表中查找符合某一条件的地图对象数据,只能用于可地图化的表中。
在Find语句之前用FindUsing语句可以指定表中字段,若Find语句之前没有FindUsing语句,则MapBasic查寻MapInfoProfessional中最近一次使用“查询>查找”命令时所选定的表,见程序示例16-3。
Find语句不能自动将查找结果显示在地图上,若要在地图上显示确定满足查找条件的位置,可以用CreatePoint语句或CreatePoint()函数等来实现。
程序示例16-3
Include"mapbasic.def"
Dimx,yAsFloat,win_idAsInteger
OpenTable"states"Interactive
MapFromStates
win_id=FrontWindow()
FindUsingstates(state)‘设定要查找的字段
Find"NY"
IfCommandInfo(CMD_INFO_FIND_RC)>=1Then
x=CommandInfo(CMD_INFO_X)
y=CommandInfo(CMD_INFO_Y)
SetMap‘将查找到的点设置为地图中心
Windowwin_id
Center(x,y)
'在查找到的位置设定一个标志并在装饰图层中创建一个对象
InsertInto
WindowInfo(win_id,WIN_INFO_TABLE)(Object)
Values(CreatePoint(x,y))
Else
Note"Locationnotfound."
EndIf
MapBasic可以将查找结果存储在一个系统变量中,这个系统变量的值可以通过CommandInfo()函数获得。
函数CommandInfo(CMD_INFO_FIND_RC)用于检验查找结果匹配情况:
若查找结果完全匹配返回1;若查找结果基本上匹配返回大于1的值;若查找失败返回一个负值。
函数CommandInfo(CMD_INFO_X)和CommandInfo(CMD_INFO_Y)保存查找到的点的位置。
16.3元数据操作
16.3.1MapInfoProfessional的元数据
元数据,即关于数据的数据。
在MapBasic中表的.TAB文件中保存的数据就是元数据,用以说明表的属性。
例如,如果保存表的修改者或修改时间,可以以元数据的形式保存。
每一个元数据关键字都有以反斜杠“\”开头的名字,且总是为字符串型的值,最长可达239个字符。
每一个表中可以有多个元数据关键字,每一个关键字代表一种信息,如作者姓名、版权信息等。
表16-3列出了MapInfoProfessional表提供的一些元数据关键字。
表16-3元数据关键字
关键字名
示例
“\CopyrightNotice”
“Copyrighr1995AcmCorp.”
“\Info”
“TaxParcelsMap”
“\Info\Author”
“LauraSmith”
“\Info\Date\Start”
“12\14\95”
“\Info\Date\End”
“12\31\95”
“\IsReadOnly”
“FALSE”
在标准MapInfoProfessional用户界面中,元数据对用户是隐藏的,除非用户以文本文件的形式打开.TAB文件才能查看元数据。
MapBasic应用程序提供了对元数据进行读写和修改操作的函数和语句。
16.3.2元数据的修改
MapBasic提供MetadataTable语句以创建、修改或删除元数据。
下面语句为表Parcels的元数据关键字"\Info\Date"赋一个值,如果关键字已经存在,给关键字赋一个新值;如果关键字不存在,则创建一个新的关键字。
MetaDataTableParcelsSetKey"\Info\Date"ToStr$(CurDate())
第一次给表添加一个元数据关键字时,MapInfo会自动生成一个"\IsReadOnly"元数据关键字,并为"\IsReadOnly"赋缺省值FALSE。
MetaDataTableParcelsDropKey"\Info"Hierarchical
上面语句删除关键字"\Info",关键字Hierarchical表示可以删除"\Info"下一层的所有关键字。
如上例,若一个表有两个关键字"\Info\Author"和"\Info\Date",用上句可以一次性将它们都删除。
16.3.3元数据的读取
有时即使不知道元数据关键字的名字,同样也可用MetaData语句从表中读取元数据。
用MetadataTable…SetTraverse语句初始化一个遍历;用MetadataTraverse…Next语句获得一个关键字;用MetadataTraverse…Destroy语句结束遍历并释放遍历占用的内存。
程序示例16-4说明了怎样遍历表的元数据,表名为caller。
程序示例16-4
SubPrint_Metadata(ByValtable_nameAsString)
Dimi_traversalAsInteger
Dims_keyname,s_keyvalueAsString
‘********初始化遍历**********
MetadataTabletable_name
SetTraverse"\"HierarchicalIntoIDi_traversal
‘******获取第一个关键字******
MetadataTraversei_traversal
NextIntoKeys_keynameIntoValues_keyvalue
‘执行循环,每执行一次,得到一个关键字并打印到消息窗口,直到获得所有关键字
DoWhiles_keyname<>""
Print""
Print"Keyname:
"&s_keyname
Print"Keyvalue:
"&s_keyvalue
MetadataTraversei_traversal
NextIntoKeys_keynameIntoValues_keyvalue
Loop
‘*******终止遍历,并释放内存*******
MetaDataTraversei_traversalDestroy
EndSub
16.4几种特殊的图层
在MapInfo中,图层与表是相联系的一个概念。
图层来源于含有图形对象的数据库表,每一个含有图形对象的数据库表都可以显示为一个图层。
关于图层的一般操作在第十五章第三节中已作了介绍,如可以用AddMapLayer语句在已有的地图窗口中增加一个图层;用RemoveMapLayer语句删除已有地图窗口中的一个图层;用SetMap语句设置图层的开关属性等等。
本节主要介绍几类特殊的图层。
16.4.1装饰图层
MapInfoProfessional中的每个地图窗口都有一个装饰图层,装饰图层总是在地图窗口的最顶层,不能删除也不能重新放置装饰图层的位置,装饰图层用于存储地图的标签。
由于每个地图窗口都有一个装饰图层,所以装饰图层就以地图窗口打开的顺序来命名。
如第一个打开的地图窗口的装饰图层就叫做Cosmetic1,第二个打开的地图窗口的装饰图层叫做Cosmetic2,以此类推。
MapBasic程序将装饰图层当作一个表,对之可进行各种操作。
例如,用Select语句选取装饰图层中的对象:
Sel