Skip to main content

DataLayer

The DataLayer object displays GeoJson data, polygons, lines and points on the map. It wraps the Google maps data layer.

DataLayer extends Layer.

There are two kinds of data layer.

  • The map's own data layer. Every map has one and it's available as map.data.
  • A separate layer that you create with G.dataLayer(). Use this when you want a layer that only holds your own data.

They're the same object and support the same methods. The only difference is where the underlying Google object comes from.

Example usage

// The map's own data layer
map.data.setStyle({ fillColor: '#4caf50', fillOpacity: 0.4 });
map.loadGeoJson('/parcels.json');

// A separate layer
const parcels = G.dataLayer({
geoJson: '/parcels.json',
style: { fillColor: '#4caf50' },
});
parcels.setMap(map);

Creating the DataLayer object

G.dataLayer(options?: DataLayerValue): DataLayer

There are a few ways that you can set up the DataLayer object.

No parameters.

G.dataLayer(): DataLayer

const layer = G.dataLayer();

Pass the data layer options.

G.dataLayer(options: DataLayerOptions): DataLayer

ParameterTypeRequiredDescription
optionsDataLayerOptionsYesThe options.
const layer = G.dataLayer({
map: map,
geoJson: '/parcels.json',
style: { fillColor: '#4caf50' },
});

Pass an existing DataLayer object.

G.dataLayer(object: DataLayer): DataLayer

In this case the DataLayer object is simply returned.

ParameterTypeRequiredDescription
objectDataLayerYesA DataLayer object.
const layer = G.dataLayer(layerObject);

You don't have to wait for the map

A separate data layer only needs the Google maps library to be loaded, not a map. Because of that you can create a layer and load data into it before there's a map to show it on, and then attach the whole thing to the map later.

// This can run before the map exists
const layer = G.dataLayer();
layer.loadGeoJson('/parcels.json');

// The features are already in the layer by the time it's attached
layer.setMap(map);

Every call is run in the order that you made it, however long the map takes to be ready. So this always applies the style after the data has loaded, even though neither call waited for the other.

layer.loadGeoJson('/parcels.json');
layer.setStyle({ fillColor: '#4caf50' });

Data layer value type

Any methods that accept a data layer value accept DataLayerValue as the value type.

The DataLayerValue can be one of the following values:

Data layer options

Type DataLayerOptions

OptionTypeDefaultDescription
fitBoundsbooleanfalseWhether to fit the map to the bounds of the data once it's loaded.
geoJsonstring|string[]|objectGeoJson to load into the layer. This can be a url, an array of urls, or a GeoJson object.
idPropertystringThe name of the GeoJson property to use as the feature id.
mapMapThe map to add the data layer to.
styleDataStyleValueThe style to apply to the features in the layer.
visiblebooleantrueWhether the layer is visible on the map.

Load options

Type LoadOptions

The options for loadGeoJson and addGeoJson.

OptionTypeDefaultDescription
fitBoundsbooleanfalseWhether to fit the map to the bounds of the data once it's loaded. This overrides the layer option of the same name.
idPropertystringThe name of the GeoJson property to use as the feature id. This overrides the layer option of the same name.
replacebooleanfalseWhether to remove the existing features before loading the new ones. See the warning on clear() as this has the same effect.

Feature options

Type FeatureOptions

The options for addPolygon, addPolyline and addPoint.

OptionTypeDefaultDescription
idstring|numberThe id to give the feature.
propertiesFeaturePropertiesThe GeoJson properties to attach to the feature.
styleDataStyleOptionsThe style to set on this one feature, overriding the layer style.

Data style options

Type DataStyleOptions

These use this library's option names, which match the Polyline options, rather than the Google maps names.

OptionTypeDefaultDescription
clickablebooleantrueWhether the feature handles mouse events.
cursorstringThe CSS cursor to show when hovering over the feature.
draggablebooleanfalseWhether the feature can be dragged.
editablebooleanfalseWhether the feature's geometry can be edited.
fillColorstringThe fill color for polygons. All CSS3 colors are supported except for extended named colors.
fillOpacitynumberThe fill opacity for polygons. The value should be between 0 and 1.0.
iconIcon|SvgSymbol|string|google.maps.Icon|google.maps.SymbolThe icon to use for point geometry. This can be an Icon object, a SvgSymbol object, or a url. A Google maps icon or symbol object is passed through as it is.
strokeColorstringThe stroke color. All CSS3 colors are supported except for extended named colors.
strokeOpacitynumberThe stroke opacity. The value should be between 0 and 1.0.
strokeWeightnumberThe stroke width in pixels.
titlestringThe hover text for point geometry.
visiblebooleantrueWhether the feature is visible.
zIndexnumberThe zIndex compared to other features.

