Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read crs information from metadata #114

Merged
merged 8 commits into from
Mar 26, 2024
Merged
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
7 changes: 4 additions & 3 deletions src/initialize-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const initializeStore = async (source, version, variable, coordinateKeys) => {
let chunks
let fill_value
let dtype
let levels, maxZoom, tileSize
let levels, maxZoom, tileSize, crs
const coordinates = {}
switch (version) {
case 'v2':
Expand All @@ -21,7 +21,7 @@ const initializeStore = async (source, version, variable, coordinateKeys) => {
resolve()
})
)
;({ levels, maxZoom, tileSize } = getPyramidMetadata(
;({ levels, maxZoom, tileSize, crs } = getPyramidMetadata(
metadata.metadata['.zattrs'].multiscales
))

Expand All @@ -48,7 +48,7 @@ const initializeStore = async (source, version, variable, coordinateKeys) => {
break
case 'v3':
metadata = await fetch(`${source}/zarr.json`).then((res) => res.json())
;({ levels, maxZoom, tileSize } = getPyramidMetadata(
;({ levels, maxZoom, tileSize, crs } = getPyramidMetadata(
metadata.attributes.multiscales
))

Expand Down Expand Up @@ -114,6 +114,7 @@ const initializeStore = async (source, version, variable, coordinateKeys) => {
levels,
maxZoom,
tileSize,
crs,
}
}

Expand Down
27 changes: 24 additions & 3 deletions src/tiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const createTiles = (regl, opts) => {
setMetadata,
order,
version = 'v2',
projection = 'mercator',
projection,
}) {
this.tiles = {}
this.loaders = {}
Expand All @@ -57,8 +57,6 @@ export const createTiles = (regl, opts) => {
this.selector = selector
this.variable = variable
this.fillValue = fillValue
this.projection = projection
this.projectionIndex = ['mercator', 'equirectangular'].indexOf(projection)
this.order = order ?? [1, 1]
this.invalidate = invalidate
this.viewport = { viewportHeight: 0, viewportWidth: 0 }
Expand Down Expand Up @@ -117,13 +115,31 @@ export const createTiles = (regl, opts) => {
levels,
maxZoom,
tileSize,
crs,
}) => {
if (setMetadata) setMetadata(metadata)
this.maxZoom = maxZoom
this.level = zoomToLevel(this.zoom, maxZoom)
const position = getPositions(tileSize, mode)
this.position = regl.buffer(position)
this.size = tileSize
// Respect `projection` prop when provided, otherwise rely on `crs` value from metadata
this.projectionIndex = projection
? ['mercator', 'equirectangular'].indexOf(projection)
: ['EPSG:3857', 'EPSG:4326'].indexOf(crs)
this.projection = ['mercator', 'equirectangular'][
this.projectionIndex
]

Comment on lines +126 to +133
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like we default to mercator in the shader in the case of a -1 index, but is there any other reason to handle an invalid index early here? Seems like updateCamera and maybe the region picker stuff might be sad if this.projection ends up undefined.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call! Decided to add a check here to handle either an unexpected crs and projection value. Want to take another look.

if (!this.projection) {
this.projection = null
throw new Error(
projection
? `Unexpected \`projection\` prop provided: '${projection}'. Must be one of 'mercator', 'equirectangular'.`
: `Unexpected \`crs\` found in metadata: '${crs}'. Must be one of 'EPSG:3857', 'EPSG:4326'.`
)
}

if (mode === 'grid' || mode === 'dotgrid') {
this.count = position.length
}
Expand Down Expand Up @@ -291,6 +307,11 @@ export const createTiles = (regl, opts) => {
}

this.updateCamera = ({ center, zoom }) => {
// Return early if projection not yet initialized
if (!this.projection) {
return
}

const level = zoomToLevel(zoom, this.maxZoom)
const tile = pointToTile(
center.lng,
Expand Down
13 changes: 10 additions & 3 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { point, rhumbBearing, rhumbDestination } from '@turf/turf'
import { select } from 'd3-selection'

const d2r = Math.PI / 180

Expand Down Expand Up @@ -41,7 +40,7 @@ export const pointToTile = (lon, lat, z, projection, order) => {
y = Math.max(Math.min(y, z2), 0)
tile = [x, y, z]
default:
break
return
}
tile[0] = Math.floor(tile[0])
tile[1] = Math.min(Math.floor(tile[1]), z2 - 1)
Expand Down Expand Up @@ -349,13 +348,21 @@ export const getPyramidMetadata = (multiscales) => {
const levels = datasets.map((dataset) => Number(dataset.path))
const maxZoom = Math.max(...levels)
const tileSize = datasets[0].pixels_per_tile
let crs = datasets[0].crs

if (!tileSize) {
throw new Error(
'Missing required `pixels_per_tile` value in `multiscales` metadata. Please check your pyramid generation code.'
)
}
return { levels, maxZoom, tileSize }

if (!crs) {
console.warn(
'Missing `crs` value in `multiscales` metadata. Please check your pyramid generation code. Falling back to `crs=EPSG:3857` (Web Mercator)'
)
crs = 'EPSG:3857'
}
return { levels, maxZoom, tileSize, crs }
Comment on lines +359 to +365
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be worth adding a check to see if the provided crs is one of our two valid options and to report out those options if not

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a consolidated check in tiles.js

}

/**
Expand Down
Loading