Geomap: Fix Fit to Data for Route Layer (#101391)

* Geomap: Fix Fit to Data for Route Layer

* Update gdev panel tests to cover fit to data

* Add layer value to layer select value
pull/101472/head
Drew Slobodnjak 3 months ago committed by GitHub
parent 620d213856
commit 87a9188bb4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 209
      devenv/dev-dashboards/panel-geomap/geomap-route-layer.json
  2. 2
      public/app/plugins/panel/geomap/editor/FitMapViewEditor.tsx
  3. 34
      public/app/plugins/panel/geomap/utils/getLayersExtent.ts

@ -29,20 +29,22 @@
"liveNow": false,
"panels": [
{
"datasource": {
"type": "testdata",
"uid": "PD8C576611E62080A"
"id": 2,
"type": "geomap",
"title": "Multiple Layer Types",
"gridPos": {
"x": 0,
"y": 0,
"h": 16,
"w": 18
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "continuous-RdYlGr"
},
"custom": {
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
"viz": false,
"legend": false
}
},
"mappings": [],
@ -51,7 +53,7 @@
"steps": [
{
"color": "dark-red",
"value": 0
"value": null
},
{
"color": "yellow",
@ -62,18 +64,59 @@
"value": 100
}
]
},
"color": {
"mode": "continuous-RdYlGr"
}
},
"overrides": []
},
"gridPos": {
"h": 16,
"w": 18,
"x": 0,
"y": 0
"pluginVersion": "11.6.0-pre",
"targets": [
{
"csvContent": "lat,lon,val\n-5,2,0\n1,5,25\n6,10,50\n9,15,75\n10,20,100",
"datasource": {
"type": "testdata",
"uid": "PD8C576611E62080A"
},
"refId": "A",
"scenarioId": "csv_content"
},
{
"scenarioId": "csv_content",
"refId": "B",
"datasource": {
"uid": "PD8C576611E62080A",
"type": "grafana-testdata-datasource"
},
"csvContent": "lat,lon,alt\n45,0,0\n40,5,5\n35,10,10\n30,15, 15\n25,20,20"
}
],
"datasource": {
"type": "testdata",
"uid": "PD8C576611E62080A"
},
"id": 2,
"options": {
"view": {
"allLayers": true,
"id": "fit",
"lat": 2.359794,
"lon": 8.135816,
"zoom": 15,
"lastOnly": false,
"layer": "markers"
},
"controls": {
"showZoom": true,
"mouseWheelZoom": true,
"showAttribution": true,
"showScale": false,
"showMeasure": false,
"showDebug": false
},
"tooltip": {
"mode": "details"
},
"basemap": {
"config": {
"server": "streets"
@ -81,14 +124,6 @@
"name": "Layer 0",
"type": "esri-xyz"
},
"controls": {
"mouseWheelZoom": true,
"showAttribution": true,
"showDebug": false,
"showMeasure": false,
"showScale": false,
"showZoom": true
},
"layers": [
{
"config": {
@ -128,36 +163,108 @@
"location": {
"mode": "auto"
},
"name": "Layer 2",
"name": "route",
"tooltip": true,
"type": "route"
}
],
"tooltip": {
"mode": "details"
},
"view": {
"allLayers": true,
"id": "coords",
"lat": 2.359794,
"lon": 8.135816,
"zoom": 4.45
}
},
"pluginVersion": "9.4.0-pre",
"targets": [
{
"csvContent": "lat,lon,val\n-5,2,0\n1,5,25\n6,10,50\n9,15,75\n10,20,100",
"datasource": {
"type": "testdata",
"uid": "PD8C576611E62080A"
},
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "Route with Colors",
"type": "geomap"
{
"type": "geojson",
"name": "geojson",
"config": {
"src": "public/maps/example-with-style.geojson",
"rules": [],
"style": {
"size": {
"fixed": 5,
"min": 2,
"max": 15
},
"color": {
"fixed": "dark-green"
},
"opacity": 0.4,
"symbol": {
"mode": "fixed",
"fixed": "img/icons/marker/circle.svg"
},
"symbolAlign": {
"horizontal": "center",
"vertical": "center"
},
"textConfig": {
"fontSize": 12,
"textAlign": "center",
"textBaseline": "middle",
"offsetX": 0,
"offsetY": 0
},
"rotation": {
"fixed": 0,
"mode": "mod",
"min": -360,
"max": 360
}
}
},
"location": {
"mode": "auto"
},
"tooltip": true,
"filterData": {
"id": "byRefId",
"options": "B"
}
},
{
"type": "markers",
"name": "markers",
"config": {
"style": {
"size": {
"fixed": 5,
"min": 2,
"max": 15
},
"color": {
"fixed": "dark-green",
"field": "alt"
},
"opacity": 0.4,
"symbol": {
"mode": "fixed",
"fixed": "img/icons/marker/circle.svg"
},
"symbolAlign": {
"horizontal": "center",
"vertical": "center"
},
"textConfig": {
"fontSize": 12,
"textAlign": "center",
"textBaseline": "middle",
"offsetX": 0,
"offsetY": 0
},
"rotation": {
"fixed": 0,
"mode": "mod",
"min": -360,
"max": 360
}
},
"showLegend": true
},
"location": {
"mode": "auto"
},
"tooltip": true,
"filterData": {
"id": "byRefId",
"options": "B"
}
}
]
}
}
],
"schemaVersion": 37,
@ -171,7 +278,7 @@
},
"timepicker": {},
"timezone": "",
"title": "Panel Tests - Geomap Route Layer",
"title": "Panel Tests - Geomap Fit to Data - Multiple Layer Types",
"uid": "OYTKK3DVk",
"version": 25,
"weekStart": ""

