Added non power of two elevation images size support

This commit is contained in:
Zemledelec 2020-09-28 13:58:45 +03:00
parent 5857e15048
commit 02e74e1144
5 changed files with 184 additions and 36 deletions

View File

@ -0,0 +1,72 @@
<html>
<head>
<title>OpenGlobus - Earth planet</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../../css/og.css" type="text/css" />
</head>
<body>
<div id="globus" style="width:100%;height:100%"></div>
<div style="position: absolute; left:0; padding:10px;">
<button id="btnEmpty" style="float:left; margin: 3px;">Geoid</button>
<button id="btnGlobus" style="float:left; margin: 3px;">OpenGlobus</button>
<button id="btnMapbox" style="float:left; margin: 3px;">Mapbox</button>
<button id="btnBil" style="float:left; margin: 3px;">Bil16-Italy</button>
</div>
<script type="module">
import { Globe } from '../../src/og/Globe.js';
import { EmptyTerrain } from '../../src/og/terrain/EmptyTerrain.js';
import { GlobusTerrain } from '../../src/og/terrain/GlobusTerrain.js';
import { MapboxTerrain } from '../../src/og/terrain/MapboxTerrain.js';
import { BilTerrain } from '../../src/og/terrain/BilTerrain.js';
import { XYZ } from '../../src/og/layer/XYZ.js';
document.getElementById("btnEmpty").onclick = function () {
globus.planet.setTerrain(emptyTerrain);
};
document.getElementById("btnGlobus").onclick = function () {
globus.planet.setTerrain(globusTerrain);
};
document.getElementById("btnMapbox").onclick = function () {
globus.planet.setTerrain(mapboxTerrain);
};
document.getElementById("btnBil").onclick = function () {
globus.planet.setTerrain(bilTerrain);
};
let emptyTerrain = new EmptyTerrain(),
globusTerrain = new GlobusTerrain(),
mapboxTerrain = new MapboxTerrain(),
bilTerrain = new BilTerrain({
url: "//95.211.82.211:8080/geoserver/og/",
layers: "og:n44_e009_1arc_v3",
imageSize: 128,
gridSizeByZoom: [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 64, 64, 32, 32, 32, 16, 8],
extent: [[8.9, 44.0], [10.0, 45]]
});
let osm = new XYZ("OpenStreetMap", {
specular: [0.0003, 0.00012, 0.00001],
shininess: 20,
diffuse: [0.89, 0.9, 0.83],
isBaseLayer: true,
url: "//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
visibility: true,
attribution: 'Data @ OpenStreetMap contributors, ODbL'
});
let globus = new Globe({
"target": "globus",
"name": "Earth",
"terrain": emptyTerrain,
"layers": [osm]
});
</script>
</body>
</html>

View File

@ -170,12 +170,15 @@ let emptyTerrain = new EmptyTerrain(),
window.globe = new Globe({
'name': "Earth",
'target': "earth",
'terrain': emptyTerrain/*new MapboxTerrain(null, {
url: "http://alacst.ddns.net:8181/Tiles/testtile5/{z}/{x}/{y}.png",
'terrain': new MapboxTerrain(null, {
//url: "//alacst.ddns.net:8181/Tiles/testtile129/{z}/{x}/{y}.png",
url: "//alacst.ddns.net:8181/Tiles/129terrain/{z}/{x}/{y}.png",
minZoom: 9,
maxZoom: 23,
gridSizeByZoom: [64, 32, 32, 16, 16, 16, 16, 32, 64, 128, 128, 128, 128, 256, 256, 256, 256, 256, 256, 256, 256, 256, 128, 64, 32, 16]
})*/,
gridSizeByZoom: [64, 32, 32, 16, 16, 16, 16, 32, 64, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 64, 32, 16],
sourceImageSize: 129,
equalizeVertices: false
}),
'layers': [osm, tg],
//'viewExtent': [-1.12675, 51.60039, -1.11016, 5160336]
});

View File

