Geomap: default basemap config cleanup (#37069)

This commit is contained in:
Ryan McKinley 2021-07-21 13:48:20 -07:00 committed by GitHub
parent f26f76df5a
commit e604e69d93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 91 additions and 92 deletions

View File

@ -1013,8 +1013,8 @@ default_timezone = browser
enabled = true enabled = true
[geomap] [geomap]
# Set the default base layer in GeoMaps plugin # Set the JSON configuration for the default basemap
default_baselayer = default_baselayer_config =
# Enable or disable loading other base map layers # Enable or disable loading other base map layers
disable_custom_baselayers = false enable_custom_baselayers = true

View File

@ -993,8 +993,14 @@
;enabled = true ;enabled = true
[geomap] [geomap]
# Set the default base layer in GeoMaps plugin # Set the JSON configuration for the default basemap
;default_baselayer = ;default_baselayer_config = `{
"type": "xyz",
"config": {
"attribution": "Open street map",
"url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
}
}`
# Enable or disable loading other base map layers # Enable or disable loading other base map layers
;disable_custom_baselayers = false ;enable_custom_baselayers = true

View File

@ -1677,21 +1677,21 @@ Set this to `false` to disable expressions and hide them in the Grafana UI. Defa
This section controls the defaults settings for Geomap Plugin. This section controls the defaults settings for Geomap Plugin.
### default_baselayer ### default_baselayer_config
The json config used to define the default base map. Four base map options to choose from are `carto`, `esriXYZTiles`, `xyzTiles`, `standard`. The json config used to define the default base map. Four base map options to choose from are `carto`, `esriXYZTiles`, `xyzTiles`, `standard`.
For example, to set cartoDB light as the default base layer: For example, to set cartoDB light as the default base layer:
```ini ```ini
geomap_default_baselayer = `{ default_baselayer_config = `{
"type": "carto", "type": "xyz",
"config": { "config": {
"theme": "light", "attribution": "Open street map",
"showLabels": true "url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
} }
}` }`
``` ```
### disable_custom_baselayers ### enable_custom_baselayers
Set this to `true` to disable loading other custom base maps and hide them in the Grafana UI. Default is `false`. Set this to `true` to disable loading other custom base maps and hide them in the Grafana UI. Default is `false`.

View File

@ -88,7 +88,7 @@ export class GrafanaBootConfig implements GrafanaConfig {
caching = { caching = {
enabled: false, enabled: false,
}; };
geomapDefaultBaseLayer?: MapLayerOptions; geomapDefaultBaseLayerConfig?: MapLayerOptions;
geomapDisableCustomBaseLayer?: boolean; geomapDisableCustomBaseLayer?: boolean;
constructor(options: GrafanaBootConfig) { constructor(options: GrafanaBootConfig) {

View File

@ -259,8 +259,13 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
"caching": map[string]bool{ "caching": map[string]bool{
"enabled": hs.Cfg.SectionWithEnvOverrides("caching").Key("enabled").MustBool(true), "enabled": hs.Cfg.SectionWithEnvOverrides("caching").Key("enabled").MustBool(true),
}, },
"geomapDefaultBaseLayer": hs.Cfg.DefaultBaseLayer, }
"geomapDisableCustomBaseLayer": hs.Cfg.DisableCustomBaseLayers,
if hs.Cfg.GeomapDefaultBaseLayerConfig != nil {
jsonObj["geomapDefaultBaseLayerConfig"] = hs.Cfg.GeomapDefaultBaseLayerConfig
}
if !hs.Cfg.GeomapEnableCustomBaseLayers {
jsonObj["geomapDisableCustomBaseLayer"] = true
} }
return jsonObj, nil return jsonObj, nil

View File

@ -402,9 +402,9 @@ type Cfg struct {
// Grafana.com URL // Grafana.com URL
GrafanaComURL string GrafanaComURL string
// Geomap plugin tile server // Geomap base layer config
DefaultBaseLayer map[string]interface{} GeomapDefaultBaseLayerConfig map[string]interface{}
DisableCustomBaseLayers bool GeomapEnableCustomBaseLayers bool
} }
// IsLiveConfigEnabled returns true if live should be able to save configs to SQL tables // IsLiveConfigEnabled returns true if live should be able to save configs to SQL tables
@ -972,16 +972,17 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
} }
geomapSection := iniFile.Section("geomap") geomapSection := iniFile.Section("geomap")
basemapJSON := valueAsString(geomapSection, "default_baselayer", "") basemapJSON := valueAsString(geomapSection, "default_baselayer_config", "")
cfg.DefaultBaseLayer = make(map[string]interface{})
if basemapJSON != "" { if basemapJSON != "" {
err = json.Unmarshal([]byte(basemapJSON), &cfg.DefaultBaseLayer) layer := make(map[string]interface{})
err = json.Unmarshal([]byte(basemapJSON), &layer)
if err != nil { if err != nil {
cfg.Logger.Error(fmt.Sprintf("Error parsing JSON string: %s", err)) cfg.Logger.Error("Error reading json from default_baselayer_config", "error", err)
cfg.DefaultBaseLayer = nil } else {
cfg.GeomapDefaultBaseLayerConfig = layer
} }
} }
cfg.DisableCustomBaseLayers = geomapSection.Key("disable_custom_baselayers").MustBool(false) cfg.GeomapEnableCustomBaseLayers = geomapSection.Key("enable_custom_baselayers").MustBool(true)
cfg.readDateFormats() cfg.readDateFormats()
cfg.readSentryConfig() cfg.readSentryConfig()

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { geomapLayerRegistry } from './layers/registry'; import { DEFAULT_BASEMAP_CONFIG, geomapLayerRegistry, defaultBaseLayer } from './layers/registry';
import { Map, View } from 'ol'; import { Map, View } from 'ol';
import Attribution from 'ol/control/Attribution'; import Attribution from 'ol/control/Attribution';
import Zoom from 'ol/control/Zoom'; import Zoom from 'ol/control/Zoom';
@ -12,7 +12,6 @@ import { PanelData, MapLayerHandler, MapLayerOptions, PanelProps, GrafanaTheme }
import { config } from '@grafana/runtime'; import { config } from '@grafana/runtime';
import { ControlsOptions, GeomapPanelOptions, MapViewConfig } from './types'; import { ControlsOptions, GeomapPanelOptions, MapViewConfig } from './types';
import { defaultGrafanaThemedMap } from './layers/basemaps';
import { centerPointRegistry, MapCenterID } from './view'; import { centerPointRegistry, MapCenterID } from './view';
import { fromLonLat } from 'ol/proj'; import { fromLonLat } from 'ol/proj';
import { Coordinate } from 'ol/coordinate'; import { Coordinate } from 'ol/coordinate';
@ -153,10 +152,11 @@ export class GeomapPanel extends Component<Props> {
if (!this.map) { if (!this.map) {
return; return;
} }
if (!cfg) {
cfg = { type: defaultGrafanaThemedMap.id }; if (!cfg?.type || config.geomapDisableCustomBaseLayer) {
cfg = DEFAULT_BASEMAP_CONFIG;
} }
const item = geomapLayerRegistry.getIfExists(cfg.type) ?? defaultGrafanaThemedMap; const item = geomapLayerRegistry.getIfExists(cfg.type) ?? defaultBaseLayer;
const layer = item.create(this.map, cfg, config.theme2).init(); const layer = item.create(this.map, cfg, config.theme2).init();
if (this.basemap) { if (this.basemap) {
this.map.removeLayer(this.basemap); this.map.removeLayer(this.basemap);

View File

@ -2,7 +2,7 @@ import React, { FC } from 'react';
import { StandardEditorProps, MapLayerOptions, MapLayerRegistryItem, PluginState } from '@grafana/data'; import { StandardEditorProps, MapLayerOptions, MapLayerRegistryItem, PluginState } from '@grafana/data';
import { GeomapPanelOptions } from '../types'; import { GeomapPanelOptions } from '../types';
import { LayerEditor } from './LayerEditor'; import { LayerEditor } from './LayerEditor';
import { hasAlphaPanels } from 'app/core/config'; import { config, hasAlphaPanels } from 'app/core/config';
function baseMapFilter(layer: MapLayerRegistryItem): boolean { function baseMapFilter(layer: MapLayerRegistryItem): boolean {
if (!layer.isBaseMap) { if (!layer.isBaseMap) {
@ -19,5 +19,9 @@ export const BaseLayerEditor: FC<StandardEditorProps<MapLayerOptions, any, Geoma
onChange, onChange,
context, context,
}) => { }) => {
if (config.geomapDisableCustomBaseLayer) {
return <div>The base layer is configured by the server admin.</div>;
}
return <LayerEditor options={value} data={context.data} onChange={onChange} filter={baseMapFilter} />; return <LayerEditor options={value} data={context.data} onChange={onChange} filter={baseMapFilter} />;
}; };

View File

@ -10,8 +10,7 @@ import {
FieldType, FieldType,
Field, Field,
} from '@grafana/data'; } from '@grafana/data';
import { geomapLayerRegistry } from '../layers/registry'; import { DEFAULT_BASEMAP_CONFIG, geomapLayerRegistry } from '../layers/registry';
import { defaultGrafanaThemedMap } from '../layers/basemaps';
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor'; import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
import { setOptionImmutably } from 'app/features/dashboard/components/PanelEditor/utils'; import { setOptionImmutably } from 'app/features/dashboard/components/PanelEditor/utils';
import { fillOptionsPaneItems } from 'app/features/dashboard/components/PanelEditor/getVizualizationOptions'; import { fillOptionsPaneItems } from 'app/features/dashboard/components/PanelEditor/getVizualizationOptions';
@ -29,7 +28,7 @@ export const LayerEditor: FC<LayerEditorProps> = ({ options, onChange, data, fil
return geomapLayerRegistry.selectOptions( return geomapLayerRegistry.selectOptions(
options?.type // the selected value options?.type // the selected value
? [options.type] // as an array ? [options.type] // as an array
: [defaultGrafanaThemedMap.id], : [DEFAULT_BASEMAP_CONFIG.type],
filter filter
); );
}, [options?.type, filter]); }, [options?.type, filter]);

