cesiumjs-anywidget 0.4.0__py3-none-any.whl → 0.6.0__py3-none-any.whl
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/index.js +357 -85
- cesiumjs_anywidget/widget.py +64 -0
- {cesiumjs_anywidget-0.4.0.dist-info → cesiumjs_anywidget-0.6.0.dist-info}/METADATA +2 -2
- cesiumjs_anywidget-0.6.0.dist-info/RECORD +8 -0
- cesiumjs_anywidget-0.4.0.dist-info/RECORD +0 -8
- {cesiumjs_anywidget-0.4.0.dist-info → cesiumjs_anywidget-0.6.0.dist-info}/WHEEL +0 -0
- {cesiumjs_anywidget-0.4.0.dist-info → cesiumjs_anywidget-0.6.0.dist-info}/licenses/LICENSE +0 -0
cesiumjs_anywidget/index.js
CHANGED
|
@@ -1,18 +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() {
|
|
27
|
+
log(PREFIX, "Loading CesiumJS...");
|
|
6
28
|
if (window.Cesium) {
|
|
29
|
+
log(PREFIX, "CesiumJS already loaded, reusing existing instance");
|
|
7
30
|
return window.Cesium;
|
|
8
31
|
}
|
|
9
32
|
const script = document.createElement("script");
|
|
10
33
|
script.src = "https://cesium.com/downloads/cesiumjs/releases/1.135/Build/Cesium/Cesium.js";
|
|
34
|
+
log(PREFIX, "Loading CesiumJS from CDN...");
|
|
11
35
|
await new Promise((resolve, reject) => {
|
|
12
|
-
script.onload =
|
|
13
|
-
|
|
36
|
+
script.onload = () => {
|
|
37
|
+
log(PREFIX, "CesiumJS script loaded successfully");
|
|
38
|
+
resolve();
|
|
39
|
+
};
|
|
40
|
+
script.onerror = (err) => {
|
|
41
|
+
error(PREFIX, "Failed to load CesiumJS script:", err);
|
|
42
|
+
reject(err);
|
|
43
|
+
};
|
|
14
44
|
document.head.appendChild(script);
|
|
15
45
|
});
|
|
46
|
+
log(PREFIX, "CesiumJS initialized");
|
|
16
47
|
return window.Cesium;
|
|
17
48
|
}
|
|
18
49
|
function createLoadingIndicator(container, hasToken) {
|
|
@@ -34,6 +65,7 @@ function createLoadingIndicator(container, hasToken) {
|
|
|
34
65
|
return loadingDiv;
|
|
35
66
|
}
|
|
36
67
|
function createViewer(container, model, Cesium) {
|
|
68
|
+
log(PREFIX, "Creating viewer with options...");
|
|
37
69
|
const viewerOptions = {
|
|
38
70
|
timeline: model.get("show_timeline"),
|
|
39
71
|
animation: model.get("show_animation"),
|
|
@@ -47,17 +79,28 @@ function createViewer(container, model, Cesium) {
|
|
|
47
79
|
shadows: false,
|
|
48
80
|
shouldAnimate: false
|
|
49
81
|
};
|
|
82
|
+
log(PREFIX, "Viewer options:", viewerOptions);
|
|
50
83
|
if (model.get("enable_terrain")) {
|
|
51
84
|
viewerOptions.terrain = Cesium.Terrain.fromWorldTerrain();
|
|
85
|
+
log(PREFIX, "Terrain enabled");
|
|
52
86
|
}
|
|
53
87
|
const viewer = new Cesium.Viewer(container, viewerOptions);
|
|
54
88
|
viewer.scene.globe.enableLighting = model.get("enable_lighting");
|
|
89
|
+
log(PREFIX, "Viewer created, lighting:", model.get("enable_lighting"));
|
|
55
90
|
return viewer;
|
|
56
91
|
}
|
|
57
92
|
function setupViewerListeners(viewer, model, container, Cesium) {
|
|
93
|
+
log(PREFIX, "Setting up viewer listeners");
|
|
94
|
+
let isDestroyed = false;
|
|
95
|
+
let scrubTimeout = null;
|
|
58
96
|
model.on("change:enable_terrain", () => {
|
|
97
|
+
if (isDestroyed) {
|
|
98
|
+
log(PREFIX, "Skipping enable_terrain change - destroyed");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
59
101
|
if (!viewer)
|
|
60
102
|
return;
|
|
103
|
+
log(PREFIX, "Terrain setting changed:", model.get("enable_terrain"));
|
|
61
104
|
if (model.get("enable_terrain")) {
|
|
62
105
|
viewer.scene.setTerrain(Cesium.Terrain.fromWorldTerrain());
|
|
63
106
|
} else {
|
|
@@ -65,32 +108,47 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
65
108
|
}
|
|
66
109
|
});
|
|
67
110
|
model.on("change:enable_lighting", () => {
|
|
111
|
+
if (isDestroyed)
|
|
112
|
+
return;
|
|
68
113
|
if (!viewer)
|
|
69
114
|
return;
|
|
115
|
+
log(PREFIX, "Lighting setting changed:", model.get("enable_lighting"));
|
|
70
116
|
viewer.scene.globe.enableLighting = model.get("enable_lighting");
|
|
71
117
|
});
|
|
72
118
|
model.on("change:height", () => {
|
|
119
|
+
if (isDestroyed)
|
|
120
|
+
return;
|
|
73
121
|
if (!viewer)
|
|
74
122
|
return;
|
|
123
|
+
log(PREFIX, "Height changed:", model.get("height"));
|
|
75
124
|
container.style.height = model.get("height");
|
|
76
125
|
viewer.resize();
|
|
77
126
|
});
|
|
78
127
|
model.on("change:show_timeline", () => {
|
|
128
|
+
if (isDestroyed)
|
|
129
|
+
return;
|
|
79
130
|
if (!viewer || !viewer.timeline)
|
|
80
131
|
return;
|
|
132
|
+
log(PREFIX, "Timeline visibility changed:", model.get("show_timeline"));
|
|
81
133
|
viewer.timeline.container.style.visibility = model.get("show_timeline") ? "visible" : "hidden";
|
|
82
134
|
});
|
|
83
135
|
model.on("change:show_animation", () => {
|
|
136
|
+
if (isDestroyed)
|
|
137
|
+
return;
|
|
84
138
|
if (!viewer || !viewer.animation)
|
|
85
139
|
return;
|
|
140
|
+
log(PREFIX, "Animation visibility changed:", model.get("show_animation"));
|
|
86
141
|
viewer.animation.container.style.visibility = model.get("show_animation") ? "visible" : "hidden";
|
|
87
142
|
});
|
|
88
143
|
model.on("change:atmosphere_settings", () => {
|
|
144
|
+
if (isDestroyed)
|
|
145
|
+
return;
|
|
89
146
|
if (!viewer || !viewer.scene || !viewer.scene.atmosphere)
|
|
90
147
|
return;
|
|
91
148
|
const settings = model.get("atmosphere_settings");
|
|
92
149
|
if (!settings || Object.keys(settings).length === 0)
|
|
93
150
|
return;
|
|
151
|
+
log(PREFIX, "Atmosphere settings changed:", settings);
|
|
94
152
|
const atmosphere = viewer.scene.atmosphere;
|
|
95
153
|
if (settings.brightnessShift !== void 0) {
|
|
96
154
|
atmosphere.brightnessShift = settings.brightnessShift;
|
|
@@ -129,11 +187,14 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
129
187
|
}
|
|
130
188
|
});
|
|
131
189
|
model.on("change:sky_atmosphere_settings", () => {
|
|
190
|
+
if (isDestroyed)
|
|
191
|
+
return;
|
|
132
192
|
if (!viewer || !viewer.scene || !viewer.scene.skyAtmosphere)
|
|
133
193
|
return;
|
|
134
194
|
const settings = model.get("sky_atmosphere_settings");
|
|
135
195
|
if (!settings || Object.keys(settings).length === 0)
|
|
136
196
|
return;
|
|
197
|
+
log(PREFIX, "Sky atmosphere settings changed:", settings);
|
|
137
198
|
const skyAtmosphere = viewer.scene.skyAtmosphere;
|
|
138
199
|
if (settings.show !== void 0) {
|
|
139
200
|
skyAtmosphere.show = settings.show;
|
|
@@ -178,11 +239,14 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
178
239
|
}
|
|
179
240
|
});
|
|
180
241
|
model.on("change:skybox_settings", () => {
|
|
242
|
+
if (isDestroyed)
|
|
243
|
+
return;
|
|
181
244
|
if (!viewer || !viewer.scene || !viewer.scene.skyBox)
|
|
182
245
|
return;
|
|
183
246
|
const settings = model.get("skybox_settings");
|
|
184
247
|
if (!settings || Object.keys(settings).length === 0)
|
|
185
248
|
return;
|
|
249
|
+
log(PREFIX, "SkyBox settings changed:", settings);
|
|
186
250
|
const skyBox = viewer.scene.skyBox;
|
|
187
251
|
if (settings.show !== void 0) {
|
|
188
252
|
skyBox.show = settings.show;
|
|
@@ -207,104 +271,155 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
207
271
|
}
|
|
208
272
|
});
|
|
209
273
|
function getCameraState() {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
274
|
+
if (!viewer || !viewer.camera || !viewer.camera.positionCartographic) {
|
|
275
|
+
warn(PREFIX, "Cannot get camera state - viewer or camera not available");
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
try {
|
|
279
|
+
const cartographic = viewer.camera.positionCartographic;
|
|
280
|
+
return {
|
|
281
|
+
latitude: Cesium.Math.toDegrees(cartographic.latitude),
|
|
282
|
+
longitude: Cesium.Math.toDegrees(cartographic.longitude),
|
|
283
|
+
altitude: cartographic.height,
|
|
284
|
+
heading: Cesium.Math.toDegrees(viewer.camera.heading),
|
|
285
|
+
pitch: Cesium.Math.toDegrees(viewer.camera.pitch),
|
|
286
|
+
roll: Cesium.Math.toDegrees(viewer.camera.roll)
|
|
287
|
+
};
|
|
288
|
+
} catch (error2) {
|
|
289
|
+
warn(PREFIX, "Error getting camera state:", error2);
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
219
292
|
}
|
|
220
293
|
function getClockState() {
|
|
221
|
-
if (!viewer.clock)
|
|
294
|
+
if (!viewer || !viewer.clock)
|
|
222
295
|
return null;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
296
|
+
try {
|
|
297
|
+
return {
|
|
298
|
+
current_time: Cesium.JulianDate.toIso8601(viewer.clock.currentTime),
|
|
299
|
+
multiplier: viewer.clock.multiplier,
|
|
300
|
+
is_animating: viewer.clock.shouldAnimate
|
|
301
|
+
};
|
|
302
|
+
} catch (error2) {
|
|
303
|
+
warn(PREFIX, "Error getting clock state:", error2);
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
228
306
|
}
|
|
229
307
|
function sendInteractionEvent(type, additionalData = {}) {
|
|
308
|
+
if (isDestroyed) {
|
|
309
|
+
log(PREFIX, "Skipping interaction event - destroyed:", type);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
if (!viewer) {
|
|
313
|
+
warn(PREFIX, "Cannot send interaction event - viewer not available");
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const cameraState = getCameraState();
|
|
317
|
+
if (!cameraState) {
|
|
318
|
+
warn(PREFIX, "Skipping interaction event - camera state not available");
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
230
321
|
const event = {
|
|
231
322
|
type,
|
|
232
323
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
233
|
-
camera:
|
|
324
|
+
camera: cameraState,
|
|
234
325
|
clock: getClockState(),
|
|
235
326
|
...additionalData
|
|
236
327
|
};
|
|
237
|
-
|
|
328
|
+
log(PREFIX, "Interaction event:", type, event);
|
|
238
329
|
model.set("interaction_event", event);
|
|
239
330
|
model.save_changes();
|
|
240
331
|
}
|
|
241
332
|
const camera = viewer.camera;
|
|
242
333
|
camera.moveEnd.addEventListener(() => {
|
|
334
|
+
if (isDestroyed || !viewer)
|
|
335
|
+
return;
|
|
243
336
|
sendInteractionEvent("camera_move");
|
|
244
337
|
});
|
|
245
338
|
const scene = viewer.scene;
|
|
246
339
|
const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
|
|
247
340
|
handler.setInputAction((click) => {
|
|
341
|
+
if (isDestroyed || !viewer || !viewer.scene || !viewer.camera)
|
|
342
|
+
return;
|
|
248
343
|
const pickedData = {};
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
344
|
+
try {
|
|
345
|
+
const ray = viewer.camera.getPickRay(click.position);
|
|
346
|
+
if (ray && viewer.scene.globe) {
|
|
347
|
+
const cartesian = viewer.scene.globe.pick(ray, viewer.scene);
|
|
348
|
+
if (cartesian) {
|
|
349
|
+
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
|
350
|
+
pickedData.picked_position = {
|
|
351
|
+
latitude: Cesium.Math.toDegrees(cartographic.latitude),
|
|
352
|
+
longitude: Cesium.Math.toDegrees(cartographic.longitude),
|
|
353
|
+
altitude: cartographic.height
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
} catch (error2) {
|
|
358
|
+
warn(PREFIX, "Error picking position:", error2);
|
|
258
359
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
propertyNames.
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
360
|
+
try {
|
|
361
|
+
const pickedObject = viewer.scene.pick(click.position);
|
|
362
|
+
if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) {
|
|
363
|
+
const entity = pickedObject.id;
|
|
364
|
+
pickedData.picked_entity = {
|
|
365
|
+
id: entity.id,
|
|
366
|
+
name: entity.name || null
|
|
367
|
+
};
|
|
368
|
+
if (entity.properties) {
|
|
369
|
+
const props = {};
|
|
370
|
+
const propertyNames = entity.properties.propertyNames;
|
|
371
|
+
if (propertyNames && propertyNames.length > 0) {
|
|
372
|
+
propertyNames.forEach((name) => {
|
|
373
|
+
try {
|
|
374
|
+
props[name] = entity.properties[name].getValue(viewer.clock.currentTime);
|
|
375
|
+
} catch (e) {
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
if (Object.keys(props).length > 0) {
|
|
379
|
+
pickedData.picked_entity.properties = props;
|
|
274
380
|
}
|
|
275
|
-
});
|
|
276
|
-
if (Object.keys(props).length > 0) {
|
|
277
|
-
pickedData.picked_entity.properties = props;
|
|
278
381
|
}
|
|
279
382
|
}
|
|
280
383
|
}
|
|
384
|
+
} catch (error2) {
|
|
385
|
+
warn(PREFIX, "Error picking entity:", error2);
|
|
281
386
|
}
|
|
282
387
|
sendInteractionEvent("left_click", pickedData);
|
|
283
388
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
284
389
|
handler.setInputAction((click) => {
|
|
390
|
+
if (isDestroyed || !viewer || !viewer.scene || !viewer.camera)
|
|
391
|
+
return;
|
|
285
392
|
const pickedData = {};
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
393
|
+
try {
|
|
394
|
+
const ray = viewer.camera.getPickRay(click.position);
|
|
395
|
+
if (ray && viewer.scene.globe) {
|
|
396
|
+
const cartesian = viewer.scene.globe.pick(ray, viewer.scene);
|
|
397
|
+
if (cartesian) {
|
|
398
|
+
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
|
399
|
+
pickedData.picked_position = {
|
|
400
|
+
latitude: Cesium.Math.toDegrees(cartographic.latitude),
|
|
401
|
+
longitude: Cesium.Math.toDegrees(cartographic.longitude),
|
|
402
|
+
altitude: cartographic.height
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
} catch (error2) {
|
|
407
|
+
warn(PREFIX, "Error picking position:", error2);
|
|
295
408
|
}
|
|
296
409
|
sendInteractionEvent("right_click", pickedData);
|
|
297
410
|
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
|
|
298
411
|
if (viewer.timeline) {
|
|
299
412
|
let timelineScrubbing = false;
|
|
300
|
-
let scrubTimeout = null;
|
|
301
413
|
viewer.clock.onTick.addEventListener(() => {
|
|
414
|
+
if (isDestroyed)
|
|
415
|
+
return;
|
|
302
416
|
if (viewer.timeline) {
|
|
303
417
|
if (scrubTimeout) {
|
|
304
418
|
clearTimeout(scrubTimeout);
|
|
419
|
+
scrubTimeout = null;
|
|
305
420
|
}
|
|
306
421
|
scrubTimeout = setTimeout(() => {
|
|
307
|
-
if (timelineScrubbing) {
|
|
422
|
+
if (!isDestroyed && timelineScrubbing) {
|
|
308
423
|
timelineScrubbing = false;
|
|
309
424
|
sendInteractionEvent("timeline_scrub");
|
|
310
425
|
}
|
|
@@ -313,13 +428,23 @@ function setupViewerListeners(viewer, model, container, Cesium) {
|
|
|
313
428
|
}
|
|
314
429
|
});
|
|
315
430
|
}
|
|
431
|
+
log(PREFIX, "Viewer listeners setup complete");
|
|
316
432
|
}
|
|
317
433
|
function setupGeoJSONLoader(viewer, model, Cesium) {
|
|
434
|
+
log(PREFIX, "Setting up GeoJSON loader");
|
|
318
435
|
let geojsonDataSources = [];
|
|
319
|
-
|
|
320
|
-
|
|
436
|
+
let isDestroyed = false;
|
|
437
|
+
async function loadGeoJSONData(flyToData = true) {
|
|
438
|
+
if (isDestroyed) {
|
|
439
|
+
log(PREFIX, "Skipping geojson_data load - destroyed");
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (!viewer || !viewer.dataSources) {
|
|
443
|
+
warn(PREFIX, "Cannot load GeoJSON - viewer or dataSources not available");
|
|
321
444
|
return;
|
|
445
|
+
}
|
|
322
446
|
const geojsonDataArray = model.get("geojson_data");
|
|
447
|
+
log(PREFIX, "Loading GeoJSON data, count:", geojsonDataArray?.length || 0);
|
|
323
448
|
geojsonDataSources.forEach((dataSource) => {
|
|
324
449
|
if (viewer && viewer.dataSources) {
|
|
325
450
|
viewer.dataSources.remove(dataSource);
|
|
@@ -329,6 +454,7 @@ function setupGeoJSONLoader(viewer, model, Cesium) {
|
|
|
329
454
|
if (geojsonDataArray && Array.isArray(geojsonDataArray)) {
|
|
330
455
|
for (const geojsonData of geojsonDataArray) {
|
|
331
456
|
try {
|
|
457
|
+
log(PREFIX, "Loading GeoJSON dataset...");
|
|
332
458
|
const dataSource = await Cesium.GeoJsonDataSource.load(geojsonData, {
|
|
333
459
|
stroke: Cesium.Color.HOTPINK,
|
|
334
460
|
fill: Cesium.Color.PINK.withAlpha(0.5),
|
|
@@ -337,18 +463,28 @@ function setupGeoJSONLoader(viewer, model, Cesium) {
|
|
|
337
463
|
if (viewer && viewer.dataSources) {
|
|
338
464
|
viewer.dataSources.add(dataSource);
|
|
339
465
|
geojsonDataSources.push(dataSource);
|
|
466
|
+
log(PREFIX, "GeoJSON dataset loaded successfully");
|
|
340
467
|
}
|
|
341
|
-
} catch (
|
|
342
|
-
|
|
468
|
+
} catch (error2) {
|
|
469
|
+
error2(PREFIX, "Error loading GeoJSON:", error2);
|
|
343
470
|
}
|
|
344
471
|
}
|
|
345
|
-
if (geojsonDataSources.length > 0 && viewer && viewer.flyTo) {
|
|
472
|
+
if (flyToData && geojsonDataSources.length > 0 && viewer && viewer.flyTo) {
|
|
473
|
+
log(PREFIX, "Flying to GeoJSON data");
|
|
346
474
|
viewer.flyTo(geojsonDataSources[0]);
|
|
347
475
|
}
|
|
348
476
|
}
|
|
349
|
-
}
|
|
477
|
+
}
|
|
478
|
+
model.on("change:geojson_data", () => loadGeoJSONData(true));
|
|
479
|
+
const initialData = model.get("geojson_data");
|
|
480
|
+
if (initialData && Array.isArray(initialData) && initialData.length > 0) {
|
|
481
|
+
log(PREFIX, "Loading initial GeoJSON data...");
|
|
482
|
+
loadGeoJSONData(true);
|
|
483
|
+
}
|
|
350
484
|
return {
|
|
351
485
|
destroy: () => {
|
|
486
|
+
log(PREFIX, "Destroying GeoJSON loader");
|
|
487
|
+
isDestroyed = true;
|
|
352
488
|
geojsonDataSources.forEach((dataSource) => {
|
|
353
489
|
if (viewer) {
|
|
354
490
|
viewer.dataSources.remove(dataSource);
|
|
@@ -359,11 +495,20 @@ function setupGeoJSONLoader(viewer, model, Cesium) {
|
|
|
359
495
|
};
|
|
360
496
|
}
|
|
361
497
|
function setupCZMLLoader(viewer, model, Cesium) {
|
|
498
|
+
log(PREFIX, "Setting up CZML loader");
|
|
362
499
|
let czmlDataSources = [];
|
|
363
|
-
|
|
364
|
-
|
|
500
|
+
let isDestroyed = false;
|
|
501
|
+
async function loadCZMLData(flyToData = true) {
|
|
502
|
+
if (isDestroyed) {
|
|
503
|
+
log(PREFIX, "Skipping czml_data load - destroyed");
|
|
365
504
|
return;
|
|
505
|
+
}
|
|
506
|
+
if (!viewer || !viewer.dataSources) {
|
|
507
|
+
warn(PREFIX, "Cannot load CZML - viewer or dataSources not available");
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
366
510
|
const czmlDataArray = model.get("czml_data");
|
|
511
|
+
log(PREFIX, "Loading CZML data, count:", czmlDataArray?.length || 0);
|
|
367
512
|
czmlDataSources.forEach((dataSource) => {
|
|
368
513
|
if (viewer && viewer.dataSources) {
|
|
369
514
|
viewer.dataSources.remove(dataSource);
|
|
@@ -374,23 +519,36 @@ function setupCZMLLoader(viewer, model, Cesium) {
|
|
|
374
519
|
for (const czmlData of czmlDataArray) {
|
|
375
520
|
if (Array.isArray(czmlData) && czmlData.length > 0) {
|
|
376
521
|
try {
|
|
522
|
+
log(PREFIX, "Loading CZML document with", czmlData.length, "packets...");
|
|
377
523
|
const dataSource = await Cesium.CzmlDataSource.load(czmlData);
|
|
378
524
|
if (viewer && viewer.dataSources) {
|
|
379
525
|
viewer.dataSources.add(dataSource);
|
|
380
526
|
czmlDataSources.push(dataSource);
|
|
527
|
+
log(PREFIX, "CZML document loaded successfully, entities:", dataSource.entities.values.length);
|
|
381
528
|
}
|
|
382
|
-
} catch (
|
|
383
|
-
|
|
529
|
+
} catch (error2) {
|
|
530
|
+
error2(PREFIX, "Error loading CZML:", error2);
|
|
384
531
|
}
|
|
532
|
+
} else {
|
|
533
|
+
warn(PREFIX, "Skipping invalid CZML data (not an array or empty):", czmlData);
|
|
385
534
|
}
|
|
386
535
|
}
|
|
387
|
-
if (czmlDataSources.length > 0 && viewer && viewer.flyTo) {
|
|
536
|
+
if (flyToData && czmlDataSources.length > 0 && viewer && viewer.flyTo) {
|
|
537
|
+
log(PREFIX, "Flying to CZML data");
|
|
388
538
|
viewer.flyTo(czmlDataSources[0]);
|
|
389
539
|
}
|
|
390
540
|
}
|
|
391
|
-
}
|
|
541
|
+
}
|
|
542
|
+
model.on("change:czml_data", () => loadCZMLData(true));
|
|
543
|
+
const initialData = model.get("czml_data");
|
|
544
|
+
if (initialData && Array.isArray(initialData) && initialData.length > 0) {
|
|
545
|
+
log(PREFIX, "Loading initial CZML data...");
|
|
546
|
+
loadCZMLData(true);
|
|
547
|
+
}
|
|
392
548
|
return {
|
|
393
549
|
destroy: () => {
|
|
550
|
+
log(PREFIX, "Destroying CZML loader");
|
|
551
|
+
isDestroyed = true;
|
|
394
552
|
czmlDataSources.forEach((dataSource) => {
|
|
395
553
|
if (viewer) {
|
|
396
554
|
viewer.dataSources.remove(dataSource);
|
|
@@ -402,30 +560,60 @@ function setupCZMLLoader(viewer, model, Cesium) {
|
|
|
402
560
|
}
|
|
403
561
|
|
|
404
562
|
// src/cesiumjs_anywidget/js/camera-sync.js
|
|
563
|
+
var PREFIX2 = "CameraSync";
|
|
405
564
|
function initializeCameraSync(viewer, model) {
|
|
406
565
|
const Cesium = window.Cesium;
|
|
407
|
-
let cameraUpdateTimeout;
|
|
566
|
+
let cameraUpdateTimeout = null;
|
|
567
|
+
let isDestroyed = false;
|
|
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
|
+
});
|
|
408
574
|
function updateCameraFromModel() {
|
|
409
|
-
if (
|
|
575
|
+
if (isDestroyed) {
|
|
576
|
+
log(PREFIX2, "Skipping updateCameraFromModel - module destroyed");
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
if (!viewer) {
|
|
580
|
+
warn(PREFIX2, "updateCameraFromModel called but viewer is null");
|
|
410
581
|
return;
|
|
582
|
+
}
|
|
411
583
|
const lat = model.get("latitude");
|
|
412
584
|
const lon = model.get("longitude");
|
|
413
585
|
const alt = model.get("altitude");
|
|
414
586
|
const heading = Cesium.Math.toRadians(model.get("heading"));
|
|
415
587
|
const pitch = Cesium.Math.toRadians(model.get("pitch"));
|
|
416
588
|
const roll = Cesium.Math.toRadians(model.get("roll"));
|
|
589
|
+
log(PREFIX2, "Updating camera from model:", { lat, lon, alt });
|
|
417
590
|
viewer.camera.setView({
|
|
418
591
|
destination: Cesium.Cartesian3.fromDegrees(lon, lat, alt),
|
|
419
592
|
orientation: { heading, pitch, roll }
|
|
420
593
|
});
|
|
421
594
|
}
|
|
422
595
|
function updateModelFromCamera() {
|
|
423
|
-
if (
|
|
596
|
+
if (isDestroyed) {
|
|
597
|
+
log(PREFIX2, "Skipping updateModelFromCamera - module destroyed");
|
|
424
598
|
return;
|
|
599
|
+
}
|
|
600
|
+
if (!syncEnabled) {
|
|
601
|
+
log(PREFIX2, "Skipping updateModelFromCamera - sync disabled");
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
if (!viewer) {
|
|
605
|
+
warn(PREFIX2, "updateModelFromCamera called but viewer is null");
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
425
608
|
const position = viewer.camera.positionCartographic;
|
|
426
609
|
const heading = viewer.camera.heading;
|
|
427
610
|
const pitch = viewer.camera.pitch;
|
|
428
611
|
const roll = viewer.camera.roll;
|
|
612
|
+
log(PREFIX2, "Updating model from camera:", {
|
|
613
|
+
lat: Cesium.Math.toDegrees(position.latitude),
|
|
614
|
+
lon: Cesium.Math.toDegrees(position.longitude),
|
|
615
|
+
alt: position.height
|
|
616
|
+
});
|
|
429
617
|
model.set("latitude", Cesium.Math.toDegrees(position.latitude));
|
|
430
618
|
model.set("longitude", Cesium.Math.toDegrees(position.longitude));
|
|
431
619
|
model.set("altitude", position.height);
|
|
@@ -435,9 +623,20 @@ function initializeCameraSync(viewer, model) {
|
|
|
435
623
|
model.save_changes();
|
|
436
624
|
}
|
|
437
625
|
function handleCameraChanged() {
|
|
438
|
-
|
|
626
|
+
if (isDestroyed) {
|
|
627
|
+
log(PREFIX2, "Skipping handleCameraChanged - module destroyed");
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
if (!syncEnabled) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
if (cameraUpdateTimeout) {
|
|
634
|
+
clearTimeout(cameraUpdateTimeout);
|
|
635
|
+
}
|
|
439
636
|
cameraUpdateTimeout = setTimeout(() => {
|
|
440
|
-
|
|
637
|
+
if (!isDestroyed && syncEnabled) {
|
|
638
|
+
updateModelFromCamera();
|
|
639
|
+
}
|
|
441
640
|
}, 500);
|
|
442
641
|
}
|
|
443
642
|
updateCameraFromModel();
|
|
@@ -449,10 +648,15 @@ function initializeCameraSync(viewer, model) {
|
|
|
449
648
|
model.on("change:pitch", updateCameraFromModel);
|
|
450
649
|
model.on("change:roll", updateCameraFromModel);
|
|
451
650
|
model.on("change:camera_command", () => {
|
|
651
|
+
if (isDestroyed) {
|
|
652
|
+
log(PREFIX2, "Skipping camera_command - module destroyed");
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
452
655
|
const command = model.get("camera_command");
|
|
453
656
|
if (!command || !command.command || !command.timestamp)
|
|
454
657
|
return;
|
|
455
658
|
const cmd = command.command;
|
|
659
|
+
log(PREFIX2, "Executing camera command:", cmd, command);
|
|
456
660
|
try {
|
|
457
661
|
switch (cmd) {
|
|
458
662
|
case "flyTo":
|
|
@@ -535,27 +739,36 @@ function initializeCameraSync(viewer, model) {
|
|
|
535
739
|
viewer.camera.zoomOut(command.distance || 100);
|
|
536
740
|
break;
|
|
537
741
|
default:
|
|
538
|
-
|
|
742
|
+
warn(PREFIX2, `Unknown camera command: ${cmd}`);
|
|
539
743
|
}
|
|
540
|
-
} catch (
|
|
541
|
-
|
|
744
|
+
} catch (err) {
|
|
745
|
+
error(PREFIX2, `Error executing camera command ${cmd}:`, err);
|
|
542
746
|
}
|
|
543
747
|
});
|
|
544
748
|
return {
|
|
545
749
|
updateCameraFromModel,
|
|
546
750
|
updateModelFromCamera,
|
|
547
751
|
destroy: () => {
|
|
548
|
-
|
|
752
|
+
log(PREFIX2, "Destroying camera sync module");
|
|
753
|
+
isDestroyed = true;
|
|
754
|
+
if (cameraUpdateTimeout) {
|
|
755
|
+
clearTimeout(cameraUpdateTimeout);
|
|
756
|
+
cameraUpdateTimeout = null;
|
|
757
|
+
}
|
|
549
758
|
viewer.camera.changed.removeEventListener(handleCameraChanged);
|
|
759
|
+
log(PREFIX2, "Camera sync module destroyed");
|
|
550
760
|
}
|
|
551
761
|
};
|
|
552
762
|
}
|
|
553
763
|
|
|
554
764
|
// src/cesiumjs_anywidget/js/measurement-tools.js
|
|
765
|
+
var PREFIX3 = "Measurements";
|
|
555
766
|
function initializeMeasurementTools(viewer, model, container) {
|
|
767
|
+
log(PREFIX3, "Initializing measurement tools");
|
|
556
768
|
const Cesium = window.Cesium;
|
|
557
769
|
let measurementHandler = null;
|
|
558
770
|
let editHandler = null;
|
|
771
|
+
let isDestroyed = false;
|
|
559
772
|
let measurementState = {
|
|
560
773
|
mode: null,
|
|
561
774
|
points: [],
|
|
@@ -777,6 +990,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
777
990
|
};
|
|
778
991
|
}
|
|
779
992
|
function clearAllMeasurements() {
|
|
993
|
+
log(PREFIX3, "Clearing all measurements");
|
|
780
994
|
measurementState.entities.forEach((e) => viewer.entities.remove(e));
|
|
781
995
|
measurementState.labels.forEach((l) => viewer.entities.remove(l));
|
|
782
996
|
measurementState.polylines.forEach((p) => viewer.entities.remove(p));
|
|
@@ -941,12 +1155,12 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
941
1155
|
const editLatInput = document.getElementById("edit-lat");
|
|
942
1156
|
const editAltInput = document.getElementById("edit-alt");
|
|
943
1157
|
if (!applyBtn || !closeBtn || !editLonInput || !editLatInput || !editAltInput) {
|
|
944
|
-
|
|
1158
|
+
warn(PREFIX3, "Editor panel input elements not found in DOM");
|
|
945
1159
|
}
|
|
946
1160
|
if (applyBtn) {
|
|
947
1161
|
applyBtn.onclick = () => {
|
|
948
1162
|
if (!editLonInput || !editLatInput || !editAltInput) {
|
|
949
|
-
|
|
1163
|
+
warn(PREFIX3, "Editor input fields not available");
|
|
950
1164
|
return;
|
|
951
1165
|
}
|
|
952
1166
|
const lon = parseFloat(editLonInput.value);
|
|
@@ -1123,9 +1337,10 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1123
1337
|
}
|
|
1124
1338
|
function updateMeasurementsList() {
|
|
1125
1339
|
const results = model.get("measurement_results") || [];
|
|
1340
|
+
log(PREFIX3, "Updating measurements list, count:", results.length);
|
|
1126
1341
|
const listContent = document.getElementById("measurements-list-content");
|
|
1127
1342
|
if (!listContent) {
|
|
1128
|
-
|
|
1343
|
+
warn(PREFIX3, "Measurements list content element not found in DOM");
|
|
1129
1344
|
return;
|
|
1130
1345
|
}
|
|
1131
1346
|
if (results.length === 0) {
|
|
@@ -1185,7 +1400,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1185
1400
|
renameMeasurement(index, name);
|
|
1186
1401
|
};
|
|
1187
1402
|
} else {
|
|
1188
|
-
|
|
1403
|
+
warn(PREFIX3, `Rename button not found for measurement ${index}`);
|
|
1189
1404
|
}
|
|
1190
1405
|
});
|
|
1191
1406
|
}
|
|
@@ -1488,6 +1703,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1488
1703
|
}
|
|
1489
1704
|
}
|
|
1490
1705
|
function enableMeasurementMode(mode) {
|
|
1706
|
+
log(PREFIX3, "Enabling measurement mode:", mode);
|
|
1491
1707
|
if (measurementHandler) {
|
|
1492
1708
|
measurementHandler.destroy();
|
|
1493
1709
|
measurementHandler = null;
|
|
@@ -1676,31 +1892,50 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1676
1892
|
});
|
|
1677
1893
|
}
|
|
1678
1894
|
model.on("change:measurement_mode", () => {
|
|
1895
|
+
if (isDestroyed) {
|
|
1896
|
+
log(PREFIX3, "Skipping measurement_mode change - destroyed");
|
|
1897
|
+
return;
|
|
1898
|
+
}
|
|
1679
1899
|
const mode = model.get("measurement_mode");
|
|
1900
|
+
log(PREFIX3, "Measurement mode changed:", mode);
|
|
1680
1901
|
enableMeasurementMode(mode);
|
|
1681
1902
|
});
|
|
1682
1903
|
model.on("change:measurement_results", () => {
|
|
1904
|
+
if (isDestroyed) {
|
|
1905
|
+
log(PREFIX3, "Skipping measurement_results change - destroyed");
|
|
1906
|
+
return;
|
|
1907
|
+
}
|
|
1683
1908
|
const results = model.get("measurement_results") || [];
|
|
1909
|
+
log(PREFIX3, "Measurement results changed, count:", results.length);
|
|
1684
1910
|
if (results.length === 0) {
|
|
1685
1911
|
clearAllMeasurements();
|
|
1686
1912
|
}
|
|
1687
1913
|
updateMeasurementsList();
|
|
1688
1914
|
});
|
|
1689
1915
|
model.on("change:load_measurements_trigger", () => {
|
|
1916
|
+
if (isDestroyed)
|
|
1917
|
+
return;
|
|
1690
1918
|
const triggerData = model.get("load_measurements_trigger");
|
|
1919
|
+
log(PREFIX3, "Load measurements trigger:", triggerData);
|
|
1691
1920
|
if (triggerData && triggerData.measurements) {
|
|
1692
1921
|
loadAndDisplayMeasurements(triggerData.measurements);
|
|
1693
1922
|
updateMeasurementsList();
|
|
1694
1923
|
}
|
|
1695
1924
|
});
|
|
1696
1925
|
model.on("change:focus_measurement_trigger", () => {
|
|
1926
|
+
if (isDestroyed)
|
|
1927
|
+
return;
|
|
1697
1928
|
const triggerData = model.get("focus_measurement_trigger");
|
|
1929
|
+
log(PREFIX3, "Focus measurement trigger:", triggerData);
|
|
1698
1930
|
if (triggerData && typeof triggerData.index === "number") {
|
|
1699
1931
|
focusOnMeasurement(triggerData.index);
|
|
1700
1932
|
}
|
|
1701
1933
|
});
|
|
1702
1934
|
model.on("change:show_measurement_tools", () => {
|
|
1935
|
+
if (isDestroyed)
|
|
1936
|
+
return;
|
|
1703
1937
|
const show = model.get("show_measurement_tools");
|
|
1938
|
+
log(PREFIX3, "Show measurement tools:", show);
|
|
1704
1939
|
toolbarDiv.style.display = show ? "flex" : "none";
|
|
1705
1940
|
editorPanel.style.display = show ? editorPanel.style.display : "none";
|
|
1706
1941
|
if (!show && editState.enabled) {
|
|
@@ -1709,7 +1944,10 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1709
1944
|
}
|
|
1710
1945
|
});
|
|
1711
1946
|
model.on("change:show_measurements_list", () => {
|
|
1947
|
+
if (isDestroyed)
|
|
1948
|
+
return;
|
|
1712
1949
|
const show = model.get("show_measurements_list");
|
|
1950
|
+
log(PREFIX3, "Show measurements list:", show);
|
|
1713
1951
|
measurementsListPanel.style.display = show ? "block" : "none";
|
|
1714
1952
|
});
|
|
1715
1953
|
toolbarDiv.style.display = model.get("show_measurement_tools") ? "flex" : "none";
|
|
@@ -1719,6 +1957,8 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1719
1957
|
enableMeasurementMode,
|
|
1720
1958
|
clearAllMeasurements,
|
|
1721
1959
|
destroy: () => {
|
|
1960
|
+
log(PREFIX3, "Destroying measurement tools");
|
|
1961
|
+
isDestroyed = true;
|
|
1722
1962
|
if (measurementHandler) {
|
|
1723
1963
|
measurementHandler.destroy();
|
|
1724
1964
|
}
|
|
@@ -1726,6 +1966,7 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1726
1966
|
if (toolbarDiv.parentNode) {
|
|
1727
1967
|
toolbarDiv.remove();
|
|
1728
1968
|
}
|
|
1969
|
+
log(PREFIX3, "Measurement tools destroyed");
|
|
1729
1970
|
}
|
|
1730
1971
|
};
|
|
1731
1972
|
}
|
|
@@ -1733,15 +1974,26 @@ function initializeMeasurementTools(viewer, model, container) {
|
|
|
1733
1974
|
// src/cesiumjs_anywidget/js/index.js
|
|
1734
1975
|
window.CESIUM_BASE_URL = "https://cesium.com/downloads/cesiumjs/releases/1.135/Build/Cesium/";
|
|
1735
1976
|
async function render({ model, el }) {
|
|
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...");
|
|
1736
1983
|
const Cesium = await loadCesiumJS();
|
|
1984
|
+
log("Main", "CesiumJS loaded successfully");
|
|
1737
1985
|
const container = document.createElement("div");
|
|
1738
1986
|
container.style.width = "100%";
|
|
1739
1987
|
container.style.height = model.get("height");
|
|
1740
1988
|
container.style.position = "relative";
|
|
1741
1989
|
el.appendChild(container);
|
|
1990
|
+
log("Main", "Container created with height:", model.get("height"));
|
|
1742
1991
|
const ionToken = model.get("ion_access_token");
|
|
1743
1992
|
if (ionToken) {
|
|
1744
1993
|
Cesium.Ion.defaultAccessToken = ionToken;
|
|
1994
|
+
log("Main", "Ion access token set");
|
|
1995
|
+
} else {
|
|
1996
|
+
warn("Main", "No Ion access token provided");
|
|
1745
1997
|
}
|
|
1746
1998
|
const loadingDiv = createLoadingIndicator(container, !!ionToken);
|
|
1747
1999
|
let viewer = null;
|
|
@@ -1751,37 +2003,57 @@ async function render({ model, el }) {
|
|
|
1751
2003
|
let czmlLoader = null;
|
|
1752
2004
|
(async () => {
|
|
1753
2005
|
try {
|
|
2006
|
+
log("Main", "Creating Cesium Viewer...");
|
|
1754
2007
|
viewer = createViewer(container, model, Cesium);
|
|
2008
|
+
log("Main", "Cesium Viewer created successfully");
|
|
1755
2009
|
if (loadingDiv.parentNode) {
|
|
1756
2010
|
loadingDiv.remove();
|
|
1757
2011
|
}
|
|
2012
|
+
log("Main", "Initializing camera synchronization...");
|
|
1758
2013
|
cameraSync = initializeCameraSync(viewer, model);
|
|
2014
|
+
log("Main", "Camera synchronization initialized");
|
|
2015
|
+
log("Main", "Initializing measurement tools...");
|
|
1759
2016
|
measurementTools = initializeMeasurementTools(viewer, model, container);
|
|
2017
|
+
log("Main", "Measurement tools initialized");
|
|
2018
|
+
log("Main", "Setting up viewer listeners...");
|
|
1760
2019
|
setupViewerListeners(viewer, model, container, Cesium);
|
|
2020
|
+
log("Main", "Viewer listeners set up");
|
|
2021
|
+
log("Main", "Setting up GeoJSON loader...");
|
|
1761
2022
|
geoJsonLoader = setupGeoJSONLoader(viewer, model, Cesium);
|
|
2023
|
+
log("Main", "GeoJSON loader set up");
|
|
2024
|
+
log("Main", "Setting up CZML loader...");
|
|
1762
2025
|
czmlLoader = setupCZMLLoader(viewer, model, Cesium);
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
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}`;
|
|
1766
2031
|
loadingDiv.style.background = "rgba(255,0,0,0.8)";
|
|
1767
2032
|
}
|
|
1768
2033
|
})();
|
|
1769
2034
|
return () => {
|
|
2035
|
+
log("Main", "Starting cleanup...");
|
|
1770
2036
|
if (cameraSync) {
|
|
2037
|
+
log("Main", "Destroying camera sync...");
|
|
1771
2038
|
cameraSync.destroy();
|
|
1772
2039
|
}
|
|
1773
2040
|
if (measurementTools) {
|
|
2041
|
+
log("Main", "Destroying measurement tools...");
|
|
1774
2042
|
measurementTools.destroy();
|
|
1775
2043
|
}
|
|
1776
2044
|
if (geoJsonLoader) {
|
|
2045
|
+
log("Main", "Destroying GeoJSON loader...");
|
|
1777
2046
|
geoJsonLoader.destroy();
|
|
1778
2047
|
}
|
|
1779
2048
|
if (czmlLoader) {
|
|
2049
|
+
log("Main", "Destroying CZML loader...");
|
|
1780
2050
|
czmlLoader.destroy();
|
|
1781
2051
|
}
|
|
1782
2052
|
if (viewer) {
|
|
2053
|
+
log("Main", "Destroying viewer...");
|
|
1783
2054
|
viewer.destroy();
|
|
1784
2055
|
}
|
|
2056
|
+
log("Main", "Cleanup complete");
|
|
1785
2057
|
};
|
|
1786
2058
|
}
|
|
1787
2059
|
var js_default = { render };
|
cesiumjs_anywidget/widget.py
CHANGED
|
@@ -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,
|
|
@@ -1,10 +1,10 @@
|
|
|
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
|
|
7
|
-
Author:
|
|
7
|
+
Author: Alexis Placet
|
|
8
8
|
License: Apache License
|
|
9
9
|
Version 2.0, January 2004
|
|
10
10
|
http://www.apache.org/licenses/
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
cesiumjs_anywidget/__init__.py,sha256=9WVcAtreHgk6C5clPG6sZy4m7s5AIbGU1DJ4oDpx3Is,165
|
|
2
|
+
cesiumjs_anywidget/styles.css,sha256=kt2i9fJuM6gaR7WkoQ2VGGoHzhqy6RpJVK2xwMKPV70,689
|
|
3
|
+
cesiumjs_anywidget/widget.py,sha256=Yh_pluGI23vu-RvB1oHiZtq7ySAxPlYzIHViDFvS85k,41258
|
|
4
|
+
cesiumjs_anywidget/index.js,sha256=22bGV7SzM8b69-kFEWoXhh94TQaUAM9cJmEV5Ykmmbc,78269
|
|
5
|
+
cesiumjs_anywidget-0.6.0.dist-info/METADATA,sha256=D2p5Jx2HOWr-B9krknzNtGWhV53BKMjojhTCYti6SMg,24780
|
|
6
|
+
cesiumjs_anywidget-0.6.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
7
|
+
cesiumjs_anywidget-0.6.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
8
|
+
cesiumjs_anywidget-0.6.0.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
cesiumjs_anywidget/__init__.py,sha256=9WVcAtreHgk6C5clPG6sZy4m7s5AIbGU1DJ4oDpx3Is,165
|
|
2
|
-
cesiumjs_anywidget/styles.css,sha256=kt2i9fJuM6gaR7WkoQ2VGGoHzhqy6RpJVK2xwMKPV70,689
|
|
3
|
-
cesiumjs_anywidget/widget.py,sha256=_7uXX7B3KsOg_3QrMDfV0pZ8BGA-6coFnZ7_gTI3nck,39104
|
|
4
|
-
cesiumjs_anywidget/index.js,sha256=SrJ9F9xHdfvbz5CkP_ydspiDaPU6vp74vxtUv-RVimE,68405
|
|
5
|
-
cesiumjs_anywidget-0.4.0.dist-info/METADATA,sha256=NwADYoiPPp4RLblmHCM5_mhak_cCB7ptC4iN0NXVZTY,24778
|
|
6
|
-
cesiumjs_anywidget-0.4.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
7
|
-
cesiumjs_anywidget-0.4.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
8
|
-
cesiumjs_anywidget-0.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|