Google maps javascript api v3 疊加層(Overlays)介紹


很多人嘗試google maps api的開發,通常會涉及到在Google maps上進行標注功能的開發。Helloj2ee學習一項技術通常不在看書,而是多以幫助為主。當我看完之后,我將Overlay這一章翻譯成中文,和大家共享。該文英文全文是Google maps api javascript v3幫助,鏈接:https://developers.google.com/maps/documentation/javascript/overlays

相應會有一個中文的Google翻譯:https://developers.google.com/maps/documentation/javascript/overlays?hl=zh-cn。但是這篇譯文和Google的譯文相比,會有如下不同:

1 我會保留諸如Overlay,marker保留其英文原文,通常該詞第一次出現,我會以中文英文同時出現的方式,而第二次只保留英文;

2 代碼中的英文注釋將其翻譯成了對應中文;

3 對於Google翻譯中生硬的地方做了修改;

4 Google的中文文檔幫助和英文文檔幫助並不對應,我會英文中沒有的對應翻譯過來(目錄中標紅的地方)

5 由於眾所周知的原因,大家未必能夠很順暢地瀏覽V3中的例子,我將該篇用到的示例一並打包。鏈接地址:http://vdisk.weibo.com/s/n5w3t

 

目錄:

1  疊加層(Overlay)概述

1.1 添加Overlay

1.2 刪除Overlay

2 符號(Symbol)

2.1 預定義路徑(Path)

3 標注(Marker)

3.1 Marker動畫

3.2 自定義Marker

3.2.1 簡單圖標(Icon)

3.2.2 復雜Icon

3.2.3 矢量Icon

4 折線(Polyline)

4.1 Polyline選項(Options)

4.2 Polyline數組

4.3 Polyline符號化

5 多邊形(Polygon)

5.1 Polygon選項

5.2 Polygon自動閉合

5.3 Polygon數組

6 圓和矩形

6.1 圓

6.2 矩形

7 可編輯形狀

7.1 編輯事件

8 繪圖(Drawing)庫

8.1 DrawingManager選項

8.2 圖形繪制工具控件更新

8.3 繪圖事件

9  信息窗口(info window)

10 Ground Overlays

11 自定義overlay

11.1  overlay的子類化

11.2 初始化自定義的overlay

11.3 自定義overlay的繪制

11.4 隱藏和顯示自定義的overlay

 

1. 疊加層(Overlay)概述

Overlay是地圖上有經緯坐標的對象集合,因此Overlay會隨地圖拖拽或縮放而移動。Overlay表示的是“添加”到地圖上具有明確位置的點、線、面或者三者集合的對象。

Google Maps API有以下幾種類型的Overlay:

  • 使用Marker表示地圖上單個位置的對象。Marker有時可顯示自定義的圖標,這時Marker又被稱之為icon。Marker和icon我們都稱之為marker對象。(有關詳細信息參見下面的Marker和Icon節)
  • 使用折線(Polyline)(一系列順序排列的位置點集合)表示地圖上的線段。線段就是一種類型的Polyline。
  • 使用多邊形(Polygon)表示地圖上的不規則區域。Polygon類似於Polyline。與Polyline相同的是,多邊形也是由一系列順序排列的位置點構成;不同的是,Polygon定義的是一個閉合區域。(有關詳細信息,請參見下面的Polygon節。)
  • 地圖圖層可顯示為overlay地圖類型。您可以通過創建自定義地圖類型以創建自己的圖塊集,該自定義地圖類型可取代基本地圖圖塊集,或作為overlay顯示在現有基本地圖圖塊集之上。(有關詳細信息,請參見自定義地圖類型。)
  • 信息窗口(info window)也是特殊類型的Overlay,用於在地圖特定位置上的彈出式提示框里顯示信息(通常是文字或圖片)(有關詳細信息,請參見info window節。)
  • 您還可以實現自定義的Overlay。這些自定義Overlay會實現 OverlayView 接口。(有關詳細信息,請參見自定義Overlay節。)

1.1添加Overlay

Overlay通常在構造時,添加到地圖中。所有的Overlay都定義了選項(Options)對象,來指定Overlay在哪個地圖上顯示。當然您也可以直接使用Overlay的SetMap方法,將Overlay添加到指定的地圖上。

  var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
  var myOptions = {
    zoom: 4,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
  }
 var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    
 var marker = new google.maps.Marker({
      position: myLatlng,
      title:"Hello World!"
  });
  
  // 調用setMap方法,將Marker添加到地圖上
  marker.setMap(map);

1.2 刪除Overlay

要從地圖上刪除Overlay,同樣可調用Overlay對象的 setMap() 方法,只是傳遞 null參數。請注意,調用此方法不會刪除Overlay,而只是從地圖上刪除Overlay。如果您要真正刪除Overlay,則應當從地圖上刪除Overlay,然后將Overlay設置為 null。

如果要管理一組Overlay對象,則應當創建一個數組來存儲這些Overlay。使用數組時,如果需要刪除Overlay,需要對數組中的每個Overlay依次調用 setMap()。(注意,與第 2 版不同,該版本中未提供 clearOverlays() 方法。您需要自己負責追蹤Overlay的狀態,並在不需要他們時,將其刪除。)您可以通過在地圖上依次移除Overlay,並將數組的長度(Length)設置為0,以此刪除Overlay。但該操作會刪除所有對Overlay的外部引用。

下面示例是單擊地圖時將Marker放在地圖上,然后將Marker存入數組中。Overlay可以隱藏、顯示或者刪除:

View Code
var map;
var markersArray = [];

function initialize() {
  var haightAshbury = new google.maps.LatLng(37.7699298, -122.4469157);
  var mapOptions = {
    zoom: 12,
    center: haightAshbury,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };
  map =  new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

  google.maps.event.addListener(map, 'click', function(event) {
    addMarker(event.latLng);
  });
}
  
function addMarker(location) {
  marker = new google.maps.Marker({
    position: location,
    map: map
  });
  markersArray.push(marker);
}

// 從地圖中移除overlay,但仍然保存在數組中
function clearOverlays() {
  if (markersArray) {
    for (i in markersArray) {
      markersArray[i].setMap(null);
    }
  }
}

// 在數組中顯示當前的overlay
function showOverlays() {
  if (markersArray) {
    for (i in markersArray) {
      markersArray[i].setMap(map);
    }
  }
}

// 刪除數組中所有的marker
function deleteOverlays() {
  if (markersArray) {
    for (i in markersArray) {
      markersArray[i].setMap(null);
    }
    markersArray.length = 0;
  }
}

查看示例 (overlay-remove.html)

2. 符號(Symbol)

Symbol是一種基於矢量的圖像,它可以應用在Marker或者Polyline對象上。Symbol通過路徑(path)來定義(使用SVG Path語法規則),其他選項控制Symbol如何顯示。SymbolPath對象已經預定義了若干個Symbol。除了Path這個唯一必須設置的屬性外,Symbol類還支持若干個顯示設置的屬性,比如畫筆填充色以及畫筆寬度等。

