Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/modules/editable-layers/developer-guide/geojson-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# GeoJSON types
The `editable-layers` module uses Turf.js 7, which in turn uses standard types from the `geojson` package for features, geometries, etc.

## SimpleGeometry types
Editable layers operate on `FeatureCollection`s that contain `Feature`s with any [standard geojson geometry](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1) __except__ `GeometryCollection` (which has a `geometries` property instead of `geometry`)

To simplify working with the library in TypeScript, the package exports a `SimpleGeometry` type (a union of all geometries except `GeometryCollection`), as well `SimpleFeature`, `SimpleFeatureCollection`, and `SimpleCoordinates`.

These are useful when building your own editing modes:

```ts
import { GeoJsonEditMode, SimpleFeatureCollection, ModeProps } from '@deck.gl-community/editable-layers';

export class MyEditMode extends GeoJsonEditMode {
handleClick(event: ClickEvent, props: ModeProps<SimpleFeatureCollection>) {
// custom logic here
}
}
```
1 change: 1 addition & 0 deletions docs/modules/editable-layers/sidebar.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"modules/editable-layers/README",
"modules/editable-layers/developer-guide/get-started",
"modules/editable-layers/developer-guide/data-model",
"modules/editable-layers/developer-guide/geojson-types",
"modules/editable-layers/developer-guide/configuration",
{
"type": "category",
Expand Down
1 change: 1 addition & 0 deletions docs/whats-new.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Highlights:
- deck.gl v9.2 compatibility.
- Website: Documentation improvements and search.
- Tests updated to use `vitest` instead of `jest`
- editable-layers now uses turf.js 7 (and geojson types)

### `@deck.gl-community/widgets` (NEW module)

Expand Down
63 changes: 31 additions & 32 deletions modules/editable-layers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,38 +36,37 @@
"src"
],
"dependencies": {
"@turf/along": "^6.5.0",
"@turf/area": "^6.5.0",
"@turf/bbox": "^6.5.0",
"@turf/bbox-polygon": "^6.5.0",
"@turf/bearing": "^6.5.0",
"@turf/boolean-point-in-polygon": "^6.5.0",
"@turf/boolean-within": "^6.5.0",
"@turf/buffer": "^6.5.0",
"@turf/center": "^6.5.0",
"@turf/centroid": "^6.5.0",
"@turf/circle": "^6.5.0",
"@turf/clone": "^6.5.0",
"@turf/destination": "^6.5.0",
"@turf/difference": "^6.5.0",
"@turf/distance": "^6.5.0",
"@turf/ellipse": "^6.5.0",
"@turf/helpers": "^6.5.0",
"@turf/intersect": "^6.5.0",
"@turf/invariant": "^6.5.0",
"@turf/line-intersect": "^6.5.0",
"@turf/meta": "^6.5.0",
"@turf/midpoint": "^6.5.0",
"@turf/nearest-point-on-line": "^6.5.0",
"@turf/point-to-line-distance": "^6.5.0",
"@turf/polygon-to-line": "^6.5.0",
"@turf/rewind": "^6.5.0",
"@turf/transform-rotate": "^6.5.0",
"@turf/transform-scale": "^6.5.0",
"@turf/transform-translate": "^6.5.0",
"@turf/union": "^6.5.0",
"@types/geojson": "^7946.0.14",
"cubic-hermite-spline": "^1.0.1",
"@turf/along": "^7.2.0",
"@turf/area": "^7.2.0",
"@turf/bbox": "^7.2.0",
"@turf/bbox-polygon": "^7.2.0",
"@turf/bearing": "^7.2.0",
"@turf/boolean-point-in-polygon": "^7.2.0",
"@turf/boolean-within": "^7.2.0",
"@turf/buffer": "^7.2.0",
"@turf/center": "^7.2.0",
"@turf/centroid": "^7.2.0",
"@turf/circle": "^7.2.0",
"@turf/clone": "^7.2.0",
"@turf/destination": "^7.2.0",
"@turf/difference": "^7.2.0",
"@turf/distance": "^7.2.0",
"@turf/ellipse": "^7.2.0",
"@turf/helpers": "^7.2.0",
"@turf/intersect": "^7.2.0",
"@turf/invariant": "^7.2.0",
"@turf/line-intersect": "^7.2.0",
"@turf/meta": "^7.2.0",
"@turf/midpoint": "^7.2.0",
"@turf/nearest-point-on-line": "^7.2.0",
"@turf/point-to-line-distance": "^7.2.0",
"@turf/polygon-to-line": "^7.2.0",
"@turf/rewind": "^7.2.0",
"@turf/transform-rotate": "^7.2.0",
"@turf/transform-scale": "^7.2.0",
"@turf/transform-translate": "^7.2.0",
"@turf/union": "^7.2.0",
"@types/geojson": "^7946.0.16",
"eventemitter3": "^5.0.0",
"lodash.omit": "^4.1.1",
"lodash.throttle": "^4.1.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
GuideFeatureCollection,
TentativeFeature
} from './types';
import {Polygon, LineString, Position, FeatureCollection} from '../utils/geojson-types';
import {Polygon, LineString, Position, FeatureCollection, SimpleFeatureCollection} from '../utils/geojson-types';
import {GeoJsonEditMode} from './geojson-edit-mode';