Data style value type

Any methods that accept a style value accept DataStyleValue as the value type.

The DataStyleValue can be one of the following values:

// One style for everything
layer.setStyle({ fillColor: '#4caf50' });

// A style for each feature
layer.setStyle((feature) => ({
fillColor: feature.getProperty('type') === 'park' ? '#4caf50' : '#2196f3',
}));

Tooltip callback type

Type DataTooltipCallback

The data layer version of TooltipCallback. It's passed a DataFeature rather than the layer.

(feature: DataFeature) => TooltipValue

layer.attachTooltip((feature) => feature.getProperty('name'));

Tooltip value type

Type DataTooltipValue

Any method that attaches a tooltip accepts DataTooltipValue. It takes the same shapes as DataPopupValue: a string with {property} placeholders, an HTMLElement or Text node, a TooltipOptions object, a Tooltip object, or a DataTooltipCallback function.

Type DataPopupCallback

This is the data layer version of PopupCallback. The only difference is what it's passed: a DataFeature rather than the layer, because one data layer holds many features.

(feature: DataFeature) => PopupValue

Like the core callback it can return any PopupValue.

// The content for the feature
layer.attachPopup((feature) => `<h3>${feature.getProperty('name')}</h3>`);

// Options, when more than the content changes
layer.attachPopup((feature) => ({
className: feature.getProperty('type'),
content: feature.getProperty('name'),
}));

// A different popup for the feature
layer.attachPopup((feature) => popups[feature.id]);

Type DataPopupValue

Any method that attaches a popup accepts DataPopupValue. It can be one of the following.

  • A string. Any {property} placeholders in it are replaced with the properties of the feature the popup is being shown for. A property the feature doesn't have becomes an empty string.
  • An HTMLElement or Text node
  • A PopupOptions object, whose content can hold placeholders
  • A Popup object
  • A DataPopupCallback function
note

The {property} placeholders are only replaced in content that you set up front. A value returned by a callback is used as it is, because the callback already has the feature and can build whatever it needs.

Events

Below are the available data layer events.

You can use the plain text name for the event, or you can use the event constant.

The event object holds the DataFeature that the event happened on in its feature value.

EventDescription
addfeatureA feature was added to the layer.
clickA feature was clicked.
contextmenuThe DOM contextmenu event was fired on a feature.
dblclickA feature was double clicked.
loadGeoJson data has finished loading. Dispatched by loadGeoJson() and addGeoJson().
mousedownThe DOM mousedown event was fired on a feature.
mouseoutThe mouse left a feature.
mouseoverThe mouse moved over a feature.
mouseupThe DOM mouseup event was fired on a feature.
readyThe data layer is loaded and ready for use.
removefeatureA feature was removed from the layer.
removepropertyA property was removed from a feature.
rightclickA feature was right clicked.
setgeometryThe geometry of a feature was changed.
setpropertyA property was set on a feature.

click

layer.on('click', (event) => {
console.log(event.feature.getProperty('name'));
});

// You can use the event constant
layer.on(G.DataLayerEvents.CLICK, (event) => {
// Do something
});

// Or, use the onClick method
layer.onClick((event) => {
// Do something
});

Data layer event object

Type DataLayerEventObject

The callback function for a data layer event has one parameter and that's the event object. It's the standard event object with the feature that the event happened on.

PropertyTypeDescription
domEventMouseEvent|TouchEvent|PointerEvent|KeyboardEvent|EventThe corresponding native DOM event. Only set for mouse events like click and mouseover.
featureDataFeatureThe feature that the event happened on. Not set for the load and ready events.
latLngLatLngThe latitude/longitude that was below the cursor. Only set for mouse events.
stopFunctionCall this function to stop the event from propagating further. Only set for mouse events.
typestringThe event type.

The callback function type is DataLayerEventCallback.

