MapObejcts组件应用设计(地图与图层)

时间:2022-05-01 03:14:03

2.2.1 地图浏览

  在地图窗口中,放大、缩小、漫游地图是地图控件的基本功能,运行附属光盘中的liulan程序,体会浏览的操作含义。liulan程序主窗口中含有一个工具栏和一个地图窗口,工具栏中的按钮功能依次是漫游、全范围显示地图、放大、缩小,使用这些按钮在地图窗口中用鼠标左键进行单击及拖放操作,体验操作过程。

放大、缩小、漫游是MapObjects.Map控件提供的功能,浏览功能由Map控件的方法实现。在以下关于浏览项功能的程序语句中,Map1是添加到Form窗体上的Map控件,是Map的一个实例,Map1所占据的矩形区域称为控件窗口,地图在控件窗口中显示,又称地图窗口。以下是liulan程序中实现浏览功能的关键语句。

1地图漫游

 Map1.Pan

Map1控件窗口中,接受鼠标左键的拖放操作,将窗口中的地图从按下鼠标的位置拖到释放鼠标的位置。

2全范围显示地图

 Map1.Extent = Map1.FullExtent   设置地图窗口的显示范围

 Map1.FullExtentMap1窗口中全部图层外围矩形的并,长度单位与地图数据坐标单位相同。 Map1.ExtentMap1窗口以地图数据坐标长度单位表示的外围矩形,控置地图的显示范围。语句Map1.Extent = Map1.FullExtent  重新设置地图窗口的显示范围,触发地图窗口重绘,产生显示全图视觉效果。

3放大(拖框放大)

      Dim r As MapObjects2.Rectangle

      Set r = Map1.TrackRectangle       在窗口中拖绘一个矩形,返回矩形的引用

      If Not r Is Nothing Then Map1.Extent = r  设置地图窗口的显示范围

Map1.TrackRectangleMap控件交互式绘制矩形的方法,它接收鼠标左键的一次拖放操作。以鼠标按下时光标所在位置为第一点,拖动鼠标光标过程中鼠标的位置为第二点,动态显示一个以这两点为对角线的矩形,松开鼠标时抹去显示的矩形,返回Ractangle实例。Map1.Extent = r语句设置地图窗口的显示范围,触发地图窗口重绘,产生地图放大视觉效果。

4缩小

       Dim Rect As MapObjects2.Rectangle

       Set Rect = Map1.Extent   获得地图窗口显示范围的引用

       Rect.ScaleRectangle (1.5)  矩形区长宽值扩大1.5

       Map1.Extent = Rect       设置地图窗口的显示范围

从上面的例句可见,地图的放大和缩小,都是通过重新设置Map1.Extent的值实现的,那么,扩大Map1.Extent矩形区边长的数值,不是放大,而是缩小呢?从操作过程可知,地图窗口的尺寸、地图库中坐标数据的值、 Map1.FullExtent矩形的长宽值三组数据始终保持不变。Map1.ExtentMap1.FullExtent中的一个矩形区,若Map1.Extent矩形长宽值增加,表示要显示的地图坐标值范围扩大,由于地图显示窗口大小不变,因此显示的地图变小。

5样例解释

以下是从样例liulanForm1窗体中剪贴的两段程序,其中实现了漫游、全范围显示地图、放大、缩小功能。

Dim strToolBarValue As String  窗体级变量,工具栏上当前按下的按纽

Private Sub Map1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

  Select Case strToolBarValue

     Case “漫游

          Map1.Pan

     Case “全图

          Map1.Extent = Map1.FullExtent ‘全范围显示地图

     Case “放大

       If Button = 1 And Shift = 0 Then

          Dim r As MapObjects2.Rectangle

          Set r = Map1.TrackRectangle      在窗口中绘制一个矩形,返回矩形的引用

          If Not r Is Nothing Then Map1.Extent = r

       End If

     Case “缩小

          Dim Rect As MapObjects2.Rectangle

          Set Rect = Map1.Extent

          Rect.ScaleRectangle (1.5)

          Map1.Extent = Rect

      End Select

