@nebula.gl/layers
Version:
A suite of 3D-enabled data editing layers, suitable for deck.gl
109 lines (90 loc) • 3.26 kB
text/typescript
import turfBearing from '@turf/bearing';
import turfDistance from '@turf/distance';
import turfTransformTranslate from '@turf/transform-translate';
import { point } from '@turf/helpers';
import { FeatureCollection, Position } from '@nebula.gl/edit-modes';
import { PointerMoveEvent, StartDraggingEvent, StopDraggingEvent } from '../event-types';
import { EditAction, ModeHandler } from './mode-handler';
// TODO edit-modes: delete handlers once EditMode fully implemented
export class TranslateHandler extends ModeHandler {
_geometryBeforeTranslate: FeatureCollection | null | undefined;
_isTranslatable: boolean;
handlePointerMove(
event: PointerMoveEvent
): { editAction: EditAction | null | undefined; cancelMapPan: boolean } {
let editAction: EditAction | null | undefined = null;
this._isTranslatable =
Boolean(this._geometryBeforeTranslate) || this.isSelectionPicked(event.picks);
if (!this._isTranslatable || !event.pointerDownGroundCoords) {
// Nothing to do
return { editAction: null, cancelMapPan: false };
}
if (event.isDragging && this._geometryBeforeTranslate) {
// Translate the geometry
editAction = this.getTranslateAction(
event.pointerDownGroundCoords,
event.groundCoords,
'translating'
);
}
return { editAction, cancelMapPan: true };
}
handleStartDragging(event: StartDraggingEvent): EditAction | null | undefined {
if (!this._isTranslatable) {
return null;
}
this._geometryBeforeTranslate = this.getSelectedFeaturesAsFeatureCollection();
return null;
}
handleStopDragging(event: StopDraggingEvent): EditAction | null | undefined {
let editAction: EditAction | null | undefined = null;
if (this._geometryBeforeTranslate) {
// Translate the geometry
editAction = this.getTranslateAction(
event.pointerDownGroundCoords,
event.groundCoords,
'translated'
);
this._geometryBeforeTranslate = null;
}
return editAction;
}
getCursor({ isDragging }: { isDragging: boolean }): string {
if (this._isTranslatable) {
return 'move';
}
return isDragging ? 'grabbing' : 'grab';
}
getTranslateAction(
startDragPoint: Position,
currentPoint: Position,
editType: string
): EditAction | null | undefined {
if (!this._geometryBeforeTranslate) {
return null;
}
const p1 = point(startDragPoint);
const p2 = point(currentPoint);
const distanceMoved = turfDistance(p1, p2);
const direction = turfBearing(p1, p2);
const movedFeatures = turfTransformTranslate(
// @ts-ignore
this._geometryBeforeTranslate,
distanceMoved,
direction
);
let updatedData = this.getImmutableFeatureCollection();
const selectedIndexes = this.getSelectedFeatureIndexes();
for (let i = 0; i < selectedIndexes.length; i++) {
const selectedIndex = selectedIndexes[i];
const movedFeature = movedFeatures.features[i];
updatedData = updatedData.replaceGeometry(selectedIndex, movedFeature.geometry);
}
return {
updatedData: updatedData.getObject(),
editType,
featureIndexes: selectedIndexes,
editContext: null,
};
}
}