(event: DataLayerEventObject) => void

Properties

  • Properties inherited from Layer.
PropertyTypeDescription
mapMap|nullThe map that the layer is attached to. Setting it is the same as calling setMap().
styleDataStyleValueThe style applied to the features in the layer.
visiblebooleanWhether the layer is visible on the map.

Methods

  • Methods inherited from Layer.
  • Methods inherited from Evented.
  • Methods inherited from Base.

Methods that change the layer return the DataLayer object so that they can be chained. They're applied as soon as the layer is ready, so you don't have to wait for them.

Methods that give you something back return a promise.

addGeoJson

addGeoJson(geoJson: object, options?: LoadOptions): Promise<DataFeature[]>

Add a GeoJson object to the layer. Resolves with the features that were added.

ParameterTypeRequiredDescription
geoJsonobjectYesThe GeoJson object to add.
optionsLoadOptionsNoThe options for adding the data.
const features = await layer.addGeoJson(geoJson);

addPoint

addPoint(position: LatLngValue, options?: FeatureOptions): Promise<DataFeature>

Add a single point to the layer. The promise is rejected if the position isn't valid.

ParameterTypeRequiredDescription
positionLatLngValueYesThe position for the point.
optionsFeatureOptionsNoThe options for the feature.
layer.addPoint({ lat: 48.8, lng: 2.3 }, { properties: { name: 'Paris' } });

addPolygon

addPolygon(paths: LatLngValue[]|LatLngValue[][], options?: FeatureOptions): Promise<DataFeature>

Add a polygon to the layer.

The paths value is either a single array of positions, for a polygon without any holes in it, or an array of arrays of positions. When it's an array of arrays the first one is the outer edge of the polygon and each one after that is a hole within it.

A path doesn't need to repeat its first position at the end to close it. If it does, as GeoJson data does, then the repeated position is dropped for you.

The promise is rejected if the first path has fewer than three valid positions.

ParameterTypeRequiredDescription
pathsLatLngValue[]|LatLngValue[][]YesThe path for the polygon, or an array of paths.
optionsFeatureOptionsNoThe options for the feature.

A polygon without any holes.

layer.addPolygon([
{ lat: -32.364, lng: 153.207 },
{ lat: -35.364, lng: 153.207 },
{ lat: -35.364, lng: 158.207 },
{ lat: -32.364, lng: 158.207 },
]);

A polygon with two holes in it. See Polygons with holes for more information.

layer.addPolygon([outerPath, holePath1, holePath2]);

addPolyline

addPolyline(path: LatLngValue[], options?: FeatureOptions): Promise<DataFeature>

Add a line to the layer. The promise is rejected if the path has fewer than two valid positions.

ParameterTypeRequiredDescription
pathLatLngValue[]YesThe path for the line.
optionsFeatureOptionsNoThe options for the feature.
layer.addPolyline([
{ lat: 48.1, lng: 2 },
{ lat: 48.4, lng: 2.1 },
{ lat: 48.6, lng: 1.8 },
]);

attachPopup

attachPopup(popupValue: DataPopupValue, event?: 'click' | 'clickon' | 'hover'): Popup

Attach a popup to every feature in the layer, including features loaded after this is called.

The content is worked out for each feature, so one popup covers the whole layer. See Popups on data layer features for the full picture.

A popup attached to a single feature with DataFeature.attachPopup() takes precedence over this one.

ParameterTypeRequiredDescription
popupValueDataPopupValueYesThe content for the popup, the popup options, or a Popup object.
eventstringThe event that shows the popup. One of click, clickon or hover. Defaults to click.
layer.attachPopup('<h3>{name}</h3><p>{address}</p>');

Build the content with a function.

layer.attachPopup((feature) => `<h3>${feature.getProperty('name')}</h3>`);

Show it on hover instead of a click.

layer.attachPopup('<h3>{name}</h3>', 'hover');

The popup opens at the point on the feature that was clicked, and the map is panned so that the popup is fully in view. A hover popup doesn't pan the map, because moving the map would take the feature out from under the cursor.

attachTooltip

attachTooltip(tooltipValue: DataTooltipValue, event?: 'click' | 'clickon' | 'hover'): Tooltip

Attach a tooltip to every feature in the layer, including features loaded after this is called. It shows on hover by default.

