Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/deck.gl-geotiff/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
},
"dependencies": {
"@developmentseed/deck.gl-raster": "workspace:^",
"@developmentseed/morecantile": "^0.1.1",
"@developmentseed/raster-reproject": "workspace:^",
"flatbush": "^4.5.0",
"geotiff": "2.1.3",
Expand Down
13 changes: 5 additions & 8 deletions packages/deck.gl-geotiff/src/cog-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,9 @@ import type {
} from "@deck.gl/geo-layers";
import { TileLayer } from "@deck.gl/geo-layers";
import { PathLayer } from "@deck.gl/layers";
import type {
RasterModule,
TileMatrix,
TileMatrixSet,
} from "@developmentseed/deck.gl-raster";
import { RasterLayer, RasterTileset2D } from "@developmentseed/deck.gl-raster";
import type { RasterModule } from "@developmentseed/deck.gl-raster";
import { RasterLayer, TMSTileset2D } from "@developmentseed/deck.gl-raster";
import type { TileMatrix, TileMatrixSet } from "@developmentseed/morecantile";
import type { ReprojectionFns } from "@developmentseed/raster-reproject";
import type { Device } from "@luma.gl/core";
import type { BaseClient, GeoTIFF, GeoTIFFImage, Pool } from "geotiff";
Expand Down Expand Up @@ -414,15 +411,15 @@ export class COGLayer<
images: GeoTIFFImage[],
): TileLayer {
// Create a factory class that wraps COGTileset2D with the metadata
class RasterTileset2DFactory extends RasterTileset2D {
class TMSTileset2DFactory extends TMSTileset2D {
constructor(opts: Tileset2DProps) {
super(metadata, opts);
}
}

return new TileLayer<GetTileDataResult<DataT>>({
id: `cog-tile-layer-${this.id}`,
TilesetClass: RasterTileset2DFactory,
TilesetClass: TMSTileset2DFactory,
getTileData: async (tile) => this._getTileData(tile, images, metadata),
renderSubLayers: (props) =>
this._renderSubLayers(
Expand Down
52 changes: 5 additions & 47 deletions packages/deck.gl-geotiff/src/cog-tile-matrix-set.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type {
BoundingBox,
TileMatrix,
TileMatrixSet,
TileMatrixSetBoundingBox,
} from "@developmentseed/deck.gl-raster";
} from "@developmentseed/morecantile";
import { metersPerUnit } from "@developmentseed/morecantile";
import type { GeoTIFF, GeoTIFFImage } from "geotiff";
import proj4, { type ProjectionDefinition } from "proj4";
import Ellipsoid from "./ellipsoids.js";
Expand Down Expand Up @@ -109,52 +110,9 @@ export async function parseCOGTileMatrixSet(
boundingBox,
wgsBounds: computeWgs84BoundingBox(boundingBox, projectToWgs84),
tileMatrices,
projectToWgs84,
projectTo3857,
};
}

/**
* Coefficient to convert the coordinate reference system (CRS)
* units into meters (metersPerUnit).
*
* From note g in http://docs.opengeospatial.org/is/17-083r2/17-083r2.html#table_2:
*
* > If the CRS uses meters as units of measure for the horizontal dimensions,
* > then metersPerUnit=1; if it has degrees, then metersPerUnit=2pa/360
* > (a is the Earth maximum radius of the ellipsoid).
*
* If `crsUnit` is provided, it takes precedence over the unit defined in the
* CRS. This exists because sometimes the parsed CRS from
* `geotiff-geokeys-to-proj4` doesn't have a unit defined.
*/
// https://github.com/developmentseed/morecantile/blob/7c95a11c491303700d6e33e9c1607f2719584dec/morecantile/utils.py#L67-L90
function metersPerUnit(
parsedCrs: ProjectionDefinition,
crsUnit?: SupportedCrsUnit,
): number {
const unit = (crsUnit || parsedCrs.units)?.toLowerCase();
switch (unit) {
case "m":
case "metre":
case "meter":
case "meters":
return 1;
case "foot":
return 0.3048;
case "us survey foot":
return 1200 / 3937;
}

if (unit === "degree") {
// 2 * π * ellipsoid semi-major-axis / 360
const { a } = Ellipsoid[parsedCrs.ellps as keyof typeof Ellipsoid];
return (2 * Math.PI * a) / 360;
}

throw new Error(`Unsupported CRS units: ${unit}`);
}

/**
* Create tile matrix for COG overview
*/
Expand Down Expand Up @@ -215,9 +173,9 @@ function createOverviewTileMatrix({
}

function computeWgs84BoundingBox(
boundingBox: TileMatrixSetBoundingBox,
boundingBox: BoundingBox,
projectToWgs84: (point: [number, number]) => [number, number],
): TileMatrixSetBoundingBox {
): BoundingBox {
const lowerLeftWgs84 = projectToWgs84(boundingBox.lowerLeft);
const lowerRightWgs84 = projectToWgs84([
boundingBox.upperRight[0],
Expand Down
1 change: 1 addition & 0 deletions packages/deck.gl-raster/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"@luma.gl/shadertools": "^9.2.7"
},
"dependencies": {
"@developmentseed/morecantile": "^0.1.1",
"@developmentseed/raster-reproject": "workspace:^",
"@math.gl/core": "^4.1.0",
"@math.gl/culling": "^4.1.0",
Expand Down
7 changes: 1 addition & 6 deletions packages/deck.gl-raster/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
export type { RasterModule } from "./gpu-modules/types.js";
export type { RasterLayerProps } from "./raster-layer.js";
export { RasterLayer } from "./raster-layer.js";
export { RasterTileset2D } from "./raster-tileset/index.js";
export type {
TileMatrix,
TileMatrixSet,
TileMatrixSetBoundingBox,
} from "./raster-tileset/types.js";
export { TMSTileset2D } from "./raster-tileset/index.js";

import { __TEST_EXPORTS as traversalTestExports } from "./raster-tileset/raster-tile-traversal.js";

Expand Down
3 changes: 1 addition & 2 deletions packages/deck.gl-raster/src/raster-tileset/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { RasterTileset2D } from "./raster-tileset-2d.js";
export type { TileMatrix, TileMatrixSet } from "./types.js";
export { TMSTileset2D } from "./raster-tileset-2d.js";
64 changes: 35 additions & 29 deletions packages/deck.gl-raster/src/raster-tileset/raster-tile-traversal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import type { Viewport } from "@deck.gl/core";
import { _GlobeViewport, assert } from "@deck.gl/core";
import type { TileMatrix, TileMatrixSet } from "@developmentseed/morecantile";
import type { OrientedBoundingBox } from "@math.gl/culling";
import {
CullingVolume,
Expand All @@ -27,9 +28,9 @@ import { lngLatToWorld, worldToLngLat } from "@math.gl/web-mercator";

import type {
Bounds,
CornerBounds,
ProjectionFunction,
TileIndex,
TileMatrix,
TileMatrixSet,
ZRange,
} from "./types.js";

Expand Down Expand Up @@ -138,11 +139,22 @@ export class RasterTileNode {
/** A cache of the children of this node. */
private _children?: RasterTileNode[] | null;

constructor(x: number, y: number, z: number, metadata: TileMatrixSet) {
private projectTo3857: ProjectionFunction;

constructor(
x: number,
y: number,
z: number,
{
metadata,
projectTo3857,
}: { metadata: TileMatrixSet; projectTo3857: ProjectionFunction },
) {
this.x = x;
this.y = y;
this.z = z;
this.metadata = metadata;
this.projectTo3857 = projectTo3857;
}

/** Get overview info for this tile's z level */
Expand Down Expand Up @@ -188,9 +200,15 @@ export class RasterTileNode {

const children: RasterTileNode[] = [];

const { metadata, projectTo3857 } = this;
for (let y = minRow; y <= maxRow; y++) {
for (let x = minCol; x <= maxCol; x++) {
children.push(new RasterTileNode(x, y, childZ, this.metadata));
children.push(
new RasterTileNode(x, y, childZ, {
metadata,
projectTo3857,
}),
);
}
}

Expand Down Expand Up @@ -364,12 +382,9 @@ export class RasterTileNode {
const [minX, minY, maxX, maxY] = bounds;
const [tileMinX, tileMinY, tileMaxX, tileMaxY] = commonSpaceBounds;

// console.log("bounds:", bounds);
// console.log("tile bounds:", commonSpaceBounds);

const inside =
tileMinX < maxX && tileMaxX > minX && tileMinY < maxY && tileMaxY > minY;
// console.log("insideBounds", inside);

return inside;
}

Expand Down Expand Up @@ -428,7 +443,7 @@ export class RasterTileNode {
const refPointsEPSG3857 = sampleReferencePointsInEPSG3857(
REF_POINTS_9,
tileCrsBounds,
this.metadata.projectTo3857,
this.projectTo3857,
);

const commonSpacePositions = refPointsEPSG3857.map((xy) =>
Expand Down Expand Up @@ -546,7 +561,7 @@ function computeProjectedTileBounds({
function sampleReferencePointsInEPSG3857(
refPoints: [number, number][],
tileBounds: [number, number, number, number],
projectTo3857: (xy: [number, number]) => [number, number],
projectTo3857: ProjectionFunction,
): [number, number][] {
const [minX, minY, maxX, maxY] = tileBounds;
const refPointPositions: [number, number][] = [];
Expand Down Expand Up @@ -675,9 +690,11 @@ export function getTileIndices(
viewport: Viewport;
maxZ: number;
zRange: ZRange | null;
projectTo3857: ProjectionFunction;
wgs84Bounds: CornerBounds;
},
): TileIndex[] {
const { viewport, maxZ, zRange } = opts;
const { viewport, maxZ, zRange, wgs84Bounds } = opts;

// Only define `project` function for Globe viewports, same as upstream
const project: ((xyz: number[]) => number[]) | null =
Expand Down Expand Up @@ -723,7 +740,7 @@ export function getTileIndices(
// minZ to 0
const minZ = 0;

const { lowerLeft, upperRight } = metadata.wgsBounds;
const { lowerLeft, upperRight } = wgs84Bounds;
const [minLng, minLat] = lowerLeft;
const [maxLng, maxLat] = upperRight;
const bottomLeft = lngLatToWorld([minLng, minLat]);
Expand All @@ -744,7 +761,12 @@ export function getTileIndices(
const roots: RasterTileNode[] = [];
for (let y = 0; y < rootMatrix.matrixHeight; y++) {
for (let x = 0; x < rootMatrix.matrixWidth; x++) {
roots.push(new RasterTileNode(x, y, 0, metadata));
roots.push(
new RasterTileNode(x, y, 0, {
metadata,
projectTo3857: opts.projectTo3857,
}),
);
}
}

Expand All @@ -759,9 +781,6 @@ export function getTileIndices(
bounds,
};

// console.log("traversalParams", traversalParams);
// console.log("roots", roots);

for (const root of roots) {
root.update(traversalParams);
}
Expand Down Expand Up @@ -800,19 +819,6 @@ function getMetersPerPixelAtBoundingVolume(
return getMetersPerPixel(lat, zoom);
}

// function getScreenMetersPerPixel(viewport: Viewport, center: Vector3): number {
// const lng
// const p0 = viewport.projectPosition(center);
// const p1 = viewport.projectPosition([
// centerArray[0]! + 1,
// centerArray[1]!,
// centerArray[2]!,
// ]);

// const pixelsPerMeter = Math.hypot(p1[0] - p0[0], p1[1] - p0[1]);
// return 1 / pixelsPerMeter;
// }

/**
* Exports only for use in testing
*/
Expand Down
Loading
Loading