End Sub

Private Sub Toolbar1_ButtonClick(ByVal Button As MSComctlLib.Button)

strToolBarValue = Button

    Select Case Button

        Case “漫游

            Map1.MousePointer = moPan   ‘MapObjects控件库中的常量

        Case “放大

            Map1.MousePointer = moZoomIn

        Case “缩小

            Map1.MousePointer = moZoomOut

        Case “全图

            Map1.MousePointer = moDefault

    End Select

End Sub

从上述两段程序中可以看出,在工具栏的Toolbar1_ButtonClick方法中,strToolBarValue变量指示按下的按钮,Case语句块设置地图窗口鼠标光标形状。Map1_MouseDown方法中实现了地图浏览功能。

Map1.PanMap1.TrackRectangle方法都处理鼠标操作,它们将被调用之前的一次MouseDown事件作为自己的第一个鼠标事件,因此适合于在Map1_MouseDown方法中使用,若用在Toolbar1_ButtonClick方法中,点击工具栏按钮时的鼠标光标位置作为操作的起始位置,与实际应用要求不符,请读者编程实验操作效果。

习题

1 编写程序实现LiuLan目录中样例的功能

2.2.2 图层与地图的概念

MapObjects中图层的概念与地图学中图层的概念基本相同,是地图窗口中的一个显示层面,全部显示层面叠加到一起形成地图,因此地图是图层的集合。为了计算机处理方便,每个图层只包括一类几何要素。在地理信息系统中,二维及其以下维的几何要素分为点、线、面三类,因此,一个图层是一类几何要素的集合,显示的图层是集合在地图窗口中的映射。同类几何要素从数据到图形的影射处理方法相同,便于计算机程序处理。除了单种几何要素图层之外,MapOjects还定义了一个特殊图层,称为跟踪层,层中可以包含多种类型的几何图形。

地图

点图层

线图层

面图层

跟踪层

影像图层

地图中的图层

MapObjects2.MapMapOjects的地图控件,它的实例的默认名称是Map1Map2Map3…MapN,完成从地理数据到图形的映射功能。实例的视觉界面是地图显示窗口,影射结果在地图控件窗口中显示,形成地图。

 

 

 

 

 

 

 

2.2.3 图层操作

地图是图层的集合,地图设计主要在图层上进行。

1添加图层

1 添加ShapeFile图层

添加ShapeFileArcView的图层文件格式,MapObjects2.1ShapeFile格式实现了读、写、编辑功能。语句:

  Dim dc As New DataConnection

  dc.Database = “d:/moBook/Samples/Data/washington”  数据库文件目录路径名

  If Not dc.Connect Then End         连接数据库,失败则退出

  Dim mLayer As New MapLayer

  Set mLayer.GeoDataset = dc.FindGeoDataset(“roads”)  ‘roads.shp可省略扩展名

  mLayer.Symbol.Color = moYellow                用黄色显示道路

  Map1.Layers.Add mLayer          添加图层到控件的图层集合中

向地图控件实例Map1中添加一个图层。

    详细程序请参考附属光盘中AddImage目录中的样例。

2)添加ArcInfo Coverage图层

假设USAD:/mobook/sample/data/Coverages目录下的一个Coverage,以下程序在地图窗口中加入一个面图层。

Private Sub Form_Load()

  Dim dCon As New DataConnection

  Dim workspace As String, featAttTable As String

  Dim objLayer As New mapobjects2.MapLayer

  featAttTable = “USA.pat”      面图层及点图层用同一名称

  workspace = “[arc]D:/mobook/sample/data/Coverages”

  dCon.Database = workspace

   If dCon.Connect Then

      Set objLayer.GeoDataset = dCon.FindGeoDataset(featAttTable)

      objLayer.Name = featAttTable

      Map1.Layers.Add objLayer     图层对象加入地图控件

  End If

