@openglobus/og 0.18.3 → 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 (44) 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/Atmosphere.js +7 -10
  11. package/lib/js/control/EarthCoordinates.js +2 -2
  12. package/lib/js/control/elevationProfile/ElevationProfile.d.ts +41 -25
  13. package/lib/js/control/elevationProfile/ElevationProfile.js +103 -74
  14. package/lib/js/control/elevationProfile/ElevationProfileButtonsView.d.ts +14 -0
  15. package/lib/js/control/elevationProfile/ElevationProfileButtonsView.js +61 -0
  16. package/lib/js/control/elevationProfile/ElevationProfileControl.d.ts +33 -0
  17. package/lib/js/control/elevationProfile/ElevationProfileControl.js +153 -0
  18. package/lib/js/control/elevationProfile/ElevationProfileLegend.d.ts +20 -0
  19. package/lib/js/control/elevationProfile/ElevationProfileLegend.js +82 -0
  20. package/lib/js/control/elevationProfile/ElevationProfileScene.d.ts +80 -0
  21. package/lib/js/control/elevationProfile/ElevationProfileScene.js +539 -0
  22. package/lib/js/control/elevationProfile/ElevationProfileView.d.ts +63 -0
  23. package/lib/js/control/elevationProfile/ElevationProfileView.js +504 -0
  24. package/lib/js/control/elevationProfile/PointListDialog.d.ts +12 -0
  25. package/lib/js/control/elevationProfile/PointListDialog.js +57 -0
  26. package/lib/js/control/index.d.ts +2 -1
  27. package/lib/js/control/index.js +2 -1
  28. package/lib/js/entity/Polyline.js +1 -1
  29. package/lib/js/layer/GeoImage.js +3 -0
  30. package/lib/js/renderer/Renderer.d.ts +0 -1
  31. package/lib/js/renderer/Renderer.js +3 -28
  32. package/lib/js/renderer/RendererEvents.js +0 -7
  33. package/lib/js/scene/Planet.d.ts +4 -0
  34. package/lib/js/scene/Planet.js +9 -1
  35. package/lib/js/terrain/GlobusTerrain.d.ts +3 -0
  36. package/lib/js/terrain/GlobusTerrain.js +14 -2
  37. package/lib/js/terrain/MapboxTerrain.js +29 -29
  38. package/lib/js/ui/Dialog.js +1 -1
  39. package/lib/js/utils/TerrainWorker.js +1 -1
  40. package/lib/js/utils/shared.d.ts +2 -1
  41. package/lib/js/utils/shared.js +21 -3
  42. package/package.json +1 -1
  43. package/lib/js/shaders/pickingMask.d.ts +0 -2
  44. package/lib/js/shaders/pickingMask.js +0 -22
