@openglobus/og 0.20.3 → 0.21.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 (41) hide show
  1. package/README.md +1 -1
  2. package/lib/@openglobus/js/Globe.d.ts +1 -1
  3. package/lib/@openglobus/js/Object3d.d.ts +1 -0
  4. package/lib/@openglobus/js/entity/EntityCollection.d.ts +4 -0
  5. package/lib/@openglobus/js/entity/GeoObject.d.ts +7 -3
  6. package/lib/@openglobus/js/entity/GeoObjectHandler.d.ts +5 -8
  7. package/lib/@openglobus/js/entity/GeometryHandler.d.ts +3 -2
  8. package/lib/@openglobus/js/layer/Vector.d.ts +5 -0
  9. package/lib/@openglobus/js/math/Quat.d.ts +1 -0
  10. package/lib/@openglobus/js/terrain/GlobusTerrain.d.ts +2 -0
  11. package/lib/@openglobus/js/terrain/RgbTerrain.d.ts +9 -0
  12. package/lib/@openglobus/og.esm.js +1 -1
  13. package/lib/@openglobus/og.esm.js.map +1 -1
  14. package/lib/@openglobus/og.umd.js +1 -1
  15. package/lib/@openglobus/og.umd.js.map +1 -1
  16. package/lib/js/Globe.d.ts +1 -1
  17. package/lib/js/Globe.js +8 -2
  18. package/lib/js/Object3d.d.ts +1 -0
  19. package/lib/js/Object3d.js +18 -0
  20. package/lib/js/entity/EntityCollection.d.ts +4 -0
  21. package/lib/js/entity/EntityCollection.js +7 -0
  22. package/lib/js/entity/GeoObject.d.ts +7 -3
  23. package/lib/js/entity/GeoObject.js +31 -16
  24. package/lib/js/entity/GeoObjectHandler.d.ts +5 -8
  25. package/lib/js/entity/GeoObjectHandler.js +34 -63
  26. package/lib/js/entity/GeometryHandler.d.ts +3 -2
  27. package/lib/js/entity/GeometryHandler.js +56 -0
  28. package/lib/js/layer/Bing.js +1 -0
  29. package/lib/js/layer/Vector.d.ts +5 -0
  30. package/lib/js/layer/Vector.js +20 -3
  31. package/lib/js/math/Quat.d.ts +1 -0
  32. package/lib/js/math/Quat.js +4 -0
  33. package/lib/js/renderer/RendererEvents.js +1 -3
  34. package/lib/js/scene/Planet.js +1 -1
  35. package/lib/js/shaders/geoObject.js +22 -71
  36. package/lib/js/terrain/GlobusRgbTerrain.js +2 -2
  37. package/lib/js/terrain/GlobusTerrain.d.ts +2 -0
  38. package/lib/js/terrain/GlobusTerrain.js +2 -0
  39. package/lib/js/terrain/RgbTerrain.d.ts +9 -0
  40. package/lib/js/terrain/RgbTerrain.js +215 -213
  41. package/package.json +14 -14
@@ -3,13 +3,6 @@ import { GlobusTerrain } from "./GlobusTerrain";
3
3
  import { isPowerOfTwo } from "../math";
4
4
  import { Layer } from "../layer/Layer";
5
5
  import { binarySearchFast } from "../utils/shared";
