Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Bounding box: calculation of MinMax values and add clamping options #1993

Merged
merged 4 commits into from
Apr 14, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat(elevationLayers): Add config.clampValues for clamping values of …
…the elevation dataset
  • Loading branch information
ftoromanoff committed Mar 29, 2023
commit 39a15afba80a715e5cb765b4095b1dcc7f345be0
12 changes: 12 additions & 0 deletions src/Layer/ElevationLayer.js
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@ import { RasterElevationTile } from 'Renderer/RasterTile';
* an ElevationLayer. Default is true. You should not change this, as it is used
* internally for optimisation.
* @property {number} noDataValue - Used to specify a **null** or **no data value** in the elevation terrain.
* @property {number} [zmin] - Used to specify a minimum value for the elevation terrain (if the data goes lower, it will be clamped).
* @property {number} [zmax] - Used to specify a maximum value for the elevation terrain (if the data goes higher, it will be clamped)
* @property {number} scale - Used to apply a scale on the elevation value. It
* can be used for exageration of the elevation, like in [this
* example](https://www.itowns-project.org/itowns/examples/#plugins_pyramidal_tiff).
@@ -37,6 +39,11 @@ class ElevationLayer extends RasterLayer {
* contains three elements `name, protocol, extent`, these elements will be
* available using `layer.name` or something else depending on the property
* name.
* @param {number} [config.noDataValue] The value coding the noData in the data set
* @param {Object} [config.clampValues] - Optional information for clamping
* the elevation between a minimum and a maximum value
* @param {number} [config.clampValues.min] The minimum value to clamp the elevation
* @param {number} [config.clampValues.max] The maximum value to clamp the elevation
Comment on lines +45 to +46
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you rename to make the parameters more understandable?
you keep zmin and zmax name for the layer properties?

*
* @example
* // Create an ElevationLayer
@@ -54,6 +61,11 @@ class ElevationLayer extends RasterLayer {
*/
constructor(id, config = {}) {
super(id, config);
if (config.zmin || config.zmax) {
console.warn('Config using zmin and zmax are deprecated, use {clampValues: {min, max}} structure.');
}
this.zmin = config.clampValues?.min ?? config.zmin;
this.zmax = config.clampValues?.max ?? config.zmax;
this.isElevationLayer = true;
this.defineLayerProperty('scale', this.scale || 1.0);
}
44 changes: 27 additions & 17 deletions src/Parser/XbilParser.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,38 @@
import { readTextureValueWithBilinearFiltering } from 'Utils/DEMUtils';

function minMax4Corners(texture, pitch, noDataValue) {
function minMax4Corners(texture, pitch, options) {
const u = pitch.x;
const v = pitch.y;
const w = pitch.z;
const z = [
readTextureValueWithBilinearFiltering({ noDataValue }, texture, u, v),
readTextureValueWithBilinearFiltering({ noDataValue }, texture, u + w, v),
readTextureValueWithBilinearFiltering({ noDataValue }, texture, u + w, v + w),
readTextureValueWithBilinearFiltering({ noDataValue }, texture, u, v + w),
].filter(v => v != undefined && v > -10);
readTextureValueWithBilinearFiltering(options, texture, u, v),
readTextureValueWithBilinearFiltering(options, texture, u + w, v),
readTextureValueWithBilinearFiltering(options, texture, u + w, v + w),
readTextureValueWithBilinearFiltering(options, texture, u, v + w),
].filter(val => val != undefined);

if (z.length) {
return { min: Math.min(...z), max: Math.max(...z) };
} else {
return {
min: Infinity,
max: -Infinity,
};
}
}

/**
* Calculates the minimum maximum texture elevation with xbil data
*
* @param {THREE.Texture} texture The texture to parse
* @param {THREE.Vector4} pitch The pitch, restrict zone to parse
* @param {number} noDataValue No data value
* @return {Object} The minimum maximum elevation.
*/
export function computeMinMaxElevation(texture, pitch, noDataValue) {
* Calculates the minimum maximum texture elevation with xbil data
*
* @param {THREE.Texture} texture The texture to parse
* @param {THREE.Vector4} pitch The pitch, restrict zone to parse
* @param {Object} options No data value and clamp values
* @param {number} options.noDataValue No data value
* @param {number} [options.zmin] The minimum elevation value after which it will be clamped
* @param {number} [options.zmax] The maximum elevation value after which it will be clamped
Comment on lines +31 to +32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you homogenize with clampValues name?

* @return {Object} The minimum and maximum elevation.
*/
export function computeMinMaxElevation(texture, pitch, options) {
const { width, height, data } = texture.image;
if (!data) {
// Return null values means there's no elevation values.
@@ -33,8 +41,8 @@ export function computeMinMaxElevation(texture, pitch, noDataValue) {
return { min: null, max: null };
}

// compute extact minimum and maximum elvation on 4 corners texture.
let { min, max } = minMax4Corners(texture, pitch, noDataValue) || { max: -Infinity, min: Infinity };
// compute the minimum and maximum elevation on the 4 corners texture.
let { min, max } = minMax4Corners(texture, pitch, options);

const sizeX = Math.floor(pitch.z * width);

@@ -50,12 +58,14 @@ export function computeMinMaxElevation(texture, pitch, noDataValue) {
const limX = x + sizeX;
for (x; x < limX; x += inc) {
const val = data[x];
if (val > -10 && val != noDataValue) {
if (val !== options.noDataValue) {
max = Math.max(max, val);
min = Math.min(min, val);
}
}
}
if (options.zmin > min) { min = options.zmin; }
if (options.zmax < max) { max = options.zmax; }
}

if (max === -Infinity || min === Infinity) {
1 change: 1 addition & 0 deletions src/Renderer/LayeredMaterial.js
Original file line number Diff line number Diff line change
@@ -40,6 +40,7 @@ export const colorLayerEffects = {

const defaultStructLayer = {
bias: 0,
noDataValue: -99999,
zmin: 0,
zmax: 0,
scale: 0,
20 changes: 13 additions & 7 deletions src/Renderer/RasterTile.js
Original file line number Diff line number Diff line change
@@ -124,7 +124,7 @@ export class RasterElevationTile extends RasterTile {
const defaultEle = {
bias: 0,
mode: ELEVATION_MODES.DATA,
zmin: 0,
zmin: -Infinity,
zmax: Infinity,
};

@@ -145,11 +145,10 @@ export class RasterElevationTile extends RasterTile {
this.min = 0;
this.max = 0;
}

this.bias = layer.bias || defaultEle.bias;
this.mode = layer.mode || defaultEle.mode;
this.zmin = layer.zmin || defaultEle.zmin;
this.zmax = layer.zmax || defaultEle.zmax;
this.bias = layer.bias ?? defaultEle.bias;
this.mode = layer.mode ?? defaultEle.mode;
this.zmin = layer.zmin ?? defaultEle.zmin;
this.zmax = layer.zmax ?? defaultEle.zmax;

layer.addEventListener('scale-property-changed', this._handlerCBEvent);
}
@@ -186,7 +185,14 @@ export class RasterElevationTile extends RasterTile {

updateMinMaxElevation() {
if (this.textures[0] && !this.layer.useColorTextureElevation) {
const { min, max } = computeMinMaxElevation(this.textures[0], this.offsetScales[0], this.layer.noDataValue);
const { min, max } = computeMinMaxElevation(
this.textures[0],
this.offsetScales[0],
{
noDataValue: this.layer.noDataValue,
zmin: this.layer.zmin,
zmax: this.layer.zmax,
});
if (this.min != min || this.max != max) {
this.min = min;
this.max = max;
3 changes: 1 addition & 2 deletions src/Renderer/Shader/Chunk/elevation_pars_vertex.glsl
Original file line number Diff line number Diff line change
@@ -35,8 +35,7 @@

float getElevation(vec2 uv, sampler2D tex, vec4 offsetScale, Layer layer) {
uv = uv * offsetScale.zw + offsetScale.xy;
float d = getElevationMode(uv, tex, layer.mode);
if (d < layer.zmin || d > layer.zmax) d = 0.;
float d = clamp(getElevationMode(uv, tex, layer.mode), layer.zmin, layer.zmax);
return d * layer.scale + layer.bias;
}
#endif