Skip to content

Commit

Permalink
* Add coreLib getGeometryType
Browse files Browse the repository at this point in the history
* Add search result ID
* Refactoring
  • Loading branch information
Waguramu committed Sep 3, 2024
1 parent fb4de46 commit 216fe4b
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 44 deletions.
21 changes: 13 additions & 8 deletions erdblick_app/app/feature.search.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import {coreLib, uint8ArrayFromWasm} from "./wasm";

export const MAX_ZOOM_LEVEL = 15;

export interface SearchResultPrimitiveId {
type: string,
index: number
}

function generateChildrenIds(parentTileId: bigint) {
if (parentTileId == -1n) {
return [0n, 4294967296n];
Expand All @@ -33,7 +38,7 @@ class FeatureSearchQuadTreeNode {
level: number;
children: Array<FeatureSearchQuadTreeNode>;
count: number;
markers: Array<[number, SearchResultPosition]> = [];
markers: Array<[SearchResultPrimitiveId, SearchResultPosition]> = [];
rectangle: Rectangle;
center: Cartesian3 | null;

Expand All @@ -42,7 +47,7 @@ class FeatureSearchQuadTreeNode {
level: number,
count: number,
children: Array<FeatureSearchQuadTreeNode> = [],
markers: Array<[number, SearchResultPosition]> = []) {
markers: Array<[SearchResultPrimitiveId, SearchResultPosition]> = []) {
this.tileId = tileId;
this.parentId = parentTileId;
this.level = level;
Expand All @@ -59,19 +64,19 @@ class FeatureSearchQuadTreeNode {
return Rectangle.contains(this.rectangle, point);
}

contains(markers: Array<[number, SearchResultPosition]>) {
contains(markers: Array<[SearchResultPrimitiveId, SearchResultPosition]>) {
return markers.some(marker =>
this.containsPoint(marker[1].cartographicRad as Cartographic)
);
}

filterPointsForNode(markers: Array<[number, SearchResultPosition]>) {
filterPointsForNode(markers: Array<[SearchResultPrimitiveId, SearchResultPosition]>) {
return markers.filter(marker =>
this.containsPoint(marker[1].cartographicRad as Cartographic)
);
}

addChildren(markers: Array<[number, SearchResultPosition]> | Cartographic) {
addChildren(markers: Array<[SearchResultPrimitiveId, SearchResultPosition]> | Cartographic) {
const existingIds = this.children.map(child => child.tileId);
const missingIds = generateChildrenIds(this.tileId).filter(id => !existingIds.includes(id));
for (const id of missingIds) {
Expand All @@ -97,7 +102,7 @@ class FeatureSearchQuadTree {
this.root = new FeatureSearchQuadTreeNode(-1n, null, -1, 0);
}

private calculateAveragePosition(markers: Array<[number, SearchResultPosition]>): Cartesian3 {
private calculateAveragePosition(markers: Array<[SearchResultPrimitiveId, SearchResultPosition]>): Cartesian3 {
const sum = markers.reduce(
(acc, marker) => {
acc.x += marker[1].cartesian.x;
Expand All @@ -111,7 +116,7 @@ class FeatureSearchQuadTree {
return new Cartesian3(sum.x / markers.length, sum.y / markers.length, sum.z / markers.length);
}

insert(tileId: bigint, markers: Array<[number, SearchResultPosition]>) {
insert(tileId: bigint, markers: Array<[SearchResultPrimitiveId, SearchResultPosition]>) {
const markersCenter = this.calculateAveragePosition(markers);
const markersCenterCartographic = Cartographic.fromCartesian(markersCenter);
let currentLevel = 0;
Expand Down Expand Up @@ -399,7 +404,7 @@ export class FeatureSearchService {
}
result[2].cartographic = null;
const featureId = result[1];
const id = this.searchResults.length;
const id: SearchResultPrimitiveId = {type: "SearchResult", index: this.searchResults.length};
this.searchResults.push({label: `${featureId}`, mapId: mapId, featureId: featureId});
return [id, result[2]];
}));
Expand Down
32 changes: 10 additions & 22 deletions erdblick_app/app/inspection.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {FeatureWrapper} from "./features.model";
import {ParametersService} from "./parameters.service";
import {coreLib} from "./wasm";
import {JumpTargetService} from "./jump.service";
import {Cartesian3, Cartographic, CesiumMath, Color, Matrix3} from "./cesium";
import {Cartesian3} from "./cesium";
import {InfoMessageService} from "./info.service";
import {KeyboardService} from "./keyboard.service";

Expand All @@ -32,12 +32,12 @@ export class InspectionService {
selectedFeatureInspectionModel: Array<InspectionModelData> | null = null;
selectedFeatureIdName: string = "";
selectedMapIdName: string = "";
selectedFeatureGeometryType: string = "";
selectedFeatureGeometryType: any;
selectedFeatureCenter: Cartesian3 | null = null;
selectedFeatureOrigin: Cartesian3 | null = null;
selectedFeatureBoundingRadius: number = 0;
selectedFeature: FeatureWrapper | null = null;
originNormalAndRadiusForFeatureZoom: Subject<[Cartesian3, Cartesian3, number]> = new Subject();
originAndNormalForFeatureZoom: Subject<[Cartesian3, Cartesian3]> = new Subject();

constructor(private mapService: MapService,
private jumpService: JumpTargetService,
Expand All @@ -63,10 +63,10 @@ export class InspectionService {
const center = feature.center() as Cartesian3;
this.selectedFeatureCenter = center;
this.selectedFeatureOrigin = Cartesian3.fromDegrees(center.x, center.y, center.z);
let radiusPoint = feature.boundingRadiusVector() as Cartesian3;
let radiusPoint = feature.boundingRadiusEndPoint() as Cartesian3;
radiusPoint = Cartesian3.fromDegrees(radiusPoint.x, radiusPoint.y, radiusPoint.z);
this.selectedFeatureBoundingRadius = Cartesian3.distance(this.selectedFeatureOrigin, radiusPoint);
this.selectedFeatureGeometryType = this.getGeometryType();
this.selectedFeatureGeometryType = feature.getGeometryType() as any;
this.isInspectionPanelVisible = true;
this.loadFeatureData();
});
Expand Down Expand Up @@ -162,19 +162,6 @@ export class InspectionService {
}
}

getGeometryType() {
if (this.selectedFeatureInspectionModel) {
for (const section of this.selectedFeatureInspectionModel) {
if (section.key == "Geometry") {
const geometryType = section.children[0].value;
console.log(geometryType)
return geometryType;
}
}
}
return "";
}

zoomToFeature() {
if (!this.selectedFeature) {
this.infoMessageService.showError("Could not zoom to feature: no feature is selected!");
Expand All @@ -185,7 +172,7 @@ export class InspectionService {
return;
}

if (this.selectedFeatureGeometryType.toLowerCase() == "mesh") {
if (this.selectedFeatureGeometryType === this.GeometryType.Mesh) {
let triangle: Array<Cartesian3> = [];
if (this.selectedFeatureInspectionModel) {
for (const section of this.selectedFeatureInspectionModel) {
Expand All @@ -208,17 +195,18 @@ export class InspectionService {
);
Cartesian3.negate(normal, normal);
Cartesian3.normalize(normal, normal);
Cartesian3.multiplyByScalar(normal, this.selectedFeatureBoundingRadius, normal);
this.originNormalAndRadiusForFeatureZoom.next([this.selectedFeatureOrigin, normal, this.selectedFeatureBoundingRadius]);
Cartesian3.multiplyByScalar(normal, 3 * this.selectedFeatureBoundingRadius, normal);
this.originAndNormalForFeatureZoom.next([this.selectedFeatureOrigin, normal]);
}
} else if (this.selectedFeatureCenter) {
this.mapService.moveToWgs84PositionTopic.next({
x: this.selectedFeatureCenter.x,
y: this.selectedFeatureCenter.y,
z: this.selectedFeatureCenter.z + this.selectedFeatureBoundingRadius
z: this.selectedFeatureCenter.z + 3 * this.selectedFeatureBoundingRadius
});
}
}

protected readonly InspectionValueType = coreLib.ValueType;
protected readonly GeometryType = coreLib.GeomType;
}
18 changes: 10 additions & 8 deletions erdblick_app/app/view.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ import {AfterViewInit, Component} from "@angular/core";
import {MapService} from "./map.service";
import {DebugWindow, ErdblickDebugApi} from "./debugapi.component";
import {StyleService} from "./style.service";
import {FeatureSearchService, MAX_ZOOM_LEVEL} from "./feature.search.service";
import {FeatureSearchService, MAX_ZOOM_LEVEL, SearchResultPrimitiveId} from "./feature.search.service";
import {CoordinatesService} from "./coordinates.service";
import {JumpTargetService} from "./jump.service";
import {distinctUntilChanged} from "rxjs";
import {SearchResultPosition} from "./featurefilter.worker";
import {InspectionService} from "./inspection.service";
import {KeyboardService} from "./keyboard.service";

// Redeclare window with extended interface
declare let window: DebugWindow;
Expand Down Expand Up @@ -73,6 +74,7 @@ export class ErdblickViewComponent implements AfterViewInit {
public parameterService: ParametersService,
public jumpService: JumpTargetService,
public inspectionService: InspectionService,
public keyboardService: KeyboardService,
public coordinatesService: CoordinatesService) {

this.tileVisForPrimitive = new Map();
Expand Down Expand Up @@ -147,13 +149,13 @@ export class ErdblickViewComponent implements AfterViewInit {
this.coordinatesService.mouseClickCoordinates.next(Cartographic.fromCartesian(coordinates));
}
let feature = this.viewer.scene.pick(position);
if (defined(feature) && feature.primitive instanceof Billboard) {
if (defined(feature) && feature.primitive instanceof Billboard && feature.primitive.id.type === "SearchResult") {
if (feature.primitive.id) {
const featureInfo = this.featureSearchService.searchResults[feature.primitive.id];
const featureInfo = this.featureSearchService.searchResults[feature.primitive.id.index];
if (featureInfo.mapId && featureInfo.featureId) {
this.jumpService.highlightFeature(featureInfo.mapId, featureInfo.featureId).then(() => {
if (this.inspectionService.selectedFeature) {
this.mapService.focusOnFeature(this.inspectionService.selectedFeature);
this.inspectionService.zoomToFeature();
}
});
}
Expand Down Expand Up @@ -243,8 +245,8 @@ export class ErdblickViewComponent implements AfterViewInit {
}
});

this.inspectionService.originNormalAndRadiusForFeatureZoom.subscribe(values => {
const [origin, normal, radius] = values;
this.inspectionService.originAndNormalForFeatureZoom.subscribe(values => {
const [origin, normal] = values;
// this.viewer.entities.add({
// position: origin,
// point: {
Expand Down Expand Up @@ -470,12 +472,12 @@ export class ErdblickViewComponent implements AfterViewInit {
renderFeatureSearchResultTree(level: number) {
this.featureSearchService.visualization.removeAll();
const color = Color.fromCssColorString(this.featureSearchService.pointColor);
let markers: Array<[number, SearchResultPosition]> = [];
let markers: Array<[SearchResultPrimitiveId, SearchResultPosition]> = [];
const nodes = this.featureSearchService.resultTree.getNodesAtLevel(level);
for (const node of nodes) {
if (node.markers.length) {
markers.push(...node.markers);
} else if (node.count > 0) {
} else if (node.count > 0 && node.center) {
this.featureSearchService.visualization.add({
position: node.center,
image: this.featureSearchService.getPinGraphics(node.count),
Expand Down
9 changes: 7 additions & 2 deletions libs/core/include/erdblick/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,16 @@ bool isPointInsideTriangle(Point const& p, Point const& p0, Point const& p1, Poi
Point geometryCenter(model_ptr<Geometry> const& g);

/**
* Calculate a reasonable bounding radius for the given geometry
* Calculate a point furthest from the center for the given geometry.
* Used to properly scale the camera in the viewer
* relative to the feature's bounding sphere.
*/
Point boundingRadiusVector(model_ptr<Geometry> const& g);
Point boundingRadiusEndPoint(model_ptr<Geometry> const& g);

/**
* Get type of the geometry.
*/
GeomType getGeometryType(model_ptr<Geometry> const& g);

/**
* Calculate a local WGS84 coordinate system for the geometry.
Expand Down
17 changes: 15 additions & 2 deletions libs/core/src/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,25 @@ EMSCRIPTEN_BINDINGS(erdblick)
return geometryCenter(self->firstGeometry());
}))
.function(
"boundingRadiusVector",
"boundingRadiusEndPoint",
std::function<mapget::Point(FeaturePtr&)>(
[](FeaturePtr& self){
return boundingRadiusVector(self->firstGeometry());
return boundingRadiusEndPoint(self->firstGeometry());
}))
.function(
"getGeometryType",
std::function<mapget::GeomType(FeaturePtr&)>(
[](FeaturePtr& self){
return getGeometryType(self->firstGeometry());
}));

////////// GeomType
em::enum_<mapget::GeomType>("GeomType")
.value("Points", mapget::GeomType::Points)
.value("Line", mapget::GeomType::Line)
.value("Polygon", mapget::GeomType::Polygon)
.value("Mesh", mapget::GeomType::Mesh);

////////// TileFeatureLayer
em::class_<mapget::TileFeatureLayer>("TileFeatureLayer")
.smart_ptr<std::shared_ptr<mapget::TileFeatureLayer>>(
Expand Down
8 changes: 6 additions & 2 deletions libs/core/src/geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ Point erdblick::geometryCenter(const model_ptr<Geometry>& g)
return averageVectorPosition(intersectedTrianglePoints);
}

Point erdblick::boundingRadiusVector(const model_ptr<Geometry>& g)
Point erdblick::boundingRadiusEndPoint(const model_ptr<Geometry>& g)
{
const Point center = erdblick::geometryCenter(g);
if (!g) {
std::cerr << "Cannot obtain bounding radius of null geometry." << std::endl;
std::cerr << "Cannot obtain bounding radius vector end point of null geometry." << std::endl;
return center;
}

Expand All @@ -144,6 +144,10 @@ Point erdblick::boundingRadiusVector(const model_ptr<Geometry>& g)
return farPoint;
}

GeomType erdblick::getGeometryType(const model_ptr<Geometry>& g) {
return g->geomType();
}

double erdblick::pointSideOfLine(const Point& lineVector, const Point& lineStart, const Point& p)
{
return lineVector.x * (p.y - lineStart.y) - lineVector.y * (p.x - lineStart.x);
Expand Down

0 comments on commit 216fe4b

Please sign in to comment.