View File

@ -1,30 +0,0 @@
import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2 } from '@grafana/data';
import Map from 'ol/Map';
import { carto } from './carto';
import { esriXYZTiles } from './esri';
import { xyzTiles } from './generic';
import { standard } from './osm';
import { config } from 'app/core/config';
// Array of base map options to search through
const baseLayers = [carto, esriXYZTiles, xyzTiles, standard];
// Default base layer depending on the server setting
export const defaultBaseLayer: MapLayerRegistryItem = {
id: 'default',
name: 'Default base layer',
isBaseMap: true,
create: (map: Map, options: MapLayerOptions, theme: GrafanaTheme2) => {
// Use Carto as the default base layer if not set from server
let layer: any = carto;
if (config.geomapDefaultBaseLayer && config.geomapDefaultBaseLayer.type) {
options = config.geomapDefaultBaseLayer; // options from server
layer = baseLayers.find((baseLayer) => baseLayer.id === options.type);
if (!layer) {
throw new Error('Invalid default base map type');
}
}
return layer.create(map, options, theme);
},
};

View File

@ -2,19 +2,11 @@ import { cartoLayers } from './carto';
import { esriLayers } from './esri'; import { esriLayers } from './esri';
import { genericLayers } from './generic'; import { genericLayers } from './generic';
import { osmLayers } from './osm'; import { osmLayers } from './osm';
import { defaultBaseLayer } from './default';
export const defaultGrafanaThemedMap = {
...defaultBaseLayer,
id: 'default',
name: 'Default base layer',
};
/** /**
* Registry for layer handlers * Registry for layer handlers
*/ */
export const basemapLayers = [ export const basemapLayers = [
defaultGrafanaThemedMap,
...osmLayers, ...osmLayers,
...cartoLayers, ...cartoLayers,
...esriLayers, // keep formatting ...esriLayers, // keep formatting

View File

@ -1,12 +1,41 @@
import { MapLayerRegistryItem, Registry } from '@grafana/data'; import { MapLayerRegistryItem, Registry, MapLayerOptions, GrafanaTheme2 } from '@grafana/data';
import Map from 'ol/Map';
import { carto } from './basemaps/carto';
import { config } from 'app/core/config';
import { basemapLayers } from './basemaps'; import { basemapLayers } from './basemaps';
import { dataLayers } from './data'; import { dataLayers } from './data';
export const DEFAULT_BASEMAP_CONFIG: MapLayerOptions = {
type: 'default',
config: {},
};
// Default base layer depending on the server setting
export const defaultBaseLayer: MapLayerRegistryItem = {
id: DEFAULT_BASEMAP_CONFIG.type,
name: 'Default base layer',
isBaseMap: true,
create: (map: Map, options: MapLayerOptions, theme: GrafanaTheme2) => {
const serverLayerType = config?.geomapDefaultBaseLayerConfig?.type;
if (serverLayerType) {
const layer = geomapLayerRegistry.getIfExists(serverLayerType);
if (!layer) {
throw new Error('Invalid basemap configuraiton on server');
}
return layer.create(map, config.geomapDefaultBaseLayerConfig!, theme);
}
// For now use carto as our default basemap
return carto.create(map, options, theme);
},
};
/** /**
* Registry for layer handlers * Registry for layer handlers
*/ */
export const geomapLayerRegistry = new Registry<MapLayerRegistryItem<any>>(() => [ export const geomapLayerRegistry = new Registry<MapLayerRegistryItem<any>>(() => [
defaultBaseLayer,
...basemapLayers, // simple basemaps ...basemapLayers, // simple basemaps
...dataLayers, // Layers with update functions ...dataLayers, // Layers with update functions
]); ]);

View File

@ -5,9 +5,8 @@ import { GeomapPanel } from './GeomapPanel';
import { MapViewEditor } from './editor/MapViewEditor'; import { MapViewEditor } from './editor/MapViewEditor';
import { defaultView, GeomapPanelOptions } from './types'; import { defaultView, GeomapPanelOptions } from './types';
import { mapPanelChangedHandler } from './migrations'; import { mapPanelChangedHandler } from './migrations';
import { defaultGrafanaThemedMap } from './layers/basemaps';
import { defaultMarkersConfig } from './layers/data/markersLayer'; import { defaultMarkersConfig } from './layers/data/markersLayer';
import { config } from 'app/core/config'; import { DEFAULT_BASEMAP_CONFIG } from './layers/registry';
export const plugin = new PanelPlugin<GeomapPanelOptions>(GeomapPanel) export const plugin = new PanelPlugin<GeomapPanelOptions>(GeomapPanel)
.setNoPadding() .setNoPadding()
@ -33,20 +32,14 @@ export const plugin = new PanelPlugin<GeomapPanelOptions>(GeomapPanel)
defaultValue: defaultView.shared, defaultValue: defaultView.shared,
}); });
// Nested builder.addCustomEditor({
if (!config.geomapDisableCustomBaseLayer) { category: ['Base Layer'],
builder.addCustomEditor({ id: 'basemap',
category: ['Base Layer'], path: 'basemap',
id: 'basemap', name: 'Base Layer',
path: 'basemap', editor: BaseLayerEditor,
name: 'Base Layer', defaultValue: DEFAULT_BASEMAP_CONFIG,
editor: BaseLayerEditor, });
defaultValue: {
type: defaultGrafanaThemedMap.id,
config: defaultGrafanaThemedMap.defaultOptions,
},
});
}
builder.addCustomEditor({ builder.addCustomEditor({
category: ['Data Layer'], category: ['Data Layer'],