feat: compact cluster contract

This commit is contained in:
Oscar Lorentzon 2022-08-03 17:50:33 -07:00
parent 3045b646d2
commit 052d0ec26f
9 changed files with 93 additions and 80 deletions

View File

@ -230,23 +230,6 @@ export interface LngLatAlt extends LngLat {
*/
alt: number;
}
/**
* Contract describing a reconstruction point.
*/
export interface PointContract {
/**
* RGB color vector of the point, normalized to floats
* on the interval [0, 1];
*/
color: number[];
/**
* Coordinates in metric scale in topocentric ENU
* reference frame with respect to a geo reference.
*/
coordinates: number[];
}
/**
* Contract describing cluster reconstruction data.
*/
@ -257,12 +240,32 @@ export interface ClusterContract {
id: string;
/**
* The points of the reconstruction.
* The IDs of the points.
* @description The order of the IDs correspond with the order
* of the color and coordinate arrays.
*/
points: {
[pointId: string]: PointContract,
...
};
pointIds: string[];
/**
* The colors of the reconstruction.
* @description The colors are represented as RGB values
* normalized to floats on the interval [0, 1].
*
* Colors are ordered according to the point IDs in
* a flattened array.
*/
colors: number[];
/**
* The points of the reconstruction.
* @description The points are represented in local topocentric
* ENU coordinates in metric scale relative to the cluster
* reference longitude, latitude, altitude.
*
* Coordinates are ordered according to the point IDs in
* a flattened array.
*/
coordinates: number[];
/**
* The reference longitude, latitude, altitude of

View File

@ -1,5 +1,4 @@
import { LngLatAlt } from "../interfaces/LngLatAlt";
import { PointContract } from "./PointContract";
/**
* Contract describing cluster reconstruction data.
@ -10,14 +9,36 @@ export interface ClusterContract {
*/
id: string;
/**
* The IDs of the points.
*
* @description The order of the IDs correspond with the order
* of the color and coordinate arrays.
*/
pointIds: string[];
/**
* The colors of the reconstruction.
*
* @description The colors are represented as RGB values
* normalized to floats on the interval [0, 1].
*
* Colors are ordered according to the point IDs in
* a flattened array.
*/
colors: number[];
/**
* The points of the reconstruction.
*
* @description The points are represented in local topocentric
* ENU coordinates relative to the cluster reference longitude,
* latitude, altitude.
* ENU coordinates in metric scale relative to the cluster
* reference longitude, latitude, altitude.
*
* Coordinates are ordered according to the point IDs in
* a flattened array.
*/
points: { [pointId: string]: PointContract; };
coordinates: number[];
/**
* The reference longitude, latitude, altitude of

View File

@ -1,16 +0,0 @@
/**
* Contract describing a reconstruction point.
*/
export interface PointContract {
/**
* RGB color vector of the point, normalized to floats
* on the interval [0, 1];
*/
color: number[];
/**
* Coordinates in metric scale in topocentric ENU
* reference frame with respect to a geo reference.
*/
coordinates: number[];
}

View File

@ -38,16 +38,26 @@ export class GraphConverter {
: ClusterContract {
const id: string = null;
const colors: number[] = [];
const coordinates: number[] = [];
const pointIds: string[] = [];
const points = source.points;
const normalize = 1 / 255;
const normalizer = 1 / 255;
for (const pointId in points) {
if (!points.hasOwnProperty(pointId)) {
continue;
}
const color = points[pointId].color;
color[0] *= normalize;
color[1] *= normalize;
color[2] *= normalize;
pointIds.push(pointId);
const point = points[pointId];
const color = point.color;
colors.push(color[0] * normalizer);
colors.push(color[1] * normalizer);
colors.push(color[2] * normalizer);
coordinates.push(...point.coordinates);
}
const lla = source.reference_lla;
@ -57,8 +67,10 @@ export class GraphConverter {
lng: lla.longitude,
};
return {
colors,
coordinates,
id,
points,
pointIds,
reference,
};
}

View File

@ -53,30 +53,16 @@ export class ClusterPoints extends Points {
}
private _makeAttributes(cluster: ClusterContract): void {
const positions: number[] = [];
const colors: number[] = [];
const points = cluster.points;
for (const pointId in points) {
if (!points.hasOwnProperty(pointId)) {
continue;
}
const point = points[pointId];
positions.push(...point.coordinates);
const color = point.color;
colors.push(color[0]);
colors.push(color[1]);
colors.push(color[2]);
}
const geometry = this.geometry;
geometry.setAttribute(
"position",
new BufferAttribute(new Float32Array(positions), 3));
new BufferAttribute(
new Float32Array(cluster.coordinates), 3));
const colorSize = cluster.colors.length / cluster.pointIds.length;
geometry.setAttribute(
"color",
new BufferAttribute(new Float32Array(colors), 3));
new BufferAttribute(new Float32Array(cluster.colors), colorSize));
}
}

