KmlLayer 會將 KML 和 GeoRSS 元素算繪成 Maps JavaScript API 圖塊疊加層。
總覽
Maps JavaScript API 支援顯示地理資訊的 KML 和 GeoRSS 資料格式。這些資料格式使用 KmlLayer 物件顯示在地圖上,該物件的建構函式接受可公開存取的 KML 或 GeoRSS 檔案網址。
注意:在 Maps JavaScript API 中產生 KML 疊加層的 KmlLayer 類別,會以 Google 代管的服務擷取和剖析 KML 檔案,並進行算繪。因此,只有當 KML 檔案代管在無需驗證即可公開存取的網址時,才能顯示這些檔案。
如果您需要存取私人檔案、精確控制快取,或是將瀏覽器可視區域做為查詢參數傳送至地理空間資料伺服器,建議使用資料層,而非 KmlLayer。這會引導使用者的瀏覽器直接向您的網路伺服器要求資源。
Maps JavaScript API 會將提供的地理 XML 資料轉換成 KML 表示法,並使用 Maps JavaScript API 圖塊疊加層顯示在地圖上。這個 KML 不僅外觀與 Maps JavaScript API 疊加層元素十分相似,兩者的某些行為也十分雷同。舉例來說,KML <Placemark> 與 GeoRSS point 元素都會算繪為標記,<LineString> 元素會算繪為折線,而 <Polygon> 元素則會算繪為多邊形。同樣地,<GroundOverlay> 元素在地圖上會算繪為矩形圖片。但請注意,這些物件不是 Maps JavaScript API Markers、Polylines、Polygons 或 GroundOverlays,而是會算繪為地圖上的單一物件。
設定 KmlLayer 物件的 map 屬性後,物件就會顯示在地圖上。您可以呼叫 setMap() 並傳遞 null,將該物件從地圖上移除。KmlLayer 物件會針對地圖的特定範圍自動擷取適合的地圖項目,藉此管理這些子元素的算繪作業。範圍會產生變化時,目前可視區域內的地圖項目會自動算繪。
KmlLayer 內的元件是隨需算繪,因此您可以運用圖層輕鬆管理數千個標記、折線及多邊形的算繪作業。請注意,雖然每個構成物件所提供的點擊事件會針對各物件本身傳回資料,但您無法直接存取這些構成物件。
KML 圖層選項
KmlLayer() 建構函式會視需要傳遞數個 KmlLayerOptions:
map指定要算繪KmlLayer的Map。在setMap()方法中將此值設定為null,即可隱藏KmlLayer。preserveViewport指定顯示圖層時,不應根據KmlLayer的內容範圍調整地圖。根據預設,顯示KmlLayer時,地圖會縮放並調整位置以顯示圖層的完整內容。suppressInfoWindows表示KmlLayer內的可點選地圖項目不應觸發InfoWindow物件顯示。
此外,經過算繪後,KmlLayer 會包含不可變更的 metadata 屬性,該屬性的 KmlLayerMetadata 物件常值中內含圖層的名稱、說明、程式碼片段及作者。您可以使用 getMetadata() 方法檢查此資訊。算繪 KmlLayer 物件時需要與外部伺服器進行非同步通訊,因此建議您監聽 metadata_changed 事件,事件會表示已經填入屬性。
以下範例是根據指定的 GeoRSS 動態饋給來建構 KmlLayer:
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 4, center: { lat: 49.496675, lng: -102.65625 }, } ); const georssLayer = new google.maps.KmlLayer({ url: "http://api.flickr.com/services/feeds/geo/?g=322338@N20&lang=en-us&format=feed-georss", }); georssLayer.setMap(map); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 4, center: { lat: 49.496675, lng: -102.65625 }, }); const georssLayer = new google.maps.KmlLayer({ url: "http://api.flickr.com/services/feeds/geo/?g=322338@N20&lang=en-us&format=feed-georss", }); georssLayer.setMap(map); } window.initMap = initMap;
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
HTML
<html>
<head>
<title>GeoRSS Layers</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
</head>
<body>
<div id="map"></div>
<!--
The `defer` attribute causes the script to execute after the full HTML
document has been parsed. For non-blocking uses, avoiding race conditions,
and consistent behavior across browsers, consider loading using Promises. See
https://developers.google.com/maps/documentation/javascript/load-maps-js-api
for more information.
-->
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
defer
></script>
</body>
</html>測試範例
以下範例是根據指定的 KML 動態饋給來建構 KmlLayer:
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 11, center: { lat: 41.876, lng: -87.624 }, } ); const ctaLayer = new google.maps.KmlLayer({ url: "https://googlearchive.github.io/js-v2-samples/ggeoxml/cta.kml", map: map, }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 11, center: { lat: 41.876, lng: -87.624 }, }); const ctaLayer = new google.maps.KmlLayer({ url: "https://googlearchive.github.io/js-v2-samples/ggeoxml/cta.kml", map: map, }); } window.initMap = initMap;
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
HTML
<html>
<head>
<title>KML Layers</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
</head>
<body>
<div id="map"></div>
<!--
The `defer` attribute causes the script to execute after the full HTML
document has been parsed. For non-blocking uses, avoiding race conditions,
and consistent behavior across browsers, consider loading using Promises. See
https://developers.google.com/maps/documentation/javascript/load-maps-js-api
for more information.
-->
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
defer
></script>
</body>
</html>測試範例
KML 地圖項目詳細資料
KML 可能包含大量地圖項目,因此您無法直接從 KmlLayer 物件存取地圖項目資料。不過,顯示地圖項目時,系統會進行算繪,使地圖項目看起來像是可點選的 Maps JavaScript API 疊加層。根據預設,點選個別地圖項目時,系統會顯示 <title>,其中包含與指定地圖項目相關的 KML <title> 和 <description> 資訊。此外,點選 KML 地圖項目會產生 KmlMouseEvent 並傳遞下列資訊:
position表示錨定此 KML 地圖項目InfoWindow的經緯度座標。這個位置通常是多邊形、折線和地面疊加層的點選位置,但對標記而言,則是實際起點。pixelOffset表示從上方的position到錨定InfoWindow「尾端」位置的偏移值。對多邊形物件而言,此偏移值通常是0,0,但對標記而言,還必須包含標記的高度。featureData包含KmlFeatureData的 JSON 結構。
以下顯示範例 KmlFeatureData 物件:
{ author: { email: "nobody@google.com", name: "Mr Nobody", uri: "http://example.com" }, description: "description", id: "id", infoWindowHtml: "html", name: "name", snippet: "snippet" }
以下範例顯示地圖項目經點選時,側邊 <div> 內的 KML 地圖項目 <Description> 文字:
TypeScript
function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 12, center: { lat: 37.06, lng: -95.68 }, } ); const kmlLayer = new google.maps.KmlLayer({ url: "https://raw.githubusercontent.com/googlearchive/kml-samples/gh-pages/kml/Placemark/placemark.kml", suppressInfoWindows: true, map: map, }); kmlLayer.addListener("click", (kmlEvent) => { const text = kmlEvent.featureData.description; showInContentWindow(text); }); function showInContentWindow(text: string) { const sidebar = document.getElementById("sidebar") as HTMLElement; sidebar.innerHTML = text; } } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 12, center: { lat: 37.06, lng: -95.68 }, }); const kmlLayer = new google.maps.KmlLayer({ url: "https://raw.githubusercontent.com/googlearchive/kml-samples/gh-pages/kml/Placemark/placemark.kml", suppressInfoWindows: true, map: map, }); kmlLayer.addListener("click", (kmlEvent) => { const text = kmlEvent.featureData.description; showInContentWindow(text); }); function showInContentWindow(text) { const sidebar = document.getElementById("sidebar"); sidebar.innerHTML = text; } } window.initMap = initMap;
CSS
/* Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; } #container { height: 100%; display: flex; } #sidebar { flex-basis: 15rem; flex-grow: 1; padding: 1rem; max-width: 30rem; height: 100%; box-sizing: border-box; overflow: auto; } #map { flex-basis: 0; flex-grow: 4; height: 100%; }
HTML
<html>
<head>
<title>KML Feature Details</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
</head>
<body>
<div id="container">
<div id="map"></div>
<div id="sidebar"></div>
</div>
<!--
The `defer` attribute causes the script to execute after the full HTML
document has been parsed. For non-blocking uses, avoiding race conditions,
and consistent behavior across browsers, consider loading using Promises. See
https://developers.google.com/maps/documentation/javascript/load-maps-js-api
for more information.
-->
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
defer
></script>
</body>
</html>測試範例
KML 算繪的大小和複雜度限制
Maps JavaScript API 會限制所載入 KML 檔案的大小和複雜度。以下摘要列出目前的限制:
注意:這些限制隨時可能有所變動。
- 可擷取檔案大小上限 (原始 KML、原始 GeoRSS 或壓縮過的 KMZ)
- 3 MB
- 未壓縮 KML 檔案大小上限
- 10 MB
- KMZ 檔案中未壓縮圖片檔大小上限
- 每個檔案 500 KB
- 網路連結數量上限
- 10
- 整份文件的地圖項目總數上限
- 1,000
- KML 圖層數量
- 單一 Google 地圖可顯示的 KML 圖層數量有上限。如果超過此上限,地圖上就不會顯示您的任何圖層,且網路瀏覽器的 JavaScript 控制台中會顯示錯誤訊息。這個上限取決於兩項因素,即已建立的
KmlLayer類別數量,以及用於建立這些圖層的所有網址總長度。您建立的所有新KmlLayer都會佔圖層上限的一部分,而 KML 檔案載入來源的網址長度也會佔另一部分。因此,可新增的圖層數量會因應用程式而異。平均來說,您應該可以載入 10 到 20 個圖層,而不會達到上限。如果您仍達到上限,請使用網址縮短工具縮短 KML 網址。您也可以建立單一 KML 檔案,在其中納入指向個別 KML 網址的 NetworkLink。
效能和快取注意事項
Google 的伺服器會暫時快取 KML 檔案,以降低伺服器的負載。這也會在使用者點選、平移和縮放地圖時,為 KML 檔案提供適當區隔以有效利用空間呈現方式,進而改善使用者體驗。
為獲得最佳成效,建議您:
- 在 KML 中使用適當的
<expires>標記。
KmlLayer決定如何快取 KML 檔案時,「不會」使用 HTTP 標頭。 - 請勿在要求時動態產生檔案。
請改為在有需要前就產生檔案,並以靜態方式提供。如果伺服器需要較長的時間來傳輸 KML 檔案,KmlLayer可能無法顯示。 - 除非您明確知道檔案已更新,否則請勿嘗試略過快取。
如果網站使用者突然增加,且您提供大型的 KML 檔案,則一律略過快取 (例如透過附加隨機號碼或使用者的時鐘時間做為查詢參數) 會導致伺服器過載。
此外,如果使用者的時鐘不正確,且<expires>標記未正確設定,還可能會導致快取為使用者提供過時的資料。
請改為使用獨立的新修訂版本編號發布更新後的靜態檔案,然後使用伺服器端程式碼,將傳送至KmlLayer的網址動態更新為目前版本。 - 將您的 KML 檔案變更頻率限制為每分鐘一次。
如果所有檔案的總大小 (未壓縮) 超過 1 MB,則將變更頻率限制為每 5 分鐘一次。 - 使用地理空間資料伺服器時,請避免使用查詢參數來限制圖層的可視區域。
您可以改為使用bounds_changed事件來限制地圖可視區域。系統只會向使用者傳送可自動顯示的地圖項目。
如果地理空間資料伺服器中有大量資料,建議您改用資料層。 - 使用地理空間資料伺服器時,請針對要允許使用者切換的每個地圖項目群組使用多個
KmlLayer,而不要使用具備不同查詢參數的單一KmlLayer。 - 使用壓縮的 KMZ 檔案縮減檔案大小。
- 如果您使用 Google Cloud Storage 或其他雲端儲存空間解決方案,請「避免」使用經簽署的網址或臨時權杖等功能來強制執行存取權控管。這類操作可能會意外造成快取作業無法執行。
- 將所有點的精確度降低為適當的精確度。
- 合併並簡化類似地圖項目 (例如多邊形和折線) 的幾何圖形。
- 移除所有未使用的元素或圖片資源。
- 移除所有不支援的元素。
如果您需要存取私人資料、防止快取,或是將瀏覽器可視區域傳送至地理空間資料伺服器做為查詢參數,建議您使用資料層,而非 KmlLayer。這會引導使用者的瀏覽器直接向您的網路伺服器要求資源。
支援的 KML 元素
Maps JavaScript API 支援下列 KML 元素。KML 剖析器通常會自動忽略無法辨識的 XML 標記。
- 地標
- 圖示
- 資料夾
- 描述性 HTML:透過 <BalloonStyle> 和 <text> 的實體替代項目
- KMZ (壓縮過的 KML,包括附加圖片)
- 折線和多邊形
- 折線和多邊形樣式,包括顏色、填滿和不透明度
- 可動態匯入資料的網路連結
- 區域疊加層和螢幕疊加層
下表提供支援的 KML 元素完整詳細資料。
| KML 元素 | API 是否支援? | 註解 |
|---|---|---|
| <address> | 否 | |
| <AddressDetails> | 否 | |
| <Alias> | 不適用 | 不支援 <Model> |
| <altitude> | 否 | |
| <altitudeMode> | 否 | |
| <atom:author> | 是 | |
| <atom:link> | 是 | |
| <atom:name> | 是 | |
| <BalloonStyle> | 部分支援 | 僅支援 <text> |
| <begin> | 不適用 | 不支援 <TimeSpan> |
| <bgColor> | 否 | |
| <bottomFov> | 不適用 | 不支援 <PhotoOverlay> |
| <Camera> | 否 | |
| <Change> | 部分支援 | 僅支援樣式變更 |
| <color> | 部分支援 | 包含 #AABBGGRR 和 #BBGGRR;<IconStyle>、<ScreenOverlay> 和 <GroundOverlay> 不支援 |
| <colorMode> | 否 | |
| <cookie> | 否 | |
| <coordinates> | 是 | |
| <Create> | 否 | |
| <Data> | 是 | |
| <Delete> | 否 | |
| <description> | 是 | 允許 HTML 內容,但會經過清除,以免受到跨瀏覽器攻擊。不支援 $[dataName] 表單的實體替代項目。 |
| <displayMode> | 否 | |
| <displayName> | 否 | |
| <Document> | 部分支援 | 默示支援子項;做為其他地圖項目的子項無效 |
| <drawOrder> | 否 | |
| <east> | 是 | |
| <end> | 不適用 | 不支援 <TimeSpan> |
| <expires> | 是 | 詳情請參閱「摘要」部分 |
| <ExtendedData> | 部分支援 | 僅支援未經類型宣告的 <Data>,不支援 <SimpleData> 或 <Schema>,也不支援 $[dataName] 表單的實體替代項目。 |
| <extrude> | 否 | |
| <fill> | 是 | |
| <flyToView> | 否 | |
| <Folder> | 是 | |
| <geomColor> | 否 | 已淘汰 |
| <GeometryCollection> | 否 | 已淘汰 |
| <geomScale> | 否 | 已淘汰 |
| <gridOrigin> | 不適用 | 不支援 <PhotoOverlay> |
| <GroundOverlay> | 是 | 無法旋轉 |
| <h> | 是 | 已淘汰 |
| <heading> | 是 | |
| hint | 是 | 支援 target=... |
| <hotSpot> | 是 | |
| <href> | 是 | |
| <httpQuery> | 否 | |
| <Icon> | 是 | 無法旋轉 |
| <IconStyle> | 是 | |
| <ImagePyramid> | 不適用 | 不支援 <PhotoOverlay> |
| <innerBoundaryIs> | 是 | 依 <LinearRing> 順序默示 |
| <ItemIcon> | 不適用 | 不支援 <ListStyle> |
| <key> | 不適用 | 不支援 <StyleMap> |
| <kml> | 是 | |
| <labelColor> | 否 | 已淘汰 |
| <LabelStyle> | 否 | |
| <latitude> | 是 | |
| <LatLonAltBox> | 是 | |
| <LatLonBox> | 是 | |
| <leftFov> | 不適用 | 不支援 <PhotoOverlay> |
| <LinearRing> | 是 | |
| <LineString> | 是 | |
| <LineStyle> | 是 | |
| <Link> | 是 | |
| <linkDescription> | 否 | |
| <linkName> | 否 | |
| <linkSnippet> | 否 | |
| <listItemType> | 不適用 | 不支援 <ListStyle> |
| <ListStyle> | 否 | |
| <Location> | 不適用 | 不支援 <Model> |
| <Lod> | 是 | |
| <longitude> | 是 | |
| <LookAt> | 否 | |
| <maxAltitude> | 是 | |
| <maxFadeExtent> | 是 | |
| <maxHeight> | 不適用 | 不支援 <PhotoOverlay> |
| <maxLodPixels> | 是 | |
| <maxSessionLength> | 否 | |
| <maxWidth> | 不適用 | 不支援 <PhotoOverlay> |
| <message> | 否 | |
| <Metadata> | 否 | 已淘汰 |
| <minAltitude> | 是 | |
| <minFadeExtent> | 是 | |
| <minLodPixels> | 是 | |
| <minRefreshPeriod> | 否 | <NetworkLink> |
| <Model> | 否 | |
| <MultiGeometry> | 部分支援 | 已進行算繪,但在左側面板中顯示為獨立地圖項目 |
| <name> | 是 | |
| <near> | 不適用 | 不支援 <PhotoOverlay> |
| <NetworkLink> | 是 | |
| <NetworkLinkControl> | 部分支援 | 部分支援 <Update> 和 <expires>。API 會忽略 HTTP 標頭中的到期時間設定,但會使用 KML 中指定的到期時間設定。如果沒有到期時間設定或在有效期間的間隔內,Google 地圖可能會快取從網際網路擷取的資料 (未指定持續時間)。重新命名文件並以不同網址擷取,或是確保文件包含適當的到期時間設定,都可以強制從網際網路重新擷取資料。 |
| <north> | 是 | |
| <open> | 是 | |
| <Orientation> | 不適用 | 不支援 <Model> |
| <outerBoundaryIs> | 是 | 依 <LinearRing> 順序默示 |
| <outline> | 是 | |
| <overlayXY> | 否 | |
| <Pair> | 不適用 | 不支援 <StyleMap> |
| <phoneNumber> | 否 | |
| <PhotoOverlay> | 否 | |
| <Placemark> | 是 | |
| <Point> | 是 | |
| <Polygon> | 是 | |
| <PolyStyle> | 是 | |
| <range> | 是 | |
| <refreshInterval> | 部分支援 | 僅限 <Link>;<Icon> 不支援 |
| <refreshMode> | 是 | 「onExpire」模式不支援 HTTP 標頭。請參閱上方的 <Update> 和 <expires> 註解。 |
| <refreshVisibility> | 否 | |
| <Region> | 是 | |
| <ResourceMap> | 不適用 | 不支援 <Model> |
| <rightFov> | 不適用 | 不支援 <PhotoOverlay> |
| <roll> | 不適用 | 不支援 <Camera> 和 <Model> |
| <rotation> | 否 | |
| <rotationXY> | 否 | |
| <Scale> | 不適用 | 不支援 <Model> |
| <scale> | 否 | |
| <Schema> | 否 | |
| <SchemaData> | 否 | |
| <ScreenOverlay> | 是 | 無法旋轉 |
| <screenXY> | 否 | |
| <shape> | 不適用 | 不支援 <PhotoOverlay> |
| <SimpleData> | 不適用 | 不支援 <SchemaData> |
| <SimpleField> | 不適用 | 不支援 <Schema> |
| <size> | 是 | |
| <Snippet> | 是 | |
| <south> | 是 | |
| <state> | 不適用 | 不支援 <ListStyle> |
| <Style> | 是 | |
| <StyleMap> | 否 | 不支援滑鼠游標懸停 (醒目顯示) 效果 |
| <styleUrl> | 不適用 | 不支援 <StyleMap> |
| <targetHref> | 部分支援 | <Update> 支援,<Alias> 不支援 |
| <tessellate> | 否 | |
| <text> | 是 | 不支援 $[geDirections] 替代項目 |
| <textColor> | 否 | |
| <tileSize> | 不適用 | 不支援 <PhotoOverlay> |
| <tilt> | 否 | |
| <TimeSpan> | 否 | |
| <TimeStamp> | 否 | |
| <topFov> | 不適用 | 不支援 <PhotoOverlay> |
| <Update> | 部分支援 | 僅樣式變更,不支援 <Create> 或 <Delete> |
| <Url> | 是 | 已淘汰 |
| <value> | 是 | |
| <viewBoundScale> | 否 | |
| <viewFormat> | 否 | |
| <viewRefreshMode> | 部分支援 | 支援「onStop」 |
| <viewRefreshTime> | 是 | |
| <ViewVolume> | 不適用 | 不支援 <PhotoOverlay> |
| <visibility> | 部分支援 | 在 <Folder> 上支援 - 子項地標會沿用其中的瀏覽權限 |
| <w> | 是 | 已淘汰 |
| <west> | 是 | |
| <when> | 不適用 | 不支援 <TimeStamp> |
| <width> | 是 | |
| <x> | 是 | 已淘汰 |
| <y> | 是 | 已淘汰 |