发表用户:xxzxzax
收集整理:James.Liu
相关讨论:http://www.mygis.com.cn/forum/dispbbs.asp?boardID=4&ID=7411
信息原始来源:不祥

文章标题:关于逐层细化图层

逐层细化图层使用户得以执行逐层细化分析和探测。如果地图包含逐层细化图层,用户就可以通过鼠标指向和单击地图的某个区域得到该区域更详细的信息。逐层细化图层所提供的直观、易用的界面使用户得以通过指定和单击来探测数据。

     
第一节 “逐层细化”应用程序开发步骤

逐层细化应用程序需要相当数量的设置以及精心地准备。主要步骤总结如下:
1. 获取用来建立多层次逐层细化图层的多种表。可以使用 MapInfo Professional 创建表,或者从 MapInfo 公司或第三方供应商处购买表。
2. 使用特殊的列和特殊的元数据创建新的空逐层细化表(.tab 文件)。元数据为每一张成员表分配层次名,并且标识成员表中的重要列--ID 列和标题列。
3. 把逐层细化表加入地图(例如,把逐层细化表加入所使用的 Geoset(s)中,或者通过象 Layers.Add 这样的方法,把逐层细化表添加到地图中)。
4. 添加用户接口元素(例如工具栏按钮)到应用程序中,以便用户选择逐层细化工具并单击地图来进行细化。
向应用程序添加代码来响应用户对逐层细化工具的使用(即:编写层次结构管理器)。此代码需要检测用户所选择的图元;确定替换图元的子图元;并调用一些方法 (DrilldownRemoveFeatures, DrilldownAddFeatures) 来展开或者收缩地图图元。
第二节 准备“逐层细化”图层

要创建逐层细化图层,需要提供由两个或更多 MapInfo 表组成的表集合。特别地,需要:
 逐层细化图层的每一层次的详细信息都需要一张 MapInfo 表。这些被称为成员表。
 额外会有包含特殊元数据的空表来描述成员表。它被称为逐层细化表。
成员表的要求

逐层细化图层中的每个图元都必须有标识关键字(可能是字符串,如 “New York”)。在单个层次中的所有关键字必须是唯一的;例如,州边界层只能包含一个被称为 “Washington”的州。但是,对于逐层细化图层的所有其它层次,图元的标识关键字是不需要唯一的。例如,逐层细化图层包含州边界和县市边界,就可以同时有 “Washington” 州和 “Washington” 县。
“逐层细化”表的要求

逐层细化表与其它表不同,它只包含一个文件:filename.tab。
逐层细化表的 .tab 文件必须定义特定的列和元数据关键字,描述如下:
逐层细化表必须定义三个标准列:Key、Level 和 Label。所有这三列都为字符(字符串)列,32个字符宽度。
逐层细化表必须包含一系列元数据关键字。元数据关键字语法如下:
 以关键字 begin_metadata 标记 .tab 文件元数据部分的开始。
 原数据的每一行都有两个元素:关键字和数值。例如,关键字 “\IsDrilldown” 值为 “True”。所有的关键字和数值都用双引号括起来。
 逐层细化表必须包含 “\IsDrilldown” 关键字,且此关键字值必须为 “True”。
 每一个关键字都以字符 “\” (反斜线)开始。
 元数据关键字可以层次化地嵌套。层次结构的每一层次用反斜线 (\) 符号标记。关键字值限制最多为 239 个字符。
 逐层细化表包含 \DDMap\ComponentMaps\ 关键字层次结构。在此层次结构中,为每一张成员表指定四个元数据关键字:
成员表元数据关键字 
 关键字 描述
 File  必需的关键字,指定成员表路径和文件名。
 LevelID  必需的关键字,为此成员表定义标识符。
FeatureIDCol  指定成员表中包含唯一逐层细化关键字的列号。可选关键字;如果忽略,列号为 1。
FeatureCaptionCol 指定成员表中用来作标注的列号。可选关键字;如果忽略,列号为 1。
 
例如,“逐层细化表示例”包含如 “\DDMap\ComponentMaps\One\LevelID”和“\DDMap\ComponentMaps\Twox\LevelID”这样的关键字层次结构。请注意 DDMap、ComponentMaps 和 LevelID 是关键字层次结构标准的、必需的部分,而 One 和 Twox 是可自定义的。可使用任何喜欢的关键字名代替 One、Twox、Twoxx 等等;那些关键字名只是用来区分每个成员表的关键字集。
“逐层细化”表示例
逐层细化表示例内容如下。如果要创建自己的逐层细化表,可以复制该示例到一文本文件,并参照自己的成员表进行修改。
!table
!version 300
!charset WindowsLatin1