讀者希望學習線要素符號化和動畫的相關知識,請參見Polyline符號化一節。讀者希望學習marker符號化的相關知識,請參見矢量Icon一節。

  • Symbol類提供如下屬性。注意Symbol的默認行為會因應用在Marker或者Polyline上,而略微有些變化。
  • Path(必設置項),Path定義了Symbol的形狀。您可以使用google.maps.SymbolPath內置的path對象或者使用SVG path語法規則自定義Path。注意:Polyline上定義的Path對象必須在22*22像素范圍內,如果Path上的點在該范圍外,那么必須將Scale屬性調整為一個小數值(比如0.2),使得縮小后的點能夠在該范圍內。
  • anchor,Symbol相對Marker或者Polyline的位置。Symbol的Path屬性坐標以anchor的x和y為坐標原點,橫軸左方為正,縱軸上方為正。默認Symbol的anchor坐標位置為(0,0)。該坐標和Symbol的Path屬性在同一坐標系下。
  • fillColor,Symbol的填充色。除去擴展命名的顏色外,fillcolor支持所有的CSS3的顏色。對於符號化的Marker而言,該屬性默認為“黑色”。對於Polyline而言,該屬性默認為相應的畫筆顏色。
  • fillOpacity,Symbol填充的透明度,該屬性值在0和1之間,默認為0。
  • rotation,Symbol旋轉的角度,順時針方向,以度為單位。默認marker的Symbol,rotation屬性為0,Polyline上的symbol旋轉角度取決於Polyline邊的角度。對Polyline的Symbol設置rotation屬性,這意味着該符號不會沿着Polyline邊的方向。
  • scale,符號尺寸的比例值。對於Marker的Symbol而言,該值默認為1。經過縮放后,該Symbol可以是任意尺寸。對於Polyline的Symbol而言,該值默認為筆寬。經過縮放后,Symbol必須在以anchor為中心,22*22像素區域內。
  • strokecolor,符號畫筆顏色。除去擴展命名的顏色外,fillcolor支持所有的CSS3的顏色。對於Marker的Symbol而言,默認值為“黑色”。對於Polyline的Symbol而言,該值默認為Polyline的畫筆顏色。
  • strokeOpacity,符號畫筆的透明度,該屬性值在0和1之間。對於Marker的Symbol而言,默認值為0。對於Polyline的Symbol而言,該值默認為Polyline的畫筆透明度。
  • strokeWeight,符號的畫筆寬度。默認為Symbol的scale值。

下面示例創建了一個黃色五角星的Symbol,用淺黃色填充,並且用深黃色描邊。

View Code
var goldStar = {
  path: 'M 125,5 155,90 245,90 175,145 200,230 125,180 50,230 75,145 5,90 95,90 z',
  fillColor: "yellow",
  fillOpacity: 0.8,
  scale: 1,
  strokeColor: "gold",
  strokeWeight: 14
};

var marker = new google.maps.Marker({
  position: new google.maps.LatLng(-25.363, 131.044),
  icon: goldStar,
  map: map
});

2.1 預定義路徑(Path)

Google Maps JavaScript API提供內置的符號,可以應用在Marker或者Polyline上。默認的符號包括圓,兩種類型的箭頭。在Polyline上的Symbol方向是固定的,因此需要前方和后方兩種箭頭,前方是Polyline前進的方向。內置的Symbol如下表所示。

您也可以通過Symbol options修改內置符號的畫筆或者填充屬性。

3. 標注(Marker)

標注(Marker)用於標識地圖上的位置。默認情況下,標注使用的是標准圖標(Icon),但可以在標注的構造函數中設置一個自定義Icon,或者通過調用 setIcon方法 來設置一個自定義Icon。google.maps.Marker 構造函數采用了一個Marker options對象設置Marker的初始屬性。在構造Marker時,下面的屬性非常重要,而且經常會被設置。

  • position(必需),用於指定Marker初始位置的經緯度 LatLng。
  • map(可選),用於指定Marker在哪個Map 對象上。

注意,在 Marker構造函數中需要指定為哪個地圖添加Marker。如果不指定該參數,那么,只能創建Marker,而無法將其添加到地圖上(或顯示在地圖上)。但是可以在后面通過調用Marker的setMap()方法在地圖上添加Marker。如果要移除Marker,則調用setMap()方法時,傳遞null參數。

Marker也可設計成交互的。比如,默認情況下它們接收 'click' 事件,常在該事件響應函數中彈出信息窗口。並且將Marker的draggable屬性設置成true,就能夠使Marker在地圖上可拖拽。

以下示例介紹了如何將一個簡單的Marker添加到澳大利亞中心區域的Uluru的地圖上:

View Code
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
  var mapOptions = {
    zoom: 4,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

  var marker = new google.maps.Marker({
      position: myLatlng,
      map: map,
      title:"Hello World!"
  });

Marker 標題將會以提示框(Tooltip)的形式顯示。

如果不想在Marker的構造函數中傳遞任何 Marker options,那么,請在構造函數的參數中傳遞一個空對象 {}。

查看示例 (marker-simple.html)

3.1 Marker動畫

您也可以對Marker添加動畫效果,以便它們在各種不同的環境中展現動態運動效果。為Marker添加動畫效果的方法是設置Marker的 animation 屬性(該屬性屬於 google.maps.Animation 類型)。系統目前支持以下 Animation 值:

  • DROP 表明Marker初次放置於地圖上時,應當從地圖頂端落到目標位置。當Marker停止移動時,動畫也會立即結束,且 animation值還原為 null。通常,該類型動畫應用在Marker 創建過程中。
  • BOUNCE 表明Marker會在相應的位置上“彈跳”。Marker會不停“彈跳”,直到Marker的animation屬性設置為null。

可以調用 Marker 對象的 setAnimation()方法,對現有Marker添加動畫效果。

下面示例在瑞典斯德哥爾摩(Stockholm)市創建了一個采用 DROP 動畫的Marker。點擊該Marker時,可使它在 BOUNCE 動畫和無動畫之間切換:

View Code
var stockholm = new google.maps.LatLng(59.32522, 18.07002);
var parliament = new google.maps.LatLng(59.327383, 18.06747);
var marker;
var map;

function initialize() {
  var mapOptions = {
    zoom: 13,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    center: stockholm
  };

  map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);

  marker = new google.maps.Marker({
    map:map,
    draggable:true,
    animation: google.maps.Animation.DROP,
    position: parliament
  });
  google.maps.event.addListener(marker, 'click', toggleBounce);
}

function toggleBounce() {

  if (marker.getAnimation() != null) {
    marker.setAnimation(null);
  } else {
    marker.setAnimation(google.maps.Animation.BOUNCE);
  }
}

查看示例 (marker-animations.html)

注意:如果您有多個Marker,則不應讓所有Marker同時掉落到地圖上。您可以調用 setTimeout()方法,(類似於以下示例中所示)來間隔顯示標記的動畫效果。

