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.
Files changed (95) hide show
  1. package/CODING.md +1 -1
  2. package/CONTRIBUTORS.md +1 -0
  3. package/dist/debug.js +1 -1
  4. package/dist/debug.js.map +1 -1
  5. package/dist/itowns.js +1 -1
  6. package/dist/itowns.js.LICENSE.txt +0 -2
  7. package/dist/itowns.js.map +1 -1
  8. package/dist/itowns_widgets.js +1 -1
  9. package/dist/itowns_widgets.js.map +1 -1
  10. package/examples/3dtiles_loader.html +109 -45
  11. package/examples/config.json +3 -10
  12. package/examples/entwine_3d_loader.html +3 -1
  13. package/examples/entwine_simple_loader.html +1 -1
  14. package/examples/images/itowns_logo.svg +123 -0
  15. package/examples/js/plugins/COGParser.js +1 -1
  16. package/examples/jsm/OGC3DTilesHelper.js +1 -1
  17. package/examples/layers/JSONLayers/GeoidMNT.json +3 -1
  18. package/examples/source_file_geojson_3d.html +0 -1
  19. package/examples/source_file_kml_raster_usgs.html +0 -1
  20. package/examples/source_stream_wfs_raster.html +0 -7
  21. package/examples/vector_tile_mapbox_raster.html +91 -0
  22. package/lib/Controls/GlobeControls.js +45 -28
  23. package/lib/Controls/StateControl.js +5 -2
  24. package/lib/Converter/Feature2Mesh.js +10 -4
  25. package/lib/Converter/Feature2Texture.js +6 -1
  26. package/lib/Converter/convertToTile.js +3 -8
  27. package/lib/Converter/textureConverter.js +3 -4
  28. package/lib/Core/Deprecated/Undeprecator.js +0 -1
  29. package/lib/Core/Feature.js +1 -2
  30. package/lib/Core/Geographic/Coordinates.js +143 -132
  31. package/lib/Core/Geographic/Crs.js +140 -145
  32. package/lib/Core/Geographic/Extent.js +72 -267
  33. package/lib/Core/Geographic/GeoidGrid.js +1 -1
  34. package/lib/Core/Math/Ellipsoid.js +62 -21
  35. package/lib/Core/Prefab/Globe/Atmosphere.js +4 -8
  36. package/lib/Core/Prefab/Globe/GlobeLayer.js +22 -15
  37. package/lib/Core/Prefab/Globe/GlobeTileBuilder.js +111 -0
  38. package/lib/Core/Prefab/GlobeView.js +2 -7
  39. package/lib/Core/Prefab/Planar/PlanarLayer.js +17 -11
  40. package/lib/Core/Prefab/Planar/PlanarTileBuilder.js +43 -43
  41. package/lib/Core/Prefab/TileBuilder.js +27 -32
  42. package/lib/Core/Prefab/computeBufferTileGeometry.js +189 -130
  43. package/lib/Core/Style.js +60 -42
  44. package/lib/Core/Tile/Tile.js +219 -0
  45. package/lib/Core/Tile/TileGrid.js +43 -0
  46. package/lib/Core/TileGeometry.js +112 -28
  47. package/lib/Core/TileMesh.js +3 -3
  48. package/lib/Core/View.js +15 -8
  49. package/lib/Layer/C3DTilesLayer.js +20 -16
  50. package/lib/Layer/ColorLayer.js +35 -9
  51. package/lib/Layer/CopcLayer.js +5 -0
  52. package/lib/Layer/ElevationLayer.js +39 -7
  53. package/lib/Layer/EntwinePointTileLayer.js +12 -5
  54. package/lib/Layer/FeatureGeometryLayer.js +20 -6
  55. package/lib/Layer/GeometryLayer.js +42 -11
  56. package/lib/Layer/LabelLayer.js +45 -27
  57. package/lib/Layer/Layer.js +83 -57
  58. package/lib/Layer/OGC3DTilesLayer.js +81 -30
  59. package/lib/Layer/OrientedImageLayer.js +11 -5
  60. package/lib/Layer/PointCloudLayer.js +74 -30
  61. package/lib/Layer/Potree2Layer.js +7 -2
  62. package/lib/Layer/PotreeLayer.js +8 -3
  63. package/lib/Layer/RasterLayer.js +12 -2
  64. package/lib/Layer/TiledGeometryLayer.js +69 -13
  65. package/lib/Main.js +2 -2
  66. package/lib/Parser/GeoJsonParser.js +1 -1
  67. package/lib/Parser/VectorTileParser.js +42 -29
  68. package/lib/Parser/XbilParser.js +14 -2
  69. package/lib/Provider/Fetcher.js +5 -1
  70. package/lib/Provider/URLBuilder.js +22 -11
  71. package/lib/Renderer/Camera.js +1 -1
  72. package/lib/Renderer/Label2DRenderer.js +9 -7
  73. package/lib/Renderer/OBB.js +11 -13
  74. package/lib/Renderer/PointsMaterial.js +1 -1
  75. package/lib/Renderer/RasterTile.js +1 -2
  76. package/lib/Renderer/SphereHelper.js +0 -6
  77. package/lib/Source/CopcSource.js +13 -2
  78. package/lib/Source/EntwinePointTileSource.js +14 -4
  79. package/lib/Source/FileSource.js +1 -4
  80. package/lib/Source/Source.js +1 -4
  81. package/lib/Source/TMSSource.js +10 -9
  82. package/lib/Source/VectorTilesSource.js +32 -22
  83. package/lib/Source/WFSSource.js +15 -10
  84. package/lib/Source/WMSSource.js +56 -18
  85. package/lib/Source/WMTSSource.js +13 -7
  86. package/lib/Utils/CameraUtils.js +1 -1
  87. package/lib/Utils/gui/C3DTilesStyle.js +2 -3
  88. package/lib/Utils/placeObjectOnGround.js +0 -1
  89. package/package.json +13 -6
  90. package/examples/3dtiles_25d.html +0 -120
  91. package/examples/3dtiles_basic.html +0 -94
  92. package/examples/3dtiles_batch_table.html +0 -86
  93. package/examples/3dtiles_ion.html +0 -126
  94. package/examples/3dtiles_pointcloud.html +0 -95
  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/Geographic/Extent.js";
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 sourceLayers = Object.keys(vectorTile.layers);
109
- if (sourceLayers.length < 1) {
110
- return;
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 collection = new FeatureCollection(options.out);
121
- const vFeature = vectorTile.layers[sourceLayers[0]];
122
- // TODO: verify if size is correct because is computed with only one feature (vFeature).
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(vFeature.extent * x + center, vFeature.extent * y + center, 0).multiply(collection.scale);
126
+ collection.position.set(vFeature0.extent * x + center, vFeature0.extent * y + center, 0).multiply(collection.scale);
127
127
  collection.updateMatrixWorld();
128
- sourceLayers.forEach(layer_id => {
129
- if (!options.in.layers[layer_id]) {
130
- return;
128
+ vtLayerNames.forEach(vtLayerName => {
129
+ if (!options.in.layers[vtLayerName]) {
130
+ return Promise.resolve(collection);
131
131
  }
132
- const sourceLayer = vectorTile.layers[layer_id];
133
- for (let i = sourceLayer.length - 1; i >= 0; i--) {
134
- const vtFeature = sourceLayer.feature(i);
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
- const layers = options.in.layers[layer_id].filter(l => l.filterExpression.filter({
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) && z >= l.zoom.min && z < l.zoom.max);
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
- if (!feature) {
146
- feature = collection.requestFeatureById(layer.id, vtFeature.type - 1);
147
- feature.id = layer.id;
148
- feature.order = layer.order;
149
- feature.style = options.in.styles[feature.id];
150
- vtFeatureToFeatureGeometry(vtFeature, feature);
151
- } else if (!collection.features.find(f => f.id === layer.id)) {
152
- feature = collection.newFeatureByReference(feature);
153
- feature.id = layer.id;
154
- feature.order = layer.order;
155
- feature.style = options.in.styles[feature.id];
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();
@@ -67,10 +67,22 @@ export function computeMinMaxElevation(texture, pitch, options) {
67
67
  }
68
68
  }
69
69
  }
70
- if (options.zmin > min) {
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 (options.zmax < max) {
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
  }
@@ -102,7 +102,11 @@ export default {
102
102
  res = resolve;
103
103
  rej = reject;
104
104
  });
105
- textureLoader.load(url, res, () => {}, rej);
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 {Extent} coords - the coordinates
55
- * @param {Source} source
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 {Extent} bbox - the bounding box
83
- * @param {Object} source
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.as(source.crs, extent);
97
- const w = extent.west.toFixed(precision);
98
- const s = extent.south.toFixed(precision);
99
- const e = extent.east.toFixed(precision);
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));
@@ -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, this.camera3D.position).as(crs || 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
- // Check if content isn't present in visible labels
172
- this.grid.visible.some(l => {
173
- // TODO for icon without text filter by position
174
- const textContent = label.content.textContent;
175
- return textContent !== '' && l.content.textContent.toLowerCase() == textContent.toLowerCase();
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
@@ -1,12 +1,11 @@
1
1
  import * as THREE from 'three';
2
- import TileGeometry from "../Core/TileGeometry.js";
3
- import BuilderEllipsoidTile from "../Core/Prefab/Globe/BuilderEllipsoidTile.js";
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 BuilderEllipsoidTile({
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
- sharableExtent,
116
+ shareableExtent,
118
117
  quaternion,
119
118
  position
120
- } = builder.computeSharableExtent(extent);
119
+ } = builder.computeShareableExtent(extent);
121
120
  // Compute the minimum count of segment to build tile
122
- const segments = Math.max(Math.floor(sharableExtent.planarDimensions(dimension).x / 90 + 1), 2);
123
- const geometry = new TileGeometry({
124
- extent: sharableExtent,
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 (!CRS.isTms(extent.crs) && CRS.isMetricUnit(extent.crs)) {
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=0] size point
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(CRS.formatToTms(layer.crs));
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);
@@ -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
- // TODO: use wkt definition in `metadata.wkt` to infer/define crs
106
- this.crs = config.crs || 'EPSG:4326';
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 && metadata.srs.authority && metadata.srs.horizontal) {
42
- this.crs = `${metadata.srs.authority}:${metadata.srs.horizontal}`;
43
- if (!proj4.defs(this.crs)) {
44
- proj4.defs(this.crs, metadata.srs.wkt);
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
  });
@@ -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 : CRS.formatToEPSG(this.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]);
@@ -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);
@@ -1,8 +1,9 @@
1
1
  import Source from "./Source.js";
2
2
  import URLBuilder from "../Provider/URLBuilder.js";
3
- import Extent, { globalExtentTMS } from "../Core/Geographic/Extent.js";
4
- import CRS from "../Core/Geographic/Crs.js";
5
- const extent = new Extent(CRS.tms_4326, 0, 0, 0);
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 = CRS.formatToTms(source.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(extent) {
111
- return URLBuilder.xyz(extent, this);
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
- extent.crs = this.crs;
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
- } = extent.set(i, tmsl.minTileRow, tmsl.minTileCol).as(crs);
128
+ } = _tile.set(i, tmsl.minTileRow, tmsl.minTileCol).toExtent(crs);
128
129
  const {
129
130
  east,
130
131
  south
131
- } = extent.set(i, tmsl.maxTileRow, tmsl.maxTileCol).as(crs);
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 '@mapbox/mapbox-gl-style-spec';
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
- const styleUrl = urlParser.normalizeStyleURL(source.style, this.accessToken);
75
- promise = Fetcher.json(styleUrl, this.networkOptions);
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(style => {
83
- this.jsonStyle = style;
84
- const baseurl = source.sprite || style.sprite;
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 style;
102
+ return mvtStyle;
92
103
  });
93
104
  }
94
- return style;
95
- }).then(style => {
96
- style.layers.forEach((layer, order) => {
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
- const style = Style.setFromVectorTileLayer(layer, this.sprites, order, this.symbolToCircle);
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(style.sources).map(sourceVT => {
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(extent, url) {
139
- return URLBuilder.xyz(extent, {
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);