6
- const rgb2Height = (r, g, b) => {
7
- // Filter for "yellowish" pixels
8
- if (r === 255) {
9
- return -10000;
10
- }
11
- return -10000 + 0.1 * (r * 256 * 256 + g * 256 + b);
12
- };
13
6
  class RgbTerrain extends GlobusTerrain {
14
7
  constructor(name, options = {}) {
15
8
  super(name || "RgbTerrain", {
@@ -30,6 +23,8 @@ class RgbTerrain extends GlobusTerrain {
30
23
  this._imageSize = options.imageSize || 256;
31
24
  this._ctx = this._createTemporalCanvas(this._imageSize);
32
25
  this._imageDataCache = {};
26
+ this._minHeight = options.minHeight || -10000.0;
27
+ this._resolution = options.resolution || 0.1;
33
28
  }
34
29
  static checkNoDataValue(noDataValues, value) {
35
30
  if (value > 50000) {
@@ -37,6 +32,13 @@ class RgbTerrain extends GlobusTerrain {
37
32
  }
38
33
  return binarySearchFast(noDataValues, value) !== -1;
39
34
  }
35
+ rgb2Height(r, g, b) {
36
+ // Filter for "yellowish" pixels
37
+ if (r === 255) {
38
+ return this._minHeight;
39
+ }
40
+ return this._minHeight + this._resolution * (r * 256 * 256 + g * 256 + b);
41
+ }
40
42
  isBlur(segment) {
41
43
  return segment.tileZoom >= 16;
42
44
  }
@@ -78,7 +80,7 @@ class RgbTerrain extends GlobusTerrain {
78
80
  //
79
81
  if (!isPowerOfTwo(this._imageSize) && SIZE === this._imageSize) {
80
82
  let outCurrenElevations = new Float32Array(SIZE * SIZE);
81
- extractElevationTilesRgbNonPowerOfTwo(rgbaData, outCurrenElevations, this._heightFactor);
83
+ this.extractElevationTilesRgbNonPowerOfTwo(rgbaData, outCurrenElevations, this._heightFactor);
82
84
  return outCurrenElevations;
83
85
  }
84
86
  //
@@ -88,7 +90,7 @@ class RgbTerrain extends GlobusTerrain {
88
90
  let elevationsSize = (this.plainGridSize + 1) * (this.plainGridSize + 1);
89
91
  let outCurrenElevations = new Float32Array(elevationsSize);
90
92
  let [availableParentOffsetX, availableParentOffsetY, availableZoomDiff] = segment ? getTileOffset(segment.tileX, segment.tileY, segment.tileZoom, availableParentTileX, availableParentTileY, availableParentTileZoom) : [0, 0, 0];
91
- extractElevationSimple(rgbaData, this.noDataValues, availableParentData, availableParentOffsetX, availableParentOffsetY, availableZoomDiff, skipPositiveHeights, outCurrenElevations, this._heightFactor, this._imageSize);
93
+ this.extractElevationSimple(rgbaData, this.noDataValues, availableParentData, availableParentOffsetX, availableParentOffsetY, availableZoomDiff, skipPositiveHeights, outCurrenElevations, this._heightFactor, this._imageSize);
92
94
  return outCurrenElevations;
93
95
  }
94
96
  //
@@ -105,7 +107,7 @@ class RgbTerrain extends GlobusTerrain {
105
107
  }
106
108
  }
107
109
  if (!preventChildren) {
108
- extractElevationTilesRgb(rgbaData, this._heightFactor, this.noDataValues, availableParentData, availableParentTileX, availableParentTileY, availableParentTileZoom, segment ? segment.tileX : 0, segment ? segment.tileY : 0, segment ? segment.tileZoom : 0, skipPositiveHeights, outCurrenElevations, outChildrenElevations);
110
+ this.extractElevationTilesRgb(rgbaData, this._heightFactor, this.noDataValues, availableParentData, availableParentTileX, availableParentTileY, availableParentTileZoom, segment ? segment.tileX : 0, segment ? segment.tileY : 0, segment ? segment.tileZoom : 0, skipPositiveHeights, outCurrenElevations, outChildrenElevations);
109
111
  // Save children data to cache
110
112
  for (let i = 0; i < d; i++) {
111
113
  for (let j = 0; j < d; j++) {
@@ -122,7 +124,7 @@ class RgbTerrain extends GlobusTerrain {
122
124
  }
123
125
  }
124
126
  else {
125
- extractElevationTilesRgbNoChildren(rgbaData, this._heightFactor, this.noDataValues, availableParentData, availableParentTileX, availableParentTileY, availableParentTileZoom, segment ? segment.tileX : 0, segment ? segment.tileY : 0, segment ? segment.tileZoom : 0, skipPositiveHeights, outCurrenElevations);
127
+ this.extractElevationTilesRgbNoChildren(rgbaData, this._heightFactor, this.noDataValues, availableParentData, availableParentTileX, availableParentTileY, availableParentTileZoom, segment ? segment.tileX : 0, segment ? segment.tileY : 0, segment ? segment.tileZoom : 0, skipPositiveHeights, outCurrenElevations);
126
128
  }
127
129
  let tileIndex = Layer.getTileIndex(tileX, tileY, tileZoom, tileGroup);
128
130
  // Save current data to cache
@@ -145,13 +147,13 @@ class RgbTerrain extends GlobusTerrain {
145
147
  const tileIndex = Layer.getTileIndex(x, y, z, tileGroup);
146
148
  if (this._imageDataCache[tileIndex]) {
147
149
  let data = this._imageDataCache[tileIndex];
148
- let height = this._heightFactor * rgb2Height(data[index], data[index + 1], data[index + 2]);
150
+ let height = this._heightFactor * this.rgb2Height(data[index], data[index + 1], data[index + 2]);
149
151
  let isNoData = RgbTerrain.checkNoDataValue(this.noDataValues, height);
150
152
  if (isNoData) {
151
153
  return this.getHeightAsync(lonLat, callback, zoom - 1);
152
154
  }
153
155
  else {
154
- callback(this._heightFactor * rgb2Height(data[index], data[index + 1], data[index + 2]));
156
+ callback(this._heightFactor * this.rgb2Height(data[index], data[index + 1], data[index + 2]));
155
157
  return true;
156
158
  }
157
159
  }
@@ -169,13 +171,13 @@ class RgbTerrain extends GlobusTerrain {
169
171
  this._ctx.drawImage(response.data, 0, 0);
170
172
  let data = this._ctx.getImageData(0, 0, 256, 256).data;
171
173
  this._imageDataCache[tileIndex] = data;
172
- let height = this._heightFactor * rgb2Height(data[index], data[index + 1], data[index + 2]);
174
+ let height = this._heightFactor * this.rgb2Height(data[index], data[index + 1], data[index + 2]);
173
175
  let isNoData = RgbTerrain.checkNoDataValue(this.noDataValues, height);
174
176
  if (isNoData) {
175
177
  return this.getHeightAsync(lonLat, callback, zoom - 1);
176
178
  }
177
179
  else {
178
- callback(this._heightFactor * rgb2Height(data[index], data[index + 1], data[index + 2]));
180
+ callback(this._heightFactor * this.rgb2Height(data[index], data[index + 1], data[index + 2]));
179
181
  }
180
182
  }
181
183
  else if (response.status === "error") {
@@ -189,227 +191,227 @@ class RgbTerrain extends GlobusTerrain {
189
191
  });
190
192
  return false;
191
193
  }
192
- }
193
- function getTileOffset(currentTileX, currentTileY, currentTileZoom, parentTileX, parentTileY, parentTileZoom) {
194
- let dz2 = 2 << (currentTileZoom - parentTileZoom - 1);
195
- return [currentTileX - dz2 * parentTileX, currentTileY - dz2 * parentTileY, 1.0 / dz2];
196
- }
197
- function getChildTileIndex(currentParentTileX, currentParentTileY, currentParentTileZoom, childOffsetX, childOffsetY) {
198
- return [currentParentTileX * 2 + childOffsetX, currentParentTileY * 2 + childOffsetY, currentParentTileZoom + 1];
199
- }
200
- function getParentHeight(oneByDz2, offsetX, offsetY, heights, i, j, skipPositiveHeights) {
201
- let parentGridSize = Math.sqrt(heights.length);
202
- let pi = Math.floor(offsetY * oneByDz2 * parentGridSize + i * oneByDz2), pj = Math.floor(offsetX * oneByDz2 * parentGridSize + j * oneByDz2);
203
- let h = heights[pi * parentGridSize + pj];
204
- return skipPositiveHeights ? (h > 0 ? 0 : h) : h;
205
- }
206
- function extractElevationSimple(rgbaData, noDataValues, availableParentData = null, availableParentOffsetX, availableParentOffsetY, availableZoomDiff, skipPositiveHeights, outCurrenElevations, heightFactor = 1, imageSize) {
207
- for (let k = 0, len = imageSize * imageSize; k < len; k++) {
208
- let j = k % imageSize, i = Math.floor(k / imageSize);
209
- let fromInd4 = k * 4;
210
- let height = heightFactor * rgb2Height(rgbaData[fromInd4], rgbaData[fromInd4 + 1], rgbaData[fromInd4 + 2]);
211
- let isNoData = RgbTerrain.checkNoDataValue(noDataValues, height);
212
- if ((isNoData || height === 0) && availableParentData) {
213
- height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, i, j, skipPositiveHeights);
194
+ extractElevationSimple(rgbaData, noDataValues, availableParentData = null, availableParentOffsetX, availableParentOffsetY, availableZoomDiff, skipPositiveHeights, outCurrenElevations, heightFactor = 1, imageSize) {
195
+ for (let k = 0, len = imageSize * imageSize; k < len; k++) {
196
+ let j = k % imageSize, i = Math.floor(k / imageSize);
197
+ let fromInd4 = k * 4;
198
+ let height = heightFactor * this.rgb2Height(rgbaData[fromInd4], rgbaData[fromInd4 + 1], rgbaData[fromInd4 + 2]);
199
+ let isNoData = RgbTerrain.checkNoDataValue(noDataValues, height);
200
+ if ((isNoData || height === 0) && availableParentData) {
201
+ height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, i, j, skipPositiveHeights);
202
+ }
203
+ outCurrenElevations[i * (imageSize + 1) + j] = height;
214
204
  }
215
- outCurrenElevations[i * (imageSize + 1) + j] = height;
216
- }
217
- for (let i = 0, len = imageSize; i < len; i++) {
218
- let j = imageSize - 1;
219
- let fromInd4 = (i * imageSize + j) * 4;
220
- let height = heightFactor * rgb2Height(rgbaData[fromInd4], rgbaData[fromInd4 + 1], rgbaData[fromInd4 + 2]);
221
- let isNoData = RgbTerrain.checkNoDataValue(noDataValues, height);
222
- if ((isNoData || height === 0) && availableParentData) {
223
- height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, i, j, skipPositiveHeights);
205
+ for (let i = 0, len = imageSize; i < len; i++) {
206
+ let j = imageSize - 1;
207
+ let fromInd4 = (i * imageSize + j) * 4;
208
+ let height = heightFactor * this.rgb2Height(rgbaData[fromInd4], rgbaData[fromInd4 + 1], rgbaData[fromInd4 + 2]);
209
+ let isNoData = RgbTerrain.checkNoDataValue(noDataValues, height);
210
+ if ((isNoData || height === 0) && availableParentData) {
211
+ height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, i, j, skipPositiveHeights);
212
+ }
213
+ outCurrenElevations[i * (imageSize + 1) + imageSize] = height;
224
214
  }
225
- outCurrenElevations[i * (imageSize + 1) + imageSize] = height;
226
- }
227
- for (let j = 0, len = imageSize; j < len; j++) {
228
- let i = imageSize - 1;
229
- let fromInd4 = (i * imageSize + j) * 4;
230
- let height = heightFactor * rgb2Height(rgbaData[fromInd4], rgbaData[fromInd4 + 1], rgbaData[fromInd4 + 2]);
215
+ for (let j = 0, len = imageSize; j < len; j++) {
216
+ let i = imageSize - 1;
217
+ let fromInd4 = (i * imageSize + j) * 4;
218
+ let height = heightFactor * this.rgb2Height(rgbaData[fromInd4], rgbaData[fromInd4 + 1], rgbaData[fromInd4 + 2]);
219
+ let isNoData = RgbTerrain.checkNoDataValue(noDataValues, height);
220
+ if ((isNoData || height === 0) && availableParentData) {
221
+ height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, i, j, skipPositiveHeights);
222
+ }
223
+ outCurrenElevations[imageSize * (imageSize + 1) + j] = height;
224
+ }
225
+ let height = heightFactor * this.rgb2Height(rgbaData[rgbaData.length - 4], rgbaData[rgbaData.length - 3], rgbaData[rgbaData.length - 2]);
231
226
  let isNoData = RgbTerrain.checkNoDataValue(noDataValues, height);
232
227
  if ((isNoData || height === 0) && availableParentData) {
233
- height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, i, j, skipPositiveHeights);
228
+ height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, imageSize - 1, imageSize - 1, skipPositiveHeights);
234
229
  }
235
- outCurrenElevations[imageSize * (imageSize + 1) + j] = height;
236
- }
237
- let height = heightFactor * rgb2Height(rgbaData[rgbaData.length - 4], rgbaData[rgbaData.length - 3], rgbaData[rgbaData.length - 2]);
238
- let isNoData = RgbTerrain.checkNoDataValue(noDataValues, height);
239
- if ((isNoData || height === 0) && availableParentData) {
240
- height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, imageSize - 1, imageSize - 1, skipPositiveHeights);
241
- }
242
- outCurrenElevations[outCurrenElevations.length - 1] = height;
243
- }
244
- function extractElevationTilesRgbNonPowerOfTwo(rgbaData, outCurrenElevations, heightFactor = 1) {
245
- for (let i = 0, len = outCurrenElevations.length; i < len; i++) {
246
- let i4 = i * 4;
247
- outCurrenElevations[i] = heightFactor * rgb2Height(rgbaData[i4], rgbaData[i4 + 1], rgbaData[i4 + 2]);
230
+ outCurrenElevations[outCurrenElevations.length - 1] = height;
248
231
  }
249
- }
250
- function extractElevationTilesRgb(rgbaData, heightFactor, noDataValues, availableParentData = null, availableParentTileX, availableParentTileY, availableParentTileZoom, currentTileX, currentTileY, currentTileZoom, skipPositiveHeights, outCurrenElevations, outChildrenElevations) {
251
- let destSize = Math.sqrt(outCurrenElevations.length) - 1;
252
- let destSizeOne = destSize + 1;
253
- let sourceSize = Math.sqrt(rgbaData.length / 4);
254
- let dt = sourceSize / destSize;
255
- let rightHeight = 0, bottomHeight = 0, sourceSize4 = 0;
256
- let [availableParentOffsetX, availableParentOffsetY, availableZoomDiff] = getTileOffset(currentTileX, currentTileY, currentTileZoom, availableParentTileX, availableParentTileY, availableParentTileZoom);
257
- for (let k = 0, currIndex = 0, sourceDataLength = rgbaData.length / 4; k < sourceDataLength; k++) {
258
- let k4 = k * 4;
259
- let height = heightFactor * rgb2Height(rgbaData[k4], rgbaData[k4 + 1], rgbaData[k4 + 2]);
260
- let isNoDataCurrent = RgbTerrain.checkNoDataValue(noDataValues, height), isNoDataRight = false, isNoDataBottom = false;
261
- let i = Math.floor(k / sourceSize), j = k % sourceSize;
262
- //
263
- // Try to get current height from the parent data
264
- if ((isNoDataCurrent || height === 0) && availableParentData) {
265
- height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor(i / dt), Math.floor(j / dt), skipPositiveHeights);
266
- }
267
- let tileX = Math.floor(j / destSize), tileY = Math.floor(i / destSize);
268
- let destArr = outChildrenElevations[tileY][tileX];
269
- let ii = i % destSize, jj = j % destSize;
270
- let destIndex = (ii + tileY) * destSizeOne + jj + tileX;
271
- destArr[destIndex] = height;
272
- if ((i + tileY) % dt === 0 && (j + tileX) % dt === 0) {
273
- outCurrenElevations[currIndex++] = height;
232
+ extractElevationTilesRgbNonPowerOfTwo(rgbaData, outCurrenElevations, heightFactor = 1) {
233
+ for (let i = 0, len = outCurrenElevations.length; i < len; i++) {
234
+ let i4 = i * 4;
235
+ outCurrenElevations[i] = heightFactor * this.rgb2Height(rgbaData[i4], rgbaData[i4 + 1], rgbaData[i4 + 2]);
274
236
  }
275
- if ((j + 1) % destSize === 0 && j !== sourceSize - 1) {
276
- //current tile
277
- rightHeight = heightFactor * rgb2Height(rgbaData[k4 + 4], rgbaData[k4 + 5], rgbaData[k4 + 6]);
278
- isNoDataRight = RgbTerrain.checkNoDataValue(noDataValues, rightHeight);
237
+ }
238
+ extractElevationTilesRgb(rgbaData, heightFactor, noDataValues, availableParentData = null, availableParentTileX, availableParentTileY, availableParentTileZoom, currentTileX, currentTileY, currentTileZoom, skipPositiveHeights, outCurrenElevations, outChildrenElevations) {
239
+ let destSize = Math.sqrt(outCurrenElevations.length) - 1;
240
+ let destSizeOne = destSize + 1;
241
+ let sourceSize = Math.sqrt(rgbaData.length / 4);
242
+ let dt = sourceSize / destSize;
243
+ let rightHeight = 0, bottomHeight = 0, sourceSize4 = 0;
244
+ let [availableParentOffsetX, availableParentOffsetY, availableZoomDiff] = getTileOffset(currentTileX, currentTileY, currentTileZoom, availableParentTileX, availableParentTileY, availableParentTileZoom);
245
+ for (let k = 0, currIndex = 0, sourceDataLength = rgbaData.length / 4; k < sourceDataLength; k++) {
246
+ let k4 = k * 4;
247
+ let height = heightFactor * this.rgb2Height(rgbaData[k4], rgbaData[k4 + 1], rgbaData[k4 + 2]);
248
+ let isNoDataCurrent = RgbTerrain.checkNoDataValue(noDataValues, height), isNoDataRight = false, isNoDataBottom = false;
249
+ let i = Math.floor(k / sourceSize), j = k % sourceSize;
279
250
  //
280
- // Try to get right height from the parent data
281
- if ((isNoDataRight || rightHeight === 0) && availableParentData) {
282
- rightHeight = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor(i / dt), Math.floor((j + 1) / dt), skipPositiveHeights);
283
- }
284
- let middleHeight = height;
285
- if (!(isNoDataCurrent || isNoDataRight)) {
286
- middleHeight = (height + rightHeight) * 0.5;
251
+ // Try to get current height from the parent data
252
+ if ((isNoDataCurrent || height === 0) && availableParentData) {
253
+ height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor(i / dt), Math.floor(j / dt), skipPositiveHeights);
287
254
  }
288
- destIndex = (ii + tileY) * destSizeOne + jj + 1;
289
- destArr[destIndex] = middleHeight;
290
- if ((i + tileY) % dt === 0) {
291
- outCurrenElevations[currIndex++] = middleHeight;
255
+ let tileX = Math.floor(j / destSize), tileY = Math.floor(i / destSize);
256
+ let destArr = outChildrenElevations[tileY][tileX];
257
+ let ii = i % destSize, jj = j % destSize;
258
+ let destIndex = (ii + tileY) * destSizeOne + jj + tileX;
259
+ destArr[destIndex] = height;
260
+ if ((i + tileY) % dt === 0 && (j + tileX) % dt === 0) {
261
+ outCurrenElevations[currIndex++] = height;
292
262
  }
293
- //next right tile
294
- let rightindex = (ii + tileY) * destSizeOne + ((jj + 1) % destSize);
295
- outChildrenElevations[tileY][tileX + 1][rightindex] = middleHeight;
296
- }
297
- if ((i + 1) % destSize === 0 && i !== sourceSize - 1) {
298
- //current tile
299
- sourceSize4 = sourceSize * 4;
300
- bottomHeight = heightFactor * rgb2Height(rgbaData[k4 + sourceSize4], rgbaData[k4 + sourceSize4 + 1], rgbaData[k4 + sourceSize4 + 2]);
301
- isNoDataBottom = RgbTerrain.checkNoDataValue(noDataValues, bottomHeight);
302
- //
303
- // Try to get bottom height from the parent data
304
- if ((isNoDataBottom || bottomHeight === 0) && availableParentData) {
305
- bottomHeight = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor((i + 1) / dt), Math.floor(j / dt), skipPositiveHeights);
263
+ if ((j + 1) % destSize === 0 && j !== sourceSize - 1) {
264
+ //current tile
265
+ rightHeight = heightFactor * this.rgb2Height(rgbaData[k4 + 4], rgbaData[k4 + 5], rgbaData[k4 + 6]);
266
+ isNoDataRight = RgbTerrain.checkNoDataValue(noDataValues, rightHeight);
267
+ //
268
+ // Try to get right height from the parent data
269
+ if ((isNoDataRight || rightHeight === 0) && availableParentData) {
270
+ rightHeight = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor(i / dt), Math.floor((j + 1) / dt), skipPositiveHeights);
271
+ }
272
+ let middleHeight = height;
273
+ if (!(isNoDataCurrent || isNoDataRight)) {
274
+ middleHeight = (height + rightHeight) * 0.5;
275
+ }
276
+ destIndex = (ii + tileY) * destSizeOne + jj + 1;
277
+ destArr[destIndex] = middleHeight;
278
+ if ((i + tileY) % dt === 0) {
279
+ outCurrenElevations[currIndex++] = middleHeight;
280
+ }
281
+ //next right tile
282
+ let rightindex = (ii + tileY) * destSizeOne + ((jj + 1) % destSize);
283
+ outChildrenElevations[tileY][tileX + 1][rightindex] = middleHeight;
306
284
  }
307
- let middleHeight = (height + bottomHeight) * 0.5;
308
- if (!(isNoDataCurrent || isNoDataBottom)) {
309
- middleHeight = (height + bottomHeight) * 0.5;
285
+ if ((i + 1) % destSize === 0 && i !== sourceSize - 1) {
286
+ //current tile
287
+ sourceSize4 = sourceSize * 4;
288
+ bottomHeight = heightFactor * this.rgb2Height(rgbaData[k4 + sourceSize4], rgbaData[k4 + sourceSize4 + 1], rgbaData[k4 + sourceSize4 + 2]);
289
+ isNoDataBottom = RgbTerrain.checkNoDataValue(noDataValues, bottomHeight);
290
+ //
291
+ // Try to get bottom height from the parent data
292
+ if ((isNoDataBottom || bottomHeight === 0) && availableParentData) {
293
+ bottomHeight = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor((i + 1) / dt), Math.floor(j / dt), skipPositiveHeights);
294
+ }
295
+ let middleHeight = (height + bottomHeight) * 0.5;
296
+ if (!(isNoDataCurrent || isNoDataBottom)) {
297
+ middleHeight = (height + bottomHeight) * 0.5;
298
+ }
299
+ destIndex = (ii + 1) * destSizeOne + jj + tileX;
300
+ destArr[destIndex] = middleHeight;
301
+ if ((j + tileX) % dt === 0) {
302
+ outCurrenElevations[currIndex++] = middleHeight;
303
+ }
304
+ //next bottom tile
305
+ let bottomindex = ((ii + 1) % destSize) * destSizeOne + jj + tileX;
306
+ outChildrenElevations[tileY + 1][tileX][bottomindex] = middleHeight;
310
307
  }
311
- destIndex = (ii + 1) * destSizeOne + jj + tileX;
312
- destArr[destIndex] = middleHeight;
313
- if ((j + tileX) % dt === 0) {
308
+ if ((j + 1) % destSize === 0 && j !== sourceSize - 1 &&
309
+ (i + 1) % destSize === 0 && i !== sourceSize - 1) {
310
+ //current tile
311
+ let rightBottomHeight = heightFactor * this.rgb2Height(rgbaData[k4 + sourceSize4 + 4], rgbaData[k4 + sourceSize4 + 5], rgbaData[k4 + sourceSize4 + 6]);
312
+ let isNoDataRightBottom = RgbTerrain.checkNoDataValue(noDataValues, rightBottomHeight);
313
+ //
314
+ // Try to get right bottom height from the parent data
315
+ if ((isNoDataRightBottom || rightBottomHeight === 0) && availableParentData) {
316
+ rightBottomHeight = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor((i + 1) / dt), Math.floor((j + 1) / dt), skipPositiveHeights);
317
+ }
318
+ let middleHeight = height;
319
+ if (!(isNoDataCurrent || isNoDataRight || isNoDataBottom || isNoDataRightBottom)) {
320
+ middleHeight = (height + rightHeight + bottomHeight + rightBottomHeight) * 0.25;
321
+ }
322
+ destIndex = (ii + 1) * destSizeOne + (jj + 1);
323
+ destArr[destIndex] = middleHeight;
314
324
  outCurrenElevations[currIndex++] = middleHeight;
325
+ //next right tile
326
+ let rightindex = (ii + 1) * destSizeOne;
327
+ outChildrenElevations[tileY][tileX + 1][rightindex] = middleHeight;
328
+ //next bottom tile
329
+ let bottomindex = destSize;
330
+ outChildrenElevations[tileY + 1][tileX][bottomindex] = middleHeight;
331
+ //next right bottom tile
332
+ let rightBottomindex = 0;
333
+ outChildrenElevations[tileY + 1][tileX + 1][rightBottomindex] = middleHeight;
315
334
  }
316
- //next bottom tile
317
- let bottomindex = ((ii + 1) % destSize) * destSizeOne + jj + tileX;
318
- outChildrenElevations[tileY + 1][tileX][bottomindex] = middleHeight;
319
- }
320
- if ((j + 1) % destSize === 0 && j !== sourceSize - 1 &&
321
- (i + 1) % destSize === 0 && i !== sourceSize - 1) {
322
- //current tile
323
- let rightBottomHeight = heightFactor * rgb2Height(rgbaData[k4 + sourceSize4 + 4], rgbaData[k4 + sourceSize4 + 5], rgbaData[k4 + sourceSize4 + 6]);
324
- let isNoDataRightBottom = RgbTerrain.checkNoDataValue(noDataValues, rightBottomHeight);
325
- //
326
- // Try to get right bottom height from the parent data
327
- if ((isNoDataRightBottom || rightBottomHeight === 0) && availableParentData) {
328
- rightBottomHeight = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor((i + 1) / dt), Math.floor((j + 1) / dt), skipPositiveHeights);
329
- }
330
- let middleHeight = height;
331
- if (!(isNoDataCurrent || isNoDataRight || isNoDataBottom || isNoDataRightBottom)) {
332
- middleHeight = (height + rightHeight + bottomHeight + rightBottomHeight) * 0.25;
333
- }
334
- destIndex = (ii + 1) * destSizeOne + (jj + 1);
335
- destArr[destIndex] = middleHeight;
336
- outCurrenElevations[currIndex++] = middleHeight;
337
- //next right tile
338
- let rightindex = (ii + 1) * destSizeOne;
339
- outChildrenElevations[tileY][tileX + 1][rightindex] = middleHeight;
340
- //next bottom tile
341
- let bottomindex = destSize;
342
- outChildrenElevations[tileY + 1][tileX][bottomindex] = middleHeight;
343
- //next right bottom tile
344
- let rightBottomindex = 0;
345
- outChildrenElevations[tileY + 1][tileX + 1][rightBottomindex] = middleHeight;
346
335
  }
347
336
  }
348
- }
349
- function extractElevationTilesRgbNoChildren(rgbaData, heightFactor, noDataValues, availableParentData = null, availableParentTileX, availableParentTileY, availableParentTileZoom, currentTileX, currentTileY, currentTileZoom, skipPositiveHeights, outCurrenElevations) {
350
- let destSize = Math.sqrt(outCurrenElevations.length) - 1;
351
- let destSizeOne = destSize + 1;
352
- let sourceSize = Math.sqrt(rgbaData.length / 4);
353
- let dt = sourceSize / destSize;
354
- let rightHeight = 0, bottomHeight = 0, sourceSize4 = 0;
355
- let [availableParentOffsetX, availableParentOffsetY, availableZoomDiff] = getTileOffset(currentTileX, currentTileY, currentTileZoom, availableParentTileX, availableParentTileY, availableParentTileZoom);
356
- for (let k = 0, currIndex = 0, sourceDataLength = rgbaData.length / 4; k < sourceDataLength; k++) {
357
- let k4 = k * 4;
358
- let height = heightFactor * rgb2Height(rgbaData[k4], rgbaData[k4 + 1], rgbaData[k4 + 2]);
359
- let isNoDataCurrent = RgbTerrain.checkNoDataValue(noDataValues, height), isNoDataRight = false, isNoDataBottom = false;
360
- let i = Math.floor(k / sourceSize), j = k % sourceSize;
361
- if ((isNoDataCurrent || height === 0) && availableParentData) {
362
- height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor(currIndex / destSizeOne), currIndex % destSizeOne, skipPositiveHeights);
363
- }
364
- let tileX = Math.floor(j / destSize), tileY = Math.floor(i / destSize);
365
- if ((i + tileY) % dt === 0 && (j + tileX) % dt === 0) {
366
- outCurrenElevations[currIndex++] = height;
367
- }
368
- if ((j + 1) % destSize === 0 && j !== sourceSize - 1) {
369
- //current tile
370
- rightHeight = heightFactor * rgb2Height(rgbaData[k4 + 4], rgbaData[k4 + 5], rgbaData[k4 + 6]);
371
- isNoDataRight = RgbTerrain.checkNoDataValue(noDataValues, rightHeight);
372
- if ((isNoDataRight || rightHeight === 0) && availableParentData) {
373
- rightHeight = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor(currIndex / destSizeOne), currIndex % destSizeOne, skipPositiveHeights);
337
+ extractElevationTilesRgbNoChildren(rgbaData, heightFactor, noDataValues, availableParentData = null, availableParentTileX, availableParentTileY, availableParentTileZoom, currentTileX, currentTileY, currentTileZoom, skipPositiveHeights, outCurrenElevations) {
338
+ let destSize = Math.sqrt(outCurrenElevations.length) - 1;
339
+ let destSizeOne = destSize + 1;
340
+ let sourceSize = Math.sqrt(rgbaData.length / 4);
341
+ let dt = sourceSize / destSize;
342
+ let rightHeight = 0, bottomHeight = 0, sourceSize4 = 0;
343
+ let [availableParentOffsetX, availableParentOffsetY, availableZoomDiff] = getTileOffset(currentTileX, currentTileY, currentTileZoom, availableParentTileX, availableParentTileY, availableParentTileZoom);
344
+ for (let k = 0, currIndex = 0, sourceDataLength = rgbaData.length / 4; k < sourceDataLength; k++) {
345
+ let k4 = k * 4;
346
+ let height = heightFactor * this.rgb2Height(rgbaData[k4], rgbaData[k4 + 1], rgbaData[k4 + 2]);
347
+ let isNoDataCurrent = RgbTerrain.checkNoDataValue(noDataValues, height), isNoDataRight = false, isNoDataBottom = false;
348
+ let i = Math.floor(k / sourceSize), j = k % sourceSize;
349
+ if ((isNoDataCurrent || height === 0) && availableParentData) {
350
+ height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor(currIndex / destSizeOne), currIndex % destSizeOne, skipPositiveHeights);
374
351
  }
375
- let middleHeight = height;
376
- if (!(isNoDataCurrent || isNoDataRight)) {
377
- middleHeight = (height + rightHeight) * 0.5;
378
- }
379
- if ((i + tileY) % dt === 0) {
380
- outCurrenElevations[currIndex++] = middleHeight;
352
+ let tileX = Math.floor(j / destSize), tileY = Math.floor(i / destSize);
353
+ if ((i + tileY) % dt === 0 && (j + tileX) % dt === 0) {
354
+ outCurrenElevations[currIndex++] = height;
381
355
  }
382
- }
383
- if ((i + 1) % destSize === 0 && i !== sourceSize - 1) {
384
- //current tile
385
- sourceSize4 = sourceSize * 4;
386
- bottomHeight = heightFactor * rgb2Height(rgbaData[k4 + sourceSize4], rgbaData[k4 + sourceSize4 + 1], rgbaData[k4 + sourceSize4 + 2]);
387
- isNoDataBottom = RgbTerrain.checkNoDataValue(noDataValues, bottomHeight);
388
- if ((isNoDataBottom || bottomHeight === 0) && availableParentData) {
389
- bottomHeight = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor(currIndex / destSizeOne), currIndex % destSizeOne, skipPositiveHeights);
356
+ if ((j + 1) % destSize === 0 && j !== sourceSize - 1) {
357
+ //current tile
358
+ rightHeight = heightFactor * this.rgb2Height(rgbaData[k4 + 4], rgbaData[k4 + 5], rgbaData[k4 + 6]);
359
+ isNoDataRight = RgbTerrain.checkNoDataValue(noDataValues, rightHeight);
360
+ if ((isNoDataRight || rightHeight === 0) && availableParentData) {
361
+ rightHeight = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor(currIndex / destSizeOne), currIndex % destSizeOne, skipPositiveHeights);
362
+ }
363
+ let middleHeight = height;
364
+ if (!(isNoDataCurrent || isNoDataRight)) {
365
+ middleHeight = (height + rightHeight) * 0.5;
366
+ }
367
+ if ((i + tileY) % dt === 0) {
368
+ outCurrenElevations[currIndex++] = middleHeight;
369
+ }
390
370
  }
391
- let middleHeight = (height + bottomHeight) * 0.5;
392
- if (!(isNoDataCurrent || isNoDataBottom)) {
393
- middleHeight = (height + bottomHeight) * 0.5;
371
+ if ((i + 1) % destSize === 0 && i !== sourceSize - 1) {
372
+ //current tile
373
+ sourceSize4 = sourceSize * 4;
374
+ bottomHeight = heightFactor * this.rgb2Height(rgbaData[k4 + sourceSize4], rgbaData[k4 + sourceSize4 + 1], rgbaData[k4 + sourceSize4 + 2]);
375
+ isNoDataBottom = RgbTerrain.checkNoDataValue(noDataValues, bottomHeight);
376
+ if ((isNoDataBottom || bottomHeight === 0) && availableParentData) {
377
+ bottomHeight = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor(currIndex / destSizeOne), currIndex % destSizeOne, skipPositiveHeights);
378
+ }
379
+ let middleHeight = (height + bottomHeight) * 0.5;
380
+ if (!(isNoDataCurrent || isNoDataBottom)) {
381
+ middleHeight = (height + bottomHeight) * 0.5;
382
+ }
383
+ if ((j + tileX) % dt === 0) {
384
+ outCurrenElevations[currIndex++] = middleHeight;
385
+ }
394
386
  }
395
- if ((j + tileX) % dt === 0) {
387
+ if ((j + 1) % destSize === 0 && j !== sourceSize - 1 &&
388
+ (i + 1) % destSize === 0 && i !== sourceSize - 1) {
389
+ //current tile
390
+ let rightBottomHeight = heightFactor * this.rgb2Height(rgbaData[k4 + sourceSize4 + 4], rgbaData[k4 + sourceSize4 + 5], rgbaData[k4 + sourceSize4 + 6]);
391
+ let isNoDataRightBottom = RgbTerrain.checkNoDataValue(noDataValues, rightBottomHeight);
392
+ if ((isNoDataRightBottom || rightBottomHeight === 0) && availableParentData) {
393
+ rightBottomHeight = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor(currIndex / destSizeOne), currIndex % destSizeOne, skipPositiveHeights);
394
+ }
395
+ let middleHeight = height;
396
+ if (!(isNoDataCurrent || isNoDataRight || isNoDataBottom || isNoDataRightBottom)) {
397
+ middleHeight = (height + rightHeight + bottomHeight + rightBottomHeight) * 0.25;
398
+ }
396
399
  outCurrenElevations[currIndex++] = middleHeight;
397
400
  }
398
401
  }
399
- if ((j + 1) % destSize === 0 && j !== sourceSize - 1 &&
400
- (i + 1) % destSize === 0 && i !== sourceSize - 1) {
401
- //current tile
402
- let rightBottomHeight = heightFactor * rgb2Height(rgbaData[k4 + sourceSize4 + 4], rgbaData[k4 + sourceSize4 + 5], rgbaData[k4 + sourceSize4 + 6]);
403
- let isNoDataRightBottom = RgbTerrain.checkNoDataValue(noDataValues, rightBottomHeight);
404
- if ((isNoDataRightBottom || rightBottomHeight === 0) && availableParentData) {
405
- rightBottomHeight = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, Math.floor(currIndex / destSizeOne), currIndex % destSizeOne, skipPositiveHeights);
406
- }
407
- let middleHeight = height;
408
- if (!(isNoDataCurrent || isNoDataRight || isNoDataBottom || isNoDataRightBottom)) {
409
- middleHeight = (height + rightHeight + bottomHeight + rightBottomHeight) * 0.25;
410
- }
411
- outCurrenElevations[currIndex++] = middleHeight;
412
- }
413
402
  }
414
403
  }
