@openglobus/og 0.18.4 → 0.19.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.
Files changed (64) hide show
  1. package/README.md +19 -68
  2. package/css/og.css +308 -45
  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/Globe.d.ts +2 -0
  9. package/lib/js/Globe.js +3 -1
  10. package/lib/js/camera/PlanetCamera.d.ts +2 -2
  11. package/lib/js/camera/PlanetCamera.js +3 -2
  12. package/lib/js/control/DebugInfo.js +5 -0
  13. package/lib/js/control/EarthCoordinates.js +2 -2
  14. package/lib/js/control/LayerSwitcher.d.ts +18 -3
  15. package/lib/js/control/LayerSwitcher.js +111 -11
  16. package/lib/js/control/MouseNavigation.d.ts +2 -0
  17. package/lib/js/control/MouseNavigation.js +15 -15
  18. package/lib/js/control/elevationProfile/ElevationProfile.d.ts +41 -25
  19. package/lib/js/control/elevationProfile/ElevationProfile.js +106 -75
  20. package/lib/js/control/elevationProfile/ElevationProfileButtonsView.d.ts +14 -0
  21. package/lib/js/control/elevationProfile/ElevationProfileButtonsView.js +61 -0
  22. package/lib/js/control/elevationProfile/ElevationProfileControl.d.ts +33 -0
  23. package/lib/js/control/elevationProfile/ElevationProfileControl.js +153 -0
  24. package/lib/js/control/elevationProfile/ElevationProfileLegend.d.ts +20 -0
  25. package/lib/js/control/elevationProfile/ElevationProfileLegend.js +82 -0
  26. package/lib/js/control/elevationProfile/ElevationProfileScene.d.ts +80 -0
  27. package/lib/js/control/elevationProfile/ElevationProfileScene.js +539 -0
  28. package/lib/js/control/elevationProfile/ElevationProfileView.d.ts +63 -0
  29. package/lib/js/control/elevationProfile/ElevationProfileView.js +504 -0
  30. package/lib/js/control/elevationProfile/PointListDialog.d.ts +12 -0
  31. package/lib/js/control/elevationProfile/PointListDialog.js +57 -0
  32. package/lib/js/control/heightRuler/HeightRulerScene.js +1 -1
  33. package/lib/js/control/index.d.ts +2 -1
  34. package/lib/js/control/index.js +2 -1
  35. package/lib/js/control/ruler/RulerScene.js +3 -3
  36. package/lib/js/control/selection/SelectionScene.js +2 -2
  37. package/lib/js/entity/Entity.js +5 -1
  38. package/lib/js/entity/Polyline.js +1 -1
  39. package/lib/js/layer/GeoImage.js +3 -0
  40. package/lib/js/layer/Layer.d.ts +18 -4
  41. package/lib/js/layer/Layer.js +25 -4
  42. package/lib/js/layer/XYZ.d.ts +0 -1
  43. package/lib/js/quadTree/Node.d.ts +21 -3
  44. package/lib/js/quadTree/Node.js +173 -62
  45. package/lib/js/renderer/Renderer.d.ts +0 -1
  46. package/lib/js/renderer/Renderer.js +22 -44
  47. package/lib/js/renderer/RendererEvents.d.ts +1 -0
  48. package/lib/js/renderer/RendererEvents.js +5 -7
  49. package/lib/js/scene/Planet.d.ts +33 -4
  50. package/lib/js/scene/Planet.js +206 -84
  51. package/lib/js/segment/Segment.d.ts +7 -1
  52. package/lib/js/segment/Segment.js +40 -12
  53. package/lib/js/shaders/drawnode.js +21 -2
  54. package/lib/js/shaders/geoObject.js +26 -18
  55. package/lib/js/terrain/GlobusTerrain.d.ts +3 -0
  56. package/lib/js/terrain/GlobusTerrain.js +15 -3
  57. package/lib/js/terrain/MapboxTerrain.js +29 -29
  58. package/lib/js/ui/Dialog.js +1 -1
  59. package/lib/js/utils/TerrainWorker.js +1 -1
  60. package/lib/js/utils/shared.d.ts +3 -1
  61. package/lib/js/utils/shared.js +22 -3
  62. package/package.json +2 -2
  63. package/lib/js/shaders/pickingMask.d.ts +0 -2
  64. 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
+ hideInLayerSwitcher: true
136
+ });
137
+ this._groundPointersLayer = new Vector("ground-pointers", {
138
+ entities: [],
139
+ pickingEnabled: true,
140
+ hideInLayerSwitcher: true,
141
+ scaleByDistance: [1, 5000, 0.02],
142
+ pickingScale: 1.5
143
+ });
144
+ this._headPointersLayer = new Vector("head-pointers", {
145
+ entities: [],
146
+ pickingEnabled: true,
147
+ hideInLayerSwitcher: true,
148
+ scaleByDistance: [1, 10000, 0.02],
149
+ pickingScale: 1
150
+ });
151
+ this._columnPointersLayer = new Vector("column-pointers", {
152
+ entities: [],
153
+ pickingEnabled: false,
154
+ hideInLayerSwitcher: true
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
+ hideInLayerSwitcher: true
168
+ });
169
+ this._heightsLayer = new Vector("heights-labels", {
170
+ entities: [],
171
+ pickingEnabled: false,
172
+ hideInLayerSwitcher: true
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
+ hideInLayerSwitcher: true
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 };