查看示例 (marker-animations-iteration.html)

 

3.2自定義Marker

Marker也可以定義為圖標(icon)來替代原默認的Google圖釘形狀。定義icon涉及到一系列關於Marker外觀的屬性設置。

3.2.1簡單圖標(Icon)

在絕大多數情況下,可以通過設置Marker的icon屬性為某一圖像的URL地址的方法,來替換掉默認的Google圖釘圖標。

在下面的例子中,創建了一個icon標示澳大利亞Bondi海灘的位置。

View Code
function initialize() {
  var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
  var myOptions = {
    zoom: 4,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

  var image = 'beachflag.png';
  var myLatLng = new google.maps.LatLng(-33.890542, 151.274856);
  var beachMarker = new google.maps.Marker({
      position: myLatLng,
      map: map,
      icon: image
  });
}

查看示例 (icon-simple.html)

3.2.2 復雜Icon

復雜Icon可用於指定復雜的形狀(表示用戶可點擊的區域)、添加陰影,以及指定這些形狀與其他疊加層在顯示時的“壓蓋順序”。以這種方式設定的Icon需要將Marker的 icon 屬性和 shadow 屬性設置為 MarkerImage 類型的對象。

陰影通常應該和主圖像成 45 度夾角(向右上方傾斜),並且陰影的左下角應與圖標圖像的左下角對齊。陰影圖像應是半透明的 24 位 PNG 圖像,這樣圖像邊界便可以在地圖上正確顯示。

MarkerImage 對象不僅可以定義顯示的圖像,還可以定義圖標的大小、圖標的原點(比如,您所需要的圖像只是一幅較大圖像的一部分。)以及圖標所定位的熱點對應的 anchor屬性(基於原點距離)。

以下示例介紹了如何創建復雜的Icon,來表示澳大利亞新南威爾士悉尼附近的海灘。請注意,應當將 anchor 設置為 (0,32),從而與旗桿的基座相對應。

View Code
function initialize() {
  var mapOptions = {
    zoom: 10,
    center: new google.maps.LatLng(-33.9, 151.2),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var map = new google.maps.Map(document.getElementById("map_canvas"),
                                mapOptions);

  setMarkers(map, beaches);
}

/**
 * Marker包括的數據項分別為名稱,經緯度,以及zIndex(標示彼此壓蓋順序)
 */
var beaches = [
  ['Bondi Beach', -33.890542, 151.274856, 4],
  ['Coogee Beach', -33.923036, 151.259052, 5],
  ['Cronulla Beach', -34.028249, 151.157507, 3],
  ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
  ['Maroubra Beach', -33.950198, 151.259302, 1]
];

function setMarkers(map, locations) {
  // 將Marker添加到地圖上

  // Marker的大小用X,Y表示 
  // 圖像(0,0)表示的是圖像的左上角

  // Origins, anchor的坐標都是橫軸向右增加,縱軸向下增加
   var image = new google.maps.MarkerImage('images/beachflag.png',
      // 該marker 20個像素寬,32個像素高
      new google.maps.Size(20, 32),
      // 圖像原點0,0.
      new google.maps.Point(0,0),
      // 圖像anchor屬性為(0,32)
      new google.maps.Point(0, 32));
  var shadow = new google.maps.MarkerImage('images/beachflag_shadow.png',
      // 陰影在橫軸方向寬
      // 高和主圖像相同
      new google.maps.Size(37, 32),
      new google.maps.Point(0,0),
      new google.maps.Point(0, 32));
      // shape定義了圖標可點擊的區域
      // 該類型是一系列x,y坐標串。最后一個坐標和第一個坐標自動閉合。
  var shape = {
      coord: [1, 1, 1, 20, 18, 20, 18 , 1],
      type: 'poly'
  };
  for (var i = 0; i < locations.length; i++) {
    var beach = locations[i];
    var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
    var marker = new google.maps.Marker({
        position: myLatLng,
        map: map,
        shadow: shadow,
        icon: image,
        shape: shape,
        title: beach[0],
        zIndex: beach[3]
    });
  }
}

查看示例 (icon-complex.html)

3.2.3 矢量Icon

Marker既支持柵格圖像也支持矢量路徑(也稱之為Symbol)。為了顯示矢量路徑(path),需要將Maker的Icon屬性設置成一個Symbol對象。您可以使用google.maps.SymbolPath內置的path,也可以通過SVG Path語法規則自定義Path。

更多關於Google maps矢量圖形信息,參見symbol的相關文檔。

下面示例展示的通過內置的矢量path創建一個icon。詳細的示例,參見Symbol一節。

View Code
marker = new google.maps.Marker({
  position: new google.maps.LatLng(-25.363882, 131.044922),
  icon: {
    path: google.maps.SymbolPath.CIRCLE,
    scale: 10
  },
  draggable: true,
  map: map
});

4 折線(Polyline)

Polyline 類定義地圖上線段彼此相連的折線。Polyline 對象包含一組經緯度位置,由此創建了一系列按順序相連的線段。

4.1 折線選項(Polyline Options)

Polyline 構造函數通過Polyline Options對象來指定線的經緯度坐標,以及線的外觀。

Polyline 就是在地圖上繪制的一系列直線段。您可以在構造Polyline時,通過 Polyline options 對象指定線的畫筆顏色、粗細和透明度,或者在構造之后更改這些屬性。Polyline支持以下畫筆樣式:

  • strokeColor 指定 "#FFFFFF" 格式的十六進制 HTML 顏色。Polyline 類不支持顏色名稱。
  • strokeOpacity 指定線的顏色不透明度,為 0.0 到 1.0(默認值)之間的小數值。
  • strokeWeight 指定線的粗細(以像素為單位)。

除此之外,Polyline的editable屬性定義的是該形狀是否允許用戶在地圖上編輯。

以下代碼段繪制一條粗細為 2 像素的紅色折線,連接威廉·金斯福德·史密斯 (William Kingsford Smith) 從美國加利福尼亞州奧克蘭到澳大利亞布里斯班的首次跨太平洋飛行路線。

View Code
function initialize() {
  var myLatLng = new google.maps.LatLng(0, -180);
  var myOptions = {
    zoom: 3,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      myOptions);
  var flightPlanCoordinates = [
    new google.maps.LatLng(37.772323, -122.214897),
    new google.maps.LatLng(21.291982, -157.821856),
    new google.maps.LatLng(-18.142599, 178.431),
    new google.maps.LatLng(-27.46758, 153.027892)
  ];
  var flightPath = new google.maps.Polyline({
    path: flightPlanCoordinates,
    strokeColor: "#FF0000",
    strokeOpacity: 1.0,
    strokeWeight: 2
  });

  flightPath.setMap(map);
}

4.2 Polyline數組

Polyline通過Latlng對象數組來設定一系列坐標。要訪問這些坐標,需要調用Polyline的GetPath方法,它會傳回MVCArray類型的數組。並且可以使用以下方法來操作和檢查數組:

  • getAt() 用於在指定的索引值(從零開始)處傳回 LatLng值。
  • insertAt() 用於在指定索引值(從零開始)處插入所傳遞的 LatLng值。注意,由於插入操作,使得所有在索引值之后坐標均向后移動。
  • removeAt() 用於在指定的索引值(從零開始)處刪除 LatLng值。

注意:不能只是使用語法 mvcArray[i] 檢索數組的第 i 個元素,而必須使用 mvcArray.getAt(i)。

以下代碼創建了一幅交互式地圖,其中的折線是根據用戶的點擊構造的。請注意,只有當折線的 path 屬性包含兩個 LatLng 坐標時,折線才會顯示。

View Code
var poly;
var map;

function initialize() {
  var chicago = new google.maps.LatLng(41.879535, -87.624333);
  var myOptions = {
    zoom: 7,
    center: chicago,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);

  var polyOptions = {
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 3
  }
  poly = new google.maps.Polyline(polyOptions);
  poly.setMap(map);

  //對”click”事件添加監聽器 
  google.maps.event.addListener(map, 'click', addLatLng);
}

/**
 * 處理地圖上單擊事件,並且為Polyline添加新的點。
 * @param {MouseEvent} mouseEvent
 */
function addLatLng(event) {

  var path = poly.getPath();

  // 由於path是MVCArray類型, 我們只是簡單添加新的坐標,
  // 並且Path將自動顯示
   path.push(event.latLng);

  // 在Polyline上新增的點上再增加一個Marker
   var marker = new google.maps.Marker({
    position: event.latLng,
    title: '#' + path.getLength(),
    map: map
  });
}

查看示例 (polyline-complex.html)

 

4.3 Polyline符號化

您可以對Polyline進行符號化。為了對Polyline符號化,需要設置PolylineOptions對象的icons[]屬性。Icons數組中會有一個或者多個IconSequence序列,IconSequence包含如下幾項:

  • icon(必須的),線符號。關於如何對線進行符號化參見Symbols一節。
  • offset從線頂端開始需要符號化的距離。該距離可以表示為線長的百分比(如50%)或者象素(如“50px”),默認為“100%”。
  • repeat表示線上符號之間的距離。該距離可以表示為線長度的百分比(如50%)或者象素(如“50px”)。為了符號不重復,可以將該值設置為“0”。默認為 “0”。

如果Polyline是具有地理坐標的一條線,那么offset和repeat距離的默認單位應該是米。將offset或者repeat設置為象素值,那么Google會自動計算該距離在屏幕上的象素值。

通過對符號的組合,以及使用PolylineOptions類,您還可以對地圖上的線外觀有更多的控制。下面是幾個典型的例子。

箭頭

使用IconSequence.offset屬性,可以為線的兩端天價箭頭。在這個例子中將offset設置為100%,這樣把箭頭就放置在線的末端。

View Code
var lineCoordinates = [
  new google.maps.LatLng(22.291, 153.027),
  new google.maps.LatLng(18.291, 153.027)
];

var lineSymbol = {
  path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW
};

var line = new google.maps.Polyline({
  path: lineCoordinates,
  icons: [{
    icon: lineSymbol,
    offset: '100%'
  }],
  map: map
});

虛線

您可以先將Polyline的透明度設置為0%,然后每隔固定間隔繪制不透明的符號來達到虛線的效果。

View Code
var lineCoordinates = [
  new google.maps.LatLng(22.291, 153.027),
  new google.maps.LatLng(18.291, 153.027)
];

var lineSymbol = {
  path: 'M 0,-1 0,1',
  strokeOpacity: 1,
  scale: 4
};

var line = new google.maps.Polyline({
  path: lineCoordinates,
  strokeOpacity: 0,
  icons: [{
    icon: lineSymbol,
    offset: '0',
    repeat: '20px'
  }],
  map: map
});

自定義路徑

自定義符號允許您在Polyline上添加多個不同的形狀。

View Code
var lineCoordinates = [
  new google.maps.LatLng(22.291, 153.027),
  new google.maps.LatLng(18.291, 153.027)
];

var symbolOne = {
  path: 'M -2,0 0,-2 2,0 0,2 z',
  strokeColor: '#F00',
  fillColor: '#F00',
  fillOpacity: 1
};

var symbolTwo = {
  path: 'M -2,-2 2,2 M 2,-2 -2,2',
  strokeColor: '#292',
  strokeWeight: 4
};

var symbolThree = {
  path: 'M -1,0 A 1,1 0 0 0 -3,0 1,1 0 0 0 -1,0M 1,0 A 1,1 0 0 0 3,0 1,1 0 0 0 1,0M -3,3 Q 0,5 3,3',
  strokeColor: '#00F',
  rotation: 0
};

var line = new google.maps.Polyline({
  path: lineCoordinates,
  icons: [{
    icon: symbolOne,
    offset: '0%'
    },{
      icon: symbolTwo,
      offset: '50%'
    },{
      icon: symbolThree,
      offset: '100%'
    }
  ],
  map: map
});

動畫符號

可以通過setTimeout()函數在固定時間間隔內改變符號的偏移量,從而使得符號似乎沿某一路徑在運動。

View Code
var line;

function initialize() {
  var mapOptions = {
    center: new google.maps.LatLng(20.291, 153.027),
    zoom: 6,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  
  var map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);
      
  var lineCoordinates = [
    new google.maps.LatLng(22.291, 153.027),
    new google.maps.LatLng(18.291, 153.027)
  ];

  var lineSymbol = {
    path: google.maps.SymbolPath.CIRCLE,
    scale: 8,
    strokeColor: '#393'
  };

  line = new google.maps.Polyline({
    path: lineCoordinates,
    icons: [{
      icon: lineSymbol,
      offset: '100%'
    }],
    map: map
  });
}

function animateCircle() {
    var count = 0;
    offsetId = window.setInterval(function() {
      count = (count + 1) % 200;

      var icons = line.get('icons');
      icons[0].offset = (count / 2) + '%';
      line.set('icons', icons);
  }, 20);
}

5 多邊形(Polygon)

Polygon 對象類似於 Polyline 對象,都由一系列有序坐標構成。不過,多邊形不像折線一樣有兩個端點,而是定義閉合區域。與折線類似的是,您可以定義影響多邊形輪廓的畫筆;不同的是,您還可以定義多邊形內的填充區域。

此外,Polygon 還可以展示復雜形狀,包括不連續形狀(多個多邊形定義為一個多邊形)、“圓環”(多邊形區域在多邊形內顯示為“島”)以及一個或多個多邊形的交叉重疊。因此,一個多邊形可指定多條路徑(Path)。

 

5.1 多邊形選項(Polygon Options)

與Polyline一樣,您可以定義Polygon的邊(“畫筆”)的自定義顏色、粗細和不透明度,以及封閉區域(“填充”)的自定義顏色和不透明度。顏色應當采用十六進制數字的HTML樣式。

由於Polygon區域可能包括多條獨立的Path,因此 Polygon 對象的 paths 屬性指定成“數組的數組”(每個都是 MVCArray 類型),其中每個數組分別定義一系列 LatLng 有序坐標。

但是,對於只包含一條Path的簡單Polygon,為方便起見,您可以采用單個 LatLng 坐標數組構造 Polygon。在將數組存儲到 Polygon 的 paths 屬性時,Google Maps API 會在構造時將其轉換為“數組的數組”。同樣,該API還為只包含一條Path的簡單多邊形提供了簡單的 getPath() 方法。

注意:如果采用此方式構造Polygon,則仍需要將路徑處理為 MVCArray,以便檢索多邊形的值。

除此之外, Polygon的editable值規定了地圖上的Polygon是否可編輯。

以下代碼段創建一個表示百慕大三角的多邊形:

View Code
function initialize() {
  var myLatLng = new google.maps.LatLng(24.886436490787712, -70.2685546875);
  var mapOptions = {
    zoom: 5,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var bermudaTriangle;

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);

  var triangleCoords = [
    new google.maps.LatLng(25.774252, -80.190262),
    new google.maps.LatLng(18.466465, -66.118292),
    new google.maps.LatLng(32.321384, -64.75737),
    new google.maps.LatLng(25.774252, -80.190262)
  ];

  // Construct the polygon
  // Note that we don't specify an array or arrays, but instead just
  // a simple array of LatLngs in the paths property
  bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35
  });

  bermudaTriangle.setMap(map);
}

