@cesium/engine 25.0.0 → 26.0.0

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 (187) hide show
  1. package/Build/Workers/{chunk-GPIGURCG.js → chunk-3VFEWOBI.js} +7 -7
  2. package/Build/Workers/{chunk-BTX2NL3P.js → chunk-424RNO3D.js} +18 -18
  3. package/Build/Workers/{chunk-HSVQATK2.js → chunk-4MGMYHOO.js} +6 -6
  4. package/Build/Workers/{chunk-FIBS5S7R.js → chunk-4S7IE3LB.js} +2 -2
  5. package/Build/Workers/{chunk-A7ZBMVFS.js → chunk-52JDLOEM.js} +14 -14
  6. package/Build/Workers/{chunk-ZCCIIBZT.js → chunk-54I6Y66F.js} +6 -6
  7. package/Build/Workers/{chunk-J647NNZW.js → chunk-6YEE6JDR.js} +6 -6
  8. package/Build/Workers/{chunk-HVMG6AG4.js → chunk-7J2HKPRH.js} +9 -9
  9. package/Build/Workers/{chunk-K6NFIRFB.js → chunk-7WM2PX4V.js} +5 -5
  10. package/Build/Workers/{chunk-3LSD7OOA.js → chunk-ACXQXN46.js} +16 -16
  11. package/Build/Workers/{chunk-CZ23Y3RM.js → chunk-AYKR4VBR.js} +2 -2
  12. package/Build/Workers/{chunk-4MTRQFJP.js → chunk-C6J67V5A.js} +1 -1
  13. package/Build/Workers/{chunk-WTQGE7Q6.js → chunk-C6KNZ7T4.js} +17 -17
  14. package/Build/Workers/{chunk-AWFZHD2B.js → chunk-CFQP6LYM.js} +4 -4
  15. package/Build/Workers/{chunk-ST2UWDUU.js → chunk-CXOYE2WM.js} +5 -5
  16. package/Build/Workers/{chunk-H2A4USJR.js → chunk-CZEYZU4N.js} +10 -10
  17. package/Build/Workers/{chunk-DFEI5MAV.js → chunk-DBOEKL43.js} +7 -7
  18. package/Build/Workers/{chunk-A7A433MD.js → chunk-DDWSZVMY.js} +5 -5
  19. package/Build/Workers/{chunk-J7KQEKPK.js → chunk-DOBXCNC3.js} +13 -13
  20. package/Build/Workers/{chunk-URUCCIPS.js → chunk-E7VQ76KE.js} +6 -6
  21. package/Build/Workers/{chunk-ZAPOS52G.js → chunk-EBSIOBXY.js} +8 -8
  22. package/Build/Workers/{chunk-3VDDRF2E.js → chunk-EF2QYXGA.js} +14 -14
  23. package/Build/Workers/{chunk-WN6P5UDH.js → chunk-EPYXRCDB.js} +12 -12
  24. package/Build/Workers/{chunk-EZARA5FJ.js → chunk-F6QDY6HU.js} +13 -13
  25. package/Build/Workers/{chunk-GL7DNVUS.js → chunk-FRQZECAO.js} +5 -5
  26. package/Build/Workers/{chunk-VQKLRBIK.js → chunk-G7PXZRVF.js} +7 -7
  27. package/Build/Workers/{chunk-4QQXGTCE.js → chunk-INUEEEQA.js} +8 -8
  28. package/Build/Workers/{chunk-ITD2IN7N.js → chunk-IRBKFCEJ.js} +2 -2
  29. package/Build/Workers/{chunk-6SDGQI27.js → chunk-IYOUHCZB.js} +1 -1
  30. package/Build/Workers/{chunk-DYT5NR6P.js → chunk-J6BWOHUF.js} +3 -3
  31. package/Build/Workers/{chunk-4GF4MVPY.js → chunk-KFSTQKNM.js} +7 -7
  32. package/Build/Workers/{chunk-4XXHJI6Y.js → chunk-KKOSKAZB.js} +17 -17
  33. package/Build/Workers/{chunk-WC57YYBN.js → chunk-KSSWJIZW.js} +2 -2
  34. package/Build/Workers/{chunk-5T6QQAJW.js → chunk-M3B5JKSM.js} +1 -1
  35. package/Build/Workers/{chunk-QO2CGXMP.js → chunk-MPZHGZU6.js} +6 -6
  36. package/Build/Workers/{chunk-WUBKZFF6.js → chunk-MYP774IS.js} +9 -9
  37. package/Build/Workers/{chunk-WNN5D4W3.js → chunk-O3EA5HS7.js} +10 -10
  38. package/Build/Workers/{chunk-77RL3MBD.js → chunk-P3CK7MCY.js} +25 -4
  39. package/Build/Workers/{chunk-QXNQQYPV.js → chunk-Q3PY526V.js} +8 -8
  40. package/Build/Workers/{chunk-CKQP3DSS.js → chunk-QN67VG36.js} +6 -6
  41. package/Build/Workers/{chunk-ACFFCHHZ.js → chunk-QRWGUWI6.js} +11 -11
  42. package/Build/Workers/{chunk-LH5SF3XV.js → chunk-S4MCOY6I.js} +5 -5
  43. package/Build/Workers/{chunk-FVLVVOBQ.js → chunk-SMQZZOW6.js} +10 -10
  44. package/Build/Workers/{chunk-TA777BGS.js → chunk-TKKIREQ6.js} +1 -1
  45. package/Build/Workers/{chunk-AEAVLYPS.js → chunk-U3ZA64U7.js} +2 -2
  46. package/Build/Workers/{chunk-7LSFAEWF.js → chunk-UA25D5MX.js} +10 -10
  47. package/Build/Workers/{chunk-J3OFS2RD.js → chunk-UOOIQ3KX.js} +12 -12
  48. package/Build/Workers/{chunk-ND3NTTOF.js → chunk-V7VQKN6N.js} +6 -6
  49. package/Build/Workers/{chunk-I3A6DXYZ.js → chunk-VQYETPWC.js} +4 -4
  50. package/Build/Workers/{chunk-35H3UBIO.js → chunk-VWV2IJRB.js} +11 -11
  51. package/Build/Workers/{chunk-QSDY4NS7.js → chunk-XZMBNNDX.js} +9 -9
  52. package/Build/Workers/{chunk-TAI4HLII.js → chunk-Y57HREW5.js} +4 -4
  53. package/Build/Workers/{chunk-3TKLDHV3.js → chunk-Y5BF6AFU.js} +2 -2
  54. package/Build/Workers/{chunk-3XY3MVPG.js → chunk-YLY7NKAB.js} +4 -4
  55. package/Build/Workers/{chunk-BVAIWR7O.js → chunk-ZK3CF7ZD.js} +12 -12
  56. package/Build/Workers/{chunk-DH26SNAB.js → chunk-ZP7JMQV4.js} +1 -1
  57. package/Build/Workers/{chunk-3RFFPH4M.js → chunk-ZZ46LWL6.js} +1 -1
  58. package/Build/Workers/combineGeometry.js +24 -24
  59. package/Build/Workers/createBoxGeometry.js +18 -18
  60. package/Build/Workers/createBoxOutlineGeometry.js +16 -16
  61. package/Build/Workers/createCircleGeometry.js +26 -26
  62. package/Build/Workers/createCircleOutlineGeometry.js +19 -19
  63. package/Build/Workers/createCoplanarPolygonGeometry.js +33 -33
  64. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +31 -31
  65. package/Build/Workers/createCorridorGeometry.js +29 -29
  66. package/Build/Workers/createCorridorOutlineGeometry.js +28 -28
  67. package/Build/Workers/createCylinderGeometry.js +20 -20
  68. package/Build/Workers/createCylinderOutlineGeometry.js +18 -18
  69. package/Build/Workers/createEllipseGeometry.js +26 -26
  70. package/Build/Workers/createEllipseOutlineGeometry.js +19 -19
  71. package/Build/Workers/createEllipsoidGeometry.js +19 -19
  72. package/Build/Workers/createEllipsoidOutlineGeometry.js +18 -18
  73. package/Build/Workers/createFrustumGeometry.js +18 -18
  74. package/Build/Workers/createFrustumOutlineGeometry.js +18 -18
  75. package/Build/Workers/createGeometry.js +24 -24
  76. package/Build/Workers/createGroundPolylineGeometry.js +22 -22
  77. package/Build/Workers/createPlaneGeometry.js +16 -16
  78. package/Build/Workers/createPlaneOutlineGeometry.js +15 -15
  79. package/Build/Workers/createPolygonGeometry.js +32 -32
  80. package/Build/Workers/createPolygonOutlineGeometry.js +30 -30
  81. package/Build/Workers/createPolylineGeometry.js +25 -25
  82. package/Build/Workers/createPolylineVolumeGeometry.js +31 -31
  83. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +27 -27
  84. package/Build/Workers/createRectangleGeometry.js +27 -27
  85. package/Build/Workers/createRectangleOutlineGeometry.js +20 -20
  86. package/Build/Workers/createSimplePolylineGeometry.js +23 -23
  87. package/Build/Workers/createSphereGeometry.js +19 -19
  88. package/Build/Workers/createSphereOutlineGeometry.js +18 -18
  89. package/Build/Workers/createTaskProcessorWorker.js +3 -3
  90. package/Build/Workers/createVectorTileClampedPolylines.js +14 -14
  91. package/Build/Workers/createVectorTileGeometries.js +24 -24
  92. package/Build/Workers/createVectorTilePoints.js +13 -13
  93. package/Build/Workers/createVectorTilePolygons.js +22 -22
  94. package/Build/Workers/createVectorTilePolylines.js +14 -14
  95. package/Build/Workers/createVerticesFromCesium3DTilesTerrain.js +25 -25
  96. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +22 -22
  97. package/Build/Workers/createVerticesFromHeightmap.js +22 -22
  98. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +20 -20
  99. package/Build/Workers/createWallGeometry.js +24 -24
  100. package/Build/Workers/createWallOutlineGeometry.js +23 -23
  101. package/Build/Workers/decodeDraco.js +10 -10
  102. package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
  103. package/Build/Workers/decodeI3S.js +10 -10
  104. package/Build/Workers/gaussianSplatSorter.js +4 -4
  105. package/Build/Workers/gaussianSplatTextureGenerator.js +4 -4
  106. package/Build/Workers/incrementallyBuildTerrainPicker.js +10 -10
  107. package/Build/Workers/transcodeKTX2.js +6 -6
  108. package/Build/Workers/transferTypedArrayTest.js +1 -1
  109. package/Build/Workers/upsampleQuantizedTerrainMesh.js +22 -22
  110. package/Build/Workers/upsampleVerticesFromCesium3DTilesTerrain.js +25 -25
  111. package/Source/Core/Cartesian2.js +1 -1
  112. package/Source/Core/Cartesian3.js +1 -1
  113. package/Source/Core/Cartesian4.js +1 -1
  114. package/Source/Core/ComponentDatatype.js +35 -0
  115. package/Source/Core/Ion.js +1 -1
  116. package/Source/Core/MapProjection.js +1 -0
  117. package/Source/Core/Matrix2.js +1 -1
  118. package/Source/Core/Matrix3.js +1 -1
  119. package/Source/Core/Matrix4.js +1 -1
  120. package/Source/Core/Resource.js +1 -1
  121. package/Source/Core/ScreenSpaceEventHandler.js +51 -41
  122. package/Source/Core/createColorRamp.js +37 -0
  123. package/Source/Core/globalTypes.js +25 -0
  124. package/Source/Renderer/Pass.js +3 -2
  125. package/Source/Renderer/createUniform.js +346 -239
  126. package/Source/Renderer/createUniformArray.js +494 -381
  127. package/Source/Scene/ArcGisMapService.js +1 -1
  128. package/Source/Scene/BufferPoint.js +1 -0
  129. package/Source/Scene/BufferPointCollection.js +14 -1
  130. package/Source/Scene/BufferPolygon.js +3 -2
  131. package/Source/Scene/BufferPolygonCollection.js +10 -0
  132. package/Source/Scene/BufferPolyline.js +1 -0
  133. package/Source/Scene/BufferPolylineCollection.js +2 -0
  134. package/Source/Scene/BufferPrimitiveCollection.js +79 -28
  135. package/Source/Scene/CameraEventAggregator.js +30 -18
  136. package/Source/Scene/Cesium3DTile.js +54 -1
  137. package/Source/Scene/Cesium3DTileContent.js +195 -254
  138. package/Source/Scene/Cesium3DTileContentFactory.js +10 -2
  139. package/Source/Scene/Cesium3DTileset.js +45 -5
  140. package/Source/Scene/Composite3DTileContent.js +254 -292
  141. package/Source/Scene/EdgeDisplayMode.js +50 -0
  142. package/Source/Scene/Empty3DTileContent.js +100 -132
  143. package/Source/Scene/GaussianSplat3DTileContent.js +436 -478
  144. package/Source/Scene/GeoJsonPrimitive.js +874 -0
  145. package/Source/Scene/Geometry3DTileContent.js +151 -185
  146. package/Source/Scene/GltfLoader.js +109 -0
  147. package/Source/Scene/Implicit3DTileContent.js +179 -214
  148. package/Source/Scene/MVTDataProvider.js +147 -0
  149. package/Source/Scene/Model/EdgeVisibilityPipelineStage.js +79 -311
  150. package/Source/Scene/Model/Model.js +34 -0
  151. package/Source/Scene/Model/Model3DTileContent.js +424 -458
  152. package/Source/Scene/Model/ModelDrawCommand.js +31 -3
  153. package/Source/Scene/Model/ModelUtility.js +4 -0
  154. package/Source/Scene/Model/createVectorTileBuffersFromModelComponents.js +466 -150
  155. package/Source/Scene/ModelComponents.js +39 -1
  156. package/Source/Scene/Multiple3DTileContent.js +291 -334
  157. package/Source/Scene/Scene.js +26 -0
  158. package/Source/Scene/Tileset3DTileContent.js +113 -146
  159. package/Source/Scene/UrlTemplate3DTilesDataProvider.js +499 -0
  160. package/Source/Scene/Vector3DTileContent.js +205 -234
  161. package/Source/Scene/VectorGltf3DTileContent.js +85 -36
  162. package/Source/Scene/VoxelPrimitive.js +159 -175
  163. package/Source/Scene/VoxelProvider.js +64 -91
  164. package/Source/Scene/buildVectorGltfFromMVT.js +1059 -0
  165. package/Source/Scene/buildVoxelCustomShader.js +199 -0
  166. package/Source/Scene/decodeMVT.js +634 -0
  167. package/Source/Scene/renderBufferPointCollection.js +110 -64
  168. package/Source/Scene/renderBufferPolygonCollection.js +102 -55
  169. package/Source/Scene/renderBufferPolylineCollection.js +365 -166
  170. package/Source/Shaders/BufferPointMaterialFS.glsl +1 -0
  171. package/Source/Shaders/BufferPointMaterialFS.js +1 -0
  172. package/Source/Shaders/BufferPointMaterialVS.glsl +19 -9
  173. package/Source/Shaders/BufferPointMaterialVS.js +20 -10
  174. package/Source/Shaders/BufferPolygonMaterialVS.glsl +13 -4
  175. package/Source/Shaders/BufferPolygonMaterialVS.js +14 -5
  176. package/Source/Shaders/BufferPolylineMaterialVS.glsl +16 -2
  177. package/Source/Shaders/BufferPolylineMaterialVS.js +17 -3
  178. package/Source/Shaders/Builtin/Constants/passCesium3DTileEdgesDirect.glsl +9 -0
  179. package/Source/Shaders/Builtin/Constants/passCesium3DTileEdgesDirect.js +11 -0
  180. package/Source/Shaders/Builtin/Constants/passOverlay.glsl +1 -1
  181. package/Source/Shaders/Builtin/Constants/passOverlay.js +1 -1
  182. package/Source/Shaders/Builtin/CzmBuiltins.js +2 -0
  183. package/Source/Shaders/Model/EdgeVisibilityStageVS.glsl +0 -1
  184. package/Source/Shaders/Model/EdgeVisibilityStageVS.js +0 -1
  185. package/index.d.ts +253 -35
  186. package/index.js +71 -62
  187. package/package.json +2 -2
