跪拜 Guibai
← All articles
Frontend · JavaScript

Building a Forest Fire Monitoring Dashboard with Cesium: Arcs, Particles, and Glow Effects

By 尘世中一位迷途小书童 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Dashboards that overlay real-time resource relationships on a 3D globe are increasingly common in logistics, emergency response, and infrastructure monitoring. The techniques here—dynamic arc-height scaling, Canvas-based particle layers outside the 3D engine, and bounding-sphere camera framing—directly solve the visual and performance problems that make these projects brittle when hardcoded.

Summary

A forest fire monitoring demo built entirely in one HTML file uses Cesium to display a 3D globe with satellite imagery, semi-transparent fire perimeters, and color-coded arcs linking resource stations to a fire point. The arcs are custom-interpolated parabolas—not geodesic lines—with height dynamically scaled to 12% of the ground distance, capped at 4.5 km, to avoid the missile-trajectory look that hardcoded heights produce.

Particle flow along the arcs runs on a separate 2D Canvas layer, projecting pre-computed world coordinates to screen space each frame. This bypasses Cesium's rendering pipeline entirely, keeping 80 animated light points smooth without per-frame Entity or PointPrimitive overhead. Glow arcs use a sine-wave-driven CallbackProperty with per-line phase offsets and an alpha-change threshold that skips unnecessary color-object clones.

Station icons are Canvas-generated emoji-on-circle data URLs, eliminating image requests. The camera auto-frames all points using a bounding sphere, avoiding the hardcoded pitch that cropped northern stations off-screen. All station data lives in a single array, making the jump from mock data to a live API a matter of swapping the source and re-running the build functions.

Takeaways
Hardcoded arc heights produce absurd trajectories when ground distances vary; scaling height to 12% of the point-to-point distance with a 4.5 km cap keeps arcs readable.
Setting arcType to NONE and interpolating longitude, latitude, and height with a sine function creates smooth parabolic arcs instead of Earth-hugging geodesics.
Merging four static arc lines into a single Primitive with GeometryInstance reduces draw calls compared to adding each line as a separate Entity.
Glow-arc alpha animation uses performance.now() inside a CallbackProperty rather than JulianDate interpolation to avoid per-frame object allocation and GC pressure.
An alpha-change threshold of 0.005 prevents unnecessary color-object clones during the sine-wave breathing cycle.
Eighty flowing particles run on an overlaid 2D Canvas, projecting pre-computed world coordinates to screen space with scene.cartesianToCanvasCoordinates, completely outside Cesium's rendering pipeline.
Station icons are Canvas-generated data URLs (emoji on a colored circle) cached in memory, requiring zero HTTP requests and letting color changes happen via a single parameter.
Billboard and Label components bound to the same Entity halve the draw calls compared to adding them separately.
Disabling depthTestAgainstTerrain prevents annotation labels from flickering behind terrain in hilly areas.
A bounding sphere computed from all station and fire-point coordinates, with a radius multiplier of 1.6 and a pitch of -32°, automatically frames the scene and avoids cropping edge points.
All station configuration—coordinates, labels, colors, icons—lives in one array; swapping it for live API data and re-running the build functions is the entire integration path.
Conclusions

Canvas-based particle layers are an underused escape hatch in 3D map engines. They sidestep the entity system's per-frame overhead entirely while staying perfectly pinned to world coordinates via a single projection call.

The jump from hardcoded arc heights to distance-proportional scaling is the difference between a demo that breaks on the first data change and one that survives real-world coordinate variance. The 12% ratio and 4.5 km cap are empirical tuning knobs, not universal constants, but the principle generalizes to any geospatial link visualization.

Using performance.now() instead of JulianDate inside a CallbackProperty is a micro-optimization that only matters at scale, but it reveals a broader Cesium pattern: the engine's time API allocates, and animation-heavy dashboards feel that allocation in frame drops.

Generating icons as cached Canvas data URLs eliminates an entire class of asset-management friction—no sprite sheets, no HTTP requests, no build-step dependencies—while keeping the visual output indistinguishable from pre-rendered PNGs.

Binding Billboard and Label to the same Entity is a small API choice with an outsized rendering impact. It's the kind of detail that separates a dashboard that runs at 60 fps from one that stutters once annotation counts climb.

The bounding-sphere camera strategy turns a fragile, coordinate-specific setup into a self-adjusting system. It's a one-time cost that pays off every time the data changes or a new station is added.

Concepts & terms
ArcType.NONE
A Cesium PolylineGeometry setting that disables Earth-surface-following geodesic interpolation, allowing manual control over each vertex's longitude, latitude, and height to create parabolic arcs.
CallbackProperty
A Cesium property type that recomputes its value every frame via a callback function, commonly used for animations like pulsing alpha or shifting colors without manual update loops.
GeometryInstance + Primitive
A Cesium pattern where multiple GeometryInstance objects (each holding a geometry and per-instance attributes like color) are submitted together in a single Primitive, merging them into one GPU draw call.
cartesianToCanvasCoordinates
A Cesium Scene method that projects a 3D world position (Cartesian3) into 2D screen pixel coordinates, enabling Canvas or HTML overlays to track geographic points during camera movement.
BoundingSphere.fromPoints
A Cesium utility that computes the smallest sphere enclosing a set of positions, used here to automatically frame the camera so all stations and the fire point are visible.
depthTestAgainstTerrain
A Cesium globe setting that, when enabled, hides primitives and labels behind terrain; disabling it ensures annotations remain visible even when mountains would otherwise occlude them.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