5.2 多邊形自動閉合

上例中的 Polygon 包含四個坐標,但第一個坐標和最后一個坐標為相同位置,從而定義了一個環路。不過,實際上由於多邊形定義的就是封閉區域,因而無需定義這最后一個坐標。

 

對於任意指定路徑,Google Maps API 將通過繪制連接最后一個坐標和第一個坐標以自動“封閉”任何多邊形。

 

下例除了省略最后一個坐標之外,其他與上例均相同。

 

查看示例 (polygon-autoclose.html)

5.3 Polygon數組

多邊形將其一系列坐標指定為數組的數組,其中每個數組都是 MVCArray 類型。每個子數組都是 LatLng 坐標的數組,用於指定單條Path。要檢索這些坐標,可調用 Polygon 的getPaths() 方法。由於數組為 MVCArray,因此您需要使用以下操作處理和檢查該數組:

  • getAt() 用於在指定的索引值(從零開始)處傳回 LatLng。
  • insertAt() 用於在指定索引值(從零開始)處插入所傳遞的 LatLng。注意,該索引值的所有現有坐標均向前移動。
  • removeAt() 用於在指定的索引值(從零開始)處刪除 LatLng。

注意:不能只是使用語法 mvcArray[i] 檢索數組的第 i 個元素,而必須使用 mvcArray.getAt(i)。