1
src/external/api.ts vendored
View File

@ -48,7 +48,6 @@ export { ImageTilesContract } from "../api/contracts/ImageTilesContract";
export { ImageTilesRequestContract }
from "../api/contracts/ImageTilesRequestContract";
export { MeshContract } from "../api/contracts/MeshContract";
export { PointContract } from "../api/contracts/PointContract";
export { SequenceContract } from "../api/contracts/SequenceContract";
export { SpatialImagesContract } from "../api/contracts/SpatialImagesContract";

View File

@ -72,14 +72,20 @@ describe("GraphConverter.clusterReconstruction", () => {
expect(cluster).toBeDefined();
// Points
expect(Object.keys(cluster.points).length).toBe(1);
expect(pointId in cluster.points).toBe(true);
expect(cluster.points[pointId]).toBeDefined();
expect(cluster.points[pointId].color[0]).toBeCloseTo(color[0] / 255);
expect(cluster.points[pointId].color[1]).toBeCloseTo(color[1] / 255);
expect(cluster.points[pointId].color[2]).toBeCloseTo(color[2] / 255);
expect(cluster.points[pointId].coordinates)
.toEqual(point.coordinates);
expect(Object.keys(cluster.pointIds).length).toBe(1);
const index = cluster.pointIds.indexOf(pointId);
expect(index).toBeGreaterThanOrEqual(0);
const pointIndex = 3 * index;
expect(cluster.colors[pointIndex + 0]).toBeCloseTo(color[0] / 255);
expect(cluster.colors[pointIndex + 1]).toBeCloseTo(color[1] / 255);
expect(cluster.colors[pointIndex + 2]).toBeCloseTo(color[2] / 255);
expect(cluster.coordinates[pointIndex + 0]).toBeCloseTo(coordinates[0]);
expect(cluster.coordinates[pointIndex + 1]).toBeCloseTo(coordinates[1]);
expect(cluster.coordinates[pointIndex + 2]).toBeCloseTo(coordinates[2]);
// Reference
expect(cluster.reference).toBeDefined();

View File

@ -52,7 +52,7 @@ describe("GraphDataProvider.ctor", () => {
describe("GraphDataProvider.getCluster", () => {
it("should return cluster reconstruction on successful load", (done) => {
const compressed = [{
points: {},
pointIds: <number[]>[],
reference_lla: { altitude: 1, latitude: 2, longitude: 3 },
}];
const fetchMock = (<jest.Mock>fetchArrayBuffer)
@ -65,7 +65,7 @@ describe("GraphDataProvider.getCluster", () => {
provider.getCluster("url")
.then(
(r: ClusterContract): void => {
expect(r.points).toEqual({});
expect(r.pointIds.length).toBe(0);
expect(r.reference.alt).toBe(1);
expect(r.reference.lat).toBe(2);
expect(r.reference.lng).toBe(3);

View File

@ -387,8 +387,10 @@ describe("SpatialCache.updateCell$", () => {
describe("SpatialCache.updateReconstructions$", () => {
const createCluster = (key: string): ClusterContract => {
return {
colors: [],
coordinates: [],
id: key,
points: {},
pointIds: [],
reference: { lat: 0, lng: 0, alt: 0 },
};
};