內蒙古java團隊

          j2se,j2ee開發組
          posts - 139, comments - 212, trackbacks - 0, articles - 65
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          基于OpenLayers的地圖小工具

          Posted on 2010-11-12 00:02 帥子 閱讀(2105) 評論(0)  編輯  收藏 所屬分類: 申請加入java團隊j2ee技術專區

          提到小工具,就不得不提到 OpenLayers OpenLayers (主頁是 http://www.openlayers.org )是由 MetaCarta 最初發起的,用于在網頁界面上展示地圖的一套 Javascript 腳本框架。

          MapGuide Fusion 框架最為核心的地圖 Widget ,就是采用了 OpenLayers 框架。 Fusion 框架對 OpenLayers 進行包裝,為其添加了更多的功能,從而使之能夠更符合 Fusion 框架并與其余 Fusion 組件進行交互。

          非常有趣的是,由于 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>

          布局文件中地圖定義的部分代碼

          其實, 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

          ?Fusion OpenLayers 之間的概念映射關系

          在閱讀 Fusion OpenLayers 的源代碼或學習他們的 API 時,一定要注意兩者術語上的區別。

          本節中,我們提到了 Fusion 引入了地圖組這一個概念。這只是 Fusion 對于 OpenLayers 眾多改動中的一個。下面我們來看看到底 Fusion OpenLayers 還做了哪些改動。
          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 作為右鍵菜單,再也不需要直接與底層鼠標事件打交道了。

          地圖的定義
          前面在介紹 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: 該項表示用什么顏色來顯示選中的要素。

          主站蜘蛛池模板: 阳高县| 姚安县| 永平县| 汝南县| 武夷山市| 楚雄市| 赤水市| 中西区| 新建县| 平谷区| 天祝| 万盛区| 潮安县| 汤阴县| 石狮市| 扎兰屯市| 贡嘎县| 绥宁县| 房山区| 东源县| 宕昌县| 牡丹江市| 子洲县| 辽阳县| 永善县| 无极县| 登封市| 荔浦县| 翼城县| 黄浦区| 武穴市| 湘乡市| 延长县| 曲松县| 曲周县| 陇川县| 盈江县| 桂东县| 阜阳市| 东乌珠穆沁旗| 蕲春县|