Definition Table
  Type Native Charset "WindowsLatin1"
  Fields 3
    Key Char (32);
    Level Char (32);
    Label Char (32);

begin_metadata
"\IsDrilldown" = "TRUE"
"\DDMap\ComponentMaps\One\File" = "C:\Program Files\MapInfo\Data\USA\usaXXX.TAB"
"\DDMap\ComponentMaps\One\LevelID" = "USA"
"\DDMap\ComponentMaps\One\FeatureIDCol" = "3"
"\DDMap\ComponentMaps\One\FeatureCaptionCol" = "1"

"\DDMap\ComponentMaps\Twox\File" = "C:\Program Files\MapInfo\Data\USA\2Region.TAB"
"\DDMap\ComponentMaps\Twox\LevelID" = "2Region"
"\DDMap\ComponentMaps\Twox\FeatureIDCol" = "1"
"\DDMap\ComponentMaps\Twox\FeatureCaptionCol" = "3"

"\DDMap\ComponentMaps\Twoxx\File" = "C:\Program Files\MapInfo\Data\USA\MultiRegionSales.TAB"
"\DDMap\ComponentMaps\Twoxx\LevelID" = "MultiRegion"
"\DDMap\ComponentMaps\Twoxx\FeatureIDCol" = "1"
"\DDMap\ComponentMaps\Twoxx\FeatureCaptionCol" = "3"

"\DDMap\ComponentMaps\Two\File" = "C:\Program Files\MapInfo\Data\USA\states.TAB"
"\DDMap\ComponentMaps\Two\LevelID" = "States"
"\DDMap\ComponentMaps\Two\FeatureIDCol" = "3"
"\DDMap\ComponentMaps\Two\FeatureCaptionCol" = "1"

"\DDMap\HierarchyManager\IsDLL" = "TRUE"
"\DDMap\HierarchyManager\ID" = "SomeDLL.dll"
"\DDMap\HierarchyManager\InitialLevel" = "USA" 
end_metadata
第三节 创建逐层细化和卷起工具

创建“细化”工具
使用 CreateCustomTool 方法可以实现逐层细化工具。CursorConstants 集包括两个为逐层细化应用程序特别提供的光标:miDrilldownExpandCursor 和 miDrilldownContractCursor。例如:

每次使用自定义逐层细化工具将触发 ToolUsed 事件。在 ToolUsed 事件过程中,需要执行引起逐层细化动作的代码。这基本上是一个四步过程:
1. 使用如 SelectByPoint 或 SearchAtPoint 这样的方法,确定用户所单击的地图图元。
2. 确定用来替换用户所单击图元的子图元集。例如,可使用一个或者更多嵌套的 Case 语句来确定用来替换所选父图元的子图元。
3. 调用 DrilldownAddFeatures 方法添加子图元到地图。
4. 调用 DrilldownRemoveFeatures 方法从地图上删除父图元(用户所单击的图元)。
说明:这些添加/删除操作绝不会修改组件表;即并不是“编辑”表。使用DrilldownAddFeatures 方法添加图元,唯一的效果是复制图元到当前可视的图元集。
创建“卷起”工具
当实现逐层细化工具后,可能希望为用户提供卷起工具——与逐层细化工具有相反效果的工具。
可使用与创建逐层细化工具相同的方式来创建卷起工具。将会使用同样的方法 (DrilldownAddFeatures 和 DrilldownRemoveFeatures)。不同的是不是添加子图元和删除父图元,而是做相反操作——添加父图元和删除子图元。
示例:“逐层细化”/“卷起”工具示例
以下示例 ToolUsed 事件过程说明如何操作逐层细化工具。
此过程为以下图层层次结构来处理逐层细化图层:
 USA 包含单个区域的图层,代表整个美国。
 2Region 包含两个大区域(东区和西区)的图层。每一个区域覆盖大约一半的美国疆域。
 MultiRegion 包含八个小区域的图层。每一个区域覆盖大约八分之一的美国疆域。
 States 包含美国五十个州的图层。

