3.3 一颗奔腾的心——基于OpenLayers的地图小工具

3.3      

一颗奔腾的心——基于

OpenLayers

的地图小工具

提到小工具,就不得不提到

OpenLayers

OpenLayers

(主页是

http://www.openlayers.org

)是由

MetaCarta

最初发起的,用于在网页界面上展示地图的一套

Javascript

脚本框架。

MapGuide

Fusion

框架最为核心的地图

Widget

,就是采用了

OpenLayers

框架。

Fusion

框架对

OpenLayers

进行包装,为其添加了更多的功能,从而使之能够更符合

Fusion

框架并与其余

Fusion

组件进行交互。

3.3.1         

起名是个学问——术语不一致引发的问题

非常有趣的是,由于

OpenLayers

所采用的术语跟

Fusion

采用的并不是十分一致,甚至

Fusion

不同部分采用的术语也不是十分一致,所以同一个名字在不同地方表达的意思却很可能并不相同。所以,在详细介绍

Fusion

如何对

OpenLayers

进行包装之前,有必要对两者之间的术语进行一下区分,以免当您阅读到相关材料时感到疑惑。

OpenLayers

认为,用户看到的由多个图层

(layer)

组成的一张地图

(map)

。地图本身与加载的数据源格式无关,与数据源格式相关的是图层。因此,地图类只有一个(

OpenLayers.Map

),而图层类却有很多,这些类都以

OpenLayers.Layer

作为命名空间,如

OpenLayers.Layer.Google/Yahoo/MapGuide/WMS/Vector

等等。

这样的结构有一个问题,那就是所有的图层之间是平行的关系,这是很不利于图层管理的。我们假设有这样一张地图:该地图包含有十二个图层,有九个来自于不同数据源的图层和三个位于顶层的

Vector

层。那么,我如果想用代码去处理所有

Vector

的层,就必须遍历所有的层,依次比较是不是

Vector

层,再对

Vector

层进行处理。解决这个问题的方案很简单,那就是引入层级结构,允许用户把图层分组。比如上面的例子中,把三个

Vector

分成一组,比如命名为“标记”组,届时只需要对标记组中的每一个层进行处理即可。

这也正是

Fusion

对于

OpenLayers

众多改进中的一个。而问题也正是这里引入的:地图

Widget

在给这种层级结构命名的时候,出人意料地采用了另外的命名方式:地图

Widget

把图层组命名为“地图组”

(map group)

,把组里面的图层命名为

(map)

。下面代码是示例数据中

Library://Samples/Sheboygan/FlexibleLayouts/Slate.ApplicationDefinition

布局文件对于地图定义的那一部分,用户可以在

MapGuide Studio

中通过点击位于

Map

面板上的

“Edit Map Group”

按钮来查看这部分内容。

<?xml version=”1.0″
encoding=”utf-8″?>

<MapSet
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>

 

<MapGroupType id=”Sheboygan”>

   

<Map>

     

<Type>MapGuide</Type>

     

<SingleTile>true</SingleTile>

     

<Extension>

       

<ResourceId>Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition</ResourceId>

       

<SelectionAsOverlay>true</SelectionAsOverlay>

       

<SelectionColor>0x0000FFA0</SelectionColor>

     

</Extension>

   

</Map>

   

<Extension />

 

</MapGroupType>

</MapSet>

代码

3-4

布局文件中地图定义的部分代码

其实,

MapGuide

这样做是有原因的。这个问题源于不同产品之间定位的不同:

OpenLayers

框架的目的是在同一张地图上面显示多个数据源。所以在

OpenLayers

看来,一个来自

MapGuide

的地图仅仅是一个层而已。然而,在

MapGuide

内部,一张

MapGuide

地图内是包含多个

Layer

,具体表现就是一个

MapDefinition

里可以包含多个

LayerDefinition

。所以,如果

Fusion

MapGuide

叫做一个

Layer

的话,又该如何称呼里面的

Layer

呢?

鉴于这样的考虑,

Fusion

才做了这种概念上的映射:

Fusion

中的地图

Widget

对应

OpenLayers

里面的地图;

Fusion

里面的地图组是一个逻辑概念,从而形成一种逻辑上的层级结构以便管理;

Fusion

中的地图实际对应于

OpenLayers

里面的图层。

但事情到这里还没有结束,接下来的事情可能会让您有些意外:在编写地图

Widget

实现代码时,为了能够便于与

OpenLayers

中的类对应起来,

Fusion

将地图(也就是

OpenLayers

中的图层)称为

Layers

(注意,不是

Layer

),并要求每一个地图的代码都继承自

Fusion.Layers

。比如,

MapGuide

Layers

的名称就叫做

Fusion.Layers.MapGuide

下表总结了

Fusion

OpenLayers

之间这种概念映射关系

Fusion

概念

Fusion

代码命名