以下代碼通過顯示Polygon的坐標信息,處理Polygon的點擊事件:

View Code
var map;
var infoWindow;

function initialize() {
  var myLatLng = new google.maps.LatLng(24.886436490787712, -70.2685546875);
  var myOptions = {
    zoom: 5,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var bermudaTriangle;

  map = new google.maps.Map(document.getElementById("map_canvas"),
      myOptions);

  var triangleCoords = [
    new google.maps.LatLng(25.774252, -80.190262),
    new google.maps.LatLng(18.466465, -66.118292),
    new google.maps.LatLng(32.321384, -64.75737)
  ];

  bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: "#FF0000",
    fillOpacity: 0.35
  });

  bermudaTriangle.setMap(map);

  // 為click事件添加監聽器
  google.maps.event.addListener(bermudaTriangle, 'click', showArrays);

  infowindow = new google.maps.InfoWindow();
}

function showArrays(event) {

  // 因為該Polygon只有一個path,因此調用getpath()方法返回
 // LatLngs的MVCArray數組。
  var vertices = this.getPath();

  var contentString = "<b>Bermuda Triangle Polygon</b><br />";
  contentString += "Clicked Location: <br />" + event.latLng.lat() + "," + event.latLng.lng() + "<br />";

  // 對頂點進行循環
  for (var i =0; i < vertices.length; i++) {
    var xy = vertices.getAt(i);
    contentString += "<br />" + "Coordinate: " + i + "<br />" + xy.lat() +"," + xy.lng();
  }

  // 替換掉Infowindow的內容,以及修改其位置
  infowindow.setContent(contentString);
  infowindow.setPosition(event.latLng);

  infowindow.open(map);
}

查看示例 (polygon-array.html)

 

6 圓形(Circle)和矩形(Rectangle)

除了普通的 Polygon 類之外,JavaScript Maps API 還包括面向 Circle 和 Rectangle 的特定類,簡化Polygon的構造。

6.1 Circle

Circle 與 Polygon 類似,您可以自定義Cirlce(“畫筆”)邊緣的顏色、粗細和透明度,以及封閉區域(“填充”)的顏色和透明度。顏色應當采用十六進制數字的 HTML 樣式。

與 Polygon 不同,您不應為 Circle 定義 paths;圓形有兩個用於定義其形狀的其他屬性:

  • center 用於指定圓心,類型為google.maps.LatLng;
  • radius 用於指定該圓的半徑(以米為單位)。

 除此之外,Circle的editable屬性規定了圖形在地圖上是否可編輯。

 下列代碼段創建了用於表示美國人口的圓形:

View Code
// 創建一個對象包含經緯度和對應人口
var citymap = {};
citymap['chicago'] = {
  center: new google.maps.LatLng(41.878113, -87.629798),
  population: 2842518
};
citymap['newyork'] = {
  center: new google.maps.LatLng(40.714352, -74.005973),
  population: 8143197
};
citymap['losangeles'] = {
  center: new google.maps.LatLng(34.052234, -118.243684),
  population: 3844829
}
var cityCircle;

function initialize() {
  var mapOptions = {
    zoom: 4,
    center: new google.maps.LatLng(37.09024, -95.712891),
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);

  for (var city in citymap) {
    // 構建圓形大小
    var populationOptions = {
      strokeColor: "#FF0000",
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: "#FF0000",
      fillOpacity: 0.35,
      map: map,
      center: citymap[city].center,
      radius: citymap[city].population / 20
    };
    cityCircle = new google.maps.Circle(populationOptions);
  }
}

查看示例(Circle-simple.html)

 

6.2 Rectangle

Rectangle 與 Polygon 類似,您可以自定義矩形(“畫筆”)邊緣的顏色、粗細和透明度,以及封閉區域(“填充”)的顏色和透明度。顏色應當采用十六進制數字的 HTML 樣式。

與 Polygon 不同,您不應為 Rectangle 定義 path;矩形有一個用於定義其形狀的其他屬性:

  • bounds 用於指定矩形的邊界,類型為 google.maps.LatLngBounds。

除此之外,Rectangle的editable屬性規定了圖形在地圖上是否可編輯。

