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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Vector2, Vector3 } from 'three';
|
|
2
2
|
import Protobuf from 'pbf';
|
|
3
3
|
import { VectorTile } from '@mapbox/vector-tile';
|
|
4
|
-
import { globalExtentTMS } from "../Core/
|
|
4
|
+
import { globalExtentTMS } from "../Core/Tile/TileGrid.js";
|
|
5
5
|
import { FeatureCollection, FEATURE_TYPES } from "../Core/Feature.js";
|
|
6
6
|
import { deprecatedParsingOptionsToNewOne } from "../Core/Deprecated/Undeprecator.js";
|
|
7
7
|
import Coordinates from "../Core/Geographic/Coordinates.js";
|
|
@@ -105,9 +105,10 @@ function vtFeatureToFeatureGeometry(vtFeature, feature) {
|
|
|
105
105
|
function readPBF(file, options) {
|
|
106
106
|
options.out = options.out || {};
|
|
107
107
|
const vectorTile = new VectorTile(new Protobuf(file));
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
const vtLayerNames = Object.keys(vectorTile.layers);
|
|
109
|
+
const collection = new FeatureCollection(options.out);
|
|
110
|
+
if (vtLayerNames.length < 1) {
|
|
111
|
+
return Promise.resolve(collection);
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
// x,y,z tile coordinates
|
|
@@ -117,44 +118,56 @@ function readPBF(file, options) {
|
|
|
117
118
|
// https://alastaira.wordpress.com/2011/07/06/converting-tms-tile-coordinates-to-googlebingosm-tile-coordinates/
|
|
118
119
|
// Only if the layer.origin is top
|
|
119
120
|
const y = options.in.isInverted ? options.extent.row : (1 << z) - options.extent.row - 1;
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const size = vFeature.extent * 2 ** z;
|
|
121
|
+
const vFeature0 = vectorTile.layers[vtLayerNames[0]];
|
|
122
|
+
// TODO: verify if size is correct because is computed with only one feature (vFeature0).
|
|
123
|
+
const size = vFeature0.extent * 2 ** z;
|
|
124
124
|
const center = -0.5 * size;
|
|
125
125
|
collection.scale.set(globalExtent.x / size, -globalExtent.y / size, 1);
|
|
126
|
-
collection.position.set(
|
|
126
|
+
collection.position.set(vFeature0.extent * x + center, vFeature0.extent * y + center, 0).multiply(collection.scale);
|
|
127
127
|
collection.updateMatrixWorld();
|
|
128
|
-
|
|
129
|
-
if (!options.in.layers[
|
|
130
|
-
return;
|
|
128
|
+
vtLayerNames.forEach(vtLayerName => {
|
|
129
|
+
if (!options.in.layers[vtLayerName]) {
|
|
130
|
+
return Promise.resolve(collection);
|
|
131
131
|
}
|
|
132
|
-
const
|
|
133
|
-
for (let i =
|
|
134
|
-
const vtFeature =
|
|
132
|
+
const vectorTileLayer = vectorTile.layers[vtLayerName];
|
|
133
|
+
for (let i = vectorTileLayer.length - 1; i >= 0; i--) {
|
|
134
|
+
const vtFeature = vectorTileLayer.feature(i);
|
|
135
135
|
vtFeature.tileNumbers = {
|
|
136
136
|
x,
|
|
137
137
|
y: options.extent.row,
|
|
138
138
|
z
|
|
139
139
|
};
|
|
140
|
-
|
|
140
|
+
// Find layers where this vtFeature is used
|
|
141
|
+
const layers = options.in.layers[vtLayerName].filter(l => l.filterExpression.filter({
|
|
141
142
|
zoom: z
|
|
142
|
-
}, vtFeature)
|
|
143
|
+
}, vtFeature));
|
|
144
|
+
for (const layer of layers) {
|
|
145
|
+
const feature = collection.requestFeatureById(layer.id, vtFeature.type - 1);
|
|
146
|
+
feature.id = layer.id;
|
|
147
|
+
feature.order = layer.order;
|
|
148
|
+
feature.style = options.in.styles[feature.id];
|
|
149
|
+
vtFeatureToFeatureGeometry(vtFeature, feature);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/*
|
|
153
|
+
// This optimization is not fully working and need to be reassessed
|
|
154
|
+
// (see https://github.com/iTowns/itowns/pull/2469/files#r1861802136)
|
|
143
155
|
let feature;
|
|
144
156
|
for (const layer of layers) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
+
if (!feature) {
|
|
158
|
+
feature = collection.requestFeatureById(layer.id, vtFeature.type - 1);
|
|
159
|
+
feature.id = layer.id;
|
|
160
|
+
feature.order = layer.order;
|
|
161
|
+
feature.style = options.in.styles[feature.id];
|
|
162
|
+
vtFeatureToFeatureGeometry(vtFeature, feature);
|
|
163
|
+
} else if (!collection.features.find(f => f.id === layer.id)) {
|
|
164
|
+
feature = collection.newFeatureByReference(feature);
|
|
165
|
+
feature.id = layer.id;
|
|
166
|
+
feature.order = layer.order;
|
|
167
|
+
feature.style = options.in.styles[feature.id];
|
|
168
|
+
}
|
|
157
169
|
}
|
|
170
|
+
*/
|
|
158
171
|
}
|
|
159
172
|
});
|
|
160
173
|
collection.removeEmptyFeature();
|
package/lib/Parser/XbilParser.js
CHANGED
|
@@ -67,10 +67,22 @@ export function computeMinMaxElevation(texture, pitch, options) {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Clamp values to zmin and zmax values configured in ElevationLayer
|
|
73
|
+
if (options.zmin != null) {
|
|
74
|
+
if (min < options.zmin) {
|
|
71
75
|
min = options.zmin;
|
|
72
76
|
}
|
|
73
|
-
if (
|
|
77
|
+
if (max < options.zmin) {
|
|
78
|
+
max = options.zmin;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (options.zmax != null) {
|
|
82
|
+
if (min > options.zmax) {
|
|
83
|
+
min = options.zmax;
|
|
84
|
+
}
|
|
85
|
+
if (max > options.zmax) {
|
|
74
86
|
max = options.zmax;
|
|
75
87
|
}
|
|
76
88
|
}
|
package/lib/Provider/Fetcher.js
CHANGED
|
@@ -102,7 +102,11 @@ export default {
|
|
|
102
102
|
res = resolve;
|
|
103
103
|
rej = reject;
|
|
104
104
|
});
|
|
105
|
-
textureLoader.load(url, res, () => {},
|
|
105
|
+
textureLoader.load(url, res, () => {}, event => {
|
|
106
|
+
const error = new Error(`Failed to load texture from URL: \`${url}\``);
|
|
107
|
+
error.originalEvent = event;
|
|
108
|
+
rej(error);
|
|
109
|
+
});
|
|
106
110
|
return promise;
|
|
107
111
|
},
|
|
108
112
|
/**
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import Extent from "../Core/Geographic/Extent.js";
|
|
2
|
-
const extent = new Extent('EPSG:4326', [0, 0, 0, 0]);
|
|
3
1
|
let subDomainsCount = 0;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {string} url
|
|
5
|
+
* @returns {string}
|
|
6
|
+
*/
|
|
4
7
|
function subDomains(url) {
|
|
5
8
|
const subDomainsPtrn = /\$\{u:([\w-_.|]+)\}/.exec(url);
|
|
6
9
|
if (!subDomainsPtrn) {
|
|
@@ -51,8 +54,13 @@ export default {
|
|
|
51
54
|
* // The resulting url is:
|
|
52
55
|
* // http://server.geo/tms/15/2142/3412.jpg;
|
|
53
56
|
*
|
|
54
|
-
* @param {
|
|
55
|
-
* @param {
|
|
57
|
+
* @param {Object} coords - tile coordinates
|
|
58
|
+
* @param {number} coords.row - tile row
|
|
59
|
+
* @param {number} coords.col - tile column
|
|
60
|
+
* @param {number} coords.zoom - tile zoom
|
|
61
|
+
* @param {Object} source
|
|
62
|
+
* @param {string} source.url
|
|
63
|
+
* @param {Function} source.tileMatrixCallback
|
|
56
64
|
*
|
|
57
65
|
* @return {string} the formed url
|
|
58
66
|
*/
|
|
@@ -79,8 +87,12 @@ export default {
|
|
|
79
87
|
* // The resulting url is:
|
|
80
88
|
* // http://server.geo/wms/BBOX=12,35,14,46&FORMAT=jpg&SERVICE=WMS
|
|
81
89
|
*
|
|
82
|
-
* @param {
|
|
83
|
-
* @param {
|
|
90
|
+
* @param {Object} bbox - the bounding box
|
|
91
|
+
* @param {number} bbox.west
|
|
92
|
+
* @param {number} bbox.south
|
|
93
|
+
* @param {number} bbox.east
|
|
94
|
+
* @param {number} bbox.north
|
|
95
|
+
* @param {Object} source - the source of data
|
|
84
96
|
* @param {string} source.crs
|
|
85
97
|
* @param {number} source.bboxDigits
|
|
86
98
|
* @param {string} source.url
|
|
@@ -93,11 +105,10 @@ export default {
|
|
|
93
105
|
if (source.bboxDigits !== undefined) {
|
|
94
106
|
precision = source.bboxDigits;
|
|
95
107
|
}
|
|
96
|
-
bbox.
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
const n = extent.north.toFixed(precision);
|
|
108
|
+
const w = bbox.west.toFixed(precision);
|
|
109
|
+
const s = bbox.south.toFixed(precision);
|
|
110
|
+
const e = bbox.east.toFixed(precision);
|
|
111
|
+
const n = bbox.north.toFixed(precision);
|
|
101
112
|
let bboxInUnit = source.axisOrder || 'wsen';
|
|
102
113
|
bboxInUnit = bboxInUnit.replace('w', `${w},`).replace('s', `${s},`).replace('e', `${e},`).replace('n', `${n},`).slice(0, -1);
|
|
103
114
|
return subDomains(source.url.replace('%bbox', bboxInUnit));
|
package/lib/Renderer/Camera.js
CHANGED
|
@@ -173,7 +173,7 @@ class Camera {
|
|
|
173
173
|
* @return {Coordinates} Coordinates object holding camera's position.
|
|
174
174
|
*/
|
|
175
175
|
position(crs) {
|
|
176
|
-
return new Coordinates(this.crs
|
|
176
|
+
return new Coordinates(this.crs).setFromVector3(this.camera3D.position).as(crs || this.crs);
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
/**
|
|
@@ -167,13 +167,15 @@ class Label2DRenderer {
|
|
|
167
167
|
if (!frustum.containsPoint(worldPosition.applyMatrix4(camera.matrixWorldInverse)) ||
|
|
168
168
|
// Check if globe horizon culls the label
|
|
169
169
|
// Do some horizon culling (if possible) if the tiles level is small enough.
|
|
170
|
-
label.horizonCullingPoint && GlobeLayer.horizonCulling(label.horizonCullingPoint)
|
|
171
|
-
//
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
170
|
+
label.horizonCullingPoint && GlobeLayer.horizonCulling(label.horizonCullingPoint)
|
|
171
|
+
// Why do we might need this part ?
|
|
172
|
+
// || // Check if content isn't present in visible labels
|
|
173
|
+
// this.grid.visible.some((l) => {
|
|
174
|
+
// // TODO for icon without text filter by position
|
|
175
|
+
// const textContent = label.content.textContent;
|
|
176
|
+
// return textContent !== '' && l.content.textContent.toLowerCase() == textContent.toLowerCase();
|
|
177
|
+
// })
|
|
178
|
+
) {
|
|
177
179
|
label.visible = false;
|
|
178
180
|
} else {
|
|
179
181
|
// projecting world position label
|
package/lib/Renderer/OBB.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import * as CRS from "../Core/Geographic/Crs.js";
|
|
3
|
+
import { TileGeometry } from "../Core/TileGeometry.js";
|
|
4
|
+
import { GlobeTileBuilder } from "../Core/Prefab/Globe/GlobeTileBuilder.js";
|
|
4
5
|
import Coordinates from "../Core/Geographic/Coordinates.js";
|
|
5
|
-
import CRS from "../Core/Geographic/Crs.js";
|
|
6
6
|
|
|
7
7
|
// get oriented bounding box of tile
|
|
8
|
-
const builder = new
|
|
9
|
-
crs: 'EPSG:4978',
|
|
8
|
+
const builder = new GlobeTileBuilder({
|
|
10
9
|
uvCount: 1
|
|
11
10
|
});
|
|
12
11
|
const size = new THREE.Vector3();
|
|
@@ -114,18 +113,17 @@ class OBB extends THREE.Object3D {
|
|
|
114
113
|
let maxHeight = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : extent.max || 0;
|
|
115
114
|
if (extent.crs == 'EPSG:4326') {
|
|
116
115
|
const {
|
|
117
|
-
|
|
116
|
+
shareableExtent,
|
|
118
117
|
quaternion,
|
|
119
118
|
position
|
|
120
|
-
} = builder.
|
|
119
|
+
} = builder.computeShareableExtent(extent);
|
|
121
120
|
// Compute the minimum count of segment to build tile
|
|
122
|
-
const segments = Math.max(Math.floor(
|
|
123
|
-
const geometry = new TileGeometry({
|
|
124
|
-
extent:
|
|
121
|
+
const segments = Math.max(Math.floor(shareableExtent.planarDimensions(dimension).x / 90 + 1), 2);
|
|
122
|
+
const geometry = new TileGeometry(builder, {
|
|
123
|
+
extent: shareableExtent,
|
|
125
124
|
level: 0,
|
|
126
125
|
segments,
|
|
127
|
-
disableSkirt: true
|
|
128
|
-
builder
|
|
126
|
+
disableSkirt: true
|
|
129
127
|
});
|
|
130
128
|
obb.box3D.copy(geometry.boundingBox);
|
|
131
129
|
obb.natBox.copy(geometry.boundingBox);
|
|
@@ -137,7 +135,7 @@ class OBB extends THREE.Object3D {
|
|
|
137
135
|
this.position.copy(position);
|
|
138
136
|
this.quaternion.copy(quaternion);
|
|
139
137
|
this.updateMatrixWorld(true);
|
|
140
|
-
} else if (
|
|
138
|
+
} else if (CRS.isMetricUnit(extent.crs)) {
|
|
141
139
|
extent.center(coord).toVector3(this.position);
|
|
142
140
|
extent.planarDimensions(dimension);
|
|
143
141
|
size.set(dimension.x, dimension.y, Math.abs(maxHeight - minHeight));
|
|
@@ -258,7 +258,7 @@ class PointsMaterial extends THREE.ShaderMaterial {
|
|
|
258
258
|
/**
|
|
259
259
|
* @class PointsMaterial
|
|
260
260
|
* @param {object} [options={}] The options
|
|
261
|
-
* @param {number} [options.size=
|
|
261
|
+
* @param {number} [options.size=1] point size
|
|
262
262
|
* @param {number} [options.mode=PNTS_MODE.COLOR] display mode.
|
|
263
263
|
* @param {number} [options.shape=PNTS_SHAPE.CIRCLE] rendered points shape.
|
|
264
264
|
* @param {THREE.Vector4} [options.overlayColor=new THREE.Vector4(0, 0, 0, 0)] overlay color.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
import { ELEVATION_MODES } from "./LayeredMaterial.js";
|
|
3
3
|
import { checkNodeElevationTextureValidity, insertSignificantValuesFromParent, computeMinMaxElevation } from "../Parser/XbilParser.js";
|
|
4
|
-
import CRS from "../Core/Geographic/Crs.js";
|
|
5
4
|
export const EMPTY_TEXTURE_ZOOM = -1;
|
|
6
5
|
const pitch = new THREE.Vector4();
|
|
7
6
|
function getIndiceWithPitch(i, pitch, w) {
|
|
@@ -29,7 +28,7 @@ class RasterTile extends THREE.EventDispatcher {
|
|
|
29
28
|
constructor(material, layer) {
|
|
30
29
|
super();
|
|
31
30
|
this.layer = layer;
|
|
32
|
-
this.crs = layer.parent.tileMatrixSets.indexOf(
|
|
31
|
+
this.crs = layer.parent.tileMatrixSets.indexOf(layer.crs);
|
|
33
32
|
if (this.crs == -1) {
|
|
34
33
|
console.error('Unknown crs:', layer.crs);
|
|
35
34
|
}
|
|
@@ -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
|
function SphereHelper(radius) {
|
|
9
3
|
THREE.Mesh.call(this);
|
package/lib/Source/CopcSource.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import proj4 from 'proj4';
|
|
1
2
|
import { Binary, Info, Las } from 'copc';
|
|
2
3
|
import Extent from "../Core/Geographic/Extent.js";
|
|
3
4
|
import Fetcher from "../Provider/Fetcher.js";
|
|
@@ -102,8 +103,18 @@ class CopcSource extends Source {
|
|
|
102
103
|
this.header = metadata.header;
|
|
103
104
|
this.info = metadata.info;
|
|
104
105
|
this.eb = metadata.eb;
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
proj4.defs('unknown', metadata.wkt);
|
|
107
|
+
let projCS;
|
|
108
|
+
if (proj4.defs('unknown').type === 'COMPD_CS') {
|
|
109
|
+
console.warn('CopcSource: compound coordinate system is not yet supported.');
|
|
110
|
+
projCS = proj4.defs('unknown').PROJCS;
|
|
111
|
+
} else {
|
|
112
|
+
projCS = proj4.defs('unknown');
|
|
113
|
+
}
|
|
114
|
+
this.crs = projCS.title || projCS.name || 'EPSG:4326';
|
|
115
|
+
if (!(this.crs in proj4.defs)) {
|
|
116
|
+
proj4.defs(this.crs, projCS);
|
|
117
|
+
}
|
|
107
118
|
const bbox = new THREE.Box3();
|
|
108
119
|
bbox.min.fromArray(this.info.cube, 0);
|
|
109
120
|
bbox.max.fromArray(this.info.cube, 3);
|
|
@@ -38,10 +38,19 @@ class EntwinePointTileSource extends Source {
|
|
|
38
38
|
// Set parser and its configuration from schema
|
|
39
39
|
this.parse = metadata.dataType === 'laszip' ? LASParser.parse : PotreeBinParser.parse;
|
|
40
40
|
this.extension = metadata.dataType === 'laszip' ? 'laz' : 'bin';
|
|
41
|
-
if (metadata.srs
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
proj4.defs(this.crs
|
|
41
|
+
if (metadata.srs) {
|
|
42
|
+
if (metadata.srs.authority && metadata.srs.horizontal) {
|
|
43
|
+
this.crs = `${metadata.srs.authority}:${metadata.srs.horizontal}`;
|
|
44
|
+
if (!proj4.defs(this.crs)) {
|
|
45
|
+
proj4.defs(this.crs, metadata.srs.wkt);
|
|
46
|
+
}
|
|
47
|
+
} else if (metadata.srs.wkt) {
|
|
48
|
+
proj4.defs('unknown', metadata.srs.wkt);
|
|
49
|
+
const projCS = proj4.defs('unknown');
|
|
50
|
+
this.crs = projCS.title || projCS.name;
|
|
51
|
+
if (!(this.crs in proj4.defs)) {
|
|
52
|
+
proj4.defs(this.crs, projCS);
|
|
53
|
+
}
|
|
45
54
|
}
|
|
46
55
|
if (metadata.srs.vertical && metadata.srs.vertical !== metadata.srs.horizontal) {
|
|
47
56
|
console.warn('EntwinePointTileSource: Vertical coordinates system code is not yet supported.');
|
|
@@ -53,6 +62,7 @@ class EntwinePointTileSource extends Source {
|
|
|
53
62
|
// span in ept.json. This needs improvements.
|
|
54
63
|
this.spacing = (Math.abs(metadata.boundsConforming[3] - metadata.boundsConforming[0]) + Math.abs(metadata.boundsConforming[4] - metadata.boundsConforming[1])) / (2 * metadata.span);
|
|
55
64
|
this.boundsConforming = metadata.boundsConforming;
|
|
65
|
+
this.bounds = metadata.bounds;
|
|
56
66
|
this.span = metadata.span;
|
|
57
67
|
return this;
|
|
58
68
|
});
|
package/lib/Source/FileSource.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import Source from "./Source.js";
|
|
2
2
|
import Cache from "../Core/Scheduler/Cache.js";
|
|
3
|
-
import CRS from "../Core/Geographic/Crs.js";
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* An object defining the source of a single resource to get from a direct
|
|
@@ -104,12 +103,10 @@ class FileSource extends Source {
|
|
|
104
103
|
* presents in `features` under the property `crs`, it is fine.
|
|
105
104
|
*/
|
|
106
105
|
constructor(source) {
|
|
107
|
-
/* istanbul ignore next */
|
|
108
106
|
if (source.parsedData) {
|
|
109
107
|
console.warn('FileSource parsedData parameter is deprecated, use features instead of.');
|
|
110
108
|
source.features = source.features || source.parsedData;
|
|
111
109
|
}
|
|
112
|
-
/* istanbul ignore next */
|
|
113
110
|
if (source.projection) {
|
|
114
111
|
console.warn('FileSource projection parameter is deprecated, use crs instead.');
|
|
115
112
|
source.crs = source.crs || source.projection;
|
|
@@ -155,7 +152,7 @@ class FileSource extends Source {
|
|
|
155
152
|
if (!features) {
|
|
156
153
|
options.out.buildExtent = this.crs != 'EPSG:4978';
|
|
157
154
|
if (options.out.buildExtent) {
|
|
158
|
-
options.out.forcedExtentCrs = options.out.crs != 'EPSG:4978' ? options.out.crs :
|
|
155
|
+
options.out.forcedExtentCrs = options.out.crs != 'EPSG:4978' ? options.out.crs : this.crs;
|
|
159
156
|
}
|
|
160
157
|
features = this.parser(this.fetchedData, options);
|
|
161
158
|
this._featuresCaches[options.out.crs].setByArray(features, [0]);
|
package/lib/Source/Source.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as CRS from "../Core/Geographic/Crs.js";
|
|
1
2
|
import Extent from "../Core/Geographic/Extent.js";
|
|
2
3
|
import GeoJsonParser from "../Parser/GeoJsonParser.js";
|
|
3
4
|
import KMLParser from "../Parser/KMLParser.js";
|
|
@@ -8,7 +9,6 @@ import ISGParser from "../Parser/ISGParser.js";
|
|
|
8
9
|
import VectorTileParser from "../Parser/VectorTileParser.js";
|
|
9
10
|
import Fetcher from "../Provider/Fetcher.js";
|
|
10
11
|
import Cache from "../Core/Scheduler/Cache.js";
|
|
11
|
-
import CRS from "../Core/Geographic/Crs.js";
|
|
12
12
|
|
|
13
13
|
/** @private */
|
|
14
14
|
export const supportedParsers = new Map([['application/geo+json', GeoJsonParser.parse], ['application/json', GeoJsonParser.parse], ['application/kml', KMLParser.parse], ['application/gpx', GpxParser.parse], ['application/x-protobuf;type=mapbox-vector', VectorTileParser.parse], ['application/gtx', GTXParser.parse], ['application/isg', ISGParser.parse], ['application/gdf', GDFParser.parse]]);
|
|
@@ -30,7 +30,6 @@ const noCache = {
|
|
|
30
30
|
*/
|
|
31
31
|
class InformationsData {
|
|
32
32
|
constructor(options) {
|
|
33
|
-
/* istanbul ignore next */
|
|
34
33
|
if (options.projection) {
|
|
35
34
|
console.warn('Source projection parameter is deprecated, use crs instead.');
|
|
36
35
|
options.crs = options.crs || options.projection;
|
|
@@ -166,8 +165,6 @@ class Source extends InformationsData {
|
|
|
166
165
|
in: this,
|
|
167
166
|
extent
|
|
168
167
|
})).catch(err => this.handlingError(err)), key);
|
|
169
|
-
|
|
170
|
-
/* istanbul ignore next */
|
|
171
168
|
if (this.onParsedFile) {
|
|
172
169
|
features.then(feat => {
|
|
173
170
|
this.onParsedFile(feat);
|
package/lib/Source/TMSSource.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import Source from "./Source.js";
|
|
2
2
|
import URLBuilder from "../Provider/URLBuilder.js";
|
|
3
|
-
import Extent
|
|
4
|
-
import
|
|
5
|
-
|
|
3
|
+
import Extent from "../Core/Geographic/Extent.js";
|
|
4
|
+
import Tile from "../Core/Tile/Tile.js";
|
|
5
|
+
import { globalExtentTMS } from "../Core/Tile/TileGrid.js";
|
|
6
|
+
const _tile = new Tile('EPSG:4326', 0, 0, 0);
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* An object defining the source of resources to get from a
|
|
@@ -86,7 +87,7 @@ class TMSSource extends Source {
|
|
|
86
87
|
}
|
|
87
88
|
this.zoom = source.zoom;
|
|
88
89
|
this.isInverted = source.isInverted || false;
|
|
89
|
-
this.crs =
|
|
90
|
+
this.crs = source.crs;
|
|
90
91
|
this.tileMatrixSetLimits = source.tileMatrixSetLimits;
|
|
91
92
|
this.extentSetlimits = {};
|
|
92
93
|
this.tileMatrixCallback = source.tileMatrixCallback || (zoomLevel => zoomLevel);
|
|
@@ -107,8 +108,8 @@ class TMSSource extends Source {
|
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
|
-
urlFromExtent(
|
|
111
|
-
return URLBuilder.xyz(
|
|
111
|
+
urlFromExtent(tile) {
|
|
112
|
+
return URLBuilder.xyz(tile, this);
|
|
112
113
|
}
|
|
113
114
|
onLayerAdded(options) {
|
|
114
115
|
super.onLayerAdded(options);
|
|
@@ -118,17 +119,17 @@ class TMSSource extends Source {
|
|
|
118
119
|
const crs = parent ? parent.extent.crs : options.out.crs;
|
|
119
120
|
if (this.tileMatrixSetLimits && !this.extentSetlimits[crs]) {
|
|
120
121
|
this.extentSetlimits[crs] = {};
|
|
121
|
-
|
|
122
|
+
_tile.crs = this.crs;
|
|
122
123
|
for (let i = this.zoom.max; i >= this.zoom.min; i--) {
|
|
123
124
|
const tmsl = this.tileMatrixSetLimits[i];
|
|
124
125
|
const {
|
|
125
126
|
west,
|
|
126
127
|
north
|
|
127
|
-
} =
|
|
128
|
+
} = _tile.set(i, tmsl.minTileRow, tmsl.minTileCol).toExtent(crs);
|
|
128
129
|
const {
|
|
129
130
|
east,
|
|
130
131
|
south
|
|
131
|
-
} =
|
|
132
|
+
} = _tile.set(i, tmsl.maxTileRow, tmsl.maxTileCol).toExtent(crs);
|
|
132
133
|
this.extentSetlimits[crs][i] = new Extent(crs, west, east, south, north);
|
|
133
134
|
}
|
|
134
135
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { featureFilter } from '@
|
|
1
|
+
import { featureFilter } from '@maplibre/maplibre-gl-style-spec';
|
|
2
2
|
import Style from "../Core/Style.js";
|
|
3
3
|
import TMSSource from "./TMSSource.js";
|
|
4
4
|
import URLBuilder from "../Provider/URLBuilder.js";
|
|
@@ -20,6 +20,15 @@ function mergeCollections(collections) {
|
|
|
20
20
|
return collection;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
// A deprecated (but still in use) Mapbox spec allows using 'ref' as a propertie to reference an other layer
|
|
24
|
+
// instead of duplicating the following properties: 'type', 'source', 'source-layer', 'minzoom', 'maxzoom', 'filter', 'layout'
|
|
25
|
+
function getPropertiesFromRefLayer(layers, layer) {
|
|
26
|
+
const refLayer = layers.filter(l => l.id === layer.ref)[0];
|
|
27
|
+
['type', 'source', 'source-layer', 'minzoom', 'maxzoom', 'filter', 'layout'].forEach(prop => {
|
|
28
|
+
layer[prop] = refLayer[prop];
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
23
32
|
/**
|
|
24
33
|
* VectorTilesSource are object containing informations on how to fetch vector
|
|
25
34
|
* tiles resources.
|
|
@@ -69,36 +78,41 @@ class VectorTilesSource extends TMSSource {
|
|
|
69
78
|
let promise;
|
|
70
79
|
this.isVectorTileSource = true;
|
|
71
80
|
this.accessToken = source.accessToken;
|
|
81
|
+
let mvtStyleUrl;
|
|
72
82
|
if (source.style) {
|
|
73
83
|
if (typeof source.style == 'string') {
|
|
74
|
-
|
|
75
|
-
promise = Fetcher.json(
|
|
84
|
+
mvtStyleUrl = urlParser.normalizeStyleURL(source.style, this.accessToken);
|
|
85
|
+
promise = Fetcher.json(mvtStyleUrl, this.networkOptions);
|
|
76
86
|
} else {
|
|
77
87
|
promise = Promise.resolve(source.style);
|
|
78
88
|
}
|
|
79
89
|
} else {
|
|
80
90
|
throw new Error('New VectorTilesSource: style is required');
|
|
81
91
|
}
|
|
82
|
-
this.whenReady = promise.then(
|
|
83
|
-
this.jsonStyle =
|
|
84
|
-
|
|
92
|
+
this.whenReady = promise.then(mvtStyle => {
|
|
93
|
+
this.jsonStyle = mvtStyle;
|
|
94
|
+
let baseurl = source.sprite || mvtStyle.sprite;
|
|
85
95
|
if (baseurl) {
|
|
96
|
+
baseurl = new URL(baseurl, mvtStyleUrl).toString();
|
|
86
97
|
const spriteUrl = urlParser.normalizeSpriteURL(baseurl, '', '.json', this.accessToken);
|
|
87
98
|
return Fetcher.json(spriteUrl, this.networkOptions).then(sprites => {
|
|
88
99
|
this.sprites = sprites;
|
|
89
100
|
const imgUrl = urlParser.normalizeSpriteURL(baseurl, '', '.png', this.accessToken);
|
|
90
101
|
this.sprites.source = imgUrl;
|
|
91
|
-
return
|
|
102
|
+
return mvtStyle;
|
|
92
103
|
});
|
|
93
104
|
}
|
|
94
|
-
return
|
|
95
|
-
}).then(
|
|
96
|
-
|
|
105
|
+
return mvtStyle;
|
|
106
|
+
}).then(mvtStyle => {
|
|
107
|
+
mvtStyle.layers.forEach((layer, order) => {
|
|
97
108
|
layer.sourceUid = this.uid;
|
|
98
109
|
if (layer.type === 'background') {
|
|
99
110
|
this.backgroundLayer = layer;
|
|
100
111
|
} else if (ffilter(layer)) {
|
|
101
|
-
|
|
112
|
+
if (layer['source-layer'] === undefined) {
|
|
113
|
+
getPropertiesFromRefLayer(mvtStyle.layers, layer);
|
|
114
|
+
}
|
|
115
|
+
const style = Style.setFromVectorTileLayer(layer, this.sprites, this.symbolToCircle);
|
|
102
116
|
this.styles[layer.id] = style;
|
|
103
117
|
if (!this.layers[layer['source-layer']]) {
|
|
104
118
|
this.layers[layer['source-layer']] = [];
|
|
@@ -106,20 +120,18 @@ class VectorTilesSource extends TMSSource {
|
|
|
106
120
|
this.layers[layer['source-layer']].push({
|
|
107
121
|
id: layer.id,
|
|
108
122
|
order,
|
|
109
|
-
filterExpression: featureFilter(layer.filter)
|
|
110
|
-
zoom: {
|
|
111
|
-
min: layer.minzoom || 0,
|
|
112
|
-
max: layer.maxzoom || 24
|
|
113
|
-
}
|
|
123
|
+
filterExpression: featureFilter(layer.filter)
|
|
114
124
|
});
|
|
115
125
|
}
|
|
116
126
|
});
|
|
117
127
|
if (this.url == '.') {
|
|
118
|
-
const TMSUrlList = Object.values(
|
|
128
|
+
const TMSUrlList = Object.values(mvtStyle.sources).map(sourceVT => {
|
|
119
129
|
if (sourceVT.url) {
|
|
130
|
+
sourceVT.url = new URL(sourceVT.url, mvtStyleUrl).toString();
|
|
120
131
|
const urlSource = urlParser.normalizeSourceURL(sourceVT.url, this.accessToken);
|
|
121
132
|
return Fetcher.json(urlSource, this.networkOptions).then(tileJSON => {
|
|
122
133
|
if (tileJSON.tiles[0]) {
|
|
134
|
+
tileJSON.tiles[0] = decodeURIComponent(new URL(tileJSON.tiles[0], urlSource).toString());
|
|
123
135
|
return toTMSUrl(tileJSON.tiles[0]);
|
|
124
136
|
}
|
|
125
137
|
});
|
|
@@ -130,13 +142,13 @@ class VectorTilesSource extends TMSSource {
|
|
|
130
142
|
});
|
|
131
143
|
return Promise.all(TMSUrlList);
|
|
132
144
|
}
|
|
133
|
-
return Promise.resolve([this.url]);
|
|
145
|
+
return Promise.resolve([toTMSUrl(this.url)]);
|
|
134
146
|
}).then(TMSUrlList => {
|
|
135
147
|
this.urls = Array.from(new Set(TMSUrlList));
|
|
136
148
|
});
|
|
137
149
|
}
|
|
138
|
-
urlFromExtent(
|
|
139
|
-
return URLBuilder.xyz(
|
|
150
|
+
urlFromExtent(tile, url) {
|
|
151
|
+
return URLBuilder.xyz(tile, {
|
|
140
152
|
tileMatrixCallback: this.tileMatrixCallback,
|
|
141
153
|
url
|
|
142
154
|
});
|
|
@@ -162,8 +174,6 @@ class VectorTilesSource extends TMSSource {
|
|
|
162
174
|
in: this,
|
|
163
175
|
extent
|
|
164
176
|
})))).then(collections => mergeCollections(collections)).catch(err => this.handlingError(err)), key);
|
|
165
|
-
|
|
166
|
-
/* istanbul ignore next */
|
|
167
177
|
if (this.onParsedFile) {
|
|
168
178
|
features.then(feat => {
|
|
169
179
|
this.onParsedFile(feat);
|