diff --git a/debug/tags.html b/debug/tags.html
index 3fe0db70..70291a2e 100644
--- a/debug/tags.html
+++ b/debug/tags.html
@@ -14,6 +14,7 @@
+
@@ -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);
}
diff --git a/src/component/tag/TagComponent.ts b/src/component/tag/TagComponent.ts
index 62545a14..eca36484 100644
--- a/src/component/tag/TagComponent.ts
+++ b/src/component/tag/TagComponent.ts
@@ -12,6 +12,8 @@ import {
ITagConfiguration,
PointGeometry,
OutlineCreateTag,
+ PolygonGeometry,
+ RectGeometry,
Tag,
TagCreator,
TagDOMRenderer,
@@ -413,7 +415,8 @@ export class TagComponent extends Component {
.flatMapLatest(
(configuration: ITagConfiguration): rx.Observable => {
return configuration.creating &&
- configuration.createType === "rect" ?
+ configuration.createType === "rect" ||
+ configuration.createType === "polygon" ?
this._validBasicClick$.take(1) :
rx.Observable.empty();
})
@@ -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((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];
diff --git a/src/component/tag/TagCreator.ts b/src/component/tag/TagCreator.ts
index 7e60c5f7..e33f7c07 100644
--- a/src/component/tag/TagCreator.ts
+++ b/src/component/tag/TagCreator.ts
@@ -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);
}
diff --git a/src/component/tag/tag/OutlineCreateTag.ts b/src/component/tag/tag/OutlineCreateTag.ts
index 8f8fd284..6d7cd434 100644
--- a/src/component/tag/tag/OutlineCreateTag.ts
+++ b/src/component/tag/tag/OutlineCreateTag.ts
@@ -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 = 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 = this._geometry;
+ if (this._geometry instanceof RectGeometry) {
+ let 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 = this._geometry;
+
+ polygonGeometry.addVertex2d(point);
}
-
- this._created$.onNext(this);
}
private _getPositions(polygon3d: number[][]): Float32Array {
diff --git a/styles/TagComponent.css b/styles/TagComponent.css
index d5c0e182..15ccae18 100644
--- a/styles/TagComponent.css
+++ b/styles/TagComponent.css
@@ -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;
}