Skip to content

Commit

Permalink
fix: updated processes to passthrough tiff metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
tawera-manaena committed Dec 9, 2024
1 parent b19e45d commit 3994738
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 133 deletions.
8 changes: 7 additions & 1 deletion src/commands/basemaps-topo-import/gdal-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ export function gdalBuildVrt(targetVrt: URL, source: URL[]): GdalCommand {
return {
output: targetVrt,
command: 'gdalbuildvrt',
args: [['-addalpha'], urlToString(targetVrt), ...source.map(urlToString)]
args: [
['-addalpha'],
['-hidenodata'],
['-vrtnodata', '208 231 244'],
urlToString(targetVrt),
...source.map(urlToString),
]
.filter((f) => f != null)
.flat()
.map(String),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Bounds, Projection } from '@basemaps/geo';
import { Tiff } from '@cogeotiff/core';

import { logger } from '../../../log.js';
Expand All @@ -14,8 +13,8 @@ import { TiffItem } from '../types/tiff-item.js';
* For each group, we then need to identify the latest version and set it aside from the rest.
* The latest version will have special metadata, whereas the rest will have similar metadata.
*
* @param tiffs: The tiffs to group by map code and version
* @returns a `SplitEpsgMap` Map object
* @param tiffs: The tiffs to group by epsg, and map code
* @returns a `ByDirectory<TiffItem>` promise
*/
export async function groupTiffsByDirectory(tiffs: Tiff[]): Promise<ByDirectory<TiffItem>> {
// group the tiffs by directory, epsg, and map code
Expand Down Expand Up @@ -43,13 +42,7 @@ export async function groupTiffsByDirectory(tiffs: Tiff[]): Promise<ByDirectory<
continue;
}

const projection = Projection.tryGet(epsg);
if (projection == null) throw new Error(`Could not find a projection for epsg:${epsg.code}`);

// Convert bounds to WGS84 for different source epsg
const boundsCoverted = Bounds.fromBbox(projection.boundsToWgs84BoundingBox(bounds));

const item = new TiffItem(tiff, source, mapCode, version, boundsCoverted, epsg);
const item = new TiffItem(tiff, source, mapCode, version, bounds, epsg);

// push the item into 'all' by {epsg} and {map code}
byDirectory.all.get(epsg.toString()).get(mapCode, []).push(item);
Expand Down
29 changes: 10 additions & 19 deletions src/commands/basemaps-topo-import/stac/create-base-stac-item.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Epsg } from '@basemaps/geo';
import { CliId } from '@basemaps/shared/build/cli/info.js';
import { StacItem } from 'stac-ts';
import { GeoJSONPolygon } from 'stac-ts/src/types/geojson.js';
Expand All @@ -10,30 +9,23 @@ const cliDate = new Date().toISOString();

