Stay organized with collections Save and categorize content based on your preferences.
The KmlLayer
renders KML and GeoRSS elements into a Maps JavaScript API tile overlay.
The Maps JavaScript API supports the KML and GeoRSS data formats for displaying geographic information. These data formats are displayed on a map using a KmlLayer
object, whose constructor takes the URL of a publicly accessible KML or GeoRSS file.
Note: The KmlLayer
class that generates KML overlays in the Maps JavaScript API uses a Google hosted service to retrieve and parse KML files for rendering. Consequently, it is only possible to display KML files if they are hosted at a publicly accessible URL that does not require authentication to access.
If you require access to private files, fine-grained control over caches, or send the browser viewport to a geospatial data server as a query parameter, we recommend using data layers instead of KmlLayer
. This will direct your users' browsers to directly request resources from your web server.
The Maps JavaScript API converts the provided geographic XML data into a KML representation which is displayed on the map using a Maps JavaScript API tile overlay. This KML looks (and somewhat behaves) like familiar Maps JavaScript API overlay elements. KML <Placemark>
and GeoRSS point
elements are rendered as markers, for example, <LineString>
elements are rendered as polylines and <Polygon>
elements are rendered as polygons. Similarly, <GroundOverlay>
elements are rendered as rectangular images on the map. Importantly, however, these objects are not Maps JavaScript API Markers
, Polylines
, Polygons
or GroundOverlays
; instead, they are rendered into a single object on the map.
KmlLayer
objects appear on a map once their map
property has been set. You can remove them from the map by calling setMap()
passing null
. The KmlLayer
object manages the rendering of these child elements by automatically retrieving appropriate features for the map’s given bounds. As the bounds change, features in the current viewport are automatically rendered.
Because the components within a KmlLayer
are rendered on demand, the layer allows you to easily manage the rendering of thousands of markers, polylines, and polygons. Note that you can’t access these constituent objects directly, though they each provide click events which return data on those individual objects.
The KmlLayer()
constructor optionally passes a number of KmlLayerOptions
:
map
specifies the Map
on which to render the KmlLayer
. You can hide a KmlLayer
by setting this value to null
within the setMap()
method.preserveViewport
specifies that the map should not be adjusted to the bounds of the KmlLayer
’s contents when showing the layer. By default, when displaying a KmlLayer
, the map is zoomed and positioned to show the entirety of the layer’s contents.suppressInfoWindows
indicates that clickable features within the KmlLayer
should not trigger the display of InfoWindow
objects.Additionally, once the KmlLayer
is rendered, it contains an immutable metadata
property containing the layer’s name, description, snippet and author within a KmlLayerMetadata
object literal. You can inspect this information using the getMetadata()
method. Because rendering of KmlLayer
objects requires asynchronous communication to an external server, you will want to listen for the metadata_changed
event, which will indicate that the property has been populated.
The following example constructs a KmlLayer
from the given GeoRSS feed:
The following example constructs a KmlLayer
from the given KML feed:
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;Note: Read the guide on using TypeScript and Google Maps. 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;Note: The JavaScript is compiled from the TypeScript snippet. 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>Try Sample KML feature details
Because KML may include a large number of features, you may not access feature data from the KmlLayer
object directly. Instead, as features are displayed, they are rendered to look like clickable Maps JavaScript API overlays. Clicking on individual features, by default, brings up an InfoWindow
containing KML <title>
and <description>
information on the given feature. Additionally, a click on a KML feature generates a KmlMouseEvent
, which passes the following information:
position
indicates the latitude/longitude coordinates at which to anchor the InfoWindow
for this KML feature. This position is generally the clicked location for polygons, polylines, and GroundOverlays, but the true origin for markers.pixelOffset
indicates the offset from the above position
to anchor the InfoWindow
“tail.” For polygonal objects, this offset is typically 0,0
but for markers includes the height of the marker.featureData
contains a JSON structure of KmlFeatureData
.A sample KmlFeatureData
object is shown below:
{ author: { email: "nobody@google.com", name: "Mr Nobody", uri: "http://example.com" }, description: "description", id: "id", infoWindowHtml: "html", name: "name", snippet: "snippet" }
The following example displays KML feature <Description>
text within a side <div>
when the feature is clicked:
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;Note: Read the guide on using TypeScript and Google Maps. 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;Note: The JavaScript is compiled from the TypeScript snippet. 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>Try Sample Size and complexity restrictions for KML rendering
The Maps JavaScript API has limitations to the size and complexity of loaded KML files. Below is a summary of the current limits.
Note: These limits are subject to change at any time.
KmlLayer
classes created and the total length of all the URLs used to create those layers. Each new KmlLayer
you create will take up a portion of the limit for the layer and a further portion of the limit depending on the length of the URL where the KML file was loaded from. Consequently, the number of layers you can add will vary by application; on average, you should be able to load between 10 and 20 layers without hitting the limit. If you still hit the limit, use a URL shortener to shorten the KML URLs. Alternatively, create a single KML file consisting of NetworkLinks to the individual KML URLs.
Google's servers will temporarily cache KML files to reduce load on your servers. This will also improve performance for your users by serving a space-efficient representation of appropriate segments your KML file, as your users click on, pan and zoom the map.
For best performance, we recommend that you:
<expires>
tag in KML.
KmlLayer
will not use HTTP headers when deciding how to cache KML files.
Instead, generate the files before they will be needed, and serve them statically. If it takes a long time for your server to transmit the KML file, the KmlLayer
may not display.
Always bypassing caches (for example, by appending a random number or the user's clock time as a query parameter) can easily cause your servers to be overwhelmed if your site suddenly gets popular, and you are serving large KML files.
It can also cause the cache to serve stale data to users, if any user's clock is incorrect, and the <expires>
tag has not been set correctly.
Instead, publish updated static files with a new, discrete revision number, and use server-side code to dynamically update the URL passed to KmlLayer
with the current version.
If all files total more than 1MB in size (uncompressed), limit changes to once per 5 minutes.
Instead, you can limit the map viewport with the bounds_changed
event. Users will only be sent features that can be displayed automatically.
If there is a large amount of data in your geospatial data server, consider using data layers instead.
KmlLayer
s for each group of features that you wish to permit users to toggle, rather than a single KmlLayer
with different query parameters.If you need to access private data, prevent caching, or send the browser viewport to a geospatial data server as a query parameter, we recommend using data layers instead of KmlLayer
. This will direct your users' browsers to directly request resources from your web server.
The Maps JavaScript API supports the following KML elements. The KML parser generally silently ignores XML tags it does not understand.
The following table gives full details of the supported KML elements.
KML element Supported in the API? Comment <address> no <AddressDetails> no <Alias> N/A <Model> is not supported <altitude> no <altitudeMode> no <atom:author> yes <atom:link> yes <atom:name> yes <BalloonStyle> partially only <text> is supported <begin> N/A <TimeSpan> is not supported <bgColor> no <bottomFov> N/A <PhotoOverlay> is not supported <Camera> no <Change> partially only style changes are supported <color> partially includes #AABBGGRR and #BBGGRR; not supported in <IconStyle>, <ScreenOverlay>, and <GroundOverlay> <colorMode> no <cookie> no <coordinates> yes <Create> no <Data> yes <Delete> no <description> yes HTML content is allowed but is sanitized to protect from cross-browser attacks. Entity replacements of the form$[dataName]
are not supported. <displayMode> no <displayName> no <Document> partially implicitly, children are supported; no effect as child of other Features <drawOrder> no <east> yes <end> N/A <TimeSpan> is not supported <expires> yes see Summary section for details <ExtendedData> partially untyped <Data> only, no <SimpleData> or <Schema>, and entity replacements of the form $[dataName]
are not supported. <extrude> no <fill> yes <flyToView> no <Folder> yes <geomColor> no deprecated <GeometryCollection> no deprecated <geomScale> no deprecated <gridOrigin> N/A <PhotoOverlay> is not supported <GroundOverlay> yes cannot be rotated <h> yes deprecated <heading> yes hint yes target=...
supported <hotSpot> yes <href> yes <httpQuery> no <Icon> yes cannot be rotated <IconStyle> yes <ImagePyramid> N/A <PhotoOverlay> is not supported <innerBoundaryIs> yes implicitly from <LinearRing> order <ItemIcon> N/A <ListStyle> is not supported <key> N/A <StyleMap> is not supported <kml> yes <labelColor> no deprecated <LabelStyle> no <latitude> yes <LatLonAltBox> yes <LatLonBox> yes <leftFov> N/A <PhotoOverlay> is not supported <LinearRing> yes <LineString> yes <LineStyle> yes <Link> yes <linkDescription> no <linkName> no <linkSnippet> no <listItemType> N/A <ListStyle> is not supported <ListStyle> no <Location> N/A <Model> is not supported <Lod> yes <longitude> yes <LookAt> no <maxAltitude> yes <maxFadeExtent> yes <maxHeight> N/A <PhotoOverlay> is not supported <maxLodPixels> yes <maxSessionLength> no <maxWidth> N/A <PhotoOverlay> is not supported <message> no <Metadata> no deprecated <minAltitude> yes <minFadeExtent> yes <minLodPixels> yes <minRefreshPeriod> no <NetworkLink> <Model> no <MultiGeometry> partially rendered but displayed as separate features in left side panel <name> yes <near> N/A <PhotoOverlay> is not supported <NetworkLink> yes <NetworkLinkControl> partially <Update> and <expires> partially supported. The API ignores expiration settings in the HTTP headers but does use the expiration settings specified in KML. In the absence of expiration settings, or within the time validity interval, Google Maps may cache data fetched from the Internet for unspecified durations. A refetch of the data from the Internet can be forced by renaming the document and fetching it under a different URL, or by making sure that the document contains appropriate expiration settings. <north> yes <open> yes <Orientation> N/A <Model> is not supported <outerBoundaryIs> yes implicitly from <LinearRing> order <outline> yes <overlayXY> no <Pair> N/A <StyleMap> is not supported <phoneNumber> no <PhotoOverlay> no <Placemark> yes <Point> yes <Polygon> yes <PolyStyle> yes <range> yes <refreshInterval> partially <Link> only; not in <Icon> <refreshMode> yes HTTP headers not supported for "onExpire" mode. See notes on <Update> and <expires> above. <refreshVisibility> no <Region> yes <ResourceMap> N/A <Model> is not supported <rightFov> N/A <PhotoOverlay> is not supported <roll> N/A <Camera> and <Model> are not supported <rotation> no <rotationXY> no <Scale> N/A <Model> is not supported <scale> no <Schema> no <SchemaData> no <ScreenOverlay> yes cannot be rotated <screenXY> no <shape> N/A <PhotoOverlay> is not supported <SimpleData> N/A <SchemaData> are not supported <SimpleField> N/A <Schema> are not supported <size> yes <Snippet> yes <south> yes <state> N/A <ListStyle> is not supported <Style> yes <StyleMap> no rollover (highlight) effects are not supported <styleUrl> N/A <StyleMap> is not supported <targetHref> partially supported in <Update>, not in <Alias> <tessellate> no <text> yes replacement of $[geDirections]
is not supported <textColor> no <tileSize> N/A <PhotoOverlay> is not supported <tilt> no <TimeSpan> no <TimeStamp> no <topFov> N/A <PhotoOverlay> is not supported <Update> partially only style changes, not <Create> or <Delete> <Url> yes deprecated <value> yes <viewBoundScale> no <viewFormat> no <viewRefreshMode> partially "onStop" is supported <viewRefreshTime> yes <ViewVolume> N/A <PhotoOverlay> is not supported <visibility> partially yes on <Folder> - child placemarks inherit their visibility <w> yes deprecated <west> yes <when> N/A <TimeStamp> is not supported <width> yes <x> yes deprecated <y> yes deprecated
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-08-14 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-14 UTC."],[[["The `KmlLayer` renders publicly accessible KML and GeoRSS data as tile overlays on a map, handling feature clicks and displaying information windows."],["It has limitations on file size (3MB raw or compressed, 10MB uncompressed KML), image size (500KB per KMZ file), network links (10), and features (1,000 document-wide)."],["Feature data like author, description, and ID can be accessed through `KmlMouseEvent` when a feature is clicked, enabling custom interactions."],["For private KML files, bypassing limitations, or needing more control over data, using data layers is recommended."],["Performance can be improved by optimizing KML files for caching and using supported elements effectively."]]],["The `KmlLayer` in the Maps JavaScript API displays KML and GeoRSS data fetched via URL. Data is rendered as tile overlays, converting elements like `\u003cPlacemark\u003e` to markers and `\u003cPolygon\u003e` to polygons, and can be removed using `setMap(null)`. KML files must be publicly accessible. `KmlLayerOptions` allow map assignment, viewport preservation, and disabling info windows. The `metadata` property provides details asynchronously. KML file sizes and network links have restrictions. Caching is used, and the `\u003cexpires\u003e` tag sets expiration. The API supports various KML elements, partially supports others, and ignores the rest.\n"]]
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4