UNPKG

@loaders.gl/3d-tiles

Version:

3D Tiles, an open standard for streaming massive heterogeneous 3D geospatial datasets.

61 lines 2.47 kB
// loaders.gl // SPDX-License-Identifier: MIT // Copyright vis.gl contributors import { IJToST, STToUV, FaceUVToXYZ, XYZToLngLat } from "../s2geometry/s2-geometry.js"; const MAX_RESOLUTION = 100; /** * Get a polygon with corner coordinates for an S2 cell * @param s2cell {S2Cell} S2 cell * @return {Float64Array} - a simple polygon in flat array format: [lng0, lat0, lng1, lat1, ...] * - the polygon is closed, i.e. last coordinate is a copy of the first coordinate */ // eslint-disable-next-line max-statements export function getS2BoundaryFlatFromS2Cell(s2cell) { const { face, ij, level } = s2cell; const offsets = [ [0, 0], [0, 1], [1, 1], [1, 0], [0, 0] ]; // The S2 cell edge is curved: http://s2geometry.io/ // This is more prominent at lower levels // resolution is the number of segments to generate per edge. // We exponentially reduce resolution as level increases so it doesn't affect perf // when there are a large number of cells const resolution = Math.max(1, Math.ceil(MAX_RESOLUTION * Math.pow(2, -level))); const result = new Float64Array(4 * resolution * 2 + 2); let ptIndex = 0; let prevLng = 0; for (let i = 0; i < 4; i++) { const offset = offsets[i].slice(0); const nextOffset = offsets[i + 1]; const stepI = (nextOffset[0] - offset[0]) / resolution; const stepJ = (nextOffset[1] - offset[1]) / resolution; for (let j = 0; j < resolution; j++) { offset[0] += stepI; offset[1] += stepJ; // Cell can be represented by coordinates IJ, ST, UV, XYZ // http://s2geometry.io/devguide/s2cell_hierarchy#coordinate-systems const st = IJToST(ij, level, offset); const uv = STToUV(st); const xyz = FaceUVToXYZ(face, uv); const lngLat = XYZToLngLat(xyz); // Adjust longitude for Web Mercator projection if (Math.abs(lngLat[1]) > 89.999) { lngLat[0] = prevLng; } const deltaLng = lngLat[0] - prevLng; lngLat[0] += deltaLng > 180 ? -360 : deltaLng < -180 ? 360 : 0; result[ptIndex++] = lngLat[0]; result[ptIndex++] = lngLat[1]; prevLng = lngLat[0]; } } // close the loop result[ptIndex++] = result[0]; result[ptIndex++] = result[1]; return result; } //# sourceMappingURL=s2-to-boundary.js.map