KmlLayer
を使うと、KML 要素と GeoRSS 要素を Maps JavaScript API タイル オーバーレイにレンダリングできます。
概要
Maps JavaScript API は、地理情報を表示するために KML および GeoRSS のデータ形式をサポートしています。これらのデータ形式は、KmlLayer
オブジェクトを使用して地図上に表示されます。このオブジェクトのコンストラクタは公開されてアクセス可能な KML または GeoRSS ファイルの URL を受け取ります。
注: Maps JavaScript API で KML オーバーレイを生成する KmlLayer
クラスは、Google がホストするサービスを使用して、レンダリングする KML ファイルの取得および解析を行います。したがって、KML ファイルを表示できるのは、一般公開されている URL でホストされており、そのアクセスに認証を必要としない場合に限られます。
プライベート ファイルにアクセス、キャッシュに対して細かい管理、またはクエリ パラメータとしてブラウザのビューポートを地理空間データサーバーに送信する必要がある場合は、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
ではなく、地図上で 1 つのオブジェクトにレンダリングされます。
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 オーバーレイのような表示になるようにレンダリングされます。個々の対象物をクリックすると、デフォルトでは、該当する対象物に関する KML <title>
および <description>
情報を含む InfoWindow
が表示されます。また、KML 対象物をクリックすると KmlMouseEvent
が生成されます。これにより次の情報が渡されます。
position
は、KML 対象物のInfoWindow
が固定されている緯度と経度の座標を示します。この位置は、通常はポリゴン、ポリラインおよび GroundOverlay はクリックされた位置になり、マーカーの場合はマーカーの位置になります。pixelOffset
は、InfoWindow
の「尾」の部分を固定する上記のposition
からのオフセットを示します。ポリゴン オブジェクトの場合、このオフセットは通常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" }
次のサンプルでは、KML 対象物がクリックされたときに対象物の <Description>
テキストがサイドの <div>
内に表示されます。
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 ファイルの画像非圧縮ファイルの最大サイズ
- 1 ファイルあたり 500 KB
- ネットワーク リンクの最大数
- 10
- ドキュメント全体における対象物の最大合計数
- 1,000
- KML レイヤ数
- 1 つの Google マップ上に表示可能な KML レイヤの数には制限があります。この制限を超えると、地図上には一切レイヤが表示されず、ウェブブラウザの JavaScript コンソールでエラーが報告されます。この制限は、作成された
KmlLayer
クラスの数と、それらのレイヤの作成に使用されたすべての URL の合計長に基づいています。新しく作成するKmlLayer
はそれぞれレイヤ数に加算されます。また、KML ファイルの読み込み元 URL の長さに応じて、さらに多くのレイヤ数が加算されます。そのため、追加できるレイヤ数はアプリケーションによって異なります。制限に達することなく平均で 10~20 のレイヤを読み込むことができます。それでも制限に達する場合は、短縮 URL サービスを使用して KML URL を短縮します。または、各 KML URL を参照する NetworkLink からなる KML ファイルを 1 つ作成します。
パフォーマンスとキャッシュ保存に関する考慮事項
サーバーの負荷を軽減するために、Google のサーバーでは KML ファイルが一時的にキャッシュに保存されます。キャッシュに保存することで、ユーザーが地図上でクリック、パン、ズームを行った際に、KML ファイルの適切なセグメントの表示をスペース効率の高い方法で提供できるため、ユーザー側のパフォーマンスも向上します。
最適なパフォーマンスを実現するための推奨事項は次のとおりです
- 適切な
<expires>
タグを KML で使用します。
KmlLayer
は、KML ファイルのキャッシュ方法を決定する際に HTTP ヘッダーを使用しません。 - リクエスト時にファイルを動的に生成しないようにします。
必要になると思われるファイルはあらかじめ生成しておき、静的に提供します。サーバーからの KML ファイルの送信に時間がかかる場合は、KmlLayer
が表示されないこともあります。 - ファイルが明らかに更新されたことがわかっている場合を除き、キャッシュをバイパスしようとしないでください。
常にキャッシュをバイパスする(例: クエリ パラメータとして乱数またはユーザー側の時計の時刻を追加する)と、サイトへのアクセスが急減に増加し、大きな KML ファイルを配信している場合、ご利用のサーバーに負担がかかりすぎることがあります。
また、ユーザー側の時計の時刻が正確でなく、かつ<expires>
タグが正しく設定されていない場合は、キャッシュから古いデータがユーザーに配信されることもあります。
この場合は、更新された静的ファイルを個別の新しいリビジョン番号で公開し、サーバー側のコードを使用してKmlLayer
に渡される URL を現在のバージョンに動的に更新します。 - KML ファイルへの変更は 1 分に 1 回に制限します。
すべてのファイルの合計サイズ(非圧縮)が 1 MB を超える場合は、変更は 5 分に 1 回に制限します。 - 地理空間データサーバーを使用する場合は、レイヤのビューポートを制限するためにクエリ パラメータを使用しないでください。
代わりに、bounds_changed
イベントで地図ビューポートを制限できます。ユーザーには、自動的に表示可能な対象物のみが送信されます。
地理空間データサーバーに大量のデータがある場合は、代わりにデータレイヤの使用を検討してください。 - 地理空間データサーバーを使用する場合は、異なるクエリ パラメータを持つ単一の
KmlLayer
ではなく、ユーザーに切り替えを許可する対象物のグループごとに複数のKmlLayer
を使用します。 - 圧縮された KMZ ファイルを使用して、ファイルサイズを削減します。
- Google Cloud Storage などのクラウド ストレージ ソリューションを使用している場合は、署名済み URL や一時トークンなどの機能を使用してアクセス制御を行わないでください。そうすると、意図せずキャッシュ保存を阻止してしまう可能性があります。
- すべてのポイントの精度を適切な精度に下げてください。
- ポリゴンやポリラインなど、類似した対象物のジオメトリを結合して簡素化します。
- 使用されていない要素または画像リソースがあれば削除します。
- サポートされていない要素があれば削除します。
プライベート データにアクセスしたり、キャッシュ保存を阻止したり、ブラウザのビューポートをクエリ パラメータとして地理空間データサーバーに送信したりする必要がある場合は、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 マップはインターネットから取得したデータを不特定の期間にわたってキャッシュします。インターネットからデータを再取得するように強制するには、ドキュメントの名前を変更する、別の URL でデータを取得する、またはドキュメントに適切な有効期限を指定する方法があります。 |
<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> | あり | 廃止 |