itowns 2.44.3-next.3 → 2.44.3-next.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CODING.md +1 -1
- package/CONTRIBUTORS.md +1 -0
- package/dist/debug.js +1 -1
- package/dist/debug.js.map +1 -1
- package/dist/itowns.js +1 -1
- package/dist/itowns.js.LICENSE.txt +0 -2
- package/dist/itowns.js.map +1 -1
- package/dist/itowns_widgets.js +1 -1
- package/dist/itowns_widgets.js.map +1 -1
- package/examples/3dtiles_loader.html +109 -45
- package/examples/config.json +2 -10
- package/examples/entwine_3d_loader.html +3 -1
- package/examples/entwine_simple_loader.html +1 -1
- package/examples/images/itowns_logo.svg +123 -0
- package/examples/js/plugins/COGParser.js +1 -1
- package/examples/jsm/OGC3DTilesHelper.js +1 -1
- package/examples/layers/JSONLayers/GeoidMNT.json +3 -1
- package/examples/source_file_geojson_3d.html +0 -1
- package/examples/source_stream_wfs_raster.html +0 -7
- package/lib/Controls/GlobeControls.js +45 -28
- package/lib/Controls/StateControl.js +5 -2
- package/lib/Converter/Feature2Mesh.js +10 -4
- package/lib/Converter/Feature2Texture.js +3 -1
- package/lib/Converter/convertToTile.js +3 -8
- package/lib/Converter/textureConverter.js +3 -4
- package/lib/Core/Deprecated/Undeprecator.js +0 -1
- package/lib/Core/Feature.js +1 -2
- package/lib/Core/Geographic/Coordinates.js +143 -132
- package/lib/Core/Geographic/Crs.js +140 -145
- package/lib/Core/Geographic/Extent.js +72 -267
- package/lib/Core/Geographic/GeoidGrid.js +1 -1
- package/lib/Core/Math/Ellipsoid.js +62 -21
- package/lib/Core/Prefab/Globe/Atmosphere.js +4 -8
- package/lib/Core/Prefab/Globe/GlobeLayer.js +22 -15
- package/lib/Core/Prefab/Globe/GlobeTileBuilder.js +111 -0
- package/lib/Core/Prefab/GlobeView.js +2 -7
- package/lib/Core/Prefab/Planar/PlanarLayer.js +17 -11
- package/lib/Core/Prefab/Planar/PlanarTileBuilder.js +43 -43
- package/lib/Core/Prefab/TileBuilder.js +27 -32
- package/lib/Core/Prefab/computeBufferTileGeometry.js +189 -130
- package/lib/Core/Style.js +3 -3
- package/lib/Core/Tile/Tile.js +219 -0
- package/lib/Core/Tile/TileGrid.js +43 -0
- package/lib/Core/TileGeometry.js +112 -28
- package/lib/Core/TileMesh.js +3 -3
- package/lib/Core/View.js +15 -8
- package/lib/Layer/C3DTilesLayer.js +20 -16
- package/lib/Layer/ColorLayer.js +35 -9
- package/lib/Layer/CopcLayer.js +5 -0
- package/lib/Layer/ElevationLayer.js +39 -7
- package/lib/Layer/EntwinePointTileLayer.js +12 -5
- package/lib/Layer/FeatureGeometryLayer.js +20 -6
- package/lib/Layer/GeometryLayer.js +42 -11
- package/lib/Layer/LabelLayer.js +19 -9
- package/lib/Layer/Layer.js +83 -57
- package/lib/Layer/OGC3DTilesLayer.js +81 -30
- package/lib/Layer/OrientedImageLayer.js +11 -5
- package/lib/Layer/PointCloudLayer.js +74 -30
- package/lib/Layer/Potree2Layer.js +7 -2
- package/lib/Layer/PotreeLayer.js +8 -3
- package/lib/Layer/RasterLayer.js +12 -2
- package/lib/Layer/TiledGeometryLayer.js +69 -13
- package/lib/Main.js +2 -2
- package/lib/Parser/GeoJsonParser.js +1 -1
- package/lib/Parser/VectorTileParser.js +1 -1
- package/lib/Parser/XbilParser.js +14 -2
- package/lib/Provider/Fetcher.js +5 -1
- package/lib/Provider/URLBuilder.js +22 -11
- package/lib/Renderer/Camera.js +1 -1
- package/lib/Renderer/OBB.js +11 -13
- package/lib/Renderer/PointsMaterial.js +1 -1
- package/lib/Renderer/RasterTile.js +1 -2
- package/lib/Renderer/SphereHelper.js +0 -6
- package/lib/Source/CopcSource.js +13 -2
- package/lib/Source/EntwinePointTileSource.js +14 -4
- package/lib/Source/FileSource.js +1 -4
- package/lib/Source/Source.js +1 -4
- package/lib/Source/TMSSource.js +10 -9
- package/lib/Source/VectorTilesSource.js +3 -5
- package/lib/Source/WFSSource.js +15 -10
- package/lib/Source/WMSSource.js +56 -18
- package/lib/Source/WMTSSource.js +13 -7
- package/lib/Utils/CameraUtils.js +1 -1
- package/lib/Utils/gui/C3DTilesStyle.js +2 -3
- package/lib/Utils/placeObjectOnGround.js +0 -1
- package/package.json +13 -6
- package/examples/3dtiles_25d.html +0 -120
- package/examples/3dtiles_basic.html +0 -94
- package/examples/3dtiles_batch_table.html +0 -86
- package/examples/3dtiles_ion.html +0 -126
- package/examples/3dtiles_pointcloud.html +0 -95
- package/lib/Core/Prefab/Globe/BuilderEllipsoidTile.js +0 -110
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
+
import * as CRS from "./Crs.js";
|
|
2
3
|
import Coordinates from "./Coordinates.js";
|
|
3
|
-
import CRS from "./Crs.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Extent is a SIG-area (so 2D)
|
|
@@ -9,82 +9,34 @@ import CRS from "./Crs.js";
|
|
|
9
9
|
|
|
10
10
|
const _dim = new THREE.Vector2();
|
|
11
11
|
const _dim2 = new THREE.Vector2();
|
|
12
|
-
const _countTiles = new THREE.Vector2();
|
|
13
12
|
const _box = new THREE.Box3();
|
|
14
|
-
const tmsCoord = new THREE.Vector2();
|
|
15
|
-
const dimensionTile = new THREE.Vector2();
|
|
16
13
|
const defaultScheme = new THREE.Vector2(2, 2);
|
|
17
|
-
const r = {
|
|
18
|
-
row: 0,
|
|
19
|
-
col: 0,
|
|
20
|
-
invDiff: 0
|
|
21
|
-
};
|
|
22
14
|
const cNorthWest = new Coordinates('EPSG:4326', 0, 0, 0);
|
|
23
15
|
const cSouthWest = new Coordinates('EPSG:4326', 0, 0, 0);
|
|
24
16
|
const cNorthEast = new Coordinates('EPSG:4326', 0, 0, 0);
|
|
25
17
|
const southWest = new THREE.Vector3();
|
|
26
18
|
const northEast = new THREE.Vector3();
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const diff = 2 ** diffLevel;
|
|
30
|
-
r.invDiff = 1 / diff;
|
|
31
|
-
r.row = (extent.row - extent.row % diff) * r.invDiff;
|
|
32
|
-
r.col = (extent.col - extent.col % diff) * r.invDiff;
|
|
33
|
-
return r;
|
|
34
|
-
}
|
|
19
|
+
|
|
20
|
+
/** @type {Extent} */
|
|
35
21
|
let _extent;
|
|
36
|
-
let _extent2;
|
|
37
22
|
const cardinals = new Array(8);
|
|
38
23
|
for (let i = cardinals.length - 1; i >= 0; i--) {
|
|
39
|
-
cardinals[i] = new Coordinates('EPSG:4326', 0, 0, 0
|
|
24
|
+
cardinals[i] = new Coordinates('EPSG:4326', 0, 0, 0);
|
|
40
25
|
}
|
|
41
26
|
const _c = new Coordinates('EPSG:4326', 0, 0);
|
|
42
|
-
|
|
43
|
-
/** @private */
|
|
44
|
-
export const globalExtentTMS = new Map();
|
|
45
|
-
/** @private */
|
|
46
|
-
export const schemeTiles = new Map();
|
|
47
|
-
function getInfoTms(crs) {
|
|
48
|
-
const epsg = CRS.formatToEPSG(crs);
|
|
49
|
-
const globalExtent = globalExtentTMS.get(epsg);
|
|
50
|
-
const globalDimension = globalExtent.planarDimensions(_dim2);
|
|
51
|
-
const tms = CRS.formatToTms(crs);
|
|
52
|
-
const sTs = schemeTiles.get(tms) || schemeTiles.get('default');
|
|
53
|
-
// The isInverted parameter is to be set to the correct value, true or false
|
|
54
|
-
// (default being false) if the computation of the coordinates needs to be
|
|
55
|
-
// inverted to match the same scheme as OSM, Google Maps or other system.
|
|
56
|
-
// See link below for more information
|
|
57
|
-
// https://alastaira.wordpress.com/2011/07/06/converting-tms-tile-coordinates-to-googlebingosm-tile-coordinates/
|
|
58
|
-
// in crs includes ':NI' => tms isn't inverted (NOT INVERTED)
|
|
59
|
-
const isInverted = !tms.includes(':NI');
|
|
60
|
-
return {
|
|
61
|
-
epsg,
|
|
62
|
-
globalExtent,
|
|
63
|
-
globalDimension,
|
|
64
|
-
sTs,
|
|
65
|
-
isInverted
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function getCountTiles(crs, zoom) {
|
|
69
|
-
const sTs = schemeTiles.get(CRS.formatToTms(crs)) || schemeTiles.get('default');
|
|
70
|
-
const count = 2 ** zoom;
|
|
71
|
-
_countTiles.set(count, count).multiply(sTs);
|
|
72
|
-
return _countTiles;
|
|
73
|
-
}
|
|
74
27
|
class Extent {
|
|
75
28
|
/**
|
|
76
29
|
* Extent is geographical bounding rectangle defined by 4 limits: west, east, south and north.
|
|
77
|
-
* If crs is tiled projection (WMTS or TMS), the extent is defined by zoom, row and column.
|
|
78
30
|
*
|
|
79
31
|
* Warning, using geocentric projection isn't consistent with geographical extent.
|
|
80
32
|
*
|
|
81
33
|
* @param {String} crs projection of limit values.
|
|
82
|
-
* @param {number|Array.<number>|Coordinates|Object} v0 west value,
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* @param {number|Coordinates} [v1] east value
|
|
34
|
+
* @param {number|Array.<number>|Coordinates|Object} v0 west value, Array
|
|
35
|
+
* of values [west, east, south and north], Coordinates of west-south
|
|
36
|
+
* corner or object {west, east, south and north}
|
|
37
|
+
* @param {number|Coordinates} [v1] east value or Coordinates of
|
|
86
38
|
* east-north corner
|
|
87
|
-
* @param {number} [v2] south value
|
|
39
|
+
* @param {number} [v2] south value
|
|
88
40
|
* @param {number} [v3] north value
|
|
89
41
|
*/
|
|
90
42
|
constructor(crs, v0, v1, v2, v3) {
|
|
@@ -93,17 +45,10 @@ class Extent {
|
|
|
93
45
|
}
|
|
94
46
|
this.isExtent = true;
|
|
95
47
|
this.crs = crs;
|
|
96
|
-
|
|
97
|
-
this.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
this.col = 0;
|
|
101
|
-
} else {
|
|
102
|
-
this.west = 0;
|
|
103
|
-
this.east = 0;
|
|
104
|
-
this.south = 0;
|
|
105
|
-
this.north = 0;
|
|
106
|
-
}
|
|
48
|
+
this.west = 0;
|
|
49
|
+
this.east = 0;
|
|
50
|
+
this.south = 0;
|
|
51
|
+
this.north = 0;
|
|
107
52
|
this.set(v0, v1, v2, v3);
|
|
108
53
|
}
|
|
109
54
|
|
|
@@ -112,126 +57,48 @@ class Extent {
|
|
|
112
57
|
* @return {Extent} cloned extent
|
|
113
58
|
*/
|
|
114
59
|
clone() {
|
|
115
|
-
|
|
116
|
-
return new Extent(this.crs, this.zoom, this.row, this.col);
|
|
117
|
-
} else {
|
|
118
|
-
return new Extent(this.crs, this.west, this.east, this.south, this.north);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* get tiled extents convering this extent
|
|
124
|
-
*
|
|
125
|
-
* @param {string} crs WMTS, TMS crs
|
|
126
|
-
* @return {Array<Extent>} array of extents covering
|
|
127
|
-
*/
|
|
128
|
-
tiledCovering(crs) {
|
|
129
|
-
if (this.crs == 'EPSG:4326' && crs == CRS.tms_3857) {
|
|
130
|
-
const extents_WMTS_PM = [];
|
|
131
|
-
const extent = _extent.copy(this).as(CRS.formatToEPSG(crs), _extent2);
|
|
132
|
-
const {
|
|
133
|
-
globalExtent,
|
|
134
|
-
globalDimension,
|
|
135
|
-
sTs
|
|
136
|
-
} = getInfoTms(CRS.formatToEPSG(crs));
|
|
137
|
-
extent.clampByExtent(globalExtent);
|
|
138
|
-
extent.planarDimensions(dimensionTile);
|
|
139
|
-
const zoom = this.zoom + 1 || Math.floor(Math.log2(Math.round(globalDimension.x / (dimensionTile.x * sTs.x))));
|
|
140
|
-
const countTiles = getCountTiles(crs, zoom);
|
|
141
|
-
const center = extent.center(_c);
|
|
142
|
-
tmsCoord.x = center.x - globalExtent.west;
|
|
143
|
-
tmsCoord.y = globalExtent.north - extent.north;
|
|
144
|
-
tmsCoord.divide(globalDimension).multiply(countTiles).floor();
|
|
145
|
-
|
|
146
|
-
// ]N; N+1] => N
|
|
147
|
-
const maxRow = Math.ceil((globalExtent.north - extent.south) / globalDimension.x * countTiles.y) - 1;
|
|
148
|
-
for (let r = maxRow; r >= tmsCoord.y; r--) {
|
|
149
|
-
extents_WMTS_PM.push(new Extent(crs, zoom, r, tmsCoord.x));
|
|
150
|
-
}
|
|
151
|
-
return extents_WMTS_PM;
|
|
152
|
-
} else {
|
|
153
|
-
const target = new Extent(crs, 0, 0, 0);
|
|
154
|
-
const {
|
|
155
|
-
globalExtent,
|
|
156
|
-
globalDimension,
|
|
157
|
-
sTs,
|
|
158
|
-
isInverted
|
|
159
|
-
} = getInfoTms(this.crs);
|
|
160
|
-
const center = this.center(_c);
|
|
161
|
-
this.planarDimensions(dimensionTile);
|
|
162
|
-
// Each level has 2^n * 2^n tiles...
|
|
163
|
-
// ... so we count how many tiles of the same width as tile we can fit in the layer
|
|
164
|
-
// ... 2^zoom = tilecount => zoom = log2(tilecount)
|
|
165
|
-
const zoom = Math.floor(Math.log2(Math.round(globalDimension.x / (dimensionTile.x * sTs.x))));
|
|
166
|
-
const countTiles = getCountTiles(crs, zoom);
|
|
167
|
-
|
|
168
|
-
// Now that we have computed zoom, we can deduce x and y (or row / column)
|
|
169
|
-
tmsCoord.x = center.x - globalExtent.west;
|
|
170
|
-
tmsCoord.y = isInverted ? globalExtent.north - center.y : center.y - globalExtent.south;
|
|
171
|
-
tmsCoord.divide(globalDimension).multiply(countTiles).floor();
|
|
172
|
-
target.set(zoom, tmsCoord.y, tmsCoord.x);
|
|
173
|
-
return [target];
|
|
174
|
-
}
|
|
60
|
+
return new Extent(this.crs, this.west, this.east, this.south, this.north);
|
|
175
61
|
}
|
|
176
62
|
|
|
177
63
|
/**
|
|
178
64
|
* Convert Extent to the specified projection.
|
|
179
65
|
* @param {string} crs the projection of destination.
|
|
180
|
-
* @param {Extent} target copy the destination to target.
|
|
66
|
+
* @param {Extent} [target] copy the destination to target.
|
|
181
67
|
* @return {Extent}
|
|
182
68
|
*/
|
|
183
69
|
as(crs, target) {
|
|
184
70
|
CRS.isValid(crs);
|
|
185
71
|
target = target || new Extent('EPSG:4326', [0, 0, 0, 0]);
|
|
186
|
-
if (
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
target.
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
cardinals[3].setFromValues(this.east, center.y);
|
|
210
|
-
cardinals[4].setFromValues(this.east, this.south);
|
|
211
|
-
cardinals[5].setFromValues(center.x, this.south);
|
|
212
|
-
cardinals[6].setFromValues(this.west, this.south);
|
|
213
|
-
cardinals[7].setFromValues(this.west, center.y);
|
|
214
|
-
target.set(Infinity, -Infinity, Infinity, -Infinity);
|
|
215
|
-
|
|
216
|
-
// loop over the coordinates
|
|
217
|
-
for (let i = 0; i < cardinals.length; i++) {
|
|
218
|
-
// convert the coordinate.
|
|
219
|
-
cardinals[i].crs = this.crs;
|
|
220
|
-
cardinals[i].as(crs, _c);
|
|
221
|
-
target.north = Math.max(target.north, _c.y);
|
|
222
|
-
target.south = Math.min(target.south, _c.y);
|
|
223
|
-
target.east = Math.max(target.east, _c.x);
|
|
224
|
-
target.west = Math.min(target.west, _c.x);
|
|
225
|
-
}
|
|
226
|
-
target.zoom = this.zoom;
|
|
227
|
-
target.crs = crs;
|
|
228
|
-
return target;
|
|
72
|
+
if (this.crs != crs) {
|
|
73
|
+
// Compute min/max in x/y by projecting 8 cardinal points,
|
|
74
|
+
// and then taking the min/max of each coordinates.
|
|
75
|
+
const center = this.center(_c);
|
|
76
|
+
cardinals[0].setFromValues(this.west, this.north);
|
|
77
|
+
cardinals[1].setFromValues(center.x, this.north);
|
|
78
|
+
cardinals[2].setFromValues(this.east, this.north);
|
|
79
|
+
cardinals[3].setFromValues(this.east, center.y);
|
|
80
|
+
cardinals[4].setFromValues(this.east, this.south);
|
|
81
|
+
cardinals[5].setFromValues(center.x, this.south);
|
|
82
|
+
cardinals[6].setFromValues(this.west, this.south);
|
|
83
|
+
cardinals[7].setFromValues(this.west, center.y);
|
|
84
|
+
target.set(Infinity, -Infinity, Infinity, -Infinity);
|
|
85
|
+
|
|
86
|
+
// loop over the coordinates
|
|
87
|
+
for (let i = 0; i < cardinals.length; i++) {
|
|
88
|
+
// convert the coordinate.
|
|
89
|
+
cardinals[i].crs = this.crs;
|
|
90
|
+
cardinals[i].as(crs, _c);
|
|
91
|
+
target.north = Math.max(target.north, _c.y);
|
|
92
|
+
target.south = Math.min(target.south, _c.y);
|
|
93
|
+
target.east = Math.max(target.east, _c.x);
|
|
94
|
+
target.west = Math.min(target.west, _c.x);
|
|
229
95
|
}
|
|
230
96
|
target.crs = crs;
|
|
231
|
-
target.zoom = this.zoom;
|
|
232
|
-
target.set(this.west, this.east, this.south, this.north);
|
|
233
97
|
return target;
|
|
234
98
|
}
|
|
99
|
+
target.crs = crs;
|
|
100
|
+
target.set(this.west, this.east, this.south, this.north);
|
|
101
|
+
return target;
|
|
235
102
|
}
|
|
236
103
|
|
|
237
104
|
/**
|
|
@@ -241,9 +108,6 @@ class Extent {
|
|
|
241
108
|
*/
|
|
242
109
|
center() {
|
|
243
110
|
let target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Coordinates(this.crs);
|
|
244
|
-
if (CRS.isTms(this.crs)) {
|
|
245
|
-
throw new Error('Invalid operation for WMTS bbox');
|
|
246
|
-
}
|
|
247
111
|
this.planarDimensions(_dim);
|
|
248
112
|
target.crs = this.crs;
|
|
249
113
|
target.setFromValues(this.west + _dim.x * 0.5, this.south + _dim.y * 0.5);
|
|
@@ -352,20 +216,9 @@ class Extent {
|
|
|
352
216
|
* @return {boolean}
|
|
353
217
|
*/
|
|
354
218
|
isInside(extent, epsilon) {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
} else if (this.zoom < extent.zoom) {
|
|
359
|
-
return false;
|
|
360
|
-
} else {
|
|
361
|
-
_rowColfromParent(this, extent.zoom);
|
|
362
|
-
return r.row == extent.row && r.col == extent.col;
|
|
363
|
-
}
|
|
364
|
-
} else {
|
|
365
|
-
extent.as(this.crs, _extent);
|
|
366
|
-
epsilon = epsilon == undefined ? CRS.reasonnableEpsilon(this.crs) : epsilon;
|
|
367
|
-
return this.east - _extent.east <= epsilon && _extent.west - this.west <= epsilon && this.north - _extent.north <= epsilon && _extent.south - this.south <= epsilon;
|
|
368
|
-
}
|
|
219
|
+
extent.as(this.crs, _extent);
|
|
220
|
+
epsilon = epsilon ?? CRS.reasonableEpsilon(this.crs);
|
|
221
|
+
return this.east - _extent.east <= epsilon && _extent.west - this.west <= epsilon && this.north - _extent.north <= epsilon && _extent.south - this.south <= epsilon;
|
|
369
222
|
}
|
|
370
223
|
|
|
371
224
|
/**
|
|
@@ -380,10 +233,6 @@ class Extent {
|
|
|
380
233
|
if (this.crs != extent.crs) {
|
|
381
234
|
throw new Error('unsupported mix');
|
|
382
235
|
}
|
|
383
|
-
if (CRS.isTms(this.crs)) {
|
|
384
|
-
_rowColfromParent(this, extent.zoom);
|
|
385
|
-
return target.set(this.col * r.invDiff - r.col, this.row * r.invDiff - r.row, r.invDiff, r.invDiff);
|
|
386
|
-
}
|
|
387
236
|
extent.planarDimensions(_dim);
|
|
388
237
|
this.planarDimensions(_dim2);
|
|
389
238
|
const originX = (this.west - extent.west) / _dim.x;
|
|
@@ -393,21 +242,6 @@ class Extent {
|
|
|
393
242
|
return target.set(originX, originY, scaleX, scaleY);
|
|
394
243
|
}
|
|
395
244
|
|
|
396
|
-
/**
|
|
397
|
-
* Return parent tiled extent with input level
|
|
398
|
-
*
|
|
399
|
-
* @param {number} levelParent level of parent.
|
|
400
|
-
* @return {Extent}
|
|
401
|
-
*/
|
|
402
|
-
tiledExtentParent(levelParent) {
|
|
403
|
-
if (levelParent && levelParent < this.zoom) {
|
|
404
|
-
_rowColfromParent(this, levelParent);
|
|
405
|
-
return new Extent(this.crs, levelParent, r.row, r.col);
|
|
406
|
-
} else {
|
|
407
|
-
return this;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
245
|
/**
|
|
412
246
|
* Return true if this bounding box intersect with the bouding box parameter
|
|
413
247
|
* @param {Extent} extent
|
|
@@ -416,7 +250,7 @@ class Extent {
|
|
|
416
250
|
intersectsExtent(extent) {
|
|
417
251
|
return Extent.intersectsExtent(this, extent);
|
|
418
252
|
}
|
|
419
|
-
static intersectsExtent(extentA, extentB) {
|
|
253
|
+
static intersectsExtent(/** @type {Extent} */extentA, /** @type {Extent} */extentB) {
|
|
420
254
|
// TODO don't work when is on limit
|
|
421
255
|
const other = extentB.crs == extentA.crs ? extentB : extentB.as(extentA.crs, _extent);
|
|
422
256
|
return !(extentA.west >= other.east || extentA.east <= other.west || extentA.south >= other.north || extentA.north <= other.south);
|
|
@@ -425,7 +259,7 @@ class Extent {
|
|
|
425
259
|
/**
|
|
426
260
|
* Return the intersection of this extent with another one
|
|
427
261
|
* @param {Extent} extent
|
|
428
|
-
* @returns {
|
|
262
|
+
* @returns {Extent}
|
|
429
263
|
*/
|
|
430
264
|
intersect(extent) {
|
|
431
265
|
if (!this.intersectsExtent(extent)) {
|
|
@@ -439,12 +273,11 @@ class Extent {
|
|
|
439
273
|
|
|
440
274
|
/**
|
|
441
275
|
* Set west, east, south and north values.
|
|
442
|
-
* Or if tiled extent, set zoom, row and column values
|
|
443
276
|
*
|
|
444
277
|
* @param {number|Array.<number>|Coordinates|Object|Extent} v0 west value,
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
*
|
|
278
|
+
* Array of values [west, east, south and north], Extent of same type (tiled
|
|
279
|
+
* or not), Coordinates of west-south corner or object {west, east, south
|
|
280
|
+
* and north}
|
|
448
281
|
* @param {number|Coordinates} [v1] east value, row value or Coordinates of
|
|
449
282
|
* east-north corner
|
|
450
283
|
* @param {number} [v2] south value or column value
|
|
@@ -457,22 +290,12 @@ class Extent {
|
|
|
457
290
|
throw new Error('No values to set in the extent');
|
|
458
291
|
}
|
|
459
292
|
if (v0.isExtent) {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
} else {
|
|
465
|
-
v1 = v0.east;
|
|
466
|
-
v2 = v0.south;
|
|
467
|
-
v3 = v0.north;
|
|
468
|
-
v0 = v0.west;
|
|
469
|
-
}
|
|
293
|
+
v1 = v0.east;
|
|
294
|
+
v2 = v0.south;
|
|
295
|
+
v3 = v0.north;
|
|
296
|
+
v0 = v0.west;
|
|
470
297
|
}
|
|
471
|
-
if (
|
|
472
|
-
this.zoom = v0;
|
|
473
|
-
this.row = v1;
|
|
474
|
-
this.col = v2;
|
|
475
|
-
} else if (v0.isCoordinates) {
|
|
298
|
+
if (v0.isCoordinates) {
|
|
476
299
|
// seem never used
|
|
477
300
|
this.west = v0.x;
|
|
478
301
|
this.east = v1.x;
|
|
@@ -605,11 +428,7 @@ class Extent {
|
|
|
605
428
|
*/
|
|
606
429
|
toString() {
|
|
607
430
|
let separator = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
608
|
-
|
|
609
|
-
return `${this.zoom}${separator}${this.row}${separator}${this.col}`;
|
|
610
|
-
} else {
|
|
611
|
-
return `${this.east}${separator}${this.north}${separator}${this.west}${separator}${this.south}`;
|
|
612
|
-
}
|
|
431
|
+
return `${this.east}${separator}${this.north}${separator}${this.west}${separator}${this.south}`;
|
|
613
432
|
}
|
|
614
433
|
|
|
615
434
|
/**
|
|
@@ -625,7 +444,7 @@ class Extent {
|
|
|
625
444
|
/**
|
|
626
445
|
* subdivise extent by scheme.x on west-east and scheme.y on south-north.
|
|
627
446
|
*
|
|
628
|
-
* @param {Vector2} [scheme=Vector2(2,2)] The scheme to subdivise.
|
|
447
|
+
* @param {THREE.Vector2} [scheme=Vector2(2,2)] The scheme to subdivise.
|
|
629
448
|
* @return {Array<Extent>} subdivised extents.
|
|
630
449
|
*/
|
|
631
450
|
subdivisionByScheme() {
|
|
@@ -649,25 +468,23 @@ class Extent {
|
|
|
649
468
|
* @return {Extent} return this extent instance.
|
|
650
469
|
*/
|
|
651
470
|
applyMatrix4(matrix) {
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
this.north = temp;
|
|
668
|
-
}
|
|
669
|
-
return this;
|
|
471
|
+
southWest.set(this.west, this.south, 0).applyMatrix4(matrix);
|
|
472
|
+
northEast.set(this.east, this.north, 0).applyMatrix4(matrix);
|
|
473
|
+
this.west = southWest.x;
|
|
474
|
+
this.east = northEast.x;
|
|
475
|
+
this.south = southWest.y;
|
|
476
|
+
this.north = northEast.y;
|
|
477
|
+
if (this.west > this.east) {
|
|
478
|
+
const temp = this.west;
|
|
479
|
+
this.west = this.east;
|
|
480
|
+
this.east = temp;
|
|
481
|
+
}
|
|
482
|
+
if (this.south > this.north) {
|
|
483
|
+
const temp = this.south;
|
|
484
|
+
this.south = this.north;
|
|
485
|
+
this.north = temp;
|
|
670
486
|
}
|
|
487
|
+
return this;
|
|
671
488
|
}
|
|
672
489
|
|
|
673
490
|
/**
|
|
@@ -711,16 +528,4 @@ class Extent {
|
|
|
711
528
|
}
|
|
712
529
|
}
|
|
713
530
|
_extent = new Extent('EPSG:4326', [0, 0, 0, 0]);
|
|
714
|
-
_extent2 = new Extent('EPSG:4326', [0, 0, 0, 0]);
|
|
715
|
-
globalExtentTMS.set('EPSG:4326', new Extent('EPSG:4326', -180, 180, -90, 90));
|
|
716
|
-
|
|
717
|
-
// Compute global extent of TMS in EPSG:3857
|
|
718
|
-
// It's square whose a side is between -180° to 180°.
|
|
719
|
-
// So, west extent, it's 180 convert in EPSG:3857
|
|
720
|
-
const extent3857 = globalExtentTMS.get('EPSG:4326').as('EPSG:3857');
|
|
721
|
-
extent3857.clampSouthNorth(extent3857.west, extent3857.east);
|
|
722
|
-
globalExtentTMS.set('EPSG:3857', extent3857);
|
|
723
|
-
schemeTiles.set('default', new THREE.Vector2(1, 1));
|
|
724
|
-
schemeTiles.set(CRS.tms_3857, schemeTiles.get('default'));
|
|
725
|
-
schemeTiles.set(CRS.tms_4326, new THREE.Vector2(2, 1));
|
|
726
531
|
export default Extent;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
+
import * as CRS from "./Crs.js";
|
|
2
3
|
import Coordinates from "./Coordinates.js";
|
|
3
|
-
import CRS from "./Crs.js";
|
|
4
4
|
const coord = new Coordinates('EPSG:4326');
|
|
5
5
|
const indexes = new THREE.Vector2();
|
|
6
6
|
function biLinearInterpolation(indexes, getData) {
|
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
import proj4 from 'proj4';
|
|
3
3
|
import Coordinates from "../Geographic/Coordinates.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Length of the semi-axes of the WGS84 ellipsoid.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
4
9
|
export const ellipsoidSizes = new THREE.Vector3(proj4.WGS84.a, proj4.WGS84.a, proj4.WGS84.b);
|
|
5
10
|
const normal = new THREE.Vector3();
|
|
6
11
|
class Ellipsoid {
|
|
12
|
+
/**
|
|
13
|
+
* Length of the semi-axes of the ellipsoid.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Eccentricity of the ellipsoid.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param size - Length of the semi-axes of the ellipsoid. Defaults to those
|
|
22
|
+
* defined by the WGS84 ellipsoid.
|
|
23
|
+
*/
|
|
7
24
|
constructor() {
|
|
8
25
|
let size = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ellipsoidSizes;
|
|
9
26
|
this.size = new THREE.Vector3();
|
|
@@ -12,10 +29,28 @@ class Ellipsoid {
|
|
|
12
29
|
this.eccentricity = 0;
|
|
13
30
|
this.setSize(size);
|
|
14
31
|
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Computes the normal vector to an ellipsoid at the given cartesian
|
|
35
|
+
* coordinate `(x, y, z)`.
|
|
36
|
+
*
|
|
37
|
+
* @param cartesian - The given cartesian coordinate.
|
|
38
|
+
* @param target - An object to store this vector to. If this is not
|
|
39
|
+
* specified, a new vector will be created.
|
|
40
|
+
*/
|
|
15
41
|
geodeticSurfaceNormal(cartesian) {
|
|
16
42
|
let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new THREE.Vector3();
|
|
17
43
|
return cartesian.toVector3(target).multiply(this._invRadiiSquared).normalize();
|
|
18
44
|
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Computes the normal vector to an ellipsoid at the given geographic
|
|
48
|
+
* coordinate `(longitude, latitude, altitude)`.
|
|
49
|
+
*
|
|
50
|
+
* @param coordCarto - The given geographic coordinate.
|
|
51
|
+
* @param target - An object to store this vector to. If this is not
|
|
52
|
+
* specified, a new vector will be created.
|
|
53
|
+
*/
|
|
19
54
|
geodeticSurfaceNormalCartographic(coordCarto) {
|
|
20
55
|
let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new THREE.Vector3();
|
|
21
56
|
const longitude = THREE.MathUtils.degToRad(coordCarto.longitude);
|
|
@@ -23,13 +58,22 @@ class Ellipsoid {
|
|
|
23
58
|
const cosLatitude = Math.cos(latitude);
|
|
24
59
|
return target.set(cosLatitude * Math.cos(longitude), cosLatitude * Math.sin(longitude), Math.sin(latitude));
|
|
25
60
|
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Sets the length of the semi-axes of this ellipsoid from a 3-dimensional
|
|
64
|
+
* vector-like object. The object shall have both `x`, `y` and `z`
|
|
65
|
+
* properties.
|
|
66
|
+
*
|
|
67
|
+
* @param size - The source vector.
|
|
68
|
+
*/
|
|
26
69
|
setSize(size) {
|
|
27
70
|
this.size.set(size.x, size.y, size.z);
|
|
28
71
|
this._radiiSquared.multiplyVectors(size, size);
|
|
29
|
-
this._invRadiiSquared.x = size.x
|
|
30
|
-
this._invRadiiSquared.y = size.y
|
|
31
|
-
this._invRadiiSquared.z = size.z
|
|
72
|
+
this._invRadiiSquared.x = size.x === 0 ? 0 : 1 / this._radiiSquared.x;
|
|
73
|
+
this._invRadiiSquared.y = size.y === 0 ? 0 : 1 / this._radiiSquared.y;
|
|
74
|
+
this._invRadiiSquared.z = size.z === 0 ? 0 : 1 / this._radiiSquared.z;
|
|
32
75
|
this.eccentricity = Math.sqrt(this._radiiSquared.x - this._radiiSquared.z) / this.size.x;
|
|
76
|
+
return this;
|
|
33
77
|
}
|
|
34
78
|
cartographicToCartesian(coordCarto) {
|
|
35
79
|
let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new THREE.Vector3();
|
|
@@ -42,18 +86,18 @@ class Ellipsoid {
|
|
|
42
86
|
}
|
|
43
87
|
|
|
44
88
|
/**
|
|
45
|
-
* Convert cartesian coordinates to geographic according to the current
|
|
46
|
-
*
|
|
47
|
-
* @param
|
|
48
|
-
* @param
|
|
49
|
-
* @
|
|
50
|
-
*
|
|
51
|
-
* @returns {Coordinate} an object describing the coordinates on the reference ellipsoid, angles are in degree
|
|
89
|
+
* Convert cartesian coordinates to geographic according to the current
|
|
90
|
+
* ellipsoid of revolution.
|
|
91
|
+
* @param position - The coordinate to convert
|
|
92
|
+
* @param target - coordinate to copy result
|
|
93
|
+
* @returns an object describing the coordinates on the reference ellipsoid,
|
|
94
|
+
* angles are in degree
|
|
52
95
|
*/
|
|
53
96
|
cartesianToCartographic(position) {
|
|
54
97
|
let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Coordinates('EPSG:4326', 0, 0, 0);
|
|
55
98
|
// for details, see for example http://www.linz.govt.nz/data/geodetic-system/coordinate-conversion/geodetic-datum-conversions/equations-used-datum
|
|
56
|
-
// TODO the following is only valable for oblate ellipsoid of
|
|
99
|
+
// TODO the following is only valable for oblate ellipsoid of
|
|
100
|
+
// revolution. do we want to support triaxial ellipsoid?
|
|
57
101
|
const R = Math.sqrt(position.x * position.x + position.y * position.y + position.z * position.z);
|
|
58
102
|
const a = this.size.x; // x
|
|
59
103
|
const b = this.size.z; // z
|
|
@@ -92,9 +136,9 @@ class Ellipsoid {
|
|
|
92
136
|
const t1 = (-b + d) / (2 * a);
|
|
93
137
|
const t2 = (-b - d) / (2 * a);
|
|
94
138
|
if (t1 <= EPSILON && t2 <= EPSILON) {
|
|
139
|
+
// both intersections are behind the ray origin
|
|
95
140
|
return false;
|
|
96
|
-
}
|
|
97
|
-
// var back = (t1 <= EPSILON || t2 <= EPSILON); // If only one intersection (t>0) then we are inside the ellipsoid and the intersection is at the back of the ellipsoid
|
|
141
|
+
}
|
|
98
142
|
let t = 0;
|
|
99
143
|
if (t1 <= EPSILON) {
|
|
100
144
|
t = t2;
|
|
@@ -111,19 +155,16 @@ class Ellipsoid {
|
|
|
111
155
|
inter.addVectors(ray.origin, dir.clone().setLength(t));
|
|
112
156
|
return inter;
|
|
113
157
|
}
|
|
114
|
-
computeDistance(coordCarto1, coordCarto2) {
|
|
115
|
-
console.warn('computeDistance is renamed to geodesicDistance');
|
|
116
|
-
this.geodesicDistance(coordCarto1, coordCarto2);
|
|
117
|
-
}
|
|
118
158
|
|
|
119
159
|
/**
|
|
120
160
|
* Calculate the geodesic distance, between coordCarto1 and coordCarto2.
|
|
121
|
-
* It's most short distance on ellipsoid surface between coordCarto1 and
|
|
161
|
+
* It's most short distance on ellipsoid surface between coordCarto1 and
|
|
162
|
+
* coordCarto2.
|
|
122
163
|
* It's called orthodromy.
|
|
123
164
|
*
|
|
124
|
-
* @param
|
|
125
|
-
* @param
|
|
126
|
-
* @
|
|
165
|
+
* @param coordCarto1 - The coordinate carto 1
|
|
166
|
+
* @param coordCarto2 - The coordinate carto 2
|
|
167
|
+
* @returns The orthodromic distance between the two given coordinates.
|
|
127
168
|
*/
|
|
128
169
|
geodesicDistance(coordCarto1, coordCarto2) {
|
|
129
170
|
// The formula uses the distance on approximated sphere,
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* To change this license header, choose License Headers in Project Properties.
|
|
3
|
-
* To change this template file, choose Tools | Templates
|
|
4
|
-
* and open the template in the editor.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
import * as THREE from 'three';
|
|
8
2
|
import GeometryLayer from "../../../Layer/GeometryLayer.js";
|
|
9
3
|
import Coordinates from "../../Geographic/Coordinates.js";
|
|
@@ -31,6 +25,10 @@ const colorSky = new THREE.Color();
|
|
|
31
25
|
const spaceColor = new THREE.Color(0x030508);
|
|
32
26
|
const limitAlti = 600000;
|
|
33
27
|
const mfogDistance = ellipsoidSizes.x * 160.0;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @extends GeometryLayer
|
|
31
|
+
*/
|
|
34
32
|
class Atmosphere extends GeometryLayer {
|
|
35
33
|
/**
|
|
36
34
|
* It's layer to simulate Globe atmosphere.
|
|
@@ -40,8 +38,6 @@ class Atmosphere extends GeometryLayer {
|
|
|
40
38
|
* * [Atmosphere Shader From Space (Atmospheric scattering)](http://stainlessbeer.weebly.com/planets-9-atmospheric-scattering.html)
|
|
41
39
|
* * [Accurate Atmospheric Scattering (NVIDIA GPU Gems 2)](https://developer.nvidia.com/gpugems/gpugems2/part-ii-shading-lighting-and-shadows/chapter-16-accurate-atmospheric-scattering).
|
|
42
40
|
*
|
|
43
|
-
* @extends GeometryLayer
|
|
44
|
-
*
|
|
45
41
|
* @param {string} id - The id of the layer Atmosphere.
|
|
46
42
|
* @param {Object} [options] - options layer.
|
|
47
43
|
* @param {number} [options.Kr] - `Kr` is the rayleigh scattering constant.
|