@ -54,7 +54,7 @@ export const FitMapViewEditor = ({ labelWidth, value, onChange, context }: Props
const allLayersEditorFragment = (
<InlineFieldRow>
<InlineField label="Layer" labelWidth={labelWidth} grow={true}>
<Select options={layers} onChange={onSelectLayer} placeholder={layers[0]?.label} />
<Select options={layers} onChange={onSelectLayer} placeholder={layers[0]?.label} value={value.layer} />
</InlineField>
</InlineFieldRow>
);

@ -14,14 +14,19 @@ export function getLayersExtent(
return layers
.filter((l) => l.layer instanceof VectorLayer || l.layer instanceof LayerGroup || l.layer instanceof VectorImage)
.flatMap((ll) => {
const layerName = ll.options.name;
const l = ll.layer;
if (l instanceof LayerGroup) {
return getLayerGroupExtent(l);
// If not all layers check for matching layer name
if (!allLayers && layerName !== layer) {
return [];
}
return getLayerGroupExtent(l, lastOnly);
} else if (l instanceof VectorLayer || l instanceof VectorImage) {
if (allLayers) {
// Return everything from all layers
return [l.getSource().getExtent()];
} else if (lastOnly && layer === ll.options.name) {
} else if (lastOnly && layer === layerName) {
// Return last only for selected layer
const feat = l.getSource().getFeatures();
const featOfInterest = feat[feat.length - 1];
@ -30,7 +35,7 @@ export function getLayersExtent(
return [geo.getExtent()];
}
return [];
} else if (!lastOnly && layer === ll.options.name) {
} else if (!lastOnly && layer === layerName) {
// Return all points for selected layer
return [l.getSource().getExtent()];
}
@ -42,13 +47,30 @@ export function getLayersExtent(
.reduce(extend, createEmpty());
}
export function getLayerGroupExtent(lg: LayerGroup) {
export function getLayerGroupExtent(lg: LayerGroup, lastOnly: boolean) {
return lg
.getLayers()
.getArray()
.filter((l) => l instanceof VectorLayer)
.filter((l) => l instanceof VectorLayer || l instanceof VectorImage)
.map((l) => {
if (l instanceof VectorLayer) {
if (l instanceof VectorLayer || l instanceof VectorImage) {
if (lastOnly) {
// Return last coordinate only
const feat = l.getSource().getFeatures();
const featOfInterest = feat[feat.length - 1];
const geo = featOfInterest?.getGeometry();
if (geo) {
// Look at flatCoordinates for more robust support including route layer
const flatCoordinates = geo.flatCoordinates;
const flatCoordinatesLength = flatCoordinates.length;
if (flatCoordinatesLength > 1) {
const lastX = flatCoordinates[flatCoordinatesLength - 2];
const lastY = flatCoordinates[flatCoordinatesLength - 1];
return [lastX, lastY, lastX, lastY];
}
}
return [];
}
return l.getSource().getExtent() ?? [];
} else {
return [];

Loading…
Cancel
Save