vizicities/src/layer/tile/Tile.js

216 wiersze
5.0 KiB
JavaScript
Executable File
Czysty Wina Historia

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

import {point as Point} from '../../geo/Point';
import {latLon as LatLon} from '../../geo/LatLon';
import THREE from 'three';
// TODO: Make sure nothing is left behind in the heap after calling destroy()
// Manages a single tile and its layers
var r2d = 180 / Math.PI;
var tileURLRegex = /\{([szxy])\}/g;
class Tile {
constructor(quadcode, path, layer) {
this._layer = layer;
this._world = layer._world;
this._quadcode = quadcode;
this._path = path;
this._ready = false;
this._aborted = false;
this._tile = this._quadcodeToTile(quadcode);
// Bottom-left and top-right bounds in WGS84 coordinates
this._boundsLatLon = this._tileBoundsWGS84(this._tile);
// Bottom-left and top-right bounds in world coordinates
this._boundsWorld = this._tileBoundsFromWGS84(this._boundsLatLon);
// Tile center in world coordinates
this._center = this._boundsToCenter(this._boundsWorld);
// Tile center in projected coordinates
this._centerLatlon = this._world.pointToLatLon(Point(this._center[0], this._center[1]));
// Length of a tile side in world coorindates
this._side = this._getSide(this._boundsWorld);
// Point scale for tile (for unit conversion)
this._pointScale = this._world.pointScale(this._centerLatlon);
}
// Returns true if the tile mesh and texture are ready to be used
// Otherwise, returns false
isReady() {
return this._ready;
}
isAborted() {
return this._aborted;
}
// Request data for the tile
requestTileAsync() {}
getQuadcode() {
return this._quadcode;
}
getBounds() {
return this._boundsWorld;
}
getCenter() {
return this._center;
}
getSide() {
return this._side;
}
getMesh() {
return this._mesh;
}
getPickingMesh() {
return this._pickingMesh;
}
// Destroys the tile and removes it from the layer and memory
//
// Ensure that this leaves no trace of the tile – no textures, no meshes,
// nothing in memory or the GPU
destroy() {
// console.log('Destroying tile', this._quadcode);
// Delete reference to layer and world
this._layer = null;
this._world = null;
// Delete location references
this._boundsLatLon = null;
this._boundsWorld = null;
this._center = null;
// Done if no mesh
if (!this._mesh && !this._pickingMesh) {
return;
}
this.destroyMesh(this._mesh);
this.destroyMesh(this._pickingMesh);
this._mesh = null;
this._pickingMesh = null;
}
destroyMesh(mesh, dispose = true) {
if (mesh) {
if (mesh.children) {
mesh.children.forEach((child) => {
mesh.remove(child);
this.destroyMesh(child);
});
}
if (dispose) {
if (mesh.geometry) {
mesh.geometry.dispose();
mesh.geometry = null;
}
if (mesh.material) {
if (mesh.material.map) {
mesh.material.map.dispose();
mesh.material.map = null;
}
mesh.material.dispose();
mesh.material = null;
}
}
}
}
_createMesh() {}
_createDebugMesh() {}
_getTileURL(urlParams) {
if (!urlParams.s) {
// Default to a random choice of a, b or c
urlParams.s = String.fromCharCode(97 + Math.floor(Math.random() * 3));
}
tileURLRegex.lastIndex = 0;
return this._path.replace(tileURLRegex, function(value, key) {
// Replace with paramter, otherwise keep existing value
return urlParams[key];
});
}
// Convert from quadcode to TMS tile coordinates
_quadcodeToTile(quadcode) {
var x = 0;
var y = 0;
var z = quadcode.length;
for (var i = z; i > 0; i--) {
var mask = 1 << (i - 1);
var q = +quadcode[z - i];
if (q === 1) {
x |= mask;
}
if (q === 2) {
y |= mask;
}
if (q === 3) {
x |= mask;
y |= mask;
}
}
return [x, y, z];
}
// Convert WGS84 tile bounds to world coordinates
_tileBoundsFromWGS84(boundsWGS84) {
var sw = this._layer._world.latLonToPoint(LatLon(boundsWGS84[1], boundsWGS84[0]));
var ne = this._layer._world.latLonToPoint(LatLon(boundsWGS84[3], boundsWGS84[2]));
return [sw.x, sw.y, ne.x, ne.y];
}
// Get tile bounds in WGS84 coordinates
_tileBoundsWGS84(tile) {
var e = this._tile2lon(tile[0] + 1, tile[2]);
var w = this._tile2lon(tile[0], tile[2]);
var s = this._tile2lat(tile[1] + 1, tile[2]);
var n = this._tile2lat(tile[1], tile[2]);
return [w, s, e, n];
}
_tile2lon(x, z) {
return x / Math.pow(2, z) * 360 - 180;
}
_tile2lat(y, z) {
var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
}
_boundsToCenter(bounds) {
var x = bounds[0] + (bounds[2] - bounds[0]) / 2;
var y = bounds[1] + (bounds[3] - bounds[1]) / 2;
return [x, y];
}
_getSide(bounds) {
return (new THREE.Vector3(bounds[0], 0, bounds[3])).sub(new THREE.Vector3(bounds[0], 0, bounds[1])).length();
}
}
export default Tile;