@openglobus/og 0.18.4 → 0.18.5

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.
Files changed (43) hide show
  1. package/README.md +8 -5
  2. package/css/og.css +251 -3
  3. package/lib/@openglobus/og.css +1 -1
  4. package/lib/@openglobus/og.esm.js +1 -1
  5. package/lib/@openglobus/og.esm.js.map +1 -1
  6. package/lib/@openglobus/og.umd.js +1 -1
  7. package/lib/@openglobus/og.umd.js.map +1 -1
  8. package/lib/js/camera/PlanetCamera.d.ts +2 -2
  9. package/lib/js/camera/PlanetCamera.js +3 -2
  10. package/lib/js/control/EarthCoordinates.js +2 -2
  11. package/lib/js/control/elevationProfile/ElevationProfile.d.ts +41 -25
  12. package/lib/js/control/elevationProfile/ElevationProfile.js +103 -74
  13. package/lib/js/control/elevationProfile/ElevationProfileButtonsView.d.ts +14 -0
  14. package/lib/js/control/elevationProfile/ElevationProfileButtonsView.js +61 -0
  15. package/lib/js/control/elevationProfile/ElevationProfileControl.d.ts +33 -0
  16. package/lib/js/control/elevationProfile/ElevationProfileControl.js +153 -0
  17. package/lib/js/control/elevationProfile/ElevationProfileLegend.d.ts +20 -0
  18. package/lib/js/control/elevationProfile/ElevationProfileLegend.js +82 -0
  19. package/lib/js/control/elevationProfile/ElevationProfileScene.d.ts +80 -0
  20. package/lib/js/control/elevationProfile/ElevationProfileScene.js +539 -0
  21. package/lib/js/control/elevationProfile/ElevationProfileView.d.ts +63 -0
  22. package/lib/js/control/elevationProfile/ElevationProfileView.js +504 -0
  23. package/lib/js/control/elevationProfile/PointListDialog.d.ts +12 -0
  24. package/lib/js/control/elevationProfile/PointListDialog.js +57 -0
  25. package/lib/js/control/index.d.ts +2 -1
  26. package/lib/js/control/index.js +2 -1
  27. package/lib/js/entity/Polyline.js +1 -1
  28. package/lib/js/layer/GeoImage.js +3 -0
  29. package/lib/js/renderer/Renderer.d.ts +0 -1
  30. package/lib/js/renderer/Renderer.js +3 -28
  31. package/lib/js/renderer/RendererEvents.js +0 -7
  32. package/lib/js/scene/Planet.d.ts +4 -0
  33. package/lib/js/scene/Planet.js +8 -0
  34. package/lib/js/terrain/GlobusTerrain.d.ts +3 -0
  35. package/lib/js/terrain/GlobusTerrain.js +14 -2
  36. package/lib/js/terrain/MapboxTerrain.js +29 -29
  37. package/lib/js/ui/Dialog.js +1 -1
  38. package/lib/js/utils/TerrainWorker.js +1 -1
  39. package/lib/js/utils/shared.d.ts +2 -1
  40. package/lib/js/utils/shared.js +21 -3
  41. package/package.json +1 -1
  42. package/lib/js/shaders/pickingMask.d.ts +0 -2
  43. package/lib/js/shaders/pickingMask.js +0 -22
