@anov/gis-skills-cli 0.0.0-stage → 0.3.0
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.
- package/CHANGELOG.md +618 -0
- package/INSTALL.md +478 -0
- package/LICENSE +15 -0
- package/README.md +148 -2
- package/RELEASING.md +160 -0
- package/bin/anov-gis-skills.mjs +408 -0
- package/lib/mcp-config.mjs +273 -0
- package/package.json +42 -4
- package/skills/anovgis-analysis/SKILL.md +585 -0
- package/skills/anovgis-effects/SKILL.md +260 -0
- package/skills/anovgis-imagery-terrain/SKILL.md +505 -0
- package/skills/anovgis-layers/SKILL.md +627 -0
- package/skills/anovgis-materials/SKILL.md +635 -0
- package/skills/anovgis-models-3dtiles/SKILL.md +448 -0
- package/skills/anovgis-pitfalls/SKILL.md +561 -0
- package/skills/anovgis-popup-widget/SKILL.md +474 -0
- package/skills/anovgis-primitives/SKILL.md +482 -0
- package/skills/anovgis-vector-graphics/SKILL.md +602 -0
- package/skills/anovgis-viewer/SKILL.md +618 -0
- package/skills/using-anovgis/DEMO-MAP.md +64 -0
- package/skills/using-anovgis/DEMO-SKILL-MAP.md +248 -0
- package/skills/using-anovgis/DOMAINS.md +183 -0
- package/skills/using-anovgis/REFERENCE.md +114 -0
- package/skills/using-anovgis/SKILL.md +392 -0
- package/skills/using-anovgis/templates/README.md +154 -0
- package/skills/using-anovgis/templates/combo1-vue3-vite.md +295 -0
- package/skills/using-anovgis/templates/combo2-vue2-cli.md +119 -0
- package/skills/using-anovgis/templates/combo3-html-cdn.md +107 -0
- package/skills/using-anovgis/templates/combo4-vanilla-webpack.md +91 -0
- package/skills/using-anovgis/templates/wizard-profiles.md +105 -0
- package/vendor/cesiumjs-skills/LICENSE +201 -0
- package/vendor/cesiumjs-skills/NOTICE +18 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-3d-tiles/SKILL.md +465 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-camera/SKILL.md +500 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-core-utilities/SKILL.md +403 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/REFERENCE.md +397 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/SKILL.md +351 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/01-diffuse-tint.js +38 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/02-texture-swap.js +42 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/03-feature-id-tileset.js +29 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/04-translucent-override.js +37 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/05-vertex-displacement.js +49 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/06-metadata-ramp.js +34 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/07-voxel-shader.js +27 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/README.md +19 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/_sandcastle-template.html +9 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-entities/SKILL.md +389 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-imagery/SKILL.md +471 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-interaction/SKILL.md +423 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-materials-shaders/SKILL.md +292 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-models-particles/SKILL.md +423 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-primitives/SKILL.md +537 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-spatial-math/SKILL.md +358 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-terrain-environment/SKILL.md +401 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-time-properties/SKILL.md +353 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-viewer-setup/SKILL.md +434 -0
- package/vendor/cesiumjs-skills/skills/using-cesiumjs-skills/SKILL.md +35 -0
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cesiumjs-primitives
|
|
3
|
+
description: "CesiumJS primitives and geometry - Primitive, GeometryInstance, Appearance, BufferPrimitive collections, GeoJsonPrimitive, Billboard/Label/PointPrimitive collections, built-in geometry shapes, ground primitives, classification. Use when rendering performance-critical static or vector geometry, loading GeoJSON without entities, creating custom shapes, batching draw calls, or using low-level collections."
|
|
4
|
+
---
|
|
5
|
+
# CesiumJS Primitives & Geometry
|
|
6
|
+
|
|
7
|
+
> **Applies to:** CesiumJS v1.142+ (ES module imports, `??` instead of `defaultValue`)
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
The Primitive API is the low-level rendering layer beneath the Entity API, trading convenience for performance.
|
|
12
|
+
|
|
13
|
+
**Core formula:** `Primitive = GeometryInstance[] + Appearance`
|
|
14
|
+
|
|
15
|
+
- **GeometryInstance** -- positions a Geometry in world space with per-instance attributes (color, show).
|
|
16
|
+
- **Geometry** -- vertex data describing a shape (polygon, box, ellipsoid, etc.).
|
|
17
|
+
- **Appearance** -- GLSL shaders + render state + optional Material that shade the geometry.
|
|
18
|
+
|
|
19
|
+
Primitives are **immutable after first render** -- geometry cannot change, but per-instance attributes update via `primitive.getGeometryInstanceAttributes(id)`.
|
|
20
|
+
|
|
21
|
+
## Primitive
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
import {
|
|
25
|
+
Viewer, Primitive, GeometryInstance, EllipseGeometry,
|
|
26
|
+
EllipsoidSurfaceAppearance, Material, Cartesian3, Math as CesiumMath,
|
|
27
|
+
} from "cesium";
|
|
28
|
+
|
|
29
|
+
const viewer = new Viewer("cesiumContainer");
|
|
30
|
+
const scene = viewer.scene;
|
|
31
|
+
|
|
32
|
+
const primitive = scene.primitives.add(new Primitive({
|
|
33
|
+
geometryInstances: new GeometryInstance({
|
|
34
|
+
geometry: new EllipseGeometry({
|
|
35
|
+
center: Cartesian3.fromDegrees(-100.0, 40.0),
|
|
36
|
+
semiMinorAxis: 250000.0,
|
|
37
|
+
semiMajorAxis: 400000.0,
|
|
38
|
+
rotation: CesiumMath.PI_OVER_FOUR,
|
|
39
|
+
vertexFormat: EllipsoidSurfaceAppearance.VERTEX_FORMAT, // must match appearance
|
|
40
|
+
}),
|
|
41
|
+
id: "myEllipse", // returned by Scene.pick()
|
|
42
|
+
}),
|
|
43
|
+
appearance: new EllipsoidSurfaceAppearance({ material: Material.fromType("Stripe") }),
|
|
44
|
+
}));
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Key Options
|
|
48
|
+
|
|
49
|
+
| Option | Default | Purpose |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| `geometryInstances` | -- | Single instance or array |
|
|
52
|
+
| `appearance` | -- | Shading (Appearance subclass) |
|
|
53
|
+
| `show` | `true` | Toggle visibility |
|
|
54
|
+
| `modelMatrix` | `Matrix4.IDENTITY` | Transform all instances |
|
|
55
|
+
| `asynchronous` | `true` | Build geometry on web worker |
|
|
56
|
+
| `releaseGeometryInstances` | `true` | Free geometry after GPU upload |
|
|
57
|
+
| `allowPicking` | `true` | `false` saves GPU memory |
|
|
58
|
+
| `shadows` | `ShadowMode.DISABLED` | Cast/receive shadows |
|
|
59
|
+
|
|
60
|
+
## Batching Multiple Instances
|
|
61
|
+
|
|
62
|
+
All instances in one Primitive share a single draw call.
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
import {
|
|
66
|
+
Primitive, GeometryInstance, RectangleGeometry, EllipseGeometry,
|
|
67
|
+
PerInstanceColorAppearance, ColorGeometryInstanceAttribute,
|
|
68
|
+
Cartesian3, Rectangle, Color,
|
|
69
|
+
} from "cesium";
|
|
70
|
+
|
|
71
|
+
scene.primitives.add(new Primitive({
|
|
72
|
+
geometryInstances: [
|
|
73
|
+
new GeometryInstance({
|
|
74
|
+
geometry: new RectangleGeometry({
|
|
75
|
+
rectangle: Rectangle.fromDegrees(-140, 30, -100, 40),
|
|
76
|
+
vertexFormat: PerInstanceColorAppearance.VERTEX_FORMAT,
|
|
77
|
+
}),
|
|
78
|
+
id: "rect",
|
|
79
|
+
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.RED.withAlpha(0.5)) },
|
|
80
|
+
}),
|
|
81
|
+
new GeometryInstance({
|
|
82
|
+
geometry: new EllipseGeometry({
|
|
83
|
+
center: Cartesian3.fromDegrees(-80, 35),
|
|
84
|
+
semiMinorAxis: 200000.0,
|
|
85
|
+
semiMajorAxis: 300000.0,
|
|
86
|
+
vertexFormat: PerInstanceColorAppearance.VERTEX_FORMAT,
|
|
87
|
+
}),
|
|
88
|
+
id: "ellipse",
|
|
89
|
+
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.BLUE.withAlpha(0.5)) },
|
|
90
|
+
}),
|
|
91
|
+
],
|
|
92
|
+
appearance: new PerInstanceColorAppearance(),
|
|
93
|
+
}));
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Updating Per-Instance Attributes
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
import { ColorGeometryInstanceAttribute, ShowGeometryInstanceAttribute } from "cesium";
|
|
100
|
+
|
|
101
|
+
// Wait for async geometry compilation
|
|
102
|
+
const removeListener = scene.postRender.addEventListener(() => {
|
|
103
|
+
if (!primitive.ready) return;
|
|
104
|
+
const attrs = primitive.getGeometryInstanceAttributes("rect");
|
|
105
|
+
attrs.color = ColorGeometryInstanceAttribute.toValue(Color.YELLOW);
|
|
106
|
+
attrs.show = ShowGeometryInstanceAttribute.toValue(true);
|
|
107
|
+
removeListener();
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## PrimitiveCollection
|
|
112
|
+
|
|
113
|
+
Nestable container -- `scene.primitives` is itself a PrimitiveCollection.
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
import { PrimitiveCollection, BillboardCollection, LabelCollection } from "cesium";
|
|
117
|
+
|
|
118
|
+
const group = new PrimitiveCollection();
|
|
119
|
+
group.add(new BillboardCollection());
|
|
120
|
+
group.add(new LabelCollection());
|
|
121
|
+
scene.primitives.add(group);
|
|
122
|
+
group.show = false; // toggle all children
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Choosing a Vector Data Path
|
|
126
|
+
|
|
127
|
+
| Need | Use |
|
|
128
|
+
|---|---|
|
|
129
|
+
| Entity lifecycle, clustering, per-entity styling, time-dynamic values | `GeoJsonDataSource` in `cesiumjs-entities` |
|
|
130
|
+
| One large GeoJSON object with low overhead and primitive-level performance | `GeoJsonPrimitive` in this skill |
|
|
131
|
+
| Tiled vector data, 3D Tiles LOD, metadata styling, feature picking | `MVTDataProvider` in `cesiumjs-3d-tiles` |
|
|
132
|
+
| Fully manual high-throughput point/polyline/polygon buffers | `BufferPointCollection`, `BufferPolylineCollection`, `BufferPolygonCollection` |
|
|
133
|
+
|
|
134
|
+
## Buffer Primitive Collections (Experimental, 1.140+)
|
|
135
|
+
|
|
136
|
+
Use `BufferPointCollection`, `BufferPolylineCollection`, and `BufferPolygonCollection`
|
|
137
|
+
for very large vector datasets where Entity/DataSource overhead is too high. These
|
|
138
|
+
APIs were introduced in 1.140 (#13212) and refined through 1.142; they are
|
|
139
|
+
experimental and use flyweight primitive objects: reuse one `BufferPoint`,
|
|
140
|
+
`BufferPolyline`, or `BufferPolygon` when adding or iterating thousands of items.
|
|
141
|
+
|
|
142
|
+
```js
|
|
143
|
+
import {
|
|
144
|
+
BlendOption,
|
|
145
|
+
BoundingSphere,
|
|
146
|
+
BufferPoint,
|
|
147
|
+
BufferPointCollection,
|
|
148
|
+
BufferPointMaterial,
|
|
149
|
+
Cartesian3,
|
|
150
|
+
Color,
|
|
151
|
+
} from "cesium";
|
|
152
|
+
|
|
153
|
+
const positions = [
|
|
154
|
+
Cartesian3.fromDegrees(-75.16, 39.95),
|
|
155
|
+
Cartesian3.fromDegrees(-73.98, 40.75),
|
|
156
|
+
];
|
|
157
|
+
|
|
158
|
+
const points = scene.primitives.add(new BufferPointCollection({
|
|
159
|
+
primitiveCountMax: positions.length,
|
|
160
|
+
allowPicking: true,
|
|
161
|
+
blendOption: BlendOption.TRANSLUCENT,
|
|
162
|
+
boundingVolume: BoundingSphere.fromPoints(positions), // world space in 1.142+
|
|
163
|
+
}));
|
|
164
|
+
|
|
165
|
+
const point = new BufferPoint();
|
|
166
|
+
const material = new BufferPointMaterial({
|
|
167
|
+
color: Color.CYAN.withAlpha(0.65),
|
|
168
|
+
outlineColor: Color.WHITE.withAlpha(0.9),
|
|
169
|
+
outlineWidth: 2,
|
|
170
|
+
size: 10,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
positions.forEach((position, featureId) => {
|
|
174
|
+
points.add({
|
|
175
|
+
position,
|
|
176
|
+
featureId,
|
|
177
|
+
material,
|
|
178
|
+
}, point);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
const picked = scene.pick(windowPosition);
|
|
182
|
+
if (picked?.collection === points) {
|
|
183
|
+
console.log(picked.index, picked.primitive.featureId);
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
> **Breaking change (1.141, #13448):** `BufferPrimitiveCollection.modelMatrix`,
|
|
188
|
+
> `boundingVolume`, and `boundingVolumeWC` are now **readonly** -- you may mutate
|
|
189
|
+
> the object in place, but reassigning the property (`collection.modelMatrix = ...`)
|
|
190
|
+
> throws. Update the existing matrix/volume instead of swapping in a new one.
|
|
191
|
+
|
|
192
|
+
1.142 notes:
|
|
193
|
+
- `boundingVolume` is now world-space, not local/model-space. If you provide it manually, include the collection `modelMatrix` transform yourself.
|
|
194
|
+
- Providing `boundingVolume` skips automatic recomputation; this helps large animated collections but makes you responsible for keeping the volume valid.
|
|
195
|
+
- `blendOption` is supported on all three buffer collections and enables alpha from `BufferPrimitiveMaterial#color`; `BufferPointCollection` also honors `outlineColor.alpha`.
|
|
196
|
+
- Use `BlendOption.OPAQUE` only when every material is fully opaque; use `TRANSLUCENT` or mixed blending when alpha varies.
|
|
197
|
+
|
|
198
|
+
## GeoJsonPrimitive (Experimental, 1.142+)
|
|
199
|
+
|
|
200
|
+
`GeoJsonPrimitive` loads GeoJSON directly into buffer primitive collections,
|
|
201
|
+
bypassing `GeoJsonDataSource` and the Entity layer. Prefer it for large static
|
|
202
|
+
or bulk-updated vector datasets. Keep using `GeoJsonDataSource` when you need
|
|
203
|
+
Entity conveniences, time-dynamic properties, clustering, or DataSource lifecycle
|
|
204
|
+
integration.
|
|
205
|
+
|
|
206
|
+
```js
|
|
207
|
+
import { GeoJsonPrimitive } from "cesium";
|
|
208
|
+
|
|
209
|
+
const counties = await GeoJsonPrimitive.fromUrl("/data/counties.geojson", {
|
|
210
|
+
allowPicking: true,
|
|
211
|
+
});
|
|
212
|
+
scene.primitives.add(counties);
|
|
213
|
+
|
|
214
|
+
console.log(counties.featureCount);
|
|
215
|
+
console.log(counties.points); // BufferPointCollection | undefined
|
|
216
|
+
console.log(counties.polylines); // BufferPolylineCollection | undefined
|
|
217
|
+
console.log(counties.polygons); // BufferPolygonCollection | undefined
|
|
218
|
+
|
|
219
|
+
// Picking returns the GeoJsonPrimitive pick object, including source properties.
|
|
220
|
+
const picked = scene.pick(windowPosition);
|
|
221
|
+
if (picked?.parentPrimitive === counties) {
|
|
222
|
+
const featureId = picked.primitive.featureId;
|
|
223
|
+
console.log(counties.getId(featureId));
|
|
224
|
+
console.log(counties.getProperties(featureId));
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
`GeoJsonPrimitive.fromGeoJson(parsedObject)` is available when the GeoJSON is
|
|
229
|
+
already in memory. Source feature IDs are exposed through `ids`/`getId()`, and
|
|
230
|
+
source properties through `properties`/`getProperties()`.
|
|
231
|
+
|
|
232
|
+
## Built-in Geometry Types (31)
|
|
233
|
+
|
|
234
|
+
All geometries take shape parameters and a `vertexFormat` matching the Appearance. Most have a paired `*OutlineGeometry`. Outlines require a separate Primitive.
|
|
235
|
+
|
|
236
|
+
### Filled + Outline Pattern
|
|
237
|
+
|
|
238
|
+
```js
|
|
239
|
+
import {
|
|
240
|
+
Primitive, GeometryInstance, PolygonGeometry, PolygonOutlineGeometry,
|
|
241
|
+
PolygonHierarchy, PerInstanceColorAppearance, ColorGeometryInstanceAttribute,
|
|
242
|
+
Cartesian3, Color,
|
|
243
|
+
} from "cesium";
|
|
244
|
+
|
|
245
|
+
const positions = Cartesian3.fromDegreesArray([-115, 37, -115, 32, -107, 33, -102, 35]);
|
|
246
|
+
|
|
247
|
+
// Fill primitive
|
|
248
|
+
scene.primitives.add(new Primitive({
|
|
249
|
+
geometryInstances: new GeometryInstance({
|
|
250
|
+
geometry: new PolygonGeometry({
|
|
251
|
+
polygonHierarchy: new PolygonHierarchy(positions),
|
|
252
|
+
vertexFormat: PerInstanceColorAppearance.VERTEX_FORMAT,
|
|
253
|
+
}),
|
|
254
|
+
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.CYAN.withAlpha(0.5)) },
|
|
255
|
+
}),
|
|
256
|
+
appearance: new PerInstanceColorAppearance(),
|
|
257
|
+
}));
|
|
258
|
+
|
|
259
|
+
// Outline primitive (separate draw call)
|
|
260
|
+
scene.primitives.add(new Primitive({
|
|
261
|
+
geometryInstances: new GeometryInstance({
|
|
262
|
+
geometry: new PolygonOutlineGeometry({ polygonHierarchy: new PolygonHierarchy(positions) }),
|
|
263
|
+
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.WHITE) },
|
|
264
|
+
}),
|
|
265
|
+
appearance: new PerInstanceColorAppearance({ flat: true }),
|
|
266
|
+
}));
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Geometry Catalog
|
|
270
|
+
|
|
271
|
+
Every `XxxGeometry` has a matching `XxxOutlineGeometry` unless noted.
|
|
272
|
+
|
|
273
|
+
**Surface** (work with GroundPrimitive): `CircleGeometry`, `CorridorGeometry`, `EllipseGeometry`, `PolygonGeometry`, `RectangleGeometry`.
|
|
274
|
+
|
|
275
|
+
**Volume** (need `modelMatrix`): `BoxGeometry` (`fromDimensions()`), `CylinderGeometry` (cone when topRadius != bottomRadius), `EllipsoidGeometry`, `SphereGeometry`, `FrustumGeometry`, `PlaneGeometry`.
|
|
276
|
+
|
|
277
|
+
**Path**: `CorridorGeometry` (buffered path), `PolylineVolumeGeometry` (2D shape extruded along path), `WallGeometry` (vertical curtain).
|
|
278
|
+
|
|
279
|
+
**Polygon**: `PolygonGeometry` (holes via `PolygonHierarchy`), `CoplanarPolygonGeometry` (non-Earth-surface).
|
|
280
|
+
|
|
281
|
+
**Line** (no outline): `PolylineGeometry` (pixel-width), `SimplePolylineGeometry` (1px), `GroundPolylineGeometry` (GroundPolylinePrimitive only).
|
|
282
|
+
|
|
283
|
+
### Positioning Off-Surface Geometry
|
|
284
|
+
|
|
285
|
+
Box, Ellipsoid, Cylinder, and Frustum need a `modelMatrix` on the GeometryInstance.
|
|
286
|
+
|
|
287
|
+
```js
|
|
288
|
+
import { GeometryInstance, BoxGeometry, PerInstanceColorAppearance,
|
|
289
|
+
ColorGeometryInstanceAttribute, Cartesian3, Matrix4, Transforms, Color } from "cesium";
|
|
290
|
+
|
|
291
|
+
const modelMatrix = Matrix4.multiplyByTranslation(
|
|
292
|
+
Transforms.eastNorthUpToFixedFrame(Cartesian3.fromDegrees(-105, 40)),
|
|
293
|
+
new Cartesian3(0, 0, 250000), new Matrix4(),
|
|
294
|
+
);
|
|
295
|
+
new GeometryInstance({
|
|
296
|
+
geometry: BoxGeometry.fromDimensions({
|
|
297
|
+
dimensions: new Cartesian3(400000, 300000, 500000),
|
|
298
|
+
vertexFormat: PerInstanceColorAppearance.VERTEX_FORMAT,
|
|
299
|
+
}),
|
|
300
|
+
modelMatrix,
|
|
301
|
+
id: "floatingBox",
|
|
302
|
+
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.CORAL) },
|
|
303
|
+
});
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## Appearances (7 Types)
|
|
307
|
+
|
|
308
|
+
| Appearance | Use Case | Material? |
|
|
309
|
+
|---|---|---|
|
|
310
|
+
| `PerInstanceColorAppearance` | Per-instance color | No |
|
|
311
|
+
| `MaterialAppearance` | Arbitrary geometry + Material | Yes |
|
|
312
|
+
| `EllipsoidSurfaceAppearance` | Surface geometry + Material (fewer attrs) | Yes |
|
|
313
|
+
| `PolylineColorAppearance` | Per-instance color polylines | No |
|
|
314
|
+
| `PolylineMaterialAppearance` | Polylines with Material | Yes |
|
|
315
|
+
| `DebugAppearance` | Visualize vertex attributes | No |
|
|
316
|
+
| `Appearance` | Base class / custom shaders | Optional |
|
|
317
|
+
|
|
318
|
+
The geometry `vertexFormat` **must** match the appearance. Use the appearance's static `VERTEX_FORMAT`. For `PerInstanceColorAppearance` without lighting, use `FLAT_VERTEX_FORMAT`.
|
|
319
|
+
|
|
320
|
+
### MaterialAppearance Example
|
|
321
|
+
|
|
322
|
+
```js
|
|
323
|
+
import { Primitive, GeometryInstance, WallGeometry, MaterialAppearance, Material, Cartesian3 } from "cesium";
|
|
324
|
+
|
|
325
|
+
scene.primitives.add(new Primitive({
|
|
326
|
+
geometryInstances: new GeometryInstance({
|
|
327
|
+
geometry: new WallGeometry({
|
|
328
|
+
positions: Cartesian3.fromDegreesArrayHeights([-115, 44, 200000, -110, 44, 200000, -105, 44, 200000]),
|
|
329
|
+
vertexFormat: MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat,
|
|
330
|
+
}),
|
|
331
|
+
}),
|
|
332
|
+
appearance: new MaterialAppearance({
|
|
333
|
+
material: Material.fromType("Checkerboard"),
|
|
334
|
+
faceForward: true, // shade both sides
|
|
335
|
+
}),
|
|
336
|
+
}));
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## GroundPrimitive
|
|
340
|
+
|
|
341
|
+
Drapes geometry onto terrain/3D Tiles. Supported: `CircleGeometry`, `CorridorGeometry`, `EllipseGeometry`, `PolygonGeometry`, `RectangleGeometry`.
|
|
342
|
+
|
|
343
|
+
```js
|
|
344
|
+
import { GroundPrimitive, GeometryInstance, PolygonGeometry, PolygonHierarchy,
|
|
345
|
+
ColorGeometryInstanceAttribute, ClassificationType, Cartesian3, Color } from "cesium";
|
|
346
|
+
|
|
347
|
+
scene.groundPrimitives.add(new GroundPrimitive({
|
|
348
|
+
geometryInstances: new GeometryInstance({
|
|
349
|
+
geometry: new PolygonGeometry({
|
|
350
|
+
polygonHierarchy: new PolygonHierarchy(
|
|
351
|
+
Cartesian3.fromDegreesArray([-112, 36, -112, 36.1, -111.9, 36.1]),
|
|
352
|
+
),
|
|
353
|
+
}),
|
|
354
|
+
id: "groundPolygon",
|
|
355
|
+
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.RED.withAlpha(0.5)) },
|
|
356
|
+
}),
|
|
357
|
+
classificationType: ClassificationType.TERRAIN, // TERRAIN, CESIUM_3D_TILE, or BOTH
|
|
358
|
+
}));
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## GroundPolylinePrimitive
|
|
362
|
+
|
|
363
|
+
```js
|
|
364
|
+
import { GroundPolylinePrimitive, GeometryInstance, GroundPolylineGeometry,
|
|
365
|
+
PolylineColorAppearance, ColorGeometryInstanceAttribute, Cartesian3, Color } from "cesium";
|
|
366
|
+
|
|
367
|
+
scene.groundPrimitives.add(new GroundPolylinePrimitive({
|
|
368
|
+
geometryInstances: new GeometryInstance({
|
|
369
|
+
geometry: new GroundPolylineGeometry({
|
|
370
|
+
positions: Cartesian3.fromDegreesArray([-112.13, 36.05, -112.09, 36.10, -112.13, 36.17]),
|
|
371
|
+
width: 4.0,
|
|
372
|
+
loop: true,
|
|
373
|
+
}),
|
|
374
|
+
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.LIME.withAlpha(0.7)) },
|
|
375
|
+
}),
|
|
376
|
+
appearance: new PolylineColorAppearance(),
|
|
377
|
+
}));
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## ClassificationPrimitive
|
|
381
|
+
|
|
382
|
+
Highlights volumes classifying terrain or 3D Tiles. Valid: `BoxGeometry`, `CylinderGeometry`, `EllipsoidGeometry`, `PolylineVolumeGeometry`, `SphereGeometry`, plus extruded surface geometries.
|
|
383
|
+
|
|
384
|
+
```js
|
|
385
|
+
import { ClassificationPrimitive, GeometryInstance, BoxGeometry, PerInstanceColorAppearance,
|
|
386
|
+
ColorGeometryInstanceAttribute, ClassificationType, Cartesian3, Transforms, Color } from "cesium";
|
|
387
|
+
|
|
388
|
+
scene.primitives.add(new ClassificationPrimitive({
|
|
389
|
+
geometryInstances: new GeometryInstance({
|
|
390
|
+
geometry: BoxGeometry.fromDimensions({
|
|
391
|
+
dimensions: new Cartesian3(100, 100, 50),
|
|
392
|
+
vertexFormat: PerInstanceColorAppearance.VERTEX_FORMAT,
|
|
393
|
+
}),
|
|
394
|
+
modelMatrix: Transforms.eastNorthUpToFixedFrame(Cartesian3.fromDegrees(-75.59, 40.04, 25)),
|
|
395
|
+
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.YELLOW.withAlpha(0.5)) },
|
|
396
|
+
}),
|
|
397
|
+
classificationType: ClassificationType.BOTH,
|
|
398
|
+
}));
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## BillboardCollection
|
|
402
|
+
|
|
403
|
+
GPU-efficient viewport-aligned images -- far more performant than entities at scale.
|
|
404
|
+
|
|
405
|
+
> **Breaking change (1.140, #13253):** `BillboardCollection` and `LabelCollection`
|
|
406
|
+
> now require WebGL 2, or WebGL 1 with `ANGLE_instanced_arrays` and
|
|
407
|
+
> `MAX_VERTEX_TEXTURE_IMAGE_UNITS > 0`. On unsupported devices they no longer
|
|
408
|
+
> render -- gate on `scene.context.webgl2` (or feature-detect the extension) if you
|
|
409
|
+
> still target legacy WebGL 1 hardware.
|
|
410
|
+
|
|
411
|
+
```js
|
|
412
|
+
import { BillboardCollection, Cartesian3, Color, NearFarScalar,
|
|
413
|
+
HeightReference, HorizontalOrigin, VerticalOrigin } from "cesium";
|
|
414
|
+
|
|
415
|
+
const billboards = scene.primitives.add(new BillboardCollection({ scene }));
|
|
416
|
+
const b = billboards.add({
|
|
417
|
+
position: Cartesian3.fromDegrees(-75.59, 40.04),
|
|
418
|
+
image: "marker.png",
|
|
419
|
+
horizontalOrigin: HorizontalOrigin.CENTER,
|
|
420
|
+
verticalOrigin: VerticalOrigin.BOTTOM,
|
|
421
|
+
heightReference: HeightReference.CLAMP_TO_GROUND,
|
|
422
|
+
scaleByDistance: new NearFarScalar(1000, 1.5, 1e7, 0.3),
|
|
423
|
+
});
|
|
424
|
+
b.position = Cartesian3.fromDegrees(-75.60, 40.05); // update dynamically
|
|
425
|
+
billboards.remove(b);
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
## LabelCollection
|
|
429
|
+
|
|
430
|
+
```js
|
|
431
|
+
import { LabelCollection, Cartesian3, Cartesian2, Color, LabelStyle, VerticalOrigin } from "cesium";
|
|
432
|
+
|
|
433
|
+
const labels = scene.primitives.add(new LabelCollection({ scene }));
|
|
434
|
+
labels.add({
|
|
435
|
+
position: Cartesian3.fromDegrees(-75.59, 40.04, 300),
|
|
436
|
+
text: "Philadelphia",
|
|
437
|
+
font: "16px sans-serif",
|
|
438
|
+
fillColor: Color.WHITE,
|
|
439
|
+
outlineColor: Color.BLACK,
|
|
440
|
+
outlineWidth: 2,
|
|
441
|
+
style: LabelStyle.FILL_AND_OUTLINE,
|
|
442
|
+
verticalOrigin: VerticalOrigin.BOTTOM,
|
|
443
|
+
pixelOffset: new Cartesian2(0, -10),
|
|
444
|
+
});
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
## PointPrimitiveCollection
|
|
448
|
+
|
|
449
|
+
```js
|
|
450
|
+
import { PointPrimitiveCollection, Cartesian3, Color, NearFarScalar } from "cesium";
|
|
451
|
+
|
|
452
|
+
const points = scene.primitives.add(new PointPrimitiveCollection());
|
|
453
|
+
points.add({
|
|
454
|
+
position: Cartesian3.fromDegrees(-75.59, 40.04),
|
|
455
|
+
pixelSize: 10,
|
|
456
|
+
color: Color.YELLOW,
|
|
457
|
+
outlineColor: Color.BLACK,
|
|
458
|
+
outlineWidth: 2,
|
|
459
|
+
scaleByDistance: new NearFarScalar(1000, 1.0, 1e7, 0.1),
|
|
460
|
+
});
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
## CloudCollection and PolylineCollection
|
|
464
|
+
|
|
465
|
+
```js
|
|
466
|
+
import { CloudCollection, PolylineCollection, Cartesian3, Cartesian2, Color, Material } from "cesium";
|
|
467
|
+
|
|
468
|
+
// Procedural cumulus clouds
|
|
469
|
+
const clouds = scene.primitives.add(new CloudCollection());
|
|
470
|
+
clouds.add({
|
|
471
|
+
position: Cartesian3.fromDegrees(-75.59, 40.04, 1500),
|
|
472
|
+
scale: new Cartesian2(40, 12),
|
|
473
|
+
maximumSize: new Cartesian3(40, 12, 15),
|
|
474
|
+
slice: 0.36,
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// Low-level polyline collection
|
|
478
|
+
const polylines = scene.primitives.add(new PolylineCollection());
|
|
479
|
+
polylines.add({
|
|
480
|
+
positions: Cartesian3.fromDegreesArray([-75, 40, -70, 42, -65, 38]),
|
|
481
|
+
width: 3.0,
|
|
482
|
+
material: Material.fromType("Color", { color: Color.AQUA }),
|
|
483
|
+
});
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
## Polyline via Primitive
|
|
487
|
+
|
|
488
|
+
```js
|
|
489
|
+
import { Primitive, GeometryInstance, PolylineGeometry, PolylineColorAppearance,
|
|
490
|
+
ColorGeometryInstanceAttribute, Cartesian3, Color, ArcType } from "cesium";
|
|
491
|
+
|
|
492
|
+
scene.primitives.add(new Primitive({
|
|
493
|
+
geometryInstances: new GeometryInstance({
|
|
494
|
+
geometry: new PolylineGeometry({
|
|
495
|
+
positions: Cartesian3.fromDegreesArray([0, 0, 5, 0]),
|
|
496
|
+
width: 10.0,
|
|
497
|
+
vertexFormat: PolylineColorAppearance.VERTEX_FORMAT,
|
|
498
|
+
arcType: ArcType.GEODESIC, // GEODESIC, RHUMB, or NONE
|
|
499
|
+
}),
|
|
500
|
+
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.WHITE) },
|
|
501
|
+
}),
|
|
502
|
+
appearance: new PolylineColorAppearance({ translucent: false }),
|
|
503
|
+
}));
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
## Enums
|
|
507
|
+
|
|
508
|
+
| Enum | Values | Used By |
|
|
509
|
+
|---|---|---|
|
|
510
|
+
| `ArcType` | `GEODESIC`, `RHUMB`, `NONE` | PolylineGeometry, PolygonGeometry |
|
|
511
|
+
| `CornerType` | `ROUNDED`, `MITERED`, `BEVELED` | CorridorGeometry, PolylineVolumeGeometry |
|
|
512
|
+
| `ClassificationType` | `TERRAIN`, `CESIUM_3D_TILE`, `BOTH` | GroundPrimitive, ClassificationPrimitive |
|
|
513
|
+
| `PrimitiveType` | `POINTS`, `LINES`, `TRIANGLES`, etc. | Low-level Geometry |
|
|
514
|
+
| `CloudType` | `CUMULUS` | CloudCollection |
|
|
515
|
+
|
|
516
|
+
## Performance Tips
|
|
517
|
+
|
|
518
|
+
1. **Batch aggressively.** Combine thousands of GeometryInstances into one Primitive for a single draw call.
|
|
519
|
+
2. **Use `PerInstanceColorAppearance`** when each instance only needs a distinct color.
|
|
520
|
+
3. **Set `flat: true`** on PerInstanceColorAppearance when lighting is unneeded; uses `FLAT_VERTEX_FORMAT`.
|
|
521
|
+
4. **Set `allowPicking: false`** on Primitives that will never be picked to save GPU memory.
|
|
522
|
+
5. **Keep `asynchronous: true`** (default). Check `primitive.ready` before accessing instance attributes.
|
|
523
|
+
6. **Prefer fewer large collections** for Billboard, Label, and PointPrimitive. Group by update frequency.
|
|
524
|
+
7. **Use `BlendOption.OPAQUE`** on BillboardCollection/PointPrimitiveCollection when all items are opaque (up to 2x gain).
|
|
525
|
+
8. **Use buffer primitive collections** for large vector data when flyweight updates are acceptable.
|
|
526
|
+
9. **Precompute buffer collection bounding volumes** for large animated collections, but remember they are world-space in 1.142+.
|
|
527
|
+
10. **Use GroundPrimitive** for terrain draping instead of entity `heightReference`.
|
|
528
|
+
11. **Separate fill and outline** into two Primitives -- they cannot share a draw call.
|
|
529
|
+
12. **Match `vertexFormat` exactly** to the appearance to skip unused vertex attribute computation.
|
|
530
|
+
13. **Use `EllipsoidSurfaceAppearance`** over `MaterialAppearance` for surface geometry -- fewer vertex attributes.
|
|
531
|
+
|
|
532
|
+
## See Also
|
|
533
|
+
|
|
534
|
+
- **cesiumjs-entities** -- High-level Entity API wrapping primitives with time-dynamic properties.
|
|
535
|
+
- **cesiumjs-3d-tiles** -- Use `MVTDataProvider` for tiled vector data as runtime 3D Tiles.
|
|
536
|
+
- **cesiumjs-materials-shaders** -- Material (Fabric) system consumed by Appearances, post-processing.
|
|
537
|
+
- **cesiumjs-spatial-math** -- Cartesian3, Matrix4, Transforms, coordinate conversions for positioning geometry.
|