Geomap: Support geojson styling properties (#80272)

* Geomap: Support geojson styling properties

* Add enum for geojson styles

* Move styleStrings outside of style function

* Add styling note to geoJSON docs

* Clean up geomap docs

* Add support for points

* Add simple example

* Add support for all geojson types and update example

* Update colors

* Update docs

* Remove old TODO

* Update geojson name

---------

Co-authored-by: nmarrs <nathanielmarrs@gmail.com>
This commit is contained in:
Drew Slobodnjak 2024-01-19 16:55:17 -08:00 committed by GitHub
parent 9b9d91e7ae
commit 378c863616
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 228 additions and 12 deletions

View File

@ -282,6 +282,26 @@ The GeoJSON layer allows you to select and load a static GeoJSON file from the f
- **Add style rule** creates additional style rules.
- **Display tooltip** allows you to toggle tooltips for the layer.
{{% admonition type="note" %}}
Styles can be set within the "properties" object of the GeoJSON with support for the following geometries:
- Polygon, MultiPolygon
- **"fill"** - The color of the interior of the polygon(s)
- **"fill-opacity"** - The opacity of the interior of the polygon(s)
- **"stroke-width"** - The width of the line component of the polygon(s)
- Point, MultiPoint
- **"marker-color"** - The color of the point(s)
- **"marker-size"** - The size of the point(s)
- LineString, MultiLineString
- **"stroke"** - The color of the line(s)
- **"stroke-width"** - The width of the line(s)
{{% /admonition %}}
## Night / Day layer
The Night / Day layer displays night and day regions based on the current time range.
@ -457,7 +477,7 @@ A map from a collaborative free geographic world database.
### More Information
- [**About Open Street Map**](https://www.openstreetmap.org/about)\
- [**About Open Street Map**](https://www.openstreetmap.org/about)
## ArcGIS layer
@ -536,7 +556,7 @@ Displays measure tools in the upper right corner. Measurements appear only when
- **Double-click** to end measurement
{{% admonition type="note" %}}
<br /- When you change measurement type or units, the previous measurement is removed from the map. <br /- If the control is closed and then re-opened, the most recent measurement is displayed. <br /- A measurement can be modified by clicking and dragging on it.
When you change measurement type or units, the previous measurement is removed from the map. If the control is closed and then re-opened, the most recent measurement is displayed. A measurement can be modified by clicking and dragging on it.
{{% /admonition %}}
#### Length

View File

@ -8,25 +8,27 @@ import { Style } from 'ol/style';
import { ReplaySubject } from 'rxjs';
import { map as rxjsmap, first } from 'rxjs/operators';
import {
MapLayerRegistryItem,
MapLayerOptions,
GrafanaTheme2,
EventBus,
} from '@grafana/data';
import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2, EventBus } from '@grafana/data';
import { ComparisonOperation } from '@grafana/schema';
import { GeomapStyleRulesEditor } from '../../editor/GeomapStyleRulesEditor';
import { StyleEditor } from '../../editor/StyleEditor';
import { polyStyle } from '../../style/markers';
import { defaultStyleConfig, StyleConfig, StyleConfigState } from '../../style/types';
import {
defaultStyleConfig,
GeoJSONLineStyles,
GeoJSONPointStyles,
GeoJSONPolyStyles,
StyleConfig,
StyleConfigState,
StyleConfigValues,
} from '../../style/types';
import { getStyleConfigState } from '../../style/utils';
import { FeatureRuleConfig, FeatureStyleConfig } from '../../types';
import { checkFeatureMatchesStyleRule } from '../../utils/checkFeatureMatchesStyleRule';
import { getLayerPropertyInfo } from '../../utils/getFeatures';
import { getPublicGeoJSONFiles } from '../../utils/utils';
export interface GeoJSONMapperConfig {
// URL for a geojson file
src?: string;
@ -107,10 +109,16 @@ export const geojsonLayer: MapLayerRegistryItem<GeoJSONMapperConfig> = {
});
}
const polyStyleStrings: string[] = Object.values(GeoJSONPolyStyles);
const pointStyleStrings: string[] = Object.values(GeoJSONPointStyles);
const lineStyleStrings: string[] = Object.values(GeoJSONLineStyles);
const vectorLayer = new VectorLayer({
source,
style: (feature: FeatureLike) => {
const isPoint = feature.getGeometry()?.getType() === 'Point';
const featureType = feature.getGeometry()?.getType();
const isPoint = featureType === 'Point' || featureType === 'MultiPoint';
const isPolygon = featureType === 'Polygon' || featureType === 'MultiPolygon';
const isLine = featureType === 'LineString' || featureType === 'MultiLineString';
for (const check of styles) {
if (check.rule && !checkFeatureMatchesStyleRule(check.rule, feature)) {
@ -131,6 +139,29 @@ export const geojsonLayer: MapLayerRegistryItem<GeoJSONMapperConfig> = {
return polyStyle(values);
}
// Support styling polygons from Feature properties
const featureProps = feature.getProperties();
if (isPolygon && Object.keys(featureProps).some((property) => polyStyleStrings.includes(property))) {
const values: StyleConfigValues = {
color: featureProps[GeoJSONPolyStyles.color] ?? check.state.base.color,
opacity: featureProps[GeoJSONPolyStyles.opacity] ?? check.state.base.opacity,
lineWidth: featureProps[GeoJSONPolyStyles.lineWidth] ?? check.state.base.lineWidth,
};
return polyStyle(values);
} else if (isLine && Object.keys(featureProps).some((property) => lineStyleStrings.includes(property))) {
const values: StyleConfigValues = {
color: featureProps[GeoJSONLineStyles.color] ?? check.state.base.color,
lineWidth: featureProps[GeoJSONLineStyles.lineWidth] ?? check.state.base.lineWidth,
};
return check.state.maker(values);
} else if (isPoint && Object.keys(featureProps).some((property) => pointStyleStrings.includes(property))) {
const values: StyleConfigValues = {
color: featureProps[GeoJSONPointStyles.color] ?? check.state.base.color,
size: featureProps[GeoJSONPointStyles.size] ?? check.state.base.size,
};
return check.state.maker(values);
}
// Lazy create the style object
if (isPoint) {
if (!check.point) {
@ -196,4 +227,3 @@ export const geojsonLayer: MapLayerRegistryItem<GeoJSONMapperConfig> = {
},
defaultOptions,
};

View File

@ -127,6 +127,22 @@ export interface StyleConfigValues {
textConfig?: TextStyleConfig;
}
export enum GeoJSONPolyStyles {
color = 'fill',
opacity = 'fill-opacity',
lineWidth = 'stroke-width',
}
export enum GeoJSONPointStyles {
color = 'marker-color',
size = 'marker-size',
}
export enum GeoJSONLineStyles {
color = 'stroke',
lineWidth = 'stroke-width',
}
/** When the style depends on a field */
export interface StyleConfigFields {
color?: string;

View File

@ -0,0 +1,150 @@
{
"type": "FeatureCollection",
"name": "Example with Style",
"features": [
{
"type": "Feature",
"properties": {
"name": "Bermuda Triangle",
"fill": "red",
"fill-opacity": 0.5,
"stroke-width": 10
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-80.226529, 25.789106],
[-66.1057427, 18.4663188],
[-64.78138, 32.294887]
]
]
}
},
{
"type": "Feature",
"properties": {
"name": "Bermuda Triangles",
"fill": "red",
"fill-opacity": 0.1,
"stroke-width": 1
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[-72.5039545, 29.0419965],
[-73.16613585, 22.1277124],
[-80.226529, 25.789106]
],
[
[-65.44356135, 25.3806029],
[-73.16613585, 22.12771244],
[-66.1057427, 18.4663188]
],
[
[-65.44356135, 25.3806029],
[-72.5039545, 29.0419965],
[-64.78138, 32.294887]
]
]
]
}
},
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [-80.226529, 25.789106] },
"properties": {
"name": "Miami",
"marker-color": "rgb(255,255,0)",
"marker-size": 20
}
},
{
"type": "Feature",
"geometry": {
"type": "MultiPoint",
"coordinates": [
[-66.1057427, 18.4663188],
[-64.78138, 32.294887]
]
},
"properties": {
"name": "San Juan and Hamilton",
"marker-color": "#F99E26",
"marker-size": 10
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-77.76975242, 13.2503978],
[-73.16613585, 22.1277124]
]
},
"properties": {
"name": "Line 1",
"stroke": "red",
"stroke-width": 2
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-55.48910779, 24.42726436],
[-65.44356135, 25.3806029]
]
},
"properties": {
"name": "Line 2",
"stroke": "white",
"stroke-width": 2
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-76.38582213, 38.25780378],
[-72.5039545, 29.0419965]
]
},
"properties": {
"name": "Line 3",
"stroke": "blue",
"stroke-width": 2
}
},
{
"type": "Feature",
"geometry": {
"type": "MultiLineString",
"coordinates": [
[
[-80.226529, 25.789106],
[-66.1057427, 18.4663188]
],
[
[-66.1057427, 18.4663188],
[-64.78138, 32.294887]
],
[
[-64.78138, 32.294887],
[-80.226529, 25.789106]
]
]
},
"properties": {
"name": "Bermuda Triangle Thin Line",
"stroke": "yellow",
"stroke-width": 1
}
}
]
}