-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix #7485
- Loading branch information
Showing
21 changed files
with
342 additions
and
371 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// @flow | ||
|
||
import LngLat from '../geo/lng_lat'; | ||
import type {LngLatLike} from '../geo/lng_lat'; | ||
|
||
/* | ||
* The circumference of the world in meters at the given latitude. | ||
*/ | ||
function circumferenceAtLatitude(latitude: number) { | ||
const circumference = 2 * Math.PI * 6378137; | ||
return circumference * Math.cos(latitude * Math.PI / 180); | ||
} | ||
|
||
export function mercatorXfromLng(lng: number) { | ||
return (180 + lng) / 360; | ||
} | ||
|
||
export function mercatorYfromLat(lat: number) { | ||
return (180 - (180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)))) / 360; | ||
} | ||
|
||
export function mercatorZfromAltitude(altitude: number, lat: number) { | ||
return altitude / circumferenceAtLatitude(lat); | ||
} | ||
|
||
export function lngFromMercatorX(x: number) { | ||
return x * 360 - 180; | ||
} | ||
|
||
export function latFromMercatorY(y: number) { | ||
const y2 = 180 - y * 360; | ||
return 360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90; | ||
} | ||
|
||
export function altitudeFromMercatorZ(z: number, y: number) { | ||
return z * circumferenceAtLatitude(latFromMercatorY(y)); | ||
} | ||
|
||
/** | ||
* A `MercatorCoordinate` object represents a projected three dimensional position. | ||
* | ||
* `MercatorCoordinate` uses the web mercator projection ([EPSG:3857](https://epsg.io/3857)) with slightly different units: | ||
* - the size of 1 unit is the width of the projected world instead of the "mercator meter" | ||
* - the origin of the coordinate space is at the north-west corner instead of the middle | ||
* | ||
* For example, `MercatorCoordinate(0, 0, 0)` is the north-west corner of the mercator world and | ||
* `MercatorCoordinate(1, 1, 0)` is the south-east corner. If you are familiar with | ||
* [vector tiles](https://github.com/mapbox/vector-tile-spec) it may be helpful to think | ||
* of the coordinate space as the `0/0/0` tile with an extent of `1`. | ||
* | ||
* The `z` dimension of `MercatorCoordinate` is conformal. A cube in the mercator coordinate space would be rendered as a cube. | ||
* | ||
* @param {number} x The x component of the position. | ||
* @param {number} y The y component of the position. | ||
* @param {number} z The z component of the position. | ||
* @example | ||
* var nullIsland = new mapboxgl.MercatorCoordinate(0.5, 0.5, 0); | ||
* | ||
* @see [Add a custom style layer](https://www.mapbox.com/mapbox-gl-js/example/custom-style-layer/) | ||
*/ | ||
class MercatorCoordinate { | ||
x: number; | ||
y: number; | ||
z: number; | ||
|
||
constructor(x: number, y: number, z: number = 0) { | ||
this.x = +x; | ||
this.y = +y; | ||
this.z = +z; | ||
} | ||
|
||
/** | ||
* Project a `LngLat` to a `MercatorCoordinate`. | ||
* | ||
* @param {LngLatLike} lngLatLike The location to project. | ||
* @param {number} altitude The altitude in meters of the position. | ||
* @returns {MercatorCoordinate} The projected mercator coordinate. | ||
* @example | ||
* var coord = mapboxgl.MercatorCoordinate.fromLngLat({ lng: 0, lat: 0}, 0); | ||
* coord; // MercatorCoordinate(0.5, 0.5, 0) | ||
*/ | ||
static fromLngLat(lngLatLike: LngLatLike, altitude: number = 0) { | ||
const lngLat = LngLat.convert(lngLatLike); | ||
|
||
return new MercatorCoordinate( | ||
mercatorXfromLng(lngLat.lng), | ||
mercatorYfromLat(lngLat.lat), | ||
mercatorZfromAltitude(altitude, lngLat.lat)); | ||
} | ||
|
||
/** | ||
* Returns the `LatLng` for the coordinate. | ||
* | ||
* @returns {LngLat} The `LngLat` object. | ||
* @example | ||
* var coord = new mapboxgl.MercatorCoordinate(0.5, 0.5, 0); | ||
* var latLng = coord.toLatLng(); // LngLat(0, 0) | ||
*/ | ||
toLngLat() { | ||
return new LngLat( | ||
lngFromMercatorX(this.x), | ||
latFromMercatorY(this.y)); | ||
} | ||
|
||
/** | ||
* Returns the altitude in meters of the coordinate. | ||
* | ||
* @returns {number} The altitude in meters. | ||
* @example | ||
* var coord = new mapboxgl.MercatorCoordinate(0, 0, 0.02); | ||
* coord.toAltitude(); // 6914.281956295339 | ||
*/ | ||
toAltitude() { | ||
return altitudeFromMercatorZ(this.z, this.y); | ||
} | ||
} | ||
|
||
export default MercatorCoordinate; |
Oops, something went wrong.