cesium-alpha-earth 1.0.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.
@@ -0,0 +1,374 @@
1
+ import {
2
+ Cartesian3,
3
+ defined,
4
+ RuntimeError,
5
+ VerticalOrigin,
6
+ HorizontalOrigin,
7
+ DistanceDisplayCondition,
8
+ Cartesian2,
9
+ } from "cesium";
10
+ import { getPositionsCenter } from "@/util/getPositionCenters/getPositionCenter";
11
+ import type { GeoJSON } from "geojson";
12
+ import type { GeoJsonLayer } from "..";
13
+ import { GeoJsonLayerType } from "../type";
14
+ import { parseColorToCesium } from "@/util/parseColor";
15
+ export type CrsFunction = (coors: number[]) => Cartesian3;
16
+ export function defaultCrsFunction(coordinates: number[]) {
17
+ return Cartesian3.fromDegrees(coordinates[0], coordinates[1], coordinates[2]);
18
+ }
19
+
20
+ export const crsNames: Record<string, CrsFunction> = {
21
+ "urn:ogc:def:crs:OGC:1.3:CRS84": defaultCrsFunction,
22
+ "EPSG:4326": defaultCrsFunction,
23
+ "urn:ogc:def:crs:EPSG::4326": defaultCrsFunction,
24
+ };
25
+
26
+ export const crsLinkHrefs: Record<string, (properties: any) => CrsFunction> =
27
+ {};
28
+ export const crsLinkTypes: Record<string, (properties: any) => CrsFunction> =
29
+ {};
30
+
31
+ export function coordinatesArrayToCartesianArray(
32
+ coordinates: number[][],
33
+ crsFunction: CrsFunction
34
+ ) {
35
+ const positions: Cartesian3[] = new Array(coordinates.length);
36
+ coordinates.map((coor, i) => {
37
+ positions[i] = crsFunction(coor);
38
+ });
39
+ return positions;
40
+ }
41
+
42
+ type GetKey<T extends { type: string }> = {
43
+ [K in T["type"]]: (
44
+ geoJsonLayer: GeoJsonLayer,
45
+ geoJson: any,
46
+ geometryCollection: any,
47
+ crsFunction: CrsFunction,
48
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
49
+ ) => void;
50
+ };
51
+
52
+ export const geoJsonObjectTypes: GetKey<GeoJSON.GeoJSON> = {
53
+ Feature: processFeature,
54
+ FeatureCollection: processFeatureCollection,
55
+ GeometryCollection: processGeometryCollection,
56
+ LineString: processLineString,
57
+ MultiLineString: processMultiLineString,
58
+ MultiPoint: processMultiPoint,
59
+ MultiPolygon: processMultiPolygon,
60
+ Point: processPoint,
61
+ Polygon: processPolygon,
62
+ };
63
+
64
+ export const geometryTypes: GetKey<GeoJSON.Geometry> = {
65
+ GeometryCollection: processGeometryCollection,
66
+ LineString: processLineString,
67
+ MultiLineString: processMultiLineString,
68
+ MultiPoint: processMultiPoint,
69
+ MultiPolygon: processMultiPolygon,
70
+ Point: processPoint,
71
+ Polygon: processPolygon,
72
+ };
73
+
74
+ export function processFeature(
75
+ geoJsonLayer: GeoJsonLayer,
76
+ feature: GeoJSON.Feature,
77
+ notUsed: GeoJSON.Feature | undefined,
78
+ crsFunction: CrsFunction,
79
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
80
+ ) {
81
+ if (feature.geometry === null) {
82
+ return;
83
+ }
84
+
85
+ if (!defined(feature.geometry)) {
86
+ throw new RuntimeError("feature.geometry is required.");
87
+ }
88
+
89
+ const geometryType = feature.geometry.type;
90
+ const geometryHandler = geometryTypes[geometryType];
91
+ if (!defined(geometryHandler)) {
92
+ throw new RuntimeError(`Unknown geometry type: ${geometryType}`);
93
+ }
94
+ geometryHandler(
95
+ geoJsonLayer,
96
+ feature,
97
+ feature.geometry,
98
+ crsFunction,
99
+ options
100
+ );
101
+ }
102
+
103
+ export function processFeatureCollection(
104
+ geoJsonLayer: GeoJsonLayer,
105
+ featureCollection: GeoJSON.FeatureCollection,
106
+ notUsed: GeoJSON.FeatureCollection,
107
+ crsFunction: CrsFunction,
108
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
109
+ ) {
110
+ const features = featureCollection.features;
111
+ features.map((feature) => {
112
+ processFeature(geoJsonLayer, feature, undefined, crsFunction, options);
113
+ });
114
+ }
115
+
116
+ export function processGeometryCollection(
117
+ geoJsonLayer: GeoJsonLayer,
118
+ geoJson: GeoJSON,
119
+ geometryCollection: GeoJSON.GeometryCollection,
120
+ crsFunction: CrsFunction,
121
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
122
+ ) {
123
+ const geometries = geometryCollection.geometries;
124
+ geometries.map((geometry) => {
125
+ const geometryType = geometry.type;
126
+ const geometryHandler = geometryTypes[geometryType];
127
+ if (!defined(geometryHandler)) {
128
+ throw new RuntimeError(`Unknown geometry type: ${geometryType}`);
129
+ }
130
+ geometryHandler(geoJsonLayer, geoJson, geometry, crsFunction, options);
131
+ });
132
+ }
133
+
134
+ export function createPoint(
135
+ geoJsonLayer: GeoJsonLayer,
136
+ geoJson: GeoJSON.Feature,
137
+ crsFunction: CrsFunction,
138
+ coordinates: number[],
139
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
140
+ ) {
141
+ const symbol = options.pointSymbol;
142
+ const color = options.pointSymbol;
143
+ const size = options.pointSize;
144
+ const properties = geoJson.properties ?? {};
145
+ const labelDistanceDisplay = options.labelDistanceDisplay ?? [0, 5000];
146
+ const labelColor = options.labelColor ?? "red";
147
+ if (!symbol) {
148
+ geoJsonLayer.addPoint({
149
+ type: "Point",
150
+ position: crsFunction(coordinates),
151
+ uid: geoJsonLayer._generateId(),
152
+ style: {
153
+ color: color,
154
+ pixelSize: size,
155
+ },
156
+ properties,
157
+ });
158
+ } else {
159
+ const billboard = geoJsonLayer.addBillboard({
160
+ type: "Billboard",
161
+ position: crsFunction(coordinates),
162
+ uid: geoJsonLayer._generateId(),
163
+ style: {
164
+ verticalOrigin: VerticalOrigin.BOTTOM,
165
+ image: symbol,
166
+ width: size,
167
+ height: size,
168
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
169
+ },
170
+ properties,
171
+ });
172
+ }
173
+ if (options.pointLabelFields) {
174
+ geoJsonLayer.addLabel({
175
+ type: "Label",
176
+ position: crsFunction(coordinates),
177
+ uid: geoJsonLayer._generateId(),
178
+ style: {
179
+ font: options.labelFont,
180
+ verticalOrigin: VerticalOrigin.CENTER,
181
+ horizontalOrigin: HorizontalOrigin.CENTER,
182
+ pixelOffset: new Cartesian2(
183
+ options.pixelOffset[0],
184
+ options.pixelOffset[1]
185
+ ),
186
+ fillColor: parseColorToCesium(labelColor),
187
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
188
+ distanceDisplayCondition: new DistanceDisplayCondition(
189
+ labelDistanceDisplay[0],
190
+ labelDistanceDisplay[1]
191
+ ),
192
+ text: properties[options.pointLabelFields],
193
+ },
194
+ });
195
+ }
196
+ }
197
+
198
+ export function processPoint(
199
+ geoJsonLayer: GeoJsonLayer,
200
+ geoJson: GeoJSON.Feature,
201
+ geometry: GeoJSON.Point,
202
+ crsFunction: CrsFunction,
203
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
204
+ ) {
205
+ createPoint(
206
+ geoJsonLayer,
207
+ geoJson,
208
+ crsFunction,
209
+ geometry.coordinates,
210
+ options
211
+ );
212
+ }
213
+
214
+ export function processMultiPoint(
215
+ geoJsonLayer: GeoJsonLayer,
216
+ geoJson: GeoJSON.Feature,
217
+ geometry: GeoJSON.MultiPoint,
218
+ crsFunction: CrsFunction,
219
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
220
+ ) {
221
+ geometry.coordinates.map((coor) =>
222
+ createPoint(geoJsonLayer, geoJson, crsFunction, coor, options)
223
+ );
224
+ }
225
+
226
+ export function createLineString(
227
+ geoJsonLayer: GeoJsonLayer,
228
+ geoJson: GeoJSON.Feature,
229
+ crsFunction: CrsFunction,
230
+ coordinates: number[][],
231
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
232
+ ) {
233
+ const properties = geoJson.properties ?? {};
234
+ const positions = coordinatesArrayToCartesianArray(coordinates, crsFunction);
235
+ const labelColor = options.labelColor;
236
+ const labelDistanceDisplay = options.labelDistanceDisplay ?? [0, 5000];
237
+ geoJsonLayer.addPolyline({
238
+ type: "Polyline",
239
+ uid: geoJsonLayer._generateId(),
240
+ positions,
241
+ properties,
242
+ style: {
243
+ material: options.lineColor,
244
+ width: options.lineWidth,
245
+ },
246
+ });
247
+
248
+ // positions.forEach((point) => {
249
+ // geoJsonLayer.labelCollection.add({
250
+ // position: point,
251
+ // font: options.labelFont,
252
+ // verticalOrigin: VerticalOrigin.CENTER,
253
+ // horizontalOrigin: HorizontalOrigin.CENTER,
254
+ // pixelOffset: new Cartesian2(options.pixelOffset[0], options.pixelOffset[1]),
255
+ // fillColor: parseColorToCesium(labelColor),
256
+ // disableDepthTestDistance: Number.POSITIVE_INFINITY,
257
+ // distanceDisplayCondition: new DistanceDisplayCondition(labelDistanceDisplay[0], labelDistanceDisplay[1]),
258
+ // text: properties[options.lineLabelFields]
259
+ // })
260
+ // })
261
+ }
262
+
263
+ export function processLineString(
264
+ geoJsonLayer: GeoJsonLayer,
265
+ geoJson: GeoJSON.Feature,
266
+ geometry: GeoJSON.LineString,
267
+ crsFunction: CrsFunction,
268
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
269
+ ) {
270
+ createLineString(
271
+ geoJsonLayer,
272
+ geoJson,
273
+ crsFunction,
274
+ geometry.coordinates,
275
+ options
276
+ );
277
+ }
278
+
279
+ export function processMultiLineString(
280
+ geoJsonLayer: GeoJsonLayer,
281
+ geoJson: GeoJSON.Feature,
282
+ geometry: GeoJSON.MultiLineString,
283
+ crsFunction: CrsFunction,
284
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
285
+ ) {
286
+ const lineStrings = geometry.coordinates;
287
+ let geometryLine: any[] = [];
288
+ lineStrings.map((lineString) => {
289
+ geometryLine.push(...lineString);
290
+ });
291
+ createLineString(geoJsonLayer, geoJson, crsFunction, geometryLine, options);
292
+ }
293
+
294
+ export function createPolygon(
295
+ geoJsonLayer: GeoJsonLayer,
296
+ geoJson: GeoJSON.Feature,
297
+ crsFunction: CrsFunction,
298
+ coordinates: GeoJSON.Position[][],
299
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
300
+ ) {
301
+ if (coordinates.length === 0 || coordinates[0].length === 0) {
302
+ return;
303
+ }
304
+ const properties = geoJson.properties ?? {};
305
+ const labelDistanceDisplay = options.labelDistanceDisplay ?? [0, 5000];
306
+ const labelColor = options.labelColor ?? "red";
307
+ const cartesian3Coords = coordinates.map((it) =>
308
+ coordinatesArrayToCartesianArray(it, crsFunction)
309
+ );
310
+ geoJsonLayer.addPolygon({
311
+ type: "Polygon",
312
+ positions: cartesian3Coords[0],
313
+ holes: cartesian3Coords.slice(1),
314
+ uid: geoJsonLayer._generateId(),
315
+ style: {
316
+ material: options.gonColor,
317
+ },
318
+ properties,
319
+ });
320
+ if (options.gonLabelFields) {
321
+ geoJsonLayer.addLabel({
322
+ type: "Label",
323
+ position: getPositionsCenter(cartesian3Coords[0], 500).cartesian3,
324
+ uid: geoJsonLayer._generateId(),
325
+ style: {
326
+ font: options.labelFont,
327
+ verticalOrigin: VerticalOrigin.CENTER,
328
+ horizontalOrigin: HorizontalOrigin.CENTER,
329
+ pixelOffset: new Cartesian2(
330
+ options.pixelOffset[0],
331
+ options.pixelOffset[1]
332
+ ),
333
+ fillColor: parseColorToCesium(labelColor),
334
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
335
+ distanceDisplayCondition: new DistanceDisplayCondition(
336
+ labelDistanceDisplay[0],
337
+ labelDistanceDisplay[1]
338
+ ),
339
+ text: properties[options.gonLabelFields],
340
+ },
341
+ });
342
+ }
343
+ }
344
+
345
+ export function processPolygon(
346
+ geoJsonLayer: GeoJsonLayer,
347
+ geoJson: GeoJSON.Feature,
348
+ geometry: GeoJSON.Polygon,
349
+ crsFunction: CrsFunction,
350
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
351
+ ) {
352
+ createPolygon(
353
+ geoJsonLayer,
354
+ geoJson,
355
+ crsFunction,
356
+ geometry.coordinates,
357
+ options
358
+ );
359
+ }
360
+
361
+ export function processMultiPolygon(
362
+ geoJsonLayer: GeoJsonLayer,
363
+ geoJson: GeoJSON.Feature,
364
+ geometry: GeoJSON.MultiPolygon,
365
+ crsFunction: CrsFunction,
366
+ options: Required<GeoJsonLayerType.GeoJsonLayerOptions>
367
+ ) {
368
+ const polygons = geometry.coordinates;
369
+ let polygonGeo: any[] = [];
370
+ polygons.map((polygon) => {
371
+ polygonGeo.push(...polygon)
372
+ });
373
+ createPolygon(geoJsonLayer, geoJson, crsFunction, polygonGeo, options);
374
+ }
@@ -0,0 +1,108 @@
1
+ import * as Cesium from "cesium";
2
+ export declare namespace GeoJsonLayerType {
3
+ type GeoJsonLayerOptions = {
4
+ name?: string;
5
+ sourceUri?: string;
6
+ pointSize?: number;
7
+ pointSymbol?: string;
8
+ pointColor?: string;
9
+ pointLabelFields?: string;
10
+ pointClampToGround?: boolean;
11
+ lineColor?: string;
12
+ lineWidth?: number;
13
+ lineClampToGround?: boolean;
14
+ lineLabelFields?: string;
15
+ lineMaterial?: Cesium.Material;
16
+ gonColor?: string;
17
+ gonLabelFields?: string;
18
+ gonClampToGround?: boolean;
19
+ labelDistanceDisplay?: [number, number];
20
+ labelColor?: string;
21
+ labelFont?: string;
22
+ pixelOffset?: [number, number];
23
+ showLevel?: number;
24
+ zIndex?: number;
25
+ depthTest?: boolean;
26
+ bathSize?: number;
27
+ show?: boolean;
28
+ finishFun?: Function;
29
+ allowPick?: boolean;
30
+ popupType?: LayerPopupType;
31
+ popupShowFields?: string[];
32
+ fieldsAlias?: Array<{
33
+ name: string;
34
+ alias: string;
35
+ [key: string]: any;
36
+ }>;
37
+ };
38
+
39
+ type LayerPopupType = "attribute" | "rtsp";
40
+
41
+ type PrimitiveItem =
42
+ | PointPrimitiveItem
43
+ | BillboardPrimitiveItem
44
+ | PolygonPrimitiveItem
45
+ | PolylinePrimitiveItem
46
+ | LabelPrimitiveItem;
47
+
48
+ type GeoJsonFeatureItem = {
49
+ id?: any;
50
+ properties?: Record<string, any>;
51
+ uid: string;
52
+ center?: {
53
+ cartesian3: Cesium.Cartesian3;
54
+ height?: number;
55
+ };
56
+ };
57
+
58
+ type PointPrimitiveItem = {
59
+ type: "Point";
60
+ position: Cesium.Cartesian3;
61
+ style?: {
62
+ pixelSize?: number;
63
+ heightReference?: Cesium.HeightReference;
64
+ color?: string;
65
+ outlineColor?: string;
66
+ outlineWidth?: number;
67
+ };
68
+ instance?: Cesium.PointPrimitive;
69
+ } & GeoJsonFeatureItem;
70
+
71
+ type BillboardPrimitiveItem = {
72
+ type: "Billboard";
73
+ position: Cesium.Cartesian3;
74
+ style?: Cesium.BillboardGraphics.ConstructorOptions;
75
+ instance?: Cesium.Billboard;
76
+ } & GeoJsonFeatureItem;
77
+
78
+ type LabelPrimitiveItem = {
79
+ type: "Label";
80
+ position: Cesium.Cartesian3;
81
+ style?: Cesium.LabelGraphics.ConstructorOptions;
82
+ instance?: Cesium.Label;
83
+ } & GeoJsonFeatureItem;
84
+
85
+ type PolygonPrimitiveItem = {
86
+ type: "Polygon";
87
+ positions: Cesium.Cartesian3[];
88
+ holes: Cesium.Cartesian3[][];
89
+ style?: {
90
+ material?: string;
91
+ height?: number;
92
+ extrudedHeight?: number;
93
+ outlineColor?: string;
94
+ outlineWidth?: number;
95
+ };
96
+ instance?: Cesium.PolygonGeometry;
97
+ } & GeoJsonFeatureItem;
98
+
99
+ type PolylinePrimitiveItem = {
100
+ type: "Polyline";
101
+ positions: Cesium.Cartesian3[];
102
+ style?: {
103
+ material?: string;
104
+ width?: number;
105
+ };
106
+ instance?: Cesium.PolylineGeometry | Cesium.GroundPolylineGeometry;
107
+ } & GeoJsonFeatureItem;
108
+ }
@@ -0,0 +1,106 @@
1
+ import {
2
+ Cartesian3,
3
+ Cartographic,
4
+ Cesium3DTileset,
5
+ EllipsoidTerrainProvider,
6
+ sampleTerrainMostDetailed,
7
+ Viewer,
8
+ } from "cesium";
9
+ import {
10
+ ViewerOption,
11
+ FlyToOptionType,
12
+ FlyToTargetType,
13
+ LayerInfoOption,
14
+ ModelInfoOption,
15
+ } from "./type";
16
+ import { createViewer } from "./method/createViewer";
17
+ import { goTo } from "./method/goTo";
18
+ import { GeoJsonLayer } from "../CesiumAlphaGeoJsonLayer";
19
+ import { enableCluster } from "./method/clusterFun";
20
+ import { load3DtilestModel } from "./method/load3DtilestModel";
21
+ import { loadGeoJsonLayer } from "./method/loadGeoJsonLayer";
22
+ import { toRaw } from "vue";
23
+
24
+ export default class CesiumAlphaViewer {
25
+ private _layerDatasource: GeoJsonLayer[] = [];
26
+
27
+ viewer: Viewer;
28
+
29
+ private _modelDatasource: any;
30
+
31
+ get modelDatasource() {
32
+ return this._modelDatasource;
33
+ }
34
+
35
+ get layerDatasource() {
36
+ return this._layerDatasource;
37
+ }
38
+
39
+ constructor(container: string | HTMLElement, option?: ViewerOption) {
40
+ this.viewer = createViewer(container, option);
41
+ }
42
+
43
+ //飞向目标
44
+ public goTo(target: FlyToTargetType, flyToOption?: FlyToOptionType): void {
45
+ if (this.viewer) goTo(this.viewer, target, flyToOption);
46
+ }
47
+
48
+ //开启图层聚合
49
+ public enableLayerCluster(layer: GeoJsonLayer) {
50
+ layer.cluster = enableCluster(this, layer);
51
+ return layer.cluster;
52
+ }
53
+
54
+ //关闭图层聚合
55
+ public closeLayerCluster(layer: GeoJsonLayer) {
56
+ layer.show = true;
57
+
58
+ layer.cluster.get(0).destroy();
59
+
60
+ layer.cluster = undefined;
61
+
62
+ return true;
63
+ }
64
+
65
+ //加载3D模型
66
+ public load3DtilestModel(modelInfo: ModelInfoOption[]) {
67
+ return load3DtilestModel(this, modelInfo);
68
+ }
69
+
70
+ //根据UID寻找图层
71
+ public findLayerByUID(uid: string): GeoJsonLayer | undefined {
72
+ return this._layerDatasource.find((layer) => {
73
+ return layer.layerId == uid;
74
+ });
75
+ }
76
+
77
+ public async loadGeoJsonLayer(layerInfo: LayerInfoOption[]) {
78
+ return loadGeoJsonLayer(this, layerInfo);
79
+ }
80
+
81
+ //根据图层ID移除图层
82
+ public removeLayerById(layerId: string) {
83
+ this.layerDatasource?.forEach((item: GeoJsonLayer, index: number) => {
84
+ if (item.layerId == layerId) {
85
+ item.destroy();
86
+ //@ts-ignore
87
+ this.layerDatasource.splice(index, 1);
88
+ }
89
+ });
90
+ }
91
+
92
+ //重置当前场景
93
+ resetScene() {
94
+ this._layerDatasource.forEach((layer: GeoJsonLayer) => {
95
+ layer.destroy();
96
+ });
97
+ this._layerDatasource = [];
98
+
99
+ this._modelDatasource.forEach((model: Cesium3DTileset) => {
100
+ this.viewer?.scene.primitives.remove(model);
101
+ });
102
+ this._modelDatasource = [];
103
+ }
104
+
105
+
106
+ }
@@ -0,0 +1,116 @@
1
+ import { GeoJsonLayer } from "../layer/GeoJsonLayer";
2
+ import * as Cesium from "cesium"
3
+ import PrimitiveCluster from "@/util/PrimitiveCuster/index.js"
4
+ import { EarthViewMap } from "./EarthViewMap";
5
+ export function enableCluster(that:EarthViewMap,layer: GeoJsonLayer) {
6
+ layer.show = false
7
+ // 使用primitives 添加点
8
+ var labels = new Cesium.LabelCollection()
9
+ var billboards = new Cesium.BillboardCollection()
10
+ var collection = new Cesium.PrimitiveCollection()
11
+
12
+ for (let i = 0; i < layer.billboardCollection.length; i++) {
13
+ let element = layer.billboardCollection.get(i)
14
+
15
+ let center = element.position
16
+
17
+ let title = {
18
+ id: element.id,
19
+ position: center,
20
+ font: "30px Source Han Sans CN", //字体样式
21
+ fillColor: Cesium.Color.fromCssColorString("#ffffff"), //字体颜色
22
+ showBackground: true, //是否显示背景颜色
23
+ backgroundColor: Cesium.Color.fromCssColorString("#000000"), //背景颜色
24
+ verticalOrigin: Cesium.VerticalOrigin.CENTER, //垂直位置
25
+ horizontalOrigin: Cesium.HorizontalOrigin.CENTER, //水平位置
26
+ disableDepthTestDistance: Number.POSITIVE_INFINITY
27
+ }
28
+
29
+ let img = {
30
+ id: element.id,
31
+ position: center,
32
+ image: element.image,
33
+ width: 50,
34
+ height: 50,
35
+ scale: 1,
36
+ verticalOrigin: Cesium.VerticalOrigin.CENTER, //垂直位置
37
+ horizontalOrigin: Cesium.HorizontalOrigin.CENTER, //水平位置
38
+ disableDepthTestDistance: Number.POSITIVE_INFINITY
39
+ }
40
+ labels.add(title)
41
+ billboards.add(img)
42
+ }
43
+
44
+ let primitivecluster = null
45
+ primitivecluster = new PrimitiveCluster()
46
+ primitivecluster.enabled = true
47
+ primitivecluster.pixelRange = 60
48
+ primitivecluster.minimumClusterSize = 2
49
+ primitivecluster._billboardCollection = billboards
50
+ // 同时在赋值时调用_initialize方法
51
+ primitivecluster._initialize(that.viewer?.scene)
52
+ collection.add(primitivecluster)
53
+ let primitivesCluster = that.viewer?.scene.primitives.add(collection)
54
+ primitivecluster.clusterEvent.addEventListener((clusteredEntities: any, cluster: any) => {
55
+
56
+ if (that.viewer) {
57
+ if (that.viewer.scene.camera.positionCartographic.height < 30000) {
58
+ primitivecluster.show = false
59
+ layer.show = true
60
+ } else {
61
+ primitivecluster.show = true
62
+ layer.show = false
63
+ }
64
+ }
65
+
66
+ // 关闭自带的显示聚合数量的标签
67
+ cluster.label.show = false;
68
+ cluster.billboard.show = true;
69
+ cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
70
+ // 根据聚合数量的多少设置不同层级的图片以及大小
71
+ cluster.billboard.image = combineIconAndLabel(
72
+ layer.option.pointSymbol || "",
73
+ clusteredEntities.length,
74
+ 64
75
+ );
76
+ cluster.billboard.disableDepthTestDistance = Number.POSITIVE_INFINITY
77
+ cluster.billboard._imageHeight = 30;
78
+ cluster.billboard._imageWidth = 30;
79
+ cluster.billboard._dirty = false;
80
+ cluster.billboard.width = 40;
81
+ cluster.billboard.height = 40;
82
+ })
83
+
84
+ return primitivesCluster
85
+ }
86
+
87
+
88
+
89
+ export function combineIconAndLabel(url: string, label: string, size: number) {
90
+ // 创建画布对象
91
+ let canvas = document.createElement("canvas");
92
+ canvas.width = size;
93
+ canvas.height = size;
94
+ let ctx = canvas.getContext("2d");
95
+ let promise: any = Cesium.Resource.fetchImage({ url })?.then((image: any) => {
96
+ // 异常判断
97
+ try {
98
+ ctx?.drawImage(image, 0, 0, canvas.width, canvas.height);
99
+ } catch (e) {
100
+ console.log(e);
101
+ }
102
+
103
+ if (ctx) {
104
+ // 渲染字体
105
+ // font属性设置顺序:font-style, font-variant, font-weight, font-size, line-height, font-family
106
+ ctx.fillStyle = Cesium.Color.BLACK.toCssColorString();
107
+ ctx.font = "bold 20px Microsoft YaHei";
108
+ ctx.textAlign = "center";
109
+ ctx.textBaseline = "middle";
110
+ ctx.fillText(label, size / 2, size / 2);
111
+ }
112
+
113
+ return canvas;
114
+ });
115
+ return promise;
116
+ }