This works exactly like attachPopup() — the content can hold {property} placeholders or be a function — so see Popups on data layer features for the detail, and Tooltips on data layer features for what differs.

A tooltip attached to a single feature with DataFeature.attachTooltip() takes precedence over this one.

ParameterTypeRequiredDescription
tooltipValueDataTooltipValueYesThe content for the tooltip, the tooltip options, or a Tooltip object.
eventstringThe event that shows the tooltip. One of click, clickon or hover. Defaults to hover.
layer.attachTooltip('{name}');

A layer can have both a tooltip and a popup attached at the same time.

layer.attachTooltip('{name}');
layer.attachPopup('<h3>{name}</h3><p>{address}</p>');

clear

clear(): DataLayer

Remove every feature from the layer. The Google maps API doesn't have a way to do this so each feature is removed in turn.

warning

Take care when calling this on the map's own data layer (map.data). Google gives each map one shared data layer, so this removes every feature on it, including any that another part of your application added.

If you need a layer that only holds your own data, and that you can clear without affecting anything else, create one with G.dataLayer().

The same applies to the replace load option, which clears the layer before loading.

layer.clear();

contains

contains(feature: DataFeature): Promise<boolean>

Returns whether the feature is in this layer.

ParameterTypeRequiredDescription
featureDataFeatureYesThe feature to test for.
if (await layer.contains(feature)) {
// Do something
}

fitBounds

fitBounds(): Promise<DataLayer>

Fit the map to the bounds of the data in the layer.

Nothing happens if the layer has no features, or if it isn't attached to a map.

await layer.loadGeoJson('/parcels.json');
layer.fitBounds();

You can also do this as part of loading the data.

layer.loadGeoJson('/parcels.json', { fitBounds: true });

forEach

forEach(callback: (feature: DataFeature) => void): Promise<DataLayer>

Call the callback function for each feature in the layer.

ParameterTypeRequiredDescription
callbackFunctionYesThe function to call for each feature. It's passed the DataFeature object.
layer.forEach((feature) => {
console.log(feature.getProperty('name'));
});

getBounds

getBounds(): Promise<LatLngBounds>

Get the bounds of all of the features in the layer.

const bounds = await layer.getBounds();

getFeature

getFeature(id: string|number): Promise<DataFeature|undefined>

Get a feature by its id. Resolves with undefined if no feature has that id.

The id comes from the GeoJson data, the idProperty option, or the id feature option.

ParameterTypeRequiredDescription
idstring|numberYesThe feature id.
const feature = await layer.getFeature('parcel-12');

getFeatures

getFeatures(): Promise<DataFeature[]>

Get every feature in the layer as an array.

The Google maps API only provides forEach(), so this collects the features for you. Because it's an array you have all of the array methods available, so there's no separate filter method.

const features = await layer.getFeatures();

const parks = features.filter((feature) => feature.getProperty('type') === 'park');

hide

hide(): DataLayer

Hide the layer on the map. The features stay in the layer, so use show() to display them again.

layer.hide();

loadGeoJson

loadGeoJson(url: string|string[], options?: LoadOptions): Promise<DataFeature[]>

Load GeoJson data into the layer from a url. Resolves with the features that were loaded.

More than one url can be passed. The promise then resolves once every file has loaded, with all of the features from all of the files.

The promise is rejected if no url is passed.

ParameterTypeRequiredDescription
urlstring|string[]YesThe url to load the GeoJson from, or an array of urls.
optionsLoadOptionsNoThe options for loading the data.
const features = await layer.loadGeoJson('/parcels.json');

Load more than one file into the same layer.

const features = await layer.loadGeoJson(['/parcels.json', '/zoning.json']);

Replace what's already in the layer, and fit the map to the new data.

layer.loadGeoJson('/parcels.json', { replace: true, fitBounds: true });

onAddFeature

onAddFeature(callback: DataLayerEventCallback): void

Add an event listener for when a feature is added to the layer.

layer.onAddFeature((event) => {
console.log(event.feature.id);
});

onClick

onClick(callback: DataLayerEventCallback): void

Add an event listener for when a feature is clicked.

layer.onClick((event) => {
console.log(event.feature.getProperty('name'), event.latLng);
});

onDblClick