@@ -0,0 +1,539 @@
1
+ import { Entity } from '../../entity/Entity';
2
+ import { createEvents } from '../../Events';
3
+ import { LonLat } from "../../LonLat";
4
+ import { Extent } from "../../Extent";
5
+ import { Object3d } from '../../Object3d';
6
+ import { RenderNode } from '../../scene/RenderNode';
7
+ import { Vector } from '../../layer/Vector';
8
+ import { Vec2 } from '../../math/Vec2';
9
+ import { Vec3 } from '../../math/Vec3';
10
+ import { Ray } from "../../math/Ray";
11
+ let groundObj3d = Object3d.createCylinder(0.33, 0, 1.0, 20, 1, true, false, 0, 0, 0);
12
+ let headObj3d = Object3d.createCylinder(0.33, 0.33, 1.1, 20, 1, true, true, 0, -0.55, 0);
13
+ const POINTER_RAY_OPTIONS = {
14
+ startPosition: new Vec3(),
15
+ endPosition: new Vec3(),
16
+ startColor: "rgba(255,131,0,0.2)",
17
+ endColor: "rgba(255,131,0,1.0)",
18
+ thickness: 2.7
19
+ };
20
+ const POINTER_BILLBOARD_OPTIONS = {
21
+ src: "data:image/png;base64,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",
22
+ color: "rgb(255,131,0)",
23
+ size: [8, 8]
24
+ };
25
+ const POINTER_LABEL_OPTIONS = {
26
+ text: "",
27
+ size: 10.5,
28
+ color: "rgba(455,455,455,1.0)",
29
+ outlineColor: "rgba(0,0,0,0.34)",
30
+ outline: 0.23,
31
+ align: "left",
32
+ offset: [5, 15, -5]
33
+ };
34
+ const LABEL_OPTIONS = {
35
+ text: "",
36
+ size: 10.5,
37
+ color: "rgba(455,455,455,1.0)",
38
+ outlineColor: "rgba(0,0,0,0.34)",
39
+ outline: 0.23,
40
+ align: "right",
41
+ offset: [-47, 25, 0]
42
+ };
43
+ const GROUND_POINTER_OPTIONS = {
44
+ instanced: true,
45
+ tag: "ground-pointer",
46
+ color: "rgb(0,305,0)",
47
+ object3d: groundObj3d
48
+ };
49
+ const HEAD_POINTER_OPTIONS = {
50
+ instanced: true,
51
+ tag: "head-pointer",
52
+ color: "rgb(305,305,0)",
53
+ object3d: headObj3d
54
+ };
55
+ class ElevationProfileScene extends RenderNode {
56
+ constructor(options = {}) {
57
+ super("ElevationProfileScene");
58
+ this._onLClick = (e) => {
59
+ let groundPos = this._planet.getCartesianFromPixelTerrain(e.pos);
60
+ if (groundPos) {
61
+ this.addGroundPoint3vAsync(groundPos);
62
+ }
63
+ };
64
+ this._onMouseMove = (e) => {
65
+ let mouseCart = this._planet.getCartesianFromMouseTerrain();
66
+ if (this._pickedGroundEntity) {
67
+ let d = new Vec2(e.x, e.y).sub(this._startClickPos), p = this._startEntityPos.add(d);
68
+ let groundCart = this._planet.getCartesianFromPixelTerrain(p);
69
+ if (groundCart) {
70
+ this.setGroundPointCartesian3v(this._pickedGroundEntity.properties.index, groundCart);
71
+ }
72
+ }
73
+ else if (this._pickedHeadEntity) {
74
+ let cam = this._planet.camera;
75
+ let p0 = this._pickedHeadEntity.properties.groundEntity.getCartesian();
76
+ let groundNormal = this._planet.ellipsoid.getSurfaceNormal3v(p0);
77
+ let p1 = p0.add(groundNormal);
78
+ let p2 = p0.add(cam.getRight());
79
+ let px = new Vec3();
80
+ if (new Ray(cam.eye, e.direction).hitPlane(p0, p1, p2, px) === Ray.INSIDE) {
81
+ let h = Vec3.proj_b_to_a(px, p0);
82
+ let s = h.sub(p0).dot(p0);
83
+ let headPos = p0.add(groundNormal.scale(Math.sign(s) * h.distance(p0)));
84
+ this.setHeadPointCartesian3v(this._pickedHeadEntity.properties.index, headPos);
85
+ }
86
+ }
87
+ };
88
+ this._onLUp = (e) => {
89
+ };
90
+ this._onGroundPointerEnter = (e) => {
91
+ e.renderer.handler.canvas.style.cursor = "pointer";
92
+ };
93
+ this._onGroundPointerLeave = (e) => {
94
+ e.renderer.handler.canvas.style.cursor = "default";
95
+ };
96
+ this._onGroundPointerLDown = (e) => {
97
+ this._clampToGround = false;
98
+ this.renderer.controls.mouseNavigation.deactivate();
99
+ this._pickedGroundEntity = e.pickingObject;
100
+ const coords = this._pickedGroundEntity.getCartesian();
101
+ this._startClickPos.set(e.x, e.y);
102
+ this._startEntityPos = this._planet.getPixelFromCartesian(coords);
103
+ };
104
+ this._onGroundPointerLUp = (e) => {
105
+ this._clampToGround = true;
106
+ this.renderer.controls.mouseNavigation.activate();
107
+ this._pickedGroundEntity = null;
108
+ };
109
+ this._onHeadPointerEnter = (e) => {
110
+ e.renderer.handler.canvas.style.cursor = "pointer";
111
+ };
112
+ this._onHeadPointerLeave = (e) => {
113
+ e.renderer.handler.canvas.style.cursor = "default";
114
+ };
115
+ this._onHeadPointerLDown = (e) => {
116
+ this.renderer.controls.mouseNavigation.deactivate();
117
+ this._pickedHeadEntity = e.pickingObject;
118
+ };
119
+ this._onHeadPointerLUp = (e) => {
120
+ this.renderer.controls.mouseNavigation.activate();
121
+ this._pickedHeadEntity = null;
122
+ };
123
+ this.events = createEvents(ELEVATIONPROFILESCENE_EVENTS);
124
+ this._planet = options.planet || null;
125
+ this._pickedGroundEntity = null;
126
+ this._pickedHeadEntity = null;
127
+ this._startClickPos = new Vec2();
128
+ this._startEntityPos = new Vec2();
129
+ this._clampToGround = true;
130
+ this._trackLayer = new Vector("track", {
131
+ entities: [],
132
+ pickingEnabled: false,
133
+ polygonOffsetUnits: -1.0,
134
+ relativeToGround: true,
135
+ displayInLayerSwitcher: false
136
+ });
137
+ this._groundPointersLayer = new Vector("ground-pointers", {
138
+ entities: [],
139
+ pickingEnabled: true,
140
+ displayInLayerSwitcher: false,
141
+ scaleByDistance: [1, 5000, 0.02],
142
+ pickingScale: 1.5
143
+ });
144
+ this._headPointersLayer = new Vector("head-pointers", {
145
+ entities: [],
146
+ pickingEnabled: true,
147
+ displayInLayerSwitcher: false,
148
+ scaleByDistance: [1, 10000, 0.02],
149
+ pickingScale: 1
150
+ });
151
+ this._columnPointersLayer = new Vector("column-pointers", {
152
+ entities: [],
153
+ pickingEnabled: false,
154
+ displayInLayerSwitcher: false
155
+ });
156
+ this._trackEntity = new Entity({
157
+ polyline: {
158
+ path3v: [],
159
+ thickness: 3.8,
160
+ color: "rgba(0,305,0,0.8)",
161
+ isClosed: false
162
+ }
163
+ });
164
+ this._trackLayer = new Vector("column-pointers", {
165
+ entities: [this._trackEntity],
166
+ pickingEnabled: false,
167
+ displayInLayerSwitcher: false
168
+ });
169
+ this._heightsLayer = new Vector("heights-labels", {
170
+ entities: [],
171
+ pickingEnabled: false,
172
+ displayInLayerSwitcher: false
173
+ });
174
+ this._pointerHeadEntity = new Entity({
175
+ cartesian: new Vec3(),
176
+ billboard: POINTER_BILLBOARD_OPTIONS
177
+ });
178
+ this._pointerLabelEntity = new Entity({
179
+ cartesian: new Vec3(),
180
+ label: POINTER_LABEL_OPTIONS
181
+ });
182
+ this._pointerRayEntity = new Entity({
183
+ cartesian: new Vec3(),
184
+ ray: POINTER_RAY_OPTIONS
185
+ });
186
+ this._pointerLayer = new Vector("pointer", {
187
+ entities: [this._pointerHeadEntity, this._pointerLabelEntity, this._pointerRayEntity],
188
+ pickingEnabled: false,
189
+ displayInLayerSwitcher: false
190
+ });
191
+ }
192
+ flyExtent() {
193
+ let entities = this._headPointersLayer.getEntities();
194
+ let minLon = 180, minLat = 180, maxLon = -180, maxLat = -180, maxHeight = -1000000;
195
+ if (entities.length > 1) {
196
+ for (let i = 0; i < entities.length; i++) {
197
+ let ll = entities[i].getLonLat();
198
+ if (ll.lon < minLon)
199
+ minLon = ll.lon;
200
+ if (ll.lat < minLat)
201
+ minLat = ll.lat;
202
+ if (ll.lon > maxLon)
203
+ maxLon = ll.lon;
204
+ if (ll.lat > maxLat)
205
+ maxLat = ll.lat;
206
+ if (ll.height > maxHeight)
207
+ maxHeight = ll.height;
208
+ }
209
+ this._planet.camera.flyExtent(new Extent(new LonLat(minLon, minLat), new LonLat(maxLon, maxLat)), maxHeight, null, 0);
210
+ }
211
+ }
212
+ get planet() {
213
+ return this._planet;
214
+ }
215
+ _createGroundPointer(groundCart, altitude = 10) {
216
+ let surfaceNormal = this.ellipsoid.getSurfaceNormal3v(groundCart);
217
+ let headCart = groundCart.add(surfaceNormal.scale(altitude));
218
+ let columnEntity = new Entity({
219
+ ray: {
220
+ startPosition: groundCart,
221
+ endPosition: headCart,
222
+ startColor: "rgba(255,255,255,0.2)",
223
+ endColor: "rgba(355,355,355,1.0)",
224
+ thickness: 3.2
225
+ }
226
+ });
227
+ let groundEntity = new Entity({
228
+ cartesian: groundCart,
229
+ geoObject: GROUND_POINTER_OPTIONS,
230
+ });
231
+ let headEntity = new Entity({
232
+ cartesian: headCart,
233
+ geoObject: HEAD_POINTER_OPTIONS,
234
+ properties: {}
235
+ });
236
+ let heightLabelEntity = new Entity({
237
+ cartesian: headCart,
238
+ label: LABEL_OPTIONS
239
+ });
240
+ heightLabelEntity.appendChild(new Entity({
241
+ cartesian: headCart,
242
+ label: { ...LABEL_OPTIONS, offset: [-47, 45, 0] }
243
+ }));
244
+ const index = this._groundPointersLayer.getEntities().length;
245
+ columnEntity.properties =
246
+ groundEntity.properties =
247
+ headEntity.properties = {
248
+ index,
249
+ altitude: altitude,
250
+ lonLatEll: new LonLat(),
251
+ headEntity,
252
+ groundEntity,
253
+ columnEntity,
254
+ heightLabelEntity
255
+ };
256
+ return { headEntity, groundEntity, columnEntity, heightLabelEntity };
257
+ }
258
+ setPointerCartesian3v(p, height) {
259
+ this._pointerLabelEntity.setCartesian3v(p);
260
+ this._pointerLabelEntity.label.setText(`${Math.round(height).toString()} m`);
261
+ this._pointerRayEntity.ray.setEndPosition3v(p);
262
+ let n = this._planet.ellipsoid.getSurfaceNormal3v(p);
263
+ this._pointerRayEntity.ray.setStartPosition3v(p.add(n.scale(-height)));
264
+ this._pointerHeadEntity.setCartesian3v(p);
265
+ }
266
+ bindPlanet(planet) {
267
+ this._planet = planet;
268
+ }
269
+ init() {
270
+ this._activate();
271
+ }
272
+ onremove() {
273
+ this._deactivate();
274
+ }
275
+ _activate() {
276
+ this._planet.addLayer(this._trackLayer);
277
+ this._planet.addLayer(this._groundPointersLayer);
278
+ this._planet.addLayer(this._columnPointersLayer);
279
+ this._planet.addLayer(this._headPointersLayer);
280
+ this._planet.addLayer(this._heightsLayer);
281
+ this._planet.addLayer(this._pointerLayer);
282
+ this.renderer.events.on("ldblclick", this._onLClick);
283
+ this.renderer.events.on("mousemove", this._onMouseMove);
284
+ this.renderer.events.on("lup", this._onLUp);
285
+ this._groundPointersLayer.events.on("mouseenter", this._onGroundPointerEnter);
286
+ this._groundPointersLayer.events.on("mouseleave", this._onGroundPointerLeave);
287
+ this._groundPointersLayer.events.on("ldown", this._onGroundPointerLDown);
288
+ this._groundPointersLayer.events.on("lup", this._onGroundPointerLUp);
289
+ this._headPointersLayer.events.on("mouseenter", this._onHeadPointerEnter);
290
+ this._headPointersLayer.events.on("mouseleave", this._onHeadPointerLeave);
291
+ this._headPointersLayer.events.on("ldown", this._onHeadPointerLDown);
292
+ this._headPointersLayer.events.on("lup", this._onHeadPointerLUp);
293
+ this.setPointerVisibility(false);
294
+ }
295
+ getPointLonLat(index) {
296
+ let entity = this._headPointersLayer.getEntities()[index];
297
+ if (entity) {
298
+ return entity.getLonLat();
299
+ }
300
+ }
301
+ getPointsLonLat() {
302
+ let entities = this._headPointersLayer.getEntities();
303
+ let points = new Array(entities.length);
304
+ for (let i = 0, len = points.length; i < len; i++) {
305
+ let ei = entities[i];
306
+ points[i] = ei.getLonLat();
307
+ }
308
+ return points;
309
+ }
310
+ getHeightMSL(lonLat) {
311
+ if (this._planet && this._planet.terrain.geoid) {
312
+ return this._planet.terrain.geoid.getHeightLonLat(lonLat);
313
+ }
314
+ return 0;
315
+ }
316
+ getHeightELLAsync(lonLat) {
317
+ return new Promise((resolve, reject) => {
318
+ this._planet.terrain.getHeightAsync(lonLat, (hGnd) => {
319
+ if (this._planet) {
320
+ let hMsl = this.getHeightMSL(lonLat);
321
+ resolve(hGnd + hMsl);
322
+ }
323
+ else {
324
+ reject();
325
+ }
326
+ });
327
+ });
328
+ }
329
+ addPointLonLatArrayAsync(lonLatArr, stopPropagation = false) {
330
+ if (!this._planet) {
331
+ throw new Error("Planet is not defined");
332
+ }
333
+ let ell = this._planet.ellipsoid;
334
+ for (let i = 0, len = lonLatArr.length - 1; i < len; i++) {
335
+ let p0 = ell.lonLatToCartesian(lonLatArr[i]), p1 = ell.lonLatToCartesian(lonLatArr[i + 1]);
336
+ if (p0.distance(p1) > 100000) {
337
+ throw new Error("Track is too long! 100 km is maximum.");
338
+ }
339
+ }
340
+ let res = new Array(lonLatArr.length);
341
+ for (let i = 0, len = lonLatArr.length; i < len; i++) {
342
+ res[i] = this.addPointLonLatAsync(lonLatArr[i], true);
343
+ }
344
+ Promise.all(res).then(() => {
345
+ if (!stopPropagation) {
346
+ this.events.dispatch(this.events.change, this);
347
+ }
348
+ });
349
+ return res;
350
+ }
351
+ addPointLonLatAsync(lonLat, stopPropagation = false) {
352
+ let headPos = this._planet.ellipsoid.lonLatToCartesian(lonLat);
353
+ let n = this._planet.ellipsoid.getSurfaceNormal3v(headPos);
354
+ let ellLonLat = new LonLat(lonLat.lon, lonLat.lat);
355
+ let ellPos = this._planet.ellipsoid.lonLatToCartesian(ellLonLat);
356
+ let { headEntity, groundEntity, columnEntity, heightLabelEntity } = this._createGroundPointer(ellPos);
357
+ this._groundPointersLayer.add(groundEntity);
358
+ this._columnPointersLayer.add(columnEntity);
359
+ this._headPointersLayer.add(headEntity);
360
+ this._heightsLayer.add(heightLabelEntity);
361
+ this._trackEntity.polyline.appendPoint3v(headEntity.getCartesian());
362
+ groundEntity.properties.lonLatEll.lon = ellLonLat.lon;
363
+ groundEntity.properties.lonLatEll.lat = ellLonLat.lat;
364
+ groundEntity.properties.lonLatEll.height = ellLonLat.height;
365
+ return new Promise((resolve) => {
366
+ this.getHeightELLAsync(lonLat).then((hEll) => {
367
+ groundEntity.properties.lonLatEll.height = hEll;
368
+ let altitude = 10, groundPos;
369
+ if (lonLat.height === 0) {
370
+ groundPos = headPos.add(n.scaleTo(hEll));
371
+ headPos = groundPos.add(n.scaleTo(altitude));
372
+ }
373
+ else {
374
+ altitude = lonLat.height - hEll;
375
+ groundPos = headPos.sub(n.scaleTo(altitude));
376
+ }
377
+ groundEntity.setCartesian3v(groundPos);
378
+ heightLabelEntity.setCartesian3v(headPos);
379
+ heightLabelEntity.label.setText(`${hEll.toFixed(1)} m`);
380
+ heightLabelEntity.childrenNodes[0].label.setText(`${altitude.toFixed(1)} m`);
381
+ headEntity.properties.altitude = altitude;
382
+ headEntity.setCartesian3v(headPos);
383
+ headEntity.properties.columnEntity.ray.setStartPosition3v(groundPos);
384
+ headEntity.properties.columnEntity.ray.setEndPosition3v(headPos);
385
+ this._trackEntity.polyline?.setPoint3v(headPos, headEntity.properties.index);
386
+ if (!stopPropagation) {
387
+ this.events.dispatch(this.events.addpoint, headEntity, this);
388
+ this.events.dispatch(this.events.change, this);
389
+ }
390
+ resolve(headEntity);
391
+ });
392
+ });
393
+ }
394
+ addGroundPointLonLatAsync(lonLat, altitude = 10, stopPropagation = false) {
395
+ let groundPos = this._planet.ellipsoid.lonLatToCartesian(lonLat);
396
+ return this._addPoint(groundPos, lonLat, altitude, stopPropagation);
397
+ }
398
+ addGroundPoint3vAsync(groundPos, altitude = 10, stopPropagation = false) {
399
+ let lonLat = this._planet.ellipsoid.cartesianToLonLat(groundPos);
400
+ return this._addPoint(groundPos, lonLat, altitude, stopPropagation);
401
+ }
402
+ _addPoint(groundPos, lonLat, altitude, stopPropagation = false) {
403
+ return new Promise((resolve, reject) => {
404
+ let { headEntity, groundEntity, columnEntity, heightLabelEntity } = this._createGroundPointer(groundPos, altitude);
405
+ this._groundPointersLayer.add(groundEntity);
406
+ this._columnPointersLayer.add(columnEntity);
407
+ this._headPointersLayer.add(headEntity);
408
+ this._heightsLayer.add(heightLabelEntity);
409
+ this._trackEntity.polyline.appendPoint3v(headEntity.getCartesian());
410
+ groundEntity.properties.lonLatEll.lon = lonLat.lon;
411
+ groundEntity.properties.lonLatEll.lat = lonLat.lat;
412
+ groundEntity.properties.lonLatEll.height = lonLat.height;
413
+ this.getHeightELLAsync(lonLat).then((hEll) => {
414
+ groundEntity.properties.lonLatEll.height = lonLat.height = hEll;
415
+ let groundPos = this._planet.ellipsoid.lonLatToCartesian(lonLat);
416
+ let groundNormal = this._planet.ellipsoid.getSurfaceNormal3v(groundPos);
417
+ let headPos = groundPos.add(groundNormal.scale(altitude));
418
+ heightLabelEntity.setCartesian3v(headPos);
419
+ heightLabelEntity.label.setText(`${hEll.toFixed(1)} m`);
420
+ heightLabelEntity.childrenNodes[0].label.setText(`${altitude.toFixed(1)} m`);
421
+ headEntity.setCartesian3v(headPos);
422
+ headEntity.properties.columnEntity.ray.setEndPosition3v(headPos);
423
+ this._trackEntity.polyline?.setPoint3v(headPos, headEntity.properties.index);
424
+ if (!stopPropagation) {
425
+ this.events.dispatch(this.events.addpoint, headEntity, this);
426
+ this.events.dispatch(this.events.change, this);
427
+ }
428
+ resolve(headEntity);
429
+ });
430
+ });
431
+ }
432
+ setHeadPointCartesian3v(entityIndex, headPos) {
433
+ const headEntity = this._headPointersLayer.getEntities()[entityIndex];
434
+ if (headEntity) {
435
+ let groundPos = this._planet.ellipsoid.lonLatToCartesian(headEntity.properties.lonLatEll);
436
+ let altitude = headPos.length() - groundPos.length();
437
+ if (altitude <= 0) {
438
+ headPos = groundPos;
439
+ altitude = 0;
440
+ }
441
+ headEntity.properties.altitude = altitude;
442
+ headEntity.setCartesian3v(headPos);
443
+ headEntity.properties.columnEntity.ray.setEndPosition3v(headPos);
444
+ headEntity.properties.heightLabelEntity.setCartesian3v(headPos);
445
+ headEntity.properties.heightLabelEntity.childrenNodes[0].label.setText(`${altitude.toFixed(1)} m`);
446
+ this._trackEntity.polyline.setPoint3v(headPos, entityIndex);
447
+ this.events.dispatch(this.events.change, this._pickedHeadEntity);
448
+ }
449
+ }
450
+ setGroundPointCartesian3v(entityIndex, groundPos) {
451
+ let groundEntity = this._groundPointersLayer.getEntities()[entityIndex];
452
+ if (groundEntity) {
453
+ let lonLat = this._planet.ellipsoid.cartesianToLonLat(groundPos);
454
+ groundEntity.properties.lonLatEll.lon = lonLat.lon;
455
+ groundEntity.properties.lonLatEll.lat = lonLat.lat;
456
+ groundEntity.properties.lonLatEll.height = lonLat.height;
457
+ let groundNormal = this._planet.ellipsoid.getSurfaceNormal3v(groundPos);
458
+ let headEntity = groundEntity.properties.headEntity;
459
+ let heightLabelEntity = groundEntity.properties.heightLabelEntity;
460
+ let altitude = groundEntity.properties.altitude;
461
+ groundEntity.setCartesian3v(groundPos);
462
+ let headPos = groundPos.add(groundNormal.scale(altitude));
463
+ headEntity.setCartesian3v(headPos);
464
+ headEntity.properties.columnEntity.ray.setStartPosition3v(groundPos);
465
+ headEntity.properties.columnEntity.ray.setEndPosition3v(headPos);
466
+ this._trackEntity.polyline?.setPoint3v(headPos, headEntity.properties.index);
467
+ heightLabelEntity.setCartesian3v(headPos);
468
+ heightLabelEntity.label.setText(`${lonLat.height.toFixed(1)} m`);
469
+ heightLabelEntity.childrenNodes[0].label.setText(`${altitude.toFixed(1)} m`);
470
+ this.events.dispatch(this.events.change, groundEntity.properties.headEntity);
471
+ }
472
+ }
473
+ _deactivate() {
474
+ this.renderer.events.off("ldblclick", this._onLClick);
475
+ this.renderer.events.off("mousemove", this._onMouseMove);
476
+ this.renderer.events.off("lup", this._onLUp);
477
+ this._groundPointersLayer.events.off("mouseenter", this._onGroundPointerEnter);
478
+ this._groundPointersLayer.events.off("mouseleave", this._onGroundPointerLeave);
479
+ this._groundPointersLayer.events.off("ldown", this._onGroundPointerLDown);
480
+ this._groundPointersLayer.events.off("lup", this._onGroundPointerLUp);
481
+ this._headPointersLayer.events.off("mouseenter", this._onHeadPointerEnter);
482
+ this._headPointersLayer.events.off("mouseleave", this._onHeadPointerLeave);
483
+ this._headPointersLayer.events.off("ldown", this._onHeadPointerLDown);
484
+ this._headPointersLayer.events.off("lup", this._onHeadPointerLUp);
485
+ this._trackLayer.remove();
486
+ this._groundPointersLayer.remove();
487
+ this._headPointersLayer.remove();
488
+ this._columnPointersLayer.remove();
489
+ this._trackLayer.remove();
490
+ this._heightsLayer.remove();
491
+ this._pointerLayer.remove();
492
+ this.clear();
493
+ }
494
+ setPointerVisibility(visibility) {
495
+ this._pointerLayer.setVisibility(visibility);
496
+ }
497
+ setVisibility(visibility) {
498
+ this._groundPointersLayer.setVisibility(visibility);
499
+ this._trackLayer.setVisibility(visibility);
500
+ this._columnPointersLayer.setVisibility(visibility);
501
+ this._headPointersLayer.setVisibility(visibility);
502
+ this._trackLayer.setVisibility(visibility);
503
+ this._heightsLayer.setVisibility(visibility);
504
+ this._pointerLayer.setVisibility(visibility);
505
+ }
506
+ clear() {
507
+ this._headPointersLayer.setEntities([]);
508
+ this._groundPointersLayer.setEntities([]);
509
+ this._columnPointersLayer.setEntities([]);
510
+ this._heightsLayer.setEntities([]);
511
+ this._trackEntity.polyline.setPath3v([]);
512
+ }
513
+ frame() {
514
+ if (this._clampToGround) {
515
+ let __tempVec__ = new Vec3();
516
+ const nodes = this._planet._renderedNodes;
517
+ const entities = this._groundPointersLayer.getEntities();
518
+ for (let i = 0; i < entities.length; i++) {
519
+ let ei = entities[i];
520
+ for (let j = 0; j < nodes.length; j++) {
521
+ let nj = nodes[j];
522
+ if (nj.segment.isEntityInside(ei)) {
523
+ nj.segment.getEntityTerrainPoint(ei, __tempVec__);
524
+ ei.setCartesian3v(__tempVec__);
525
+ ei.properties.columnEntity.ray.setStartPosition3v(__tempVec__);
526
+ break;
527
+ }
528
+ }
529
+ }
530
+ }
531
+ }
532
+ get ellipsoid() {
533
+ return this._planet ? this._planet.ellipsoid : null;
534
+ }
535
+ }
536
+ const ELEVATIONPROFILESCENE_EVENTS = [
537
+ "change", "addpoint"
538
+ ];
539
+ export { ElevationProfileScene };
@@ -0,0 +1,63 @@
1
+ import { EventsHandler } from "../../Events";
2
+ import { IViewParams, View, ViewEventsList } from '../../ui/View';
3
+ import { ElevationProfile, GroundItem, TrackItem } from './ElevationProfile';
4
+ import { MouseEventExt } from "../../input/MouseHandler";
5
+ interface IElevationProfileViewParams extends IViewParams {
6
+ fillStyle?: string;
7
+ }
8
+ type ElevationProfileViewEventsList = ["startdrag", "stopdrag", "pointer", "mouseenter", "mouseleave", "dblclick", "tracklength", "groundlength", "warninglength", "collisionlength"];
9
+ declare class ElevationProfileView extends View<ElevationProfile> {
10
+ events: EventsHandler<ElevationProfileViewEventsList> & EventsHandler<ViewEventsList>;
11
+ fillStyle: string;
12
+ protected _pixelsInMeter_x: number;
13
+ protected _pixelsInMeter_y: number;
14
+ protected _canvasScale: number;
15
+ $canvas: HTMLCanvasElement;
16
+ $pointerCanvas: HTMLCanvasElement;
17
+ protected _ctx: CanvasRenderingContext2D;
18
+ protected _pointerCtx: CanvasRenderingContext2D;
19
+ protected _onResizeObserver_: () => void;
20
+ protected _resizeObserver: ResizeObserver;
21
+ $loading: HTMLElement | null;
22
+ protected _isMouseOver: boolean;
23
+ protected _isDragging: boolean;
24
+ protected _clickPosX: number;
25
+ protected _clickLeftDistance: number;
26
+ protected _clickRightDistance: number;
27
+ protected _leftDistance: number;
28
+ protected _rightDistance: number;
29
+ protected _customFrame: boolean;
30
+ protected _timeStartHandler: number;
31
+ constructor(options?: IElevationProfileViewParams);
32
+ protected _onResizeObserver(): void;
33
+ get canvasScale(): number;
34
+ set canvasScale(scale: number);
35
+ resize(): void;
36
+ render(): this;
37
+ protected _hideLoading(): void;
38
+ protected _showLoading(): void;
39
+ protected _onMouseDblClick: (e: MouseEvent) => void;
40
+ protected _onMouseEnter: (e: MouseEvent) => void;
41
+ protected _onMouseOut: (e: MouseEvent) => void;
42
+ protected _onMouseDown: (e: MouseEvent) => void;
43
+ protected _onMouseUp: (e: MouseEvent) => void;
44
+ protected _onCanvasMouseMove: (e: MouseEvent) => void;
45
+ redrawPointerCanvas(x: number): void;
46
+ protected _onMouseMove: (e: MouseEvent) => void;
47
+ protected _onMouseWheelFF: (e: MouseEventExt) => void;
48
+ protected _onMouseWheel: (e: MouseEventExt) => void;
49
+ get clientWidth(): number;
50
+ get clientHeight(): number;
51
+ protected _resize(): void;
52
+ clearPointerCanvas(): void;
53
+ clearCanvas(): void;
54
+ setFrame(leftDistance: number, rightDistance: number): void;
55
+ _updateUnits(): void;
56
+ clear(): void;
57
+ draw(): void;
58
+ protected _drawLabels(coords: TrackItem[], groundCoords: GroundItem[]): void;
59
+ protected _drawTrack(coords: TrackItem[], groundCoords: GroundItem[]): void;
60
+ protected _drawTerrain(coords: number[][]): void;
61
+ protected _drawWarningAndCollision(coords: number[][]): void;
62
+ }
63
+ export { ElevationProfileView };