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

Commit

Permalink
MAPSJS-2953: Support custom DataAdapters for VectorTileDecoder. (#2203)
Browse files Browse the repository at this point in the history
* MAPSJS-2953: Support custom DataAdapters for VectorTileDecoder.

VectorTileDecoder has now a method getDataAdapter() whose default
implementation returns one of the 3 default adapters (omv, geojson,
or geojson-vt), the one that supports the provided data.

The method can be overriden by a subclass to provide a custom adapter.

Signed-off-by: Andres Mandado <andres.mandado-almajano@here.com>

* MAPSJS-2953: Simplify usage of IGeometryProcessor interface.

- Add documentation.
- Move responsibility to create MapEnv and add reserved properties
to VectorTileDataProcessor.

Signed-off-by: Andres Mandado <andres.mandado-almajano@here.com>

* MAPSJS-2953: Add unit tests for VectorTileDataProcessor.

Signed-off-by: Andres Mandado <andres.mandado-almajano@here.com>

* MAPSJS-2953: Address some of the review comments.

Signed-off-by: Andres Mandado <andres.mandado-almajano@here.com>

* MAPSJS-2953: Move OMV decode options to OMVDataAdapter.

Fix documentation in getDataAdapter as suggested in review comments.

Signed-off-by: Andres Mandado <andres.mandado-almajano@here.com>

* MAPSJS-2953: Address review comments.

Signed-off-by: Andres Mandado <andres.mandado-almajano@here.com>

* MAPSJS-2953: Address more review comments.

Signed-off-by: Andres Mandado <andres.mandado-almajano@here.com>
  • Loading branch information
atomicsulfate committed Jun 16, 2021
1 parent e15ae90 commit 7b4d481
Show file tree
Hide file tree
Showing 20 changed files with 1,099 additions and 712 deletions.
1 change: 1 addition & 0 deletions @here/harp-vectortile-datasource/index-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
export * from "./lib/VectorTileDecoder";
export * from "./lib/GeoJsonTilerService";
export * from "./lib/OmvDecoderDefs";
export * from "./lib/DataAdapter";
14 changes: 8 additions & 6 deletions @here/harp-vectortile-datasource/lib/DataAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,13 @@
*/

import { DecodeInfo } from "./DecodeInfo";
import { IGeometryProcessor } from "./IGeometryProcessor";

/**
* The class `DataAdapter` prepares vector data so it
* can be processed by the vector tile decoder.
*/
export interface DataAdapter {
/**
* `DataAdapter`'s id.
*/
id: string;

/**
* Checks if the given data can be processed by this `DataAdapter`.
*
Expand All @@ -28,6 +24,12 @@ export interface DataAdapter {
*
* @param data - The raw data to process.
* @param decodeInfo - The `DecodeInfo` of the tile to process.
* @param geometryProcessor - Must be called for every feature providing its geometry
* (point,line or polygon) and properties. @see {@link IGeometryProcessor} for more details.
*/
process(data: ArrayBufferLike | {}, decodeInfo: DecodeInfo): void;
process(
data: ArrayBufferLike | {},
decodeInfo: DecodeInfo,
geometryProcessor: IGeometryProcessor
): void;
}
2 changes: 0 additions & 2 deletions @here/harp-vectortile-datasource/lib/DecodeInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,11 @@ export class DecodeInfo {
/**
* Constructs a new [[DecodeInfo]].
*
* @param adapterId - The id of the [[OmvDataAdapter]] used for decoding.
* @param targetProjection - The [[Projection]]
* @param tileKey - The [[TileKey]] of the Tile to decode.
* @param storageLevelOffset - The storage level offset.
*/
constructor(
readonly adapterId: string,
readonly targetProjection: Projection,
readonly tileKey: TileKey,
readonly storageLevelOffset: number = 0
Expand Down
63 changes: 30 additions & 33 deletions @here/harp-vectortile-datasource/lib/IGeometryProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { MapEnv } from "@here/harp-datasource-protocol/index-decoder";
import { ValueMap } from "@here/harp-datasource-protocol/index-decoder";
import { GeoCoordinates } from "@here/harp-geoutils";
import { Vector2, Vector3 } from "three";

Expand Down Expand Up @@ -34,11 +34,10 @@ export interface ILineGeometry {
}

/**
* The [[IGeometryProcessor]] is used to process geometry features encoded in OMV tiles.
* The [[IGeometryProcessor]] is used to process geometry features from vector tiles.
*
* [[OmvDecoder]] will pass to the processing methods of the concrete implementations
* of this interface, sequences of geometries projected in the local space of the OMV
* [[TilingScheme]] that is always defined to be an instance of [[webMercatorTilingScheme]].
* [[VectorTileDecoder]] will pass to this interface implementation sequences of geometries
* projected in webMercator local tile space (coordinates relative to tile's north-east corner).
* If desired, the world positions can be converted to [[GeoCoordinates]] using the
* [[Projection.unprojectPoint]], for example:
*
Expand All @@ -54,68 +53,66 @@ export interface ILineGeometry {
* ```
*
* The methods of concrete implementations of [[IGeometryProcessor]] are called to process point,
* line and polygon geometries, see [[OmvDecoder]].
* line and polygon geometries, see [[VectorTileDecoder]].
*/
export interface IGeometryProcessor {
/**
* The offset to apply the storage level of a tile to compute the zoom level.
*/
storageLevelOffset?: number;

/**
* Process a sequence of point features.
*
* The points are represented as local webMercator coordinates.
* The points are represented as local webMercator coordinates (coordinates relative to
* tile's north-east corner).
*
* @param layerName - The name of the enclosing layer.
* @param layerExtents - The extents of the enclosing layer.
* @param tileExtents - The tile size (north to south, east to west) in webMercator.
* @param geometry - The positions of the point features in local webMercator coordinates.
* @param env - The environment containing the properties of the geometry.
* @param storageLevel - The storage level of the data.
* @param properties - The geometry properties.
* @param featureId - The feature identifier.
*/
processPointFeature(
layerName: string,
layerExtents: number,
tileExtents: number,
geometry: Vector3[],
env: MapEnv,
storageLevel: number
properties: ValueMap,
featureId: string | number | undefined
): void;

/**
* Process a sequence of line features.
*
* Each line is represented as an Array of local webMercator coordinates.
* Each line is represented as an Array of local webMercator coordinates (coordinates relative
* to tile's north-east corner).
*
* @param layerName - The name of the enclosing layer.
* @param layerExtents - The extents of the enclosing layer.
* @param tileExtents -The tile size (north to south, east to west) in webMercator.
* @param geometry - The list of line geometries.
* @param env - The environment containing the properties of the geometry.
* @param storageLevel - The storage level of the data.
* @param properties - The geometry properties.
* @param featureId - The feature identifier.
*/
processLineFeature(
layerName: string,
layerExtents: number,
tileExtents: number,
geometry: ILineGeometry[],
env: MapEnv,
storageLevel: number
properties: ValueMap,
featureId: string | number | undefined
): void;

/**
* Process a sequence of polygon features.
*
* Each polygon is represented as an Array of contour representing exterior and interior rings.
* Each polygon is represented as an Array of contour representing exterior and interior rings
* in local webMercator coordinates (coordinates relative to tile's north-east corner).
*
* @param layerName - The name of the enclosing layer.
* @param layerExtents - The extents of the enclosing layer.
* @param geometry - The list of polygons.
* @param env - The environment containing the properties of the geometry.
* @param storageLevel - The storage level of the data.
* @param tileExtents - The tile size (north to south, east to west) in webMercator.
* @param geometry - The list of polygons in local webMercator coordinates.
* @param properties - The geometry properties.
* @param featureId - The feature identifier.
*/
processPolygonFeature(
layerName: string,
layerExtents: number,
tileExtents: number,
geometry: IPolygonGeometry[],
env: MapEnv,
storageLevel: number
properties: ValueMap,
featureId: string | number | undefined
): void;
}
2 changes: 1 addition & 1 deletion @here/harp-vectortile-datasource/lib/OmvDataFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ export class ComposedDataFilter implements OmvFeatureFilter {
*/
get hasKindFilter() {
return this.filters.reduce<boolean>(
(result, filter) => result && filter.hasKindFilter,
(result, filter) => result || filter.hasKindFilter,
true
);
}
Expand Down
2 changes: 1 addition & 1 deletion @here/harp-vectortile-datasource/lib/OmvDecoderDefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export interface OmvFeatureFilterDescription {
/**
* Internal interface for options passed from the [[OmvDataSource]] to the decoder.
*
* @hidden
* @internal
*/
export interface OmvDecoderOptions {
/**
Expand Down
50 changes: 32 additions & 18 deletions @here/harp-vectortile-datasource/lib/VectorTileDataEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,17 @@ enum LineType {
type TexCoordsFunction = (tilePos: THREE.Vector2, tileExtents: number) => THREE.Vector2;
const tmpColor = new THREE.Color();

/**
* Options for VectorTileDataEmitter, see {@link DecoderOptions} and {@link OmvDecoderOptions}.
* @internal
*/
export interface VectorTileDataEmitterOptions {
gatherFeatureAttributes?: boolean;
skipShortLabels?: boolean;
enableElevationOverlay?: boolean;
languages?: string[];
}

export class VectorTileDataEmitter {
// mapping from style index to mesh buffers
private readonly m_meshBuffers = new Map<number, MeshBuffers>();
Expand All @@ -245,11 +256,12 @@ export class VectorTileDataEmitter {
constructor(
private readonly m_decodeInfo: DecodeInfo,
private readonly m_styleSetEvaluator: StyleSetEvaluator,
private readonly m_gatherFeatureAttributes: boolean,
private readonly m_skipShortLabels: boolean,
private readonly m_enableElevationOverlay: boolean,
private readonly m_languages?: string[]
) {}
private readonly m_options: VectorTileDataEmitterOptions = {}
) {
this.m_options.gatherFeatureAttributes = m_options.gatherFeatureAttributes ?? false;
this.m_options.skipShortLabels = m_options.skipShortLabels ?? true;
this.m_options.enableElevationOverlay = m_options.enableElevationOverlay ?? false;
}

get projection() {
return this.m_decodeInfo.targetProjection;
Expand Down Expand Up @@ -336,7 +348,7 @@ export class VectorTileDataEmitter {
for (const pos of tilePositions) {
if (shouldCreateTextGeometries) {
const textTechnique = technique as TextTechnique;
const text = getFeatureText(context, textTechnique, this.m_languages);
const text = getFeatureText(context, textTechnique, this.m_options.languages);

if (text !== undefined && text.length > 0) {
texts.push(meshBuffers.addText(text));
Expand Down Expand Up @@ -365,7 +377,7 @@ export class VectorTileDataEmitter {
);
}
positions.push(tmpV3.x, tmpV3.y, tmpV3.z);
objInfos.push(this.m_gatherFeatureAttributes ? env.entries : featureId);
objInfos.push(this.m_options.gatherFeatureAttributes ? env.entries : featureId);
offsetDirections.push((env.lookup("offset_direction") as number) ?? 0);

if (wantsPoi) {
Expand Down Expand Up @@ -634,14 +646,14 @@ export class VectorTileDataEmitter {
isLineMarkerTechnique(technique)
) {
const textTechnique = technique as TextTechnique;
const text = getFeatureText(context, textTechnique, this.m_languages);
const text = getFeatureText(context, textTechnique, this.m_options.languages);

if (text === undefined || text.length === 0) {
continue;
}
let validLines: number[][] = [];

if (this.m_skipShortLabels) {
if (this.m_options.skipShortLabels) {
// Filter the lines, keep only those that are long enough for labelling. Also,
// split jagged label paths to keep processing and rendering only those that
// have no sharp corners, which would not be rendered anyway.
Expand Down Expand Up @@ -679,7 +691,7 @@ export class VectorTileDataEmitter {
path,
pathLengthSqr,
text: String(text),
objInfos: this.m_gatherFeatureAttributes
objInfos: this.m_options.gatherFeatureAttributes
? env.entries
: getFeatureId(env.entries)
});
Expand Down Expand Up @@ -719,7 +731,7 @@ export class VectorTileDataEmitter {
texts: [0],
stringCatalog: [text, imageTexture],
imageTextures: [1],
objInfos: this.m_gatherFeatureAttributes
objInfos: this.m_options.gatherFeatureAttributes
? [env.entries]
: [getFeatureId(env.entries)]
});
Expand Down Expand Up @@ -764,7 +776,9 @@ export class VectorTileDataEmitter {
triangulateLine(aLine, lineWidth, positions, indices, addCircle);
featureStarts.push(start);
objInfos.push(
this.m_gatherFeatureAttributes ? env.entries : getFeatureId(env.entries)
this.m_options.gatherFeatureAttributes
? env.entries
: getFeatureId(env.entries)
);
});

Expand Down Expand Up @@ -1189,7 +1203,7 @@ export class VectorTileDataEmitter {
(isFillTechnique(technique) ||
isSolidLineTechnique(technique) ||
isExtrudedPolygonTechnique(technique)) &&
this.m_enableElevationOverlay
this.m_options.enableElevationOverlay
) {
return TextureCoordinateType.TileSpace;
}
Expand Down Expand Up @@ -1265,7 +1279,7 @@ export class VectorTileDataEmitter {
lines: lineGroup
};

if (this.m_gatherFeatureAttributes) {
if (this.m_options.gatherFeatureAttributes) {
aLine.objInfos = [featureAttributes];
aLine.featureStarts = [0];
}
Expand All @@ -1275,7 +1289,7 @@ export class VectorTileDataEmitter {
lineGroup = lineGroupGeometries.lines;

if (
this.m_gatherFeatureAttributes &&
this.m_options.gatherFeatureAttributes &&
lineGroupGeometries.objInfos &&
lineGroupGeometries.featureStarts
) {
Expand Down Expand Up @@ -1615,7 +1629,7 @@ export class VectorTileDataEmitter {
if (texCoordType !== undefined) {
textureCoordinates.push(vertices[i + 2], vertices[i + 3]);
}
if (this.m_enableElevationOverlay) {
if (this.m_options.enableElevationOverlay) {
normals.push(...tempVertNormal.toArray());
}
if (isExtruded) {
Expand All @@ -1638,7 +1652,7 @@ export class VectorTileDataEmitter {
if (texCoordType !== undefined) {
textureCoordinates.push(vertices[i + 2], vertices[i + 3]);
}
if (this.m_enableElevationOverlay) {
if (this.m_options.enableElevationOverlay) {
normals.push(...tempVertNormal.toArray());
}
if (color !== undefined) {
Expand Down Expand Up @@ -1693,7 +1707,7 @@ export class VectorTileDataEmitter {
logger.error(`cannot triangulate geometry`, err);
}

if (this.m_gatherFeatureAttributes) {
if (this.m_options.gatherFeatureAttributes) {
meshBuffers.objInfos.push(context.env.entries);
meshBuffers.featureStarts.push(startIndexCount);
meshBuffers.edgeFeatureStarts.push(edgeStartIndexCount);
Expand Down
Loading

0 comments on commit 7b4d481

Please sign in to comment.