404
+ function getTileOffset(currentTileX, currentTileY, currentTileZoom, parentTileX, parentTileY, parentTileZoom) {
405
+ let dz2 = 2 << (currentTileZoom - parentTileZoom - 1);
406
+ return [currentTileX - dz2 * parentTileX, currentTileY - dz2 * parentTileY, 1.0 / dz2];
407
+ }
408
+ function getChildTileIndex(currentParentTileX, currentParentTileY, currentParentTileZoom, childOffsetX, childOffsetY) {
409
+ return [currentParentTileX * 2 + childOffsetX, currentParentTileY * 2 + childOffsetY, currentParentTileZoom + 1];
410
+ }
411
+ function getParentHeight(oneByDz2, offsetX, offsetY, heights, i, j, skipPositiveHeights) {
412
+ let parentGridSize = Math.sqrt(heights.length);
413
+ let pi = Math.floor(offsetY * oneByDz2 * parentGridSize + i * oneByDz2), pj = Math.floor(offsetX * oneByDz2 * parentGridSize + j * oneByDz2);
414
+ let h = heights[pi * parentGridSize + pj];
415
+ return skipPositiveHeights ? (h > 0 ? 0 : h) : h;
416
+ }
415
417
  export { RgbTerrain };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openglobus/og",
3
- "version": "0.20.3",
3
+ "version": "0.21.0",
4
4
  "description": "[openglobus](https://www.openglobus.org/) is a javascript/typescript library designed to display interactive 3d maps and planets with map tiles, imagery and vector data, markers, and 3D objects. It uses the WebGL technology, open source, and completely free.",
