mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
GeoMap: support setting view based on map data (#44852)
This commit is contained in:
parent
6967b15e76
commit
1dbfbc0e96
@ -23,7 +23,7 @@ The initial view configures how the GeoMap panel renders when the panel is first
|
|||||||
- **View** sets the center for the map when the panel first loads.
|
- **View** sets the center for the map when the panel first loads.
|
||||||
- **Latitude** (available when the **View** mode is _Coordinates_)
|
- **Latitude** (available when the **View** mode is _Coordinates_)
|
||||||
- **Longitude** (available when the **View** mode is _Coordinates_)
|
- **Longitude** (available when the **View** mode is _Coordinates_)
|
||||||
- **Zoom** sets the initial zoom level for the GeoMap panel.
|
- **Zoom** sets the initial zoom level for the GeoMap panel, or the initial maximum zoom level in case the _Fit data layers_ view is selected.
|
||||||
|
|
||||||
## Data layer
|
## Data layer
|
||||||
|
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
import React, { Component, ReactNode } from 'react';
|
import React, { Component, ReactNode } from 'react';
|
||||||
import { DEFAULT_BASEMAP_CONFIG, geomapLayerRegistry } from './layers/registry';
|
import { DEFAULT_BASEMAP_CONFIG, geomapLayerRegistry } from './layers/registry';
|
||||||
import { Map as OpenLayersMap, MapBrowserEvent, PluggableMap, View } from 'ol';
|
import { Collection, Map as OpenLayersMap, MapBrowserEvent, PluggableMap, 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';
|
||||||
import ScaleLine from 'ol/control/ScaleLine';
|
import ScaleLine from 'ol/control/ScaleLine';
|
||||||
|
import { createEmpty, extend, isEmpty } from 'ol/extent';
|
||||||
import { defaults as interactionDefaults } from 'ol/interaction';
|
import { defaults as interactionDefaults } from 'ol/interaction';
|
||||||
|
import BaseLayer from 'ol/layer/Base';
|
||||||
|
import VectorLayer from 'ol/layer/Vector';
|
||||||
import MouseWheelZoom from 'ol/interaction/MouseWheelZoom';
|
import MouseWheelZoom from 'ol/interaction/MouseWheelZoom';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -219,7 +222,7 @@ export class GeomapPanel extends Component<Props, State> {
|
|||||||
|
|
||||||
if (options.view !== oldOptions.view) {
|
if (options.view !== oldOptions.view) {
|
||||||
console.log('View changed');
|
console.log('View changed');
|
||||||
this.map!.setView(this.initMapView(options.view));
|
this.map!.setView(this.initMapView(options.view, this.map!.getLayers()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.controls !== oldOptions.controls) {
|
if (options.controls !== oldOptions.controls) {
|
||||||
@ -252,7 +255,7 @@ export class GeomapPanel extends Component<Props, State> {
|
|||||||
const { options } = this.props;
|
const { options } = this.props;
|
||||||
|
|
||||||
const map = (this.map = new OpenLayersMap({
|
const map = (this.map = new OpenLayersMap({
|
||||||
view: this.initMapView(options.view),
|
view: this.initMapView(options.view, undefined),
|
||||||
pixelRatio: 1, // or zoom?
|
pixelRatio: 1, // or zoom?
|
||||||
layers: [], // loaded explicitly below
|
layers: [], // loaded explicitly below
|
||||||
controls: [],
|
controls: [],
|
||||||
@ -282,6 +285,7 @@ export class GeomapPanel extends Component<Props, State> {
|
|||||||
}
|
}
|
||||||
this.layers = layers;
|
this.layers = layers;
|
||||||
this.map = map; // redundant
|
this.map = map; // redundant
|
||||||
|
this.initViewExtent(map.getView(), options.view, map.getLayers());
|
||||||
|
|
||||||
this.mouseWheelZoom = new MouseWheelZoom();
|
this.mouseWheelZoom = new MouseWheelZoom();
|
||||||
this.map.addInteraction(this.mouseWheelZoom);
|
this.map.addInteraction(this.mouseWheelZoom);
|
||||||
@ -497,7 +501,7 @@ export class GeomapPanel extends Component<Props, State> {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
initMapView(config: MapViewConfig): View {
|
initMapView(config: MapViewConfig, layers?: Collection<BaseLayer>): View {
|
||||||
let view = new View({
|
let view = new View({
|
||||||
center: [0, 0],
|
center: [0, 0],
|
||||||
zoom: 1,
|
zoom: 1,
|
||||||
@ -512,13 +516,31 @@ export class GeomapPanel extends Component<Props, State> {
|
|||||||
view = sharedView;
|
view = sharedView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (layers) {
|
||||||
|
this.initViewExtent(view, config, layers);
|
||||||
|
}
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
initViewExtent(view: View, config: MapViewConfig, layers: Collection<BaseLayer>) {
|
||||||
const v = centerPointRegistry.getIfExists(config.id);
|
const v = centerPointRegistry.getIfExists(config.id);
|
||||||
if (v) {
|
if (v) {
|
||||||
let coord: Coordinate | undefined = undefined;
|
let coord: Coordinate | undefined = undefined;
|
||||||
if (v.lat == null) {
|
if (v.lat == null) {
|
||||||
if (v.id === MapCenterID.Coordinates) {
|
if (v.id === MapCenterID.Coordinates) {
|
||||||
coord = [config.lon ?? 0, config.lat ?? 0];
|
coord = [config.lon ?? 0, config.lat ?? 0];
|
||||||
|
} else if (v.id === MapCenterID.Fit) {
|
||||||
|
var extent = layers
|
||||||
|
.getArray()
|
||||||
|
.filter((l) => l instanceof VectorLayer)
|
||||||
|
.map((l) => (l as VectorLayer<any>).getSource().getExtent() ?? [])
|
||||||
|
.reduce(extend, createEmpty());
|
||||||
|
if (!isEmpty(extent)) {
|
||||||
|
view.fit(extent, {
|
||||||
|
padding: [30, 30, 30, 30],
|
||||||
|
maxZoom: config.zoom ?? config.maxZoom,
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('TODO, view requires special handling', v);
|
console.log('TODO, view requires special handling', v);
|
||||||
}
|
}
|
||||||
@ -536,10 +558,9 @@ export class GeomapPanel extends Component<Props, State> {
|
|||||||
if (config.minZoom) {
|
if (config.minZoom) {
|
||||||
view.setMaxZoom(config.minZoom);
|
view.setMaxZoom(config.minZoom);
|
||||||
}
|
}
|
||||||
if (config.zoom) {
|
if (config.zoom && v?.id !== MapCenterID.Fit) {
|
||||||
view.setZoom(config.zoom);
|
view.setZoom(config.zoom);
|
||||||
}
|
}
|
||||||
return view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initControls(options: ControlsOptions) {
|
initControls(options: ControlsOptions) {
|
||||||
|
@ -9,9 +9,15 @@ interface MapCenterItems extends RegistryItem {
|
|||||||
export enum MapCenterID {
|
export enum MapCenterID {
|
||||||
Zero = 'zero',
|
Zero = 'zero',
|
||||||
Coordinates = 'coords',
|
Coordinates = 'coords',
|
||||||
|
Fit = 'fit',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const centerPointRegistry = new Registry<MapCenterItems>(() => [
|
export const centerPointRegistry = new Registry<MapCenterItems>(() => [
|
||||||
|
{
|
||||||
|
id: MapCenterID.Fit as string,
|
||||||
|
name: 'Fit data layers',
|
||||||
|
zoom: 15, // max zoom
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: MapCenterID.Zero as string,
|
id: MapCenterID.Zero as string,
|
||||||
name: '(0°, 0°)',
|
name: '(0°, 0°)',
|
||||||
|
Loading…
Reference in New Issue
Block a user