@openglobus/og 0.20.4 → 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.
- package/lib/@openglobus/js/Globe.d.ts +1 -1
- package/lib/@openglobus/js/Object3d.d.ts +1 -0
- package/lib/@openglobus/js/entity/GeometryHandler.d.ts +3 -2
- package/lib/@openglobus/js/terrain/RgbTerrain.d.ts +9 -0
- package/lib/@openglobus/og.esm.js +1 -1
- package/lib/@openglobus/og.esm.js.map +1 -1
- package/lib/@openglobus/og.umd.js +1 -1
- package/lib/@openglobus/og.umd.js.map +1 -1
- package/lib/js/Globe.d.ts +1 -1
- package/lib/js/Globe.js +7 -2
- package/lib/js/Object3d.d.ts +1 -0
- package/lib/js/Object3d.js +18 -0
- package/lib/js/entity/GeometryHandler.d.ts +3 -2
- package/lib/js/entity/GeometryHandler.js +56 -0
- package/lib/js/layer/Bing.js +1 -0
- package/lib/js/layer/Vector.js +4 -2
- package/lib/js/terrain/RgbTerrain.d.ts +9 -0
- package/lib/js/terrain/RgbTerrain.js +215 -213
- 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
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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,
|
|
228
|
+
height = getParentHeight(availableZoomDiff, availableParentOffsetX, availableParentOffsetY, availableParentData, imageSize - 1, imageSize - 1, skipPositiveHeights);
|
|
234
229
|
}
|
|
235
|
-
outCurrenElevations[
|
|
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
|
-
|
|
251
|
-
|
|
252
|
-
|
|
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
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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
|
|
281
|
-
if ((
|
|
282
|
-
|
|
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
|
-
|
|
289
|
-
destArr
|
|
290
|
-
|
|
291
|
-
|
|
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
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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
|
-
|
|
308
|
-
|
|
309
|
-
|
|
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
|
-
|
|
312
|
-
|
|
313
|
-
|
|
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
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
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
|
|
376
|
-
if (
|
|
377
|
-
|
|
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
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
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
|
-
|
|
392
|
-
|
|
393
|
-
|
|
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 +
|
|
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.
|
|
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.
|
|
38
|
-
"@babel/core": "^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.
|
|
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": "^
|
|
48
|
-
"@typescript-eslint/parser": "^
|
|
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": "^
|
|
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.
|
|
57
|
-
"local-web-server": "^5.
|
|
58
|
-
"postcss": "^8.4.
|
|
59
|
-
"prettier": "^3.3.
|
|
60
|
-
"rollup": "^4.
|
|
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.
|
|
64
|
-
"typescript": "^5.5.
|
|
63
|
+
"ts-jest": "^29.2.5",
|
|
64
|
+
"typescript": "^5.5.4"
|
|
65
65
|
},
|
|
66
66
|
"lint-staged": {
|
|
67
67
|
"*.{js,ts}": [
|