跪拜 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 ↗