@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.
- package/Build/Workers/{chunk-GPIGURCG.js → chunk-3VFEWOBI.js} +7 -7
- package/Build/Workers/{chunk-BTX2NL3P.js → chunk-424RNO3D.js} +18 -18
- package/Build/Workers/{chunk-HSVQATK2.js → chunk-4MGMYHOO.js} +6 -6
- package/Build/Workers/{chunk-FIBS5S7R.js → chunk-4S7IE3LB.js} +2 -2
- package/Build/Workers/{chunk-A7ZBMVFS.js → chunk-52JDLOEM.js} +14 -14
- package/Build/Workers/{chunk-ZCCIIBZT.js → chunk-54I6Y66F.js} +6 -6
- package/Build/Workers/{chunk-J647NNZW.js → chunk-6YEE6JDR.js} +6 -6
- package/Build/Workers/{chunk-HVMG6AG4.js → chunk-7J2HKPRH.js} +9 -9
- package/Build/Workers/{chunk-K6NFIRFB.js → chunk-7WM2PX4V.js} +5 -5
- package/Build/Workers/{chunk-3LSD7OOA.js → chunk-ACXQXN46.js} +16 -16
- package/Build/Workers/{chunk-CZ23Y3RM.js → chunk-AYKR4VBR.js} +2 -2
- package/Build/Workers/{chunk-4MTRQFJP.js → chunk-C6J67V5A.js} +1 -1
- package/Build/Workers/{chunk-WTQGE7Q6.js → chunk-C6KNZ7T4.js} +17 -17
- package/Build/Workers/{chunk-AWFZHD2B.js → chunk-CFQP6LYM.js} +4 -4
- package/Build/Workers/{chunk-ST2UWDUU.js → chunk-CXOYE2WM.js} +5 -5
- package/Build/Workers/{chunk-H2A4USJR.js → chunk-CZEYZU4N.js} +10 -10
- package/Build/Workers/{chunk-DFEI5MAV.js → chunk-DBOEKL43.js} +7 -7
- package/Build/Workers/{chunk-A7A433MD.js → chunk-DDWSZVMY.js} +5 -5
- package/Build/Workers/{chunk-J7KQEKPK.js → chunk-DOBXCNC3.js} +13 -13
- package/Build/Workers/{chunk-URUCCIPS.js → chunk-E7VQ76KE.js} +6 -6
- package/Build/Workers/{chunk-ZAPOS52G.js → chunk-EBSIOBXY.js} +8 -8
- package/Build/Workers/{chunk-3VDDRF2E.js → chunk-EF2QYXGA.js} +14 -14
- package/Build/Workers/{chunk-WN6P5UDH.js → chunk-EPYXRCDB.js} +12 -12
- package/Build/Workers/{chunk-EZARA5FJ.js → chunk-F6QDY6HU.js} +13 -13
- package/Build/Workers/{chunk-GL7DNVUS.js → chunk-FRQZECAO.js} +5 -5
- package/Build/Workers/{chunk-VQKLRBIK.js → chunk-G7PXZRVF.js} +7 -7
- package/Build/Workers/{chunk-4QQXGTCE.js → chunk-INUEEEQA.js} +8 -8
- package/Build/Workers/{chunk-ITD2IN7N.js → chunk-IRBKFCEJ.js} +2 -2
- package/Build/Workers/{chunk-6SDGQI27.js → chunk-IYOUHCZB.js} +1 -1
- package/Build/Workers/{chunk-DYT5NR6P.js → chunk-J6BWOHUF.js} +3 -3
- package/Build/Workers/{chunk-4GF4MVPY.js → chunk-KFSTQKNM.js} +7 -7
- package/Build/Workers/{chunk-4XXHJI6Y.js → chunk-KKOSKAZB.js} +17 -17
- package/Build/Workers/{chunk-WC57YYBN.js → chunk-KSSWJIZW.js} +2 -2
- package/Build/Workers/{chunk-5T6QQAJW.js → chunk-M3B5JKSM.js} +1 -1
- package/Build/Workers/{chunk-QO2CGXMP.js → chunk-MPZHGZU6.js} +6 -6
- package/Build/Workers/{chunk-WUBKZFF6.js → chunk-MYP774IS.js} +9 -9
- package/Build/Workers/{chunk-WNN5D4W3.js → chunk-O3EA5HS7.js} +10 -10
- package/Build/Workers/{chunk-77RL3MBD.js → chunk-P3CK7MCY.js} +25 -4
- package/Build/Workers/{chunk-QXNQQYPV.js → chunk-Q3PY526V.js} +8 -8
- package/Build/Workers/{chunk-CKQP3DSS.js → chunk-QN67VG36.js} +6 -6
- package/Build/Workers/{chunk-ACFFCHHZ.js → chunk-QRWGUWI6.js} +11 -11
- package/Build/Workers/{chunk-LH5SF3XV.js → chunk-S4MCOY6I.js} +5 -5
- package/Build/Workers/{chunk-FVLVVOBQ.js → chunk-SMQZZOW6.js} +10 -10
- package/Build/Workers/{chunk-TA777BGS.js → chunk-TKKIREQ6.js} +1 -1
- package/Build/Workers/{chunk-AEAVLYPS.js → chunk-U3ZA64U7.js} +2 -2
- package/Build/Workers/{chunk-7LSFAEWF.js → chunk-UA25D5MX.js} +10 -10
- package/Build/Workers/{chunk-J3OFS2RD.js → chunk-UOOIQ3KX.js} +12 -12
- package/Build/Workers/{chunk-ND3NTTOF.js → chunk-V7VQKN6N.js} +6 -6
- package/Build/Workers/{chunk-I3A6DXYZ.js → chunk-VQYETPWC.js} +4 -4
- package/Build/Workers/{chunk-35H3UBIO.js → chunk-VWV2IJRB.js} +11 -11
- package/Build/Workers/{chunk-QSDY4NS7.js → chunk-XZMBNNDX.js} +9 -9
- package/Build/Workers/{chunk-TAI4HLII.js → chunk-Y57HREW5.js} +4 -4
- package/Build/Workers/{chunk-3TKLDHV3.js → chunk-Y5BF6AFU.js} +2 -2
- package/Build/Workers/{chunk-3XY3MVPG.js → chunk-YLY7NKAB.js} +4 -4
- package/Build/Workers/{chunk-BVAIWR7O.js → chunk-ZK3CF7ZD.js} +12 -12
- package/Build/Workers/{chunk-DH26SNAB.js → chunk-ZP7JMQV4.js} +1 -1
- package/Build/Workers/{chunk-3RFFPH4M.js → chunk-ZZ46LWL6.js} +1 -1
- package/Build/Workers/combineGeometry.js +24 -24
- package/Build/Workers/createBoxGeometry.js +18 -18
- package/Build/Workers/createBoxOutlineGeometry.js +16 -16
- package/Build/Workers/createCircleGeometry.js +26 -26
- package/Build/Workers/createCircleOutlineGeometry.js +19 -19
- package/Build/Workers/createCoplanarPolygonGeometry.js +33 -33
- package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +31 -31
- package/Build/Workers/createCorridorGeometry.js +29 -29
- package/Build/Workers/createCorridorOutlineGeometry.js +28 -28
- package/Build/Workers/createCylinderGeometry.js +20 -20
- package/Build/Workers/createCylinderOutlineGeometry.js +18 -18
- package/Build/Workers/createEllipseGeometry.js +26 -26
- package/Build/Workers/createEllipseOutlineGeometry.js +19 -19
- package/Build/Workers/createEllipsoidGeometry.js +19 -19
- package/Build/Workers/createEllipsoidOutlineGeometry.js +18 -18
- package/Build/Workers/createFrustumGeometry.js +18 -18
- package/Build/Workers/createFrustumOutlineGeometry.js +18 -18
- package/Build/Workers/createGeometry.js +24 -24
- package/Build/Workers/createGroundPolylineGeometry.js +22 -22
- package/Build/Workers/createPlaneGeometry.js +16 -16
- package/Build/Workers/createPlaneOutlineGeometry.js +15 -15
- package/Build/Workers/createPolygonGeometry.js +32 -32
- package/Build/Workers/createPolygonOutlineGeometry.js +30 -30
- package/Build/Workers/createPolylineGeometry.js +25 -25
- package/Build/Workers/createPolylineVolumeGeometry.js +31 -31
- package/Build/Workers/createPolylineVolumeOutlineGeometry.js +27 -27
- package/Build/Workers/createRectangleGeometry.js +27 -27
- package/Build/Workers/createRectangleOutlineGeometry.js +20 -20
- package/Build/Workers/createSimplePolylineGeometry.js +23 -23
- package/Build/Workers/createSphereGeometry.js +19 -19
- package/Build/Workers/createSphereOutlineGeometry.js +18 -18
- package/Build/Workers/createTaskProcessorWorker.js +3 -3
- package/Build/Workers/createVectorTileClampedPolylines.js +14 -14
- package/Build/Workers/createVectorTileGeometries.js +24 -24
- package/Build/Workers/createVectorTilePoints.js +13 -13
- package/Build/Workers/createVectorTilePolygons.js +22 -22
- package/Build/Workers/createVectorTilePolylines.js +14 -14
- package/Build/Workers/createVerticesFromCesium3DTilesTerrain.js +25 -25
- package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +22 -22
- package/Build/Workers/createVerticesFromHeightmap.js +22 -22
- package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +20 -20
- package/Build/Workers/createWallGeometry.js +24 -24
- package/Build/Workers/createWallOutlineGeometry.js +23 -23
- package/Build/Workers/decodeDraco.js +10 -10
- package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
- package/Build/Workers/decodeI3S.js +10 -10
- package/Build/Workers/gaussianSplatSorter.js +4 -4
- package/Build/Workers/gaussianSplatTextureGenerator.js +4 -4
- package/Build/Workers/incrementallyBuildTerrainPicker.js +10 -10
- package/Build/Workers/transcodeKTX2.js +6 -6
- package/Build/Workers/transferTypedArrayTest.js +1 -1
- package/Build/Workers/upsampleQuantizedTerrainMesh.js +22 -22
- package/Build/Workers/upsampleVerticesFromCesium3DTilesTerrain.js +25 -25
- package/Source/Core/Cartesian2.js +1 -1
- package/Source/Core/Cartesian3.js +1 -1
- package/Source/Core/Cartesian4.js +1 -1
- package/Source/Core/ComponentDatatype.js +35 -0
- package/Source/Core/Ion.js +1 -1
- package/Source/Core/MapProjection.js +1 -0
- package/Source/Core/Matrix2.js +1 -1
- package/Source/Core/Matrix3.js +1 -1
- package/Source/Core/Matrix4.js +1 -1
- package/Source/Core/Resource.js +1 -1
- package/Source/Core/ScreenSpaceEventHandler.js +51 -41
- package/Source/Core/createColorRamp.js +37 -0
- package/Source/Core/globalTypes.js +25 -0
- package/Source/Renderer/Pass.js +3 -2
- package/Source/Renderer/createUniform.js +346 -239
- package/Source/Renderer/createUniformArray.js +494 -381
- package/Source/Scene/ArcGisMapService.js +1 -1
- package/Source/Scene/BufferPoint.js +1 -0
- package/Source/Scene/BufferPointCollection.js +14 -1
- package/Source/Scene/BufferPolygon.js +3 -2
- package/Source/Scene/BufferPolygonCollection.js +10 -0
- package/Source/Scene/BufferPolyline.js +1 -0
- package/Source/Scene/BufferPolylineCollection.js +2 -0
- package/Source/Scene/BufferPrimitiveCollection.js +79 -28
- package/Source/Scene/CameraEventAggregator.js +30 -18
- package/Source/Scene/Cesium3DTile.js +54 -1
- package/Source/Scene/Cesium3DTileContent.js +195 -254
- package/Source/Scene/Cesium3DTileContentFactory.js +10 -2
- package/Source/Scene/Cesium3DTileset.js +45 -5
- package/Source/Scene/Composite3DTileContent.js +254 -292
- package/Source/Scene/EdgeDisplayMode.js +50 -0
- package/Source/Scene/Empty3DTileContent.js +100 -132
- package/Source/Scene/GaussianSplat3DTileContent.js +436 -478
- package/Source/Scene/GeoJsonPrimitive.js +874 -0
- package/Source/Scene/Geometry3DTileContent.js +151 -185
- package/Source/Scene/GltfLoader.js +109 -0
- package/Source/Scene/Implicit3DTileContent.js +179 -214
- package/Source/Scene/MVTDataProvider.js +147 -0
- package/Source/Scene/Model/EdgeVisibilityPipelineStage.js +79 -311
- package/Source/Scene/Model/Model.js +34 -0
- package/Source/Scene/Model/Model3DTileContent.js +424 -458
- package/Source/Scene/Model/ModelDrawCommand.js +31 -3
- package/Source/Scene/Model/ModelUtility.js +4 -0
- package/Source/Scene/Model/createVectorTileBuffersFromModelComponents.js +466 -150
- package/Source/Scene/ModelComponents.js +39 -1
- package/Source/Scene/Multiple3DTileContent.js +291 -334
- package/Source/Scene/Scene.js +26 -0
- package/Source/Scene/Tileset3DTileContent.js +113 -146
- package/Source/Scene/UrlTemplate3DTilesDataProvider.js +499 -0
- package/Source/Scene/Vector3DTileContent.js +205 -234
- package/Source/Scene/VectorGltf3DTileContent.js +85 -36
- package/Source/Scene/VoxelPrimitive.js +159 -175
- package/Source/Scene/VoxelProvider.js +64 -91
- package/Source/Scene/buildVectorGltfFromMVT.js +1059 -0
- package/Source/Scene/buildVoxelCustomShader.js +199 -0
- package/Source/Scene/decodeMVT.js +634 -0
- package/Source/Scene/renderBufferPointCollection.js +110 -64
- package/Source/Scene/renderBufferPolygonCollection.js +102 -55
- package/Source/Scene/renderBufferPolylineCollection.js +365 -166
- package/Source/Shaders/BufferPointMaterialFS.glsl +1 -0
- package/Source/Shaders/BufferPointMaterialFS.js +1 -0
- package/Source/Shaders/BufferPointMaterialVS.glsl +19 -9
- package/Source/Shaders/BufferPointMaterialVS.js +20 -10
- package/Source/Shaders/BufferPolygonMaterialVS.glsl +13 -4
- package/Source/Shaders/BufferPolygonMaterialVS.js +14 -5
- package/Source/Shaders/BufferPolylineMaterialVS.glsl +16 -2
- package/Source/Shaders/BufferPolylineMaterialVS.js +17 -3
- package/Source/Shaders/Builtin/Constants/passCesium3DTileEdgesDirect.glsl +9 -0
- package/Source/Shaders/Builtin/Constants/passCesium3DTileEdgesDirect.js +11 -0
- package/Source/Shaders/Builtin/Constants/passOverlay.glsl +1 -1
- package/Source/Shaders/Builtin/Constants/passOverlay.js +1 -1
- package/Source/Shaders/Builtin/CzmBuiltins.js +2 -0
- package/Source/Shaders/Model/EdgeVisibilityStageVS.glsl +0 -1
- package/Source/Shaders/Model/EdgeVisibilityStageVS.js +0 -1
- package/index.d.ts +253 -35
- package/index.js +71 -62
- 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;
|