onDblClick(callback: DataLayerEventCallback): void

Add an event listener for when a feature is double clicked.

onLoad

onLoad(callback: DataLayerEventCallback): void

Add an event listener for when GeoJson data has finished loading. This is dispatched by loadGeoJson and addGeoJson.

layer.onLoad(() => {
// Do something
});

onMouseOut

onMouseOut(callback: DataLayerEventCallback): void

Add an event listener for when the mouse leaves a feature.

onMouseOver

onMouseOver(callback: DataLayerEventCallback): void

Add an event listener for when the mouse moves over a feature.

Together with onMouseOut this is how you set up a hover style.

layer.onMouseOver((event) => {
event.feature.setStyle({ fillOpacity: 1, strokeWeight: 3 });
});
layer.onMouseOut((event) => {
event.feature.resetStyle();
});

onRemoveFeature

onRemoveFeature(callback: DataLayerEventCallback): void

Add an event listener for when a feature is removed from the layer.

onRightClick

onRightClick(callback: DataLayerEventCallback): void

Add an event listener for when a feature is right clicked.

overrideStyle

overrideStyle(feature: DataFeatureValue, style: DataStyleOptions): DataLayer

Set the style for one feature, overriding the layer style. Use revertStyle to undo it.

DataFeature.setStyle() does the same thing from the feature itself.

ParameterTypeRequiredDescription
featureDataFeature|string|numberYesThe feature, or the feature id, to set the style on.
styleDataStyleOptionsYesThe style to set on the feature.
layer.overrideStyle(feature, { fillColor: '#ff0000' });

remove

remove(feature: DataFeatureValue): DataLayer

Remove a feature from the layer.

ParameterTypeRequiredDescription
featureDataFeature|string|numberYesThe feature, or the feature id, to remove.
layer.remove(feature);

// Or by id
layer.remove('parcel-12');

revertStyle

revertStyle(feature?: DataFeatureValue): DataLayer

Remove the style override for a feature so that it uses the layer style again.

If no feature is passed then the override is removed from every feature.

ParameterTypeRequiredDescription
featureDataFeature|string|numberNoThe feature, or the feature id, to revert the style for. If this is not set then every feature is reverted.
layer.revertStyle(feature);

// Revert everything
layer.revertStyle();

setMap

setMap(map: Map|null): Promise<DataLayer>

Add the data layer to the map.

ParameterTypeRequiredDescription
mapMapYesThe map object. Set to null to remove the layer from the map.
layer.setMap(map);

// Remove it from the map
layer.setMap(null);

setOptions

setOptions(options: DataLayerOptions): DataLayer

Set the options for the data layer.

ParameterTypeRequiredDescription
optionsDataLayerOptionsYesThe data layer options.
layer.setOptions({
map: map,
geoJson: '/parcels.json',
style: { fillColor: '#4caf50' },
});

setStyle

setStyle(style: DataStyleValue): DataLayer

Set the style to apply to the features in the layer.

The style is either a single style object that is applied to every feature, or a function that is called for each feature and returns the style for it.

note

This replaces the existing style rather than merging with it, which matches the Google maps API. Set every value that you need each time.

ParameterTypeRequiredDescription
styleDataStyleValueYesThe style to apply to the features in the layer.
layer.setStyle({ fillColor: '#4caf50', fillOpacity: 0.5, strokeWeight: 1 });

Style each feature based on one of its properties.

const colors = { park: '#4caf50', water: '#2196f3' };

layer.setStyle((feature) => ({
fillColor: colors[feature.getProperty('type')] || '#999999',
fillOpacity: 0.5,
}));

show

show(map?: Map): Promise<DataLayer>

Show the layer on the map. This will also set the map object if it's passed.

ParameterTypeRequiredDescription
mapMapNoThe map object to add the layer to.
layer.show();

// Set the map and show the layer
layer.show(map);

toGeoJson

toGeoJson(): Promise<object>

Export every feature in the layer as a GeoJson object.

const geoJson = await layer.toGeoJson();

toGoogle

toGoogle(): Promise<google.maps.Data>

Returns the Google maps Data object.

The Data object may not exist yet, so this returns a promise. It also waits for any calls that you've already made on the layer, so the object it resolves with has had all of them applied to it.

const data = await layer.toGoogle();