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,253 @@
|
|
1
|
+
import {
|
2
|
+
Cesium3DTileset,
|
3
|
+
Cesium3DTileStyle,
|
4
|
+
HeadingPitchRange,
|
5
|
+
ShadowMode,
|
6
|
+
Math as cMath,
|
7
|
+
Transforms,
|
8
|
+
Cartesian3,
|
9
|
+
HeadingPitchRoll,
|
10
|
+
Matrix4,
|
11
|
+
SplitDirection,
|
12
|
+
} from "cesium";
|
13
|
+
import { Options, ModelData, Point, MapType } from "../app.interface";
|
14
|
+
import type CesiumView from "../droneView";
|
15
|
+
import { cartesianToPoint } from "../utility";
|
16
|
+
/**
|
17
|
+
* Use this class to create a Ortho layer
|
18
|
+
* @param { MapBox } mapObject - The mapbox map object
|
19
|
+
* @param { string } uniqueName - The unique name of the layer
|
20
|
+
* @param { ModelData } data - The data to be used in the layer
|
21
|
+
* @param { Options } options - The options for the layer (see {@link Options})
|
22
|
+
*/
|
23
|
+
export default class ModelLayer {
|
24
|
+
tilsetLayerLayers: Cesium3DTileset;
|
25
|
+
|
26
|
+
data: ModelData;
|
27
|
+
|
28
|
+
modelLayerId: string;
|
29
|
+
|
30
|
+
type: string;
|
31
|
+
|
32
|
+
uniqueName: string;
|
33
|
+
|
34
|
+
opacity: number;
|
35
|
+
|
36
|
+
mapObject: CesiumView;
|
37
|
+
|
38
|
+
options: Options;
|
39
|
+
|
40
|
+
tileset: Cesium3DTileset;
|
41
|
+
|
42
|
+
mapType: MapType;
|
43
|
+
|
44
|
+
constructor(
|
45
|
+
mapObject: CesiumView,
|
46
|
+
uniqueName: string,
|
47
|
+
data: ModelData,
|
48
|
+
options: Options,
|
49
|
+
mapType: MapType
|
50
|
+
|
51
|
+
) {
|
52
|
+
this.modelLayerId = `Model-${this.uniqueName}`;
|
53
|
+
this.mapType = mapType;
|
54
|
+
this.opacity = 1;
|
55
|
+
this.data = data;
|
56
|
+
this.mapObject = mapObject;
|
57
|
+
this.uniqueName = uniqueName;
|
58
|
+
this.options = options;
|
59
|
+
this.addLayer(data, true);
|
60
|
+
}
|
61
|
+
|
62
|
+
getSplitDirection() {
|
63
|
+
if (this.mapType && this.mapType === 'default') {
|
64
|
+
return SplitDirection.LEFT;
|
65
|
+
}
|
66
|
+
|
67
|
+
if (this.mapType && this.mapType === 'compare') {
|
68
|
+
return SplitDirection.RIGHT;
|
69
|
+
}
|
70
|
+
|
71
|
+
return SplitDirection.NONE;
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* To load 3D data and return tileset for future use (visibility, remove, zoom)
|
76
|
+
* @param url string Url or Path to main tileset.json file
|
77
|
+
* @returns Cesium3DTileset
|
78
|
+
*/
|
79
|
+
public async addTilset(
|
80
|
+
url: string,
|
81
|
+
color: string = '#ffffff',
|
82
|
+
shadow: boolean,
|
83
|
+
modelMatrix: Matrix4,
|
84
|
+
setBound: boolean = true
|
85
|
+
) {
|
86
|
+
const tileset = await new Cesium3DTileset({
|
87
|
+
url,
|
88
|
+
shadows: shadow ? ShadowMode.ENABLED : ShadowMode.DISABLED,
|
89
|
+
maximumScreenSpaceError: 2,
|
90
|
+
skipLevelOfDetail: true,
|
91
|
+
immediatelyLoadDesiredLevelOfDetail: true,
|
92
|
+
dynamicScreenSpaceError: true,
|
93
|
+
splitDirection: this.getSplitDirection(),
|
94
|
+
// modelMatrix: modelMatrix,
|
95
|
+
});
|
96
|
+
|
97
|
+
tileset.readyPromise.then((tileset => {
|
98
|
+
|
99
|
+
const center = cartesianToPoint(tileset.boundingSphere.center);
|
100
|
+
|
101
|
+
if (+(center.height || 0) < -1000) {
|
102
|
+
tileset.modelMatrix = modelMatrix;
|
103
|
+
}else{
|
104
|
+
this.data.center = center;
|
105
|
+
}
|
106
|
+
|
107
|
+
// if(!tileset.asset || !tileset.asset.extras || !tileset.asset.extras.ion || !tileset.asset.extras.ion.georeferenced){
|
108
|
+
// console.log("pppp");
|
109
|
+
// }
|
110
|
+
|
111
|
+
if (color) {
|
112
|
+
tileset.style = new Cesium3DTileStyle({
|
113
|
+
color: {
|
114
|
+
conditions: [["true", `color("${color}", ${this.opacity})`]],
|
115
|
+
},
|
116
|
+
});
|
117
|
+
}
|
118
|
+
this.mapObject.viewer.scene.primitives.add(tileset);
|
119
|
+
this.tileset = tileset;
|
120
|
+
if (setBound) this.mapObject.viewer.zoomTo(tileset);
|
121
|
+
// this.tilsetLayerLayers = tilsetLayer;
|
122
|
+
this.mapObject.viewer.scene.requestRender();
|
123
|
+
return tileset;
|
124
|
+
}))
|
125
|
+
|
126
|
+
}
|
127
|
+
|
128
|
+
setBounds() {
|
129
|
+
const time = this.options.setBoundsInstant ? 0 : undefined;
|
130
|
+
this.mapObject.viewer.flyTo(this.tilsetLayerLayers, {
|
131
|
+
duration: time,
|
132
|
+
offset: new HeadingPitchRange(
|
133
|
+
cMath.toRadians(this.mapObject.viewer.camera.heading),
|
134
|
+
-Math.PI / 2,
|
135
|
+
0
|
136
|
+
),
|
137
|
+
});
|
138
|
+
}
|
139
|
+
|
140
|
+
/**
|
141
|
+
* Add a raster layer to the map
|
142
|
+
* @param {number} index - The index of the layer
|
143
|
+
* @param {ModelData} data - The data to be used in the layer
|
144
|
+
*/
|
145
|
+
async addLayer(layer: ModelData, setBound: boolean) {
|
146
|
+
const color = layer.color || "#ffffff";
|
147
|
+
const isShadow = layer.shadow || true;
|
148
|
+
const { url } = layer;
|
149
|
+
const { center } = layer;
|
150
|
+
const { rotationX } = layer || 0;
|
151
|
+
const { rotationY } = layer || 0;
|
152
|
+
const { rotationZ } = layer || 0;
|
153
|
+
|
154
|
+
const modelMatrix = Transforms.headingPitchRollToFixedFrame(
|
155
|
+
Cartesian3.fromDegrees(+center?.long || 0, +center?.lat || 0, +(center?.height || 0)),
|
156
|
+
new HeadingPitchRoll(
|
157
|
+
cMath.toRadians(rotationX),
|
158
|
+
cMath.toRadians(rotationY),
|
159
|
+
cMath.toRadians(rotationZ)
|
160
|
+
)
|
161
|
+
);
|
162
|
+
|
163
|
+
const tilsetLayer: any = await this.addTilset(
|
164
|
+
url,
|
165
|
+
color,
|
166
|
+
isShadow,
|
167
|
+
modelMatrix,
|
168
|
+
setBound
|
169
|
+
);
|
170
|
+
|
171
|
+
}
|
172
|
+
|
173
|
+
/** Remove layer from map and destroy layer */
|
174
|
+
public remove(): void {
|
175
|
+
this.mapObject.viewer.scene.primitives.remove(this.tileset);
|
176
|
+
this.mapObject.viewer.scene.requestRender();
|
177
|
+
}
|
178
|
+
|
179
|
+
/** Show model */
|
180
|
+
public show(): void{
|
181
|
+
this.tileset.show = true;
|
182
|
+
this.mapObject.viewer.scene.requestRender();
|
183
|
+
}
|
184
|
+
|
185
|
+
/** Hide model */
|
186
|
+
public hide(): void{
|
187
|
+
this.tileset.show = false;
|
188
|
+
this.mapObject.viewer.scene.requestRender();
|
189
|
+
}
|
190
|
+
|
191
|
+
/** @inheritdoc */
|
192
|
+
setOpacity(opacity: number) {
|
193
|
+
this.opacity = opacity;
|
194
|
+
this.remove();
|
195
|
+
this.addLayer(this.data, false);
|
196
|
+
this.mapObject.viewer.scene.requestRender();
|
197
|
+
}
|
198
|
+
|
199
|
+
setRotation(rotationX: number, rotationY: number, rotationZ: number) {
|
200
|
+
|
201
|
+
if (this.tileset.asset.extras.ion.georeferenced) {
|
202
|
+
return;
|
203
|
+
}
|
204
|
+
|
205
|
+
if (rotationX) {
|
206
|
+
this.data.rotationX = rotationX;
|
207
|
+
}
|
208
|
+
|
209
|
+
if (rotationY) {
|
210
|
+
this.data.rotationY = rotationY;
|
211
|
+
}
|
212
|
+
|
213
|
+
if (rotationZ) {
|
214
|
+
this.data.rotationZ = rotationZ;
|
215
|
+
}
|
216
|
+
|
217
|
+
const { center } = this.data;
|
218
|
+
|
219
|
+
const modelMatrix = Transforms.headingPitchRollToFixedFrame(
|
220
|
+
Cartesian3.fromDegrees(+center.long, +center.lat, +(center.height || 0)),
|
221
|
+
new HeadingPitchRoll(
|
222
|
+
cMath.toRadians(rotationX || 0),
|
223
|
+
cMath.toRadians(rotationY || 0),
|
224
|
+
cMath.toRadians(rotationZ || 0)
|
225
|
+
)
|
226
|
+
);
|
227
|
+
|
228
|
+
this.tileset.modelMatrix = modelMatrix;
|
229
|
+
this.mapObject.viewer.scene.requestRender();
|
230
|
+
}
|
231
|
+
|
232
|
+
setPosition(position: Point) {
|
233
|
+
if (this.tileset?.asset?.extras?.ion?.georeferenced) {
|
234
|
+
return;
|
235
|
+
}
|
236
|
+
this.data.center = position;
|
237
|
+
const modelMatrix = Transforms.headingPitchRollToFixedFrame(
|
238
|
+
Cartesian3.fromDegrees(
|
239
|
+
+this.data.center.long,
|
240
|
+
+this.data.center.lat,
|
241
|
+
+(this.data.center.height || 0)
|
242
|
+
),
|
243
|
+
new HeadingPitchRoll(
|
244
|
+
cMath.toRadians(this.data.rotationX || 0),
|
245
|
+
cMath.toRadians(this.data.rotationY || 0),
|
246
|
+
cMath.toRadians(this.data.rotationZ || 0)
|
247
|
+
)
|
248
|
+
);
|
249
|
+
|
250
|
+
this.tileset.modelMatrix = modelMatrix;
|
251
|
+
this.mapObject.viewer.scene.requestRender();
|
252
|
+
}
|
253
|
+
}
|
@@ -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 { NoteData, NoteIcon, NoteOptions } from "../app.interface";
|
16
|
+
import { addLabel } from "../utility";
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Use this class to create a note layer
|
20
|
+
* @param {MapBox} mapObject - The mapbox map object
|
21
|
+
* @param {string} uniqueName - The unique name of the layer
|
22
|
+
* @param {NoteData[]} data - The data to be used in the layer
|
23
|
+
* @param {NoteOptions} options - The options for the layer (see {@link NoteOptions})
|
24
|
+
*/
|
25
|
+
|
26
|
+
export default class NoteLayer {
|
27
|
+
noteLayerId: string;
|
28
|
+
|
29
|
+
icons: BillboardGraphics[] = [];
|
30
|
+
|
31
|
+
noteSize: 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<NoteData>
|
43
|
+
* @param options NoteOptions
|
44
|
+
*/
|
45
|
+
constructor(
|
46
|
+
public mapObject: CesiumView,
|
47
|
+
public uniqueName: string,
|
48
|
+
public data: Array<NoteData>,
|
49
|
+
public options: NoteOptions
|
50
|
+
) {
|
51
|
+
this.noteLayerId = `note-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 note 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("note" + this.uniqueName)
|
87
|
+
) {
|
88
|
+
this.mapObject.viewer.dataSources.remove(
|
89
|
+
this.mapObject.viewer.dataSources.getByName(
|
90
|
+
"note" + this.uniqueName
|
91
|
+
)[0],
|
92
|
+
true
|
93
|
+
);
|
94
|
+
}
|
95
|
+
this.layer = new CustomDataSource("note" + this.uniqueName);
|
96
|
+
}
|
97
|
+
|
98
|
+
/** To add layer on map */
|
99
|
+
public add(data: NoteData[]) {
|
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 { NoteData[] } data - load data on map
|
115
|
+
* @returns { void }
|
116
|
+
*/
|
117
|
+
public async addToMap(data: NoteData[]): 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 addNotes = (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.noteLayerId,
|
156
|
+
},
|
157
|
+
data: data[i].properties,
|
158
|
+
layerId: this.noteLayerId,
|
159
|
+
};
|
160
|
+
this.layer.entities.add(pin);
|
161
|
+
}
|
162
|
+
}
|
163
|
+
}
|
164
|
+
});
|
165
|
+
};
|
166
|
+
|
167
|
+
addNotes(cartesiansWith3D);
|
168
|
+
const updatedCartesiansWith3D = await this.mapObject.viewer.scene.clampToHeightMostDetailed(cartesians);
|
169
|
+
addNotes(updatedCartesiansWith3D);
|
170
|
+
}
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Loads all specified note 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 { NoteIcon } icon - create bill board from icons
|
203
|
+
* @returns { void }
|
204
|
+
*/
|
205
|
+
load(icon: NoteIcon) {
|
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 isMouseOverNote = false;
|
254
|
+
let hoverTimer: NodeJS.Timeout | undefined;
|
255
|
+
|
256
|
+
this.mapObject.addLayerListener('click', this.noteLayerId, (event: any) => {
|
257
|
+
if(this.options.onClick){
|
258
|
+
this.options.onClick(event);
|
259
|
+
}
|
260
|
+
});
|
261
|
+
|
262
|
+
this.mapObject.addLayerListener(
|
263
|
+
'mousemove',
|
264
|
+
this.noteLayerId,
|
265
|
+
(e: any) => {
|
266
|
+
this.mapObject.viewer.canvas.style.cursor = 'pointer';
|
267
|
+
if (!isMouseOverNote) {
|
268
|
+
const hoverEvent = event
|
269
|
+
isMouseOverNote = 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.noteLayerId,
|
282
|
+
(event: any) => {
|
283
|
+
this.mapObject.viewer.canvas.style.cursor = 'pointer';
|
284
|
+
}
|
285
|
+
);
|
286
|
+
|
287
|
+
this.mapObject.addLayerListener('mouseout', this.noteLayerId, () => {
|
288
|
+
isMouseOverNote = 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.noteLayerId);
|
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,76 @@
|
|
1
|
+
import {
|
2
|
+
ImageryLayer,
|
3
|
+
WebMapServiceImageryProvider,
|
4
|
+
WebMercatorTilingScheme,
|
5
|
+
} from "cesium";
|
6
|
+
import type { LayerOptions, OrthoData } from "../app.interface";
|
7
|
+
import type CesiumView from "../droneView";
|
8
|
+
/**
|
9
|
+
* Use this class to create a Ortho layer
|
10
|
+
* @param {CesiumView} mapObject - The CesiumView map object
|
11
|
+
* @param {string} uniqueName - The unique name of the layer
|
12
|
+
* @param {OrthoData} data - The data to be used in the layer
|
13
|
+
* @param {LayerOptions} options - The options for the layer (see {@link LayerOptions})
|
14
|
+
*/
|
15
|
+
class RasterLayer {
|
16
|
+
imageryLayer: ImageryLayer;
|
17
|
+
|
18
|
+
orthoId: string;
|
19
|
+
|
20
|
+
constructor(
|
21
|
+
public mapObject: CesiumView,
|
22
|
+
public uniqueName: string,
|
23
|
+
public data: OrthoData,
|
24
|
+
public options: LayerOptions
|
25
|
+
) {
|
26
|
+
this.orthoId = `ortho-layer-${uniqueName}`;
|
27
|
+
|
28
|
+
this.addRaster(data);
|
29
|
+
}
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Add a raster layer to the map
|
33
|
+
* @param {OrthoData} data - The data to be used in the layer
|
34
|
+
*/
|
35
|
+
addRaster(layer: OrthoData) {
|
36
|
+
let opacity = 1;
|
37
|
+
|
38
|
+
console.log(layer);
|
39
|
+
|
40
|
+
const imageryLayer =
|
41
|
+
this.mapObject.viewer.scene.imageryLayers.addImageryProvider(
|
42
|
+
new WebMapServiceImageryProvider({
|
43
|
+
url: layer.url,
|
44
|
+
layers: 'ortho',
|
45
|
+
parameters: {
|
46
|
+
transparent: "true",
|
47
|
+
format: "image/png",
|
48
|
+
},
|
49
|
+
tileWidth: layer.tileSize || 256,
|
50
|
+
tileHeight: layer.tileSize || 256,
|
51
|
+
maximumLevel: layer.maxZoom || 23,
|
52
|
+
minimumLevel: layer.minZoom || 0,
|
53
|
+
credit: layer.credit,
|
54
|
+
tilingScheme: new WebMercatorTilingScheme(),
|
55
|
+
})
|
56
|
+
);
|
57
|
+
|
58
|
+
imageryLayer.alpha = opacity;
|
59
|
+
|
60
|
+
this.imageryLayer = imageryLayer;
|
61
|
+
|
62
|
+
// this.mapObject.viewer.zoomTo(this.imageryLayer)
|
63
|
+
}
|
64
|
+
|
65
|
+
/** Remove layer from map and destroy layer */
|
66
|
+
public remove(): void {
|
67
|
+
this.mapObject.viewer.scene.imageryLayers.remove(this.imageryLayer, true);
|
68
|
+
this.mapObject.viewer.scene.requestRender();
|
69
|
+
}
|
70
|
+
|
71
|
+
setOpacity(opacity: number) {
|
72
|
+
this.imageryLayer.alpha = opacity * 0.01;
|
73
|
+
this.mapObject.viewer.scene.requestRender();
|
74
|
+
}
|
75
|
+
}
|
76
|
+
export default RasterLayer;
|