@vcmap/core 6.0.0-rc.6 → 6.0.0-rc.7
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/dist/cesium.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/src/layer/cesium/clusterContext.d.ts +4 -2
- package/dist/src/layer/cesium/clusterContext.js +14 -3
- package/dist/src/layer/cesium/clusterContext.js.map +1 -1
- package/dist/src/layer/cesium/vectorContext.d.ts +2 -2
- package/dist/src/layer/cesium/vectorContext.js +7 -5
- package/dist/src/layer/cesium/vectorContext.js.map +1 -1
- package/dist/src/layer/oblique/obliqueHelpers.js +3 -3
- package/dist/src/layer/oblique/obliqueHelpers.js.map +1 -1
- package/dist/src/layer/vectorProperties.d.ts +2 -2
- package/dist/src/layer/vectorProperties.js +6 -4
- package/dist/src/layer/vectorProperties.js.map +1 -1
- package/dist/src/ol/geom/geometryCollection.js +1 -1
- package/dist/src/ol/geom/geometryCollection.js.map +1 -1
- package/dist/src/util/clipping/clippingPlaneHelper.js +2 -2
- package/dist/src/util/clipping/clippingPlaneHelper.js.map +1 -1
- package/dist/src/util/editor/editorHelpers.js +3 -3
- package/dist/src/util/editor/editorHelpers.js.map +1 -1
- package/dist/src/util/featureconverter/convert.d.ts +4 -0
- package/dist/src/util/featureconverter/convert.js +1 -1
- package/dist/src/util/featureconverter/convert.js.map +1 -1
- package/dist/src/util/featureconverter/pointHelpers.js +9 -3
- package/dist/src/util/featureconverter/pointHelpers.js.map +1 -1
- package/dist/src/util/geometryHelpers.d.ts +12 -1
- package/dist/src/util/geometryHelpers.js +89 -12
- package/dist/src/util/geometryHelpers.js.map +1 -1
- package/dist/tests/unit/helpers/helpers.d.ts +1 -1
- package/dist/tests/unit/helpers/helpers.js +2 -2
- package/dist/tests/unit/helpers/helpers.js.map +1 -1
- package/index.ts +3 -1
- package/package.json +1 -1
- package/src/cesium/cesium.d.ts +1 -0
- package/src/layer/cesium/clusterContext.ts +16 -3
- package/src/layer/cesium/vectorContext.ts +13 -10
- package/src/layer/oblique/obliqueHelpers.ts +3 -3
- package/src/layer/vectorProperties.ts +7 -5
- package/src/ol/geom/geometryCollection.js +3 -1
- package/src/util/clipping/clippingPlaneHelper.ts +3 -4
- package/src/util/editor/editorHelpers.ts +3 -3
- package/src/util/featureconverter/convert.ts +3 -1
- package/src/util/featureconverter/pointHelpers.ts +9 -4
- package/src/util/geometryHelpers.ts +145 -14
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
Entity,
|
|
5
5
|
SplitDirection,
|
|
6
6
|
Scene,
|
|
7
|
+
ConstantProperty,
|
|
7
8
|
} from '@vcmap-cesium/engine';
|
|
8
9
|
import { StyleLike } from 'ol/style/Style.js';
|
|
9
10
|
import type { Feature } from 'ol/index.js';
|
|
@@ -17,12 +18,18 @@ import convert, { ConvertedItem } from '../../util/featureconverter/convert.js';
|
|
|
17
18
|
class ClusterContext implements CesiumVectorContext {
|
|
18
19
|
entities: EntityCollection;
|
|
19
20
|
|
|
21
|
+
splitDirection: SplitDirection;
|
|
22
|
+
|
|
23
|
+
private _splitDirectionProperty: ConstantProperty;
|
|
24
|
+
|
|
20
25
|
private _featureItems = new Map<Feature, (() => void)[]>();
|
|
21
26
|
|
|
22
27
|
private _convertingFeatures: Map<Feature, () => void> = new Map();
|
|
23
28
|
|
|
24
|
-
constructor(dataSource: CustomDataSource) {
|
|
29
|
+
constructor(dataSource: CustomDataSource, splitDirection: SplitDirection) {
|
|
25
30
|
this.entities = dataSource.entities;
|
|
31
|
+
this.splitDirection = splitDirection;
|
|
32
|
+
this._splitDirectionProperty = new ConstantProperty(splitDirection);
|
|
26
33
|
}
|
|
27
34
|
|
|
28
35
|
private _addConvertedItems(
|
|
@@ -36,7 +43,10 @@ class ClusterContext implements CesiumVectorContext {
|
|
|
36
43
|
let removeItem: (() => void) | undefined;
|
|
37
44
|
if (item.type === 'billboard') {
|
|
38
45
|
instance = this.entities.add({
|
|
39
|
-
billboard:
|
|
46
|
+
billboard: {
|
|
47
|
+
...item.item,
|
|
48
|
+
splitDirection: this._splitDirectionProperty,
|
|
49
|
+
},
|
|
40
50
|
position: item.item.position,
|
|
41
51
|
});
|
|
42
52
|
} else if (item.type === 'label') {
|
|
@@ -108,7 +118,10 @@ class ClusterContext implements CesiumVectorContext {
|
|
|
108
118
|
}
|
|
109
119
|
|
|
110
120
|
// eslint-disable-next-line class-methods-use-this,no-unused-vars
|
|
111
|
-
updateSplitDirection(
|
|
121
|
+
updateSplitDirection(splitDirection: SplitDirection): void {
|
|
122
|
+
this.splitDirection = splitDirection;
|
|
123
|
+
this._splitDirectionProperty.setValue(this.splitDirection);
|
|
124
|
+
}
|
|
112
125
|
|
|
113
126
|
clear(): void {
|
|
114
127
|
this.entities.removeAll();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
Billboard,
|
|
3
3
|
BillboardCollection,
|
|
4
4
|
Cartesian3,
|
|
5
5
|
type Entity,
|
|
@@ -34,13 +34,12 @@ export function setReferenceForPicking(
|
|
|
34
34
|
/**
|
|
35
35
|
* Sets splitDirection on primitives. Currently only Model primitives support splitting.
|
|
36
36
|
*/
|
|
37
|
-
export function setSplitDirectionOnPrimitives
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
): void {
|
|
37
|
+
export function setSplitDirectionOnPrimitives<
|
|
38
|
+
T extends PrimitiveCollection | BillboardCollection,
|
|
39
|
+
>(splitDirection: SplitDirection, primitives: T): void {
|
|
41
40
|
for (let i = 0; i < primitives.length; i++) {
|
|
42
|
-
const p = primitives.get(i) as Primitive | Model;
|
|
43
|
-
if (p instanceof Model) {
|
|
41
|
+
const p = primitives.get(i) as Primitive | Model | Billboard;
|
|
42
|
+
if (p instanceof Model || p instanceof Billboard) {
|
|
44
43
|
p.splitDirection = splitDirection;
|
|
45
44
|
}
|
|
46
45
|
}
|
|
@@ -84,7 +83,7 @@ export function setupScalingPrimitiveCollection(
|
|
|
84
83
|
primitive.modelMatrix = Matrix4.setScale(
|
|
85
84
|
modelMatrix,
|
|
86
85
|
new Cartesian3(res, res, res),
|
|
87
|
-
|
|
86
|
+
primitive.modelMatrix,
|
|
88
87
|
);
|
|
89
88
|
primitive[scaleSymbol] = res;
|
|
90
89
|
}
|
|
@@ -202,8 +201,11 @@ export default class VectorContext implements CesiumVectorContext {
|
|
|
202
201
|
setReferenceForPicking(feature, instance);
|
|
203
202
|
}
|
|
204
203
|
|
|
205
|
-
if (
|
|
206
|
-
|
|
204
|
+
if (
|
|
205
|
+
this.splitDirection &&
|
|
206
|
+
(instance instanceof Model || instance instanceof Billboard)
|
|
207
|
+
) {
|
|
208
|
+
// Cesium currently only supports splitDirection on Model & Billboard Primitives
|
|
207
209
|
instance.splitDirection = this.splitDirection;
|
|
208
210
|
}
|
|
209
211
|
}
|
|
@@ -262,6 +264,7 @@ export default class VectorContext implements CesiumVectorContext {
|
|
|
262
264
|
this.splitDirection = splitDirection;
|
|
263
265
|
setSplitDirectionOnPrimitives(splitDirection, this.primitives);
|
|
264
266
|
setSplitDirectionOnPrimitives(splitDirection, this.scaledPrimitives);
|
|
267
|
+
setSplitDirectionOnPrimitives(splitDirection, this.billboards);
|
|
265
268
|
}
|
|
266
269
|
|
|
267
270
|
clear(): void {
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from '../vectorSymbols.js';
|
|
20
20
|
import {
|
|
21
21
|
convertGeometryToPolygon,
|
|
22
|
-
|
|
22
|
+
getFlatCoordinateReferences,
|
|
23
23
|
} from '../../util/geometryHelpers.js';
|
|
24
24
|
import { transformFromImage } from '../../oblique/helpers.js';
|
|
25
25
|
import type ObliqueImage from '../../oblique/obliqueImage.js';
|
|
@@ -97,7 +97,7 @@ export async function mercatorGeometryToImageGeometry(
|
|
|
97
97
|
? fromCircle(inputSourceGeometry)
|
|
98
98
|
: inputSourceGeometry;
|
|
99
99
|
const coordinates = sourceGeometry.getCoordinates() as any[];
|
|
100
|
-
const flattenCoordinates =
|
|
100
|
+
const flattenCoordinates = getFlatCoordinateReferences(
|
|
101
101
|
sourceGeometry,
|
|
102
102
|
coordinates,
|
|
103
103
|
);
|
|
@@ -151,7 +151,7 @@ export function imageGeometryToMercatorGeometry(
|
|
|
151
151
|
image: ObliqueImage,
|
|
152
152
|
): Promise<Geometry> {
|
|
153
153
|
const coordinates = sourceGeometry.getCoordinates() as any[];
|
|
154
|
-
const flattenCoordinates =
|
|
154
|
+
const flattenCoordinates = getFlatCoordinateReferences(
|
|
155
155
|
sourceGeometry,
|
|
156
156
|
coordinates,
|
|
157
157
|
);
|
|
@@ -897,10 +897,10 @@ class VectorProperties {
|
|
|
897
897
|
}
|
|
898
898
|
|
|
899
899
|
/**
|
|
900
|
-
* Get the features or the properties modelOptions.
|
|
900
|
+
* Get the features or the properties modelOptions.
|
|
901
901
|
* @param feature
|
|
902
902
|
*/
|
|
903
|
-
getModelOptions(feature: Feature): Record<string, unknown> {
|
|
903
|
+
getModelOptions(feature: Feature): Record<string, unknown> | undefined {
|
|
904
904
|
const featureValue = feature.get('olcs_modelOptions') as
|
|
905
905
|
| Record<string, unknown>
|
|
906
906
|
| undefined;
|
|
@@ -910,7 +910,7 @@ class VectorProperties {
|
|
|
910
910
|
if (this.modelOptions) {
|
|
911
911
|
return this.modelOptions;
|
|
912
912
|
}
|
|
913
|
-
return
|
|
913
|
+
return undefined;
|
|
914
914
|
}
|
|
915
915
|
|
|
916
916
|
get modelAutoScale(): boolean {
|
|
@@ -1315,7 +1315,7 @@ class VectorProperties {
|
|
|
1315
1315
|
}
|
|
1316
1316
|
|
|
1317
1317
|
getValues(): VectorPropertiesOptions {
|
|
1318
|
-
|
|
1318
|
+
return {
|
|
1319
1319
|
altitudeMode: getAltitudeModeOptions(this.altitudeMode),
|
|
1320
1320
|
allowPicking: this.allowPicking,
|
|
1321
1321
|
classificationType: getClassificationTypeOptions(this.classificationType),
|
|
@@ -1336,9 +1336,11 @@ class VectorProperties {
|
|
|
1336
1336
|
modelHeading: this.modelHeading,
|
|
1337
1337
|
modelPitch: this.modelPitch,
|
|
1338
1338
|
modelRoll: this.modelRoll,
|
|
1339
|
+
modelAutoScale: this.modelAutoScale,
|
|
1340
|
+
modelOptions: this.modelOptions,
|
|
1339
1341
|
baseUrl: this.baseUrl,
|
|
1342
|
+
primitiveOptions: this.primitiveOptions,
|
|
1340
1343
|
};
|
|
1341
|
-
return values;
|
|
1342
1344
|
}
|
|
1343
1345
|
|
|
1344
1346
|
/**
|
|
@@ -54,5 +54,7 @@ GeometryCollection.prototype.getStride = function getStride() {
|
|
|
54
54
|
*/
|
|
55
55
|
GeometryCollection.prototype.getFlatCoordinates =
|
|
56
56
|
function getFlatCoordinates() {
|
|
57
|
-
return this.
|
|
57
|
+
return this.getGeometriesArrayRecursive().flatMap((g) =>
|
|
58
|
+
g.getFlatCoordinates(),
|
|
59
|
+
);
|
|
58
60
|
};
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
type Camera,
|
|
14
14
|
} from '@vcmap-cesium/engine';
|
|
15
15
|
import type { Coordinate } from 'ol/coordinate.js';
|
|
16
|
-
import type { Geometry } from 'ol/geom.js';
|
|
17
16
|
import Feature from 'ol/Feature.js';
|
|
18
17
|
import LineString from 'ol/geom/LineString.js';
|
|
19
18
|
import { offset } from 'ol/sphere.js';
|
|
@@ -27,7 +26,7 @@ import Extent3D from '../featureconverter/extent3D.js';
|
|
|
27
26
|
import {
|
|
28
27
|
enforceEndingVertex,
|
|
29
28
|
enforceRightHand,
|
|
30
|
-
|
|
29
|
+
getFlatCoordinateReferences,
|
|
31
30
|
} from '../geometryHelpers.js';
|
|
32
31
|
import { mercatorToCartesian } from '../math.js';
|
|
33
32
|
|
|
@@ -162,7 +161,7 @@ export function createClippingPlaneCollection(
|
|
|
162
161
|
check(transformMatrix, optional(Matrix4));
|
|
163
162
|
|
|
164
163
|
const clippingPlanes = [];
|
|
165
|
-
const geometry = feature.getGeometry()
|
|
164
|
+
const geometry = feature.getGeometry()!;
|
|
166
165
|
const geometryType = geometry.getType();
|
|
167
166
|
|
|
168
167
|
if (geometryType === 'Point') {
|
|
@@ -174,7 +173,7 @@ export function createClippingPlaneCollection(
|
|
|
174
173
|
),
|
|
175
174
|
);
|
|
176
175
|
} else {
|
|
177
|
-
const coords =
|
|
176
|
+
const coords = getFlatCoordinateReferences(geometry);
|
|
178
177
|
if (
|
|
179
178
|
coords.length < 2 ||
|
|
180
179
|
(coords[0][0] === coords[1][0] && coords[0][1] === coords[1][1])
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
} from '@vcmap-cesium/engine';
|
|
19
19
|
|
|
20
20
|
import { mercatorToCartesian } from '../math.js';
|
|
21
|
-
import {
|
|
21
|
+
import { getFlatCoordinateReferences } from '../geometryHelpers.js';
|
|
22
22
|
import CesiumMap from '../../map/cesiumMap.js';
|
|
23
23
|
import { vertexIndexSymbol, vertexSymbol } from './editorSymbols.js';
|
|
24
24
|
import {
|
|
@@ -365,7 +365,7 @@ export async function drapeGeometryOnTerrain(
|
|
|
365
365
|
): Promise<void> {
|
|
366
366
|
if (map instanceof CesiumMap) {
|
|
367
367
|
const coordinates = geometry.getCoordinates() as any[];
|
|
368
|
-
const flats =
|
|
368
|
+
const flats = getFlatCoordinateReferences(geometry, coordinates);
|
|
369
369
|
await map.getHeightFromTerrain(flats);
|
|
370
370
|
geometry.setCoordinates(coordinates, 'XYZ');
|
|
371
371
|
}
|
|
@@ -382,7 +382,7 @@ export async function placeGeometryOnTerrain(
|
|
|
382
382
|
): Promise<void> {
|
|
383
383
|
if (map instanceof CesiumMap) {
|
|
384
384
|
const coordinates = geometry.getCoordinates() as any[];
|
|
385
|
-
const flats =
|
|
385
|
+
const flats = getFlatCoordinateReferences(geometry, coordinates);
|
|
386
386
|
await map.getHeightFromTerrain(flats);
|
|
387
387
|
let minHeight = Infinity;
|
|
388
388
|
flats.forEach((coord) => {
|
|
@@ -109,7 +109,9 @@ export function getStylesArray(
|
|
|
109
109
|
return styles;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
function getSingleGeometriesFromGeometry(
|
|
112
|
+
export function getSingleGeometriesFromGeometry(
|
|
113
|
+
geometry: Geometry,
|
|
114
|
+
): SingleGeometry[] {
|
|
113
115
|
if (
|
|
114
116
|
geometry instanceof Point ||
|
|
115
117
|
geometry instanceof Polygon ||
|
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
RelativeHeightReference,
|
|
45
45
|
VectorHeightInfo,
|
|
46
46
|
} from './vectorHeightInfo.js';
|
|
47
|
+
import { scaleSymbol } from '../../layer/cesium/vectorContext.js';
|
|
47
48
|
|
|
48
49
|
function makeOffsetAutoScalePrimitive(
|
|
49
50
|
primitive: Primitive | Model,
|
|
@@ -114,12 +115,16 @@ function makeClampedPrimitive(
|
|
|
114
115
|
undefined,
|
|
115
116
|
scratchUpdateHeightCartesian,
|
|
116
117
|
);
|
|
117
|
-
|
|
118
|
-
const
|
|
118
|
+
let usedScale = scale;
|
|
119
|
+
const autoScale = primitive[scaleSymbol];
|
|
120
|
+
if (autoScale != null) {
|
|
121
|
+
usedScale = new Cartesian3(autoScale, autoScale, autoScale);
|
|
122
|
+
}
|
|
123
|
+
const geometryModelMatrix = Matrix4.fromScale(usedScale);
|
|
119
124
|
if (offset) {
|
|
120
125
|
Matrix4.setTranslation(
|
|
121
126
|
geometryModelMatrix,
|
|
122
|
-
Cartesian3.multiplyComponents(offset,
|
|
127
|
+
Cartesian3.multiplyComponents(offset, usedScale, new Cartesian3()),
|
|
123
128
|
geometryModelMatrix,
|
|
124
129
|
);
|
|
125
130
|
}
|
|
@@ -131,7 +136,7 @@ function makeClampedPrimitive(
|
|
|
131
136
|
primitive.modelMatrix = Matrix4.multiply(
|
|
132
137
|
transform,
|
|
133
138
|
geometryModelMatrix,
|
|
134
|
-
|
|
139
|
+
primitive.modelMatrix,
|
|
135
140
|
);
|
|
136
141
|
};
|
|
137
142
|
|
|
@@ -19,8 +19,18 @@ import {
|
|
|
19
19
|
Polygon,
|
|
20
20
|
SimpleGeometry,
|
|
21
21
|
} from 'ol/geom.js';
|
|
22
|
+
import { Feature } from 'ol';
|
|
22
23
|
import Projection from './projection.js';
|
|
23
24
|
import { mercatorToCartographic } from './math.js';
|
|
25
|
+
import VectorProperties from '../layer/vectorProperties.js';
|
|
26
|
+
import {
|
|
27
|
+
getHeightInfo,
|
|
28
|
+
isClampedHeightReference,
|
|
29
|
+
isRelativeHeightReference,
|
|
30
|
+
RelativeHeightReference,
|
|
31
|
+
VectorHeightInfo,
|
|
32
|
+
} from './featureconverter/vectorHeightInfo.js';
|
|
33
|
+
import { getSingleGeometriesFromGeometry } from './featureconverter/convert.js';
|
|
24
34
|
|
|
25
35
|
export function getFlatCoordinatesFromSimpleGeometry(
|
|
26
36
|
geometry: SimpleGeometry,
|
|
@@ -44,7 +54,7 @@ export function getFlatCoordinatesFromSimpleGeometry(
|
|
|
44
54
|
return [];
|
|
45
55
|
}
|
|
46
56
|
|
|
47
|
-
export function
|
|
57
|
+
export function getFlatCoordinateReferences(
|
|
48
58
|
geometry: Geometry,
|
|
49
59
|
inputCoordinates?: any[],
|
|
50
60
|
): Coordinate[] {
|
|
@@ -78,9 +88,7 @@ export function getFlatCoordinatesFromGeometry(
|
|
|
78
88
|
} else if (geometry instanceof GeometryCollection) {
|
|
79
89
|
flattenCoordinates = geometry
|
|
80
90
|
.getGeometries()
|
|
81
|
-
.map((g, i) =>
|
|
82
|
-
getFlatCoordinatesFromGeometry(g, coordinates?.[i] as any[]),
|
|
83
|
-
)
|
|
91
|
+
.map((g, i) => getFlatCoordinateReferences(g, coordinates?.[i] as any[]))
|
|
84
92
|
.reduce((current, next) => current.concat(next));
|
|
85
93
|
}
|
|
86
94
|
return flattenCoordinates as Coordinate[];
|
|
@@ -195,7 +203,7 @@ export function from3Dto2DLayout(geometry: Geometry): void {
|
|
|
195
203
|
return;
|
|
196
204
|
}
|
|
197
205
|
const coordinates = geometry.getCoordinates() as any[];
|
|
198
|
-
const flatCoordinates =
|
|
206
|
+
const flatCoordinates = getFlatCoordinateReferences(geometry, coordinates);
|
|
199
207
|
flatCoordinates.forEach((coordinate) => {
|
|
200
208
|
if (layout === 'XYZM') {
|
|
201
209
|
coordinate[2] = coordinate.pop()!;
|
|
@@ -207,13 +215,13 @@ export function from3Dto2DLayout(geometry: Geometry): void {
|
|
|
207
215
|
}
|
|
208
216
|
|
|
209
217
|
/**
|
|
210
|
-
*
|
|
211
|
-
* will
|
|
218
|
+
* Places a geometry on to the ground (or terrain). The geometry is changed in place. This function
|
|
219
|
+
* will set the layout to a respective 3D layout.
|
|
212
220
|
* @param geometry
|
|
213
221
|
* @param scene
|
|
214
|
-
* @param heightReference
|
|
222
|
+
* @param heightReference - clamp to ground will use `scene.getHeightMostDetailed`, terrain will use `sampleTerrainMostDetailed` using the scenes terrain provider
|
|
215
223
|
*/
|
|
216
|
-
export async function
|
|
224
|
+
export async function placeGeometryOnGround(
|
|
217
225
|
geometry: Geometry,
|
|
218
226
|
scene: Scene,
|
|
219
227
|
heightReference:
|
|
@@ -221,17 +229,15 @@ export async function from2Dto3DLayout(
|
|
|
221
229
|
| HeightReference.CLAMP_TO_TERRAIN,
|
|
222
230
|
): Promise<void> {
|
|
223
231
|
const layout = geometry.getLayout();
|
|
224
|
-
if (!is2DLayout(layout)) {
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
232
|
const coordinates = geometry.getCoordinates() as any[];
|
|
228
|
-
const flatCoordinates =
|
|
233
|
+
const flatCoordinates = getFlatCoordinateReferences(geometry, coordinates);
|
|
229
234
|
const cartographics = flatCoordinates.map((c) => mercatorToCartographic(c));
|
|
230
235
|
if (heightReference === HeightReference.CLAMP_TO_GROUND) {
|
|
231
236
|
await scene.sampleHeightMostDetailed(cartographics);
|
|
232
237
|
} else {
|
|
233
238
|
await sampleTerrainMostDetailed(scene.terrainProvider, cartographics);
|
|
234
239
|
}
|
|
240
|
+
|
|
235
241
|
cartographics.forEach((c, index) => {
|
|
236
242
|
if (layout === 'XYM') {
|
|
237
243
|
flatCoordinates[index][3] = flatCoordinates[index][2];
|
|
@@ -240,5 +246,130 @@ export async function from2Dto3DLayout(
|
|
|
240
246
|
flatCoordinates[index][2] = c.height;
|
|
241
247
|
}
|
|
242
248
|
});
|
|
243
|
-
|
|
249
|
+
|
|
250
|
+
geometry.setCoordinates(
|
|
251
|
+
coordinates,
|
|
252
|
+
layout === 'XYM' || layout === 'XYZM' ? 'XYZM' : 'XYZ',
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Wil transform a 2D geometry (layout XY XYM) in place to 3D (XYZ XYZM) using the provided scene & height reference.
|
|
258
|
+
* will no apply anything, if the layout is already 3D
|
|
259
|
+
* @param geometry
|
|
260
|
+
* @param scene
|
|
261
|
+
* @param heightReference
|
|
262
|
+
*/
|
|
263
|
+
export async function from2Dto3DLayout(
|
|
264
|
+
geometry: Geometry,
|
|
265
|
+
scene: Scene,
|
|
266
|
+
heightReference:
|
|
267
|
+
| HeightReference.CLAMP_TO_GROUND
|
|
268
|
+
| HeightReference.CLAMP_TO_TERRAIN,
|
|
269
|
+
): Promise<void> {
|
|
270
|
+
if (is2DLayout(geometry.getLayout())) {
|
|
271
|
+
await placeGeometryOnGround(geometry, scene, heightReference);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export async function createAbsoluteFeatures(
|
|
276
|
+
features: Feature[],
|
|
277
|
+
vectorProperties: VectorProperties,
|
|
278
|
+
scene: Scene,
|
|
279
|
+
): Promise<Feature[]> {
|
|
280
|
+
const clones = features.map((feature) => feature.clone());
|
|
281
|
+
const absoluteClones = await Promise.all(
|
|
282
|
+
clones.map(async (feature) => {
|
|
283
|
+
const geometry = feature.getGeometry();
|
|
284
|
+
if (!geometry) {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const altitudeMode = vectorProperties.getAltitudeMode(feature);
|
|
289
|
+
if (altitudeMode === HeightReference.NONE) {
|
|
290
|
+
if (is2DLayout(geometry.getLayout())) {
|
|
291
|
+
await from2Dto3DLayout(
|
|
292
|
+
geometry,
|
|
293
|
+
scene,
|
|
294
|
+
HeightReference.CLAMP_TO_GROUND,
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
} else if (isClampedHeightReference(altitudeMode)) {
|
|
298
|
+
await placeGeometryOnGround(
|
|
299
|
+
geometry,
|
|
300
|
+
scene,
|
|
301
|
+
altitudeMode !== HeightReference.CLAMP_TO_TERRAIN
|
|
302
|
+
? HeightReference.CLAMP_TO_GROUND
|
|
303
|
+
: HeightReference.CLAMP_TO_TERRAIN,
|
|
304
|
+
);
|
|
305
|
+
} else if (isRelativeHeightReference(altitudeMode)) {
|
|
306
|
+
const singleGeometries = getSingleGeometriesFromGeometry(geometry);
|
|
307
|
+
await Promise.all(
|
|
308
|
+
singleGeometries.map(async (singleGeometry) => {
|
|
309
|
+
const heightInfo = getHeightInfo(
|
|
310
|
+
feature,
|
|
311
|
+
singleGeometry,
|
|
312
|
+
vectorProperties,
|
|
313
|
+
) as VectorHeightInfo<RelativeHeightReference>;
|
|
314
|
+
|
|
315
|
+
let { groundLevel } = heightInfo;
|
|
316
|
+
if (heightInfo.clampOrigin) {
|
|
317
|
+
const cartographics = [
|
|
318
|
+
mercatorToCartographic(heightInfo.clampOrigin),
|
|
319
|
+
];
|
|
320
|
+
if (
|
|
321
|
+
heightInfo.heightReference ===
|
|
322
|
+
HeightReference.RELATIVE_TO_TERRAIN
|
|
323
|
+
) {
|
|
324
|
+
await sampleTerrainMostDetailed(
|
|
325
|
+
scene.terrainProvider,
|
|
326
|
+
cartographics,
|
|
327
|
+
);
|
|
328
|
+
} else {
|
|
329
|
+
await scene.sampleHeightMostDetailed(cartographics);
|
|
330
|
+
}
|
|
331
|
+
groundLevel = cartographics[0].height;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const coordinates = singleGeometry.getCoordinates() as any[];
|
|
335
|
+
const flatCoordinates = getFlatCoordinateReferences(
|
|
336
|
+
singleGeometry,
|
|
337
|
+
coordinates,
|
|
338
|
+
);
|
|
339
|
+
const { heightAboveGround } = heightInfo;
|
|
340
|
+
const setCoordinate =
|
|
341
|
+
heightAboveGround == null
|
|
342
|
+
? (c: Coordinate): void => {
|
|
343
|
+
c[2] += groundLevel as number;
|
|
344
|
+
}
|
|
345
|
+
: (c: Coordinate): void => {
|
|
346
|
+
c[2] = (groundLevel as number) + heightAboveGround;
|
|
347
|
+
};
|
|
348
|
+
flatCoordinates.forEach(setCoordinate);
|
|
349
|
+
singleGeometry.setCoordinates(coordinates, 'XYZ');
|
|
350
|
+
}),
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
if (geometry instanceof MultiPoint) {
|
|
354
|
+
geometry.setCoordinates(
|
|
355
|
+
singleGeometries.map((g) => g.getCoordinates() as Coordinate),
|
|
356
|
+
);
|
|
357
|
+
} else if (geometry instanceof MultiPolygon) {
|
|
358
|
+
geometry.setCoordinates(
|
|
359
|
+
singleGeometries.map((g) => g.getCoordinates() as Coordinate[][]),
|
|
360
|
+
);
|
|
361
|
+
} else if (geometry instanceof MultiLineString) {
|
|
362
|
+
geometry.setCoordinates(
|
|
363
|
+
singleGeometries.map((g) => g.getCoordinates() as Coordinate[]),
|
|
364
|
+
);
|
|
365
|
+
} else if (geometry instanceof GeometryCollection) {
|
|
366
|
+
geometry.setGeometries(singleGeometries);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
return feature;
|
|
371
|
+
}),
|
|
372
|
+
);
|
|
373
|
+
|
|
374
|
+
return absoluteClones.filter((f): f is Feature => !!f);
|
|
244
375
|
}
|