drone_view 3.0.18 → 3.0.20
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/.vscode/settings.json +3 -0
- package/dist/514.droneView.js +1 -1
- package/dist/800.droneView.js +1 -1
- package/dist/droneView.js +1 -1
- package/package.json +1 -1
- package/src/app.interface.ts +684 -0
- package/src/droneView.ts +1070 -0
- package/src/event.ts +359 -0
- package/src/layers/annotation.ts +175 -0
- package/src/layers/droneImages.ts +199 -0
- package/src/layers/editLine.ts +521 -0
- package/src/layers/editPoint.ts +345 -0
- package/src/layers/editPolygon.ts +511 -0
- package/src/layers/line.ts +210 -0
- package/src/layers/marker.ts +333 -0
- package/src/layers/marker3d.ts +326 -0
- package/src/layers/model.ts +253 -0
- package/src/layers/note.ts +333 -0
- package/src/layers/ortho.ts +76 -0
- package/src/layers/polygon.ts +218 -0
- package/src/measurement.ts +374 -0
- package/src/utility.ts +802 -0
@@ -0,0 +1,333 @@
|
|
1
|
+
import {
|
2
|
+
Cartesian2,
|
3
|
+
Color,
|
4
|
+
CustomDataSource,
|
5
|
+
BillboardGraphics,
|
6
|
+
Math as cMath,
|
7
|
+
HeadingPitchRange,
|
8
|
+
Cartesian3,
|
9
|
+
HeightReference,
|
10
|
+
VerticalOrigin,
|
11
|
+
} from "cesium";
|
12
|
+
|
13
|
+
import type CesiumView from "../droneView";
|
14
|
+
|
15
|
+
import { MarkerData, MarkerIcon, MarkerOptions } from "../app.interface";
|
16
|
+
import { addLabel } from "../utility";
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Use this class to create a marker layer
|
20
|
+
* @param {MapBox} mapObject - The mapbox map object
|
21
|
+
* @param {string} uniqueName - The unique name of the layer
|
22
|
+
* @param {MarkerData[]} data - The data to be used in the layer
|
23
|
+
* @param {MarkerOptions} options - The options for the layer (see {@link MarkerOptions})
|
24
|
+
*/
|
25
|
+
|
26
|
+
export default class MarkerLayer {
|
27
|
+
markerLayerId: string;
|
28
|
+
|
29
|
+
icons: BillboardGraphics[] = [];
|
30
|
+
|
31
|
+
markerSize: number = 12.5;
|
32
|
+
|
33
|
+
allowSVGs: boolean = false;
|
34
|
+
|
35
|
+
opacity: number;
|
36
|
+
|
37
|
+
layer: CustomDataSource;
|
38
|
+
|
39
|
+
/**
|
40
|
+
* @param mapObject CesiumView map object
|
41
|
+
* @param uniqueName string unique name for the layer
|
42
|
+
* @param data Array<MarkerData>
|
43
|
+
* @param options MarkerOptions
|
44
|
+
*/
|
45
|
+
constructor(
|
46
|
+
public mapObject: CesiumView,
|
47
|
+
public uniqueName: string,
|
48
|
+
public data: Array<MarkerData>,
|
49
|
+
public options: MarkerOptions
|
50
|
+
) {
|
51
|
+
this.markerLayerId = `marker-layer-${this.uniqueName}`;
|
52
|
+
|
53
|
+
this.opacity = 1;
|
54
|
+
|
55
|
+
this.allowSVGs = true;
|
56
|
+
const agent = navigator.userAgent.toLowerCase();
|
57
|
+
if (
|
58
|
+
(typeof this.options.allowSVGs !== "undefined" &&
|
59
|
+
!this.options.allowSVGs) ||
|
60
|
+
(agent.indexOf("chrome") === -1 &&
|
61
|
+
(agent.indexOf("edg") !== -1 ||
|
62
|
+
agent.indexOf("edge") !== -1 ||
|
63
|
+
agent.indexOf("msie") !== -1 ||
|
64
|
+
agent.indexOf("trident") > -1 ||
|
65
|
+
agent.indexOf("firefox") > -1 ||
|
66
|
+
agent.indexOf("safari") > -1))
|
67
|
+
) {
|
68
|
+
this.allowSVGs = false;
|
69
|
+
}
|
70
|
+
|
71
|
+
// load icons before adding marker on map
|
72
|
+
this.loadIcons().then(() => {
|
73
|
+
this.buildLayer();
|
74
|
+
this.add(this.data).then(() => {
|
75
|
+
if (this.options.setBounds === undefined || this.options.setBounds) {
|
76
|
+
this.setBounds();
|
77
|
+
}
|
78
|
+
this.addListeners();
|
79
|
+
});
|
80
|
+
});
|
81
|
+
}
|
82
|
+
|
83
|
+
/** To initialize layer */
|
84
|
+
public buildLayer(): void {
|
85
|
+
if (
|
86
|
+
this.mapObject.viewer.dataSources.getByName("marker" + this.uniqueName)
|
87
|
+
) {
|
88
|
+
this.mapObject.viewer.dataSources.remove(
|
89
|
+
this.mapObject.viewer.dataSources.getByName(
|
90
|
+
"marker" + this.uniqueName
|
91
|
+
)[0],
|
92
|
+
true
|
93
|
+
);
|
94
|
+
}
|
95
|
+
this.layer = new CustomDataSource("marker" + this.uniqueName);
|
96
|
+
}
|
97
|
+
|
98
|
+
/** To add layer on map */
|
99
|
+
public add(data: MarkerData[]) {
|
100
|
+
const self = this;
|
101
|
+
|
102
|
+
return new Promise<void>((resolve) => {
|
103
|
+
self.addToMap(data).then(() => {
|
104
|
+
this.mapObject.viewer.dataSources.add(this.layer);
|
105
|
+
|
106
|
+
this.mapObject.viewer.scene.requestRender();
|
107
|
+
resolve();
|
108
|
+
});
|
109
|
+
});
|
110
|
+
}
|
111
|
+
|
112
|
+
/**
|
113
|
+
*
|
114
|
+
* @param { MarkerData[] } data - load data on map
|
115
|
+
* @returns { void }
|
116
|
+
*/
|
117
|
+
public async addToMap(data: MarkerData[]): Promise<void> {
|
118
|
+
const cartesians: any = [];
|
119
|
+
const cartesiansWith3D: any = [];
|
120
|
+
|
121
|
+
data.forEach((point: any) => {
|
122
|
+
if (point.point[2])
|
123
|
+
{
|
124
|
+
cartesiansWith3D.push(Cartesian3.fromDegrees(point.point[0], point.point[1], point.point[2]));
|
125
|
+
}
|
126
|
+
else{
|
127
|
+
cartesians.push(Cartesian3.fromDegrees(point.point[0], point.point[1]));
|
128
|
+
}
|
129
|
+
});
|
130
|
+
|
131
|
+
const addMarkers = (positions: Cartesian3[]): void => {
|
132
|
+
positions.forEach((position: Cartesian3, i: number) => {
|
133
|
+
const iconIndex = Object.keys(this.options.icons).findIndex(
|
134
|
+
(icon) =>
|
135
|
+
icon === data[i].properties.icon ||
|
136
|
+
(this.options.icons[+icon] &&
|
137
|
+
this.options.icons[+icon].name === data[i].properties.icon)
|
138
|
+
);
|
139
|
+
|
140
|
+
if (iconIndex >= 0) {
|
141
|
+
const selected_icon_src = this.options.icons[+iconIndex].src
|
142
|
+
for (const hash of this.icons) {
|
143
|
+
const billBoardSource = (hash.image as any)._value;
|
144
|
+
if (billBoardSource === selected_icon_src){
|
145
|
+
const pin = {
|
146
|
+
position,
|
147
|
+
billboard: hash,
|
148
|
+
label : {
|
149
|
+
text: (data[i].properties.label || ''),
|
150
|
+
font : '16px sans-serif',
|
151
|
+
eyeOffset : Cartesian3.ZERO,
|
152
|
+
showBackground: true,
|
153
|
+
pixelOffset : new Cartesian2(0,-20),
|
154
|
+
data: data[i].properties,
|
155
|
+
layerId: this.markerLayerId,
|
156
|
+
},
|
157
|
+
data: data[i].properties,
|
158
|
+
layerId: this.markerLayerId,
|
159
|
+
};
|
160
|
+
this.layer.entities.add(pin);
|
161
|
+
}
|
162
|
+
}
|
163
|
+
}
|
164
|
+
});
|
165
|
+
};
|
166
|
+
|
167
|
+
addMarkers(cartesiansWith3D);
|
168
|
+
const updatedCartesiansWith3D = await this.mapObject.viewer.scene.clampToHeightMostDetailed(cartesians);
|
169
|
+
addMarkers(updatedCartesiansWith3D);
|
170
|
+
}
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Loads all specified marker icons and adds them to the map. Icons must be loaded before they can be used.
|
174
|
+
*/
|
175
|
+
private loadIcons() {
|
176
|
+
const self = this;
|
177
|
+
return new Promise<void>((resolve) => {
|
178
|
+
const loadCommands: any = [];
|
179
|
+
const { icons } = self.options;
|
180
|
+
|
181
|
+
Object.keys(icons).forEach((iconID: any) => {
|
182
|
+
if (iconID !== "contains") {
|
183
|
+
console.log(icons[iconID]);
|
184
|
+
loadCommands.push(self.load(icons[iconID]));
|
185
|
+
}
|
186
|
+
});
|
187
|
+
Promise.all(loadCommands)
|
188
|
+
.then(() => {
|
189
|
+
resolve();
|
190
|
+
})
|
191
|
+
.catch(() => {
|
192
|
+
const loadingElement = document.getElementById("main-loading");
|
193
|
+
if (loadingElement) {
|
194
|
+
loadingElement.style.display = "none";
|
195
|
+
}
|
196
|
+
});
|
197
|
+
});
|
198
|
+
}
|
199
|
+
|
200
|
+
/**
|
201
|
+
*
|
202
|
+
* @param { MarkerIcon } icon - create bill board from icons
|
203
|
+
* @returns { void }
|
204
|
+
*/
|
205
|
+
load(icon: MarkerIcon) {
|
206
|
+
const self = this;
|
207
|
+
return new Promise<void>((resolve) => {
|
208
|
+
let url = icon.src;
|
209
|
+
if (
|
210
|
+
this.options.allowSVGs &&
|
211
|
+
(typeof icon.options.allowSVG === "undefined" || icon.options.allowSVG)
|
212
|
+
) {
|
213
|
+
url = url.replace(".png", ".svg");
|
214
|
+
}
|
215
|
+
const { pixelRatio } = icon.options;
|
216
|
+
console.log(url);
|
217
|
+
|
218
|
+
const image: any = new Image();
|
219
|
+
const visibility = icon?.options?.deficiency === true ? 0 : Number.POSITIVE_INFINITY
|
220
|
+
image.onload = function () {
|
221
|
+
self.icons.push(
|
222
|
+
new BillboardGraphics({
|
223
|
+
image: url,
|
224
|
+
color: Color.WHITE.withAlpha(self.opacity || 1),
|
225
|
+
disableDepthTestDistance: visibility,
|
226
|
+
verticalOrigin: VerticalOrigin.BASELINE,
|
227
|
+
pixelOffset : new Cartesian2(0,-30),
|
228
|
+
width: this.width / +(pixelRatio || 4),
|
229
|
+
height: this.height / +(pixelRatio || 4),
|
230
|
+
rotation: cMath.toRadians(self.options.rotate || 0),
|
231
|
+
})
|
232
|
+
);
|
233
|
+
resolve();
|
234
|
+
};
|
235
|
+
image.src = url;
|
236
|
+
});
|
237
|
+
}
|
238
|
+
|
239
|
+
/** Set bounds after adding a layer */
|
240
|
+
public setBounds(): void {
|
241
|
+
const time = this.options.setBoundsInstant ? 0 : undefined;
|
242
|
+
this.mapObject.viewer.flyTo(this.layer.entities, {
|
243
|
+
duration: time,
|
244
|
+
offset: new HeadingPitchRange(
|
245
|
+
cMath.toRadians(this.mapObject.viewer.camera.heading),
|
246
|
+
-Math.PI / 2,
|
247
|
+
0
|
248
|
+
),
|
249
|
+
});
|
250
|
+
}
|
251
|
+
|
252
|
+
public addListeners() {
|
253
|
+
var isMouseOverMarker = false;
|
254
|
+
let hoverTimer: NodeJS.Timeout | undefined;
|
255
|
+
|
256
|
+
this.mapObject.addLayerListener('click', this.markerLayerId, (event: any) => {
|
257
|
+
if(this.options.onClick){
|
258
|
+
this.options.onClick(event);
|
259
|
+
}
|
260
|
+
});
|
261
|
+
|
262
|
+
this.mapObject.addLayerListener(
|
263
|
+
'mousemove',
|
264
|
+
this.markerLayerId,
|
265
|
+
(e: any) => {
|
266
|
+
this.mapObject.viewer.canvas.style.cursor = 'pointer';
|
267
|
+
if (!isMouseOverMarker) {
|
268
|
+
const hoverEvent = event
|
269
|
+
isMouseOverMarker = true;
|
270
|
+
hoverTimer = setTimeout(() => {
|
271
|
+
if (this.options.onHover) {
|
272
|
+
this.options.onHover(e, hoverEvent);
|
273
|
+
}
|
274
|
+
}, 1000);
|
275
|
+
}
|
276
|
+
}
|
277
|
+
);
|
278
|
+
|
279
|
+
this.mapObject.addLayerListener(
|
280
|
+
'mouseenter',
|
281
|
+
this.markerLayerId,
|
282
|
+
(event: any) => {
|
283
|
+
this.mapObject.viewer.canvas.style.cursor = 'pointer';
|
284
|
+
}
|
285
|
+
);
|
286
|
+
|
287
|
+
this.mapObject.addLayerListener('mouseout', this.markerLayerId, () => {
|
288
|
+
isMouseOverMarker = false;
|
289
|
+
clearTimeout(hoverTimer);
|
290
|
+
this.mapObject.viewer.canvas.style.cursor = '';
|
291
|
+
if (this.options.clearHover) {
|
292
|
+
this.options.clearHover(event);
|
293
|
+
}
|
294
|
+
});
|
295
|
+
}
|
296
|
+
|
297
|
+
/** Removes all listeners added by this layer */
|
298
|
+
public removeListeners() {
|
299
|
+
this.mapObject.removeLayerListeners(this.markerLayerId);
|
300
|
+
}
|
301
|
+
|
302
|
+
/** Remove layer from map and destroy layer */
|
303
|
+
public remove(): void {
|
304
|
+
this.mapObject.viewer.dataSources.remove(this.layer, true);
|
305
|
+
this.removeListeners();
|
306
|
+
this.mapObject.viewer.scene.requestRender();
|
307
|
+
}
|
308
|
+
|
309
|
+
/** enables visibility of the layer */
|
310
|
+
public show(): void {
|
311
|
+
this.layer.show = true;
|
312
|
+
}
|
313
|
+
|
314
|
+
/** Disables visibility of the layer */
|
315
|
+
public hide(): void {
|
316
|
+
this.layer.show = false;
|
317
|
+
}
|
318
|
+
|
319
|
+
/**
|
320
|
+
* Sets opacity of the layer
|
321
|
+
* @param opacity number between 0-1
|
322
|
+
*/
|
323
|
+
public setOpacity(opacity: number): void {
|
324
|
+
this.opacity = opacity;
|
325
|
+
this.icons = [];
|
326
|
+
this.loadIcons().then(() => {
|
327
|
+
this.opacity = opacity;
|
328
|
+
this.remove();
|
329
|
+
this.buildLayer();
|
330
|
+
this.add(this.data);
|
331
|
+
});
|
332
|
+
}
|
333
|
+
}
|
@@ -0,0 +1,326 @@
|
|
1
|
+
import {
|
2
|
+
Cartesian2,
|
3
|
+
Color,
|
4
|
+
CustomDataSource,
|
5
|
+
BillboardGraphics,
|
6
|
+
Math as cMath,
|
7
|
+
HeadingPitchRange,
|
8
|
+
Cartesian3,
|
9
|
+
HeightReference,
|
10
|
+
VerticalOrigin,
|
11
|
+
Entity,
|
12
|
+
ScreenSpaceEventHandler,
|
13
|
+
ScreenSpaceEventType,
|
14
|
+
} from "cesium";
|
15
|
+
|
16
|
+
import type CesiumView from "../droneView";
|
17
|
+
|
18
|
+
import { MarkerData, MarkerIcon, MarkerOptions } from "../app.interface";
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Use this class to create a marker layer
|
22
|
+
* @param {MapBox} mapObject - The mapbox map object
|
23
|
+
* @param {string} uniqueName - The unique name of the layer
|
24
|
+
* @param {MarkerData[]} data - The data to be used in the layer
|
25
|
+
* @param {MarkerOptions} options - The options for the layer (see {@link MarkerOptions})
|
26
|
+
*/
|
27
|
+
export default class Marker3DLayer {
|
28
|
+
markerLayerId: string;
|
29
|
+
|
30
|
+
icons: Entity[] = [];
|
31
|
+
|
32
|
+
markerSize: number = 12.5;
|
33
|
+
|
34
|
+
allowSVGs: boolean = false;
|
35
|
+
|
36
|
+
opacity: number;
|
37
|
+
|
38
|
+
layer: CustomDataSource;
|
39
|
+
handler: ScreenSpaceEventHandler;
|
40
|
+
hoverTimeout: NodeJS.Timeout | undefined;
|
41
|
+
isMouseOverMarker: boolean = false
|
42
|
+
|
43
|
+
/**
|
44
|
+
* @param mapObject CesiumView map object
|
45
|
+
* @param uniqueName string unique name for the layer
|
46
|
+
* @param data Array<MarkerData>
|
47
|
+
* @param options MarkerOptions
|
48
|
+
*/
|
49
|
+
constructor(
|
50
|
+
public mapObject: CesiumView,
|
51
|
+
public uniqueName: string,
|
52
|
+
public data: Array<MarkerData>,
|
53
|
+
public options: MarkerOptions
|
54
|
+
) {
|
55
|
+
this.markerLayerId = `marker-layer-${this.uniqueName}`;
|
56
|
+
|
57
|
+
this.opacity = 1;
|
58
|
+
|
59
|
+
// this.allowSVGs = true;
|
60
|
+
// const agent = navigator.userAgent.toLowerCase();
|
61
|
+
// if (
|
62
|
+
// (typeof this.options.allowSVGs !== "undefined" &&
|
63
|
+
// !this.options.allowSVGs) ||
|
64
|
+
// (agent.indexOf("chrome") === -1 &&
|
65
|
+
// (agent.indexOf("edg") !== -1 ||
|
66
|
+
// agent.indexOf("edge") !== -1 ||
|
67
|
+
// agent.indexOf("msie") !== -1 ||
|
68
|
+
// agent.indexOf("trident") > -1 ||
|
69
|
+
// agent.indexOf("firefox") > -1 ||
|
70
|
+
// agent.indexOf("safari") > -1))
|
71
|
+
// ) {
|
72
|
+
// this.allowSVGs = false;
|
73
|
+
// }
|
74
|
+
|
75
|
+
// load icons before adding marker on map
|
76
|
+
// this.loadIcons().then(() => {
|
77
|
+
this.buildLayer();
|
78
|
+
this.add(this.data).then(() => {
|
79
|
+
if (this.options.setBounds === undefined || this.options.setBounds) {
|
80
|
+
this.setBounds();
|
81
|
+
}
|
82
|
+
this.addListeners();
|
83
|
+
});
|
84
|
+
// });
|
85
|
+
}
|
86
|
+
|
87
|
+
/** To initialize layer */
|
88
|
+
public buildLayer(): void {
|
89
|
+
if (
|
90
|
+
this.mapObject.viewer.dataSources.getByName("marker" + this.uniqueName)
|
91
|
+
) {
|
92
|
+
this.mapObject.viewer.dataSources.remove(
|
93
|
+
this.mapObject.viewer.dataSources.getByName(
|
94
|
+
"marker" + this.uniqueName
|
95
|
+
)[0],
|
96
|
+
true
|
97
|
+
);
|
98
|
+
}
|
99
|
+
this.layer = new CustomDataSource("marker" + this.uniqueName);
|
100
|
+
}
|
101
|
+
|
102
|
+
/** To add layer on map */
|
103
|
+
public add(data: MarkerData[]) {
|
104
|
+
const self = this;
|
105
|
+
|
106
|
+
return new Promise<void>((resolve) => {
|
107
|
+
self.addToMap(data).then(() => {
|
108
|
+
this.mapObject.viewer.dataSources.add(this.layer);
|
109
|
+
|
110
|
+
this.mapObject.viewer.scene.requestRender();
|
111
|
+
resolve();
|
112
|
+
});
|
113
|
+
});
|
114
|
+
}
|
115
|
+
|
116
|
+
/**
|
117
|
+
*
|
118
|
+
* @param { MarkerData[] } data - load data on map
|
119
|
+
* @returns { void }
|
120
|
+
*/
|
121
|
+
|
122
|
+
public addToMap(data: MarkerData[]) {
|
123
|
+
return new Promise<void>((resolve) => {
|
124
|
+
const cartesians: any = [];
|
125
|
+
const cartesiansWithOutHeight: any = [];
|
126
|
+
const positionWithOutHeight: any = [];
|
127
|
+
|
128
|
+
console.log("data", data)
|
129
|
+
data.forEach((point) => {
|
130
|
+
const height = point.point[2] + 0.5;
|
131
|
+
|
132
|
+
if (point.point[2] == 0 || point.point[2] == null) {
|
133
|
+
const position = Cartesian3.fromDegrees(point.point[0], point.point[1]);
|
134
|
+
cartesiansWithOutHeight.push({ position, properties: point});
|
135
|
+
positionWithOutHeight.push(position)
|
136
|
+
} else {
|
137
|
+
const position = Cartesian3.fromDegrees(point.point[0], point.point[1], height || 0);
|
138
|
+
cartesians.push({
|
139
|
+
position,
|
140
|
+
properties: point,
|
141
|
+
});
|
142
|
+
}
|
143
|
+
});
|
144
|
+
console.log("cartesians", cartesians)
|
145
|
+
console.log("cartesiansWithOutHeight", cartesiansWithOutHeight)
|
146
|
+
console.log("positionWithOutHeight", positionWithOutHeight)
|
147
|
+
|
148
|
+
cartesians.forEach((position: any = [], i: number) => {
|
149
|
+
// const iconIndex = Object.keys(this.options.icons).findIndex(
|
150
|
+
// (icon) =>
|
151
|
+
// icon === data[i].properties.icon ||
|
152
|
+
// (this.options.icons[+icon] &&
|
153
|
+
// this.options.icons[+icon].name === data[i].properties.icon)
|
154
|
+
// );
|
155
|
+
// if (iconIndex >= 0) {
|
156
|
+
// const pin = {
|
157
|
+
// position,
|
158
|
+
// billboard: this.icons[iconIndex],
|
159
|
+
// data: data[i].properties,
|
160
|
+
// layerId: this.markerLayerId,
|
161
|
+
// };
|
162
|
+
// this.layer.entities.add(pin);
|
163
|
+
var markerProperty = position.properties.properties
|
164
|
+
this.layer.entities.add({
|
165
|
+
// name: 'Model 1',
|
166
|
+
position: position.position,
|
167
|
+
model: {uri : markerProperty.icon, scale: markerProperty.scale},
|
168
|
+
properties: position.properties
|
169
|
+
});
|
170
|
+
|
171
|
+
// Clone the model entity with different positions
|
172
|
+
// var modelEntity1 = viewer.entities.add(this.icons[iconIndex].clone());
|
173
|
+
// modelEntity1.position = position;
|
174
|
+
// }
|
175
|
+
// });
|
176
|
+
resolve();
|
177
|
+
})
|
178
|
+
|
179
|
+
this.mapObject.viewer.scene
|
180
|
+
.clampToHeightMostDetailed(positionWithOutHeight)
|
181
|
+
.then((pos) => {
|
182
|
+
cartesiansWithOutHeight.forEach((position: any = [], i: number) => {
|
183
|
+
// const iconIndex = Object.keys(this.options.icons).findIndex(
|
184
|
+
// (icon) =>
|
185
|
+
// icon === data[i].properties.icon ||
|
186
|
+
// (this.options.icons[+icon] &&
|
187
|
+
// this.options.icons[+icon].name === data[i].properties.icon)
|
188
|
+
// );
|
189
|
+
// if (iconIndex >= 0) {
|
190
|
+
// const pin = {
|
191
|
+
// position,
|
192
|
+
// billboard: this.icons[iconIndex],
|
193
|
+
// data: data[i].properties,
|
194
|
+
// layerId: this.markerLayerId,
|
195
|
+
// };
|
196
|
+
// this.layer.entities.add(pin);
|
197
|
+
|
198
|
+
var markerWithoutHeightProperty = position.properties.properties
|
199
|
+
this.layer.entities.add({
|
200
|
+
// name: 'Model 1',
|
201
|
+
position: position.position,
|
202
|
+
model: {uri : markerWithoutHeightProperty.icon, scale: markerWithoutHeightProperty.scale},
|
203
|
+
properties: position.properties
|
204
|
+
});
|
205
|
+
|
206
|
+
// Clone the model entity with different positions
|
207
|
+
// var modelEntity1 = viewer.entities.add(this.icons[iconIndex].clone());
|
208
|
+
// modelEntity1.position = position;
|
209
|
+
// }
|
210
|
+
// });
|
211
|
+
resolve();
|
212
|
+
});
|
213
|
+
})
|
214
|
+
});
|
215
|
+
}
|
216
|
+
|
217
|
+
|
218
|
+
/** Set bounds after adding a layer */
|
219
|
+
public setBounds(): void {
|
220
|
+
const time = this.options.setBoundsInstant ? 0 : undefined;
|
221
|
+
this.mapObject.viewer.flyTo(this.layer.entities, {
|
222
|
+
duration: time,
|
223
|
+
offset: new HeadingPitchRange(
|
224
|
+
cMath.toRadians(this.mapObject.viewer.camera.heading),
|
225
|
+
-Math.PI / 2,
|
226
|
+
0
|
227
|
+
),
|
228
|
+
});
|
229
|
+
}
|
230
|
+
|
231
|
+
public addListeners() {
|
232
|
+
this.handler = new ScreenSpaceEventHandler(this.mapObject.viewer.canvas);
|
233
|
+
|
234
|
+
// Change the event type to LEFT_CLICK
|
235
|
+
this.handler.setInputAction(
|
236
|
+
this.iconClickHandler.bind(this),
|
237
|
+
ScreenSpaceEventType.LEFT_CLICK
|
238
|
+
);
|
239
|
+
|
240
|
+
// Add MOUSE_MOVE event for on-hover functionality
|
241
|
+
this.handler.setInputAction(
|
242
|
+
this.iconHoverHandler.bind(this),
|
243
|
+
ScreenSpaceEventType.MOUSE_MOVE
|
244
|
+
);
|
245
|
+
}
|
246
|
+
|
247
|
+
iconHoverHandler(event: any) {
|
248
|
+
if (this.hoverTimeout) {
|
249
|
+
clearTimeout(this.hoverTimeout);
|
250
|
+
}
|
251
|
+
const pickedObject = this.mapObject.viewer.scene.pick(event.endPosition);
|
252
|
+
|
253
|
+
if (pickedObject && pickedObject.id) {
|
254
|
+
if (!this.isMouseOverMarker) {
|
255
|
+
this.hoverTimeout = setTimeout(() => {
|
256
|
+
this.isMouseOverMarker = true;
|
257
|
+
const hoveredMarkerProperties = pickedObject.id.properties?.properties?._value;
|
258
|
+
if (this.options.onHover) {
|
259
|
+
this.options.onHover(hoveredMarkerProperties, event);
|
260
|
+
}
|
261
|
+
}, 1000);
|
262
|
+
}
|
263
|
+
} else {
|
264
|
+
if (this.isMouseOverMarker){
|
265
|
+
clearTimeout(this.hoverTimeout);
|
266
|
+
if (this.options.clearHover) {
|
267
|
+
this.options.clearHover(event);
|
268
|
+
}
|
269
|
+
this.isMouseOverMarker = false;
|
270
|
+
}
|
271
|
+
}
|
272
|
+
}
|
273
|
+
|
274
|
+
iconClickHandler(event: any) {
|
275
|
+
const pickedObject = this.mapObject.viewer.scene.pick(event.position);
|
276
|
+
|
277
|
+
if (pickedObject && pickedObject.id) {
|
278
|
+
const selectedMarker = pickedObject.id.properties?.properties?._value
|
279
|
+
|
280
|
+
if (this.options.onClick) {
|
281
|
+
this.options.onClick(selectedMarker);
|
282
|
+
}
|
283
|
+
}
|
284
|
+
}
|
285
|
+
/** Removes all listeners added by this layer */
|
286
|
+
public removeListeners() {
|
287
|
+
this.handler.removeInputAction(ScreenSpaceEventType.LEFT_DOWN);
|
288
|
+
this.handler.removeInputAction(ScreenSpaceEventType.LEFT_UP);
|
289
|
+
this.handler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE);
|
290
|
+
this.handler.removeInputAction(ScreenSpaceEventType.PINCH_END);
|
291
|
+
this.handler.removeInputAction(ScreenSpaceEventType.PINCH_START);
|
292
|
+
this.handler.removeInputAction(ScreenSpaceEventType.PINCH_MOVE);
|
293
|
+
}
|
294
|
+
|
295
|
+
/** Remove layer from map and destroy layer */
|
296
|
+
public remove(): void {
|
297
|
+
this.mapObject.viewer.dataSources.remove(this.layer, true);
|
298
|
+
this.removeListeners();
|
299
|
+
this.mapObject.viewer.scene.requestRender();
|
300
|
+
}
|
301
|
+
|
302
|
+
/** enables visibility of the layer */
|
303
|
+
public show(): void {
|
304
|
+
this.layer.show = true;
|
305
|
+
}
|
306
|
+
|
307
|
+
/** Disables visibility of the layer */
|
308
|
+
public hide(): void {
|
309
|
+
this.layer.show = false;
|
310
|
+
}
|
311
|
+
|
312
|
+
/**
|
313
|
+
* Sets opacity of the layer
|
314
|
+
* @param opacity number between 0-1
|
315
|
+
*/
|
316
|
+
public setOpacity(opacity: number): void {
|
317
|
+
this.opacity = opacity;
|
318
|
+
this.icons = [];
|
319
|
+
// this.loadIcons().then(() => {
|
320
|
+
this.opacity = opacity;
|
321
|
+
this.remove();
|
322
|
+
this.buildLayer();
|
323
|
+
this.add(this.data);
|
324
|
+
// });
|
325
|
+
}
|
326
|
+
}
|