End Sub

featAttTable变量分别赋字符串“USA.aat” “USA.txt”则可分别添加线图层、注记图层。USAArc/Info Coverage的目录名。featAttTable的值由两部分组成:

featAttTable = Coverage.Suffix”

Suffix可用的替换字符串如下:

图层类型

Suffix

例子

Polygon

pat

landuse.pat

Arc

aat  

rivers.aat

Point

pat 

wells.pat

Node

nat

streets.nat

Regions

pat<subclass>

admin.patcity

Routes

rat<subclass>

transit.ratbus

Annotation text

txt

roads.txt

Annotation subclass

tat<subclass>

tracts.tatlevel1

详细程序请参考附属光盘中的AddCover

 (3) 添加ArcSDE图层

   ArcSDEESRI的地理数据服务器,连接参数与本机连接参数有区别,其余语句相同。以下程序添加ArcSDE图层。

Private Sub Command1_Click()

Dim dc As New MapObjects2.DataConnection

  dc.Server = “SDE81:SDEServer 1”  ‘8.1版服务器

  dc.User = “ChenC”

  dc.Password = “MyPassWord”

  dc.Database = “instance=esri_sde”  你定义的实例名

  If dc.Connect Then 

    Dim ly As New MapLayer

    Set ly.GeoDataset = dc.FindGeoDataset(”myName.roads.Feature.lines”)

    Map1.Layers.Add ly

  End If

End Sub

FindGeoDataset(”myName.roads.Feature.lines”)的参数字符串是句点分隔的四部分,分别指数据所有者名、图层名、包含地图图形要素的字段名、要素的几何类型。

   用以下语句替换If语句块,可将Geodatasets集合中的全部图层加入地图窗口中。

    If dc.Connect Then 

    Dim ly As  MapLayer

        Dim gs As  GeoDataset

    For Each gs In dc.GeoDatasets

      Set ly = New MapLayer

      Set ly.GeoDataset = dc.FindGeoDataset( gs.Name)

      Map1.Layers.Add ly

Next gs

End If

为区分ArcSDE的不同版本,在服务器名增加版本号前缀,如:

   dc.Server = “SED30:SDEServer”

   dc.Server = “SED80:SDEServer”

   详情请参考MapObjects2.1软件附带的样例SdeConnect

 (4) 添加CAD图层

  下段程序将AutoDesk公司的CAD软件形成的文件加入到地图控件中。

  Dim dc As New DataConnection

  dc.Database = “[CADLine]d:/moBook/Samples/Data/CAD”  数据库目录路径名

  If Not dc.Connect Then End         连接数据库,失败则退出

  Dim mLayer As New MapLayer

  Set mLayer.GeoDataset = dc.FindGeoDataset(“roads.dwg”) ‘roads.dwg不可省略扩展名

  mLayer.Symbol.Color = moYellow                用黄色显示道路

  Map1.Layers.Add mLayer          添加图层到控件的图层集合中

dc.Database可用的前缀还有:[CADArea][CADPoint][CADText],分别表示面、点和文本。

(1)  添加影像图层

  Dim iLayer As New ImageLayer

iLayer.File = “d:/moBook/Samples/Data/washington/Wash.bmp 

Map1.Layers.Add iLayer

  详细程序请参考附属光盘中的AddImage

  在创建ImageLayer实例时,不需创建DataConnectionGeoDataset实例。

数据集加入到Map1.Layers中影射成图层,一个数据集映射成一个图层。

1 遍历数据源中的数据集,在列表框中显示全部数据集的名称(参见样例LookupLayer)

Dim dc As New MapObjects2.DataConnection

Form_Load 事件中dc已经与数据源连接。

Private Sub Command1_Click()

    List1.Clear

 If dc.Connected Then

    List1.AddItem "数据源中的数据集"

     Dim gs As GeoDataset

     For Each gs In dc.GeoDatasets

        Me.List1.AddItem gs.Name

     Next gs

 End If