/**
* This function creates a base StacItem object based on the provided parameters.
* @param id: The id of the StacItem
* @example "CJ10" or "CJ10_v1-00"
*
* @param mapCode The map code of the map sheet
* @example "CJ10"
*
* @param version The version of the map sheet
* @example "v1-00"
*
* @param tiff TODO
* @param fileName: The map sheet's filename
* @example "CJ10" or "CJ10_v1-00"
*
* @param bounds TODO
* @param tiffItem TODO
*
* @returns
* @returns a StacItem object
*/
export function createBaseStacItem(id: string, mapCode: string, tiffItem: TiffItem): StacItem {
logger.info({ id }, 'createBaseStacItem()');
export function createBaseStacItem(fileName: string, tiffItem: TiffItem): StacItem {
logger.info({ fileName }, 'createBaseStacItem()');

const item: StacItem = {
type: 'Feature',
stac_version: '1.0.0',
id: id,
id: fileName,
links: [
{ rel: 'self', href: `./${id}.json`, type: 'application/json' },
{ rel: 'self', href: `./${fileName}.json`, type: 'application/json' },
{ rel: 'collection', href: './collection.json', type: 'application/json' },
{ rel: 'parent', href: './collection.json', type: 'application/json' },
],
Expand All @@ -47,10 +39,9 @@ export function createBaseStacItem(id: string, mapCode: string, tiffItem: TiffIt
stac_extensions: ['https://stac-extensions.github.io/file/v2.0.0/schema.json'],
properties: {
datetime: cliDate,
map_code: mapCode, // e.g. "CJ10"
map_code: tiffItem.mapCode, // e.g. "CJ10"
version: tiffItem.version.replace('-', '.'), // convert from "v1-00" to "v1.00"
'proj:epsg': Epsg.Nztm2000.code,
'source:epsg': tiffItem.epsg.code,
'proj:epsg': tiffItem.epsg.code,
},
geometry: { type: 'Polygon', coordinates: tiffItem.bounds.toPolygon() } as GeoJSONPolygon,
bbox: tiffItem.bounds.toBbox(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { BoundingBox, Nztm2000QuadTms, Projection } from '@basemaps/geo';
import { Bounds } from '@basemaps/geo';
import { CliId } from '@basemaps/shared/build/cli/info.js';
import { StacCollection, StacItem } from 'stac-ts';

import { logger } from '../../../log.js';

const projection = Projection.get(Nztm2000QuadTms);
const cliDate = new Date().toISOString();

export function createStacCollection(title: string, imageryBound: BoundingBox, items: StacItem[]): StacCollection {
export function createStacCollection(title: string, imageryBounds: Bounds, items: StacItem[]): StacCollection {
logger.info({ items: items.length }, 'CreateStacCollection()');
const collection: StacCollection = {
type: 'Collection',
Expand Down Expand Up @@ -41,7 +40,7 @@ export function createStacCollection(title: string, imageryBound: BoundingBox, i
'linz:security_classification': 'unclassified',
'linz:slug': 'topo50',
extent: {
spatial: { bbox: [projection.boundsToWgs84BoundingBox(imageryBound)] },
spatial: { bbox: [imageryBounds.toBbox()] },
// Default the temporal time today if no times were found as it is required for STAC
temporal: { interval: [[cliDate, null]] },
},
Expand Down
27 changes: 13 additions & 14 deletions src/commands/basemaps-topo-import/stac/create-stac-item-groups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,29 @@ import { createBaseStacItem } from './create-base-stac-item.js';
* All versions need a StacItem object that lives in the topo[50/250] directory
* The latest version needs a second StacItem object that lives in the topo[50/250]-latest dir
*/
export async function createStacItemPair(
scale: string,
mapCode: string,
export async function createStacItems(
allTargetURL: URL,
all: TiffItem[],
latest: TiffItem,
): Promise<{ latest: { item: TiffItem; stac: StacItem }; all: { item: TiffItem; stac: StacItem }[] }> {
const latestStacItem = { item: latest, stac: createBaseStacItem(mapCode, mapCode, latest) };
const allStacItems = all.map((tiffItem) => ({
item: tiffItem,
stac: createBaseStacItem(`${mapCode}_${tiffItem.version}`, mapCode, tiffItem),
}));
): Promise<{ all: StacItem[]; latest: StacItem }> {
const allStacItems = all.map((item) => createBaseStacItem(`${item.mapCode}_${item.version}`, item));

const latestURL = new URL(`${latest.mapCode}_${latest.version}.json`, allTargetURL);

// add link to all items pointing to the latest version
allStacItems.forEach((pair) => {
pair.stac?.links.push({
href: `./${mapCode}_${latest.version}.json`,
allStacItems.forEach((stacItem) => {
stacItem.links.push({
href: latestURL.href,
rel: 'latest-version',
type: 'application/json',
});
});

const latestStacItem = createBaseStacItem(latest.mapCode, latest);

// add link to the latest item referencing its copy that will live in the topo[50/250] directory
latestStacItem.stac.links.push({
href: `../${scale}/${mapCode}_${latest.version}.json`,
latestStacItem.links.push({
href: latestURL.href,
rel: 'derived_from',
type: 'application/json',
});
Expand Down
28 changes: 16 additions & 12 deletions src/commands/basemaps-topo-import/stac/write-stac-files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,27 @@ import { fsa } from '@basemaps/shared';
import { StacCollection, StacItem } from 'stac-ts';

import { logger } from '../../../log.js';
import { isArgo } from '../../../utils/argo.js';

export async function writeStacFiles(
target: URL,
force: boolean,
items: StacItem[],
collection: StacCollection,
): Promise<void> {
): Promise<{ itemPaths: URL[]; collectionPath: URL }> {
// Create collection json for all topo50-latest items.
if (force || isArgo()) {
logger.info({ target }, 'CreateStac:Output');
logger.info({ items: items.length, collectionID: collection.id }, 'Stac:Output');
for (const item of items) {
const itemPath = new URL(`${item.id}.json`, target);
await fsa.write(itemPath, JSON.stringify(item, null, 2));
}
const collectionPath = new URL('collection.json', target);
await fsa.write(collectionPath, JSON.stringify(collection, null, 2));
logger.info({ target }, 'CreateStac:Output');
logger.info({ items: items.length, collectionID: collection.id }, 'Stac:Output');

const itemPaths: URL[] = [];

for (const item of items) {
const itemPath = new URL(`${item.id}.json`, target);
itemPaths.push(itemPath);

await fsa.write(itemPath, JSON.stringify(item, null, 2));
}

const collectionPath = new URL('collection.json', target);
await fsa.write(collectionPath, JSON.stringify(collection, null, 2));

return { itemPaths, collectionPath };
}
2 changes: 1 addition & 1 deletion src/commands/basemaps-topo-import/topo-cog-creation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ async function createCogs(input: URL, tmp: URL): Promise<void> {

logger.info({ item: item.id }, 'CogCreation:gdalwarp');
const tempPath = new URL(`${item.id}.tiff`, tmpFolder);
const sourceEpsg = Number(item.properties['source:epsg']);
const sourceEpsg = Number(item.properties['proj:epsg']);
const sourceProj = Epsg.tryGet(sourceEpsg);
if (sourceProj == null) throw new Error(`Unknown source projection ${sourceEpsg}`);
const vrtWarpPath = new URL(`${item.id}-warp.vrt`, tmpFolder);
Expand Down
Loading

0 comments on commit 3994738

Please sign in to comment.