diff --git a/src/Core/Geographic/Coordinates.ts b/src/Core/Geographic/Coordinates.ts index fea739d4d1..ca134ee415 100644 --- a/src/Core/Geographic/Coordinates.ts +++ b/src/Core/Geographic/Coordinates.ts @@ -34,50 +34,59 @@ function proj4cache(crsIn: string, crsOut: string): proj4.Converter { } /** - * A Coordinates object, defined by a [crs](http://inspire.ec.europa.eu/theme/rs) - * and three values. These values are accessible through `x`, `y` and `z`, - * although it can also be accessible through `latitude`, `longitude` and - * `altitude`. To change a value, prefer the `set()` method below. + * A class representing a geographic or geocentric coordinate. * - * `EPSG:4978` and `EPSG:4326` are supported by default. To use another CRS, - * you have to declare it with `proj4`. You can find most projections and their - * proj4 code at [epsg.io](https://epsg.io/). + * A coordinate is defined by a [CRS](http://inspire.ec.europa.eu/theme/rs) + * (Coordinate Reference System) and a 3-dimensional vector `(x, y, z)`. + * For geocentric projections, it is recommended to use the `latitude`, + * `longitude` and `altitude` aliases to refer to vector components. * - * @example - * new Coordinates('EPSG:4978', 20885167, 849862, 23385912); //Geocentric coordinates - * new Coordinates('EPSG:4326', 2.33, 48.24, 24999549); //Geographic coordinates + * To change a value, prefer the use of the `set*` methods. * - * @example - * // Declare EPSG:3946 with proj4 - * itowns.proj4.defs('EPSG:3946', '+proj=lcc +lat_1=45.25 +lat_2=46.75 +lat_0=46 +lon_0=3 +x_0=1700000 +y_0=5200000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'); + * By default, the `EPSG:4978` and `EPSG:4326` projections are supported. To use + * a different projection, it must have been declared previously with `proj4`. + * A comprehensive list of projections and their corresponding proj4 string can + * be found at [epsg.io](https://epsg.io/). + * + * @example Geocentric coordinates + * ```js + * new Coordinates('EPSG:4978', 20885167, 849862, 23385912); + * ``` + * + * @example Geographic coordinates + * ```js + * new Coordinates('EPSG:4326', 2.33, 48.24, 24999549); + * ``` + * + * @example Defining the EPSG:2154 projection with proj4 + * ```js + * proj4.defs('EPSG:2154', `+proj=lcc +lat_0=46.5 +lon_0=3 +lat_1=49 +lat_2=44 + * +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m + * +no_defs +type=crs`); + * ``` */ class Coordinates { /** - * Used to checkout whether this coordinates is a Coordinates. Default is - * true. You should not change this, as it is used internally for - * optimisation. + * Read-only flag to check if a given object is of type `Coordinates`. */ readonly isCoordinates: boolean; /** - * A supported crs by default in - * [`proj4js`](https://github.com/proj4js/proj4js#named-projections), or an - * added crs to `proj4js` (using `proj4.defs`). Note that `EPSG:4978` is - * also supported by default in itowns. + * A default or user-defined CRS (see {@link ProjectionLike}). */ crs: ProjectionLike; - /** The first value of the coordinate. */ + /** The x value (or longitude) of this coordinate. */ x: number; - /** The second value of the coordinate. */ + /** The y value (or latitude) of this coordinate. */ y: number; - /** The third value of the coordinate. */ + /** The z value (or altitude) of this coordinate. */ z: number; private _normal: THREE.Vector3; private _normalNeedsUpdate: boolean; /** - * @param crs - A supported Coordinate Reference System. + * @param crs - A default or user-defined CRS (see {@link ProjectionLike}). * @param x - x or longitude value. * @param y - y or latitude value. * @param z - z or altitude value. @@ -131,13 +140,11 @@ class Coordinates { } /** - * Set the values of this Coordinates. + * Sets the x, y and z components of this coordinate. * * @param x - x or longitude value. * @param y - y or latitude value. * @param z - z or altitude value. - * - * @returns This Coordinates. */ setFromValues(x: number = 0, y: number = 0, z: number = 0): this { this.x = x; @@ -149,12 +156,13 @@ class Coordinates { } /** - * Set the values of this Coordinates from an array. + * Sets the coordinates's {@link Coordinates#x | x} component to + * `array[offset + 0]`, {@link Coordinates#y | y} component to + * `array[offset + 1]` and {@link Coordinates#z | z} component to + * `array[offset + 2]`. * - * @param array - An array of number to assign to the Coordinates. - * @param offset - Optional offset into the array. - * - * @returns This Coordinates. + * @param array - The source array. + * @param offset - Optional offset into the array. Default is 0. */ setFromArray(array: number[], offset: number = 0): this { return this.setFromValues( @@ -165,34 +173,29 @@ class Coordinates { } /** - * Set the values of this Coordinates from a `THREE.Vector3` or an `Object` - * having `x/y/z` properties, like a `Coordinates`. - * - * @param v - The object to read the values from. + * Sets the `(x, y, z)` vector of this coordinate from a 3-dimensional + * vector-like object. This object shall have both `x`, `y` and `z` + * properties. * - * @returns This Coordinates. + * @param v - The source object. */ setFromVector3(v: THREE.Vector3Like): this { return this.setFromValues(v.x, v.y, v.z); } /** - * Returns a new Coordinates with the same values as this one. It will - * instantiate a new Coordinates with the same CRS as this one. - * - * @returns The target with its new coordinates. + * Returns a new coordinate with the same `(x, y, z)` vector and crs as this + * one. */ clone(): Coordinates { return new Coordinates(this.crs, this.x, this.y, this.z); } /** - * Copies the values of the passed Coordinates to this one. The CRS is - * however not copied. - * - * @param src - The source to copy from. + * Copies the `(x, y, z)` vector components and crs of the passed coordinate + * to this coordinate. * - * @returns This Coordinates. + * @param src - The source coordinate to copy from. */ copy(src: CoordinatesLike): this { this.crs = src.crs; @@ -235,21 +238,24 @@ class Coordinates { } /** - * Return this Coordinates values into a `THREE.Vector3`. + * Copies the `x`, `y` and `z` components into the provided `THREE.Vector3`. * - * @param target - The target to put the values in. If not specified, a new - * vector will be created. + * @param target - An object to store this vector to. If this is not + * specified, a new vector will be created. + * + * @returns A vector `(x, y, z)`, or copies x, y and z into the provided + * vector. */ toVector3(target: THREE.Vector3 = new THREE.Vector3()): THREE.Vector3 { return target.copy(this); } /** - * Copy values coordinates to array + * Copies the `x`, `y` and `z` components into the provided array. * - * @param array - array to store this vector to. If this is not + * @param array - An array to store this vector to. If this is not * provided a new array will be created. - * @param offset - optional offset into the array. + * @param offset - An optional offset into the array. * * @returns An array [x, y, z], or copies x, y and z into the provided * array. @@ -259,12 +265,9 @@ class Coordinates { } /** - * Calculate planar distance between this coordinates and `coord`. - * Planar distance is the straight-line euclidean distance calculated in a - * 2D cartesian coordinate system. - * - * @param coord - The coordinate - * @returns planar distance + * Computes the planar distance from this coordinates to `coord`. + * **Planar distance** is the straight-line euclidean distance calculated in + * a 2D cartesian coordinate system. */ planarDistanceTo(coord: Coordinates): number { this.toVector3(v0).setZ(0); @@ -273,12 +276,9 @@ class Coordinates { } /** - * Calculate geodetic distance between this coordinates and `coord`. - * **Geodetic distance** is calculated in an ellispoid space as the shortest - * distance across the curved surface of the world. - * - * @param coord - The coordinate - * @returns geodetic distance + * Computes the geodetic distance from this coordinates to `coord`. + * **Geodetic distance** is calculated in an ellipsoid space as the shortest + * distance across the curved surface of the ellipsoid. */ geodeticDistanceTo(coord: Coordinates): number { this.as('EPSG:4326', coord0); @@ -287,7 +287,8 @@ class Coordinates { } /** - * Calculate earth euclidean distance between this coordinates and `coord`. + * Computes the euclidean distance from this coordinates to `coord` in a + * WGS84 projection. * * @param coord - The coordinate * @returns earth euclidean distance @@ -299,11 +300,10 @@ class Coordinates { } /** - * Multiplies this `coordinates` (with an implicit 1 in the 4th dimension) - * and `mat`. + * Multiplies this coordinate (with an implicit 1 in the 4th dimension) + * by `mat`, and divides by perspective. * * @param mat - The matrix. - * @returns return this object. */ applyMatrix4(mat: THREE.Matrix4): this { THREE.Vector3.prototype.applyMatrix4.call(this, mat); @@ -311,30 +311,34 @@ class Coordinates { } /** - * Returns coordinates in the wanted + * Projects this coordinate to the specified * [CRS](http://inspire.ec.europa.eu/theme/rs). * - * @param crs - The CRS to convert the Coordinates into. - * @param target - The target to put the converted - * Coordinates into. If not specified a new one will be created. - * - * @returns The resulting Coordinates after the conversion. - * - * @example - * const position = { longitude: 2.33, latitude: 48.24, altitude: 24999549 }; - * const coords = new Coordinates('EPSG:4326', position.longitude, position.latitude, position.altitude); // Geographic system - * const coordinates = coords.as('EPSG:4978'); // Geocentric system + * @param crs - The target CRS to which the coordinate will be converted. + * @param target - The target to store the projected coordinate. If this not + * provided a new coordinate will be created. * - * @example - * const position = { x: 20885167, y: 849862, z: 23385912 }; - * const coords = new Coordinates('EPSG:4978', position.x, position.y, position.z); // Geocentric system - * const coordinates = coords.as('EPSG:4326'); // Geographic system + * @returns The coordinate projected into the specified CRS. * - * @example - * new Coordinates('EPSG:4326', longitude: 2.33, latitude: 48.24, altitude: 24999549).as('EPSG:4978'); // Geocentric system + * @example Conversion from a geographic to a geocentric reference system + * ```js + * const geographicCoords = new Coordinates('EPSG:4326', + * 2.33, // longitude + * 48.24, // latitude + * 24999549, // altitude + * ); + * const geocentricCoords = geographicCoords.as('EPSG:4978'); + * ``` * - * @example - * new Coordinates('EPSG:4978', x: 20885167, y: 849862, z: 23385912).as('EPSG:4326'); // Geographic system + * @example Conversion from a geocentric to a geographic reference system + * ```js + * const geocentricCoords = new Coordinates('EPSG:4978', + * 20885167, // x + * 849862, // y + * 23385912, // z + * ); + * const geographicCoords = geocentricCoords.as('EPSG:4326'); + * ``` */ as(crs: ProjectionLike, target = new Coordinates(crs)): Coordinates { if (this.crs == crs) {