以下示例會在任何 'zoom_changed' 事件發生時基於前一個視口創建矩形:

7. 用戶可編輯的形狀

任何一個圖形Overlay(折線,多邊形,圓和矩形)都可通過將Shape選項中的editable屬性設置為true,變成“可編輯”的。

 為了使marker可拖拽,需要將maker option中的draggable屬性設置為true。

 

View Code
var circleOptions = {
  center: new google.maps.LatLng(-34.397, 150.644),
  radius: 25000,
  map: map,
  editable: true
};
var circle = new google.maps.Circle(circleOptions);

查看示例(user-editable-shape.html例子)

 

在兩個會話間,對幾何對象所做的修改是無法保存的。如果您需要保存對Polygon的修改,那么您必須自己保存這些信息。

 

7.1編輯事件

當一個圖形被編輯時,編輯完成后會觸發編輯事件,如下所示:

 

圖形

事件

Circle

radius_changed

center_changed

Polygon

insert_at

remove_at

set_at

必須在Polygon的Path上設置事件的監聽器,如果Polygon有多個path,那么必須在各個path上設置監聽器。

Rectangle

bounds_changed

View Code
google.maps.event.addListener(circle, 'radius_changed', function() {
  radius = circle.getRadius();
});

google.maps.event.addListener(outerPath, 'set_at', function() {
  print('Vertex moved on outer path.');
});

google.maps.event.addListener(innerPath, 'insert_at', function() {
  print('Vertex removed from inner path.');
});

8. 繪圖(Drawing)庫

在這篇文檔中繪圖庫的概念是指google.maps.drawing庫。默認情況下,當加載地圖Javascritp API時,該庫不會被加載,必須通過“libraries”指令顯式指定才能加載。
http://maps.googleapis.com/maps/api/js?sensor=false&libraries=drawing 

更多相關信息參見 Libraries in the V3 Maps API

DrawingManager類提供了一個繪圖接口,供用戶在地圖上繪制多邊形、矩形、折線、圓以及Marker。下面是創建一個DrawingManager對象。

var drawingManager = new google.maps.drawing.DrawingManager();
drawingManager.setMap(map);

8.1 DrawingManager選項

DrawingManager構造函數接受一組選項參數,來定義控件的顯示外觀,位置以及初始繪制狀態。

  • DrawingManager類的drawingMode屬性定義了DrawingManager的初始繪制狀態。它接受一個google.maps.drawing.OverlayType常量。默認值為null,當DrawingManager初始化時,光標為非繪制狀態。
  • DrawingManager類的drawingControl屬性定義了地圖上繪制工具是否可見。它接受boolean類型的值。
  • 您也可以定義控件的位置,使用DrawingManager類的drawingControlOptions選項定義在控件上顯示幾種類型的overlay。
  • position定義地圖上繪圖控件的位置,它接受google.maps.ControlPosition常量。
  • drawingModes是一個google.maps.drawing.OverlayType常量的數組,定義了包含多少個Overlay圖形繪制的工具。“手形”圖標總是存在,允許用戶在不繪制的情況下和地圖交互。工具出現的順序和它們在數組中的順序一致。
  • 每種類型的Overlay都有默認的屬性。這些屬性定義了Overlay創建時的外觀。這些屬性都在Overlay的{Overlayer}Options屬性中。({Overlay}代表了Overlay的類型)。舉例來說,Circle的填充,畫筆,zIndex以及是否可單擊等屬性都在CircleOptions當中定義。如果傳入了大小、位置或者擁有該Overlay的Map值,那么CircleOptions中的值將被忽略。關於這些屬性更多的細節,參見API Reference documentation。

 為了圖形被創建后可編輯,需要將editable設置為true。

 

View Code
var drawingManager = new google.maps.drawing.DrawingManager({
  drawingMode: google.maps.drawing.OverlayType.MARKER,
  drawingControl: true,
  drawingControlOptions: {
    position: google.maps.ControlPosition.TOP_CENTER,
    drawingModes: [
      google.maps.drawing.OverlayType.MARKER,
      google.maps.drawing.OverlayType.CIRCLE,
      google.maps.drawing.OverlayType.POLYGON,
      google.maps.drawing.OverlayType.POLYLINE,
      google.maps.drawing.OverlayType.RECTANGLE
    ]
  },
  markerOptions: {
    icon: new google.maps.MarkerImage('http://www.example.com/icon.png')
  },
  circleOptions: {
    fillColor: '#ffff00',
    fillOpacity: 1,
    strokeWeight: 5,
    clickable: false,
    zIndex: 1,
    editable: true
  }
});
drawingManager.setMap(map);

查看示例 (drawing-tools.html)

 

8.2 圖形繪制工具控件(Drawing Tools)更新

DrawingManager對象被創建后,您可以通過調用SetOptions方法傳入參數來更新該控件。

View Code
drawingManager.setOptions({
  drawingControlOptions: {
    position: google.maps.ControlPosition.BOTTOM_LEFT,
    drawingModes: [google.maps.drawing.OverlayType.MARKER]
  }
})

隱藏或者顯示drawing tools控件。

View Code
// 隱藏:
drawingManager.setOptions({
  drawingControl: false
});

// 顯示:
drawingManager.setOptions({
  drawingControl: true
});

在map對象上移除繪圖控件。

drawingManager.setMap(null);

隱藏繪圖控件會使得該控件不顯示,但是DrawingManager類的功能依然可用。如果需要,您可以按照此方式實現自己的控件。從map對象上移除DrawingManager類,則會移除所有繪圖功能。如果所有繪制要素要重置的話,那么DrawingManager類通過drawingManager.setMap(map)或者構造新的DrawingManager對象來和地圖重新關聯。

Drawing事件

當一個圖形Overlay被創建時,有兩個事件會被激發:

  • 一個是{Overlay}complete事件({overlay}代表了overlay的類型,比如circlecomplete,polycomplete事件等)。overlay的句柄作為參數傳入。
  • 一個是overlaycomplete事件。一個對象數組,包含OverlayType以及overlay的句柄。
View Code
google.maps.event.addListener(drawingManager, 'circlecomplete', function(circle) {
  var radius = circle.getRadius();
});

google.maps.event.addListener(drawingManager, 'overlaycomplete', function(event) {
  if (event.type == google.maps.drawing.OverlayType.CIRCLE) {
    var radius = event.overlay.getRadius();
  }
});

9.信息窗口(InfoWindow)

