[Maps] show radius when drawing distance filter (#102808)
* [Maps] show radius when drawing distance filter * show more precision when radius is between 10km and 1km * move radius display from line to left of cursor Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
dd907e5487
commit
b4b17cfdec
|
@ -11,7 +11,11 @@
|
|||
import turfDistance from '@turf/distance';
|
||||
// @ts-expect-error
|
||||
import turfCircle from '@turf/circle';
|
||||
import { Position } from 'geojson';
|
||||
import { Feature, GeoJSON, Position } from 'geojson';
|
||||
|
||||
const DRAW_CIRCLE_RADIUS = 'draw-circle-radius';
|
||||
|
||||
export const DRAW_CIRCLE_RADIUS_MB_FILTER = ['==', 'meta', DRAW_CIRCLE_RADIUS];
|
||||
|
||||
export interface DrawCircleProperties {
|
||||
center: Position;
|
||||
|
@ -22,10 +26,12 @@ type DrawCircleState = {
|
|||
circle: {
|
||||
properties: Omit<DrawCircleProperties, 'center'> & {
|
||||
center: Position | null;
|
||||
edge: Position | null;
|
||||
radiusKm: number;
|
||||
};
|
||||
id: string | number;
|
||||
incomingCoords: (coords: unknown[]) => void;
|
||||
toGeoJSON: () => unknown;
|
||||
toGeoJSON: () => GeoJSON;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -43,6 +49,7 @@ export const DrawCircle = {
|
|||
type: 'Feature',
|
||||
properties: {
|
||||
center: null,
|
||||
edge: null,
|
||||
radiusKm: 0,
|
||||
},
|
||||
geometry: {
|
||||
|
@ -96,6 +103,7 @@ export const DrawCircle = {
|
|||
}
|
||||
|
||||
const mouseLocation = [e.lngLat.lng, e.lngLat.lat];
|
||||
state.circle.properties.edge = mouseLocation;
|
||||
state.circle.properties.radiusKm = turfDistance(state.circle.properties.center, mouseLocation);
|
||||
const newCircleFeature = turfCircle(
|
||||
state.circle.properties.center,
|
||||
|
@ -124,15 +132,53 @@ export const DrawCircle = {
|
|||
this.changeMode('simple_select', {}, { silent: true });
|
||||
}
|
||||
},
|
||||
toDisplayFeatures(
|
||||
state: DrawCircleState,
|
||||
geojson: { properties: { active: string } },
|
||||
display: (geojson: unknown) => unknown
|
||||
) {
|
||||
if (state.circle.properties.center) {
|
||||
geojson.properties.active = 'true';
|
||||
return display(geojson);
|
||||
toDisplayFeatures(state: DrawCircleState, geojson: Feature, display: (geojson: Feature) => void) {
|
||||
if (!state.circle.properties.center || !state.circle.properties.edge) {
|
||||
return null;
|
||||
}
|
||||
|
||||
geojson.properties!.active = 'true';
|
||||
|
||||
let radiusLabel = '';
|
||||
if (state.circle.properties.radiusKm <= 1) {
|
||||
radiusLabel = `${Math.round(state.circle.properties.radiusKm * 1000)} m`;
|
||||
} else if (state.circle.properties.radiusKm <= 10) {
|
||||
radiusLabel = `${state.circle.properties.radiusKm.toFixed(1)} km`;
|
||||
} else {
|
||||
radiusLabel = `${Math.round(state.circle.properties.radiusKm)} km`;
|
||||
}
|
||||
|
||||
// display radius label, requires custom 'symbol' style with DRAW_CIRCLE_RADIUS_MB_FILTER filter
|
||||
display({
|
||||
type: 'Feature',
|
||||
properties: {
|
||||
meta: DRAW_CIRCLE_RADIUS,
|
||||
parent: state.circle.id,
|
||||
radiusLabel,
|
||||
active: 'false',
|
||||
},
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: state.circle.properties.edge,
|
||||
},
|
||||
});
|
||||
|
||||
// display line from center vertex to edge
|
||||
display({
|
||||
type: 'Feature',
|
||||
properties: {
|
||||
meta: 'draw-circle-radius-line',
|
||||
parent: state.circle.id,
|
||||
active: 'true',
|
||||
},
|
||||
geometry: {
|
||||
type: 'LineString',
|
||||
coordinates: [state.circle.properties.center, state.circle.properties.edge],
|
||||
},
|
||||
});
|
||||
|
||||
// display circle
|
||||
display(geojson);
|
||||
},
|
||||
onTrash(state: DrawCircleState) {
|
||||
// @ts-ignore
|
||||
|
|
|
@ -14,9 +14,11 @@ import DrawRectangle from 'mapbox-gl-draw-rectangle-mode';
|
|||
import type { Map as MbMap } from '@kbn/mapbox-gl';
|
||||
import { Feature } from 'geojson';
|
||||
import { DRAW_SHAPE } from '../../../../common/constants';
|
||||
import { DrawCircle } from './draw_circle';
|
||||
import { DrawCircle, DRAW_CIRCLE_RADIUS_MB_FILTER } from './draw_circle';
|
||||
import { DrawTooltip } from './draw_tooltip';
|
||||
|
||||
const GL_DRAW_RADIUS_LABEL_LAYER_ID = 'gl-draw-radius-label';
|
||||
|
||||
const mbModeEquivalencies = new Map<string, DRAW_SHAPE>([
|
||||
['simple_select', DRAW_SHAPE.SIMPLE_SELECT],
|
||||
['draw_rectangle', DRAW_SHAPE.BOUNDS],
|
||||
|
@ -94,6 +96,7 @@ export class DrawControl extends Component<Props> {
|
|||
this.props.mbMap.getCanvas().style.cursor = '';
|
||||
this.props.mbMap.off('draw.modechange', this._onModeChange);
|
||||
this.props.mbMap.off('draw.create', this._onDraw);
|
||||
this.props.mbMap.removeLayer(GL_DRAW_RADIUS_LABEL_LAYER_ID);
|
||||
this.props.mbMap.removeControl(this._mbDrawControl);
|
||||
this._mbDrawControlAdded = false;
|
||||
}
|
||||
|
@ -105,6 +108,25 @@ export class DrawControl extends Component<Props> {
|
|||
|
||||
if (!this._mbDrawControlAdded) {
|
||||
this.props.mbMap.addControl(this._mbDrawControl);
|
||||
this.props.mbMap.addLayer({
|
||||
id: GL_DRAW_RADIUS_LABEL_LAYER_ID,
|
||||
type: 'symbol',
|
||||
source: 'mapbox-gl-draw-hot',
|
||||
filter: DRAW_CIRCLE_RADIUS_MB_FILTER,
|
||||
layout: {
|
||||
'text-anchor': 'right',
|
||||
'text-field': '{radiusLabel}',
|
||||
'text-size': 16,
|
||||
'text-offset': [-1, 0],
|
||||
'text-ignore-placement': true,
|
||||
'text-allow-overlap': true,
|
||||
},
|
||||
paint: {
|
||||
'text-color': '#fbb03b',
|
||||
'text-halo-color': 'rgba(255, 255, 255, 1)',
|
||||
'text-halo-width': 2,
|
||||
},
|
||||
});
|
||||
this._mbDrawControlAdded = true;
|
||||
this.props.mbMap.getCanvas().style.cursor = 'crosshair';
|
||||
this.props.mbMap.on('draw.modechange', this._onModeChange);
|
||||
|
|
Loading…
Reference in a new issue