cesiumjs-anywidget 0.5.0__tar.gz → 0.6.0__tar.gz
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.
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/PKG-INFO +1 -1
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/pyproject.toml +1 -1
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/src/cesiumjs_anywidget/index.js +163 -124
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/src/cesiumjs_anywidget/widget.py +64 -0
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/uv.lock +1 -1
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/.gitignore +0 -0
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/DEVELOPMENT.md +0 -0
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/LICENSE +0 -0
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/Makefile +0 -0
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/README.md +0 -0
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/TROUBLESHOOTING.md +0 -0
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/build.js +0 -0
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/fix_tests.py +0 -0
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/package.json +0 -0
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/src/cesiumjs_anywidget/__init__.py +0 -0
- {cesiumjs_anywidget-0.5.0 → cesiumjs_anywidget-0.6.0}/src/cesiumjs_anywidget/styles.css +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cesiumjs-anywidget
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: A Jupyter widget for CesiumJS 3D globe visualization using anywidget
|
|
5
5
|
Project-URL: Homepage, https://github.com/Alex-PLACET/cesiumjs_anywidget
|
|
6
6
|
Project-URL: Repository, https://github.com/Alex-PLACET/cesiumjs_anywidget
|
|
@@ -1,28 +1,49 @@
|
|
|
1
1
|
// Generated bundle - DO NOT EDIT DIRECTLY. Edit files in src/cesiumjs_anywidget/js/ instead.
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
// src/cesiumjs_anywidget/js/logger.js
|
|
5
|
+
var debugEnabled = false;
|
|
6
|
+
function setDebugMode(enabled) {
|
|
7
|
+
debugEnabled = enabled;
|
|
8
|
+
if (enabled) {
|
|
9
|
+
console.log("[CesiumWidget] Debug mode enabled");
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function log(prefix, ...args) {
|
|
13
|
+
if (debugEnabled) {
|
|
14
|
+
console.log(`[CesiumWidget:${prefix}]`, ...args);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function warn(prefix, ...args) {
|
|
18
|
+
console.warn(`[CesiumWidget:${prefix}]`, ...args);
|
|
19
|
+
}
|
|
20
|
+
function error(prefix, ...args) {
|
|
21
|
+
console.error(`[CesiumWidget:${prefix}]`, ...args);
|
|
22
|
+
}
|
|
23
|
+
|
|
4
24
|
// src/cesiumjs_anywidget/js/viewer-init.js
|
|
25
|
+
var PREFIX = "ViewerInit";
|
|
5
26
|
async function loadCesiumJS() {
|
|
6
|
-
|
|
27
|
+
log(PREFIX, "Loading CesiumJS...");
|
|
7
28
|
if (window.Cesium) {
|
|
8
|
-
|
|
29
|
+
log(PREFIX, "CesiumJS already loaded, reusing existing instance");
|
|
9
30
|
return window.Cesium;
|
|
10
31
|
}
|
|
11
32
|
const script = document.createElement("script");
|
|
12
33
|
script.src = "https://cesium.com/downloads/cesiumjs/releases/1.135/Build/Cesium/Cesium.js";
|
|
13
|
-
|
|
34
|
+
log(PREFIX, "Loading CesiumJS from CDN...");
|
|
14
35
|
await new Promise((resolve, reject) => {
|
|
15
36
|
script.onload = () => {
|
|
16
|
-
|
|
37
|
+
log(PREFIX, "CesiumJS script loaded successfully");
|
|
17
38
|
resolve();
|
|
18
39
|
};
|
|
19
|
-
script.onerror = (
|
|
20
|
-
|
|
21
|
-
reject(
|
|
40
|
+
script.onerror = (err) => {
|
|
41
|
+
error(PREFIX, "Failed to load CesiumJS script:", err);
|
|
42
|
+
reject(err);
|
|
22
43
|
};
|
|
23
44
|
document.head.appendChild(script);
|
|
24
45
|
});
|
|
25
|
-
|
|
46
|
+
log(PREFIX, "CesiumJS initialized");
|
|
26
47
|
return window.Cesium;
|
|
27
48
|
}
|
|
28
49
|
function createLoadingIndicator(container, hasToken) {
|
|
@@ -44,7 +65,7 @@ function createLoadingIndicator(container, hasToken) {
|
|
|
44
65
|
return loadingDiv;
|
|
45
66
|
}
|
|
46
67
|
function createViewer(container, model, Cesium) {
|
|
47
|
-
|
|
68
|
+
log(PREFIX, "Creating viewer with options...");
|
|
48
69
|
const viewerOptions = {
|
|
49
70
|
timeline: model.get("show_timeline"),
|
|
50
71
|
animation: model.get("show_animation"),
|
|
@@ -58,28 +79,28 @@ function createViewer(container, model, Cesium) {
|
|
|
58
79
|
shadows: false,
|
|
59
80
|
shouldAnimate: false
|
|
60
81
|
};
|
|
61
|
-
|
|
82
|
+
log(PREFIX, "Viewer options:", viewerOptions);
|
|
62
83
|
if (model.get("enable_terrain")) {
|
|
63
84
|
viewerOptions.terrain = Cesium.Terrain.fromWorldTerrain();
|
|
64
|
-
|
|
85
|
+
log(PREFIX, "Terrain enabled");
|
|
65
86
|
}
|
|
66
87
|
const viewer = new Cesium.Viewer(container, viewerOptions);
|
|
67
88
|
viewer.scene.globe.enableLighting = model.get("enable_lighting");
|
|
68
|
-
|
|
89
|
+
log(PREFIX, "Viewer created, lighting:", model.get("enable_lighting"));
|
|
69
90
|
return viewer;
|
|
70
91
|
}
|
|
71
92
|
function setupViewerListeners(viewer, model, container, Cesium) {
|
|
72
|
-
|
|
93
|
+
log(PREFIX, "Setting up viewer listeners");
|
|
73
94
|
let isDestroyed = false;
|
|
74
95
|
let scrubTimeout = null;
|
|
75
96
|
model.on("change:enable_terrain", () => {
|
|
76
97
|
if (isDestroyed) {
|
|
77
|
-
|
|
98
|
+
log(PREFIX, "Skipping enable_terrain change - destroyed");
|
|
78
99
|
return;
|
|
79
100
|
}
|
|
80
101
|
if (!viewer)
|
|
81
102
|
return;
|
|
82
|
-
|
|
103
|
+
log(PREFIX, "Terrain setting changed:", model.get("enable_terrain"));
|
|
83
104
|
if (model.get("enable_terrain")) {
|
|
84
105
|
viewer.scene.setTerrain(Cesium.Terrain.fromWorldTerrain());
|
|
85
106
|
} else {
|
|
@@ -91,7 +112,7 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
91
112
|
return;
|
|
92
113
|
if (!viewer)
|
|
93
114
|
return;
|
|
94
|
-
|
|
115
|
+
log(PREFIX, "Lighting setting changed:", model.get("enable_lighting"));
|
|
95
116
|
viewer.scene.globe.enableLighting = model.get("enable_lighting");
|
|
96
117
|
});
|
|
97
118
|
model.on("change:height", () => {
|
|
@@ -99,7 +120,7 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
99
120
|
return;
|
|
100
121
|
if (!viewer)
|
|
101
122
|
return;
|
|
102
|
-
|
|
123
|
+
log(PREFIX, "Height changed:", model.get("height"));
|
|
103
124
|
container.style.height = model.get("height");
|
|
104
125
|
viewer.resize();
|
|
105
126
|
});
|
|
@@ -108,7 +129,7 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
108
129
|
return;
|
|
109
130
|
if (!viewer || !viewer.timeline)
|
|
110
131
|
return;
|
|
111
|
-
|
|
132
|
+
log(PREFIX, "Timeline visibility changed:", model.get("show_timeline"));
|
|
112
133
|
viewer.timeline.container.style.visibility = model.get("show_timeline") ? "visible" : "hidden";
|
|
113
134
|
});
|
|
114
135
|
model.on("change:show_animation", () => {
|
|
@@ -116,7 +137,7 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
116
137
|
return;
|
|
117
138
|
if (!viewer || !viewer.animation)
|
|
118
139
|
return;
|
|
119
|
-
|
|
140
|
+
log(PREFIX, "Animation visibility changed:", model.get("show_animation"));
|
|
120
141
|
viewer.animation.container.style.visibility = model.get("show_animation") ? "visible" : "hidden";
|
|
121
142
|
});
|
|
122
143
|
model.on("change:atmosphere_settings", () => {
|
|
@@ -127,7 +148,7 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
127
148
|
const settings = model.get("atmosphere_settings");
|
|
128
149
|
if (!settings || Object.keys(settings).length === 0)
|
|
129
150
|
return;
|
|
130
|
-
|
|
151
|
+
log(PREFIX, "Atmosphere settings changed:", settings);
|
|
131
152
|
const atmosphere = viewer.scene.atmosphere;
|
|
132
153
|
if (settings.brightnessShift !== void 0) {
|
|
133
154
|
atmosphere.brightnessShift = settings.brightnessShift;
|
|
@@ -173,7 +194,7 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
173
194
|
const settings = model.get("sky_atmosphere_settings");
|
|
174
195
|
if (!settings || Object.keys(settings).length === 0)
|
|
175
196
|
return;
|
|
176
|
-
|
|
197
|
+
log(PREFIX, "Sky atmosphere settings changed:", settings);
|
|
177
198
|
const skyAtmosphere = viewer.scene.skyAtmosphere;
|
|
178
199
|
if (settings.show !== void 0) {
|
|
179
200
|
skyAtmosphere.show = settings.show;
|
|
@@ -225,7 +246,7 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
225
246
|
const settings = model.get("skybox_settings");
|
|
226
247
|
if (!settings || Object.keys(settings).length === 0)
|
|
227
248
|
return;
|
|
228
|
-
|
|
249
|
+
log(PREFIX, "SkyBox settings changed:", settings);
|
|
229
250
|
const skyBox = viewer.scene.skyBox;
|
|
230
251
|
if (settings.show !== void 0) {
|
|
231
252
|
skyBox.show = settings.show;
|
|
@@ -251,7 +272,7 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
251
272
|
});
|
|
252
273
|
function getCameraState() {
|
|
253
274
|
if (!viewer || !viewer.camera || !viewer.camera.positionCartographic) {
|
|
254
|
-
|
|
275
|
+
warn(PREFIX, "Cannot get camera state - viewer or camera not available");
|
|
255
276
|
return null;
|
|
256
277
|
}
|
|
257
278
|
try {
|
|
@@ -264,8 +285,8 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
264
285
|
pitch: Cesium.Math.toDegrees(viewer.camera.pitch),
|
|
265
286
|
roll: Cesium.Math.toDegrees(viewer.camera.roll)
|
|
266
287
|
};
|
|
267
|
-
} catch (
|
|
268
|
-
|
|
288
|
+
} catch (error2) {
|
|
289
|
+
warn(PREFIX, "Error getting camera state:", error2);
|
|
269
290
|
return null;
|
|
270
291
|
}
|
|
271
292
|
}
|
|
@@ -278,23 +299,23 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
278
299
|
multiplier: viewer.clock.multiplier,
|
|
279
300
|
is_animating: viewer.clock.shouldAnimate
|
|
280
301
|
};
|
|
281
|
-
} catch (
|
|
282
|
-
|
|
302
|
+
} catch (error2) {
|
|
303
|
+
warn(PREFIX, "Error getting clock state:", error2);
|
|
283
304
|
return null;
|
|
284
305
|
}
|
|
285
306
|
}
|
|
286
307
|
function sendInteractionEvent(type, additionalData = {}) {
|
|
287
308
|
if (isDestroyed) {
|
|
288
|
-
|
|
309
|
+
log(PREFIX, "Skipping interaction event - destroyed:", type);
|
|
289
310
|
return;
|
|
290
311
|
}
|
|
291
312
|
if (!viewer) {
|
|
292
|
-
|
|
313
|
+
warn(PREFIX, "Cannot send interaction event - viewer not available");
|
|
293
314
|
return;
|
|
294
315
|
}
|
|
295
316
|
const cameraState = getCameraState();
|
|
296
317
|
if (!cameraState) {
|
|
297
|
-
|
|
318
|
+
warn(PREFIX, "Skipping interaction event - camera state not available");
|
|
298
319
|
return;
|
|
299
320
|
}
|
|
300
321
|
const event = {
|
|
@@ -304,7 +325,7 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
304
325
|
clock: getClockState(),
|
|
305
326
|
...additionalData
|
|
306
327
|
};
|
|
307
|
-
|
|
328
|
+
log(PREFIX, "Interaction event:", type, event);
|
|
308
329
|
model.set("interaction_event", event);
|
|
309
330
|
model.save_changes();
|
|
310
331
|
}
|
|
@@ -333,8 +354,8 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
333
354
|
};
|
|
334
355
|
}
|
|
335
356
|
}
|
|
336
|
-
} catch (
|
|
337
|
-
|
|
357
|
+
} catch (error2) {
|
|
358
|
+
warn(PREFIX, "Error picking position:", error2);
|
|
338
359
|
}
|
|
339
360
|
try {
|
|
340
361
|
const pickedObject = viewer.scene.pick(click.position);
|
|
@@ -360,8 +381,8 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
360
381
|
}
|
|
361
382
|
}
|
|
362
383
|
}
|
|
363
|
-
} catch (
|
|
364
|
-
|
|
384
|
+
} catch (error2) {
|
|
385
|
+
warn(PREFIX, "Error picking entity:", error2);
|
|
365
386
|
}
|
|
366
387
|
sendInteractionEvent("left_click", pickedData);
|
|
367
388
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
@@ -382,8 +403,8 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
382
403
|
};
|
|
383
404
|
}
|
|
384
405
|
}
|
|
385
|
-
} catch (
|
|
386
|
-
|
|
406
|
+
} catch (error2) {
|
|
407
|
+
warn(PREFIX, "Error picking position:", error2);
|
|
387
408
|
}
|
|
388
409
|
sendInteractionEvent("right_click", pickedData);
|
|
389
410
|
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
|
|
@@ -407,23 +428,23 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
407
428
|
}
|
|
408
429
|
});
|
|
409
430
|
}
|
|
410
|
-
|
|
431
|
+
log(PREFIX, "Viewer listeners setup complete");
|
|
411
432
|
}
|
|
412
433
|
function setupGeoJSONLoader(viewer, model, Cesium) {
|
|
413
|
-
|
|
434
|
+
log(PREFIX, "Setting up GeoJSON loader");
|
|
414
435
|
let geojsonDataSources = [];
|
|
415
436
|
let isDestroyed = false;
|
|
416
437
|
async function loadGeoJSONData(flyToData = true) {
|
|
417
438
|
if (isDestroyed) {
|
|
418
|
-
|
|
439
|
+
log(PREFIX, "Skipping geojson_data load - destroyed");
|
|
419
440
|
return;
|
|
420
441
|
}
|
|
421
442
|
if (!viewer || !viewer.dataSources) {
|
|
422
|
-
|
|
443
|
+
warn(PREFIX, "Cannot load GeoJSON - viewer or dataSources not available");
|
|
423
444
|
return;
|
|
424
445
|
}
|
|
425
446
|
const geojsonDataArray = model.get("geojson_data");
|
|
426
|
-
|
|
447
|
+
log(PREFIX, "Loading GeoJSON data, count:", geojsonDataArray?.length || 0);
|
|
427
448
|
geojsonDataSources.forEach((dataSource) => {
|
|
428
449
|
if (viewer && viewer.dataSources) {
|
|
429
450
|
viewer.dataSources.remove(dataSource);
|
|
@@ -433,7 +454,7 @@ function setupGeoJSONLoader(viewer, model, Cesium) {
|
|
|
433
454
|
if (geojsonDataArray && Array.isArray(geojsonDataArray)) {
|
|
434
455
|
for (const geojsonData of geojsonDataArray) {
|
|
435
456
|
try {
|
|
436
|
-
|
|
457
|
+
log(PREFIX, "Loading GeoJSON dataset...");
|
|
437
458
|
const dataSource = await Cesium.GeoJsonDataSource.load(geojsonData, {
|
|
438
459
|
stroke: Cesium.Color.HOTPINK,
|
|
439
460
|
fill: Cesium.Color.PINK.withAlpha(0.5),
|
|
@@ -442,14 +463,14 @@ function setupGeoJSONLoader(viewer, model, Cesium) {
|
|
|
442
463
|
if (viewer && viewer.dataSources) {
|
|
443
464
|
viewer.dataSources.add(dataSource);
|
|
444
465
|
geojsonDataSources.push(dataSource);
|
|
445
|
-
|
|
466
|
+
log(PREFIX, "GeoJSON dataset loaded successfully");
|
|
446
467
|
}
|
|
447
|
-
} catch (
|
|
448
|
-
|
|
468
|
+
} catch (error2) {
|
|
469
|
+
error2(PREFIX, "Error loading GeoJSON:", error2);
|
|
449
470
|
}
|
|
450
471
|
}
|
|
451
472
|
if (flyToData && geojsonDataSources.length > 0 && viewer && viewer.flyTo) {
|
|
452
|
-
|
|
473
|
+
log(PREFIX, "Flying to GeoJSON data");
|
|
453
474
|
viewer.flyTo(geojsonDataSources[0]);
|
|
454
475
|
}
|
|
455
476
|
}
|
|
@@ -457,12 +478,12 @@ function setupGeoJSONLoader(viewer, model, Cesium) {
|
|
|
457
478
|
model.on("change:geojson_data", () => loadGeoJSONData(true));
|
|
458
479
|
const initialData = model.get("geojson_data");
|
|
459
480
|
if (initialData && Array.isArray(initialData) && initialData.length > 0) {
|
|
460
|
-
|
|
481
|
+
log(PREFIX, "Loading initial GeoJSON data...");
|
|
461
482
|
loadGeoJSONData(true);
|
|
462
483
|
}
|
|
463
484
|
return {
|
|
464
485
|
destroy: () => {
|
|
465
|
-
|
|
486
|
+
log(PREFIX, "Destroying GeoJSON loader");
|
|
466
487
|
isDestroyed = true;
|
|
467
488
|
geojsonDataSources.forEach((dataSource) => {
|
|
468
489
|
if (viewer) {
|
|
@@ -474,20 +495,20 @@ function setupGeoJSONLoader(viewer, model, Cesium) {
|
|
|
474
495
|
};
|
|
475
496
|
}
|
|
476
497
|
function setupCZMLLoader(viewer, model, Cesium) {
|
|
477
|
-
|
|
498
|
+
log(PREFIX, "Setting up CZML loader");
|
|
478
499
|
let czmlDataSources = [];
|
|
479
500
|
let isDestroyed = false;
|
|
480
501
|
async function loadCZMLData(flyToData = true) {
|
|
481
502
|
if (isDestroyed) {
|
|
482
|
-
|
|
503
|
+
log(PREFIX, "Skipping czml_data load - destroyed");
|
|
483
504
|
return;
|
|
484
505
|
}
|
|
485
506
|
if (!viewer || !viewer.dataSources) {
|
|
486
|
-
|
|
507
|
+
warn(PREFIX, "Cannot load CZML - viewer or dataSources not available");
|
|
487
508
|
return;
|
|
488
509
|
}
|
|
489
510
|
const czmlDataArray = model.get("czml_data");
|
|
490
|
-
|
|
511
|
+
log(PREFIX, "Loading CZML data, count:", czmlDataArray?.length || 0);
|
|
491
512
|
czmlDataSources.forEach((dataSource) => {
|
|
492
513
|
if (viewer && viewer.dataSources) {
|
|
493
514
|
viewer.dataSources.remove(dataSource);
|
|
@@ -498,22 +519,22 @@ function setupCZMLLoader(viewer, model, Cesium) {
|
|
|
498
519
|
for (const czmlData of czmlDataArray) {
|
|
499
520
|
if (Array.isArray(czmlData) && czmlData.length > 0) {
|
|
500
521
|
try {
|
|
501
|
-
|
|
522
|
+
log(PREFIX, "Loading CZML document with", czmlData.length, "packets...");
|
|
502
523
|
const dataSource = await Cesium.CzmlDataSource.load(czmlData);
|
|
503
524
|
if (viewer && viewer.dataSources) {
|
|
504
525
|
viewer.dataSources.add(dataSource);
|
|
505
526
|
czmlDataSources.push(dataSource);
|
|
506
|
-
|
|
527
|
+
log(PREFIX, "CZML document loaded successfully, entities:", dataSource.entities.values.length);
|
|
507
528
|
}
|
|
508
|
-
} catch (
|
|
509
|
-
|
|
529
|
+
} catch (error2) {
|
|
530
|
+
error2(PREFIX, "Error loading CZML:", error2);
|
|
510
531
|
}
|
|
511
532
|
} else {
|
|
512
|
-
|
|
533
|
+
warn(PREFIX, "Skipping invalid CZML data (not an array or empty):", czmlData);
|
|
513
534
|
}
|
|
514
535
|
}
|
|
515
536
|
if (flyToData && czmlDataSources.length > 0 && viewer && viewer.flyTo) {
|
|
516
|
-
|
|
537
|
+
log(PREFIX, "Flying to CZML data");
|
|
517
538
|
viewer.flyTo(czmlDataSources[0]);
|
|
518
539
|
}
|
|
519
540
|
}
|
|
@@ -521,12 +542,12 @@ function setupCZMLLoader(viewer, model, Cesium) {
|
|
|
521
542
|
model.on("change:czml_data", () => loadCZMLData(true));
|
|
522
543
|
const initialData = model.get("czml_data");
|
|
523
544
|
if (initialData && Array.isArray(initialData) && initialData.length > 0) {
|
|
524
|
-
|
|
545
|
+
log(PREFIX, "Loading initial CZML data...");
|
|
525
546
|
loadCZMLData(true);
|
|
526
547
|
}
|
|
527
548
|
return {
|
|
528
549
|
destroy: () => {
|
|
529
|
-
|
|
550
|
+
log(PREFIX, "Destroying CZML loader");
|
|
530
551
|
isDestroyed = true;
|
|
531
552
|
czmlDataSources.forEach((dataSource) => {
|
|
532
553
|
if (viewer) {
|
|
@@ -539,18 +560,24 @@ function setupCZMLLoader(viewer, model, Cesium) {
|
|
|
539
560
|
}
|
|
540
561
|
|
|
541
562
|
// src/cesiumjs_anywidget/js/camera-sync.js
|
|
563
|
+
var PREFIX2 = "CameraSync";
|
|
542
564
|
function initializeCameraSync(viewer, model) {
|
|
543
565
|
const Cesium = window.Cesium;
|
|
544
566
|
let cameraUpdateTimeout = null;
|
|
545
567
|
let isDestroyed = false;
|
|
546
|
-
|
|
568
|
+
let syncEnabled = model.get("camera_sync_enabled") || false;
|
|
569
|
+
log(PREFIX2, "Initializing camera synchronization, sync enabled:", syncEnabled);
|
|
570
|
+
model.on("change:camera_sync_enabled", () => {
|
|
571
|
+
syncEnabled = model.get("camera_sync_enabled");
|
|
572
|
+
log(PREFIX2, "Camera sync enabled changed:", syncEnabled);
|
|
573
|
+
});
|
|
547
574
|
function updateCameraFromModel() {
|
|
548
575
|
if (isDestroyed) {
|
|
549
|
-
|
|
576
|
+
log(PREFIX2, "Skipping updateCameraFromModel - module destroyed");
|
|
550
577
|
return;
|
|
551
578
|
}
|
|
552
579
|
if (!viewer) {
|
|
553
|
-
|
|
580
|
+
warn(PREFIX2, "updateCameraFromModel called but viewer is null");
|
|
554
581
|
return;
|
|
555
582
|
}
|
|
556
583
|
const lat = model.get("latitude");
|
|
@@ -559,7 +586,7 @@ function initializeCameraSync(viewer, model) {
|
|
|
559
586
|
const heading = Cesium.Math.toRadians(model.get("heading"));
|
|
560
587
|
const pitch = Cesium.Math.toRadians(model.get("pitch"));
|
|
561
588
|
const roll = Cesium.Math.toRadians(model.get("roll"));
|
|
562
|
-
|
|
589
|
+
log(PREFIX2, "Updating camera from model:", { lat, lon, alt });
|
|
563
590
|
viewer.camera.setView({
|
|
564
591
|
destination: Cesium.Cartesian3.fromDegrees(lon, lat, alt),
|
|
565
592
|
orientation: { heading, pitch, roll }
|
|
@@ -567,18 +594,22 @@ function initializeCameraSync(viewer, model) {
|
|
|
567
594
|
}
|
|
568
595
|
function updateModelFromCamera() {
|
|
569
596
|
if (isDestroyed) {
|
|
570
|
-
|
|
597
|
+
log(PREFIX2, "Skipping updateModelFromCamera - module destroyed");
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
if (!syncEnabled) {
|
|
601
|
+
log(PREFIX2, "Skipping updateModelFromCamera - sync disabled");
|
|
571
602
|
return;
|
|
572
603
|
}
|
|
573
604
|
if (!viewer) {
|
|
574
|
-
|
|
605
|
+
warn(PREFIX2, "updateModelFromCamera called but viewer is null");
|
|
575
606
|
return;
|
|
576
607
|
}
|
|
577
608
|
const position = viewer.camera.positionCartographic;
|
|
578
609
|
const heading = viewer.camera.heading;
|
|
579
610
|
const pitch = viewer.camera.pitch;
|
|
580
611
|
const roll = viewer.camera.roll;
|
|
581
|
-
|
|
612
|
+
log(PREFIX2, "Updating model from camera:", {
|
|
582
613
|
lat: Cesium.Math.toDegrees(position.latitude),
|
|
583
614
|
lon: Cesium.Math.toDegrees(position.longitude),
|
|
584
615
|
alt: position.height
|
|
@@ -593,14 +624,17 @@ function initializeCameraSync(viewer, model) {
|
|
|
593
624
|
}
|
|
594
625
|
function handleCameraChanged() {
|
|
595
626
|
if (isDestroyed) {
|
|
596
|
-
|
|
627
|
+
log(PREFIX2, "Skipping handleCameraChanged - module destroyed");
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
if (!syncEnabled) {
|
|
597
631
|
return;
|
|
598
632
|
}
|
|
599
633
|
if (cameraUpdateTimeout) {
|
|
600
634
|
clearTimeout(cameraUpdateTimeout);
|
|
601
635
|
}
|
|
602
636
|
cameraUpdateTimeout = setTimeout(() => {
|
|
603
|
-
if (!isDestroyed) {
|
|
637
|
+
if (!isDestroyed && syncEnabled) {
|
|
604
638
|
updateModelFromCamera();
|
|
605
639
|
}
|
|
606
640
|
}, 500);
|
|
@@ -615,14 +649,14 @@ function initializeCameraSync(viewer, model) {
|
|
|
615
649
|
model.on("change:roll", updateCameraFromModel);
|
|
616
650
|
model.on("change:camera_command", () => {
|
|
617
651
|
if (isDestroyed) {
|
|
618
|
-
|
|
652
|
+
log(PREFIX2, "Skipping camera_command - module destroyed");
|
|
619
653
|
return;
|
|
620
654
|
}
|
|
621
655
|
const command = model.get("camera_command");
|
|
622
656
|
if (!command || !command.command || !command.timestamp)
|
|
623
657
|
return;
|
|
624
658
|
const cmd = command.command;
|
|
625
|
-
|
|
659
|
+
log(PREFIX2, "Executing camera command:", cmd, command);
|
|
626
660
|
try {
|
|
627
661
|
switch (cmd) {
|
|
628
662
|
case "flyTo":
|
|
@@ -705,31 +739,32 @@ function initializeCameraSync(viewer, model) {
|
|
|
705
739
|
viewer.camera.zoomOut(command.distance || 100);
|
|
706
740
|
break;
|
|
707
741
|
default:
|
|
708
|
-
|
|
742
|
+
warn(PREFIX2, `Unknown camera command: ${cmd}`);
|
|
709
743
|
}
|
|
710
|
-
} catch (
|
|
711
|
-
|
|
744
|
+
} catch (err) {
|
|
745
|
+
error(PREFIX2, `Error executing camera command ${cmd}:`, err);
|
|
712
746
|
}
|
|
713
747
|
});
|
|
714
748
|
return {
|
|
715
749
|
updateCameraFromModel,
|
|
716
750
|
updateModelFromCamera,
|
|
717
751
|
destroy: () => {
|
|
718
|
-
|
|
752
|
+
log(PREFIX2, "Destroying camera sync module");
|
|
719
753
|
isDestroyed = true;
|
|
720
754
|
if (cameraUpdateTimeout) {
|
|
721
755
|
clearTimeout(cameraUpdateTimeout);
|
|
722
756
|
cameraUpdateTimeout = null;
|
|
723
757
|
}
|
|
724
758
|
viewer.camera.changed.removeEventListener(handleCameraChanged);
|
|
725
|
-
|
|
759
|
+
log(PREFIX2, "Camera sync module destroyed");
|
|
726
760
|
}
|
|
727
761
|
};
|
|
728
762
|
}
|
|
729
763
|
|
|
730
764
|
// src/cesiumjs_anywidget/js/measurement-tools.js
|
|
765
|
+
var PREFIX3 = "Measurements";
|
|
731
766
|
function initializeMeasurementTools(viewer, model, container) {
|
|
732
|
-
|
|
767
|
+
log(PREFIX3, "Initializing measurement tools");
|
|
733
768
|
const Cesium = window.Cesium;
|
|
734
769
|
let measurementHandler = null;
|
|
735
770
|
let editHandler = null;
|
|
@@ -955,7 +990,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
955
990
|
};
|
|
956
991
|
}
|
|
957
992
|
function clearAllMeasurements() {
|
|
958
|
-
|
|
993
|
+
log(PREFIX3, "Clearing all measurements");
|
|
959
994
|
measurementState.entities.forEach((e) => viewer.entities.remove(e));
|
|
960
995
|
measurementState.labels.forEach((l) => viewer.entities.remove(l));
|
|
961
996
|
measurementState.polylines.forEach((p) => viewer.entities.remove(p));
|
|
@@ -1120,12 +1155,12 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1120
1155
|
const editLatInput = document.getElementById("edit-lat");
|
|
1121
1156
|
const editAltInput = document.getElementById("edit-alt");
|
|
1122
1157
|
if (!applyBtn || !closeBtn || !editLonInput || !editLatInput || !editAltInput) {
|
|
1123
|
-
|
|
1158
|
+
warn(PREFIX3, "Editor panel input elements not found in DOM");
|
|
1124
1159
|
}
|
|
1125
1160
|
if (applyBtn) {
|
|
1126
1161
|
applyBtn.onclick = () => {
|
|
1127
1162
|
if (!editLonInput || !editLatInput || !editAltInput) {
|
|
1128
|
-
|
|
1163
|
+
warn(PREFIX3, "Editor input fields not available");
|
|
1129
1164
|
return;
|
|
1130
1165
|
}
|
|
1131
1166
|
const lon = parseFloat(editLonInput.value);
|
|
@@ -1302,10 +1337,10 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1302
1337
|
}
|
|
1303
1338
|
function updateMeasurementsList() {
|
|
1304
1339
|
const results = model.get("measurement_results") || [];
|
|
1305
|
-
|
|
1340
|
+
log(PREFIX3, "Updating measurements list, count:", results.length);
|
|
1306
1341
|
const listContent = document.getElementById("measurements-list-content");
|
|
1307
1342
|
if (!listContent) {
|
|
1308
|
-
|
|
1343
|
+
warn(PREFIX3, "Measurements list content element not found in DOM");
|
|
1309
1344
|
return;
|
|
1310
1345
|
}
|
|
1311
1346
|
if (results.length === 0) {
|
|
@@ -1365,7 +1400,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1365
1400
|
renameMeasurement(index, name);
|
|
1366
1401
|
};
|
|
1367
1402
|
} else {
|
|
1368
|
-
|
|
1403
|
+
warn(PREFIX3, `Rename button not found for measurement ${index}`);
|
|
1369
1404
|
}
|
|
1370
1405
|
});
|
|
1371
1406
|
}
|
|
@@ -1668,7 +1703,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1668
1703
|
}
|
|
1669
1704
|
}
|
|
1670
1705
|
function enableMeasurementMode(mode) {
|
|
1671
|
-
|
|
1706
|
+
log(PREFIX3, "Enabling measurement mode:", mode);
|
|
1672
1707
|
if (measurementHandler) {
|
|
1673
1708
|
measurementHandler.destroy();
|
|
1674
1709
|
measurementHandler = null;
|
|
@@ -1858,20 +1893,20 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1858
1893
|
}
|
|
1859
1894
|
model.on("change:measurement_mode", () => {
|
|
1860
1895
|
if (isDestroyed) {
|
|
1861
|
-
|
|
1896
|
+
log(PREFIX3, "Skipping measurement_mode change - destroyed");
|
|
1862
1897
|
return;
|
|
1863
1898
|
}
|
|
1864
1899
|
const mode = model.get("measurement_mode");
|
|
1865
|
-
|
|
1900
|
+
log(PREFIX3, "Measurement mode changed:", mode);
|
|
1866
1901
|
enableMeasurementMode(mode);
|
|
1867
1902
|
});
|
|
1868
1903
|
model.on("change:measurement_results", () => {
|
|
1869
1904
|
if (isDestroyed) {
|
|
1870
|
-
|
|
1905
|
+
log(PREFIX3, "Skipping measurement_results change - destroyed");
|
|
1871
1906
|
return;
|
|
1872
1907
|
}
|
|
1873
1908
|
const results = model.get("measurement_results") || [];
|
|
1874
|
-
|
|
1909
|
+
log(PREFIX3, "Measurement results changed, count:", results.length);
|
|
1875
1910
|
if (results.length === 0) {
|
|
1876
1911
|
clearAllMeasurements();
|
|
1877
1912
|
}
|
|
@@ -1881,7 +1916,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1881
1916
|
if (isDestroyed)
|
|
1882
1917
|
return;
|
|
1883
1918
|
const triggerData = model.get("load_measurements_trigger");
|
|
1884
|
-
|
|
1919
|
+
log(PREFIX3, "Load measurements trigger:", triggerData);
|
|
1885
1920
|
if (triggerData && triggerData.measurements) {
|
|
1886
1921
|
loadAndDisplayMeasurements(triggerData.measurements);
|
|
1887
1922
|
updateMeasurementsList();
|
|
@@ -1891,7 +1926,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1891
1926
|
if (isDestroyed)
|
|
1892
1927
|
return;
|
|
1893
1928
|
const triggerData = model.get("focus_measurement_trigger");
|
|
1894
|
-
|
|
1929
|
+
log(PREFIX3, "Focus measurement trigger:", triggerData);
|
|
1895
1930
|
if (triggerData && typeof triggerData.index === "number") {
|
|
1896
1931
|
focusOnMeasurement(triggerData.index);
|
|
1897
1932
|
}
|
|
@@ -1900,7 +1935,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1900
1935
|
if (isDestroyed)
|
|
1901
1936
|
return;
|
|
1902
1937
|
const show = model.get("show_measurement_tools");
|
|
1903
|
-
|
|
1938
|
+
log(PREFIX3, "Show measurement tools:", show);
|
|
1904
1939
|
toolbarDiv.style.display = show ? "flex" : "none";
|
|
1905
1940
|
editorPanel.style.display = show ? editorPanel.style.display : "none";
|
|
1906
1941
|
if (!show && editState.enabled) {
|
|
@@ -1912,7 +1947,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1912
1947
|
if (isDestroyed)
|
|
1913
1948
|
return;
|
|
1914
1949
|
const show = model.get("show_measurements_list");
|
|
1915
|
-
|
|
1950
|
+
log(PREFIX3, "Show measurements list:", show);
|
|
1916
1951
|
measurementsListPanel.style.display = show ? "block" : "none";
|
|
1917
1952
|
});
|
|
1918
1953
|
toolbarDiv.style.display = model.get("show_measurement_tools") ? "flex" : "none";
|
|
@@ -1922,7 +1957,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1922
1957
|
enableMeasurementMode,
|
|
1923
1958
|
clearAllMeasurements,
|
|
1924
1959
|
destroy: () => {
|
|
1925
|
-
|
|
1960
|
+
log(PREFIX3, "Destroying measurement tools");
|
|
1926
1961
|
isDestroyed = true;
|
|
1927
1962
|
if (measurementHandler) {
|
|
1928
1963
|
measurementHandler.destroy();
|
|
@@ -1931,7 +1966,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1931
1966
|
if (toolbarDiv.parentNode) {
|
|
1932
1967
|
toolbarDiv.remove();
|
|
1933
1968
|
}
|
|
1934
|
-
|
|
1969
|
+
log(PREFIX3, "Measurement tools destroyed");
|
|
1935
1970
|
}
|
|
1936
1971
|
};
|
|
1937
1972
|
}
|
|
@@ -1939,22 +1974,26 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1939
1974
|
// src/cesiumjs_anywidget/js/index.js
|
|
1940
1975
|
window.CESIUM_BASE_URL = "https://cesium.com/downloads/cesiumjs/releases/1.135/Build/Cesium/";
|
|
1941
1976
|
async function render({ model, el }) {
|
|
1942
|
-
|
|
1943
|
-
|
|
1977
|
+
setDebugMode(model.get("debug_mode") || false);
|
|
1978
|
+
model.on("change:debug_mode", () => {
|
|
1979
|
+
setDebugMode(model.get("debug_mode"));
|
|
1980
|
+
});
|
|
1981
|
+
log("Main", "Starting render");
|
|
1982
|
+
log("Main", "Loading CesiumJS...");
|
|
1944
1983
|
const Cesium = await loadCesiumJS();
|
|
1945
|
-
|
|
1984
|
+
log("Main", "CesiumJS loaded successfully");
|
|
1946
1985
|
const container = document.createElement("div");
|
|
1947
1986
|
container.style.width = "100%";
|
|
1948
1987
|
container.style.height = model.get("height");
|
|
1949
1988
|
container.style.position = "relative";
|
|
1950
1989
|
el.appendChild(container);
|
|
1951
|
-
|
|
1990
|
+
log("Main", "Container created with height:", model.get("height"));
|
|
1952
1991
|
const ionToken = model.get("ion_access_token");
|
|
1953
1992
|
if (ionToken) {
|
|
1954
1993
|
Cesium.Ion.defaultAccessToken = ionToken;
|
|
1955
|
-
|
|
1994
|
+
log("Main", "Ion access token set");
|
|
1956
1995
|
} else {
|
|
1957
|
-
|
|
1996
|
+
warn("Main", "No Ion access token provided");
|
|
1958
1997
|
}
|
|
1959
1998
|
const loadingDiv = createLoadingIndicator(container, !!ionToken);
|
|
1960
1999
|
let viewer = null;
|
|
@@ -1964,57 +2003,57 @@ async function render({ model, el }) {
|
|
|
1964
2003
|
let czmlLoader = null;
|
|
1965
2004
|
(async () => {
|
|
1966
2005
|
try {
|
|
1967
|
-
|
|
2006
|
+
log("Main", "Creating Cesium Viewer...");
|
|
1968
2007
|
viewer = createViewer(container, model, Cesium);
|
|
1969
|
-
|
|
2008
|
+
log("Main", "Cesium Viewer created successfully");
|
|
1970
2009
|
if (loadingDiv.parentNode) {
|
|
1971
2010
|
loadingDiv.remove();
|
|
1972
2011
|
}
|
|
1973
|
-
|
|
2012
|
+
log("Main", "Initializing camera synchronization...");
|
|
1974
2013
|
cameraSync = initializeCameraSync(viewer, model);
|
|
1975
|
-
|
|
1976
|
-
|
|
2014
|
+
log("Main", "Camera synchronization initialized");
|
|
2015
|
+
log("Main", "Initializing measurement tools...");
|
|
1977
2016
|
measurementTools = initializeMeasurementTools(viewer, model, container);
|
|
1978
|
-
|
|
1979
|
-
|
|
2017
|
+
log("Main", "Measurement tools initialized");
|
|
2018
|
+
log("Main", "Setting up viewer listeners...");
|
|
1980
2019
|
setupViewerListeners(viewer, model, container, Cesium);
|
|
1981
|
-
|
|
1982
|
-
|
|
2020
|
+
log("Main", "Viewer listeners set up");
|
|
2021
|
+
log("Main", "Setting up GeoJSON loader...");
|
|
1983
2022
|
geoJsonLoader = setupGeoJSONLoader(viewer, model, Cesium);
|
|
1984
|
-
|
|
1985
|
-
|
|
2023
|
+
log("Main", "GeoJSON loader set up");
|
|
2024
|
+
log("Main", "Setting up CZML loader...");
|
|
1986
2025
|
czmlLoader = setupCZMLLoader(viewer, model, Cesium);
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
} catch (
|
|
1990
|
-
|
|
1991
|
-
loadingDiv.textContent = `Error: ${
|
|
2026
|
+
log("Main", "CZML loader set up");
|
|
2027
|
+
log("Main", "Initialization complete");
|
|
2028
|
+
} catch (err) {
|
|
2029
|
+
error("Main", "Error initializing CesiumJS viewer:", err);
|
|
2030
|
+
loadingDiv.textContent = `Error: ${err.message}`;
|
|
1992
2031
|
loadingDiv.style.background = "rgba(255,0,0,0.8)";
|
|
1993
2032
|
}
|
|
1994
2033
|
})();
|
|
1995
2034
|
return () => {
|
|
1996
|
-
|
|
2035
|
+
log("Main", "Starting cleanup...");
|
|
1997
2036
|
if (cameraSync) {
|
|
1998
|
-
|
|
2037
|
+
log("Main", "Destroying camera sync...");
|
|
1999
2038
|
cameraSync.destroy();
|
|
2000
2039
|
}
|
|
2001
2040
|
if (measurementTools) {
|
|
2002
|
-
|
|
2041
|
+
log("Main", "Destroying measurement tools...");
|
|
2003
2042
|
measurementTools.destroy();
|
|
2004
2043
|
}
|
|
2005
2044
|
if (geoJsonLoader) {
|
|
2006
|
-
|
|
2045
|
+
log("Main", "Destroying GeoJSON loader...");
|
|
2007
2046
|
geoJsonLoader.destroy();
|
|
2008
2047
|
}
|
|
2009
2048
|
if (czmlLoader) {
|
|
2010
|
-
|
|
2049
|
+
log("Main", "Destroying CZML loader...");
|
|
2011
2050
|
czmlLoader.destroy();
|
|
2012
2051
|
}
|
|
2013
2052
|
if (viewer) {
|
|
2014
|
-
|
|
2053
|
+
log("Main", "Destroying viewer...");
|
|
2015
2054
|
viewer.destroy();
|
|
2016
2055
|
}
|
|
2017
|
-
|
|
2056
|
+
log("Main", "Cleanup complete");
|
|
2018
2057
|
};
|
|
2019
2058
|
}
|
|
2020
2059
|
var js_default = { render };
|
|
@@ -130,6 +130,17 @@ class CesiumWidget(anywidget.AnyWidget):
|
|
|
130
130
|
default_value=True, help="Show or hide measurements list panel"
|
|
131
131
|
).tag(sync=True)
|
|
132
132
|
|
|
133
|
+
# Debug mode for JavaScript logging
|
|
134
|
+
debug_mode = traitlets.Bool(
|
|
135
|
+
default_value=False, help="Enable or disable JavaScript console logging"
|
|
136
|
+
).tag(sync=True)
|
|
137
|
+
|
|
138
|
+
# Camera synchronization callbacks
|
|
139
|
+
camera_sync_enabled = traitlets.Bool(
|
|
140
|
+
default_value=False,
|
|
141
|
+
help="Enable or disable camera position synchronization callbacks"
|
|
142
|
+
).tag(sync=True)
|
|
143
|
+
|
|
133
144
|
def __init__(self, **kwargs):
|
|
134
145
|
"""Initialize the CesiumWidget.
|
|
135
146
|
|
|
@@ -774,6 +785,59 @@ class CesiumWidget(anywidget.AnyWidget):
|
|
|
774
785
|
"""Hide the measurements list panel."""
|
|
775
786
|
self.show_measurements_list = False
|
|
776
787
|
|
|
788
|
+
def enable_debug(self):
|
|
789
|
+
"""Enable JavaScript console logging for debugging.
|
|
790
|
+
|
|
791
|
+
When enabled, detailed logs will be printed to the browser console
|
|
792
|
+
showing widget initialization, data loading, camera events, etc.
|
|
793
|
+
|
|
794
|
+
Examples
|
|
795
|
+
--------
|
|
796
|
+
>>> widget.enable_debug() # Enable logging
|
|
797
|
+
>>> # ... interact with widget, check browser console for logs
|
|
798
|
+
>>> widget.disable_debug() # Disable logging when done
|
|
799
|
+
"""
|
|
800
|
+
self.debug_mode = True
|
|
801
|
+
|
|
802
|
+
def disable_debug(self):
|
|
803
|
+
"""Disable JavaScript console logging.
|
|
804
|
+
|
|
805
|
+
Examples
|
|
806
|
+
--------
|
|
807
|
+
>>> widget.disable_debug()
|
|
808
|
+
"""
|
|
809
|
+
self.debug_mode = False
|
|
810
|
+
|
|
811
|
+
def enable_camera_sync(self):
|
|
812
|
+
"""Enable camera synchronization callbacks.
|
|
813
|
+
|
|
814
|
+
When enabled, camera position changes in the Cesium viewer will be
|
|
815
|
+
synchronized back to the Python model (latitude, longitude, altitude,
|
|
816
|
+
heading, pitch, roll properties).
|
|
817
|
+
|
|
818
|
+
Note: This is disabled by default to avoid unnecessary updates when
|
|
819
|
+
you don't need to track camera position in Python.
|
|
820
|
+
|
|
821
|
+
Examples
|
|
822
|
+
--------
|
|
823
|
+
>>> widget.enable_camera_sync()
|
|
824
|
+
>>> # Move camera in the viewer...
|
|
825
|
+
>>> print(widget.latitude, widget.longitude) # Updated values
|
|
826
|
+
"""
|
|
827
|
+
self.camera_sync_enabled = True
|
|
828
|
+
|
|
829
|
+
def disable_camera_sync(self):
|
|
830
|
+
"""Disable camera synchronization callbacks.
|
|
831
|
+
|
|
832
|
+
When disabled, camera movements in the viewer will not update the
|
|
833
|
+
Python model properties. This is the default state.
|
|
834
|
+
|
|
835
|
+
Examples
|
|
836
|
+
--------
|
|
837
|
+
>>> widget.disable_camera_sync()
|
|
838
|
+
"""
|
|
839
|
+
self.camera_sync_enabled = False
|
|
840
|
+
|
|
777
841
|
def set_atmosphere(self,
|
|
778
842
|
brightness_shift=None,
|
|
779
843
|
hue_shift=None,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|