mirror of
https://github.com/mapillary/mapillary-js.git
synced 2026-01-25 14:07:28 +00:00
Create polygon tags.
Add support for creating new polygons. Remove last vertex by clicking it. Abort creation by clicking original vertext when fewer than 4. Complete polygon by clicking original vertex.
This commit is contained in:
parent
f9f54fb17c
commit
99c7dd85ce
@ -14,6 +14,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id='viewer'></div>
|
||||
<button onclick="createGeometry('polygon')">Create polygon</button>
|
||||
<button onclick="createGeometry('rect')">Create rectangle</button>
|
||||
<button onclick="createGeometry('point')">Create point</button>
|
||||
<button onclick="stopCreate()">Stop create</button>
|
||||
@ -79,14 +80,14 @@
|
||||
|
||||
var createdIndex = 0;
|
||||
|
||||
function createOutlineTag(geometry) {
|
||||
function createOutlineTag(geometry, text) {
|
||||
createdIndex += 1;
|
||||
var id = "created" + createdIndex;
|
||||
var options = {
|
||||
editable: true,
|
||||
lineColor: 0x00FFFF,
|
||||
lineWidth: 1,
|
||||
text: "Rectangle",
|
||||
text: text,
|
||||
textColor: 0x00FFFF,
|
||||
};
|
||||
|
||||
@ -114,7 +115,9 @@
|
||||
|
||||
tagComponent.on(Mapillary.TagComponent.TagComponent.geometrycreated, function(geometry) {
|
||||
if (geometry instanceof Mapillary.TagComponent.RectGeometry) {
|
||||
createOutlineTag(geometry);
|
||||
createOutlineTag(geometry, "Rectangle");
|
||||
} else if (geometry instanceof Mapillary.TagComponent.PolygonGeometry) {
|
||||
createOutlineTag(geometry, "Polygon");
|
||||
} else if (geometry instanceof Mapillary.TagComponent.PointGeometry) {
|
||||
createSpotTag(geometry);
|
||||
}
|
||||
|
||||
@ -12,6 +12,8 @@ import {
|
||||
ITagConfiguration,
|
||||
PointGeometry,
|
||||
OutlineCreateTag,
|
||||
PolygonGeometry,
|
||||
RectGeometry,
|
||||
Tag,
|
||||
TagCreator,
|
||||
TagDOMRenderer,
|
||||
@ -413,7 +415,8 @@ export class TagComponent extends Component {
|
||||
.flatMapLatest<number[]>(
|
||||
(configuration: ITagConfiguration): rx.Observable<number[]> => {
|
||||
return configuration.creating &&
|
||||
configuration.createType === "rect" ?
|
||||
configuration.createType === "rect" ||
|
||||
configuration.createType === "polygon" ?
|
||||
this._validBasicClick$.take(1) :
|
||||
rx.Observable.empty<number[]>();
|
||||
})
|
||||
@ -468,7 +471,11 @@ export class TagComponent extends Component {
|
||||
camera,
|
||||
transform);
|
||||
|
||||
tag.geometry.setVertex2d(3, basic, transform);
|
||||
if (tag.geometry instanceof RectGeometry) {
|
||||
tag.geometry.setVertex2d(3, basic, transform);
|
||||
} else if (tag.geometry instanceof PolygonGeometry) {
|
||||
tag.geometry.setVertex2d((<PolygonGeometry>tag.geometry).polygon.length - 2, basic, transform);
|
||||
}
|
||||
});
|
||||
|
||||
this._addPointSubscription = this._creating$
|
||||
@ -621,7 +628,7 @@ export class TagComponent extends Component {
|
||||
this._container.spriteService.spriteAtlas$,
|
||||
this._tags$.startWith([]),
|
||||
this._tagChanged$.startWith(null),
|
||||
this._tagCreator.tag$.startWith(null),
|
||||
this._tagCreator.tag$.merge(this._createGeometryChanged$).startWith(null),
|
||||
(rc: RenderCamera, atlas: ISpriteAtlas, tags: Tag[], tag: Tag, createTag: OutlineCreateTag):
|
||||
[RenderCamera, ISpriteAtlas, Tag[], Tag, OutlineCreateTag] => {
|
||||
return [rc, atlas, tags, tag, createTag];
|
||||
|
||||
@ -5,6 +5,7 @@ import * as rx from "rx";
|
||||
import {
|
||||
GeometryType,
|
||||
OutlineCreateTag,
|
||||
PolygonGeometry,
|
||||
RectGeometry,
|
||||
} from "../../Component";
|
||||
|
||||
@ -56,6 +57,14 @@ export class TagCreator {
|
||||
coordinate[1],
|
||||
]);
|
||||
|
||||
return new OutlineCreateTag(geometry);
|
||||
} else if (type === "polygon") {
|
||||
let geometry: PolygonGeometry = new PolygonGeometry([
|
||||
[coordinate[0], coordinate[1]],
|
||||
[coordinate[0], coordinate[1]],
|
||||
[coordinate[0], coordinate[1]],
|
||||
]);
|
||||
|
||||
return new OutlineCreateTag(geometry);
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,11 @@ import * as rx from "rx";
|
||||
import * as THREE from "three";
|
||||
import * as vd from "virtual-dom";
|
||||
|
||||
import {VertexGeometry, RectGeometry} from "../../../Component";
|
||||
import {
|
||||
PolygonGeometry,
|
||||
RectGeometry,
|
||||
VertexGeometry,
|
||||
} from "../../../Component";
|
||||
import {Transform} from "../../../Geo";
|
||||
|
||||
export class OutlineCreateTag {
|
||||
@ -64,41 +68,117 @@ export class OutlineCreateTag {
|
||||
vd.VNode[] {
|
||||
|
||||
let vNodes: vd.VNode[] = [];
|
||||
let polygonPoints3d: number[][] = this._geometry.getVertices3d(transform);
|
||||
|
||||
let abort: (e: MouseEvent) => void = (e: MouseEvent): void => {
|
||||
e.stopPropagation();
|
||||
this._aborted$.onNext(this);
|
||||
};
|
||||
|
||||
let topLeftCameraSpace: THREE.Vector3 = this._convertToCameraSpace(polygonPoints3d[1], matrixWorldInverse);
|
||||
if (topLeftCameraSpace.z < 0) {
|
||||
let centerCanvas: number[] = this._projectToCanvas(topLeftCameraSpace, projectionMatrix);
|
||||
let centerCss: string[] = centerCanvas.map((coord: number): string => { return (100 * coord) + "%"; });
|
||||
if (this._geometry instanceof RectGeometry) {
|
||||
let topLeftPoint3d: number[] = this._geometry.getVertex3d(1, transform);
|
||||
|
||||
let pointProperties: vd.createProperties = {
|
||||
style: { background: "#FFFFFF", left: centerCss[0], position: "absolute", top: centerCss[1] },
|
||||
};
|
||||
let topLeftCameraSpace: THREE.Vector3 = this._convertToCameraSpace(topLeftPoint3d, matrixWorldInverse);
|
||||
if (topLeftCameraSpace.z < 0) {
|
||||
let centerCanvas: number[] = this._projectToCanvas(topLeftCameraSpace, projectionMatrix);
|
||||
let centerCss: string[] = centerCanvas.map((coord: number): string => { return (100 * coord) + "%"; });
|
||||
|
||||
let completerProperties: vd.createProperties = {
|
||||
onclick: abort,
|
||||
style: { left: centerCss[0], position: "absolute", top: centerCss[1] },
|
||||
};
|
||||
let pointProperties: vd.createProperties = {
|
||||
style: { background: "#FFFFFF", left: centerCss[0], position: "absolute", top: centerCss[1] },
|
||||
};
|
||||
|
||||
vNodes.push(vd.h("div.TagInteractor", completerProperties, []));
|
||||
vNodes.push(vd.h("div.TagVertex", pointProperties, []));
|
||||
let completerProperties: vd.createProperties = {
|
||||
onclick: abort,
|
||||
style: { left: centerCss[0], position: "absolute", top: centerCss[1] },
|
||||
};
|
||||
|
||||
vNodes.push(vd.h("div.TagInteractor", completerProperties, []));
|
||||
vNodes.push(vd.h("div.TagVertex", pointProperties, []));
|
||||
}
|
||||
} else if (this._geometry instanceof PolygonGeometry) {
|
||||
let polygonGeometry: PolygonGeometry = <PolygonGeometry>this._geometry;
|
||||
|
||||
if (polygonGeometry.polygon.length > 3) {
|
||||
let lastVertex3d: number[] = this._geometry.getVertex3d(polygonGeometry.polygon.length - 3, transform);
|
||||
|
||||
let lastCameraSpace: THREE.Vector3 = this._convertToCameraSpace(lastVertex3d, matrixWorldInverse);
|
||||
if (lastCameraSpace.z < 0) {
|
||||
let centerCanvas: number[] = this._projectToCanvas(lastCameraSpace, projectionMatrix);
|
||||
let centerCss: string[] = centerCanvas.map((coord: number): string => { return (100 * coord) + "%"; });
|
||||
|
||||
let remove: (e: MouseEvent) => void = (e: MouseEvent): void => {
|
||||
e.stopPropagation();
|
||||
polygonGeometry.removeVertex2d(polygonGeometry.polygon.length - 3);
|
||||
};
|
||||
|
||||
let completerProperties: vd.createProperties = {
|
||||
onclick: remove,
|
||||
style: { left: centerCss[0], position: "absolute", top: centerCss[1] },
|
||||
};
|
||||
|
||||
vNodes.push(vd.h("div.TagInteractor", completerProperties, []));
|
||||
}
|
||||
}
|
||||
|
||||
let firstVertex3d: number[] = this._geometry.getVertex3d(0, transform);
|
||||
let firstCameraSpace: THREE.Vector3 = this._convertToCameraSpace(firstVertex3d, matrixWorldInverse);
|
||||
if (firstCameraSpace.z < 0) {
|
||||
let centerCanvas: number[] = this._projectToCanvas(firstCameraSpace, projectionMatrix);
|
||||
let centerCss: string[] = centerCanvas.map((coord: number): string => { return (100 * coord) + "%"; });
|
||||
|
||||
let firstOnclick: (e: MouseEvent) => void = polygonGeometry.polygon.length > 4 ?
|
||||
(e: MouseEvent): void => {
|
||||
e.stopPropagation();
|
||||
polygonGeometry.removeVertex2d(polygonGeometry.polygon.length - 2);
|
||||
this._created$.onNext(this);
|
||||
} :
|
||||
abort;
|
||||
|
||||
let completerProperties: vd.createProperties = {
|
||||
onclick: firstOnclick,
|
||||
style: { left: centerCss[0], position: "absolute", top: centerCss[1] },
|
||||
};
|
||||
|
||||
let firstClass: string = polygonGeometry.polygon.length > 4 ?
|
||||
"TagCompleter" :
|
||||
"TagInteractor";
|
||||
|
||||
vNodes.push(vd.h("div." + firstClass, completerProperties, []));
|
||||
}
|
||||
|
||||
let vertices3d: number[][] = this._geometry.getVertices3d(transform);
|
||||
vertices3d.splice(-2, 2);
|
||||
|
||||
for (let vertex of vertices3d) {
|
||||
let vertexCameraSpace: THREE.Vector3 = this._convertToCameraSpace(vertex, matrixWorldInverse);
|
||||
if (vertexCameraSpace.z < 0) {
|
||||
let centerCanvas: number[] = this._projectToCanvas(vertexCameraSpace, projectionMatrix);
|
||||
let centerCss: string[] = centerCanvas.map((coord: number): string => { return (100 * coord) + "%"; });
|
||||
|
||||
let pointProperties: vd.createProperties = {
|
||||
style: { background: "#FFFFFF", left: centerCss[0], position: "absolute", top: centerCss[1] },
|
||||
};
|
||||
|
||||
vNodes.push(vd.h("div.TagVertex", pointProperties, []));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
public addPoint(point: number[]): void {
|
||||
let rectGeometry: RectGeometry = <RectGeometry>this._geometry;
|
||||
if (this._geometry instanceof RectGeometry) {
|
||||
let rectGeometry: RectGeometry = <RectGeometry>this._geometry;
|
||||
|
||||
if (!rectGeometry.validate(point)) {
|
||||
return;
|
||||
if (!rectGeometry.validate(point)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._created$.onNext(this);
|
||||
} else if (this._geometry instanceof PolygonGeometry) {
|
||||
let polygonGeometry: PolygonGeometry = <PolygonGeometry>this._geometry;
|
||||
|
||||
polygonGeometry.addVertex2d(point);
|
||||
}
|
||||
|
||||
this._created$.onNext(this);
|
||||
}
|
||||
|
||||
private _getPositions(polygon3d: number[][]): Float32Array {
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
}
|
||||
|
||||
.TagInteractor,
|
||||
.TagCompleter,
|
||||
.TagSpotInteractor {
|
||||
transform: translate(-50%, -50%);
|
||||
pointer-events: all;
|
||||
@ -58,10 +59,15 @@
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.TagCompleter {
|
||||
background: limegreen;
|
||||
}
|
||||
|
||||
.TagInteractor {
|
||||
background: orangered;
|
||||
}
|
||||
|
||||
.TagCompleter:hover,
|
||||
.TagInteractor:hover {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user