5
5
  "directories": {
6
6
  "example": "./sandbox"
@@ -34,34 +34,34 @@
34
34
  },
35
35
  "homepage": "https://www.openglobus.org",
36
36
  "devDependencies": {
37
- "@babel/cli": "^7.24.7",
38
- "@babel/core": "^7.24.7",
37
+ "@babel/cli": "^7.25.6",
38
+ "@babel/core": "^7.25.2",
39
39
  "@babel/plugin-proposal-class-properties": "^7.18.6",
40
40
  "@babel/plugin-proposal-object-rest-spread": "^7.20.7",
41
- "@babel/preset-env": "^7.24.7",
41
+ "@babel/preset-env": "^7.25.4",
42
42
  "@babel/preset-typescript": "^7.24.7",
43
43
  "@rollup/plugin-json": "^6.1.0",
44
44
  "@rollup/plugin-terser": "^0.4.4",
45
45
  "@rollup/plugin-typescript": "^11.1.6",
46
46
  "@types/jest": "^29.5.12",
47
- "@typescript-eslint/eslint-plugin": "^7.14.1",
48
- "@typescript-eslint/parser": "^7.14.1",
47
+ "@typescript-eslint/eslint-plugin": "^8.4.0",
48
+ "@typescript-eslint/parser": "^8.4.0",
49
49
  "clean-jsdoc-theme": "^4.3.0",
50
- "eslint": "^8.57.0",
50
+ "eslint": "^9.9.1",
51
51
  "jest": "^29.7.0",
52
52
  "jest-canvas-mock": "^2.5.2",
53
53
  "jest-environment-jsdom": "^29.7.0",
54
54
  "jsdoc": "^4.0.3",
55
55
  "jsdoc-babel": "^0.5.0",
56
- "lint-staged": "^15.2.7",
57
- "local-web-server": "^5.3.3",
58
- "postcss": "^8.4.39",
59
- "prettier": "^3.3.2",
60
- "rollup": "^4.18.0",
56
+ "lint-staged": "^15.2.10",
57
+ "local-web-server": "^5.4.0",
58
+ "postcss": "^8.4.45",
59
+ "prettier": "^3.3.3",
60
+ "rollup": "^4.21.2",
61
61
  "rollup-plugin-copy": "^3.5.0",
62
62
  "rollup-plugin-postcss": "^4.0.2",
63
- "ts-jest": "^29.1.5",
64
- "typescript": "^5.5.2"
63
+ "ts-jest": "^29.2.5",
64
+ "typescript": "^5.5.4"
65
65
  },
66
66
  "lint-staged": {
67
67
  "*.{js,ts}": [