@@ -137,7 +137,7 @@ declare class PlanetCamera extends Camera {
137
137
  * @param {Number} height - Camera height
138
138
  * @returns {Vec3}
139
139
  */
140
- getExtentPosition(extent: Extent, height?: number): Vec3;
140
+ getExtentPosition(extent: Extent, height?: number | null): Vec3;
141
141
  /**
142
142
  * View current extent.
143
143
  * @public
@@ -156,7 +156,7 @@ declare class PlanetCamera extends Camera {
156
156
  * @param {Function} [startCallback] - Callback that calls before the flying begins.
157
157
  * @param {Function} [frameCallback] - Each frame callback
158
158
  */
159
- flyExtent(extent: Extent, height?: number, up?: Vec3, ampl?: number, completeCallback?: Function, startCallback?: Function, frameCallback?: Function): void;
159
+ flyExtent(extent: Extent, height?: number | null, up?: Vec3 | null, ampl?: number | null, completeCallback?: Function | null, startCallback?: Function | null, frameCallback?: Function | null): void;
160
160
  viewDistance(cartesian: Vec3, distance?: number): void;
161
161
  flyDistance(cartesian: Vec3, distance?: number, ampl?: number, completeCallback?: Function, startCallback?: Function, frameCallback?: Function): void;
162
162
  /**
@@ -133,7 +133,8 @@ class PlanetCamera extends Camera {
133
133
  * @param {Number} height - Camera height
134
134
  * @returns {Vec3}
135
135
  */
136
- getExtentPosition(extent, height = 0) {
136
+ getExtentPosition(extent, height) {
137
+ height = height || 0;
137
138
  let north = extent.getNorth();
138
139
  let south = extent.getSouth();
139
140
  let east = extent.getEast();
@@ -196,7 +197,7 @@ class PlanetCamera extends Camera {
196
197
  * @param {Function} [frameCallback] - Each frame callback
197
198
  */
198
199
  flyExtent(extent, height, up, ampl, completeCallback, startCallback, frameCallback) {
199
- this.flyCartesian(this.getExtentPosition(extent, height), Vec3.ZERO, up, ampl, completeCallback, startCallback, frameCallback);
200
+ this.flyCartesian(this.getExtentPosition(extent, height), Vec3.ZERO, up, ampl == null ? 1 : ampl, completeCallback, startCallback, frameCallback);
200
201
  }
201
202
  viewDistance(cartesian, distance = 10000.0) {
202
203
  let p0 = this.eye.add(this.getForward().scaleTo(distance));
@@ -30,7 +30,7 @@ export class Atmosphere extends Control {
30
30
  this.planet && this.planet.events.off("draw", this._drawBackground);
31
31
  }
32
32
  _drawAtmosphereTextures() {
33
- let width = 256, height = 128;
33
+ let width = 1024, height = 1024;
34
34
  this._transmittanceBuffer = new Framebuffer(this.renderer.handler, {
35
35
  width: width,
36
36
  height: height,
@@ -142,7 +142,7 @@ function atmosphereBackgroundShader() {
142
142
  gl_Position = vec4(corners, 0.0, 1.0);
143
143
  }`,
144
144
  fragmentShader: `
145
- precision highp float;
145
+ precision lowp float;
146
146
 
147
147
  ${atmos.COMMON}
148
148
 
@@ -242,7 +242,7 @@ function atmosphereBackgroundShader() {
242
242
  if (offset > 0.0) {
243
243
  // intersection of camera ray with atmosphere
244
244
  rayOrigin = cameraPosition + rayDirection * offset;
245
- }
245
+ }
246
246
 
247
247
  float height = length(rayOrigin) - BOTTOM_RADIUS;
248
248
  float rayAngle = dot(rayOrigin, rayDirection) / length(rayOrigin);
@@ -258,12 +258,13 @@ function atmosphereBackgroundShader() {
258
258
 
259
259
  bool hitGround = intersectSphere(cameraPosition, rayDirection, BOTTOM_RADIUS, distanceToGround) && distanceToGround > 0.0;
260
260
 
261
- if(intersectSphere(cameraPosition, rayDirection, BOTTOM_RADIUS - 15000.0, distanceToGround) && hitGround){
261
+ if(intersectSphere(cameraPosition, rayDirection, BOTTOM_RADIUS - 15000.0, distanceToGround) && hitGround)
262
+ {
262
263
  discard;
263
264
  }
264
265
 
265
266
  float segmentLength = ((hitGround ? distanceToGround : distanceToSpace) - max(offset, 0.0)) / float(SAMPLE_COUNT);
266
-
267
+
267
268
  float t = segmentLength * 0.5;
268
269
 
269
270
  vec3 transmittanceCamera;
@@ -276,17 +277,13 @@ function atmosphereBackgroundShader() {
276
277
  vec3 up = position / length(position);
277
278
  float rayAngle = dot(up, rayDirection);
278
279
  float lightAngle = dot(up, lightDirection);
279
- // shadow is ommitted because it can create banding artifacts with low sample counts
280
- // float distanceToGround;
281
- // float shadow = intersectSphere(position, lightDirection, BOTTOM_RADIUS, distanceToGround) && distanceToGround >= 0.0 ? 0.0 : 1.0;
282
- float shadow = 1.0;
283
280
  vec3 transmittanceToSpace = transmittanceFromTexture(height, cameraBelow ? -rayAngle : rayAngle);
284
281
  transmittanceCamera = cameraBelow ? (transmittanceToSpace / transmittanceFromCameraToSpace) : (transmittanceFromCameraToSpace / transmittanceToSpace);
285
282
  transmittanceLight = transmittanceFromTexture(height, lightAngle);
286
283
  vec2 opticalDensity = exp(-height / rayleighMieHeights);
287
284
  vec3 scatteredLight = transmittanceLight * (rayleighScatteringCoefficient * opticalDensity.x * rayleighPhase + mieScatteringCoefficient * opticalDensity.y * miePhase);
288
285
  scatteredLight += multipleScatteringContributionFromTexture(height, lightAngle) * (rayleighScatteringCoefficient * opticalDensity.x + mieScatteringCoefficient * opticalDensity.y);
289
- light += shadow * transmittanceCamera * scatteredLight * segmentLength;
286
+ light += transmittanceCamera * scatteredLight * segmentLength;
290
287
  t += segmentLength;
291
288
  }
292
289
 
@@ -51,8 +51,8 @@ export class EarthCoordinates extends Control {
51
51
  else {
52
52
  this._lonSideEl.innerHTML = 'W';
53
53
  }
54
- this._latValEl.innerHTML = Math.abs(lat).toFixed(5) + '°';
55
- this._lonValEl.innerHTML = Math.abs(lon).toFixed(5) + '°';
54
+ this._latValEl.innerHTML = Math.abs(lat).toFixed(7) + '°';
55
+ this._lonValEl.innerHTML = Math.abs(lon).toFixed(7) + '°';
56
56
  }
57
57
  }
58
58
  _SHOW_DEGREE(ll) {
@@ -2,60 +2,76 @@ import { EventsHandler } from '../../Events';
2
2
  import { Vec3 } from "../../math/Vec3";
3
3
  import { Planet } from "../../scene/Planet";
4
4
  import { LonLat } from "../../LonLat";
5
- interface ElevationProfileParams {
6
- planet: Planet;
5
+ export interface ElevationProfileParams {
6
+ planet?: Planet;
7
7
  }
8
- interface IProfileData {
8
+ export interface IProfileData {
9
9
  dist: number;
10
10
  minY: number;
11
11
  maxY: number;
12
- trackCoords: number[][];
13
- groundCoords: number[][];
12
+ trackCoords: TrackItem[];
13
+ groundCoords: GroundItem[];
14
14
  }
15
- type ElevationProfileEventsList = ["profilecollected"];
15
+ export type ElevationProfileDrawData = [TrackItem[], GroundItem[]];
16
+ type ElevationProfileEventsList = ["startcollecting", "profilecollected", "clear"];
16
17
  /**
17
18
  * Point types
18
19
  */
19
- declare const SAFE = 0;
20
- declare const WARNING = 1;
21
- declare const COLLISION = 2;
22
- declare class ElevationProfile {
20
+ export declare const SAFE = 0;
21
+ export declare const WARNING = 1;
22
+ export declare const COLLISION = 2;
23
+ type WarningLevel = typeof SAFE | typeof WARNING | typeof COLLISION;
24
+ /**
25
+ * 0 - distance, 1 - elevation, 2 - related ground point index
26
+ */
27
+ export type TrackItem = [number, number, number];
28
+ /**
29
+ * 0 - distance, 1 - elevation, 2 - warning level, 3 - ..., 4 - related track point index
30
+ */
31
+ export type GroundItem = [number, number, WarningLevel, number, number];
32
+ export declare class ElevationProfile {
23
33
  events: EventsHandler<ElevationProfileEventsList>;
24
- planet: Planet;
34
+ planet: Planet | null;
25
35
  protected _warningHeightLevel: number;
26
36
  protected _pointsReady: boolean;
27
37
  protected _isWarning: boolean;
38
+ protected _planeDistance: number;
28
39
  protected _minX: number;
29
40
  protected _maxX: number;
30
41
  protected _minY: number;
31
42
  protected _maxY: number;
32
- protected _drawData: [number[][], number[][]];
43
+ protected _drawData: ElevationProfileDrawData;
33
44
  protected _promiseArr: Promise<void | number>[];
34
45
  protected _promiseCounter: number;
35
46
  protected _pMaxY: number;
36
47
  protected _pMinY: number;
37
48
  protected _pDist: number;
38
- protected _pTrackCoords: number[][];
39
- protected _pGroundCoords: number[][];
49
+ protected _pTrackCoords: TrackItem[];
50
+ protected _pGroundCoords: GroundItem[];
40
51
  protected _pIndex: number;
41
- constructor(options: ElevationProfileParams);
52
+ constructor(options?: ElevationProfileParams);
53
+ bindPlanet(planet: Planet): void;
42
54
  setWarningHeightLevel(warningHeight?: number): void;
43
- setRange(minX: number, maxX: number, minY: number, maxY: number): void;
44
- protected _getHeightAsync(ll: LonLat, pIndex: number): Promise<number>;
45
- protected _collectCoordsBetweenTwoTrackPoints(internalPoints: number, scaleFactor: number, p0: Vec3, trackDir: Vec3): void;
46
- protected _collectAllPoints(pointsLonLat: LonLat[]): void;
47
- protected _getGroundElevation(lonLat: LonLat): void;
48
- protected _collectPromise(resolve: (p: IProfileData) => void): void;
49
- protected _calcPointsAsync(pointsLonLat: LonLat[]): Promise<IProfileData>;
55
+ setRange(minX: number, maxX: number, minY?: number, maxY?: number): void;
56
+ protected _getHeightAsync(ll: LonLat, pIndex: number, promiseCounter: number): Promise<number>;
57
+ protected _collectCoordsBetweenTwoTrackPoints(index: number, internalPoints: number, scaleFactor: number, p0: Vec3, trackDir: Vec3, promiseCounter: number): void;
58
+ protected _collectAllPoints(pointsLonLat: LonLat[], promiseCounter: number): void;
59
+ protected _getGroundElevation(lonLat: LonLat, index: number, promiseCounter: number): void;
60
+ protected _calcPointsAsync(pointsLonLat: LonLat[], promiseCounter: number): Promise<IProfileData>;
50
61
  get minX(): number;
62
+ get planeDistance(): number;
51
63
  get maxX(): number;
52
64
  get minY(): number;
53
65
  get maxY(): number;
54
66
  get pointsReady(): boolean;
55
67
  get isWarningOrCollision(): boolean;
56
- collectProfile(pointsLonLat: LonLat[]): void;
57
- protected _setPointType(pIndex: number): void;
68
+ get drawData(): ElevationProfileDrawData;
69
+ collectProfile(pointsLonLat: LonLat[]): Promise<ElevationProfileDrawData>;
70
+ protected _updatePointType(pIndex: number): void;
71
+ /**
72
+ * @deprecated
73
+ */
58
74
  protected _setPointsType(): void;
59
75
  clear(): void;
60
76
  }
61
- export { COLLISION, SAFE, WARNING, type IProfileData, ElevationProfile, };
77
+ export {};
@@ -1,13 +1,14 @@
1
1
  import { Deferred } from '../../Deferred';
2
2
  import { createEvents } from '../../Events';
3
3
  import { Vec3 } from "../../math/Vec3";
4
- const ELEVATIONPROFILE_EVENTS = ["profilecollected"];
4
+ const DEFAULT_WARNING_HEIGHT_LEVEL = 5;
5
+ const ELEVATIONPROFILE_EVENTS = ["startcollecting", "profilecollected", "clear"];
5
6
  /**
6
7
  * Point types
7
8
  */
8
- const SAFE = 0;
9
- const WARNING = 1;
10
- const COLLISION = 2;
9
+ export const SAFE = 0;
10
+ export const WARNING = 1;
11
+ export const COLLISION = 2;
11
12
  /**
12
13
  * drawData index names
13
14
  */
@@ -16,51 +17,75 @@ const GROUND = 1;
16
17
  const SEGMMENT_LENGTH = 1.0; // Distance between query points on the ground
17
18
  const GROUND_OFFSET = 1.0; // Ground level offset
18
19
  const BOTTOM_PADDING = 0.1; // Range minY padding in percentage from the bottom
19
- const TOP_PADDING = 0.1; // Range maxY padding in percentage from the top
20
+ const TOP_PADDING = 0.2; // Range maxY padding in percentage from the top
20
21
  const HEIGHT_EPS = 0.1; // Warning height level error
21
- class ElevationProfile {
22
- constructor(options) {
22
+ export class ElevationProfile {
23
+ constructor(options = {}) {
23
24
  this.events = createEvents(ELEVATIONPROFILE_EVENTS);
24
- this.planet = options.planet;
25
- this._warningHeightLevel = 50;
25
+ this.planet = options.planet || null;
26
+ this._warningHeightLevel = DEFAULT_WARNING_HEIGHT_LEVEL;
26
27
  this._pointsReady = false;
27
28
  this._isWarning = false;
28
29
  this._minX = 0;
29
- this._maxX = 1000;
30
+ this._planeDistance = this._maxX = 1000;
30
31
  this._minY = 0;
31
32
  this._maxY = 200;
32
- this._drawData = [][0];
33
+ this._drawData = [[], []];
33
34
  this._promiseArr = [];
34
35
  this._promiseCounter = 0;
35
36
  this._pMaxY = 0;
36
37
  this._pMinY = 0;
37
38
  this._pDist = 0;
38
- this._pTrackCoords = [[0, 0, SAFE]];
39
- this._pGroundCoords = [[0, 0, SAFE]];
39
+ this._pTrackCoords = [];
40
+ this._pGroundCoords = [];
40
41
  this._pIndex = 0;
41
42
  }
43
+ bindPlanet(planet) {
44
+ this.planet = planet;
45
+ }
42
46
  setWarningHeightLevel(warningHeight = 0) {
43
47
  this._warningHeightLevel = warningHeight;
44
48
  }
45
49
  setRange(minX, maxX, minY, maxY) {
46
50
  this._minX = minX;
47
51
  this._maxX = maxX;
48
- this._minY = minY;
49
- this._maxY = maxY;
52
+ if (minY) {
53
+ this._minY = minY;
54
+ }
55
+ if (maxY) {
56
+ this._maxY = maxY;
57
+ }
50
58
  }
51
- _getHeightAsync(ll, pIndex) {
59
+ _getHeightAsync(ll, pIndex, promiseCounter) {
52
60
  let def = new Deferred();
53
- this.planet.terrain.getHeightAsync(ll, (elv) => {
54
- elv += this.planet.terrain.geoid.getHeightLonLat(ll);
55
- this._pGroundCoords[pIndex][1] = elv;
56
- this._pGroundCoords[pIndex][2] = SAFE;
57
- this._pGroundCoords[pIndex][3] = ll.height;
58
- this._setPointType(pIndex);
59
- def.resolve(elv);
60
- });
61
+ if (this.planet) {
62
+ let msl = this.planet.terrain.geoid.getHeightLonLat(ll);
63
+ this.planet.terrain.getHeightAsync(ll, (elv) => {
64
+ if (this.planet && promiseCounter === this._promiseCounter) {
65
+ elv += msl;
66
+ this._pGroundCoords[pIndex][1] = elv;
67
+ this._pGroundCoords[pIndex][2] = SAFE;
68
+ this._pGroundCoords[pIndex][3] = ll.height;
69
+ if (elv > this._pMaxY)
70
+ this._pMaxY = elv;
71
+ if (elv < this._pMinY)
72
+ this._pMinY = elv;
73
+ this._updatePointType(pIndex);
74
+ def.resolve(elv);
75
+ }
76
+ else {
77
+ def.reject();
78
+ }
79
+ });
80
+ }
81
+ else {
82
+ def.reject();
83
+ }
61
84
  return def.promise;
62
85
  }
63
- _collectCoordsBetweenTwoTrackPoints(internalPoints, scaleFactor, p0, trackDir) {
86
+ _collectCoordsBetweenTwoTrackPoints(index, internalPoints, scaleFactor, p0, trackDir, promiseCounter) {
87
+ if (!this.planet)
88
+ return;
64
89
  for (let j = 1; j <= internalPoints; j++) {
65
90
  this._pDist += SEGMMENT_LENGTH;
66
91
  this._pIndex++;
@@ -68,19 +93,17 @@ class ElevationProfile {
68
93
  let dirSegLen = j * scaleFactor;
69
94
  let pjd = p0.add(trackDir.scaleTo(dirSegLen));
70
95
  let llx = this.planet.ellipsoid.cartesianToLonLat(pjd);
71
- this._pGroundCoords[this._pIndex] = [this._pDist, 0, SAFE];
96
+ this._pGroundCoords[this._pIndex] = [this._pDist, 0, SAFE, 0, index];
72
97
  ((lonlat, index) => {
73
- this._promiseArr.push(this._getHeightAsync(lonlat, index)
74
- .then((elv) => {
75
- if (elv > this._pMaxY)
76
- this._pMaxY = elv;
77
- if (elv < this._pMinY)
78
- this._pMinY = elv;
79
- }));
98
+ this._promiseArr.push(this._getHeightAsync(lonlat, index, promiseCounter));
80
99
  })(llx, this._pIndex);
81
100
  }
82
101
  }
83
- _collectAllPoints(pointsLonLat) {
102
+ _collectAllPoints(pointsLonLat, promiseCounter) {
103
+ if (!this.planet)
104
+ return;
105
+ if (promiseCounter !== this._promiseCounter)
106
+ return;
84
107
  let p0 = new Vec3(), p1 = new Vec3();
85
108
  for (let i = 1, len = pointsLonLat.length; i < len; i++) {
86
109
  let lonlat0 = pointsLonLat[i - 1], lonlat1 = pointsLonLat[i];
@@ -93,11 +116,11 @@ class ElevationProfile {
93
116
  let projLen = proj.length();
94
117
  let internalPoints = Math.floor(projLen / SEGMMENT_LENGTH);
95
118
  let scaleFactor = SEGMMENT_LENGTH * dirLength / projLen;
96
- this._getGroundElevation(lonlat0);
119
+ this._getGroundElevation(lonlat0, i - 1, promiseCounter);
97
120
  proj.normalize();
98
121
  trackDir.normalize();
99
122
  // Getting internal point elevations and looking for the collisions
100
- this._collectCoordsBetweenTwoTrackPoints(internalPoints, scaleFactor, p0, trackDir);
123
+ this._collectCoordsBetweenTwoTrackPoints(i - 1, internalPoints, scaleFactor, p0, trackDir, promiseCounter);
101
124
  this._pDist += projLen - internalPoints * SEGMMENT_LENGTH;
102
125
  this._pIndex++;
103
126
  let elv = lonlat1.height;
@@ -105,49 +128,41 @@ class ElevationProfile {
105
128
  this._pMaxY = elv;
106
129
  if (elv < this._pMinY)
107
130
  this._pMinY = elv;
108
- this._pTrackCoords[i] = [this._pDist, elv];
131
+ this._pTrackCoords[i] = [this._pDist, elv, this._pIndex];
109
132
  }
110
133
  }
111
- _getGroundElevation(lonLat) {
112
- this._pGroundCoords[this._pIndex] = [this._pDist, 0, SAFE];
113
- this._promiseArr.push(this._getHeightAsync(lonLat, this._pIndex)
114
- .then((elv) => {
115
- if (typeof elv === 'number') {
116
- if ((elv > this._pMaxY) && (elv))
117
- this._pMaxY = elv;
118
- if ((elv < this._pMinY) && (elv))
119
- this._pMinY = elv;
120
- }
121
- }));
122
- }
123
- _collectPromise(resolve) {
124
- Promise.all(this._promiseArr).then(() => {
125
- resolve({
126
- dist: this._pDist,
127
- minY: this._pMinY,
128
- maxY: this._pMaxY,
129
- trackCoords: this._pTrackCoords,
130
- groundCoords: this._pGroundCoords
131
- });
132
- });
134
+ _getGroundElevation(lonLat, index, promiseCounter) {
135
+ this._pGroundCoords[this._pIndex] = [this._pDist, 0, SAFE, 0, index];
136
+ this._promiseArr.push(this._getHeightAsync(lonLat, this._pIndex, promiseCounter));
133
137
  }
134
- _calcPointsAsync(pointsLonLat) {
138
+ _calcPointsAsync(pointsLonLat, promiseCounter) {
135
139
  return new Promise((resolve, reject) => {
136
- this._pTrackCoords = [[0, pointsLonLat[0].height]];
140
+ this._pTrackCoords = [[0, pointsLonLat[0].height, 0]];
137
141
  this._pMaxY = pointsLonLat[0].height;
138
142
  this._pMinY = this._pMaxY;
139
143
  this._pDist = 0;
140
- this._pGroundCoords = [[0, 0, SAFE]];
144
+ this._pGroundCoords = [];
141
145
  this._pIndex = 0;
142
146
  this._promiseArr = [];
143
- this._collectAllPoints(pointsLonLat);
144
- this._getGroundElevation(pointsLonLat[pointsLonLat.length - 1]);
145
- this._collectPromise(resolve);
147
+ this._collectAllPoints(pointsLonLat, promiseCounter);
148
+ this._getGroundElevation(pointsLonLat[pointsLonLat.length - 1], pointsLonLat.length - 1, promiseCounter);
149
+ Promise.all(this._promiseArr).then(() => {
150
+ resolve({
151
+ dist: this._pDist,
152
+ minY: this._pMinY,
153
+ maxY: this._pMaxY,
154
+ trackCoords: this._pTrackCoords,
155
+ groundCoords: this._pGroundCoords
156
+ });
157
+ });
146
158
  });
147
159
  }
148
160
  get minX() {
149
161
  return this._minX;
150
162
  }
163
+ get planeDistance() {
164
+ return this._planeDistance;
165
+ }
151
166
  get maxX() {
152
167
  return this._maxX;
153
168
  }
@@ -163,24 +178,34 @@ class ElevationProfile {
163
178
  get isWarningOrCollision() {
164
179
  return this._isWarning;
165
180
  }
181
+ get drawData() {
182
+ return this._drawData;
183
+ }
166
184
  collectProfile(pointsLonLat) {
185
+ let def = new Deferred();
186
+ if (!this.planet)
187
+ def.reject();
167
188
  this._pointsReady = false;
168
189
  this._isWarning = false;
169
190
  if (!pointsLonLat || !pointsLonLat.length)
170
- return;
191
+ def.reject();
192
+ this.events.dispatch(this.events.startcollecting, this);
171
193
  this._promiseCounter++;
172
194
  ((counter) => {
173
- this._calcPointsAsync(pointsLonLat).then((p) => {
195
+ this._calcPointsAsync(pointsLonLat, counter).then((p) => {
174
196
  if (counter === this._promiseCounter) {
197
+ this._planeDistance = p.dist;
175
198
  this.setRange(0, p.dist, p.minY - BOTTOM_PADDING * Math.abs(p.minY), p.maxY + Math.abs(p.maxY) * TOP_PADDING);
176
199
  this._pointsReady = true;
177
200
  this._drawData = [p.trackCoords, p.groundCoords];
178
201
  this.events.dispatch(this.events.profilecollected, this._drawData, this);
202
+ def.resolve(this._drawData);
179
203
  }
180
204
  });
181
205
  })(this._promiseCounter);
206
+ return def.promise;
182
207
  }
183
- _setPointType(pIndex) {
208
+ _updatePointType(pIndex) {
184
209
  if ((this._pGroundCoords[pIndex][3] >= this._pGroundCoords[pIndex][1]) &&
185
210
  (this._pGroundCoords[pIndex][3] < this._pGroundCoords[pIndex][1] + this._warningHeightLevel - HEIGHT_EPS)) {
186
211
  this._pGroundCoords[pIndex][2] = WARNING;
@@ -188,30 +213,34 @@ class ElevationProfile {
188
213
  if (this._pGroundCoords[pIndex][3] <= this._pGroundCoords[pIndex][1] + GROUND_OFFSET) {
189
214
  this._pGroundCoords[pIndex][2] = COLLISION;
190
215
  }
191
- if (this._pGroundCoords[pIndex][2] == WARNING || this._pGroundCoords[pIndex][2] == COLLISION) {
216
+ if (this._pGroundCoords[pIndex][2] === WARNING || this._pGroundCoords[pIndex][2] === COLLISION) {
192
217
  this._isWarning = true;
193
218
  }
194
219
  }
220
+ /**
221
+ * @deprecated
222
+ */
195
223
  _setPointsType() {
196
224
  this._isWarning = false;
197
225
  this._pTrackCoords = this._drawData[TRACK];
198
226
  this._pGroundCoords = this._drawData[GROUND];
199
227
  for (let i = 0; i < this._pGroundCoords.length; i++) {
200
- this._setPointType(i);
228
+ this._updatePointType(i);
201
229
  }
202
230
  this._drawData[GROUND] = this._pGroundCoords;
203
231
  this.events.dispatch(this.events.profilecollected, this._drawData, this);
204
232
  }
205
233
  clear() {
234
+ this._promiseCounter = 0;
206
235
  this._pointsReady = false;
207
236
  this._isWarning = false;
208
- this._drawData = [][0];
237
+ this._drawData = [[], []];
209
238
  this._pMaxY = 0;
210
239
  this._pMinY = 0;
211
240
  this._pDist = 0;
212
- this._pTrackCoords = [[0, 0, SAFE]];
213
- this._pGroundCoords = [[0, 0, SAFE]];
241
+ this._pTrackCoords = [];
242
+ this._pGroundCoords = [];
214
243
  this._pIndex = 0;
244
+ this.events.dispatch(this.events.clear, this._drawData, this);
215
245
  }
216
246
  }
217
- export { COLLISION, SAFE, WARNING, ElevationProfile, };
@@ -0,0 +1,14 @@
1
+ import { View, IViewParams, ViewEventsList } from "../../ui/View";
2
+ import { ToggleButton } from "../../ui/ToggleButton";
3
+ import { EventsHandler } from "../../Events";
4
+ import { ElevationProfile } from "./ElevationProfile";
5
+ interface IElevationProfileButtonsViewParams extends IViewParams {
6
+ }
7
+ type ElevationProfileButtonsViewEventsList = ["reset", "list", "location"];
8
+ export declare class ElevationProfileButtonsView extends View<ElevationProfile> {
9
+ events: EventsHandler<ElevationProfileButtonsViewEventsList> & EventsHandler<ViewEventsList>;
10
+ pointListBtn: ToggleButton;
11
+ constructor(params?: IElevationProfileButtonsViewParams);
12
+ render(params: any): this;
13
+ }
14
+ export {};
@@ -0,0 +1,61 @@
1
+ import { View } from "../../ui/View";
2
+ import { Button } from "../../ui/Button";
3
+ import { ToggleButton } from "../../ui/ToggleButton";
4
+ const TEMPLATE = '<div class="og-elevationprofile-buttons"></div>';
5
+ const RESET_SVG_ICON = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
6
+ <svg width="30" height="30" viewBox="0 0 30 30" version="1.1">
7
+ <g transform="translate(0,-289.0625)">
8
+ <path d="M 15 6 C 10.041282 6 6 10.04128 6 15 C 6 19.95872 10.041282 24 15 24 C 16.586491 24 18.07668 23.58246 19.373047 22.857422 L 17.888672 21.375 C 17.00816 21.772814 16.032235 22 15 22 C 11.122162 22 8 18.87784 8 15 C 8 11.12216 11.122162 8 15 8 C 18.877838 8 22 11.12216 22 15 L 19 15 L 23 20 L 27 15 L 24 15 C 24 10.04128 19.958718 6 15 6 z " transform="translate(0,289.0625)" />
9
+ </g>
10
+ </svg>`;
11
+ const LIST_SVG_ICON = `<?xml version="1.0" encoding="utf-8"?><svg width="800px" height="800px" viewBox="0 0 32 32" id="icon" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:none;}</style></defs><title>list</title><rect x="10" y="6" width="18" height="2"/><rect x="10" y="24" width="18" height="2"/><rect x="10" y="15" width="18" height="2"/><rect x="4" y="15" width="2" height="2"/><rect x="4" y="6" width="2" height="2"/><rect x="4" y="24" width="2" height="2"/></svg>`;
12
+ const LOCATION_SVG_ICON = `<?xml version="1.0" encoding="utf-8"?>
13
+ <!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
14
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
15
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve">
16
+ <metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
17
+ <g><g><path fill="#000000" d="M127,169.4c23.7,0,42.8-18.3,42.8-41s-19.2-41-42.8-41c-23.7,0-42.8,18.4-42.8,41S103.4,169.4,127,169.4z"/><path fill="#000000" d="M221.7,120.2c-3.8-44-40.9-78.9-87-82V15h-16.3v23.6c-44.8,4-80.3,38.5-84.1,81.7H10v15.6h24.3c3.8,43.1,39.3,77.4,84.1,81.7V241h16.3v-23.2c46-3.1,83.2-37.9,87-82H246v-15.6H221.7L221.7,120.2L221.7,120.2z M128,201.6c-42.5,0-76.7-33-76.7-73.4c0-40.4,34.5-73.4,76.7-73.4c42.5,0,76.7,33,76.7,73.4C204.7,168.5,170.5,201.6,128,201.6L128,201.6z"/></g></g>
18
+ </svg>`;
19
+ const ELEVATIONPROFILEBUTTONSVIEW_EVENTS = ["reset", "list", "location"];
20
+ export class ElevationProfileButtonsView extends View {
21
+ constructor(params = {}) {
22
+ super({
23
+ ...params,
24
+ template: TEMPLATE
25
+ });
26
+ //@ts-ignore
27
+ this.events = this.events.registerNames(ELEVATIONPROFILEBUTTONSVIEW_EVENTS);
28
+ this.pointListBtn = new ToggleButton({
29
+ classList: ["og-elevationprofile-button"],
30
+ icon: LIST_SVG_ICON,
31
+ title: "Point List"
32
+ });
33
+ this.pointListBtn.events.on("change", (isActive) => {
34
+ this.events.dispatch(this.events.list, isActive);
35
+ });
36
+ }
37
+ render(params) {
38
+ super.render(params);
39
+ let resetBtn = new Button({
40
+ classList: ["og-elevationprofile-button"],
41
+ icon: RESET_SVG_ICON,
42
+ title: "Reset"
43
+ });
44
+ resetBtn.appendTo(this.el);
45
+ resetBtn.events.on("click", () => {
46
+ this.model.clear();
47
+ this.events.dispatch(this.events.reset, this);
48
+ });
49
+ this.pointListBtn.appendTo(this.el);
50
+ let locationBtn = new Button({
51
+ classList: ["og-elevationprofile-button", "og-elevationprofile-button__location"],
52
+ icon: LOCATION_SVG_ICON,
53
+ title: "View bounds"
54
+ });
55
+ locationBtn.appendTo(this.el);
56
+ locationBtn.events.on("click", () => {
57
+ this.events.dispatch(this.events.location, this);
58
+ });
59
+ return this;
60
+ }
61
+ }
@@ -0,0 +1,33 @@
1
+ import { Control, IControlParams } from "../Control";
2
+ import { Dialog } from "../../ui/Dialog";
3
+ import { View } from "../../ui/View";
4
+ import { ToggleButton } from "../../ui/ToggleButton";
5
+ import { ElevationProfileView } from "./ElevationProfileView";
6
+ import { ElevationProfileScene } from "./ElevationProfileScene";
7
+ import { ElevationProfileButtonsView } from "./ElevationProfileButtonsView";
8
+ import { PointListDialog } from "./PointListDialog";
9
+ import { GroundItem, TrackItem } from "./ElevationProfile";
10
+ import { ElevationProfileLegend } from "./ElevationProfileLegend";
11
+ interface IElevationProfileGraphParams extends IControlParams {
12
+ }
13
+ export declare class ElevationProfileControl extends Control {
14
+ protected _toggleBtn: ToggleButton;
15
+ protected _dialog: Dialog<null>;
16
+ protected _graphView: View<null>;
17
+ protected _poiListDialog: PointListDialog;
18
+ protected _elevationProfileView: ElevationProfileView;
19
+ protected _elevationProfileScene: ElevationProfileScene;
20
+ protected _elevationProfileButtonsView: ElevationProfileButtonsView;
21
+ protected _elevationProfileLegend: ElevationProfileLegend;
22
+ protected _collectProfileThrottled: () => void;
23
+ constructor(options?: IElevationProfileGraphParams);
24
+ oninit(): void;
25
+ protected _onSceneChange: () => void;
26
+ onactivate(): void;
27
+ ondeactivate(): void;
28
+ protected _onElevationProfilePointer: (pointerDistance: number, tp0: TrackItem, tp1: TrackItem, gp0: GroundItem, gp1: GroundItem, trackPoiIndex: number, groundPoiIndex: number, elevation: number) => void;
29
+ protected _onElevationProfileDblClick: (pointerDistance: number, tp0: TrackItem, tp1: TrackItem, gp0: GroundItem, gp1: GroundItem, trackPoiIndex: number, groundPoiIndex: number, elevation: number) => void;
30
+ protected _onElevationProfileMouseEnter: () => void;
31
+ protected _onElevationProfileMouseLeave: () => void;
32
+ }
33
+ export {};