diff --git a/src/Core/Geographic/Extent.ts b/src/Core/Geographic/Extent.ts index 94ebb9ce0b..f27f73a9f4 100644 --- a/src/Core/Geographic/Extent.ts +++ b/src/Core/Geographic/Extent.ts @@ -4,11 +4,6 @@ import Coordinates from './Coordinates'; import type { ProjectionLike } from './Crs'; -/** - * Extent is a SIG-area (so 2D) - * It can use explicit coordinates (e.g: lon/lat) or implicit (WMTS coordinates) - */ - const _dim = new THREE.Vector2(); const _dim2 = new THREE.Vector2(); const _box = new THREE.Box3(); @@ -37,29 +32,49 @@ export interface ExtentLike { readonly north: number; } +/** + * A class representing a geographical extent. + * + * An extent is a geographical bounding rectangle defined by 4 limits: west, + * east, south and north. + * + * **Warning**: Using a geocentric projection is not suitable for representing a + * geographical extent. Please use a geographic projection. + */ class Extent { + /** + * Read-only flag to check if a given object is of type `Extent`. + */ readonly isExtent: true; + /** + * A default or user-defined CRS (see {@link ProjectionLike}). + */ crs: ProjectionLike; + /** + * West longitude bound of this extent. + */ west: number; + /** + * East longitude bound of this extent. + */ east: number; + /** + * South latitude bound of this extent. + */ south: number; + /** + * North latitude bound of this extent. + */ north: number; /** - * Extent is geographical bounding rectangle defined by 4 limits: west, east, south and north. - * - * Warning, using geocentric projection isn't consistent with geographical extent. - * - * @param {String} crs projection of limit values. - * @param {number|Array.|Coordinates|Object} v0 west value, Array - * of values [west, east, south and north], Coordinates of west-south - * corner or object {west, east, south and north} - * @param {number|Coordinates} [v1] east value or Coordinates of - * east-north corner - * @param {number} [v2] south value - * @param {number} [v3] north value - */ - constructor(crs: ProjectionLike, v0 = 0, v1 = 0, v2 = 0, v3 = 0) { + * @param crs - A default or user-defined CRS (see {@link ProjectionLike}). + * @param west - the `west` value of this extent. Default is 0. + * @param east - the `east` value of this extent. Default is 0. + * @param south - the `south` value of this extent. Default is 0. + * @param north - the `north` value of this extent. Default is 0. + */ + constructor(crs: ProjectionLike, west = 0, east = 0, south = 0, north = 0) { if (CRS.isGeocentric(crs)) { throw new Error( `Non-compatible geocentric projection ${crs} to build a geographical extent`, @@ -74,22 +89,22 @@ class Extent { this.south = 0; this.north = 0; - this.set(v0, v1, v2, v3); + this.set(west, east, south, north); } /** - * Clone this extent - * @return {Extent} cloned extent + * Returns a new extent with the same bounds and crs as this one. */ clone() { return new Extent(this.crs, this.west, this.east, this.south, this.north); } /** - * Convert Extent to the specified projection. - * @param {string} crs the projection of destination. - * @param {Extent} [target] copy the destination to target. - * @return {Extent} + * Projects this extent to the specified projection. + * + * @param crs - target's projection. + * @param target - The target to store the projected extent. If this not + * provided a new extent will be created. */ as(crs: string, target: Extent = new Extent('EPSG:4326')) { CRS.isValid(crs); @@ -130,9 +145,10 @@ class Extent { } /** - * Return the center of Extent - * @param {Coordinates} target copy the center to the target. - * @return {Coordinates} + * Returns the center of the extent. + * + * @param target - The target to store the center coordinate. If this not + * provided a new coordinate will be created. */ center(target = new Coordinates(this.crs)) { this.planarDimensions(_dim); @@ -144,11 +160,12 @@ class Extent { } /** - * Planar dimensions are two planar distances west/east and south/north. - * Planar distance straight-line Euclidean distance calculated in a 2D Cartesian coordinate system. + * Returns the planar dimensions as two-vector planar distances west/east + * and south/north. + * The planar distance is a straight-line Euclidean distance calculated in a + * 2D Cartesian coordinate system. * - * @param {THREE.Vector2} [target=new THREE.Vector2()] The target - * @return {THREE.Vector2} Planar dimensions + * @param target - optional target */ planarDimensions(target = new THREE.Vector2()) { // Calculte the dimensions for x and y @@ -156,12 +173,12 @@ class Extent { } /** - * Geodetic dimensions are two planar distances west/east and south/north. - * Geodetic distance is calculated in an ellispoid space as the distance - * across the curved surface of the world. + * Returns the geodetic dimensions as two-vector planar distances west/east + * and south/north. + * Geodetic distance is calculated in an ellispoid space as the distance + * across the curved surface of the ellipsoid. * - * @param {THREE.Vector2} [target=new THREE.Vector2()] The target - * @return {THREE.Vector2} geodetic dimensions + * @param target - optional target */ geodeticDimensions(target = new THREE.Vector2()) { // set 3 corners extent @@ -181,11 +198,11 @@ class Extent { } /** - * Spatial euclidean dimensions are two spatial euclidean distances between west/east corner and south/north corner. - * Spatial euclidean distance chord is calculated in a ellispoid space. + * Returns the spatial euclidean dimensions as a two-vector spatial + * euclidean distances between west/east corner and south/north corner. + * Spatial euclidean distance chord is calculated in an ellispoid space. * - * @param {THREE.Vector2} [target=new THREE.Vector2()] The target - * @return {THREE.Vector2} spatial euclidean dimensions + * @param target - optional target */ spatialEuclideanDimensions(target = new THREE.Vector2()) { // set 3 corners extent @@ -205,13 +222,11 @@ class Extent { } /** - * Return true if `coord` is inside the bounding box. - * - * @param {Coordinates} coord - * @param {number} [epsilon=0] - to take into account when comparing to the - * point. + * Checks whether a coordinates is inside the extent. * - * @return {boolean} + * @param coord - the given coordinates. + * @param epsilon - error margin when comparing to the coordinates. + * Default is 0. */ isPointInside(coord: Coordinates, epsilon = 0) { if (this.crs == coord.crs) { @@ -228,13 +243,10 @@ class Extent { } /** - * Return true if `extent` is inside this extent. - * - * @param {Extent} extent the extent to check - * @param {number} epsilon to take into account when comparing to the - * point. + * Checks whether another extent is inside the extent. * - * @return {boolean} + * @param extent - the extent to check + * @param epsilon - error margin when comparing the extent bounds. */ isInside(extent: Extent, epsilon = CRS.reasonableEpsilon(this.crs)) { extent.as(this.crs, _extent); @@ -245,11 +257,15 @@ class Extent { } /** - * Return the translation and scale to transform this extent to input extent. + * Return the translation and scale to transform this extent to the input + * extent. * - * @param {Extent} extent input extent - * @param {THREE.Vector4} target copy the result to target. - * @return {THREE.Vector4} {x: translation on west-east, y: translation on south-north, z: scale on west-east, w: scale on south-north} + * @param extent - input extent + * @param target - copy the result to target. + * @returns A {@link THREE.Vector4} where the `x` property encodes the + * translation on west-east, the `y` property the translation on + * south-north, the `z` property the scale on west-east, the `w` property + * the scale on south-north. */ offsetToParent(extent: Extent, target = new THREE.Vector4()) { if (this.crs != extent.crs) { @@ -269,9 +285,9 @@ class Extent { } /** - * Return true if this bounding box intersect with the bouding box parameter - * @param {Extent} extent - * @returns {Boolean} + * Checks wheter this bounding box intersects with the given extent + * parameter. + * @param extent - the provided extent */ intersectsExtent(extent: Extent) { return Extent.intersectsExtent(this, extent); @@ -287,9 +303,8 @@ class Extent { } /** - * Return the intersection of this extent with another one - * @param {Extent} extent - * @returns {Extent} + * Returns the intersection of this extent with another one. + * @param extent - extent to intersect */ intersect(extent: Extent) { if (!this.intersectsExtent(extent)) { @@ -308,16 +323,10 @@ class Extent { /** * Set west, east, south and north values. * - * @param {number|Array.|Coordinates|Object|Extent} v0 west value, - * Array of values [west, east, south and north], Extent of same type (tiled - * or not), Coordinates of west-south corner or object {west, east, south - * and north} - * @param {number|Coordinates} [v1] east value, row value or Coordinates of - * east-north corner - * @param {number} [v2] south value or column value - * @param {number} [v3] north value - * - * @return {Extent} + * @param v0 - the `west` value of this extent. Default is 0. + * @param v1 - the `east` value of this extent. Default is 0. + * @param v2 - the `south` value of this extent. Default is 0. + * @param v3 - the `north` value of this extent. Default is 0. */ set(v0: number, v1: number, v2: number, v3: number): this { if (v0 == undefined) { @@ -350,12 +359,11 @@ class Extent { } /** - * Set this extent `west` property to `array[offset + 0]`, `east` property + * Sets this extent `west` property to `array[offset + 0]`, `east` property * to `array[offset + 1]`, `south` property to `array[offset + 2]` and * `north` property to `array[offset + 3]`. - * @param {number[]} array - the source array - * @param {number} [offset=0] - offset into the array. Default is 0. - * @returns {this} + * @param array - the source array + * @param offset - offset into the array. Default is 0. */ setFromArray(array: ArrayLike, offset: number = 0): this { this.west = array[offset]; @@ -366,10 +374,9 @@ class Extent { } /** - * Set this extent `west`, `east`, `south` and `north` properties from an + * Sets this extent `west`, `east`, `south` and `north` properties from an * `extent` bounds. - * @param {Object} extent - the source extent - * @returns {this} + * @param extent - the source extent */ setFromExtent(extent: ExtentLike): this { this.west = extent.west; @@ -380,9 +387,8 @@ class Extent { } /** - * Copy to this extent to input extent. - * @param {Extent} extent - * @return {Extent} copied extent + * Copies the passed extent to this extent. + * @param extent - extent to copy. */ copy(extent: Extent): this { this.crs = extent.crs; @@ -391,7 +397,7 @@ class Extent { /** * Union this extent with the input extent. - * @param {Extent} extent the extent to union. + * @param extent - the extent to union. */ union(extent: Extent) { if (extent.crs != this.crs) { @@ -425,7 +431,7 @@ class Extent { /** * expandByCoordinates perfoms the minimal extension * for the coordinates to belong to this Extent object - * @param {Coordinates} coordinates The coordinates to belong + * @param coordinates - The coordinates to belong */ expandByCoordinates(coordinates: Coordinates) { const coords = coordinates.crs == this.crs ? coordinates : coordinates.as(this.crs, _c); @@ -435,8 +441,8 @@ class Extent { /** * expandByValuesCoordinates perfoms the minimal extension * for the coordinates values to belong to this Extent object - * @param {number} we The coordinate on west-east - * @param {number} sn The coordinate on south-north + * @param we - The coordinate on west-east + * @param sn - The coordinate on south-north * */ expandByValuesCoordinates(we: number, sn: number) { @@ -461,9 +467,8 @@ class Extent { * should be the geocentric coordinates of `min` and `max` of a `box3` * in local tangent plane. * - * @param {string} crs Projection of extent to instancied. - * @param {THREE.Box3} box - * @return {Extent} + * @param crs - Projection of extent to instancied. + * @param box - Bounding-box */ static fromBox3(crs: ProjectionLike, box: THREE.Box3) { if (CRS.isGeocentric(crs)) { @@ -487,28 +492,28 @@ class Extent { /** * Return values of extent in string, separated by the separator input. - * @param {string} separator - * @return {string} + * @param sep - string separator */ - toString(separator = '') { - return `${this.east}${separator}${this.north}${separator}${this.west}${separator}${this.south}`; + toString(sep = '') { + return `${this.east}${sep}${this.north}${sep}${this.west}${sep}${this.south}`; } /** * Subdivide equally an extent from its center to return four extents: * north-west, north-east, south-west and south-east. * - * @returns {Extent[]} An array containing the four sections of the extent. The - * order of the sections is [NW, NE, SW, SE]. + * @returns An array containing the four sections of the extent. The order + * of the sections is [NW, NE, SW, SE]. */ subdivision() { return this.subdivisionByScheme(); } + /** * subdivise extent by scheme.x on west-east and scheme.y on south-north. * - * @param {THREE.Vector2} [scheme=Vector2(2,2)] The scheme to subdivise. - * @return {Array} subdivised extents. + * @param scheme - The scheme to subdivise. + * @returns subdivised extents. */ subdivisionByScheme(scheme = defaultScheme): Extent[] { const subdivisedExtents = []; @@ -528,10 +533,11 @@ class Extent { } /** - * Multiplies all extent `coordinates` (with an implicit 1 in the 4th dimension) and `matrix`. + * Multiplies all extent `coordinates` (with an implicit 1 in the 4th + * dimension) and `matrix`. * - * @param {THREE.Matrix4} matrix The matrix - * @return {Extent} return this extent instance. + * @param matrix - The matrix + * @returns return this extent instance. */ applyMatrix4(matrix: THREE.Matrix4): this { southWest.set(this.west, this.south, 0).applyMatrix4(matrix); @@ -556,9 +562,9 @@ class Extent { /** * clamp south and north values * - * @param {number} [south=this.south] The min south - * @param {number} [north=this.north] The max north - * @return {Extent} this extent + * @param south - The min south + * @param north - The max north + * @returns this extent */ clampSouthNorth(south = this.south, north = this.north): this { this.south = Math.max(this.south, south); @@ -569,20 +575,21 @@ class Extent { /** * clamp west and east values * - * @param {number} [west=this.west] The min west - * @param {number} [east=this.east] The max east - * @return {Extent} this extent + * @param west - The min west + * @param east - The max east + * @returns this extent */ clampWestEast(west = this.west, east = this.east): this { this.west = Math.max(this.west, west); this.east = Math.min(this.east, east); return this; } + /** * clamp this extent by passed extent * - * @param {Extent} extent The maximum extent. - * @return {Extent} this extent. + * @param extent - The maximum extent. + * @returns this extent. */ clampByExtent(extent: ExtentLike): this { this.clampSouthNorth(extent.south, extent.north);