Skip to content

Commit

Permalink
feat(VectorTile): add coordProj in pushCoordinatesValues() to get acc…
Browse files Browse the repository at this point in the history
…ess to position when using style.base_altitude.

BREAKING CHANGE: Feature.pushCoordinatesValues() signature change from pushCoordinatesValues(feature, long, lat, normal) to pushCoordinatesValues(feature, coordIn, coordProj)
  • Loading branch information
ftoromanoff authored and mgermerie committed Aug 22, 2023
1 parent 44e9532 commit 451e5d6
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 21 deletions.
41 changes: 23 additions & 18 deletions src/Core/Feature.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@ function _extendBuffer(feature, size) {
feature.normals.length = feature.vertices.length;
}
}

function _setGeometryValues(geom, feature, long, lat, alt, normal) {
function _setGeometryValues(geom, feature, coord) {
if (feature.normals) {
normal.toArray(feature.normals, feature._pos);
coord.geodesicNormal.toArray(feature.normals, feature._pos);
}

feature._pushValues(long, lat, alt);
feature._pushValues(coord.x, coord.y, coord.z);

if (geom.size == 3) {
geom.altitude.min = Math.min(geom.altitude.min, alt);
geom.altitude.max = Math.max(geom.altitude.max, alt);
geom.altitude.min = Math.min(geom.altitude.min, coord.z);
geom.altitude.max = Math.max(geom.altitude.max, coord.z);
}
}

Expand Down Expand Up @@ -147,10 +146,9 @@ export class FeatureGeometry {
coordIn.z = this.baseAltitude(feature, coordIn);

coordIn.as(feature.crs, coordOut);

feature.transformToLocalSystem(coordOut);

_setGeometryValues(this, feature, coordOut.x, coordOut.y, coordOut.z, coordOut.geodesicNormal);
_setGeometryValues(this, feature, coordOut);

// expand extent if present
if (this.#currentExtent) {
Expand All @@ -159,23 +157,30 @@ export class FeatureGeometry {
}

/**
* Push new values coordinates in vertices buffer.
* Push new values coordinates in vertices buffer without any transformation.
* No geographical conversion is made or the normal doesn't stored.
* No local transformation is made on coordinates.
*
* @param {Feature} feature - the feature containing the geometry
* @param {number} long The longitude coordinate.
* @param {number} lat The latitude coordinate.
* @param {THREE.Vector3} [normal] the normal on coordinates (only for `EPSG:4978` projection).
*/
pushCoordinatesValues(feature, long, lat, normal) {
const altitude = this.baseAltitude(feature);
* @param {Object} coordIn An object containing the coordinates values to push.
* @param {number} coordIn.x the x coordinate (in a local system).
* @param {number} coordIn.y the y coordinate (in a local system).
* @param {THREE.Vector3} [coordIn.normal] the normal on coordinates (only for `EPSG:4978` projection).
* @param {Coordinates} [coordProj] An optional argument containing the geodesic coordinates in EPSG:4326
* It allows the user to get access to the feature coordinates to set style.base_altitude.
*/
pushCoordinatesValues(feature, coordIn, coordProj, ...args) {
if (args.length > 0) {
console.warn('Deprecated: change in arguments, use pushCoordinatesValues(feature, {x: long, y: lat, normal}, coordProj) instead');
this.pushCoordinatesValues(feature, { x: coordIn, y: coordProj, normal: args[0] }, args[1]);
return;
}
coordIn.z = this.baseAltitude(feature, coordProj);

_setGeometryValues(this, feature, long, lat, altitude, normal);
_setGeometryValues(this, feature, coordIn);

// expand extent if present
if (this.#currentExtent) {
this.#currentExtent.expandByValuesCoordinates(long, lat);
this.#currentExtent.expandByValuesCoordinates(coordIn.x, coordIn.y);
}
}

Expand Down
26 changes: 24 additions & 2 deletions src/Parser/VectorTileParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,27 @@ import { VectorTile } from '@mapbox/vector-tile';
import { globalExtentTMS } from 'Core/Geographic/Extent';
import { FeatureCollection, FEATURE_TYPES } from 'Core/Feature';
import { deprecatedParsingOptionsToNewOne } from 'Core/Deprecated/Undeprecator';
import Coordinates from 'Core/Geographic/Coordinates';

const worldDimension3857 = globalExtentTMS.get('EPSG:3857').planarDimensions();
const globalExtent = new Vector3(worldDimension3857.x, worldDimension3857.y, 1);
const lastPoint = new Vector2();
const firstPoint = new Vector2();

// Calculate the projected coordinates in EPSG:4326 of a given point in the VT local system
// adapted from @mapbox/vector-tile
function project(x, y, tileNumbers, tileExtent) {
const size = tileExtent * 2 ** tileNumbers.z;
const x0 = tileExtent * tileNumbers.x;
const y0 = tileExtent * tileNumbers.y;
const y2 = 180 - (y + y0) * 360 / size;
return new Coordinates(
'EPSG:4326',
(x + x0) * 360 / size - 180,
360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90,
);
}

// Classify option, it allows to classify a full polygon and its holes.
// Each polygon with its holes are in one FeatureGeometry.
// A polygon is determined by its clockwise direction and the holes are in the opposite direction.
Expand Down Expand Up @@ -59,9 +74,15 @@ function vtFeatureToFeatureGeometry(vtFeature, feature, classify = false) {
sum = 0;
}
count++;
geometry.pushCoordinatesValues(feature, x, y);
const coordProj = project(
x,
y,
vtFeature.tileNumbers,
vtFeature.extent);
geometry.pushCoordinatesValues(feature, { x, y }, coordProj);
if (count == 1) {
firstPoint.set(x, y);
firstPoint.coordProj = coordProj;
lastPoint.set(x, y);
} else if (isPolygon && count > 1) {
sum += (lastPoint.x - x) * (lastPoint.y + y);
Expand All @@ -70,7 +91,7 @@ function vtFeatureToFeatureGeometry(vtFeature, feature, classify = false) {
} else if (cmd === 7) {
if (count) {
count++;
geometry.pushCoordinatesValues(feature, firstPoint.x, firstPoint.y);
geometry.pushCoordinatesValues(feature, { x: firstPoint.x, y: firstPoint.y }, firstPoint.coordProj);
if (isPolygon) {
sum += (lastPoint.x - firstPoint.x) * (lastPoint.y + firstPoint.y);
}
Expand Down Expand Up @@ -127,6 +148,7 @@ function readPBF(file, options) {

for (let i = sourceLayer.length - 1; i >= 0; i--) {
const vtFeature = sourceLayer.feature(i);
vtFeature.tileNumbers = { x, y: file.extent.row, z };
const layers = options.in.layers[layer_id].filter(l => l.filterExpression.filter({ zoom: z }, vtFeature) && z >= l.zoom.min && z < l.zoom.max);
let feature;

Expand Down
2 changes: 1 addition & 1 deletion test/unit/label.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('LabelLayer', function () {
const feature = collection.requestFeatureByType(FEATURE_TYPES.POINT);
const geometry = feature.bindNewGeometry();
geometry.startSubGeometry(0, feature);
geometry.pushCoordinatesValues(feature, 0, 0);
geometry.pushCoordinatesValues(feature, { x: 0, y: 0 });
geometry.closeSubGeometry(3, feature);
geometry.properties = { content: 'foo' };

Expand Down

0 comments on commit 451e5d6

Please sign in to comment.