此示例为Map1_ToolUsed函数的节选,主要阐明细化工具的工作方式 
………………………………………………
    Dim AddKeys() As String
    Dim NewLevel As String
    Dim fs As Features
    Dim strLevel As String
    Dim DelKeys() As String
    Dim pnt As New Point

    ' ---------------------------------------------
    ' Expand
    ' ----------------------------------------------
    If (ToolNum = customDrilldownExpandTool And Ctrl = False) Or (ToolNum = customDrilldownContractTool And Ctrl = True) Then
        ' Figure out which object we have
        pnt.Set X1, Y1
        Set fs = drilldownLayer.SearchAtPoint(pnt)

        If fs.Count = 1 Then
            ReDim DelKeys(0)
            drilldownLayer.KeyField = "Level"
            strLevel = fs(1).Keyvalue

            drilldownLayer.KeyField = "Key"
            DelKeys(0) = fs(1).Keyvalue

            If strLevel = "USA" Then
                NewLevel = "2Region"
                ReDim AddKeys(1)
                AddKeys(0) = "West"
                AddKeys(1) = "East"
            ElseIf strLevel = "2Region" Then
                NewLevel = "MultiRegion"
                ReDim AddKeys(3)
                Select Case DelKeys(0)
                    Case "West"
                        usaLevel = usaLevel + 1
                        AddKeys(0) = "mrRgn1"
                        AddKeys(1) = "mrRgn2"
                        AddKeys(2) = "mrRgn3"
                        AddKeys(3) = "mrRgn4"
                    Case "East"
                        usaLevel = usaLevel + 1
                        AddKeys(0) = "mrRgn5"
                        AddKeys(1) = "mrRgn6"
                        AddKeys(2) = "mrRgn7"
                        AddKeys(3) = "mrRgn8"
                End Select
            ElseIf strLevel = "MultiRegion" Then
                NewLevel = "States"
                Select Case DelKeys(0)
                    Case "mrRgn1"
                        westLevel = westLevel + 5
                        ReDim AddKeys(4)
                        AddKeys(0) = "16"
                        AddKeys(1) = "30"
                        AddKeys(2) = "41"
                        AddKeys(3) = "53"
                        AddKeys(4) = "56"
                    Case "mrRgn2"
                        westLevel = westLevel + 6
                        ReDim AddKeys(5)
                        AddKeys(0) = "04"
                        AddKeys(1) = "06"
                        AddKeys(2) = "08"
                        AddKeys(3) = "32"
                        AddKeys(4) = "35"
                        AddKeys(5) = "49"
                    Case "mrRgn3"
                   ……………………
       Case "mrRgn8"
……………………
                End Select
            Else
                MsgBox "Can't drilldown any further; Level: " + strLevel + " Key: " + DelKeys(0)
                Exit Sub
            End If
        ElseIf fs.Count = 0 Then
            MsgBox "No features selected."
            Exit Sub
        Else
            MsgBox "More than one feature selected; can only drilldown on exactly one item."
            Exit Sub
        End If
        
        drilldownLayer.DrillDownRemoveFeatures strLevel, DelKeys
        drilldownLayer.DrillDownAddFeatures NewLevel, AddKeys
  
    ' ---------------------------------------------
    ' Contract
    ' ----------------------------------------------
    ElseIf (ToolNum = customDrilldownContractTool And Ctrl = False) Or (ToolNum = customDrilldownExpandTool And Ctrl = True) Then
 …………………………
 End If
End Sub
重置“逐层细化”图层

可以通过调用 DrilldownReset 方法重置逐层细化图层。重置逐层细化图层会清除整个图层,而且使用一张成员表的图元重新初始化图层。
第四节 “逐层细化”图层的限制和要求

逐层细化图层受到一些限制,总结在下面的列表中。
 逐层细化图层中每一个图元必须拥有一个 ID,该 ID 在所属成员表中是唯一的(尽管 ID 并不需要在构成逐层细化图层的所有的成员表中是唯一的)。
 不能在逐层细化图层中使用栅格图像衬垫表。
 当使用 Themes.Add 创建专题时,将花费一些时间用大量的数据行来计算图层范围,例如逐层细化或是服务器图层。Add 方法的 ComputeTheme 参数使您得以为任意专题类型创建非计算专题。非计算专题使您得以创建没有自动计算范围的专题。可以自己创建范围。这对逐层细化或服务器图层来说是比较快的方法。
 逐层细化图层不会“记录”各种不同逐层细化层次的状态(图元被展开,等等)。如果希望应用程序恢复上一次使用地图时精确的状态,需要在退出时编写代码存储地图的逐层细化设置,并在启动时恢复设置。
 虽然可以编辑逐层细化图层的图元,但不会保存编辑,且成员表不受编辑的影响。当编辑逐层细化图层中的图元时,不是修改成员表,而是修改从成员表的图元的临时副本。