import * as THREE from "three" ; import { GeoCoordinatesLike , isGeoCoordinatesLike } from "./GeoCoordinatesLike" ; import { GeoCoordLike } from "./GeoCoordLike" ; import { GeoPointLike , isGeoPointLike } from "./GeoPointLike" ; import { isLatLngLike , LatLngLike } from "./LatLngLike" ; export const MAX_LATITUDE = 90 ; export const MIN_LATITUDE = - 90 ; export const MAX_LONGITUDE = 180 ; export const MIN_LONGITUDE = - 180 ; const tmpV0 = new THREE . Vector3 ( ) ; const tmpV1 = new THREE . Vector3 ( ) ; internal function mod ( dividend , divisor ) { const modulo = dividend % divisor ; const modulo_sign = modulo < 0 ; const divisor_sign = divisor < 0 ; return modulo_sign === divisor_sign ? modulo : modulo + divisor ; } /**
 * `GeoCoordinates` is used to represent geo positions.
 */ export class GeoCoordinates implements GeoCoordinatesLike { param latitude param longitude param altitude static fromDegrees ( latitude , longitude , altitude ? ) { return new GeoCoordinates ( latitude , longitude , altitude ) ; } param latitude param longitude param altitude static fromRadians ( latitude , longitude , altitude ? ) { return new GeoCoordinates ( THREE . MathUtils . radToDeg ( latitude ) , THREE . MathUtils . radToDeg ( longitude ) , altitude ) ; } /**
     * Creates a  GeoCoordinates from a  LatLngLike literal.
     * ```typescript
     * const center = { lat: 53.3, lng: 13.4 };
     * mapView.geoCenter = GeoCoordinates.fromLatLng(center);
     * ```
     *  param latLng - A  LatLngLike object literal.
      static fromLatLng ( latLng ) { return new GeoCoordinates ( latLng . lat , latLng . lng ) ; } /**
     * Creates a  GeoCoordinates from a [[GeoPointLike]] tuple.
     *
     * Example:
     * ```typescript
     * mapView.geoCenter = GeoCoordinates.fromGeoPoint([longitude, latitude]);
     *
     * let geoCoords: number[] = ...;
     *
     * if (isGeoPointLike(geoCoords)) {
     *     const p = GeoCoordinates.fromGeoPoint(geoCoords);
     * }
     * ```
     *  param geoPoint static fromGeoPoint ( geoPoint ) { return new GeoCoordinates ( geoPoint [ 1 ] , geoPoint [ 0 ] , geoPoint [ 2 ] ) ; } /**
     * Creates a  GeoCoordinates from different types of geo coordinate objects.
     *
     * Example:
     * ```typescript
     * const fromGeoPointLike = GeoCoordinates.fromObject([longitude, latitude]);
     * const fromGeoCoordinateLike = GeoCoordinates.fromObject({ longitude, latitude });
     * const fromGeoCoordinate = GeoCoordinates.fromObject(new GeoCoordinates(latitude, longitude));
     * const fromLatLngLike = GeoCoordinates.fromObject({ lat: latitude , lng: longitude });
     * ```
     *
     *  param geoPoint - Either [[GeoPointLike]],  GeoCoordinatesLike * or  LatLngLike object literal.
      static fromObject ( geoPoint ) { if ( isGeoPointLike ( geoPoint ) ) { return GeoCoordinates . fromGeoPoint ( geoPoint ) ; } else if ( isGeoCoordinatesLike ( geoPoint ) ) { return GeoCoordinates . fromDegrees ( geoPoint . latitude , geoPoint . longitude , geoPoint . altitude ) ; } else if ( isLatLngLike ( geoPoint ) ) { return GeoCoordinates . fromDegrees ( geoPoint . lat , geoPoint . lng ) ; } throw new Error ( "Invalid input coordinate format." ) ; } param geoCoords0 param geoCoords1 param factor param wrap default param normalize default static lerp ( geoCoords0 , geoCoords1 , factor , wrap = false , normalize = false ) { if ( wrap ) { if ( geoCoords0 . lng < geoCoords1 . lng ) { const geoCoordsEnd = geoCoords0 . clone ( ) ; geoCoordsEnd . longitude += 360 ; return this . lerp ( geoCoords1 , geoCoordsEnd , 1 - factor ) ; } else { const geoCoordsEnd = geoCoords1 . clone ( ) ; geoCoordsEnd . longitude += 360 ; return this . lerp ( geoCoords0 , geoCoordsEnd , factor ) ; } } const v0 = tmpV0 . set ( geoCoords0 . lat , geoCoords0 . lng , geoCoords0 . altitude ?? 0 ) ; const v1 = tmpV1 . set ( geoCoords1 . lat , geoCoords1 . lng , geoCoords1 . altitude ?? 0 ) ; v0 . lerp ( v1 , factor ) ; const result = new GeoCoordinates ( v0 . x , v0 . y , v0 . z ) ; return normalize ? result . normalized ( ) : result ; } param latitude param longitude param altitude constructor ( public latitude , public longitude , public altitude ? ) { } /**
     * Returns the latitude in radians.
     */ get latitudeInRadians ( ) : number { return THREE . MathUtils . degToRad ( this . latitude ) ; } /**
     * Returns the longitude in radians.
     */ get longitudeInRadians ( ) : number { return THREE . MathUtils . degToRad ( this . longitude ) ; } deprecated get latitudeInDegrees ( ) : number { return this . latitude ; } deprecated get longitudeInDegrees ( ) : number { return this . longitude ; } /**
     * The latitude in the degrees.
     */ get lat ( ) { return this . latitude ; } /**
     * The longitude in the degrees.
     */ get lng ( ) { return this . longitude ; } /**
     * Returns `true` if this `GeoCoordinates` is valid; returns `false` otherwise.
     */ isValid ( ) { return ! isNaN ( this . latitude ) && ! isNaN ( this . longitude ) ; } /**
     * Returns the normalized `GeoCoordinates`.
     */ normalized ( ) { let { latitude , longitude } = this ; if ( isNaN ( latitude ) || isNaN ( longitude ) ) { return this ; } if ( longitude < - 180 || longitude > 180 ) { longitude = mod ( longitude + 180 , 360 ) - 180 ; } latitude = THREE . MathUtils . clamp ( latitude , - 90 , 90 ) ; return new GeoCoordinates ( latitude , longitude , this . altitude ) ; } param other equals ( other ) { return ( this . latitude === other . latitude && this . longitude === other . longitude && this . altitude === other . altitude ) ; } param other copy ( other ) { this . latitude = other . latitude ; this . longitude = other . longitude ; this . altitude = other . altitude ; return this ; } /**
     * Clones this `GeoCoordinates`.
     */ clone ( ) { return new GeoCoordinates ( this . latitude , this . longitude , this . altitude ) ; } /**
     * Returns this  GeoCoordinates as  LatLngLike literal.
      toLatLng ( ) { return { lat : this . latitude , lng : this . longitude } ; } /**
     * Converts this  GeoCoordinates to a [[GeoPointLike]].
      toGeoPoint ( ) { return this . altitude !== undefined ? [ this . longitude , this . latitude , this . altitude ] : [ this . longitude , this . latitude ] ; } param other minLongitudeSpanTo ( other ) { const minLongitude = Math . min ( this . longitude , other . longitude ) ; const maxLongitude = Math . max ( this . longitude , other . longitude ) ; return Math . min ( maxLongitude - minLongitude , 360 + minLongitude - maxLongitude ) ; } }