Introduction
The purpose of this guide is to cover the most common uses of the KmlLayer and provide corresponding migration paths to alternative implementations. This information is intended for developers who need to transition from using KmlLayer due to its scheduled deprecation. The last version which supports KmlLayer is 3.65, to be decommissioned in May 2027.
Your migration path depends on how you are using the KmlLayer:
- KML file to style boundary/border/area of interest information : Use Data-driven styling (DDS) for boundaries for administrative areas using Google's boundary data.
- KML file with vector data (Points/Polylines/Boundaries/Polygons): Use
DDS for datasets, GeoJSON, or 3rd-party libraries like
deck.glorgeoxml3. - KML file with interactive elements: Implement manual event listeners and custom info windows for feature interaction.
- KML file with imagery: Use GroundOverlays or 3rd-party parsers for imagery overlays.
- KML File with network Links: Upload each KML as a separate dataset, or merge KMLs. If displaying dynamic data, refresh the dataset using the Datasets API.
- Use KML to display Screen Overlays: Use Custom Controls to replace fixed UI elements like logos, legends, or navigation aids.
KML file to style boundary/border/area of interest information
For developers using KmlLayer to display or style administrative
boundaries—such as highlighting a specific country, state, or locality—Google
Maps Platform recommends migrating to Data-driven styling (DDS) for
boundaries.
Migration Recommendation: Data-driven Styling for Boundaries
Data-driven styling for boundaries provides direct access to Google's administrative boundary polygons, allowing you to apply custom styles (fill and stroke) to these regions without needing to host or manage external KML files.
Available FeatureType
Administrative areas are categorized by function and arranged by levels. The following feature types are supported for styling:
COUNTRY: The national political entity.ADMINISTRATIVE_AREA_LEVEL_1: A first-order civil entity below the country level (e.g., states in the US).ADMINISTRATIVE_AREA_LEVEL_2: A second-order civil entity below the country level (e.g., counties in the US).LOCALITY: An incorporated city or town.POSTAL_CODE: Postal codes as used for mail.SCHOOL_DISTRICT: Unified, elementary, or secondary school districts.
See boundary coverage for regions where these feature types are available.
How to Highlight an Area
To style a specific region, you must target it by its Place ID.
- Setup: You must use a Map ID configured for JavaScript Vector map type and enable the Feature layer available in the Google Cloud Console.
- Implementation: use the Style a boundary polygon sample code.
Restricting Panning to an Area
To prevent users from navigating outside the bounding box of your highlighted
area, you can use the restriction option within the MapOptions.
The restriction object defines a latLngBounds that limits the map's viewable
area. See the
documentation
for more details on how the restriction works.
// Restrict panning to a specific bounding box
restriction: {
latLngBounds: {
north: 47.8,
south: 45.8,
east: 10.5,
west: 5.9,
},
strictBounds: true,
},
Summary Migration Implementation
Here is a complete example of how to use Data-driven styling for boundaries and a region restriction to focus the map around a specific area.
const myTargetRegion = "ChIJYW1Zb-9kjEcRFXvLDxG1Vlw"; // Place ID for Switzerland
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 46.8, lng: 8.2 },
zoom: 9,
mapId: "YOUR_MAP_ID", // Required for DDS
// Restrict panning to a specific bounding box
restriction: {
// Bounding box for Switzerland
latLngBounds: {
north: 47.8,
south: 45.8,
east: 10.5,
west: 5.9,
},
strictBounds: true,
},
});
// Access the Country layer and style a specific region by Place ID
const countryLayer = map.getFeatureLayer("COUNTRY");
countryLayer.style = (options) => {
if (options.feature.placeId === myTargetRegion) {
return {
fillColor: "#FF0000",
fillOpacity: 0.5,
strokeColor: "#FF0000",
strokeWeight: 2,
};
} else {
// Style everything else whited out, to make the area of interest pop out more.
return {
fillColor: '#ffffff',
fillOpacity: 0.8,
};
}
};
}
KML file with vector data (Points/Polylines/Boundaries/Polygons)
Migration Recommendation: Data-driven Styling for Datasets
Google recommends the below path for displaying publicly available geographic data while gaining more control over styling and performance.
Data-driven styling for datasets lets you upload your own geospatial data (KML, GeoJSON, or CSV), apply custom styling based on data attributes, and display features on vector maps.
1. Setup and Upload
Unlike KmlLayer, which fetches a URL at runtime, DDS requires you to host the
data as a dataset in the Google Cloud Console.
- Create a Map ID: Use a Map ID configured for the Vector map type.
- Upload the Dataset: Upload your KML file to the Google Cloud Console to generate a unique Dataset ID. Read the full documentation on how to manage Maps Datasets for more details.
- Display the Dataset: Once you have created a Dataset ID, you need to associate the Dataset with a Maps Style and a Map ID. You will then use the Dataset ID to actually display the data on the map. Read the full documentation on how to Add a dataset to a map for all the details.
- Note the KML requirements for Datasets, if you decide to import your data from the KML format.
2. Setting the Viewport to the Data
KmlLayer automatically pans and zooms to the data location by default. With
DDS for datasets, this behavior is not automatic and must be implemented
manually.
- Hardcoded Restrictions: If the data area is static, use the
restrictionoption inMapOptionsto lock the viewport to specific bounds. - Dynamic Zooming: To dynamically set the viewport, you can use
map.fitBounds()with the bounding box of your dataset.
3. Styling from Feature Attributes
KML files often contain style information (like colors) that DDS does not automatically apply. You must create a client-side style function that reads attributes from the dataset features to apply colors and opacity. Consult the developer documentation on how to style your data for the full details.
Example: Styling Function using Attributes
The following example demonstrates how to create a style function that reads
background_color and opacity attributes directly from the uploaded dataset:
/**
* Migration example: Styling features from dataset attributes.
*/
function styleDDSLayer(map, datasetId) {
const datasetLayer = map.getDatasetFeatureLayer(datasetId);
// Set the style function
datasetLayer.style = (params) => {
// Access attributes defined in your KML/Dataset
const featureAttributes = params.feature.datasetAttributes;
// Read style values from attributes, with fallback defaults
const fillColor = featureAttributes['background_color'] || '#4285F4';
const fillOpacity = parseFloat(featureAttributes['opacity']) || 0.5;
const strokeColor = featureAttributes['border_color'] || '#34A853';
return {
fillColor: fillColor,
fillOpacity: fillOpacity,
strokeColor: strokeColor,
strokeWeight: 2,
};
};
}
For further details on implementing interactions and styling, refer to the Data-driven styling for datasets overview and Datasets API for dynamic data.
Migration Recommendation: Client-Side Rendering with GeoJSON
For developers migrating from KmlLayer
to client-side rendering with GeoJSON,
Google Maps Platform recommends a migration path that involves converting your
data format and using the Data layer
to render and style features directly in the browser.
Client-side rendering using the Data layer provides a highly flexible way to
display geographic data. Unlike KmlLayer,
which is rendered on Google's
servers, the Data layer lets you interact with features as standard
JavaScript objects. Note, however, that for large datasets you might prefer
server-side processing and rendering of your data, such as with Data-driven
Styling for Datasets.
1. Convert KML to GeoJSON
The first step is to convert your KML files into GeoJSON. This can be done using several popular open-source tools:
- ogr2ogr: Part of the GDAL suite, this powerful command-line utility can convert between many vector formats.
ogr2ogr -f GeoJSON output.json input.kml
- togeojson: A tiny, well-tested tool designed specifically for converting KML and GPX to GeoJSON.
togeojson input.kml > output.json
2. Setting the Viewport to the Data
While KmlLayer automatically pans and zooms to the data location, the Data
layer does not. To set the viewport to fit your GeoJSON data, you must manually
calculate the bounding box and call map.fitBounds().
3. Styling from Feature Attributes
In the Data layer, you can define a style function that reads attributes
(properties) directly from each GeoJSON feature to determine its appearance.
Example: Styling Function and Viewport Adjustment
The following example demonstrates how to load GeoJSON data, calculate its bounds to set the viewport, and style features based on their attributes:
/**
* Migration example: Loading GeoJSON, fitting viewport, and styling from attributes.
*/
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 4,
center: { lat: -28, lng: 137 },
});
// Load the GeoJSON data
map.data.loadGeoJson('path/to/your/data.json', null, (features) => {
// Adjust viewport to show all loaded features
const bounds = new google.maps.LatLngBounds();
features.forEach((feature) => {
feature.getGeometry().forEachLatLng((latlng) => {
bounds.extend(latlng);
});
});
map.fitBounds(bounds);
});
// Set the style function to read from GeoJSON properties
map.data.setStyle((feature) => {
// Access attributes defined in your GeoJSON properties
const fillColor = feature.getProperty('background_color') || '#4285F4';
const opacity = parseFloat(feature.getProperty('opacity')) || 0.5;
const strokeColor = feature.getProperty('border_color') || '#34A853';
return {
fillColor: fillColor,
fillOpacity: opacity,
strokeColor: strokeColor,
strokeWeight: 2,
visible: true
};
});
}
For more information on using the Data layer, see the Importing GeoJSON into Maps documentation.
Migration Path: Client-Side Rendering with 3rd party libraries
For developers seeking other alternatives to the KmlLayer, there are
several community-maintained libraries that render KML data on the Google Maps
Platform JavaScript API.
1. deck.gl
deck.gl is a high-performance WebGL-powered visualization framework. It can be
used as a near drop-in replacement for KML rendering through its
GoogleMapsOverlay and GeoJsonLayer.
- Canvas Requirement: To use
deck.gleffectively, you must convert your map to use the Vector map type (which renders to a canvas element) with its WebGL rendering capabilities. - KML Support: Geometry parsing is handled by
@loaders.gl/kml, which converts KML into GeoJSON. Note that some KML features like complex styles, icons, and NetworkLinks may require additional manual implementation. - Documentation: deck.gl Documentation | loaders.gl KML Loader.
- Examples:
- The deckgl-kml-updated sample on the Google Maps GitHub repository demonstrates how to use deck.gl to render KML data that is updated in real-time.
- The deckgl-kml sample demonstrates how to use deck.gl to render KML data.
2. geoxml3
geoxml3 is a KML processor specifically designed for the Google Maps
JavaScript API v3. It parses KML locally in the browser and renders the data as
standard Google Maps API objects like Markers, Polylines, and Polygons.
- Standard Map Support: Unlike WebGL-based solutions,
geoxml3works on standard Google Maps JS API v3 maps without requiring a specific rendering mode. - Caveats:
- Limited KMZ Support: The library does not fully support KMZ
files natively; unzipping KMZ archives typically requires integration
with additional 3rd party scripts like
ZipFile.complete.js. - Unsupported Elements: Features such as 3D geometries, complex labels, and certain newer KML elements are not supported.
- Limited KMZ Support: The library does not fully support KMZ
files natively; unzipping KMZ archives typically requires integration
with additional 3rd party scripts like
- Documentation: geoxml3 GitHub Repository.
KML file with interactive elements
Migration Recommendation: Data-driven Styling for Datasets
For developers migrating from KmlLayer to Data-driven styling (DDS) for
datasets, this guide explains how to transition from automatic KML
interactions to custom, high-performance interactions like mouse clicks and
hover.
Initial Setup
Before implementing interactions, ensure you have followed the setup steps from the KML Migration: Vector Data guide:
- Map ID: Configure a Map ID for the Vector map type.
- Upload: Upload your KML data to the Google Cloud Console to obtain a Dataset ID.
- Layer Access: Use
map.getDatasetFeatureLayer(datasetId)to access the interactive layer.
1. Handling Interaction Events
In KmlLayer, feature clicks are handled automatically by the API to pop up an
info window. With DDS for datasets, you must manually register listeners for
mouse events on the dataset layer.
click: Triggered when a user clicks on a feature.mousemove: Triggered when the cursor moves over a feature, useful for hover effects.
2. Dynamic Styling (Hover Effect)
Because DDS styles are applied globally to the layer, you should maintain a state variable to track which feature is being interacted with and re-apply the style.
let currentFeatureId = null;
function initInteraction(map, datasetId) {
const datasetLayer = map.getDatasetFeatureLayer(datasetId);
// Apply the style function
datasetLayer.style = (params) => {
const isHovered = params.feature.datasetAttributes['id'] === currentFeatureId;
return {
strokeColor: 'green',
strokeWeight: isHovered ? 4.0 : 2.0, // Bold border on hover
fillColor: 'green',
fillOpacity: isHovered ? 0.5 : 0.3,
};
};
// Add interaction listeners
datasetLayer.addListener('mousemove', (event) => {
if (event.features.length > 0) {
currentFeatureId = event.features[0].datasetAttributes['id'];
datasetLayer.style = datasetLayer.style; // Re-apply style to reflect changes
}
});
// Clear hover state when the mouse leaves the features
map.addListener('mousemove', () => {
if (currentFeatureId !== null) {
currentFeatureId = null;
datasetLayer.style = datasetLayer.style;
}
});
}
3. Displaying HTML from the description Attribute
In KML, the <description> tag often contains HTML for the default info window.
When this data is imported as a dataset, the description becomes a feature
attribute. To render it, pass the string directly to a standard
google.maps.InfoWindow.
const infoWindow = new google.maps.InfoWindow();
datasetLayer.addListener('click', (event) => {
if (event.features.length > 0) {
const feature = event.features[0];
// Access the HTML description attribute
const htmlContent = feature.datasetAttributes['description'];
infoWindow.setContent(htmlContent);
infoWindow.setPosition(event.latLng);
infoWindow.open(map);
}
});
4. Custom InfoWindow with ExtendedData
If your KML uses <ExtendedData> to store custom name/value pairs, these are
mapped to datasetAttributes. You can iterate through these attributes to build
a custom HTML display.
function createCustomContent(feature) {
const attributes = feature.datasetAttributes;
const container = document.createElement("div");
container.style.padding = "10px";
container.innerHTML = "<h3>Feature Details</h3><dl></dl>";
const dl = container.querySelector("dl");
// Iterate through all data attributes imported from KML ExtendedData
for (const key in attributes) {
const dt = document.createElement("dt");
dt.style.fontWeight = "bold";
dt.textContent = key;
const dd = document.createElement("dd");
dd.textContent = attributes[key];
dl.appendChild(dt);
dl.appendChild(dd);
}
return container;
}
datasetLayer.addListener('click', (event) => {
if (event.features.length > 0) {
const content = createCustomContent(event.features[0]);
infoWindow.setContent(content);
infoWindow.setPosition(event.latLng);
infoWindow.open(map);
}
});
For more advanced visualization techniques, see the developer documentation on how to style data features.
Migration Recommendation: Client-Side Rendering with GeoJSON
For developers migrating from KmlLayer to client-side rendering with GeoJSON
and the Data layer, this guide explains how to transition from automatic KML
interactions to custom, event-driven interactions and dynamic styling.
Initial Setup
Before implementing interactions, you must convert your KML data to GeoJSON and
load it into the Data layer. Refer to the Migration Recommendation:
Client-Side Rendering with GeoJSON guide for details on using tools like
ogr2ogr or togeojson and initializing the map with map.data.loadGeoJson().
1. Automatic versus Manual Interactions
A key difference between these layers is how they handle user input:
KmlLayer: Automatically handles feature clicks and displays anInfoWindowcontaining the KMLanddata.- Data Layer: Does not display
InfoWindowobjects automatically. You must manually add event listeners to capture user interactions and write code to display data.
2. Handling Interaction Events
To make GeoJSON features interactive, use the addListener() method on the
map.data object. Common events include:
click: Used to trigger info windows or selection logic.mouseover/mouseout: Used for hover effects and highlighting.
3. Displaying HTML Descriptions in an InfoWindow
When KML is converted to GeoJSON, the <description> tag (which often contains
HTML) is typically mapped to a property named description. You can use
feature.getProperty('description') to retrieve this string and render it
inside a standard google.maps.InfoWindow.
const infoWindow = new google.maps.InfoWindow();
// Handle clicks to show the HTML description
map.data.addListener('click', (event) => {
// Access the 'description' property from the GeoJSON feature
const htmlContent = event.feature.getProperty('description');
if (htmlContent) {
infoWindow.setContent(htmlContent);
infoWindow.setPosition(event.latLng);
infoWindow.open(map);
}
});
4. Custom InfoWindows and ExtendedData
If your original KML utilized <ExtendedData>, these name-value pairs are
converted into GeoJSON properties. Because the Data layer doesn't have a default
UI for these, you must implement a custom InfoWindow to iterate through and
display them.
You can access these attributes using
event.feature.getProperty('attribute_name') and construct a custom HTML string
or DOM element to pass to the infoWindow.setContent() method.
5. Dynamic Styling (Hover Effects)
The Data layer lets you update feature styles programmatically in response
to events. Use overrideStyle() to temporarily change a feature's appearance
(e.g., on hover) and revertStyle() to return to the global style.
// Set a base style for all features
map.data.setStyle({
fillColor: 'blue',
strokeWeight: 1
});
// Highlight feature on mouseover
map.data.addListener('mouseover', (event) => {
map.data.revertStyle(); // Clear previous highlights
map.data.overrideStyle(event.feature, {strokeWeight: 8});
});
// Revert style on mouseout
map.data.addListener('mouseout', (event) => {
map.data.revertStyle();
});
For more detailed implementation details, see the documentation on Data Layer: Event Handling and Data Layer: Dynamic Styling.
Migration Path: Client-Side Rendering with 3rd party libraries
For developers migrating from KmlLayer to third-party solutions, this guide
focuses on handling interactive data such as mouse clicks and dynamic events
using deck.gl and geoxml3.
Initial Setup
Before implementing interactions, ensure you have followed the setup steps from the Migration Path: Client-Side Rendering with 3rd party libraries guide. This includes:
- deck.gl: Converting your map to use the Vector map type (canvas requirement).
- geoxml3: Serving the library scripts from your own host and managing Cross-Origin Resource Sharing (CORS).
1. Interactive Data with deck.gl
deck.gl supports KML as a direct input format and automatically handles
feature interactions like clicks based on the data provided in the KML file.
- KMLLoader Handling: Using the
@loaders.gl/kmlmodule, geometry and properties are parsed into a format thatdeck.gluses to trigger interaction events natively. - Feature Clicks: When a feature is clicked,
deck.glcan capture the event and display associated metadata (like<name>or<description>). - Example: The deckgl-kml-updated sample demonstrates real-time KML rendering where hovering over earthquake markers displays detailed event information.
2. Interactive Data with geoxml3
geoxml3 parses the KML locally in the browser, extracts style information, and
generates standard Google Maps API objects that retain their interactivity.
- Native Style Extraction: The library grabs
<Style>and<StyleMap>elements from the KML to apply them to the generated Markers, Polylines, and Polygons. - Click Handlers: By default,
geoxml3provides click handlers for these objects. You can also define custom callback functions (createMarker,createOverlay) during parser instantiation to implement your own selection logic or sidebar updates. - Example: This example demonstrates how to use geoxml3 to render KML, with customization like circle markers with interaction, such as clicking on the markers to display earthquake information.
- Usage Pattern:
var myParser = new geoXML3.parser({
map: map,
processStyles: true, // Automatically handle KML styles
afterParse: function(doc) {
// Code to run after the KML is fully parsed
}
});
myParser.parse('interactive_data.kml');
KML file with imagery
For developers using KmlLayer to display imagery—such as maps with
satellite-derived data, weather patterns, or historical blueprints—this guide
outlines the migration paths to GroundOverlays or 3rd party parsers.
Migration Recommendation: Maps JavaScript API GroundOverlay
The recommended path for migrating imagery is to use the
google.maps.GroundOverlay class. This lets you place an image on the map
at specific geographic coordinates directly in your code.
1. Implementation
Instead of relying on a KML file to define the bounds, you specify the image URL
and a LatLngBounds object representing the rectangle on the map.
- Documentation: Ground Overlays Guide.
- Image Preparation: If your image is georeferenced but not in the correct
projection (EPSG:4326), you can use the open-source tool
gdalwarpto warp the image for use with the Maps JS API.
gdalwarp -t_srs EPSG:4326 image.jp2 image.jpg
Migration Path: Using 3rd Party Libraries
If your workflow requires you to keep your data in KML format, third-party
libraries like geoxml3 or
deck.gl can be used to render imagery overlays.
Disclaimer: These third-party solutions are not supported by Google. However, they have been tested and should work for most use cases.
1. geoxml3
geoxml3 is a good option for parsing simple GroundOverlay elements locally
in the browser and converting them into Google Maps API objects.
Example Usage:
const geoXmlParser = new geoXML3.parser({
map: map,
afterParse: function(doc) {
console.log("Parsing complete. Number of documents: " + doc.length);
const bounds = doc[0].gbounds;
if (bounds && !bounds.isEmpty()) {
map.fitBounds(bounds);
}
},
createOverlay: function(groundOverlayData) {
// Extract bounds and URL from parsed KML data
const imageUrl = groundOverlayData.icon.href;
const imageBounds = {
north: parseFloat(groundOverlayData.latLonBox.north),
south: parseFloat(groundOverlayData.latLonBox.south),
east: parseFloat(groundOverlayData.latLonBox.east),
west: parseFloat(groundOverlayData.latLonBox.west)
};
// Create the Google Maps GroundOverlay
const nativeOverlay = new google.maps.GroundOverlay(imageUrl, imageBounds);
nativeOverlay.setMap(map);
}
});
geoXmlParser.parse('your_file.kml');
2. deck.gl
While deck.gl's standard GeoJsonLayer handles vector data, it can also
support GroundOverlays through a manual implementation using the
BitmapLayer.
This approach involves leveraging KMLLoader to parse the file and then
explicitly defining a BitmapLayer with the image URL and coordinates extracted
from the KML data.
- Requirement: Using
deck.glrequires a Vector map type. - Documentation: deck.gl Bitmap Layer
Advanced Case: Tile Pyramids using gdal2tiles
For complex KML files containing imagery tile pyramids, migration is more difficult and requires extracting the imagery data.
- Tool:
gdal2tilescan extract data from a KMZ pyramid and produce standard Maps JavaScript API code to display the tiles. Note that the end result may require manual modification to be incorporated into an existing map.
gdal2tiles -z 10- -n -u https://yourhost.com/tiles/ -w google input.kmz
KML File with Network Links
Handling KML files with network links requires a shift from the automatic,
cloud-side fetching of KmlLayer to more explicit data management strategies.
Supported Solution: Data-driven Styling (DDS) for Datasets
Because Google Maps Platform datasets don't natively parse <NetworkLink>
elements, you must choose a migration strategy based on your data structure:
- Strategy A: Distinct Datasets (Best for User-Controlled Layers) Upload
each KML file that was previously a network link as its own individual
dataset in the Google Cloud Console. You can then use JavaScript to
dynamically load and display these layers when needed by calling
map.getDatasetFeatureLayer(datasetId)and adjusting its visibility or style. - Strategy B: Flattened KML File (Best for High-Performance Display) Combine all features from your various network-linked files into a single, comprehensive KML file before uploading it as a dataset. You can then use dynamic styling based on feature attributes to filter and display specific data subsets on the fly.
Updating Dynamic Data: To mimic the "auto-refresh" behavior of network links, use the Datasets API to programmatically upload a new version of your dataset whenever the source data changes.
Open-Source Solutions: deck.gl and geoxml3
Neither deck.gl nor geoxml3 provide robust support for parsing and
automatically fetching KML <NetworkLink> elements.
deck.gl
deck.gl utilizes the KMLLoader (built on togeojson), which explicitly
does not support NetworkLinks.
- Why it is not a good solution: The parser is designed to be a
synchronous, "fuss-free" converter that avoids making its own network
requests to ensure reliability and simplicity. If your application relies on
KML files that point to multiple other URLs,
deck.glwon't automatically resolve them.
geoxml3
While geoxml3 was developed to parse KML for the Maps JS API, its support for
network links is experimental and unmaintained.
- Why it is not a good solution: The functionality exists only in a specific "network_link" branch that is old and not well-tested. Using this for production data migration is discouraged, as it may fail to handle complex link structures or modern security requirements like CORS.
Summary Recommendation
For a reliable migration, developers should avoid third-party parsers for files with network links and instead rebuild the data-fetching logic using the Datasets API. This ensures your data is managed securely within the Google Maps Platform infrastructure rather than relying on unmaintained client-side parsers.
Use KML to display Screen Overlays
For developers migrating from KmlLayer to modern alternatives like Data-driven
styling (DDS), it is important to note that Screen Overlays are not supported
in Datasets. To achieve the same effect of displaying fixed images, logos, or
legends on top of the map, you must create
Custom Controls
using the Maps JavaScript API.
1. What to Look for in Your KML File
To build an equivalent Custom Control, examine the <ScreenOverlay> element in
your KML file for the following key attributes:
<Icon><href>: The URL of the image you want to display.<screenXY>: This defines where the overlay is positioned on the screen.x=0, y=1(fractions) corresponds to the Top Left.x=1, y=1corresponds to the Top Right.x=0, y=0corresponds to the Bottom Left.x=1, y=0corresponds to the Bottom Right.
<size>: Defines the width and height of the overlay.<rotation>: Indicates if the image should be rotated.
2. Implementation: Creating a Custom Control
A Custom Control is essentially a standard HTML element (like a <div> or
<img>) that you "push" into one of the map's predefined positions.
Mapping KML Positions to ControlPosition
The Maps JavaScript API uses the ControlPosition enum to anchor controls. Use
the table below to map your KML <screenXY> to the appropriate JS API constant:
KML Position (screenXY)
|
JS API ControlPosition
|
Top Left (x:0, y:1)
|
TOP_LEFT (Legacy) or BLOCK_START_INLINE_START (Logical)
|
Top Right (x:1, y:1)
|
TOP_RIGHT or BLOCK_START_INLINE_END
|
Bottom Left (x:0, y:0)
|
BOTTOM_LEFT or BLOCK_END_INLINE_START
|
Bottom Right (x:1, y:0)
|
BOTTOM_RIGHT or BLOCK_END_INLINE_END
|
3. Migration Example: Fixed Logo Overlay
The following example mimics a KML ScreenOverlay logo positioned in the Top Right of the map.
CSS Styling
Use CSS to define the size and appearance of your "overlay".
#logo-control {
padding: 10px;
background-color: rgba(255, 255, 255, 0.8);
margin: 10px;
border-radius: 2px;
box-shadow: 0 1px 4px rgba(0,0,0,0.3);
}
#logo-control img {
width: 150px; /* Equivalent to KML <size> */
display: block;
}
JavaScript Implementation
Add the element to the map.controls array.
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 12,
center: { lat: 41.85, lng: -87.65 },
});
// 1. Create the container for the overlay
const logoControlDiv = document.createElement("div");
logoControlDiv.id = "logo-control";
// 2. Create the image (KML <Icon>)
const logoImage = document.createElement("img");
logoImage.src = "https://example.com/logo.png";
logoImage.alt = "Company Logo";
logoControlDiv.appendChild(logoImage);
// 3. Position the control (KML <screenXY>)
// In this case, we use TOP_RIGHT
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(logoControlDiv);
}