@ -1,6 +1,7 @@
import { getTileExtent } from '../mercator.js';
import { Layer } from '../layer/Layer.js';
import { GlobusTerrain } from './GlobusTerrain.js';
import { isPowerOfTwo } from '../math.js';
const KEY = "pk.eyJ1IjoiZm94bXVsZGVyODMiLCJhIjoiY2pqYmR3dG5oM2Z1bzNrczJqYm5pODhuNSJ9.Y4DRmEPhb-XSlCR9CAXACQ";
@ -19,22 +20,28 @@ class MapboxTerrain extends GlobusTerrain {
this.maxZoom = options.maxZoom != undefined ? options.maxZoom : 15;
this.plainGridSize = options.plainGridSize || 128;
this.url = options.url != undefined ? options.url : `//api.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}.pngraw?access_token=${(options.key || KEY)}`;
this._dataType = "imageBitmap";
this._canvas = document.createElement("canvas");
this._canvas.width = 256;
this._canvas.height = 256;
this._ctx = this._canvas.getContext("2d");
this.plainGridSize = options.plainGridSize || 128;
this._sourceImageSize = options.sourceImageSize || 256;
this._ctx = this._createTemporalCanvas(this._sourceImageSize);
}
isBlur() {
return false;
}
_createTemporalCanvas(size) {
let canvas = document.createElement("canvas");
canvas.width = size;
canvas.height = size;
return canvas.getContext("2d");
}
_createHeights(data, segment) {
const SIZE = data.width;
@ -42,37 +49,61 @@ class MapboxTerrain extends GlobusTerrain {
this._ctx.drawImage(data, 0, 0);
let rgbaData = this._ctx.getImageData(0, 0, SIZE, SIZE).data;
let elevationsSize = (this.plainGridSize + 1) * (this.plainGridSize + 1);
let d = SIZE / this.plainGridSize;
let outCurrenElevations = new Float32Array(elevationsSize);
let outChildrenElevations = new Array(d);
for (let i = 0; i < d; i++) {
outChildrenElevations[i] = [];
for (let j = 0; j < d; j++) {
outChildrenElevations[i][j] = new Float32Array(elevationsSize);
}
//
//Non power of two images
//
if (SIZE === this._sourceImageSize) {
let outCurrenElevations = new Float32Array(SIZE * SIZE);
extractElevationTilesMapboxNonPowerOfTwo(rgbaData, outCurrenElevations);
return outCurrenElevations;
}
extractElevationTilesMapbox(rgbaData, outCurrenElevations, outChildrenElevations);
//
// Power of two images
//
if (this._sourceImageSize === this.plainGridSize) {
this._elevationCache[segment.tileIndex] = {
heights: outCurrenElevations,
extent: segment.getExtent()
};
} else {
for (let i = 0; i < d; i++) {
for (let j = 0; j < d; j++) {
let tileIndex = Layer.getTileIndex(segment.tileX * 2 + j, segment.tileY * 2 + i, segment.tileZoom);
this._elevationCache[tileIndex] = {
heights: outChildrenElevations[i][j],
extent: getTileExtent(segment.tileX, segment.tileY, segment.tileZoom)
};
let elevationsSize = (this.plainGridSize + 1) * (this.plainGridSize + 1);
let d = SIZE / this.plainGridSize;
let outCurrenElevations = new Float32Array(elevationsSize);
let outChildrenElevations = new Array(d);
for (let i = 0; i < d; i++) {
outChildrenElevations[i] = [];
for (let j = 0; j < d; j++) {
outChildrenElevations[i][j] = new Float32Array(elevationsSize);
}
}
}
return outCurrenElevations;
extractElevationTilesMapbox(rgbaData, outCurrenElevations, outChildrenElevations);
this._elevationCache[segment.tileIndex] = {
heights: outCurrenElevations,
extent: segment.getExtent()
};
for (let i = 0; i < d; i++) {
for (let j = 0; j < d; j++) {
let tileIndex = Layer.getTileIndex(segment.tileX * 2 + j, segment.tileY * 2 + i, segment.tileZoom);
this._elevationCache[tileIndex] = {
heights: outChildrenElevations[i][j],
extent: getTileExtent(segment.tileX, segment.tileY, segment.tileZoom)
};
}
}
return outCurrenElevations;
}
}
};
function extractElevationTilesMapboxNonPowerOfTwo(rgbaData, outCurrenElevations) {
for (let i = 0, len = outCurrenElevations.length; i < len; i++) {
let i4 = i * 4;
outCurrenElevations[i] = -10000 + 0.1 * (rgbaData[i4] * 256 * 256 + rgbaData[i4 + 1] * 256 + rgbaData[i4 + 2]);
}
};

View File

@ -583,7 +583,7 @@ export function blerp2(x, y, fQ11, fQ21, fQ12, fQ22) {
return (fQ11 * (1.0 - x) * (1.0 - y) + fQ21 * x * (1.0 - y) + fQ12 * (1.0 - x) * y + fQ22 * x * y);
};
export function extractElevationTiles(rgbaData, outCurrenElevations, outChildrenElevations, fn) {
export function extractElevationTiles(rgbaData, outCurrenElevations, outChildrenElevations) {
let destSize = Math.sqrt(outCurrenElevations.length) - 1;
let destSizeOne = destSize + 1;

View File

@ -76,6 +76,48 @@ test('Test for extractElevationTiles 4 function', () => {
expect(outChildrenElevations[1][1]).toEqual(tileElevations11);
});
//test('Test for extractElevationTiles same size function', () => {
// const SIZE = 4;
// const OUTPUT_SIZE = 4;
// function createMockData() {
// let res = new Uint8Array(SIZE * SIZE * 4);
// for (let i = 0, len = res.length; i < len; i += 4) {
// let c = Math.round(i / 4);
// res[i] = c;
// res[i + 1] = c;
// res[i + 2] = c;
// res[i + 3] = 255;
// }
// return res;
// }
// let rgbaData = createMockData();
// let elevationsSize = (OUTPUT_SIZE + 1) * (OUTPUT_SIZE + 1);
// let d = Math.sqrt(rgbaData.length / 4) / OUTPUT_SIZE;
// let outCurrenElevations = new Float32Array(elevationsSize);
// let outChildrenElevations = new Array(d);
// for (let i = 0; i < d; i++) {
// outChildrenElevations[i] = [];
// for (let j = 0; j < d; j++) {
// outChildrenElevations[i][j] = new Float32Array(elevationsSize);
// }
// }
// shared.extractElevationTiles(rgbaData, outCurrenElevations, outChildrenElevations);
// // Current tile
// let currentElevations = new Float32Array([
// 0, 1.5, 3,
// 6, 7.5, 9,
// 12, 13.5, 15]);
// expect(outCurrenElevations).toEqual(currentElevations);
//});
test('Test concatTypedArrays', () => {
//