itowns 2.44.3-next.3 → 2.44.3-next.31
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 +3 -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_file_kml_raster_usgs.html +0 -1
- package/examples/source_stream_wfs_raster.html +0 -7
- package/examples/vector_tile_mapbox_raster.html +91 -0
- 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 +6 -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 +60 -42
- 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 +45 -27
- 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 +42 -29
- 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/Label2DRenderer.js +9 -7
- 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 +32 -22
- 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
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import * as CRS from "../Geographic/Crs.js";
|
|
3
|
+
import Coordinates from "../Geographic/Coordinates.js";
|
|
4
|
+
import Extent from "../Geographic/Extent.js";
|
|
5
|
+
import { getInfoTms, getCountTiles } from "./TileGrid.js";
|
|
6
|
+
const _tmsCoord = new THREE.Vector2();
|
|
7
|
+
const _dimensionTile = new THREE.Vector2();
|
|
8
|
+
const r = {
|
|
9
|
+
row: 0,
|
|
10
|
+
col: 0,
|
|
11
|
+
invDiff: 0
|
|
12
|
+
};
|
|
13
|
+
function _rowColfromParent(/** @type {Tile} */tile, /** @type {number} */zoom) {
|
|
14
|
+
const diffLevel = tile.zoom - zoom;
|
|
15
|
+
const diff = 2 ** diffLevel;
|
|
16
|
+
r.invDiff = 1 / diff;
|
|
17
|
+
r.row = (tile.row - tile.row % diff) * r.invDiff;
|
|
18
|
+
r.col = (tile.col - tile.col % diff) * r.invDiff;
|
|
19
|
+
return r;
|
|
20
|
+
}
|
|
21
|
+
const _extent = new Extent('EPSG:4326', [0, 0, 0, 0]);
|
|
22
|
+
const _extent2 = new Extent('EPSG:4326', [0, 0, 0, 0]);
|
|
23
|
+
const _c = new Coordinates('EPSG:4326', 0, 0);
|
|
24
|
+
class Tile {
|
|
25
|
+
/**
|
|
26
|
+
* Tile is a geographical bounding rectangle defined by zoom, row and column.
|
|
27
|
+
*
|
|
28
|
+
* @param {String} crs projection of limit values.
|
|
29
|
+
* @param {number} [zoom=0] zoom value
|
|
30
|
+
* @param {number} [row=0] row value
|
|
31
|
+
* @param {number} [col=0] column value
|
|
32
|
+
*/
|
|
33
|
+
constructor(crs) {
|
|
34
|
+
let zoom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
35
|
+
let row = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
36
|
+
let col = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
|
|
37
|
+
this.isTile = true;
|
|
38
|
+
this.crs = crs;
|
|
39
|
+
this.zoom = zoom;
|
|
40
|
+
this.row = row;
|
|
41
|
+
this.col = col;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Clone this tile
|
|
46
|
+
* @return {Tile} cloned tile
|
|
47
|
+
*/
|
|
48
|
+
clone() {
|
|
49
|
+
return new Tile(this.crs, this.zoom, this.row, this.col);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Convert tile to the specified extent.
|
|
54
|
+
* @param {string} crs the projection of destination.
|
|
55
|
+
* @param {Extent} target copy the destination to target.
|
|
56
|
+
* @return {Extent}
|
|
57
|
+
*/
|
|
58
|
+
toExtent(crs, target) {
|
|
59
|
+
CRS.isValid(crs);
|
|
60
|
+
target = target || new Extent('EPSG:4326', [0, 0, 0, 0]);
|
|
61
|
+
const {
|
|
62
|
+
epsg,
|
|
63
|
+
globalExtent,
|
|
64
|
+
globalDimension
|
|
65
|
+
} = getInfoTms(this.crs);
|
|
66
|
+
const countTiles = getCountTiles(this.crs, this.zoom);
|
|
67
|
+
_dimensionTile.set(1, 1).divide(countTiles).multiply(globalDimension);
|
|
68
|
+
target.west = globalExtent.west + (globalDimension.x - _dimensionTile.x * (countTiles.x - this.col));
|
|
69
|
+
target.east = target.west + _dimensionTile.x;
|
|
70
|
+
target.south = globalExtent.south + _dimensionTile.y * (countTiles.y - this.row - 1);
|
|
71
|
+
target.north = target.south + _dimensionTile.y;
|
|
72
|
+
target.crs = epsg;
|
|
73
|
+
target.zoom = this.zoom;
|
|
74
|
+
return crs == epsg ? target : target.as(crs, target);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Return true if `tile` is inside this tile.
|
|
79
|
+
*
|
|
80
|
+
* @param {Tile} tile the tile to check
|
|
81
|
+
*
|
|
82
|
+
* @return {boolean}
|
|
83
|
+
*/
|
|
84
|
+
isInside(tile) {
|
|
85
|
+
if (this.zoom == tile.zoom) {
|
|
86
|
+
return this.row == tile.row && this.col == tile.col;
|
|
87
|
+
} else if (this.zoom < tile.zoom) {
|
|
88
|
+
return false;
|
|
89
|
+
} else {
|
|
90
|
+
_rowColfromParent(this, tile.zoom);
|
|
91
|
+
return r.row == tile.row && r.col == tile.col;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Return the translation and scale to transform this tile to input tile.
|
|
97
|
+
*
|
|
98
|
+
* @param {Tile} tile input tile
|
|
99
|
+
* @param {THREE.Vector4} target copy the result to target.
|
|
100
|
+
* @return {THREE.Vector4} {x: translation on west-east, y: translation on south-north, z: scale on west-east, w: scale on south-north}
|
|
101
|
+
*/
|
|
102
|
+
offsetToParent(tile) {
|
|
103
|
+
let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new THREE.Vector4();
|
|
104
|
+
if (this.crs != tile.crs) {
|
|
105
|
+
throw new Error('unsupported mix');
|
|
106
|
+
}
|
|
107
|
+
_rowColfromParent(this, tile.zoom);
|
|
108
|
+
return target.set(this.col * r.invDiff - r.col, this.row * r.invDiff - r.row, r.invDiff, r.invDiff);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Return parent tile with input level
|
|
113
|
+
*
|
|
114
|
+
* @param {number} levelParent level of parent.
|
|
115
|
+
* @return {Tile}
|
|
116
|
+
*/
|
|
117
|
+
tiledExtentParent(levelParent) {
|
|
118
|
+
if (levelParent && levelParent < this.zoom) {
|
|
119
|
+
_rowColfromParent(this, levelParent);
|
|
120
|
+
return new Tile(this.crs, levelParent, r.row, r.col);
|
|
121
|
+
} else {
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Set zoom, row and column values
|
|
128
|
+
*
|
|
129
|
+
* @param {number} [zoom=0] zoom value
|
|
130
|
+
* @param {number} [row=0] row value
|
|
131
|
+
* @param {number} [col=0] column value
|
|
132
|
+
*
|
|
133
|
+
* @return {Tile}
|
|
134
|
+
*/
|
|
135
|
+
set() {
|
|
136
|
+
let zoom = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
137
|
+
let row = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
138
|
+
let col = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
139
|
+
this.zoom = zoom;
|
|
140
|
+
this.row = row;
|
|
141
|
+
this.col = col;
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Copy to this tile to input tile.
|
|
147
|
+
* @param {Tile} tile
|
|
148
|
+
* @return {Tile} copied extent
|
|
149
|
+
*/
|
|
150
|
+
copy(tile) {
|
|
151
|
+
this.crs = tile.crs;
|
|
152
|
+
return this.set(tile.zoom, tile.row, tile.col);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Return values of tile in string, separated by the separator input.
|
|
157
|
+
* @param {string} separator
|
|
158
|
+
* @return {string}
|
|
159
|
+
*/
|
|
160
|
+
toString() {
|
|
161
|
+
let separator = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
162
|
+
return `${this.zoom}${separator}${this.row}${separator}${this.col}`;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @param {Extent} e
|
|
168
|
+
* @param {string} tms
|
|
169
|
+
* @returns {Tile[]}
|
|
170
|
+
*/
|
|
171
|
+
export function tiledCovering(e, tms) {
|
|
172
|
+
if (e.crs == 'EPSG:4326' && tms == 'EPSG:3857') {
|
|
173
|
+
const WMTS_PM = [];
|
|
174
|
+
const extent = _extent.copy(e).as(tms, _extent2);
|
|
175
|
+
const {
|
|
176
|
+
globalExtent,
|
|
177
|
+
globalDimension,
|
|
178
|
+
sTs
|
|
179
|
+
} = getInfoTms(tms);
|
|
180
|
+
extent.clampByExtent(globalExtent);
|
|
181
|
+
extent.planarDimensions(_dimensionTile);
|
|
182
|
+
const zoom = e.zoom + 1 || Math.floor(Math.log2(Math.round(globalDimension.x / (_dimensionTile.x * sTs.x))));
|
|
183
|
+
const countTiles = getCountTiles(tms, zoom);
|
|
184
|
+
const center = extent.center(_c);
|
|
185
|
+
_tmsCoord.x = center.x - globalExtent.west;
|
|
186
|
+
_tmsCoord.y = globalExtent.north - extent.north;
|
|
187
|
+
_tmsCoord.divide(globalDimension).multiply(countTiles).floor();
|
|
188
|
+
|
|
189
|
+
// ]N; N+1] => N
|
|
190
|
+
const maxRow = Math.ceil((globalExtent.north - extent.south) / globalDimension.x * countTiles.y) - 1;
|
|
191
|
+
for (let r = maxRow; r >= _tmsCoord.y; r--) {
|
|
192
|
+
WMTS_PM.push(new Tile(tms, zoom, r, _tmsCoord.x));
|
|
193
|
+
}
|
|
194
|
+
return WMTS_PM;
|
|
195
|
+
} else {
|
|
196
|
+
const target = new Tile(tms, 0, 0, 0);
|
|
197
|
+
const {
|
|
198
|
+
globalExtent,
|
|
199
|
+
globalDimension,
|
|
200
|
+
sTs,
|
|
201
|
+
isInverted
|
|
202
|
+
} = getInfoTms(e.crs);
|
|
203
|
+
const center = e.center(_c);
|
|
204
|
+
e.planarDimensions(_dimensionTile);
|
|
205
|
+
// Each level has 2^n * 2^n tiles...
|
|
206
|
+
// ... so we count how many tiles of the same width as tile we can fit in the layer
|
|
207
|
+
// ... 2^zoom = tilecount => zoom = log2(tilecount)
|
|
208
|
+
const zoom = Math.floor(Math.log2(Math.round(globalDimension.x / (_dimensionTile.x * sTs.x))));
|
|
209
|
+
const countTiles = getCountTiles(tms, zoom);
|
|
210
|
+
|
|
211
|
+
// Now that we have computed zoom, we can deduce x and y (or row / column)
|
|
212
|
+
_tmsCoord.x = center.x - globalExtent.west;
|
|
213
|
+
_tmsCoord.y = isInverted ? globalExtent.north - center.y : center.y - globalExtent.south;
|
|
214
|
+
_tmsCoord.divide(globalDimension).multiply(countTiles).floor();
|
|
215
|
+
target.set(zoom, _tmsCoord.y, _tmsCoord.x);
|
|
216
|
+
return [target];
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
export default Tile;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import Extent from "../Geographic/Extent.js";
|
|
3
|
+
const _countTiles = new THREE.Vector2();
|
|
4
|
+
const _dim = new THREE.Vector2();
|
|
5
|
+
export const globalExtentTMS = new Map();
|
|
6
|
+
export const schemeTiles = new Map();
|
|
7
|
+
const extent4326 = new Extent('EPSG:4326', -180, 180, -90, 90);
|
|
8
|
+
globalExtentTMS.set('EPSG:4326', extent4326);
|
|
9
|
+
|
|
10
|
+
// Compute global extent of TMS in EPSG:3857
|
|
11
|
+
// It's square whose a side is between -180° to 180°.
|
|
12
|
+
// So, west extent, it's 180 convert in EPSG:3857
|
|
13
|
+
const extent3857 = extent4326.as('EPSG:3857');
|
|
14
|
+
extent3857.clampSouthNorth(extent3857.west, extent3857.east);
|
|
15
|
+
globalExtentTMS.set('EPSG:3857', extent3857);
|
|
16
|
+
schemeTiles.set('default', new THREE.Vector2(1, 1));
|
|
17
|
+
schemeTiles.set('EPSG:3857', schemeTiles.get('default'));
|
|
18
|
+
schemeTiles.set('EPSG:4326', new THREE.Vector2(2, 1));
|
|
19
|
+
export function getInfoTms(/** @type {string} */crs) {
|
|
20
|
+
const globalExtent = globalExtentTMS.get(crs);
|
|
21
|
+
const globalDimension = globalExtent.planarDimensions(_dim);
|
|
22
|
+
const sTs = schemeTiles.get(crs) || schemeTiles.get('default');
|
|
23
|
+
// The isInverted parameter is to be set to the correct value, true or false
|
|
24
|
+
// (default being false) if the computation of the coordinates needs to be
|
|
25
|
+
// inverted to match the same scheme as OSM, Google Maps or other system.
|
|
26
|
+
// See link below for more information
|
|
27
|
+
// https://alastaira.wordpress.com/2011/07/06/converting-tms-tile-coordinates-to-googlebingosm-tile-coordinates/
|
|
28
|
+
// in crs includes ':NI' => tms isn't inverted (NOT INVERTED)
|
|
29
|
+
const isInverted = !crs.includes(':NI');
|
|
30
|
+
return {
|
|
31
|
+
epsg: crs,
|
|
32
|
+
globalExtent,
|
|
33
|
+
globalDimension,
|
|
34
|
+
sTs,
|
|
35
|
+
isInverted
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function getCountTiles(/** @type {string} */crs, /** @type {number} */zoom) {
|
|
39
|
+
const sTs = schemeTiles.get(crs) || schemeTiles.get('default');
|
|
40
|
+
const count = 2 ** zoom;
|
|
41
|
+
_countTiles.set(count, count).multiply(sTs);
|
|
42
|
+
return _countTiles;
|
|
43
|
+
}
|
package/lib/Core/TileGeometry.js
CHANGED
|
@@ -1,40 +1,124 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
-
import computeBuffers,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
2
|
+
import { computeBuffers, getBufferIndexSize } from "./Prefab/computeBufferTileGeometry.js";
|
|
3
|
+
import Coordinates from "./Geographic/Coordinates.js";
|
|
4
|
+
function defaultBuffers(builder, params) {
|
|
5
|
+
const fullParams = {
|
|
6
|
+
disableSkirt: false,
|
|
7
|
+
hideSkirt: false,
|
|
8
|
+
buildIndexAndUv_0: true,
|
|
9
|
+
segments: 16,
|
|
10
|
+
coordinates: new Coordinates(builder.crs),
|
|
11
|
+
center: builder.center(params.extent).clone(),
|
|
12
|
+
...params
|
|
13
|
+
};
|
|
14
|
+
const buffers = computeBuffers(builder, fullParams);
|
|
15
|
+
const bufferAttributes = {
|
|
16
|
+
index: buffers.index ? new THREE.BufferAttribute(buffers.index, 1) : null,
|
|
17
|
+
uvs: [...(buffers.uvs[0] ? [new THREE.BufferAttribute(buffers.uvs[0], 2)] : []), ...(buffers.uvs[1] ? [new THREE.BufferAttribute(buffers.uvs[1], 1)] : [])],
|
|
18
|
+
position: new THREE.BufferAttribute(buffers.position, 3),
|
|
19
|
+
normal: new THREE.BufferAttribute(buffers.normal, 3)
|
|
20
|
+
};
|
|
21
|
+
return bufferAttributes;
|
|
15
22
|
}
|
|
16
|
-
class TileGeometry extends THREE.BufferGeometry {
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
export class TileGeometry extends THREE.BufferGeometry {
|
|
24
|
+
/** Oriented Bounding Box of the tile geometry. */
|
|
25
|
+
|
|
26
|
+
/** Ground area covered by this tile geometry. */
|
|
27
|
+
|
|
28
|
+
/** Resolution of the tile geometry in segments per side. */
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* [TileGeometry] instances are shared between tiles. Since a geometry
|
|
32
|
+
* handles its own GPU resource, it needs a reference counter to dispose of
|
|
33
|
+
* that resource only when it is discarded by every single owner of a
|
|
34
|
+
* reference to the geometry.
|
|
35
|
+
*/
|
|
36
|
+
// https://github.com/iTowns/itowns/pull/2440#discussion_r1860743294
|
|
37
|
+
// TODO: Remove nullability by reworking OBB:setFromExtent
|
|
38
|
+
|
|
39
|
+
constructor(builder, params) {
|
|
40
|
+
let bufferAttributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultBuffers(builder, params);
|
|
19
41
|
super();
|
|
20
|
-
this.center = params.center;
|
|
21
42
|
this.extent = params.extent;
|
|
22
43
|
this.segments = params.segments;
|
|
23
|
-
this.setIndex(
|
|
24
|
-
this.setAttribute('position',
|
|
25
|
-
this.setAttribute('normal',
|
|
26
|
-
this.setAttribute('uv',
|
|
27
|
-
for (let i = 1; i <
|
|
28
|
-
this.setAttribute(`uv_${i}`,
|
|
44
|
+
this.setIndex(bufferAttributes.index);
|
|
45
|
+
this.setAttribute('position', bufferAttributes.position);
|
|
46
|
+
this.setAttribute('normal', bufferAttributes.normal);
|
|
47
|
+
this.setAttribute('uv', bufferAttributes.uvs[0]);
|
|
48
|
+
for (let i = 1; i < bufferAttributes.uvs.length; i++) {
|
|
49
|
+
this.setAttribute(`uv_${i}`, bufferAttributes.uvs[i]);
|
|
29
50
|
}
|
|
30
51
|
this.computeBoundingBox();
|
|
31
|
-
this.OBB =
|
|
52
|
+
this.OBB = null;
|
|
32
53
|
if (params.hideSkirt) {
|
|
33
54
|
this.hideSkirt = params.hideSkirt;
|
|
34
55
|
}
|
|
56
|
+
this._refCount = null;
|
|
35
57
|
}
|
|
36
|
-
|
|
37
|
-
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Enables or disables skirt rendering.
|
|
61
|
+
*
|
|
62
|
+
* @param toggle - Whether to hide the skirt; true hides, false shows.
|
|
63
|
+
*/
|
|
64
|
+
set hideSkirt(toggle) {
|
|
65
|
+
this.setDrawRange(0, getBufferIndexSize(this.segments, toggle));
|
|
38
66
|
}
|
|
39
|
-
|
|
40
|
-
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Initialize reference count for this geometry if it is currently null.
|
|
70
|
+
*
|
|
71
|
+
* @param cacheTile - The [Cache] used to store this geometry.
|
|
72
|
+
* @param keys - The [south, level, epsg] key of this geometry.
|
|
73
|
+
*/
|
|
74
|
+
initRefCount(cacheTile, keys) {
|
|
75
|
+
if (this._refCount !== null) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
this._refCount = {
|
|
79
|
+
count: 0,
|
|
80
|
+
fn: () => {
|
|
81
|
+
this._refCount.count--;
|
|
82
|
+
if (this._refCount.count <= 0) {
|
|
83
|
+
// To avoid remove index buffer and attribute buffer uv
|
|
84
|
+
// error un-bound buffer in webgl with VAO rendering.
|
|
85
|
+
// Could be removed if the attribute buffer deleting is
|
|
86
|
+
// taken into account in the buffer binding state
|
|
87
|
+
// (in THREE.WebGLBindingStates code).
|
|
88
|
+
this.index = null;
|
|
89
|
+
delete this.attributes.uv;
|
|
90
|
+
cacheTile.delete(...keys);
|
|
91
|
+
super.dispose();
|
|
92
|
+
// THREE.BufferGeometry.prototype.dispose.call(this);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Increase reference count.
|
|
100
|
+
*
|
|
101
|
+
* @throws If reference count has not been initialized.
|
|
102
|
+
*/
|
|
103
|
+
increaseRefCount() {
|
|
104
|
+
if (this._refCount === null) {
|
|
105
|
+
throw new Error('[TileGeometry::increaseRefCount] ' + 'Tried to increment an unitialized reference count.');
|
|
106
|
+
}
|
|
107
|
+
this._refCount.count++;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The current reference count of this [TileGeometry] if it has been
|
|
112
|
+
* initialized.
|
|
113
|
+
*/
|
|
114
|
+
get refCount() {
|
|
115
|
+
return this._refCount?.count;
|
|
116
|
+
}
|
|
117
|
+
dispose() {
|
|
118
|
+
if (this._refCount == null) {
|
|
119
|
+
super.dispose();
|
|
120
|
+
} else {
|
|
121
|
+
this._refCount.fn();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
package/lib/Core/TileMesh.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
-
import CRS from "./Geographic/Crs.js";
|
|
3
2
|
import { geoidLayerIsVisible } from "../Layer/GeoidLayer.js";
|
|
3
|
+
import { tiledCovering } from "./Tile/Tile.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* A TileMesh is a THREE.Mesh with a geometricError and an OBB
|
|
@@ -29,7 +29,7 @@ class TileMesh extends THREE.Mesh {
|
|
|
29
29
|
this.boundingSphere = new THREE.Sphere();
|
|
30
30
|
this.obb.box3D.getBoundingSphere(this.boundingSphere);
|
|
31
31
|
for (const tms of layer.tileMatrixSets) {
|
|
32
|
-
this.#_tms.set(tms, this.extent
|
|
32
|
+
this.#_tms.set(tms, tiledCovering(this.extent, tms));
|
|
33
33
|
}
|
|
34
34
|
this.frustumCulled = false;
|
|
35
35
|
this.matrixAutoUpdate = false;
|
|
@@ -70,7 +70,7 @@ class TileMesh extends THREE.Mesh {
|
|
|
70
70
|
this.obb.box3D.getBoundingSphere(this.boundingSphere);
|
|
71
71
|
}
|
|
72
72
|
getExtentsByProjection(crs) {
|
|
73
|
-
return this.#_tms.get(
|
|
73
|
+
return this.#_tms.get(crs);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
/**
|
package/lib/Core/View.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
+
import * as CRS from "./Geographic/Crs.js";
|
|
2
3
|
import Camera from "../Renderer/Camera.js";
|
|
3
4
|
import initializeWebXR from "../Renderer/WebXR.js";
|
|
4
5
|
import MainLoop, { MAIN_LOOP_EVENTS, RENDERING_PAUSED } from "./MainLoop.js";
|
|
@@ -6,7 +7,6 @@ import Capabilities from "./System/Capabilities.js";
|
|
|
6
7
|
import { COLOR_LAYERS_ORDER_CHANGED } from "../Renderer/ColorLayersOrdering.js";
|
|
7
8
|
import c3DEngine from "../Renderer/c3DEngine.js";
|
|
8
9
|
import RenderMode from "../Renderer/RenderMode.js";
|
|
9
|
-
import CRS from "./Geographic/Crs.js";
|
|
10
10
|
import Coordinates from "./Geographic/Coordinates.js";
|
|
11
11
|
import FeaturesUtils from "../Utils/FeaturesUtils.js";
|
|
12
12
|
import { getMaxColorSamplerUnitsCount } from "../Renderer/LayeredMaterial.js";
|
|
@@ -30,7 +30,8 @@ export const VIEW_EVENTS = {
|
|
|
30
30
|
LAYER_ADDED: 'layer-added',
|
|
31
31
|
INITIALIZED: 'initialized',
|
|
32
32
|
COLOR_LAYERS_ORDER_CHANGED,
|
|
33
|
-
CAMERA_MOVED: 'camera-moved'
|
|
33
|
+
CAMERA_MOVED: 'camera-moved',
|
|
34
|
+
DISPOSED: 'disposed'
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
/**
|
|
@@ -52,7 +53,7 @@ function _preprocessLayer(view, layer, parentLayer) {
|
|
|
52
53
|
// Find crs projection layer, this is projection destination
|
|
53
54
|
layer.crs = view.referenceCrs;
|
|
54
55
|
} else if (!layer.crs) {
|
|
55
|
-
if (parentLayer && parentLayer.tileMatrixSets && parentLayer.tileMatrixSets.includes(
|
|
56
|
+
if (parentLayer && parentLayer.tileMatrixSets && parentLayer.tileMatrixSets.includes(source.crs)) {
|
|
56
57
|
layer.crs = source.crs;
|
|
57
58
|
} else {
|
|
58
59
|
layer.crs = parentLayer && parentLayer.extent.crs;
|
|
@@ -109,9 +110,11 @@ const coordinates = new Coordinates('EPSG:4326');
|
|
|
109
110
|
const viewers = [];
|
|
110
111
|
// Size of the camera frustrum, in meters
|
|
111
112
|
let screenMeters;
|
|
113
|
+
let id = 0;
|
|
112
114
|
|
|
113
115
|
/**
|
|
114
|
-
* @property {
|
|
116
|
+
* @property {number} id - The id of the view. It's incremented at each new view instance, starting at 0.
|
|
117
|
+
* @property {HTMLElement} domElement - The domElement holding the canvas where the view is displayed
|
|
115
118
|
* @property {String} referenceCrs - The coordinate reference system of the view
|
|
116
119
|
* @property {MainLoop} mainLoop - itowns mainloop scheduling the operations
|
|
117
120
|
* @property {THREE.Scene} scene - threejs scene of the view
|
|
@@ -136,10 +139,10 @@ class View extends THREE.EventDispatcher {
|
|
|
136
139
|
* var view = itowns.View('EPSG:4326', viewerDiv, { camera: { type: itowns.CAMERA_TYPE.ORTHOGRAPHIC } });
|
|
137
140
|
* var customControls = itowns.THREE.OrbitControls(view.camera3D, viewerDiv);
|
|
138
141
|
*
|
|
139
|
-
* @param {
|
|
142
|
+
* @param {String} crs - The default CRS of Three.js coordinates. Should be a cartesian CRS.
|
|
140
143
|
* @param {HTMLElement} viewerDiv - Where to instanciate the Three.js scene in the DOM
|
|
141
144
|
* @param {Object} [options] - Optional properties.
|
|
142
|
-
* @param {
|
|
145
|
+
* @param {Object} [options.camera] - Options for the camera associated to the view. See {@link Camera} options.
|
|
143
146
|
* @param {MainLoop} [options.mainLoop] - {@link MainLoop} instance to use, otherwise a default one will be constructed
|
|
144
147
|
* @param {WebGLRenderer|Object} [options.renderer] - {@link WebGLRenderer} instance to use, otherwise
|
|
145
148
|
* a default one will be constructed. In this case, if options.renderer is an object, it will be used to
|
|
@@ -159,6 +162,7 @@ class View extends THREE.EventDispatcher {
|
|
|
159
162
|
}
|
|
160
163
|
super();
|
|
161
164
|
this.domElement = viewerDiv;
|
|
165
|
+
this.id = id++;
|
|
162
166
|
this.referenceCrs = crs;
|
|
163
167
|
let engine;
|
|
164
168
|
// options.renderer can be 2 separate things:
|
|
@@ -272,8 +276,6 @@ class View extends THREE.EventDispatcher {
|
|
|
272
276
|
}
|
|
273
277
|
// remove alls frameRequester
|
|
274
278
|
this.removeAllFrameRequesters();
|
|
275
|
-
// remove alls events
|
|
276
|
-
this.removeAllEvents();
|
|
277
279
|
// remove all layers
|
|
278
280
|
const layers = this.getLayers(l => !l.isTiledGeometryLayer && !l.isAtmosphere);
|
|
279
281
|
for (const layer of layers) {
|
|
@@ -290,6 +292,11 @@ class View extends THREE.EventDispatcher {
|
|
|
290
292
|
viewers.splice(id, 1);
|
|
291
293
|
// Remove remaining objects in the scene (e.g. helpers, debug, etc.)
|
|
292
294
|
this.scene.traverse(ObjectRemovalHelper.cleanup);
|
|
295
|
+
this.dispatchEvent({
|
|
296
|
+
type: VIEW_EVENTS.DISPOSED
|
|
297
|
+
});
|
|
298
|
+
// remove alls events
|
|
299
|
+
this.removeAllEvents();
|
|
293
300
|
}
|
|
294
301
|
|
|
295
302
|
/**
|
|
@@ -51,11 +51,14 @@ function findTileID(object) {
|
|
|
51
51
|
function object3DHasFeature(object3d) {
|
|
52
52
|
return object3d.geometry && object3d.geometry.attributes._BATCHID;
|
|
53
53
|
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @extends GeometryLayer
|
|
57
|
+
*/
|
|
54
58
|
class C3DTilesLayer extends GeometryLayer {
|
|
55
59
|
#fillColorMaterialsBuffer;
|
|
56
60
|
/**
|
|
57
61
|
* @deprecated Deprecated 3D Tiles layer. Use {@link OGC3DTilesLayer} instead.
|
|
58
|
-
* @extends GeometryLayer
|
|
59
62
|
*
|
|
60
63
|
* @example
|
|
61
64
|
* // Create a new 3d-tiles layer from a web server
|
|
@@ -83,7 +86,7 @@ class C3DTilesLayer extends GeometryLayer {
|
|
|
83
86
|
* {@link View} that already has a layer going by that id.
|
|
84
87
|
* @param {object} config configuration, all elements in it
|
|
85
88
|
* will be merged as is in the layer.
|
|
86
|
-
* @param {
|
|
89
|
+
* @param {C3DTilesSource} config.source The source of 3d Tiles.
|
|
87
90
|
*
|
|
88
91
|
* name.
|
|
89
92
|
* @param {Number} [config.sseThreshold=16] The [Screen Space Error](https://github.com/CesiumGS/3d-tiles/blob/main/specification/README.md#geometric-error)
|
|
@@ -102,6 +105,7 @@ class C3DTilesLayer extends GeometryLayer {
|
|
|
102
105
|
* @param {View} view The view
|
|
103
106
|
*/
|
|
104
107
|
constructor(id, config, view) {
|
|
108
|
+
console.warn('C3DTilesLayer is deprecated and will be removed in iTowns 3.0 version. Use OGC3DTilesLayer instead.');
|
|
105
109
|
super(id, new THREE.Group(), {
|
|
106
110
|
source: config.source
|
|
107
111
|
});
|
|
@@ -142,7 +146,7 @@ class C3DTilesLayer extends GeometryLayer {
|
|
|
142
146
|
}
|
|
143
147
|
}
|
|
144
148
|
|
|
145
|
-
/** @type {Style} */
|
|
149
|
+
/** @type {Style | null} */
|
|
146
150
|
this._style = config.style || null;
|
|
147
151
|
|
|
148
152
|
/** @type {Map<string, THREE.MeshStandardMaterial>} */
|
|
@@ -368,21 +372,15 @@ class C3DTilesLayer extends GeometryLayer {
|
|
|
368
372
|
if (c3DTileFeature.object3d != object3d) {
|
|
369
373
|
continue; // this feature do not belong to object3d
|
|
370
374
|
}
|
|
375
|
+
this._style.context.setGeometry({
|
|
376
|
+
properties: c3DTileFeature
|
|
377
|
+
});
|
|
378
|
+
|
|
371
379
|
/** @type {THREE.Color} */
|
|
372
|
-
|
|
373
|
-
if (typeof this._style.fill.color === 'function') {
|
|
374
|
-
color = new THREE.Color(this._style.fill.color(c3DTileFeature));
|
|
375
|
-
} else {
|
|
376
|
-
color = new THREE.Color(this._style.fill.color);
|
|
377
|
-
}
|
|
380
|
+
const color = new THREE.Color(this._style.fill.color);
|
|
378
381
|
|
|
379
382
|
/** @type {number} */
|
|
380
|
-
|
|
381
|
-
if (typeof this._style.fill.opacity === 'function') {
|
|
382
|
-
opacity = this._style.fill.opacity(c3DTileFeature);
|
|
383
|
-
} else {
|
|
384
|
-
opacity = this._style.fill.opacity;
|
|
385
|
-
}
|
|
383
|
+
const opacity = this._style.fill.opacity;
|
|
386
384
|
const materialId = color.getHexString() + opacity;
|
|
387
385
|
let material = null;
|
|
388
386
|
if (this.#fillColorMaterialsBuffer.has(materialId)) {
|
|
@@ -445,7 +443,13 @@ class C3DTilesLayer extends GeometryLayer {
|
|
|
445
443
|
return this.#fillColorMaterialsBuffer.size;
|
|
446
444
|
}
|
|
447
445
|
set style(value) {
|
|
448
|
-
|
|
446
|
+
if (value instanceof Style) {
|
|
447
|
+
this._style = value;
|
|
448
|
+
} else if (!value) {
|
|
449
|
+
this._style = null;
|
|
450
|
+
} else {
|
|
451
|
+
this._style = new Style(value);
|
|
452
|
+
}
|
|
449
453
|
this.updateStyle();
|
|
450
454
|
}
|
|
451
455
|
get style() {
|
package/lib/Layer/ColorLayer.js
CHANGED
|
@@ -44,6 +44,8 @@ import { deprecatedColorLayerOptions } from "../Core/Deprecated/Undeprecator.js"
|
|
|
44
44
|
* * `1`: used to amplify the transparency effect.
|
|
45
45
|
* * `2`: unused.
|
|
46
46
|
* * `3`: could be used by your own glsl code.
|
|
47
|
+
*
|
|
48
|
+
* @extends RasterLayer
|
|
47
49
|
*/
|
|
48
50
|
class ColorLayer extends RasterLayer {
|
|
49
51
|
/**
|
|
@@ -51,8 +53,6 @@ class ColorLayer extends RasterLayer {
|
|
|
51
53
|
* it can be an aerial view of the ground or a simple transparent layer with the
|
|
52
54
|
* roads displayed.
|
|
53
55
|
*
|
|
54
|
-
* @extends Layer
|
|
55
|
-
*
|
|
56
56
|
* @param {string} id - The id of the layer, that should be unique. It is
|
|
57
57
|
* not mandatory, but an error will be emitted if this layer is added a
|
|
58
58
|
* {@link View} that already has a layer going by that id.
|
|
@@ -92,15 +92,41 @@ class ColorLayer extends RasterLayer {
|
|
|
92
92
|
constructor(id) {
|
|
93
93
|
let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
94
94
|
deprecatedColorLayerOptions(config);
|
|
95
|
-
|
|
95
|
+
const {
|
|
96
|
+
effect_type = 0,
|
|
97
|
+
effect_parameter = 1.0,
|
|
98
|
+
transparent,
|
|
99
|
+
...rasterConfig
|
|
100
|
+
} = config;
|
|
101
|
+
super(id, rasterConfig);
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @type {boolean}
|
|
105
|
+
* @readonly
|
|
106
|
+
*/
|
|
96
107
|
this.isColorLayer = true;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @type {boolean}
|
|
111
|
+
*/
|
|
112
|
+
this.visible = true;
|
|
113
|
+
this.defineLayerProperty('visible', this.visible);
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @type {number}
|
|
117
|
+
*/
|
|
118
|
+
this.opacity = 1.0;
|
|
119
|
+
this.defineLayerProperty('opacity', this.opacity);
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @type {number}
|
|
123
|
+
*/
|
|
124
|
+
this.sequence = 0;
|
|
125
|
+
this.defineLayerProperty('sequence', this.sequence);
|
|
126
|
+
this.transparent = transparent || this.opacity < 1.0;
|
|
101
127
|
this.noTextureParentOutsideLimit = config.source ? config.source.isFileSource : false;
|
|
102
|
-
this.effect_type =
|
|
103
|
-
this.effect_parameter =
|
|
128
|
+
this.effect_type = effect_type;
|
|
129
|
+
this.effect_parameter = effect_parameter;
|
|
104
130
|
|
|
105
131
|
// Feature options
|
|
106
132
|
this.buildExtent = true;
|