OpenLayers

概念

OpenLayers

代码命名

地图

Fusion.Layers

图层

OpenLayers.Layer

地图组

 

无对应概念

 

地图

Widget

Fusion.Widget.Map

地图

OpenLayers.Map

3-2 Fusion

OpenLayers

之间的概念映射关系

在阅读

Fusion

OpenLayers

的源代码或学习他们的

API

时,一定要注意两者术语上的区别。

本节中,我们提到了

Fusion

引入了地图组这一个概念。这只是

Fusion

对于

OpenLayers

众多改动中的一个。下面我们来看看到底

Fusion

OpenLayers

还做了哪些改动。

3.3.2         

改头换面——

Fusion

对于

OpenLayers

的改进

为了便于

Fusion

的其他组件能够与地图进行交互,

Fusion

对于

OpenLayers

进行了较为全面的包装。一般来说,如果您不是开发

Fusion.Layers

的开发人员,除了使用一些

OpenLayers

的一些工具性的函数之外,您甚至都不需要知道

OpenLayers

的存在。但是,仅仅进行包装是不够的,由于

OpenLayers

Fusion

定位的不同,

Fusion

必须对

OpenLayers

进行扩展才能适应更为复杂的模型。

1.      

Fusion

中添加了选择集的概念。

OpenLayers

在同一张地图里面显示多种不同数据源的方面确实做的很好,遗憾的是,它缺少选择集这一至关重要的概念。对于

OpenLayers

来说,选择集完全是可有可无的,因为它的目的在于将地图展示出来,而且,很多地图根本就没有选择集这样的

API

,比如

Google

地图等等。但对于

Fusion

则不同,我们很难想象没有选择集,用户该如何利用

MapGuide

进行管理。所以,

Fusion

加入了选择集这个概念,并且要求实现

Layers

的地图(比如

MapGuide

)实现选择集功能。我们可以看到,

Fusion.Widget.Map

中不但有诸如

get/set/clear/hasSelection

这样控制和读取选择集的函数,而且有

MAP_SELECTION_ON

MAP_SELECTION_OFF

这两个事件来通知监听者地图选择集的当前状况。

2.      

Fusion

开放了更多的事件。借助于

Fusion

自己独立实现的事件机制,

Fusion

允许用户接收到更多种类的事件,比如

Session

是否已创建、地图当前忙碌与否、选择集状态变更、当前图层(这个是

Fusion

中的图层,不是

OpenLayers

的)变化等等。

3.      

Fusion

允许地图的实现类返回自身支持哪些比例尺,这就使得用户可以直观的知道自己当前缩放地图到什么程度。

4.      

允许用户随时设置当前地图的背景图片和地图上的光标形状。这对于直观地反应地图当前状态是是否有用的。

5.      

支持右键菜单。虽然在浏览器上实现右键菜单相对简单一些,但是通过使用地图

Widget

setContextMenu

,代码编写者就可以直接把已经准备好的

div

作为右键菜单,再也不需要直接与底层鼠标事件打交道了。

3.3.3         

地图标签——地图的定义

前面在介绍

Fusion

OpenLayers

术语不同的时候,摘录了应用程序定义中对于地图部分的定义。通过解析这个定义,

Fusion

了解了应该如何加载该地图。下面,我们就来看看这个定义中到底都定义了哪些东西。

Fusion

中,一个地图组用一个

MapGroup

进行标签定义,

MapGroup

里面的

Map

标签就是对于一个地图的定义了。

1.      

Type:

该标签标示了地图的类型。所有

MapGuide

地图该标签的值均为

MapGuide

。当

Fusion

读取到该地图的

Type

时,就会用对应的

“Fusion.Layers.

标签值

来初始化该地图。比如

MapGuide

地图就会用

Fusion.Layer.MapGuide

来初始化。

2.      

SingleTile:

如果该项为真,则表示该项不采用分块服务。

3.      

Extension:

该于扩展

Map

标签,来为地图初始化提供更多的信息。各个

Fusion.Layers

的实现类可以自行决定其需要的内容,以及如何解释这些内容。对于

MapGuide

而言,有以下常见的扩展:

a)        

ResourceId: MapDefinition

的资源

Id

,通过该

Id

Fusion

可以知道加载哪一个地图定义。

b)       

SelectionAsOverLay:

如果该项是

true

,那么将会使用

GETDYNAMICOVERLAY

来获取地图,否则采用

GETMAPIMAGE

来获取地图。前者是新版本才支持的,可以把选择集和地图本身绘制成两张地图。如果您使用的

MapGuide

版本比较旧,您可以把该项设置成为

false

c)        

SelectionColor:

该项表示用什么颜色来显示选中的要素。

了解到了这些信息,

Fusion

就了解该如何加载地图了。

 

转载自:https://blog.csdn.net/sasyomaru/article/details/5352762

You may also like...