Skip to content
This repository has been archived by the owner on Mar 8, 2023. It is now read-only.

Commit

Permalink
HARP-14531: sort picking results by 'dataSourceOrder'
Browse files Browse the repository at this point in the history
Signed-off-by: Oleksii Markhovskyi <[email protected]>
  • Loading branch information
Oleksii Markhovskyi authored and nzjony committed Jul 28, 2021
1 parent d1edc33 commit 53a43a6
Show file tree
Hide file tree
Showing 9 changed files with 226 additions and 51 deletions.
11 changes: 10 additions & 1 deletion @here/harp-mapview/lib/PickHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ export interface PickResult {
*/
dataSourceName: string | undefined;

/**
* Data source order, useful for sorting a collection of picking results.
* A number for objects/features coming from tiles (as those have data sources attached),
* an undefined when objects are added via "mapView.mapAnchors.add(object)" - those are treated as
* base layer objects during picking (same as "dataSourceOrder: 0").
*/
dataSourceOrder: number | undefined;

/**
* Render order of the intersected object.
*/
Expand All @@ -90,7 +98,7 @@ export interface PickResult {
/**
* An optional feature ID of the picked object.
* @remarks The ID may be assigned by the object's {@link DataSource}, for example in case of
* Optimized Map Vector (OMV) and GeoJSON datata sources.
* Optimized Map Vector (OMV) and GeoJSON data sources.
*/
featureId?: number | string;

Expand Down Expand Up @@ -259,6 +267,7 @@ export class PickHandler {
point: intersection.point,
distance: intersection.distance,
dataSourceName: intersection.object.userData?.dataSource,
dataSourceOrder: tile?.dataSource?.dataSourceOrder,
intersection,
tileKey: tile?.tileKey
};
Expand Down
43 changes: 38 additions & 5 deletions @here/harp-mapview/lib/PickListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,28 @@ import { assert } from "@here/harp-utils";
import { IntersectParams } from "./IntersectParams";
import { PickResult } from "./PickHandler";

// Default sorting by distance first and then by reversed render order.
// Default sorting by:
// 1. reversed data source order (higher first)
// 2. distance to the camera (closer first)
// 3. reversed render order (higher first)
//
// This criteria order is temporary, until HARP-16245 gets implemented.
// Currently, rendering is configured in a way that makes 2D spatials occlude extruded buildings,
// since spatials belong to a higher layer. Picking order reflects that, but comparison by distance should
// happen first, once extruded buildings become rendered on top of spatials.
function defaultSort(lhs: PickResult, rhs: PickResult) {
// HARP-14531: Compare by "dataSourceOrder" first,
// to ensure that picking results are sorted according to their layers.
// The bigger "dataSourceOrder" value is, the higher its stacked in the data model,
// meaning the higher it should be appear in the resulting picking collection.
// Defaulting "dataSourceOrder" to 0 (base layer) to not skip comparison when it's undefined - in that case
// sorting results would not be consistent, as some objects become compared by different criteria.
const lDataSourceOrder = lhs.dataSourceOrder ?? 0;
const rDataSourceOrder = rhs.dataSourceOrder ?? 0;
if (lDataSourceOrder !== rDataSourceOrder) {
return rDataSourceOrder - lDataSourceOrder;
}

// HARP-14553: Set a distance tolerance to ignore small distance differences between 2D objects
// that are supposed to lie on the same plane.
const eps = 1e-4;
Expand Down Expand Up @@ -118,7 +138,7 @@ export class PickListener {
}

/**
* Returns the furtherst result collected so far, following the order documented in
* Returns the furthest result collected so far, following the order documented in
* {@link PickListener.results}
* @returns The furthest pick result, or `undefined` if no result was collected.
*/
Expand All @@ -133,9 +153,22 @@ export class PickListener {
}

private sortResults(): void {
if (!this.m_sorted) {
this.m_results.sort(defaultSort);
this.m_sorted = true;
if (this.m_sorted) {
return;
}

// HARP-14531: group zero-distance results first,
// as screen-space objects (e.g. labels) are currently rendered on top.
const zeroDistanceGroup: PickResult[] = [];
const nonZeroDistanceGroup: PickResult[] = [];

this.m_results
.sort(defaultSort)
.forEach(result =>
(result.distance === 0 ? zeroDistanceGroup : nonZeroDistanceGroup).push(result)
);
// both groups are sorted because "this.m_results" are sorted
this.m_results = zeroDistanceGroup.concat(nonZeroDistanceGroup);
this.m_sorted = true;
}
}
2 changes: 2 additions & 0 deletions @here/harp-mapview/lib/geometry/TileGeometryCreator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ export class TileGeometryCreator {
path,
tile.offset,
tile.dataSource.name,
tile.dataSource.dataSourceOrder,
textPath.objInfos,
textPath.pathLengthSqr
);
Expand Down Expand Up @@ -542,6 +543,7 @@ export class TileGeometryCreator {
point,
tile.offset,
tile.dataSource.name,
tile.dataSource.dataSourceOrder,
attributes
);
tile.addTextElement(textElement);
Expand Down
2 changes: 2 additions & 0 deletions @here/harp-mapview/lib/poi/PoiManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ export class PoiManager {
positionArray,
tile.offset,
tile.dataSource.name,
tile.dataSource.dataSourceOrder,
getAttributes(poiGeometry)
);

Expand All @@ -408,6 +409,7 @@ export class PoiManager {
getPosition(positions, worldOffsetX, i),
tile.offset,
tile.dataSource.name,
tile.dataSource.dataSourceOrder,
getAttributes(poiGeometry, i),
undefined,
offsetDirection
Expand Down
3 changes: 2 additions & 1 deletion @here/harp-mapview/lib/text/TextElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,8 @@ export class TextElement {
public fadeFar?: number,
readonly tileOffset?: number,
readonly offsetDirection?: number,
readonly dataSourceName?: string
readonly dataSourceName?: string,
readonly dataSourceOrder?: number
) {
if (renderParams instanceof TextRenderStyle) {
this.renderStyle = renderParams;
Expand Down
4 changes: 3 additions & 1 deletion @here/harp-mapview/lib/text/TextElementBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ export class TextElementBuilder {
points: THREE.Vector3 | THREE.Vector3[],
tileOffset: number,
dataSourceName: string,
dataSourceOrder: number,
attributes?: AttributeMap,
pathLengthSqr?: number,
offsetDirection?: number
Expand Down Expand Up @@ -232,7 +233,8 @@ export class TextElementBuilder {
this.m_fadeFar,
tileOffset,
offsetDirection,
dataSourceName
dataSourceName,
dataSourceOrder
);
textElement.minZoomLevel = this.m_minZoomLevel;
textElement.maxZoomLevel = this.m_maxZoomLevel;
Expand Down
1 change: 1 addition & 0 deletions @here/harp-mapview/lib/text/TextElementsRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,7 @@ export class TextElementsRenderer {
featureId: textElement.featureId,
userData: textElement.userData,
dataSourceName: textElement.dataSourceName,
dataSourceOrder: textElement.dataSourceOrder,
text: textElement.text
};

Expand Down
Loading

0 comments on commit 53a43a6

Please sign in to comment.