mirror of
https://github.com/grafana/grafana.git
synced 2026-01-15 05:35:41 +00:00
Compare commits
1 Commits
sriram/SQL
...
drew08t/ge
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5dbed75cbc |
@@ -473,6 +473,10 @@ A map from a collaborative free geographic world database.
|
||||
- **Opacity** from 0 (transparent) to 1 (opaque)
|
||||
- **Display tooltip** - allows you to toggle tooltips for the layer.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
OpenStreetMap requires attribution by license. When you use this layer, attribution automatically displays in the map controls and cannot be hidden.
|
||||
{{< /admonition >}}
|
||||
|
||||
[About Open Street Map](https://www.openstreetmap.org/about)
|
||||
|
||||
#### CARTO basemap layer
|
||||
@@ -489,6 +493,10 @@ A CARTO layer is from CARTO Raster basemaps.
|
||||
- **Opacity** from 0 (transparent) to 1 (opaque)
|
||||
- **Display tooltip** - allows you to toggle tooltips for the layer.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
CARTO requires attribution by license. When you use this layer, attribution automatically displays in the map controls and cannot be hidden.
|
||||
{{< /admonition >}}
|
||||
|
||||
[About CARTO](https://carto.com/about-us/)
|
||||
|
||||
#### ArcGIS MapServer layer
|
||||
@@ -654,6 +662,10 @@ Enables the mouse wheel to be used for zooming in or out.
|
||||
|
||||
Displays attribution for basemap layers.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Attribution is required by license for certain map layers, including OpenStreetMap and CARTO. When you use these layers, their attribution automatically displays and cannot be hidden. The toggle becomes **Show optional attribution** and controls whether attribution from other layers is also displayed.
|
||||
{{< /admonition >}}
|
||||
|
||||
{{< figure src="/static/img/docs/geomap-panel/geomap-map-controls-attribution-9-1-0.png" max-width="400px" alt="Geomap panel attribution" >}}
|
||||
|
||||
#### Show scale
|
||||
|
||||
@@ -67,6 +67,12 @@ export interface MapLayerRegistryItem<TConfig = MapLayerOptions> extends Registr
|
||||
*/
|
||||
hideOpacity?: boolean;
|
||||
|
||||
/**
|
||||
* Indicates that this layer requires attribution to be shown by license
|
||||
* When true, the attribution control will always be displayed regardless of user settings
|
||||
*/
|
||||
requiresAttribution?: boolean;
|
||||
|
||||
/**
|
||||
* Function that configures transformation and returns a transformer
|
||||
* @param options
|
||||
|
||||
@@ -9,6 +9,7 @@ import Zoom from 'ol/control/Zoom';
|
||||
import { Coordinate } from 'ol/coordinate';
|
||||
import { isEmpty } from 'ol/extent';
|
||||
import MouseWheelZoom from 'ol/interaction/MouseWheelZoom';
|
||||
import TileLayer from 'ol/layer/Tile';
|
||||
import { fromLonLat, transformExtent } from 'ol/proj';
|
||||
import { Component, ReactNode } from 'react';
|
||||
import * as React from 'react';
|
||||
@@ -30,7 +31,7 @@ import { MeasureVectorLayer } from './components/MeasureVectorLayer';
|
||||
import { GeomapHoverPayload } from './event';
|
||||
import { getGlobalStyles } from './globalStyles';
|
||||
import { defaultMarkersConfig } from './layers/data/markersLayer';
|
||||
import { DEFAULT_BASEMAP_CONFIG } from './layers/registry';
|
||||
import { DEFAULT_BASEMAP_CONFIG, geomapLayerRegistry } from './layers/registry';
|
||||
import { ControlsOptions, Options, MapLayerState, MapViewConfig, TooltipMode } from './types';
|
||||
import { getActions } from './utils/actions';
|
||||
import { getLayersExtent } from './utils/getLayersExtent';
|
||||
@@ -396,7 +397,45 @@ export class GeomapPanel extends Component<Props, State> {
|
||||
|
||||
this.mouseWheelZoom?.setActive(Boolean(options.mouseWheelZoom));
|
||||
|
||||
if (options.showAttribution) {
|
||||
// Handle attribution visibility per layer based on required vs optional
|
||||
let hasAnyAttribution = false;
|
||||
|
||||
for (const layerState of this.layers) {
|
||||
const layerType = layerState.options.type;
|
||||
const layerRegistryItem = layerType ? geomapLayerRegistry.getIfExists(layerType) : null;
|
||||
const requiresAttribution = layerRegistryItem?.requiresAttribution === true;
|
||||
|
||||
// Check if this layer's source has attribution capability
|
||||
const layer = layerState.layer;
|
||||
if (layer instanceof TileLayer) {
|
||||
const source = layer.getSource();
|
||||
if (source && typeof source.getAttributions === 'function') {
|
||||
const currentAttributions = source.getAttributions();
|
||||
|
||||
// Store original attribution if not already stored
|
||||
if (!layerState.originalAttribution && currentAttributions) {
|
||||
layerState.originalAttribution = currentAttributions;
|
||||
}
|
||||
|
||||
// Show attribution if it's required OR if user has enabled optional attributions
|
||||
if (requiresAttribution || options.showAttribution) {
|
||||
// Restore original attribution if we had cleared it
|
||||
if (layerState.originalAttribution && typeof source.setAttributions === 'function') {
|
||||
source.setAttributions(layerState.originalAttribution);
|
||||
}
|
||||
hasAnyAttribution = true;
|
||||
} else {
|
||||
// Hide optional attribution by clearing it
|
||||
if (typeof source.setAttributions === 'function') {
|
||||
source.setAttributions(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add attribution control if there are any attributions to show
|
||||
if (hasAnyAttribution) {
|
||||
this.map.addControl(new Attribution({ collapsed: true, collapsible: true }));
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ export const carto: MapLayerRegistryItem<CartoConfig> = {
|
||||
name: 'CARTO basemap',
|
||||
description: 'Add layer CARTO Raster basemaps',
|
||||
isBaseMap: true,
|
||||
requiresAttribution: true,
|
||||
defaultOptions: defaultCartoConfig,
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,7 @@ export const standard: MapLayerRegistryItem = {
|
||||
name: 'Open Street Map',
|
||||
description: 'Add map from a collaborative free geographic world database',
|
||||
isBaseMap: true,
|
||||
requiresAttribution: true,
|
||||
|
||||
/**
|
||||
* Function that configures transformation and returns a transformer
|
||||
|
||||
@@ -26,6 +26,8 @@ export const defaultBaseLayer: MapLayerRegistryItem = {
|
||||
id: DEFAULT_BASEMAP_CONFIG.type,
|
||||
name: 'Default base layer',
|
||||
isBaseMap: true,
|
||||
// Default uses CARTO which requires attribution
|
||||
requiresAttribution: true,
|
||||
|
||||
create: (map: OpenLayersMap, options: MapLayerOptions, eventBus: EventBus, theme: GrafanaTheme2) => {
|
||||
const serverLayerType = config?.geomapDefaultBaseLayerConfig?.type;
|
||||
|
||||
@@ -7,6 +7,7 @@ import { GeomapPanel } from './GeomapPanel';
|
||||
import { LayersEditor } from './editor/LayersEditor';
|
||||
import { MapViewEditor } from './editor/MapViewEditor';
|
||||
import { getLayerEditor } from './editor/layerEditor';
|
||||
import { geomapLayerRegistry } from './layers/registry';
|
||||
import { mapPanelChangedHandler, mapMigrationHandler } from './migrations';
|
||||
import { defaultMapViewConfig, Options, TooltipMode, GeomapInstanceState } from './types';
|
||||
|
||||
@@ -105,6 +106,17 @@ export const plugin = new PanelPlugin<Options>(GeomapPanel)
|
||||
|
||||
// The controls section
|
||||
category = [t('geomap.category-map-controls', 'Map controls')];
|
||||
|
||||
// Check if any layer requires attribution
|
||||
const requiresAttribution = state?.layers?.some((layerState) => {
|
||||
const layerType = layerState.options.type;
|
||||
if (layerType) {
|
||||
const layerRegistryItem = geomapLayerRegistry.getIfExists(layerType);
|
||||
return layerRegistryItem?.requiresAttribution === true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
builder
|
||||
.addBooleanSwitch({
|
||||
category,
|
||||
@@ -123,11 +135,15 @@ export const plugin = new PanelPlugin<Options>(GeomapPanel)
|
||||
.addBooleanSwitch({
|
||||
category,
|
||||
path: 'controls.showAttribution',
|
||||
name: t('geomap.name-show-attribution', 'Show attribution'),
|
||||
description: t(
|
||||
'geomap.description-show-attribution',
|
||||
'Show the map source attribution info in the lower right'
|
||||
),
|
||||
name: requiresAttribution
|
||||
? t('geomap.name-show-optional-attribution', 'Show optional attribution')
|
||||
: t('geomap.name-show-attribution', 'Show attribution'),
|
||||
description: requiresAttribution
|
||||
? t(
|
||||
'geomap.description-show-optional-attribution',
|
||||
'Required attributions are always shown. Toggle this to also show attribution from other layers at your discretion.'
|
||||
)
|
||||
: t('geomap.description-show-attribution', 'Show the map source attribution info in the lower right'),
|
||||
defaultValue: true,
|
||||
})
|
||||
.addBooleanSwitch({
|
||||
|
||||
@@ -51,6 +51,7 @@ export interface MapLayerState<TConfig = unknown> extends LayerElement {
|
||||
onChange: (cfg: MapLayerOptions<TConfig>) => void;
|
||||
isBasemap?: boolean;
|
||||
mouseEvents: Subject<FeatureLike | undefined>;
|
||||
originalAttribution?: any; // Store original attribution to restore when showing optional attributions
|
||||
}
|
||||
|
||||
export {
|
||||
|
||||
Reference in New Issue
Block a user