export class Draw90DegreePolygonMode extends GeoJsonEditMode {
Expand Down Expand Up @@ -98,7 +98,7 @@ export class Draw90DegreePolygonMode extends GeoJsonEditMode {
super.handlePointerMove(event, props);
}

handleClick(event: ClickEvent, props: ModeProps<FeatureCollection>) {
handleClick(event: ClickEvent, props: ModeProps<SimpleFeatureCollection>) {
const {picks} = event;
const tentativeFeature = this.getTentativeGuide(props);
this.addClickSequence(event);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import distance from '@turf/distance';
import area from '@turf/area';
import {memoize} from '../utils/memoize';
import {ModeProps, Tooltip} from './types';
import {Position, Polygon, FeatureOf, FeatureCollection} from '../utils/geojson-types';
import {Position, Polygon, Feature, FeatureCollection} from '../utils/geojson-types';
import {getIntermediatePosition} from './geojson-edit-mode';
import {TwoClickPolygonMode} from './two-click-polygon-mode';

Expand All @@ -16,7 +16,7 @@ export class DrawCircleByDiameterMode extends TwoClickPolygonMode {
position: Position = null!;
areaCircle: number | null | undefined = null;
diameter: number | null | undefined = null;
getTwoClickPolygon(coord1: Position, coord2: Position, modeConfig: any): FeatureOf<Polygon> {
getTwoClickPolygon(coord1: Position, coord2: Position, modeConfig: any): Feature<Polygon> {
// Default turf value for circle is 64
const {steps = 64} = modeConfig || {};
const options = {steps};
Expand Down Expand Up @@ -44,7 +44,7 @@ export class DrawCircleByDiameterMode extends TwoClickPolygonMode {
geometry.properties.editProperties.center = centerCoordinates;
// calculate area of circle with turf function
this.areaCircle = area(geometry);
// @ts-expect-error turf types diff

return geometry;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import distance from '@turf/distance';
import area from '@turf/area';
import {memoize} from '../utils/memoize';
import {ModeProps, Tooltip} from './types';
import {Position, Polygon, FeatureOf, FeatureCollection} from '../utils/geojson-types';
import {Position, Polygon, Feature, FeatureCollection} from '../utils/geojson-types';
import {TwoClickPolygonMode} from './two-click-polygon-mode';

export class DrawCircleFromCenterMode extends TwoClickPolygonMode {
radius: number | null | undefined = null;
position: Position = null!;
areaCircle: number | null | undefined = null;
getTwoClickPolygon(coord1: Position, coord2: Position, modeConfig: any): FeatureOf<Polygon> {
getTwoClickPolygon(coord1: Position, coord2: Position, modeConfig: any): Feature<Polygon> {
// Default turf value for circle is 64
const {steps = 64} = modeConfig || {};
const options = {steps};
Expand All @@ -38,7 +38,7 @@ export class DrawCircleFromCenterMode extends TwoClickPolygonMode {
geometry.properties.editProperties.center = coord1;
// calculate area of circle with turf function
this.areaCircle = area(geometry);
// @ts-expect-error turf types diff

return geometry;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import bboxPolygon from '@turf/bbox-polygon';
import distance from '@turf/distance';
import ellipse from '@turf/ellipse';
import {point} from '@turf/helpers';
import {Position, Polygon, FeatureOf} from '../utils/geojson-types';
import {Position, Polygon, Feature} from '../utils/geojson-types';
import {getIntermediatePosition} from './geojson-edit-mode';
import {TwoClickPolygonMode} from './two-click-polygon-mode';

export class DrawEllipseByBoundingBoxMode extends TwoClickPolygonMode {
getTwoClickPolygon(coord1: Position, coord2: Position, modeConfig: any): FeatureOf<Polygon> {
getTwoClickPolygon(coord1: Position, coord2: Position, modeConfig: any): Feature<Polygon> {
const minX = Math.min(coord1[0], coord2[0]);
const minY = Math.min(coord1[1], coord2[1]);
const maxX = Math.max(coord1[0], coord2[0]);
Expand All @@ -23,7 +23,7 @@ export class DrawEllipseByBoundingBoxMode extends TwoClickPolygonMode {
const xSemiAxis = Math.max(distance(point(polygonPoints[0]), point(polygonPoints[1])), 0.001);
const ySemiAxis = Math.max(distance(point(polygonPoints[0]), point(polygonPoints[3])), 0.001);

const geometry = ellipse(centerCoordinates, xSemiAxis, ySemiAxis);
const geometry = ellipse(centerCoordinates, xSemiAxis, ySemiAxis, {});

geometry.properties = geometry.properties || {};
geometry.properties.editProperties = geometry.properties.editProperties || {};
Expand All @@ -32,7 +32,7 @@ export class DrawEllipseByBoundingBoxMode extends TwoClickPolygonMode {
geometry.properties.editProperties.ySemiAxis = {value: ySemiAxis, unit: 'kilometers'};
geometry.properties.editProperties.angle = 0;
geometry.properties.editProperties.center = centerCoordinates;
// @ts-expect-error fix return types

return geometry;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import distance from '@turf/distance';
import ellipse from '@turf/ellipse';
import bearing from '@turf/bearing';
import {point} from '@turf/helpers';
import {Position, Polygon, FeatureOf} from '../utils/geojson-types';
import {Position, Polygon, Feature} from '../utils/geojson-types';
import {getIntermediatePosition} from './geojson-edit-mode';
import {ThreeClickPolygonMode} from './three-click-polygon-mode';

Expand All @@ -16,12 +16,11 @@ export class DrawEllipseUsingThreePointsMode extends ThreeClickPolygonMode {
coord2: Position,
coord3: Position,
modeConfig: any
): FeatureOf<Polygon> | null | undefined {
): Feature<Polygon> | null | undefined {
const centerCoordinates = getIntermediatePosition(coord1, coord2);
const xSemiAxis = Math.max(distance(centerCoordinates, point(coord3)), 0.001);
const ySemiAxis = Math.max(distance(coord1, coord2), 0.001) / 2;
const options = {angle: bearing(coord1, coord2)};
// @ts-expect-error fix return types
const geometry = ellipse(centerCoordinates, xSemiAxis, ySemiAxis, options);

geometry.properties = geometry.properties || {};
Expand All @@ -31,7 +30,7 @@ export class DrawEllipseUsingThreePointsMode extends ThreeClickPolygonMode {
geometry.properties.editProperties.ySemiAxis = {value: ySemiAxis, unit: 'kilometers'};
geometry.properties.editProperties.angle = options.angle;
geometry.properties.editProperties.center = centerCoordinates;
// @ts-expect-error fix return types

return geometry;
}
}
10 changes: 5 additions & 5 deletions modules/editable-layers/src/edit-modes/draw-line-string-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import distance from '@turf/distance';
import {memoize} from '../utils/memoize';
import {LineString, FeatureCollection, Position} from '../utils/geojson-types';
import {LineString, FeatureCollection, Position, SimpleFeatureCollection} from '../utils/geojson-types';
import {
ClickEvent,
PointerMoveEvent,
Expand All @@ -22,7 +22,7 @@ export class DrawLineStringMode extends GeoJsonEditMode {
dist = 0;
position: Position = null!;
elems: Position[] = [];
handleClick(event: ClickEvent, props: ModeProps<FeatureCollection>) {
handleClick(event: ClickEvent, props: ModeProps<SimpleFeatureCollection>) {
const {picks} = event;
const clickedEditHandle = getPickedEditHandle(picks);

Expand Down Expand Up @@ -62,11 +62,11 @@ export class DrawLineStringMode extends GeoJsonEditMode {
}
}

handleDoubleClick(event: DoubleClickEvent, props: ModeProps<FeatureCollection>) {
handleDoubleClick(event: DoubleClickEvent, props: ModeProps<SimpleFeatureCollection>) {
this.finishDrawing(props);
}

finishDrawing(props: ModeProps<FeatureCollection>) {
finishDrawing(props: ModeProps<SimpleFeatureCollection>) {
const clickSequence = this.getClickSequence();
if (clickSequence.length > 1) {
const lineStringToAdd: LineString = {
Expand All @@ -81,7 +81,7 @@ export class DrawLineStringMode extends GeoJsonEditMode {
}
}

handleKeyUp(event: KeyboardEvent, props: ModeProps<FeatureCollection>) {
handleKeyUp(event: KeyboardEvent, props: ModeProps<SimpleFeatureCollection>) {
const {key} = event;
if (key === 'Enter') {
this.finishDrawing(props);
Expand Down
4 changes: 2 additions & 2 deletions modules/editable-layers/src/edit-modes/draw-point-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Copyright (c) vis.gl contributors

import {ClickEvent, PointerMoveEvent, ModeProps, TentativeFeature} from './types';
import {FeatureCollection, Point} from '../utils/geojson-types';
import {FeatureCollection, SimpleFeatureCollection, Point} from '../utils/geojson-types';
import {GeoJsonEditMode} from './geojson-edit-mode';

export class DrawPointMode extends GeoJsonEditMode {
Expand All @@ -23,7 +23,7 @@ export class DrawPointMode extends GeoJsonEditMode {
};
}

handleClick({mapCoords}: ClickEvent, props: ModeProps<FeatureCollection>): void {
handleClick({mapCoords}: ClickEvent, props: ModeProps<SimpleFeatureCollection>): void {
const geometry: Point = {
type: 'Point',
coordinates: mapCoords
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@

import throttle from 'lodash.throttle';
import {ClickEvent, StartDraggingEvent, StopDraggingEvent, DraggingEvent, ModeProps} from './types';
import {Polygon, FeatureCollection} from '../utils/geojson-types';
import {Polygon, SimpleFeatureCollection} from '../utils/geojson-types';
import {getPickedEditHandle} from './utils';
import {DrawPolygonMode} from './draw-polygon-mode';

type DraggingHandler = (event: DraggingEvent, props: ModeProps<FeatureCollection>) => void;
type DraggingHandler = (event: DraggingEvent, props: ModeProps<SimpleFeatureCollection>) => void;

export class DrawPolygonByDraggingMode extends DrawPolygonMode {
handleDraggingThrottled: DraggingHandler | null | undefined = null;

handleClick(event: ClickEvent, props: ModeProps<FeatureCollection>) {
handleClick(event: ClickEvent, props: ModeProps<SimpleFeatureCollection>) {
// No-op
}

handleStartDragging(event: StartDraggingEvent, props: ModeProps<FeatureCollection>) {
handleStartDragging(event: StartDraggingEvent, props: ModeProps<SimpleFeatureCollection>) {
event.cancelPan();
if (props.modeConfig && props.modeConfig.throttleMs) {
// eslint-disable-next-line @typescript-eslint/unbound-method
Expand All @@ -28,7 +28,7 @@ export class DrawPolygonByDraggingMode extends DrawPolygonMode {
}
}

handleStopDragging(event: StopDraggingEvent, props: ModeProps<FeatureCollection>) {
handleStopDragging(event: StopDraggingEvent, props: ModeProps<SimpleFeatureCollection>) {
this.addClickSequence(event);
const clickSequence = this.getClickSequence();
// @ts-expect-error cancel() not typed
Expand All @@ -52,7 +52,7 @@ export class DrawPolygonByDraggingMode extends DrawPolygonMode {
this.resetClickSequence();
}

handleDraggingAux(event: DraggingEvent, props: ModeProps<FeatureCollection>) {
handleDraggingAux(event: DraggingEvent, props: ModeProps<SimpleFeatureCollection>) {
const {picks} = event;
const clickedEditHandle = getPickedEditHandle(picks);

Expand All @@ -69,13 +69,13 @@ export class DrawPolygonByDraggingMode extends DrawPolygonMode {
}
}

handleDragging(event: DraggingEvent, props: ModeProps<FeatureCollection>) {
handleDragging(event: DraggingEvent, props: ModeProps<SimpleFeatureCollection>) {
if (this.handleDraggingThrottled) {
this.handleDraggingThrottled(event, props);
}
}

handleKeyUp(event: KeyboardEvent, props: ModeProps<FeatureCollection>) {
handleKeyUp(event: KeyboardEvent, props: ModeProps<SimpleFeatureCollection>) {
if (event.key === 'Enter') {
const clickSequence = this.getClickSequence();
if (clickSequence.length > 2) {
Expand Down
Loading