projects/angular-cesium/src/lib/angular-cesium-widgets/models/editable-polyline.ts
Properties |
|
Methods |
|
Accessors |
constructor(id: string, pointsLayer: AcLayerComponent, polylinesLayer: AcLayerComponent, coordinateConverter: CoordinateConverter, scene: any, editOptions: PolylineEditOptions, positions?: Cartesian3[])
|
||||||||||||||||||||||||
Parameters :
|
Private _enableEdit |
_enableEdit:
|
Default value : true
|
Private _labels |
_labels:
|
Type : LabelProps[]
|
Default value : []
|
Private _outlineInstance |
_outlineInstance:
|
Type : null
|
Default value : null
|
Private _pointProps |
_pointProps:
|
Type : PointProps
|
Private doneCreation |
doneCreation:
|
Default value : false
|
Private lastDraggedToPosition |
lastDraggedToPosition:
|
Type : any
|
Private movingPoint |
movingPoint:
|
Type : EditPoint
|
Private polylineProps |
polylineProps:
|
Type : PolylineProps
|
Private polylines |
polylines:
|
Type : EditPolyline[]
|
Default value : []
|
Private positions |
positions:
|
Type : EditPoint[]
|
Default value : []
|
Private addAllVirtualEditPoints |
addAllVirtualEditPoints()
|
Returns :
void
|
addLastPoint | ||||||
addLastPoint(position: Cartesian3)
|
||||||
Parameters :
Returns :
void
|
addPoint | ||||||
addPoint(position: Cartesian3)
|
||||||
Parameters :
Returns :
void
|
addPointFromExisting | ||||||
addPointFromExisting(position: Cartesian3)
|
||||||
Parameters :
Returns :
void
|
changeVirtualPointToRealPoint | ||||||
changeVirtualPointToRealPoint(point: EditPoint)
|
||||||
Parameters :
Returns :
void
|
Private createFromExisting | ||||||
createFromExisting(positions: Cartesian3[])
|
||||||
Parameters :
Returns :
void
|
dispose |
dispose()
|
Returns :
void
|
endMoveShape |
endMoveShape()
|
Returns :
void
|
getId |
getId()
|
Returns :
string
|
getPoints |
getPoints()
|
Returns :
EditPoint[]
|
getPointsCount |
getPointsCount()
|
Returns :
number
|
getPositions |
getPositions()
|
Returns :
Cartesian3[]
|
getPositionsCallbackProperty |
getPositionsCallbackProperty()
|
Returns :
Cartesian3[]
|
getRealPoints |
getRealPoints()
|
Returns :
EditPoint[]
|
getRealPositions |
getRealPositions()
|
Returns :
Cartesian3[]
|
movePoint | |||||||||
movePoint(toPosition: Cartesian3, editPoint: EditPoint)
|
|||||||||
Parameters :
Returns :
void
|
movePointFinish | ||||||
movePointFinish(editPoint: EditPoint)
|
||||||
Parameters :
Returns :
void
|
moveShape | |||||||||
moveShape(startMovingPosition: Cartesian3, draggedToPosition: Cartesian3)
|
|||||||||
Parameters :
Returns :
void
|
moveTempMovingPoint | ||||||
moveTempMovingPoint(toPosition: Cartesian3)
|
||||||
Parameters :
Returns :
void
|
removePoint | ||||||
removePoint(pointToRemove: EditPoint)
|
||||||
Parameters :
Returns :
void
|
Private removePosition | ||||||
removePosition(point: EditPoint)
|
||||||
Parameters :
Returns :
void
|
Private renderPolylines |
renderPolylines()
|
Returns :
void
|
setManually | |||||||||
setManually(points: literal type[] | Cartesian3[], polylineProps?: PolylineProps)
|
|||||||||
Parameters :
Returns :
void
|
Private setMiddleVirtualPoint |
setMiddleVirtualPoint(firstP: EditPoint, secondP: EditPoint)
|
Returns :
EditPoint
|
update |
update()
|
Returns :
void
|
Private updateMiddleVirtualPoint | ||||||||||||
updateMiddleVirtualPoint(virtualEditPoint: EditPoint, prevPoint: EditPoint, nextPoint: EditPoint)
|
||||||||||||
Parameters :
Returns :
void
|
Private updatePointsLayer | ||||||||||||
updatePointsLayer(renderPolylines, point: EditPoint[])
|
||||||||||||
Parameters :
Returns :
void
|
Static create | ||||||||
create(json?: any)
|
||||||||
Inherited from
AcEntity
|
||||||||
Defined in AcEntity:18
|
||||||||
Creates entity from a json
Parameters :
Returns :
any
entity as AcEntity |
labels | ||||||
getlabels()
|
||||||
setlabels(labels: [])
|
||||||
Parameters :
Returns :
void
|
props | ||||
getprops()
|
||||
setprops(value)
|
||||
Parameters :
Returns :
void
|
pointProps | ||||
getpointProps()
|
||||
setpointProps(value)
|
||||
Parameters :
Returns :
void
|
enableEdit | ||||||
getenableEdit()
|
||||||
setenableEdit(value: boolean)
|
||||||
Parameters :
Returns :
void
|
import { AcEntity } from '../../angular-cesium/models/ac-entity';
import { EditPoint } from './edit-point';
import { EditPolyline } from './edit-polyline';
import { AcLayerComponent } from '../../angular-cesium/components/ac-layer/ac-layer.component';
import { Cartesian3 } from '../../angular-cesium/models/cartesian3';
import { CoordinateConverter } from '../../angular-cesium/services/coordinate-converter/coordinate-converter.service';
import { PointProps } from './point-edit-options';
import { PolylineEditOptions, PolylineProps } from './polyline-edit-options';
import { GeoUtilsService } from '../../angular-cesium/services/geo-utils/geo-utils.service';
import { defaultLabelProps, LabelProps } from './label-props';
export class EditablePolyline extends AcEntity {
private positions: EditPoint[] = [];
private polylines: EditPolyline[] = [];
private movingPoint: EditPoint;
private doneCreation = false;
private _enableEdit = true;
private _pointProps: PointProps;
private polylineProps: PolylineProps;
private lastDraggedToPosition: any;
private _labels: LabelProps[] = [];
private _outlineInstance = null;
constructor(private id: string,
private pointsLayer: AcLayerComponent,
private polylinesLayer: AcLayerComponent,
private coordinateConverter: CoordinateConverter,
private scene: any,
private editOptions: PolylineEditOptions,
positions?: Cartesian3[]) {
super();
this._pointProps = {...editOptions.pointProps};
this.props = {...editOptions.polylineProps};
if (positions && positions.length >= 2) {
this.createFromExisting(positions);
}
}
get labels(): LabelProps[] {
return this._labels;
}
set labels(labels: LabelProps[]) {
if (!labels) {
return;
}
const positions = this.getRealPositions();
this._labels = labels.map((label, index) => {
if (!label.position) {
label.position = positions[index];
}
return Object.assign({}, defaultLabelProps, label);
});
}
get props(): PolylineProps {
return this.polylineProps;
}
set props(value: PolylineProps) {
this.polylineProps = value;
}
get pointProps(): PointProps {
return this._pointProps;
}
set pointProps(value: PointProps) {
this._pointProps = value;
}
get enableEdit() {
return this._enableEdit;
}
set enableEdit(value: boolean) {
this._enableEdit = value;
this.positions.forEach(point => {
point.show = value;
this.updatePointsLayer(false, point);
});
}
private createFromExisting(positions: Cartesian3[]) {
positions.forEach((position) => {
this.addPointFromExisting(position);
});
this.addAllVirtualEditPoints();
this.doneCreation = true;
}
setManually(points: {
position: Cartesian3,
pointProp?: PointProps
}[] | Cartesian3[], polylineProps?: PolylineProps) {
if (!this.doneCreation) {
throw new Error('Update manually only in edit mode, after polyline is created');
}
this.positions.forEach(p => this.pointsLayer.remove(p.getId()));
const newPoints: EditPoint[] = [];
for (let i = 0; i < points.length; i++) {
const pointOrCartesian: any = points[i];
let newPoint = null;
if (pointOrCartesian.pointProps) {
newPoint = new EditPoint(this.id, pointOrCartesian.position, pointOrCartesian.pointProps);
} else {
newPoint = new EditPoint(this.id, pointOrCartesian, this._pointProps);
}
newPoints.push(newPoint);
}
this.positions = newPoints;
this.polylineProps = polylineProps ? polylineProps : this.polylineProps;
this.updatePointsLayer(true, ...this.positions);
this.addAllVirtualEditPoints();
}
private addAllVirtualEditPoints() {
const currentPoints = [...this.positions];
currentPoints.forEach((pos, index) => {
if (index !== currentPoints.length - 1) {
const currentPoint = pos;
const nextIndex = (index + 1) % (currentPoints.length);
const nextPoint = currentPoints[nextIndex];
const midPoint = this.setMiddleVirtualPoint(currentPoint, nextPoint);
this.updatePointsLayer(false, midPoint);
}
});
}
private setMiddleVirtualPoint(firstP: EditPoint, secondP: EditPoint): EditPoint {
const midPointCartesian3 = Cesium.Cartesian3.lerp(firstP.getPosition(), secondP.getPosition(), 0.5, new Cesium.Cartesian3());
const midPoint = new EditPoint(this.id, midPointCartesian3, this._pointProps);
midPoint.setVirtualEditPoint(true);
const firstIndex = this.positions.indexOf(firstP);
this.positions.splice(firstIndex + 1, 0, midPoint);
return midPoint;
}
private updateMiddleVirtualPoint(virtualEditPoint: EditPoint, prevPoint: EditPoint, nextPoint: EditPoint) {
const midPointCartesian3 = Cesium.Cartesian3.lerp(prevPoint.getPosition(), nextPoint.getPosition(), 0.5, new Cesium.Cartesian3());
virtualEditPoint.setPosition(midPointCartesian3);
}
changeVirtualPointToRealPoint(point: EditPoint) {
point.setVirtualEditPoint(false); // actual point becomes a real point
const pointsCount = this.positions.length;
const pointIndex = this.positions.indexOf(point);
const nextIndex = (pointIndex + 1) % (pointsCount);
const preIndex = ((pointIndex - 1) + pointsCount) % pointsCount;
const nextPoint = this.positions[nextIndex];
const prePoint = this.positions[preIndex];
const firstMidPoint = this.setMiddleVirtualPoint(prePoint, point);
const secMidPoint = this.setMiddleVirtualPoint(point, nextPoint);
this.updatePointsLayer(false, firstMidPoint, secMidPoint, point);
}
private renderPolylines() {
const realPoints = this.positions.filter(point => !point.isVirtualEditPoint());
if (this.polylineProps.useGroundPrimitiveOutline) {
if (realPoints.length < 2) {
return;
}
this.scene.groundPrimitives.remove(this._outlineInstance);
const instance = new Cesium.GeometryInstance({
geometry: new Cesium.GroundPolylineGeometry({
positions: this.positions.map(p => p.getPosition()),
width: this.polylineProps.width,
loop: false
}),
id: 'edit-polygon-outline-' + this.id,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(this.polylineProps.material())
}
});
this._outlineInstance = this.scene.groundPrimitives.add(
new Cesium.GroundPolylinePrimitive({
geometryInstances: instance,
asynchronous: false,
appearance: new Cesium.PolylineColorAppearance()
})
);
} else {
this.polylines.forEach(polyline => this.polylinesLayer.remove(polyline.getId()));
this.polylines = [];
realPoints.forEach((point, index) => {
if (index !== realPoints.length - 1) {
const nextIndex = (index + 1);
const nextPoint = realPoints[nextIndex];
const polyline = new EditPolyline(this.id, point.getPosition(), nextPoint.getPosition(), this.polylineProps);
this.polylines.push(polyline);
this.polylinesLayer.update(polyline, polyline.getId());
}
});
}
}
addPointFromExisting(position: Cartesian3) {
const newPoint = new EditPoint(this.id, position, this._pointProps);
this.positions.push(newPoint);
this.updatePointsLayer(true, newPoint);
}
addPoint(position: Cartesian3) {
if (this.doneCreation) {
return;
}
const isFirstPoint = !this.positions.length;
if (isFirstPoint) {
const firstPoint = new EditPoint(this.id, position, this._pointProps);
this.positions.push(firstPoint);
this.updatePointsLayer(true, firstPoint);
}
this.movingPoint = new EditPoint(this.id, position.clone(), this._pointProps);
this.positions.push(this.movingPoint);
this.updatePointsLayer(true, this.movingPoint);
}
movePointFinish(editPoint: EditPoint) {
if (this.editOptions.clampHeightTo3D) {
editPoint.props.disableDepthTestDistance = Number.POSITIVE_INFINITY;
this.updatePointsLayer(false, editPoint);
}
}
movePoint(toPosition: Cartesian3, editPoint: EditPoint) {
editPoint.setPosition(toPosition);
if (this.doneCreation) {
if (editPoint.props.disableDepthTestDistance && this.editOptions.clampHeightTo3D) {
// To avoid bug with pickPosition() on point with disableDepthTestDistance
editPoint.props.disableDepthTestDistance = undefined;
return; // ignore first move because the pickPosition() could be wrong
}
if (editPoint.isVirtualEditPoint()) {
this.changeVirtualPointToRealPoint(editPoint);
}
const pointsCount = this.positions.length;
const pointIndex = this.positions.indexOf(editPoint);
if (pointIndex < this.positions.length - 1) {
const nextVirtualPoint = this.positions[(pointIndex + 1) % (pointsCount)];
const nextRealPoint = this.positions[(pointIndex + 2) % (pointsCount)];
this.updateMiddleVirtualPoint(nextVirtualPoint, editPoint, nextRealPoint);
}
if (pointIndex > 0) {
const prevVirtualPoint = this.positions[((pointIndex - 1) + pointsCount) % pointsCount];
const prevRealPoint = this.positions[((pointIndex - 2) + pointsCount) % pointsCount];
this.updateMiddleVirtualPoint(prevVirtualPoint, editPoint, prevRealPoint);
}
}
this.updatePointsLayer(true, editPoint);
}
moveTempMovingPoint(toPosition: Cartesian3) {
if (this.movingPoint) {
this.movePoint(toPosition, this.movingPoint);
}
}
moveShape(startMovingPosition: Cartesian3, draggedToPosition: Cartesian3) {
if (!this.doneCreation) {
return;
}
if (!this.lastDraggedToPosition) {
this.lastDraggedToPosition = startMovingPosition;
}
const delta = GeoUtilsService.getPositionsDelta(this.lastDraggedToPosition, draggedToPosition);
this.positions.forEach(point => {
const newPos = GeoUtilsService.addDeltaToPosition(point.getPosition(), delta, true);
point.setPosition(newPos);
});
this.updatePointsLayer(true, ...this.positions);
this.lastDraggedToPosition = draggedToPosition;
}
endMoveShape() {
this.lastDraggedToPosition = undefined;
this.updatePointsLayer(true, ...this.positions);
}
removePoint(pointToRemove: EditPoint) {
this.removePosition(pointToRemove);
this.positions
.filter(p => p.isVirtualEditPoint())
.forEach(p => this.removePosition(p));
this.addAllVirtualEditPoints();
this.renderPolylines();
}
addLastPoint(position: Cartesian3) {
this.doneCreation = true;
this.removePosition(this.movingPoint); // remove movingPoint
this.movingPoint = null;
this.addAllVirtualEditPoints();
}
getRealPositions(): Cartesian3[] {
return this.getRealPoints()
.map(position => position.getPosition());
}
getRealPoints(): EditPoint[] {
return this.positions
.filter(position => !position.isVirtualEditPoint() && position !== this.movingPoint);
}
getPoints(): EditPoint[] {
return this.positions.filter(position => position !== this.movingPoint);
}
getPositions(): Cartesian3[] {
return this.positions.map(position => position.getPosition());
}
getPositionsCallbackProperty(): Cartesian3[] {
return new Cesium.CallbackProperty(this.getPositions.bind(this), false);
}
private removePosition(point: EditPoint) {
const index = this.positions.findIndex((p) => p === point);
if (index < 0) {
return;
}
this.positions.splice(index, 1);
this.pointsLayer.remove(point.getId());
}
private updatePointsLayer(renderPolylines = true, ...point: EditPoint[]) {
if (renderPolylines) {
this.renderPolylines();
}
point.forEach(p => this.pointsLayer.update(p, p.getId()));
}
update() {
this.updatePointsLayer();
}
dispose() {
this.scene.groundPrimitives.remove(this._outlineInstance);
this.positions.forEach(editPoint => {
this.pointsLayer.remove(editPoint.getId());
});
this.polylines.forEach(line => this.polylinesLayer.remove(line.getId()));
if (this.movingPoint) {
this.pointsLayer.remove(this.movingPoint.getId());
this.movingPoint = undefined;
}
this.positions.length = 0;
}
getPointsCount(): number {
return this.positions.length;
}
getId() {
return this.id;
}
}