-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
Projection.js
273 lines (246 loc) · 8.25 KB
/
Projection.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
/**
* @module ol/proj/Projection
*/
import {METERS_PER_UNIT} from './Units.js';
/**
* @typedef {Object} Options
* @property {string} code The SRS identifier code, e.g. `EPSG:4326`.
* @property {import("./Units.js").Units} [units] Units. Required unless a
* proj4 projection is defined for `code`.
* @property {import("../extent.js").Extent} [extent] The validity extent for the SRS.
* @property {string} [axisOrientation='enu'] The axis orientation as specified in Proj4.
* @property {boolean} [global=false] Whether the projection is valid for the whole globe.
* @property {number} [metersPerUnit] The meters per unit for the SRS.
* If not provided, the `units` are used to get the meters per unit from the {@link METERS_PER_UNIT}
* lookup table.
* @property {import("../extent.js").Extent} [worldExtent] The world extent for the SRS.
* @property {function(number, import("../coordinate.js").Coordinate):number} [getPointResolution]
* Function to determine resolution at a point. The function is called with a
* `number` view resolution and a {@link module:ol/coordinate~Coordinate} as arguments, and returns
* the `number` resolution in projection units at the passed coordinate. If this is `undefined`,
* the default {@link module:ol/proj.getPointResolution} function will be used.
*/
/**
* @classdesc
* In most cases, you should not need to create instances of this class.
* Instead, where projection information is required, you can use a string
* projection code or identifier (e.g. `EPSG:4326`) instead of a projection
* instance.
*
* The library includes support for transforming coordinates between the following
* projections:
*
* * WGS 84 / Geographic - Using codes `EPSG:4326`, `CRS:84`, `urn:ogc:def:crs:EPSG:6.6:4326`,
* `urn:ogc:def:crs:OGC:1.3:CRS84`, `urn:ogc:def:crs:OGC:2:84`, `http://www.opengis.net/gml/srs/epsg.xml#4326`,
* or `urn:x-ogc:def:crs:EPSG:4326`
* * WGS 84 / Spherical Mercator - Using codes `EPSG:3857`, `EPSG:102100`, `EPSG:102113`, `EPSG:900913`,
* `urn:ogc:def:crs:EPSG:6.18:3:3857`, or `http://www.opengis.net/gml/srs/epsg.xml#3857`
* * WGS 84 / UTM zones - Using codes `EPSG:32601` through `EPSG:32660` for northern zones
* and `EPSG:32701` through `EPSG:32760` for southern zones. Note that the built-in UTM transforms
* are lower accuracy (with errors on the order of 0.1 m) than those that you might get in a
* library like [proj4js](https://github.com/proj4js/proj4js).
*
* For additional projection support, or to use higher accuracy transforms than the built-in ones, you can use
* the [proj4js](https://github.com/proj4js/proj4js) library. With `proj4js`, after adding any new projection
* definitions, call the {@link module:ol/proj/proj4.register} function.
*
* You can use the {@link module:ol/proj.get} function to retrieve a projection instance
* for one of the registered projections.
*
* @api
*/
class Projection {
/**
* @param {Options} options Projection options.
*/
constructor(options) {
/**
* @private
* @type {string}
*/
this.code_ = options.code;
/**
* Units of projected coordinates. When set to `TILE_PIXELS`, a
* `this.extent_` and `this.worldExtent_` must be configured properly for each
* tile.
* @private
* @type {import("./Units.js").Units}
*/
this.units_ = /** @type {import("./Units.js").Units} */ (options.units);
/**
* Validity extent of the projection in projected coordinates. For projections
* with `TILE_PIXELS` units, this is the extent of the tile in
* tile pixel space.
* @private
* @type {import("../extent.js").Extent}
*/
this.extent_ = options.extent !== undefined ? options.extent : null;
/**
* Extent of the world in EPSG:4326. For projections with
* `TILE_PIXELS` units, this is the extent of the tile in
* projected coordinate space.
* @private
* @type {import("../extent.js").Extent}
*/
this.worldExtent_ =
options.worldExtent !== undefined ? options.worldExtent : null;
/**
* @private
* @type {string}
*/
this.axisOrientation_ =
options.axisOrientation !== undefined ? options.axisOrientation : 'enu';
/**
* @private
* @type {boolean}
*/
this.global_ = options.global !== undefined ? options.global : false;
/**
* @private
* @type {boolean}
*/
this.canWrapX_ = !!(this.global_ && this.extent_);
/**
* @private
* @type {function(number, import("../coordinate.js").Coordinate):number|undefined}
*/
this.getPointResolutionFunc_ = options.getPointResolution;
/**
* @private
* @type {import("../tilegrid/TileGrid.js").default}
*/
this.defaultTileGrid_ = null;
/**
* @private
* @type {number|undefined}
*/
this.metersPerUnit_ = options.metersPerUnit;
}
/**
* @return {boolean} The projection is suitable for wrapping the x-axis
*/
canWrapX() {
return this.canWrapX_;
}
/**
* Get the code for this projection, e.g. 'EPSG:4326'.
* @return {string} Code.
* @api
*/
getCode() {
return this.code_;
}
/**
* Get the validity extent for this projection.
* @return {import("../extent.js").Extent} Extent.
* @api
*/
getExtent() {
return this.extent_;
}
/**
* Get the units of this projection.
* @return {import("./Units.js").Units} Units.
* @api
*/
getUnits() {
return this.units_;
}
/**
* Get the amount of meters per unit of this projection. If the projection is
* not configured with `metersPerUnit` or a units identifier, the return is
* `undefined`.
* @return {number|undefined} Meters.
* @api
*/
getMetersPerUnit() {
return this.metersPerUnit_ || METERS_PER_UNIT[this.units_];
}
/**
* Get the world extent for this projection.
* @return {import("../extent.js").Extent} Extent.
* @api
*/
getWorldExtent() {
return this.worldExtent_;
}
/**
* Get the axis orientation of this projection.
* Example values are:
* enu - the default easting, northing, elevation.
* neu - northing, easting, up - useful for "lat/long" geographic coordinates,
* or south orientated transverse mercator.
* wnu - westing, northing, up - some planetary coordinate systems have
* "west positive" coordinate systems
* @return {string} Axis orientation.
* @api
*/
getAxisOrientation() {
return this.axisOrientation_;
}
/**
* Is this projection a global projection which spans the whole world?
* @return {boolean} Whether the projection is global.
* @api
*/
isGlobal() {
return this.global_;
}
/**
* Set if the projection is a global projection which spans the whole world
* @param {boolean} global Whether the projection is global.
* @api
*/
setGlobal(global) {
this.global_ = global;
this.canWrapX_ = !!(global && this.extent_);
}
/**
* @return {import("../tilegrid/TileGrid.js").default} The default tile grid.
*/
getDefaultTileGrid() {
return this.defaultTileGrid_;
}
/**
* @param {import("../tilegrid/TileGrid.js").default} tileGrid The default tile grid.
*/
setDefaultTileGrid(tileGrid) {
this.defaultTileGrid_ = tileGrid;
}
/**
* Set the validity extent for this projection.
* @param {import("../extent.js").Extent} extent Extent.
* @api
*/
setExtent(extent) {
this.extent_ = extent;
this.canWrapX_ = !!(this.global_ && extent);
}
/**
* Set the world extent for this projection.
* @param {import("../extent.js").Extent} worldExtent World extent
* [minlon, minlat, maxlon, maxlat].
* @api
*/
setWorldExtent(worldExtent) {
this.worldExtent_ = worldExtent;
}
/**
* Set the getPointResolution function (see {@link module:ol/proj.getPointResolution}
* for this projection.
* @param {function(number, import("../coordinate.js").Coordinate):number} func Function
* @api
*/
setGetPointResolution(func) {
this.getPointResolutionFunc_ = func;
}
/**
* Get the custom point resolution function for this projection (if set).
* @return {function(number, import("../coordinate.js").Coordinate):number|undefined} The custom point
* resolution function (if set).
*/
getPointResolutionFunc() {
return this.getPointResolutionFunc_;
}
}
export default Projection;