@@ -0,0 +1,874 @@
1
+ // @ts-check
2
+
3
+ /** @import {GeoJson, GeoJsonFeature, GeoJsonGeometry, GeoJsonPosition} from "../Core/globalTypes.js"; */
4
+ /** @import FrameState from "./FrameState.js"; */
5
+
6
+ import Cartesian2 from "../Core/Cartesian2.js";
7
+ import Cartesian3 from "../Core/Cartesian3.js";
8
+ import Check from "../Core/Check.js";
9
+ import defined from "../Core/defined.js";
10
+ import destroyObject from "../Core/destroyObject.js";
11
+ import DeveloperError from "../Core/DeveloperError.js";
12
+ import Ellipsoid from "../Core/Ellipsoid.js";
13
+ import Frozen from "../Core/Frozen.js";
14
+ import PolygonPipeline from "../Core/PolygonPipeline.js";
15
+ import Resource from "../Core/Resource.js";
16
+ import RuntimeError from "../Core/RuntimeError.js";
17
+ import BufferPoint from "./BufferPoint.js";
18
+ import BufferPointCollection from "./BufferPointCollection.js";
19
+ import BufferPolygon from "./BufferPolygon.js";
20
+ import BufferPolygonCollection from "./BufferPolygonCollection.js";
21
+ import BufferPolyline from "./BufferPolyline.js";
22
+ import BufferPolylineCollection from "./BufferPolylineCollection.js";
23
+
24
+ /**
25
+ * @typedef {object} GeoJsonPrimitiveConstructorOptions
26
+ * @property {object} [geoJson]
27
+ * @property {Resource|string} [url]
28
+ * @property {Ellipsoid} [ellipsoid=Ellipsoid.default]
29
+ * @property {boolean} [allowPicking=true]
30
+ * @property {boolean} [show=true]
31
+ * @property {function(number, object, Record<string, unknown>):object} [pickObjectFactory]
32
+ */
33
+
34
+ /**
35
+ * Lightweight GeoJSON loader that converts features directly into
36
+ * {@link BufferPointCollection}, {@link BufferPolylineCollection}, and
37
+ * {@link BufferPolygonCollection}.
38
+ *
39
+ * Unlike {@link GeoJsonDataSource}, this path does not create entities.
40
+ * Instead, it exposes high-throughput buffer primitive collections that can be
41
+ * added directly to {@link Scene#primitives}.
42
+ *
43
+ * @example
44
+ * const loader = await Cesium.GeoJsonPrimitive.fromUrl("./data.geojson");
45
+ * viewer.scene.primitives.add(loader);
46
+ *
47
+ * loader.points; // BufferPointCollection | undefined
48
+ * loader.polylines; // BufferPolylineCollection | undefined
49
+ * loader.polygons; // BufferPolygonCollection | undefined
50
+ * loader.ids; // source feature IDs
51
+ * loader.properties; // source feature properties
52
+ * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
53
+ */
54
+ class GeoJsonPrimitive {
55
+ /**
56
+ * @param {GeoJsonPrimitiveConstructorOptions} [options]
57
+ */
58
+ constructor(options) {
59
+ options = options ?? Frozen.EMPTY_OBJECT;
60
+
61
+ //>>includeStart('debug', pragmas.debug);
62
+ if (!defined(options.geoJson)) {
63
+ throw new DeveloperError("options.geoJson is required.");
64
+ }
65
+ //>>includeEnd('debug');
66
+
67
+ const parseResult = parseGeoJson(/** @type {GeoJson} */ (options.geoJson));
68
+ const allowPicking = options.allowPicking ?? true;
69
+ const ellipsoid = options.ellipsoid ?? Ellipsoid.default;
70
+ let packedPositionsScratch = new Float64Array(0);
71
+ /** @param {number} requiredLength */
72
+ function getPackedPositionScratch(requiredLength) {
73
+ if (packedPositionsScratch.length < requiredLength) {
74
+ packedPositionsScratch = new Float64Array(requiredLength);
75
+ }
76
+ return packedPositionsScratch;
77
+ }
78
+
79
+ this.show = options.show ?? true;
80
+ this._url = options.url;
81
+ this._ids = parseResult.ids;
82
+ this._properties = parseResult.properties;
83
+ this._featureCount = parseResult.ids.length;
84
+ this._pickObjectFactory = options.pickObjectFactory;
85
+ this._points = undefined;
86
+ this._polylines = undefined;
87
+ this._polygons = undefined;
88
+
89
+ if (parseResult.pointCount > 0) {
90
+ /** @type {Record<string, unknown>} */
91
+ const pointOptions = {
92
+ primitiveCountMax: parseResult.pointCount,
93
+ allowPicking: allowPicking,
94
+ };
95
+ this._points = new BufferPointCollection(pointOptions);
96
+ }
97
+
98
+ if (parseResult.polylineCount > 0) {
99
+ /** @type {Record<string, unknown>} */
100
+ const polylineOptions = {
101
+ primitiveCountMax: parseResult.polylineCount,
102
+ vertexCountMax: parseResult.polylineVertexCount,
103
+ allowPicking: allowPicking,
104
+ };
105
+ this._polylines = new BufferPolylineCollection(polylineOptions);
106
+ }
107
+
108
+ if (parseResult.polygonCount > 0) {
109
+ /** @type {Record<string, unknown>} */
110
+ const polygonOptions = {
111
+ primitiveCountMax: parseResult.polygonCount,
112
+ vertexCountMax: parseResult.polygonVertexCount,
113
+ holeCountMax: parseResult.polygonHoleCount,
114
+ triangleCountMax: parseResult.polygonTriangleCount,
115
+ allowPicking: allowPicking,
116
+ };
117
+ this._polygons = new BufferPolygonCollection(polygonOptions);
118
+ }
119
+
120
+ const scratch = new Cartesian3();
121
+ let pointIndex = 0;
122
+ let polylineIndex = 0;
123
+ let polygonIndex = 0;
124
+
125
+ for (let i = 0; i < parseResult.features.length; i++) {
126
+ const feature = parseResult.features[i];
127
+ const featureId = feature.featureId;
128
+ const sourceProperties = this._properties[featureId];
129
+
130
+ for (let j = 0; j < feature.points.length; j++) {
131
+ const idx = pointIndex++;
132
+ this._points.add({
133
+ featureId: featureId,
134
+ position: toCartesian(feature.points[j], ellipsoid, scratch),
135
+ pickObject: allowPicking
136
+ ? createPickObject(
137
+ this,
138
+ idx,
139
+ this._points,
140
+ BufferPoint,
141
+ sourceProperties,
142
+ )
143
+ : undefined,
144
+ });
145
+ }
146
+
147
+ for (let j = 0; j < feature.polylines.length; j++) {
148
+ const idx = polylineIndex++;
149
+ this._polylines.add({
150
+ featureId: featureId,
151
+ positions: packPositionsToScratch(
152
+ feature.polylines[j],
153
+ ellipsoid,
154
+ getPackedPositionScratch,
155
+ ),
156
+ pickObject: allowPicking
157
+ ? createPickObject(
158
+ this,
159
+ idx,
160
+ this._polylines,
161
+ BufferPolyline,
162
+ sourceProperties,
163
+ )
164
+ : undefined,
165
+ });
166
+ }
167
+
168
+ for (let j = 0; j < feature.polygons.length; j++) {
169
+ const polygon = feature.polygons[j];
170
+ const idx = polygonIndex++;
171
+ this._polygons.add({
172
+ featureId: featureId,
173
+ positions: packPositionsToScratch(
174
+ polygon.positions,
175
+ ellipsoid,
176
+ getPackedPositionScratch,
177
+ ),
178
+ holes: polygon.holes,
179
+ triangles: polygon.triangles,
180
+ pickObject: allowPicking
181
+ ? createPickObject(
182
+ this,
183
+ idx,
184
+ this._polygons,
185
+ BufferPolygon,
186
+ sourceProperties,
187
+ )
188
+ : undefined,
189
+ });
190
+ }
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Loader source URL when created via {@link GeoJsonPrimitive.fromUrl}.
196
+ *
197
+ * @type {string|undefined}
198
+ * @readonly
199
+ */
200
+ get url() {
201
+ const url = this._url;
202
+ if (!defined(url)) {
203
+ return undefined;
204
+ }
205
+ return url instanceof Resource ? url.getUrlComponent(true) : url;
206
+ }
207
+
208
+ /**
209
+ * Feature count represented by the loaded collections.
210
+ *
211
+ * @type {number}
212
+ * @readonly
213
+ */
214
+ get featureCount() {
215
+ return this._featureCount;
216
+ }
217
+
218
+ /**
219
+ * Lookup table from integer ID generated by GeoJsonPrimitive, to integer or string Feature ID from GeoJSON source.
220
+ *
221
+ * @type {Array<string|number|undefined>}
222
+ * @readonly
223
+ */
224
+ get ids() {
225
+ return this._ids;
226
+ }
227
+
228
+ /**
229
+ * Source GeoJSON properties, indexed by generated integer ID.
230
+ *
231
+ * @type {Array<Record<string, unknown>>}
232
+ * @readonly
233
+ */
234
+ get properties() {
235
+ return this._properties;
236
+ }
237
+
238
+ /**
239
+ * Buffer point collection for point geometries.
240
+ *
241
+ * @type {BufferPointCollection|undefined}
242
+ * @readonly
243
+ */
244
+ get points() {
245
+ return this._points;
246
+ }
247
+
248
+ /**
249
+ * Buffer polyline collection for linestring geometries.
250
+ *
251
+ * @type {BufferPolylineCollection|undefined}
252
+ * @readonly
253
+ */
254
+ get polylines() {
255
+ return this._polylines;
256
+ }
257
+
258
+ /**
259
+ * Buffer polygon collection for polygon geometries.
260
+ *
261
+ * @type {BufferPolygonCollection|undefined}
262
+ * @readonly
263
+ */
264
+ get polygons() {
265
+ return this._polygons;
266
+ }
267
+
268
+ /**
269
+ * Loads GeoJSON from a URL or {@link Resource}.
270
+ *
271
+ * @param {Resource|string} url
272
+ * @param {GeoJsonPrimitiveConstructorOptions} [options]
273
+ * @returns {Promise<GeoJsonPrimitive>}
274
+ */
275
+ static async fromUrl(url, options) {
276
+ //>>includeStart('debug', pragmas.debug);
277
+ if (!defined(url)) {
278
+ throw new DeveloperError("url is required.");
279
+ }
280
+ //>>includeEnd('debug');
281
+
282
+ const resource = Resource.createIfNeeded(url);
283
+ const geoJson = await resource.fetchJson();
284
+ if (!defined(geoJson)) {
285
+ throw new RuntimeError(
286
+ `Failed to load GeoJSON from ${resource.getUrlComponent(true)}.`,
287
+ );
288
+ }
289
+
290
+ return GeoJsonPrimitive.fromGeoJson(geoJson, {
291
+ ...options,
292
+ url: resource,
293
+ });
294
+ }
295
+
296
+ /**
297
+ * Creates a loader directly from a parsed GeoJSON object.
298
+ *
299
+ * @param {object} geoJson
300
+ * @param {GeoJsonPrimitiveConstructorOptions} [options]
301
+ * @returns {GeoJsonPrimitive}
302
+ */
303
+ static fromGeoJson(geoJson, options) {
304
+ return new GeoJsonPrimitive({
305
+ ...options,
306
+ geoJson: geoJson,
307
+ });
308
+ }
309
+
310
+ /**
311
+ * @param {number} featureId
312
+ */
313
+ getId(featureId) {
314
+ //>>includeStart('debug', pragmas.debug);
315
+ Check.typeOf.number.greaterThanOrEquals("featureId", featureId, 0);
316
+ Check.typeOf.number.lessThan("featureId", featureId, this._featureCount);
317
+ //>>includeEnd('debug');
318
+ return this._ids[featureId];
319
+ }
320
+
321
+ /**
322
+ * @param {number} featureId
323
+ */
324
+ getProperties(featureId) {
325
+ //>>includeStart('debug', pragmas.debug);
326
+ Check.typeOf.number.greaterThanOrEquals("featureId", featureId, 0);
327
+ Check.typeOf.number.lessThan("featureId", featureId, this._featureCount);
328
+ //>>includeEnd('debug');
329
+ return this._properties[featureId];
330
+ }
331
+
332
+ /**
333
+ * @param {FrameState} frameState
334
+ * @private
335
+ */
336
+ update(frameState) {
337
+ if (!this.show) {
338
+ return;
339
+ }
340
+
341
+ if (defined(this._points)) {
342
+ this._points.update(frameState);
343
+ }
344
+ if (defined(this._polylines)) {
345
+ this._polylines.update(frameState);
346
+ }
347
+ if (defined(this._polygons)) {
348
+ this._polygons.update(frameState);
349
+ }
350
+ }
351
+
352
+ destroy() {
353
+ if (this._points) {
354
+ this._points.destroy();
355
+ this._points = undefined;
356
+ }
357
+ if (this._polylines) {
358
+ this._polylines.destroy();
359
+ this._polylines = undefined;
360
+ }
361
+ if (this._polygons) {
362
+ this._polygons.destroy();
363
+ this._polygons = undefined;
364
+ }
365
+ return destroyObject(this);
366
+ }
367
+
368
+ isDestroyed() {
369
+ return false;
370
+ }
371
+ }
372
+
373
+ /**
374
+ * @param {GeoJsonPrimitive} loader
375
+ * @param {number} index
376
+ * @param {{get: function(number, object): object}} collection
377
+ * @param {function(new: object)} PrimitiveClass
378
+ * @param {Record<string, unknown>} properties
379
+ * @returns {object}
380
+ * @ignore
381
+ */
382
+ function createPickObject(
383
+ loader,
384
+ index,
385
+ collection,
386
+ PrimitiveClass,
387
+ properties,
388
+ ) {
389
+ if (defined(loader._pickObjectFactory)) {
390
+ return loader._pickObjectFactory(index, collection, properties);
391
+ }
392
+ return {
393
+ index,
394
+ collection,
395
+ get primitive() {
396
+ // Cannot reuse primitives; scene.drillPick() appends to a list.
397
+ return collection.get(index, new PrimitiveClass());
398
+ },
399
+ parentPrimitive: loader,
400
+ properties,
401
+ };
402
+ }
403
+
404
+ /**
405
+ * @param {GeoJson} geoJson
406
+ * @ignore
407
+ */
408
+ function parseGeoJson(geoJson) {
409
+ const featureInputs = getInputFeatures(geoJson);
410
+
411
+ /** @type {Array<{featureId:number, points:Array<GeoJsonPosition>, polylines:Array<Array<GeoJsonPosition>>, polygons:Array<{positions:Array<GeoJsonPosition>, holes:Uint32Array, triangles:Uint32Array}>}>} */
412
+ const features = [];
413
+ /** @type {Array<string|number|undefined>} */
414
+ const ids = [];
415
+ /** @type {Array<Record<string, unknown>>} */
416
+ const properties = [];
417
+
418
+ let pointCount = 0;
419
+ let polylineCount = 0;
420
+ let polylineVertexCount = 0;
421
+ let polygonCount = 0;
422
+ let polygonVertexCount = 0;
423
+ let polygonHoleCount = 0;
424
+ let polygonTriangleCount = 0;
425
+
426
+ for (let i = 0; i < featureInputs.length; i++) {
427
+ const featureInput = featureInputs[i];
428
+ /** @type {{points: Array<GeoJsonPosition>, polylines: Array<Array<GeoJsonPosition>>, polygons: Array<{positions: Array<GeoJsonPosition>, holes: Uint32Array, triangles: Uint32Array}>}} */
429
+ const featureGeometries = {
430
+ points: [],
431
+ polylines: [],
432
+ polygons: [],
433
+ };
434
+
435
+ appendGeometry(featureInput.geometry, featureGeometries);
436
+
437
+ if (
438
+ featureGeometries.points.length === 0 &&
439
+ featureGeometries.polylines.length === 0 &&
440
+ featureGeometries.polygons.length === 0
441
+ ) {
442
+ continue;
443
+ }
444
+
445
+ const featureId = ids.length;
446
+ ids.push(featureInput.id);
447
+ properties.push(
448
+ // @ts-expect-error Casting changes .d.ts output, a suspected bug in tsd-jsdoc.
449
+ isPlainObject(featureInput.properties)
450
+ ? featureInput.properties
451
+ : Frozen.EMPTY_OBJECT,
452
+ );
453
+
454
+ for (let j = 0; j < featureGeometries.polygons.length; j++) {
455
+ const polygon = featureGeometries.polygons[j];
456
+ polygonHoleCount += polygon.holes.length;
457
+ polygonTriangleCount += polygon.triangles.length / 3;
458
+ polygonVertexCount += polygon.positions.length;
459
+ }
460
+
461
+ for (let j = 0; j < featureGeometries.polylines.length; j++) {
462
+ polylineVertexCount += featureGeometries.polylines[j].length;
463
+ }
464
+
465
+ pointCount += featureGeometries.points.length;
466
+ polylineCount += featureGeometries.polylines.length;
467
+ polygonCount += featureGeometries.polygons.length;
468
+
469
+ features.push({
470
+ featureId: featureId,
471
+ points: featureGeometries.points,
472
+ polylines: featureGeometries.polylines,
473
+ polygons: featureGeometries.polygons,
474
+ });
475
+ }
476
+
477
+ return {
478
+ features: features,
479
+ ids: ids,
480
+ properties: properties,
481
+ pointCount: pointCount,
482
+ polylineCount: polylineCount,
483
+ polylineVertexCount: polylineVertexCount,
484
+ polygonCount: polygonCount,
485
+ polygonVertexCount: polygonVertexCount,
486
+ polygonHoleCount: polygonHoleCount,
487
+ polygonTriangleCount: polygonTriangleCount,
488
+ };
489
+ }
490
+
491
+ /**
492
+ * @param {GeoJson} geoJson
493
+ * @returns {Array<GeoJsonFeature>}
494
+ * @ignore
495
+ */
496
+ function getInputFeatures(geoJson) {
497
+ if (!defined(geoJson) || !defined(geoJson.type)) {
498
+ throw new RuntimeError("GeoJSON object must define 'type'.");
499
+ }
500
+
501
+ switch (geoJson.type) {
502
+ case "FeatureCollection": {
503
+ const fc = /** @type {{ features: GeoJsonFeature[] }} */ (geoJson);
504
+ return fc.features;
505
+ }
506
+ case "Feature":
507
+ return [/** @type {GeoJsonFeature} */ (geoJson)];
508
+ default:
509
+ if (isGeometryType(geoJson.type)) {
510
+ return [
511
+ {
512
+ type: "Feature",
513
+ geometry: /** @type {GeoJsonGeometry} */ (geoJson),
514
+ properties: Frozen.EMPTY_OBJECT,
515
+ id: undefined,
516
+ },
517
+ ];
518
+ }
519
+ throw new RuntimeError(`Unsupported GeoJSON type: ${geoJson.type}`);
520
+ }
521
+ }
522
+
523
+ /**
524
+ * @param {GeoJsonGeometry | null | undefined} geometry
525
+ * @param {{points: Array<GeoJsonPosition>, polylines: Array<GeoJsonPosition[]>, polygons: Array<object>}} result
526
+ * @ignore
527
+ */
528
+ function appendGeometry(geometry, result) {
529
+ if (!defined(geometry) || !defined(geometry.type)) {
530
+ return;
531
+ }
532
+
533
+ switch (geometry.type) {
534
+ case "Point":
535
+ appendPoint(geometry.coordinates, result.points);
536
+ return;
537
+ case "MultiPoint":
538
+ appendMultiPoint(
539
+ /** @type {unknown[]} */ (geometry.coordinates),
540
+ result.points,
541
+ );
542
+ return;
543
+ case "LineString":
544
+ appendLineString(geometry.coordinates, result.polylines);
545
+ return;
546
+ case "MultiLineString":
547
+ appendMultiLineString(
548
+ /** @type {unknown[]} */ (geometry.coordinates),
549
+ result.polylines,
550
+ );
551
+ return;
552
+ case "Polygon":
553
+ appendPolygon(geometry.coordinates, result.polygons);
554
+ return;
555
+ case "MultiPolygon":
556
+ appendMultiPolygon(
557
+ /** @type {unknown[]} */ (geometry.coordinates),
558
+ result.polygons,
559
+ );
560
+ return;
561
+ case "GeometryCollection":
562
+ appendGeometryCollection(geometry.geometries, result);
563
+ return;
564
+ default:
565
+ return;
566
+ }
567
+ }
568
+
569
+ /**
570
+ * @param {Array<GeoJsonGeometry>} geometries
571
+ * @param {{points: Array<GeoJsonPosition>, polylines: Array<Array<GeoJsonPosition>>, polygons: Array<object>}} result
572
+ * @ignore
573
+ */
574
+ function appendGeometryCollection(geometries, result) {
575
+ if (!Array.isArray(geometries)) {
576
+ return;
577
+ }
578
+
579
+ for (let i = 0; i < geometries.length; i++) {
580
+ appendGeometry(geometries[i], result);
581
+ }
582
+ }
583
+
584
+ /**
585
+ * @param {unknown} coordinates
586
+ * @param {Array<GeoJsonPosition>} points
587
+ * @ignore
588
+ */
589
+ function appendPoint(coordinates, points) {
590
+ const position = normalizePosition(coordinates);
591
+ if (defined(position)) {
592
+ points.push(position);
593
+ }
594
+ }
595
+
596
+ /**
597
+ * @param {Array.<unknown>} coordinates
598
+ * @param {Array<GeoJsonPosition>} points
599
+ * @ignore
600
+ */
601
+ function appendMultiPoint(coordinates, points) {
602
+ for (let i = 0; i < coordinates.length; i++) {
603
+ appendPoint(coordinates[i], points);
604
+ }
605
+ }
606
+
607
+ /**
608
+ * @param {unknown} coordinates
609
+ * @param {Array<Array<GeoJsonPosition>>} polylines
610
+ * @ignore
611
+ */
612
+ function appendLineString(coordinates, polylines) {
613
+ const polyline = normalizeLine(coordinates);
614
+ if (defined(polyline) && polyline.length >= 2) {
615
+ polylines.push(polyline);
616
+ }
617
+ }
618
+
619
+ /**
620
+ * @param {Array.<unknown>} coordinates
621
+ * @param {Array<Array<GeoJsonPosition>>} polylines
622
+ * @ignore
623
+ */
624
+ function appendMultiLineString(coordinates, polylines) {
625
+ for (let i = 0; i < coordinates.length; i++) {
626
+ appendLineString(coordinates[i], polylines);
627
+ }
628
+ }
629
+
630
+ /**
631
+ * @param {unknown} coordinates
632
+ * @param {Array<object>} polygons
633
+ * @ignore
634
+ */
635
+ function appendPolygon(coordinates, polygons) {
636
+ const polygon = normalizePolygon(coordinates);
637
+ if (defined(polygon)) {
638
+ polygons.push(polygon);
639
+ }
640
+ }
641
+
642
+ /**
643
+ * @param {Array.<unknown>} coordinates
644
+ * @param {Array<object>} polygons
645
+ * @ignore
646
+ */
647
+ function appendMultiPolygon(coordinates, polygons) {
648
+ for (let i = 0; i < coordinates.length; i++) {
649
+ appendPolygon(coordinates[i], polygons);
650
+ }
651
+ }
652
+
653
+ /**
654
+ * @param {unknown} coordinates
655
+ * @returns {Array<GeoJsonPosition> | undefined}
656
+ * @ignore
657
+ */
658
+ function normalizeLine(coordinates) {
659
+ if (!Array.isArray(coordinates)) {
660
+ return undefined;
661
+ }
662
+
663
+ const line = [];
664
+ for (let i = 0; i < coordinates.length; i++) {
665
+ const position = normalizePosition(coordinates[i]);
666
+ if (defined(position)) {
667
+ line.push(position);
668
+ }
669
+ }
670
+
671
+ return line.length >= 2 ? line : undefined;
672
+ }
673
+
674
+ /**
675
+ * @param {unknown} rings
676
+ * @returns {{positions: Array<GeoJsonPosition>, holes: Uint32Array, triangles: Uint32Array} | undefined}
677
+ * @ignore
678
+ */
679
+ function normalizePolygon(rings) {
680
+ if (!Array.isArray(rings) || rings.length === 0) {
681
+ return undefined;
682
+ }
683
+
684
+ const normalizedRings = [];
685
+ for (let i = 0; i < rings.length; i++) {
686
+ const ring = normalizeRing(rings[i]);
687
+ if (defined(ring)) {
688
+ normalizedRings.push(ring);
689
+ }
690
+ }
691
+
692
+ if (normalizedRings.length === 0) {
693
+ return undefined;
694
+ }
695
+
696
+ const outerRing = normalizedRings[0];
697
+ if (outerRing.length < 3) {
698
+ return undefined;
699
+ }
700
+
701
+ const positions2D = [];
702
+ const positions = [];
703
+ const holes = [];
704
+
705
+ for (let i = 0; i < normalizedRings.length; i++) {
706
+ const ring = normalizedRings[i];
707
+ if (ring.length < 3) {
708
+ continue;
709
+ }
710
+
711
+ if (i > 0) {
712
+ holes.push(positions.length);
713
+ }
714
+
715
+ for (let j = 0; j < ring.length; j++) {
716
+ const position = ring[j];
717
+ positions.push(position);
718
+ positions2D.push(new Cartesian2(position[0], position[1]));
719
+ }
720
+ }
721
+
722
+ if (positions.length < 3) {
723
+ return undefined;
724
+ }
725
+
726
+ const triangles = PolygonPipeline.triangulate(positions2D, holes);
727
+ if (!defined(triangles) || triangles.length < 3) {
728
+ return undefined;
729
+ }
730
+
731
+ return {
732
+ positions: positions,
733
+ holes: new Uint32Array(holes),
734
+ triangles: new Uint32Array(triangles),
735
+ };
736
+ }
737
+
738
+ /**
739
+ * @param {unknown} coordinates
740
+ * @returns {Array<GeoJsonPosition> | undefined}
741
+ * @ignore
742
+ */
743
+ function normalizeRing(coordinates) {
744
+ if (!Array.isArray(coordinates)) {
745
+ return undefined;
746
+ }
747
+
748
+ const ring = [];
749
+ for (let i = 0; i < coordinates.length; i++) {
750
+ const position = normalizePosition(coordinates[i]);
751
+ if (defined(position)) {
752
+ ring.push(position);
753
+ }
754
+ }
755
+
756
+ if (ring.length < 3) {
757
+ return undefined;
758
+ }
759
+
760
+ if (ring.length > 1 && samePosition(ring[0], ring[ring.length - 1])) {
761
+ // GeoJSON rings require the first and last position to be identical.
762
+ // BufferPolygonCollection uses LINE_LOOP topology and prohibits duplicate
763
+ // start/end vertices, so we remove the closing duplicate here.
764
+ ring.pop();
765
+ }
766
+
767
+ return ring.length >= 3 ? ring : undefined;
768
+ }
769
+
770
+ /**
771
+ * @param {unknown} coordinates
772
+ * @returns {GeoJsonPosition | undefined}
773
+ * @ignore
774
+ */
775
+ function normalizePosition(coordinates) {
776
+ if (!Array.isArray(coordinates) || coordinates.length < 2) {
777
+ return undefined;
778
+ }
779
+
780
+ const longitude = coordinates[0];
781
+ const latitude = coordinates[1];
782
+ const height = coordinates[2] ?? 0.0;
783
+
784
+ if (
785
+ !Number.isFinite(longitude) ||
786
+ !Number.isFinite(latitude) ||
787
+ !Number.isFinite(height)
788
+ ) {
789
+ return undefined;
790
+ }
791
+
792
+ return [longitude, latitude, height];
793
+ }
794
+
795
+ /**
796
+ * @param {GeoJsonPosition} left
797
+ * @param {GeoJsonPosition} right
798
+ * @ignore
799
+ */
800
+ function samePosition(left, right) {
801
+ return left[0] === right[0] && left[1] === right[1] && left[2] === right[2];
802
+ }
803
+
804
+ /**
805
+ * @param {string} type
806
+ * @returns {boolean}
807
+ * @ignore
808
+ */
809
+ function isGeometryType(type) {
810
+ return (
811
+ type === "Point" ||
812
+ type === "MultiPoint" ||
813
+ type === "LineString" ||
814
+ type === "MultiLineString" ||
815
+ type === "Polygon" ||
816
+ type === "MultiPolygon" ||
817
+ type === "GeometryCollection"
818
+ );
819
+ }
820
+
821
+ /**
822
+ * @param {GeoJsonPosition} position
823
+ * @param {Ellipsoid} ellipsoid
824
+ * @param {Cartesian3} result
825
+ * @returns {Cartesian3}
826
+ * @ignore
827
+ */
828
+ function toCartesian(position, ellipsoid, result) {
829
+ return Cartesian3.fromDegrees(
830
+ position[0],
831
+ position[1],
832
+ position[2] ?? 0,
833
+ ellipsoid,
834
+ result,
835
+ );
836
+ }
837
+
838
+ const scratchCartesian = new Cartesian3();
839
+
840
+ /**
841
+ * Packs positions into a reusable scratch typed array and returns a subarray
842
+ * view matching the required length. Callers may reuse the underlying scratch
843
+ * buffer after collection.add(), since values are copied into collection memory.
844
+ *
845
+ * @param {Array<GeoJsonPosition>} positions
846
+ * @param {Ellipsoid} ellipsoid
847
+ * @param {function(number):Float64Array} getScratch
848
+ * @returns {Float64Array}
849
+ * @ignore
850
+ */
851
+ function packPositionsToScratch(positions, ellipsoid, getScratch) {
852
+ const requiredLength = positions.length * 3;
853
+ const packed = getScratch(requiredLength);
854
+
855
+ for (let i = 0; i < positions.length; i++) {
856
+ const cartesian = toCartesian(positions[i], ellipsoid, scratchCartesian);
857
+ packed[i * 3] = cartesian.x;
858
+ packed[i * 3 + 1] = cartesian.y;
859
+ packed[i * 3 + 2] = cartesian.z;
860
+ }
861
+
862
+ return packed.subarray(0, requiredLength);
863
+ }
864
+
865
+ /**
866
+ * @param {unknown} value
867
+ * @returns {boolean}
868
+ * @ignore
869
+ */
870
+ function isPlainObject(value) {
871
+ return typeof value === "object" && value !== null && !Array.isArray(value);
872
+ }
873
+
874
+ export default GeoJsonPrimitive;