Skip to content

Commit

Permalink
doc(Coordinates): update and refine documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Desplandis committed Dec 19, 2024
1 parent 5460fd3 commit 12365ee
Showing 1 changed file with 91 additions and 87 deletions.
178 changes: 91 additions & 87 deletions src/Core/Geographic/Coordinates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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(
Expand All @@ -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;
Expand Down Expand Up @@ -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.
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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
Expand All @@ -299,42 +300,45 @@ 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);
return this;
}

/**
* 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) {
Expand Down

0 comments on commit 12365ee

Please sign in to comment.