InfoWindow 在地圖上方的浮動窗口中顯示內容。信息窗口有點像漫畫書上的文字氣球,它有一個內容區域和錐形引線,引線的頭位於地圖的指定位置上。通過點擊 Google Maps 上的商戶標記,您可以看到活動的信息窗口。

 InfoWindow 構造函數采用的是 InfoWindow options 對象,該對象指定了用於顯示信息窗口的一組初始參數。在創建信息窗口的過程中,系統不會在地圖上添加信息窗口。要顯示信息窗口,您需要調用 InfoWindow 上的 open() 方法,向其傳遞要在其中打開信息窗口的 Map,以及向其傳遞用於錨定信息窗口的 Marker(可選)。(如果未提供任何標記,那么,會在其 position 屬性上打開信息窗口)。

 InfoWindow options 對象是包含以下字段的對象常量:

  • content 包含了信息窗口打開時,系統要在其中顯示的文本字符串或 DOM 節點。
  • pixelOffset 包含了從信息窗口的頂部到信息窗口錨定位置的偏移量。實際上,您不應也無需修改此字段。
  • position 包含了此信息窗口錨定位置的 LatLng。請注意,在標記上執行打開信息窗口操作時,系統會自動使用一個新位置更新該值。
  • maxWidth 指定了信息窗口的最大寬度(以像素為單位)。默認情況下,信息窗口會根據其中包含的內容進行擴展,如果信息窗口隨着地圖的大小而擴展,那么,文本將會自動換行。如果您應用了 maxWidth,那么,信息窗口將自動換行以強制適應像素的寬度。如果屏幕的實際使用面積允許的話,信息窗口在達到最大寬度后仍可垂直擴展。

InfoWindow 的內容可以是文本字符串、HTML 代碼段或 DOM 元素本身。要設置此內容,請在 InfoWindow options 構造函數中傳遞該內容,或者對InfoWindow顯式調用 setContent()。如果想要顯式調整內容的大小,您可以使用 <div> 進行此操作,如果您願意,還可以啟用滾動功能。請注意,如果您沒有啟用滾動功能,而內容的大小又超過了信息窗口的可用空間,那么,內容可能會從信息窗口中“溢”出。

InfoWindow 可附加到 Marker 對象(在這種情況下,它們的位置取決於標記的位置)上,或附加到地圖本身指定的 LatLng 位置上。如果您一次只想顯示一個信息窗口(正如 Google Maps 上的相應行為),那么,您只需創建一個信息窗口,然后在地圖事件(例如用戶點擊)執行過程中將此信息窗口重新分配到不同的位置或標記中。但與 Google Maps API 第 2 版中的相應行為不同的是,如果您選擇進行上述操作,那么,地圖可能會立即顯示多個 InfoWindow 對象。

要更改信息窗口的位置,您可以對信息窗口調用 setPosition() 以顯式的方式更改其位置,或者使用 InfoWindow.open() 方法將信息窗口附加到新標記上。請注意,如果您在沒有傳遞標記的情況下調用了 open(),那么,InfoWindow 將會使用在構建過程中通過 InfoWindow options 對象指定的位置。

以下代碼顯示了澳大利亞中心位置的標記。點擊該標記可顯示信息窗口。

