Skip to content
Closed
24 changes: 13 additions & 11 deletions examples/editable-layers/no-map/example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
type GeoJsonEditModeType
} from '@deck.gl-community/editable-layers';
import type {FeatureCollection} from 'geojson';
import {COORDINATE_SYSTEM, OrthographicView, OrthographicViewState} from '@deck.gl/core';

import '@deck.gl/widgets/stylesheet.css';

Expand All @@ -30,9 +31,8 @@ import '@deck.gl/widgets/stylesheet.css';
const BACKGROUND_IMAGE =
'https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Dendrocygna_eytoni_-_Macquarie_University.jpg/1280px-Dendrocygna_eytoni_-_Macquarie_University.jpg';

// Position the image near the equator where Mercator distortion is minimal.
// Bounds: [west, south, east, north]
const IMAGE_BOUNDS: [number, number, number, number] = [-10, -8, 10, 8];
// Bounds: [left, top, right, bottom] - flipped from original bounds
const IMAGE_BOUNDS: [number, number, number, number] = [10, 8, -10, -8];

function getDefaultGeoJSON(): FeatureCollection {
return {
Expand Down Expand Up @@ -66,10 +66,8 @@ function getDefaultGeoJSON(): FeatureCollection {
};
}

// Centered at [0, 0] — no basemap rendered, just a plain background
const INITIAL_VIEW_STATE = {
longitude: 0,
latitude: 0,
const INITIAL_VIEW_STATE: OrthographicViewState = {
target: [0, 0, 0],
zoom: 5
};

Expand Down Expand Up @@ -166,29 +164,33 @@ export function Example() {
const backgroundLayer = new BitmapLayer({
id: 'background-image',
bounds: IMAGE_BOUNDS,
image: BACKGROUND_IMAGE
image: BACKGROUND_IMAGE,
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN
});

const editableLayer = new EditableGeoJsonLayer({
data: geoJson,
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
mode,
selectedFeatureIndexes,
onEdit: ({updatedData}) => {
setGeoJson(updatedData);
},
getFillColor: [0, 100, 200, 80],
getLineColor: [0, 100, 200, 200],
getLineColor: (feature, isSelected) => (isSelected ? [2, 107, 60, 130] : [0, 77, 153, 100]),
getLineWidth: 2,
lineWidthMinPixels: 2,
pointRadiusMinPixels: 6,
editHandlePointRadiusMinPixels: 5
editHandlePointRadiusMinPixels: 5,
autoHighlight: true,
getFillColor: (feature, isSelected) => (isSelected ? [0, 200, 110, 150] : [0, 100, 200, 130])
});

return (
<>
<DeckGL
initialViewState={INITIAL_VIEW_STATE}
controller={{doubleClickZoom: false}}
views={new OrthographicView()}
layers={[backgroundLayer, editableLayer]}
getCursor={editableLayer.getCursor.bind(editableLayer)}
onClick={(info) => {
Expand Down
37 changes: 25 additions & 12 deletions modules/editable-layers/src/edit-modes/draw-line-string-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors

import distance from '@turf/distance';
import {memoize} from '../utils/memoize';
import {
LineString,
Expand All @@ -21,6 +20,11 @@ import {
} from './types';
import {getPickedEditHandle} from './utils';
import {GeoJsonEditMode} from './geojson-edit-mode';
import {
EditModeCoordinateSystem,
GeoCoordinateSystem,
getEditModeCoordinateSystem
} from './coordinate-system';

export class DrawLineStringMode extends GeoJsonEditMode {
// declaration of variables for the calculation of the distance of linestring
Expand All @@ -37,11 +41,11 @@ export class DrawLineStringMode extends GeoJsonEditMode {
this.addClickSequence(event);
positionAdded = true;
}
const clickSequence = this.getClickSequence();
const clickSequence: Position[] = this.getClickSequence();
Comment thread
charlieforward9 marked this conversation as resolved.

// check if the pointer is on editable state calculate the distance of new point
if (!clickedEditHandle) {
this.calculateInfoDraw(clickSequence);
this.calculateInfoDraw(clickSequence, props?.coordinateSystem);
}

if (
Expand All @@ -67,7 +71,7 @@ export class DrawLineStringMode extends GeoJsonEditMode {
}
}

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

Expand Down Expand Up @@ -112,7 +116,7 @@ export class DrawLineStringMode extends GeoJsonEditMode {
features: []
};

let tentativeFeature;
let tentativeFeature: GuideFeature;
if (clickSequence.length > 0) {
tentativeFeature = {
type: 'Feature',
Expand Down Expand Up @@ -148,7 +152,7 @@ export class DrawLineStringMode extends GeoJsonEditMode {
return guides;
}

handlePointerMove(event: PointerMoveEvent, props: ModeProps<FeatureCollection>) {
handlePointerMove(_event: PointerMoveEvent, props: ModeProps<FeatureCollection>) {
props.onUpdateCursor('cell');
}

Expand All @@ -160,19 +164,24 @@ export class DrawLineStringMode extends GeoJsonEditMode {
getTooltips(props: ModeProps<FeatureCollection>): Tooltip[] {
return this._getTooltips({
modeConfig: props.modeConfig,
dist: this.dist
dist: this.dist,
coordinateSystem: props?.coordinateSystem
});
}

// utility function
calculateInfoDraw(clickSequence) {
calculateInfoDraw(
clickSequence: Position[],
coordinateSystem: EditModeCoordinateSystem = new GeoCoordinateSystem()
) {
// check if the selected points are at least 2
if (clickSequence.length > 1) {
// setting the last point
this.position = clickSequence[clickSequence.length - 1];
// calculate the new distance by adding the
// distance of the new drawn linestring
this.dist += distance(
const coordSys = getEditModeCoordinateSystem(coordinateSystem);
this.dist += coordSys.distance(
clickSequence[clickSequence.length - 2],
clickSequence[clickSequence.length - 1]
);
Expand All @@ -184,16 +193,20 @@ export class DrawLineStringMode extends GeoJsonEditMode {
* @param modeConfig
* @param dist
*/
_getTooltips = memoize(({modeConfig, dist}) => {
_getTooltips = memoize(({modeConfig, dist, coordinateSystem}) => {
let tooltips: Tooltip[] = [];
const {formatTooltip} = modeConfig || {};
let text;
let text: string;
if (dist) {
if (formatTooltip) {
text = formatTooltip(dist);
} else {
const coordSys = coordinateSystem
? getEditModeCoordinateSystem(coordinateSystem)
: new GeoCoordinateSystem();
const labelUnits = coordSys instanceof GeoCoordinateSystem ? 'kilometers' : 'pixels';
// By default, round to 2 decimal places and append units
text = `Distance: ${parseFloat(dist).toFixed(2)} kilometers`;
text = `Distance: ${parseFloat(dist).toFixed(2)} ${labelUnits}`;
}

tooltips = [
Expand Down
23 changes: 12 additions & 11 deletions modules/editable-layers/src/edit-modes/geojson-edit-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import {
SimpleGeometry,
Position,
SimpleFeatureCollection,
SimpleFeature
SimpleFeature,
MultiPolygon
} from '../utils/geojson-types';
import {getPickedEditHandles, getNonGuidePicks} from './utils';
import {EditMode} from './edit-mode';
Expand All @@ -52,11 +53,11 @@ export interface GeoJsonEditModeConstructor {
export class GeoJsonEditMode implements EditMode<FeatureCollection, GuideFeatureCollection> {
_clickSequence: Position[] = [];

getGuides(props: ModeProps<FeatureCollection>): GuideFeatureCollection {
getGuides(_props: ModeProps<FeatureCollection>): GuideFeatureCollection {
return DEFAULT_GUIDES;
}

getTooltips(props: ModeProps<FeatureCollection>): Tooltip[] {
getTooltips(_props: ModeProps<FeatureCollection>): Tooltip[] {
return DEFAULT_TOOLTIPS;
}

Expand Down Expand Up @@ -219,7 +220,7 @@ export class GeoJsonEditMode implements EditMode<FeatureCollection, GuideFeature
geometry: featureOrGeometryAsAny
};

let updatedGeometry;
let updatedGeometry: Feature<Polygon | MultiPolygon> | null;
if (modeConfig.booleanOperation === 'union') {
updatedGeometry = turfUnion(featureCollection([selectedFeature, feature]));
} else if (modeConfig.booleanOperation === 'difference') {
Expand Down Expand Up @@ -257,14 +258,14 @@ export class GeoJsonEditMode implements EditMode<FeatureCollection, GuideFeature
return this.getAddFeatureAction(featureOrGeometry, props.data, featureProperties);
}

createTentativeFeature(props: ModeProps<FeatureCollection>): TentativeFeature | null {
createTentativeFeature(_props: ModeProps<FeatureCollection>): TentativeFeature | null {
return null;
}

handleClick(event: ClickEvent, props: ModeProps<FeatureCollection>): void {}
handleDoubleClick(event: ClickEvent, props: ModeProps<FeatureCollection>): void {}
handleClick(_event: ClickEvent, _props: ModeProps<FeatureCollection>): void {}
handleDoubleClick(_event: ClickEvent, _props: ModeProps<FeatureCollection>): void {}

handlePointerMove(event: PointerMoveEvent, props: ModeProps<FeatureCollection>): void {
handlePointerMove(_event: PointerMoveEvent, props: ModeProps<FeatureCollection>): void {
const tentativeFeature = this.createTentativeFeature(props);
if (tentativeFeature) {
props.onEdit({
Expand All @@ -276,9 +277,9 @@ export class GeoJsonEditMode implements EditMode<FeatureCollection, GuideFeature
});
}
}
handleStartDragging(event: StartDraggingEvent, props: ModeProps<FeatureCollection>): void {}
handleStopDragging(event: StopDraggingEvent, props: ModeProps<FeatureCollection>): void {}
handleDragging(event: DraggingEvent, props: ModeProps<FeatureCollection>): void {}
handleStartDragging(_event: StartDraggingEvent, _props: ModeProps<FeatureCollection>): void {}
handleStopDragging(_event: StopDraggingEvent, _props: ModeProps<FeatureCollection>): void {}
handleDragging(_event: DraggingEvent, _props: ModeProps<FeatureCollection>): void {}

handleKeyUp(event: KeyboardEvent, props: ModeProps<FeatureCollection>): void {
if (event.key === 'Escape') {
Expand Down
11 changes: 7 additions & 4 deletions modules/editable-layers/src/edit-modes/modify-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
} from './types';
import {GeoJsonEditMode} from './geojson-edit-mode';
import {ImmutableFeatureCollection} from './immutable-feature-collection';
import {EditModeCoordinateSystem} from './coordinate-system';

export class ModifyMode extends GeoJsonEditMode {
// eslint-disable-next-line complexity
Expand Down Expand Up @@ -85,7 +86,8 @@ export class ModifyMode extends GeoJsonEditMode {
const candidateIntermediatePoint = this.getNearestPoint(
lineStringFeature,
referencePoint,
props.modeConfig && props.modeConfig.viewport
props.modeConfig && props.modeConfig.viewport,
props.coordinateSystem
);
if (
!intermediatePoint ||
Expand Down Expand Up @@ -129,20 +131,21 @@ export class ModifyMode extends GeoJsonEditMode {
getNearestPoint(
line: Feature<LineString>,
inPoint: Feature<Point>,
viewport: Viewport | null | undefined
viewport: Viewport | null | undefined,
coordinateSystem?: EditModeCoordinateSystem
): NearestPointType {
const {coordinates} = line.geometry;
if (coordinates.some((coord) => coord.length > 2)) {
if (viewport) {
// This line has elevation, we need to use alternative algorithm
return nearestPointOnProjectedLine(line, inPoint, viewport);
return nearestPointOnProjectedLine(line, inPoint, viewport, coordinateSystem);
}
// eslint-disable-next-line no-console,no-undef
console.log(
'Editing 3D point but modeConfig.viewport not provided. Falling back to 2D logic.'
);
}
return nearestPointOnLine(line, inPoint, viewport);
return nearestPointOnLine(line, inPoint, viewport, coordinateSystem);
}

handleClick(event: ClickEvent, props: ModeProps<SimpleFeatureCollection>) {
Expand Down
6 changes: 6 additions & 0 deletions modules/editable-layers/src/edit-modes/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,9 @@ export type ModeProps<TData> = {
// Callback used to update cursor
onUpdateCursor: (cursor: string | null | undefined) => void;
};

export type PointWithIndex = {
index: number;
x0: number;
y0: number;
};
Loading