End Sub

2图层集合

 Map.Layers是图层集合,创建Map实例时自动创建跟踪层TrackingLayer,用于保存、绘制临时地图要素,跟踪层不在Map.Layers中。

用图层的索引号或名称引用图层:

    Set layer = Map1.Layers.item(2)

Set layer = Map1.Layers(“road”)

图层索引的起始号是0

Set layer = Map1.Layers.item(0)

绘图按索引号从大到小的顺序进行,最后绘制跟踪层。

语句

Map1.Add Layer

Layer图层加入到地图窗口中,索引号是0,原有图层索引号加1

控制图层的可见性:

    Map1.Layers(2).Visible = False

更改图层的绘制顺序:

    Map1.Layers.Item(2).MoveToBottom 

    Map1.Layers.Item(2).MoveToTop

    Map1.Layers.Item(2).MoveTo 1

2  遍历Map1.Layers中的图层,在列表框中显示全部图层的名称(参见样例LookupLayer)

Private Sub Command2_Click()  '遍历地图窗口中的图层

Dim Layer As MapObjects2.MapLayer

Dim i As Integer

  Me.List1.Clear

If Map1.Layers.Count > 0 Then

  Me.List1.AddItem "Map1 中的图层"

  For i = 0 To Map1.Layers.Count - 1

    Set Layer = Map1.Layers.Item(i)

    Me.List1.AddItem Layer.Name

  Next i

Else

  Me.List1.AddItem "Map1 中没有图层"

End If

3绘图事件函数

Map控件在绘制图层过程中调用的用户函数称为绘图事件函数,可分为三组:

   Map.BeforLayerDraw,  Map.AfterLayerDraw

   Map.BeforeTrackingLayerDraw,  Map.AfterTrackingLayerDraw

   Map.DrawingCancelled

地图控件窗口刷新时执行的指令序列取自控件本身与绘图事件函数,两部分指令组合在一起的执行顺序如下:

绘图事件函数执行顺序

for  L = n  to  0  step 1

Map1.BeforeLayerDraw

绘制图层 L

Map1.AfterLayerDraw

Next  L

Map1.BeforeTrackingLayerDraw

绘制跟踪层

Map1.AfterTrackingLayerDraw

 

 

 

 

 

 

 

 

 

 

 

 

Map控件提供绘图事件函数接口,调用绘图事件函数。因此Map控件规定了地图窗口刷新指令序列的执行顺序。

VB开发环境根据Map控件提供的接口,自动生成绘图事件函数原程序模块,模块中的的执行语句部分为空白,供用户填写。

4测试连接

DataConnection.Connect方法建立与数据源的连接、打开数据库、读取数据库属性、创建GeoDataset集合,若成功,则返回True,为属性Connected赋值True,否则返回False,为属性ConnectError设置错误号。

DataConnection.Disconnect方法关闭数据库,释放DataConnection和数据源的连接,清空GeoDataset集合,重置ConnectedFalse。该方法不返回任何值。

DataConnection.Connected是只读属性,反映DataConnection实例与数据库之间的通讯状态。

DataConnection.ConnectError是只读属性。

  Dim dc As New DataConnection

  dc.Database = “d:/moBook/Samples/Data/washington”  数据库目录路径名

  If  not dc.Connect Then          

Debug.Print “连接数据库失败,错误号是:” ,dc.connectError

Debug.Print  dc.Connected      输出:  False

  Else

    Debug.Print “连接数据库成功

Debug.Print  dc.Connected      输出:  True

    dc.DisConnect

Debug.Print  dc.Connected      输出:  False

  End If

 

习题

1 编写程序实现LookupLayer样例目录中程序的功能,增加代码,交互操作调整Map1窗口中图层的叠置顺序。

2 编写程序实现AddImage样例目录中程序的功能.

3 编写程序实现AddCover样例目录中程序的功能。