View Code
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var mapOptions = {
  zoom: 4,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

var contentString = '<div id="content">'+
    '<div id="siteNotice">'+
    '</div>'+
    '<h2 id="firstHeading" class="firstHeading">Uluru</h2>'+
    '<div id="bodyContent">'+
    '<p><b>Uluru</b>, also referred to as <b>Ayers Rock</b>, is a large ' +
    'sandstone rock formation in the southern part of the '+
    'Northern Territory, central Australia. It lies 335 km (208 mi) '+
    'south west of the nearest large town, Alice Springs; 450 km '+
    '(280 mi) by road. Kata Tjuta and Uluru are the two major '+
    'features of the Uluru - Kata Tjuta National Park. Uluru is '+
    'sacred to the Pitjantjatjara and Yankunytjatjara, the '+
    'Aboriginal people of the area. It has many springs, waterholes, '+
    'rock caves and ancient paintings. Uluru is listed as a World '+
    'Heritage Site.</p>'+
    '<p>Attribution: Uluru, <a href="http://en.wikipedia.org/w/index.php?title=Uluru&oldid=297882194">'+
    'http://en.wikipedia.org/w/index.php?title=Uluru</a> (last visited June 22, 2009).</p>'+
    '</div>'+
    '</div>';

var infowindow = new google.maps.InfoWindow({
    content: contentString
});

var marker = new google.maps.Marker({
    position: myLatlng,
    map: map,
    title:"Uluru (Ayers Rock)"
});

google.maps.event.addListener(marker, 'click', function() {
  infowindow.open(map,marker);
});

查看示例 (infowindow-simple.html)

以下顯示了將信息窗口 maxWidth 設置為 200 像素的示例:

查看示例 (infowindow-simple-max.html)

 

10. Ground Overlay

多邊形可以表示任意不規則的區域,但是它們無法顯示圖像。如果您有圖像希望顯示在地圖上,那么需要用到GroundOverlay對象。GroundOverlay的構造函數中需要指定圖像的URL以及圖像的邊界(LatLngBounds)。該圖像將顯示在地圖上,並且限制在指定的邊界里,同時使用當前地圖的投影。

下面的例子是將新澤西州的紐瓦克古地圖作為一個Overlay疊加到地圖上。

View Code
var newark = new google.maps.LatLng(40.740, -74.18);
var imageBounds = new google.maps.LatLngBounds(
    new google.maps.LatLng(40.716216,-74.213393),
    new google.maps.LatLng(40.765641,-74.139235));

var mapOptions = {
  zoom: 13,
  center: newark,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

var oldmap = new google.maps.GroundOverlay(
    "http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg",
    imageBounds);
oldmap.setMap(map);

查看示例(groundoverlay-simple.html)

11. 自定義Overlay

Google Maps API 第 3 版提供了用於創建自定義疊加層的 OverlayView 類。OverlayView 是一個基類,提供了您在創建Overlay時必須實現的若干方法。該類還提供了一些方法,用於實現屏幕坐標和地圖位置之間的轉換。

 

要創建自定義疊加層,請執行以下操作:

  • 將自定義對象的 prototype 設置為 google.maps.OverlayView() 的新實例。這可以有效地實現疊加層類的“子類化”。
  • 為自定義疊加層創建構造函數,並將該構造函數中的所有初始化參數都設置為自定義屬性。
  • 在原型中實現 onAdd() 方法,以將疊加層附加到地圖上。當地圖准備好附加疊加層后,系統將會調用 OverlayView.onAdd()。
  • 在原型中實現 draw() 方法,以處理對象的視覺顯示。同樣,在對象首次顯示后,系統將會調用 OverlayView.draw()。
  • 您還應當實現 onRemove() 方法,以清理在疊加層中添加的所有元素。

我們將會在以下各部分中逐步介紹這些操作。

11.1 Overlay的子類化

我們將會使用 OverlayView 創建簡單的圖像疊加層(與第 2 版 API 中的 GGroundOverlay 相似)。我們還會創建一個 USGSOverlay 對象,它包含了相關區域的 USGS 圖像以及圖像的邊界。

View Code
var overlay;

function initialize() {
  var myLatLng = new google.maps.LatLng(62.323907, -150.109291);
  var mapOptions = {
    zoom: 11,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.SATELLITE
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

  var swBound = new google.maps.LatLng(62.281819, -150.287132);
  var neBound = new google.maps.LatLng(62.400471, -150.005608);
  var bounds = new google.maps.LatLngBounds(swBound, neBound);

  //美國地質調查局影像 
  var srcImage = 'images/talkeetna.png';
  overlay = new USGSOverlay(bounds, srcImage, map);
}

接下來,我們則會創建該類的一個構造函數,並將已傳遞的參數初始化為新對象的屬性。此外,我們還需要顯式地將 USGSOverlay 中的 OverlayView 子類化。我們可通過將新類的 prototype 設置為父類的一個實例進行上述操作(由於我們不希望修改父類,因此,我們在此處將prototype設置為父類實例,而非父類本身)。

 

View Code
function USGSOverlay(bounds, image, map) {

  //初始化所有屬性.
  this.bounds_ = bounds;
  this.image_ = image;
  this.map_ = map;

  // 定義一個能存儲影像的Div.在add()
    // 方法里創建該div,現在將其設為null值

  this.div_ = null;

  // 顯式調用setMap方法
  this.setMap(map);
}

USGSOverlay.prototype = new google.maps.OverlayView();

10.2 初始化Overlay

當Overlay第一次創建並處於准備顯示狀態時,我們需要通過瀏覽器的 DOM模型將Overlay和地圖連接起來。當Overlay添加到地圖上時,會調用overlay的onAdd()方法。在這個方法中,我們會創建一個<div>來保存我們的圖像,並且

在處理此方法時,我們會創建一個用於保存圖像的 <div>,添加一個 <img> 元素,將該元素附加到 <div>,最后將疊加層附加到地圖的一個“窗格”(即 DOM 樹中的節點)中。

 一組 MapPanes 類型的窗格用於指定不同的層在地圖上的堆疊順序。您可以使用以下窗格,並且可以按照由下至上的堆疊順序枚舉這些窗格。

 

  • MapPanes.mapPane
  • MapPanes.overlayLayer
  • MapPanes.overlayShadow
  • MapPanes.overlayImage
  • MapPanes.floatShadow
  • MapPanes.overlayMouseTarget
  • MapPanes.floatPane

 由於我們的圖像為“ground overlay”,因此,我們將會使用 overlayLayer 地圖窗格。創建了此窗格后,我們會以子對象的形式將對象附加到窗格上。

View Code
USGSOverlay.prototype.onAdd = function() {

  // 注意:overlay的onAdd()方法表明地圖的
 //  pane可以通過DOM模型將overlay和map關聯起來


  // 創建一個Div,並且設置若干基礎屬性
  var div = document.createElement('div');
  div.style.border = "none";
  div.style.borderWidth = "0px";
  div.style.position = "absolute";

  // 創建img標簽,並將img和div聯系起來
  var img = document.createElement("img");
  img.src = this.image_;
  img.style.width = "100%";
  img.style.height = "100%";
  div.appendChild(img);

  // 將overlay的div和該div關聯起來
  this.div_ = div;

  // 通過map的pane將overlay和map關聯起來
  // 將overlay添加到overlayimage pane上
  var panes = this.getPanes();
  panes.overlayLayer.appendChild(div);
}

11.3 Overlay繪制

請注意,在上述操作中,我們實際上並未調用任何特殊的視覺顯示。每當需要在地圖上繪制疊加層時(其中包括首次添加疊加層時),API 都會對疊加層調用獨立的 draw() 方法。

因此,我們將會實現此 draw() 方法,然后使用 getProjection() 檢索overlay的 MapCanvasProjection,並計算對象的右上角和左下角錨定點的准確坐標,以此重新調整 <div> 的大小;反之,此操作又可重新調整圖像的大小,從而讓圖像與我們在overlay的構造函數中所指定的范圍相匹配。

View Code
USGSOverlay.prototype.draw = function() {

  // 調整overlay的尺寸和位置。我們使用overlay的西南和東北
 //  兩點來調整overlay正確的位置和尺寸。我們需要從overlay
 //  獲得投影來完成

  var overlayProjection = this.getProjection();

  // 獲得overlay的西南和東北坐標(latlngs),然后將其轉換為
    // 屏幕像素坐標。我們使用該坐標來調整Div。

  var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
  var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());

  // 調整圖像的Div來滿足所指定的坐標
  var div = this.div_;
  div.style.left = sw.x + 'px';
  div.style.top = ne.y + 'px';
  div.style.width = (ne.x - sw.x) + 'px';
  div.style.height = (sw.y - ne.y) + 'px';
}

11.4 刪除Overlay

我們還會添加 onRemove() 方法,完全刪除地圖中的疊加層。如果我們曾經將疊加層的 map 屬性設置為 null,那么,系統將會自動通過 API 調用此方法。

USGSOverlay.prototype.onRemove = function() {
  this.div_.parentNode.removeChild(this.div_);
  this.div_ = null;
}

查看示例(overlay-simple.html)

 

11.5 隱藏和顯示overlay

如果您想要隱藏或顯示overlay,而不只是創建或刪除overlay,您可以實現 hide() 和 show() 方法,以調整overlay的可見性。或者,您也可以將overlay與地圖的 DOM 分離,但這種操作的成本有些過高。請注意,如果您隨后將疊加層重新附加到地圖的 DOM 上,則系統會重新調用疊加層的 onAdd()方法。

 以下示例介紹了如何將 hide() 和 show() 方法添加到overlay的原型中,這樣可以切換顯示容器 <div>。此外,我們還添加了 toogleDOM() 方法,它可將overlay附加到地圖,或者將兩者分離開來。請注意,如果我們將visibility設置為 "hidden",然后通過 toggleDOM() 將地圖與 DOM 分離,隨后又重新附加了地圖,那么,疊加層會再次顯示出來,這是因為,我們在疊加層的 onAdd() 方法中重新創建了其中所包含的 <div>。

View Code
// 注意visibility屬性必須是個字符串 
USGSOverlay.prototype.hide = function() {
  if (this.div_) {
    this.div_.style.visibility = "hidden";
  }
}

USGSOverlay.prototype.show = function() {
  if (this.div_) {
    this.div_.style.visibility = "visible";
  }
}

USGSOverlay.prototype.toggle = function() {
  if (this.div_) {
    if (this.div_.style.visibility == "hidden") {
      this.show();
    } else {
      this.hide();
    }
  }
}

USGSOverlay.prototype.toggleDOM = function() {
  if (this.getMap()) {
    this.setMap(null);
  } else {
    this.setMap(this.map_);
  }
}
View Code
// 現在添加一個按鈕來觸發該事件
<div id ="toolbar" width="100%; height:20px;" style="text-align:center">
  <input type="button" value="Toggle Visibility" onclick="overlay.toggle();"></input>
  <input type="button" value="Toggle DOM Attachment" onclick="overlay.toggleDOM();"></input>
</div>
<div id="map_canvas" style="width: 100%; height: 95%;"></div>

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM