Skip to content

Commit f25640c

Browse files
authored
Merge branch 'main' into cla-label
2 parents fa722f9 + dcaf957 commit f25640c

File tree

12 files changed

+472
-55
lines changed

12 files changed

+472
-55
lines changed

.vscode/cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"iife",
6363
"lerp",
6464
"Lilli",
65+
"maki",
6566
"MAXAR",
6667
"minifiers",
6768
"mipmapped",
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta
7+
name="viewport"
8+
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
9+
/>
10+
<meta
11+
name="description"
12+
content="Use Viewer to start building new applications or easily embed Cesium into existing applications."
13+
/>
14+
<meta name="cesium-sandcastle-labels" content="Beginner, Showcases" />
15+
<title>iTwin Feature Service</title>
16+
<script type="text/javascript" src="../Sandcastle-header.js"></script>
17+
<script type="module" src="../load-cesium-es6.js"></script>
18+
</head>
19+
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html">
20+
<style>
21+
@import url(../templates/bucket.css);
22+
</style>
23+
<div id="cesiumContainer" class="fullSize"></div>
24+
<div id="loadingOverlay"><h1>Loading...</h1></div>
25+
<div id="toolbar">
26+
<div id="layers"></div>
27+
</div>
28+
<script id="cesium_sandcastle_script">
29+
window.startup = async function (Cesium) {
30+
"use strict";
31+
//Sandcastle_Begin
32+
const serviceResponse = await fetch("https://api.cesium.com/itwin/token");
33+
const { access_token: token } = await serviceResponse.json();
34+
35+
Cesium.ITwinPlatform.defaultAccessToken = token;
36+
37+
const iTwinId = "04ba725f-f3c0-4f30-8014-a4488cbd612d";
38+
39+
const viewer = new Cesium.Viewer("cesiumContainer", {
40+
geocoder: false,
41+
sceneModePicker: false,
42+
homeButton: false,
43+
timeline: false,
44+
animation: false,
45+
});
46+
viewer.baseLayerPicker.viewModel.selectedImagery =
47+
viewer.baseLayerPicker.viewModel.imageryProviderViewModels[2];
48+
49+
const birdsEyeView = {
50+
destination: new Cesium.Cartesian3(
51+
-1525359.4318772827,
52+
6191643.528984093,
53+
148851.5321709012,
54+
),
55+
orientation: new Cesium.HeadingPitchRoll(
56+
0.16657338935967037,
57+
-0.7943050121851765,
58+
6.283180723449992,
59+
),
60+
duration: 0,
61+
easingFunction: Cesium.EasingFunction.LINEAR_NONE,
62+
};
63+
viewer.scene.camera.flyTo(birdsEyeView);
64+
65+
// Load feature service geojson files
66+
const points = await Cesium.ITwinData.createDataSourceForRealityDataId(
67+
iTwinId,
68+
"57b975f6-fd92-42ba-8014-79911ed606d1",
69+
);
70+
const lines = await Cesium.ITwinData.createDataSourceForRealityDataId(
71+
iTwinId,
72+
"1099c53f-c568-48a3-a57c-0230a6f37229",
73+
);
74+
const areas = await Cesium.ITwinData.createDataSourceForRealityDataId(
75+
iTwinId,
76+
"21eaf0d0-ab90-400f-97cf-adc455b29a78",
77+
);
78+
79+
// Add some styling to the lines and points to differentiate types
80+
const pinBuilder = new Cesium.PinBuilder();
81+
points.entities.values.forEach(async (entity) => {
82+
const styleByType = {
83+
Tree: { color: Cesium.Color.GREEN, icon: "park2" },
84+
Lamp_post: { color: Cesium.Color.WHITE, icon: "lighthouse" },
85+
Traffic_light: { color: Cesium.Color.CRIMSON, icon: "circle-stroked" },
86+
Arrow_Marking: { color: Cesium.Color.YELLOW, icon: "car" },
87+
Road_Sign: { color: Cesium.Color.ORANGE, icon: "triangle" },
88+
};
89+
const type = entity.properties.Type?.getValue();
90+
if (Cesium.defined(type) && Cesium.defined(styleByType[type])) {
91+
const { color, icon } = styleByType[type];
92+
const canvas = await pinBuilder.fromMakiIconId(icon, color, 48);
93+
entity.billboard.image = canvas.toDataURL();
94+
entity.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
95+
}
96+
});
97+
lines.entities.values.forEach((entity) => {
98+
const lineColorsByType = {
99+
Contours: Cesium.Color.CRIMSON,
100+
Lane_Marking: Cesium.Color.CYAN,
101+
Kerb: Cesium.Color.BLUEVIOLET,
102+
Chevron_marking: Cesium.Color.DARKORANGE,
103+
Turning_pocket: Cesium.Color.DEEPPINK,
104+
Yellow_Box: Cesium.Color.GOLD,
105+
};
106+
const type = entity.properties.Type?.getValue();
107+
if (Cesium.defined(type) && Cesium.defined(lineColorsByType[type])) {
108+
entity.polyline.material = lineColorsByType[type];
109+
}
110+
});
111+
112+
// add the geojsons to the viewer
113+
viewer.dataSources.add(points);
114+
viewer.dataSources.add(lines);
115+
viewer.dataSources.add(areas);
116+
117+
// Create tileset of the reality data mesh and pointcloud
118+
const realityMeshId = "62e4432d-621d-489a-87ff-1fc56a2b5369";
119+
const realityMesh = await Cesium.ITwinData.createTilesetForRealityDataId(
120+
iTwinId,
121+
realityMeshId,
122+
);
123+
viewer.scene.primitives.add(realityMesh);
124+
const pointcloudId = "ebf2ee74-f0de-4cd6-a311-19a169c55fdc";
125+
const pointcloud = await Cesium.ITwinData.createTilesetForRealityDataId(
126+
iTwinId,
127+
pointcloudId,
128+
);
129+
// increase the size of the pointcloud points and turn on attenuation to
130+
// make them more visible in the viewer
131+
pointcloud.maximumScreenSpaceError = 1;
132+
pointcloud.pointCloudShading.attenuation = true;
133+
pointcloud.style = new Cesium.Cesium3DTileStyle({
134+
pointSize: 5.0,
135+
});
136+
pointcloud.show = false;
137+
viewer.scene.primitives.add(pointcloud);
138+
139+
Sandcastle.addToolbarButton(
140+
"Toggle Points",
141+
() => (points.show = !points.show),
142+
"layers",
143+
);
144+
Sandcastle.addToolbarButton(
145+
"Toggle Lines",
146+
() => (lines.show = !lines.show),
147+
"layers",
148+
);
149+
Sandcastle.addToolbarButton(
150+
"Toggle Areas",
151+
() => (areas.show = !areas.show),
152+
"layers",
153+
);
154+
Sandcastle.addToolbarButton(
155+
"Toggle Reality Mesh",
156+
() => (realityMesh.show = !realityMesh.show),
157+
"layers",
158+
);
159+
Sandcastle.addToolbarButton(
160+
"Toggle Pointcloud",
161+
() => (pointcloud.show = !pointcloud.show),
162+
"layers",
163+
);
164+
165+
Sandcastle.addToolbarButton("Birdseye View", () => {
166+
viewer.scene.camera.flyTo(birdsEyeView);
167+
});
168+
Sandcastle.addToolbarButton("Zoom to Pointcloud", () => {
169+
pointcloud.show = true;
170+
viewer.zoomTo(pointcloud);
171+
});
172+
//Sandcastle_End
173+
Sandcastle.finishedLoading();
174+
};
175+
if (typeof Cesium !== "undefined") {
176+
window.startupCalled = true;
177+
window.startup(Cesium).catch((error) => {
178+
"use strict";
179+
console.error(error);
180+
});
181+
}
182+
</script>
183+
</body>
184+
</html>
Loading

CHANGES.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
# Change Log
22

3+
### 1.125 - 2025-01-02
4+
5+
##### Fixes :wrench:
6+
7+
- Fixed JulianDate to always generate valid ISO strings for fractional milliseconds [#12345](https://github.com/CesiumGS/cesium/pull/12345)
8+
39
### 1.124 - 2024-12-02
410

511
#### @cesium/engine
612

713
##### Additions :tada:
814

915
- Added an integration with the [iTwin Platform](https://developer.bentley.com/) to load iModels as 3D Tiles. Use `ITwinPlatform.defaultAccessToken` to set the access token. Use `ITwinData.createTilesetFromIModelId(iModelId)` to load the iModel as a `Cesium3DTileset`. [#12289](https://github.com/CesiumGS/cesium/pull/12289)
16+
- Added an integration with the [iTwin Platform](https://developer.bentley.com/) to load Reality Data terrain meshes and GeoJSON. Use `ITwinPlatform.defaultAccessToken` to set the access token. Then use `ITwinData.createTilesetForRealityDataId(iTwinId, dataId)` to load terrain meshes as a `Cesium3DTileset` or `ITwinData.createDataSourceForRealityDataId(iTwinId, dataId)` to load GeoJSON or KML files as data sources. [#12344](https://github.com/CesiumGS/cesium/pull/12344)
1017
- Added `getSample` to `SampledProperty` to get the time of samples. [#12253](https://github.com/CesiumGS/cesium/pull/12253)
1118
- Added `Entity.trackingReferenceFrame` property to allow tracking entities in various reference frames. [#12194](https://github.com/CesiumGS/cesium/pull/12194), [#12314](https://github.com/CesiumGS/cesium/pull/12314)
1219
- `TrackingReferenceFrame.AUTODETECT` (default): uses either VVLH or ENU depending on entity's dynamic. Use `TrackingReferenceFrame.ENU` if your camera orientation flips abruptly from time to time.

gulpfile.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,12 +1198,19 @@ function generateTypeScriptDefinitions(
11981198
.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, "$1$2enum $3 {$4")
11991199
// Replace JSDoc generation version of defined with an improved version using TS type predicates
12001200
.replace(
1201-
/defined\(value: any\): boolean/gm,
1202-
"defined<Type>(value: Type): value is NonNullable<Type>",
1201+
/\n?export function defined\(value: any\): boolean;/gm,
1202+
`\n${readFileSync("./packages/engine/Source/Core/defined.d.ts")
1203+
.toString()
1204+
.replace(/\n*\/\*.*?\*\/\n*/gms, "")
1205+
.replace("export default", "export")}`,
12031206
)
1207+
// Replace JSDoc generation version of Check with one that asserts the type of variables after called
12041208
.replace(
12051209
/\/\*\*[\*\s\w]*?\*\/\nexport const Check: any;/m,
1206-
`\n${readFileSync("./packages/engine/Source/Core/Check.d.ts").toString()}`,
1210+
`\n${readFileSync("./packages/engine/Source/Core/Check.d.ts")
1211+
.toString()
1212+
.replace(/export default.*\n?/, "")
1213+
.replace("const Check", "export const Check")}`,
12071214
)
12081215
// Fix https://github.com/CesiumGS/cesium/issues/10498 so we can use the rest parameter expand tuple
12091216
.replace(
@@ -1405,12 +1412,19 @@ function createTypeScriptDefinitions() {
14051412
.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, "$1$2enum $3 {$4")
14061413
// Replace JSDoc generation version of defined with an improved version using TS type predicates
14071414
.replace(
1408-
/defined\(value: any\): boolean/gm,
1409-
"defined<Type>(value: Type): value is NonNullable<Type>",
1415+
/\n?export function defined\(value: any\): boolean;/gm,
1416+
`\n${readFileSync("./packages/engine/Source/Core/defined.d.ts")
1417+
.toString()
1418+
.replace(/\n*\/\*.*?\*\/\n*/gms, "")
1419+
.replace("export default", "export")}`,
14101420
)
1421+
// Replace JSDoc generation version of Check with one that asserts the type of variables after called
14111422
.replace(
14121423
/\/\*\*[\*\s\w]*?\*\/\nexport const Check: any;/m,
1413-
`\n${readFileSync("./packages/engine/Source/Core/Check.d.ts").toString()}`,
1424+
`\n${readFileSync("./packages/engine/Source/Core/Check.d.ts")
1425+
.toString()
1426+
.replace(/export default.*\n?/, "")
1427+
.replace("const Check", "export const Check")}`,
14141428
)
14151429
// Fix https://github.com/CesiumGS/cesium/issues/10498 to have rest parameter expand tuple
14161430
.replace(

packages/engine/Source/Core/Check.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Contains functions for checking that supplied arguments are of a specified type
33
* or meet specified conditions
44
*/
5-
export const Check: {
5+
const Check: {
66
/**
77
* Throws if test is not defined
88
*
@@ -125,3 +125,4 @@ export const Check: {
125125
};
126126
};
127127
};
128+
export default Check;

packages/engine/Source/Core/ITwinPlatform.js

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -38,54 +38,19 @@ ITwinPlatform.ExportType = Object.freeze({
3838
});
3939

4040
/**
41-
* Types of Reality data
41+
* Types of Reality data. This is a partial list of types we know we can support
42+
*
4243
* @see https://developer.bentley.com/apis/reality-management/rm-rd-details/#types
4344
* @enum {string}
4445
*/
4546
ITwinPlatform.RealityDataType = Object.freeze({
4647
Cesium3DTiles: "Cesium3DTiles",
4748
PNTS: "PNTS",
48-
OPC: "OPC",
4949
RealityMesh3DTiles: "RealityMesh3DTiles",
5050
Terrain3DTiles: "Terrain3DTiles",
51-
"3MX": "3MX",
52-
"3SM": "3SM",
53-
CCCloudProject: "CCCloudProject",
54-
CCImageCollection: "CCImageCollection",
55-
CCOrientations: "CCOrientations",
56-
ContextCaptureInputs: "ContextCaptureInputs",
57-
ContextDetector: "ContextDetector",
58-
ContextScene: "ContextScene",
59-
DAE: "DAE",
60-
DGN: "DGN",
61-
DSM: "DSM",
62-
FBX: "FBX",
63-
GLB: "GLB",
64-
GLTF: "GLTF",
6551
KML: "KML",
66-
LAS: "LAS",
67-
LAZ: "LAZ",
68-
LOD: "LOD",
69-
LodTree: "LodTree",
70-
OBJ: "OBJ",
71-
OMI: "OMI",
72-
OMR: "OMR",
73-
Orthophoto: "Orthophoto",
74-
OrthophotoDSM: "OrthophotoDSM",
75-
OSGB: "OSGB",
76-
OVF: "OVF",
77-
OBT: "OBT",
78-
PLY: "PLY",
79-
PointCloud: "PointCloud",
80-
S3C: "S3C",
81-
ScanCollection: "ScanCollection",
82-
SHP: "SHP",
83-
SLPK: "SLPK",
84-
SpaceEyes3D: "SpaceEyes3D",
85-
STL: "STL",
86-
TSM: "TSM",
52+
GeoJSON: "GeoJSON",
8753
Unstructured: "Unstructured",
88-
Other: "Other",
8954
});
9055

9156
/**

packages/engine/Source/Core/JulianDate.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import TimeStandard from "./TimeStandard.js";
1010

1111
const gregorianDateScratch = new GregorianDate();
1212
const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
13-
const daysInLeapFeburary = 29;
13+
const daysInLeapFebruary = 29;
1414

1515
function compareLeapSecondDates(leapSecond, dateToFind) {
1616
return JulianDate.compare(leapSecond.julianDate, dateToFind.julianDate);
@@ -430,7 +430,7 @@ JulianDate.fromIso8601 = function (iso8601String, result) {
430430
month > 12 ||
431431
day < 1 ||
432432
((month !== 2 || !inLeapYear) && day > daysInMonth[month - 1]) ||
433-
(inLeapYear && month === 2 && day > daysInLeapFeburary)
433+
(inLeapYear && month === 2 && day > daysInLeapFebruary)
434434
) {
435435
throw new DeveloperError(iso8601ErrorMessage);
436436
}
@@ -542,7 +542,7 @@ JulianDate.fromIso8601 = function (iso8601String, result) {
542542
day++;
543543
}
544544

545-
tmp = inLeapYear && month === 2 ? daysInLeapFeburary : daysInMonth[month - 1];
545+
tmp = inLeapYear && month === 2 ? daysInLeapFebruary : daysInMonth[month - 1];
546546
while (day > tmp) {
547547
day -= tmp;
548548
month++;
@@ -553,7 +553,7 @@ JulianDate.fromIso8601 = function (iso8601String, result) {
553553
}
554554

555555
tmp =
556-
inLeapYear && month === 2 ? daysInLeapFeburary : daysInMonth[month - 1];
556+
inLeapYear && month === 2 ? daysInLeapFebruary : daysInMonth[month - 1];
557557
}
558558

559559
//If UTC offset is at the beginning/end of the day, minutes can be negative.
@@ -575,7 +575,7 @@ JulianDate.fromIso8601 = function (iso8601String, result) {
575575
}
576576

577577
tmp =
578-
inLeapYear && month === 2 ? daysInLeapFeburary : daysInMonth[month - 1];
578+
inLeapYear && month === 2 ? daysInLeapFebruary : daysInMonth[month - 1];
579579
day += tmp;
580580
}
581581

@@ -784,8 +784,15 @@ JulianDate.toIso8601 = function (julianDate, precision) {
784784
let millisecondStr;
785785

786786
if (!defined(precision) && millisecond !== 0) {
787-
//Forces milliseconds into a number with at least 3 digits to whatever the default toString() precision is.
788-
millisecondStr = (millisecond * 0.01).toString().replace(".", "");
787+
// Forces milliseconds into a number with at least 3 digits.
788+
const millisecondHundreds = millisecond * 0.01;
789+
// Below 1e-6, toString returns scientific notation, so it should be replaced by toFixed with appropriate number of digits.
790+
// 20 digits is a trade-off choice guided by JavaScript's Number representation accuracy (15-17 decimal digits for most numbers).
791+
// Using toFixed(20) ensures capturing enough precision while avoiding inaccuracies due to floating-point limitations.
792+
millisecondStr =
793+
millisecondHundreds < 1e-6
794+
? millisecondHundreds.toFixed(20).replace(".", "").replace(/0+$/, "")
795+
: millisecondHundreds.toString().replace(".", "");
789796
return `${year.toString().padStart(4, "0")}-${month
790797
.toString()
791798
.padStart(2, "0")}-${day.toString().padStart(2, "0")}T${hour

0 commit comments

Comments
 (0)