Skip to content

Commit

Permalink
More refactoring to remove the types.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
Wentao-Kuang committed Jan 29, 2025
1 parent 9cb3c14 commit 78ca1db
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 277 deletions.
32 changes: 13 additions & 19 deletions packages/cogify/src/cogify/cli/cli.topo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { isArgo } from '../../argo.js';
import { UrlFolder } from '../../cogify/parsers.js';
import { getLogger, logArguments } from '../../log.js';
import { TopoStacItem } from '../stac.js';
import { groupTiffsByDirectory, mapEpsgToSlug } from '../topo/mapper.js';
import { brokenTiffs, extractAllTiffs, extractLatestItem } from '../topo/extract.js';
import { mapEpsgToSlug } from '../topo/slug.js';
import { createStacCollection, createStacItems, writeStacFiles } from '../topo/stac.creation.js';
import { brokenTiffs } from '../topo/types.js';

const Q = pLimit(10);

Expand Down Expand Up @@ -147,19 +147,18 @@ async function loadTiffsToCreateStacs(
logger?.info({ numTiffs: tiffs.length }, 'LoadTiffs:End');

// group all of the Tiff objects by epsg and map code
logger?.info('GroupTiffs:Start');
const itemsByDir = groupTiffsByDirectory(tiffs, logger);
const itemsByDirPath = new URL('itemsByDirectory.json', target);
await fsa.write(itemsByDirPath, JSON.stringify(itemsByDir, null, 2));
logger?.info('GroupTiffs:End');
logger?.info('ExtractTiffs:Start');
const allTiffs = extractAllTiffs(tiffs, logger);
const latestTiffs = extractLatestItem(allTiffs);
logger?.info('ExtractTiffs:End');

const epsgDirectoryPaths: { epsg: string; url: URL }[] = [];
const stacItemPaths = [];

// create and write stac items and collections
const scale = ctx.scale;
const resolution = ctx.resolution;
for (const [epsg, itemsByMapCode] of itemsByDir.all.entries()) {
for (const [epsg, items] of Object.entries(allTiffs)) {
const allTargetURL = new URL(`${scale}/${resolution}/${epsg}/`, target);
const latestTargetURL = new URL(`${scale}_latest/${resolution}/${epsg}/`, target);

Expand All @@ -179,19 +178,14 @@ async function loadTiffsToCreateStacs(

// create stac items
logger?.info({ epsg }, 'CreateStacItems:Start');
for (const [mapCode, items] of itemsByMapCode.entries()) {
// get latest item
const latest = itemsByDir.latest.get(epsg).get(mapCode);

// create stac items
const stacItems = createStacItems(scale, resolution, tileMatrix, items, latest, logger);
// create stac items
const stacItems = createStacItems(scale, resolution, tileMatrix, items, latestTiffs, logger);

allBounds.push(...items.map((item) => item.bounds));
allStacItems.push(...stacItems.all);
allBounds.push(...items.map((item) => item.bounds));
allStacItems.push(...stacItems.all);

latestBounds.push(latest.bounds);
latestStacItems.push(stacItems.latest);
}
latestBounds.push(...Array.from(latestTiffs.values()).map((item) => item.bounds));
latestStacItems.push(...stacItems.latest);

// convert epsg to slug
const epsgSlug = mapEpsgToSlug(epsgCode.code);
Expand Down
98 changes: 95 additions & 3 deletions packages/cogify/src/cogify/topo/extract.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Bounds } from '@basemaps/geo';
import { Epsg } from '@basemaps/geo';
import { Size } from '@basemaps/geo';
import { Bounds, Epsg, Size } from '@basemaps/geo';
import { LogType } from '@basemaps/shared';
import { RasterTypeKey, Tiff, TiffTagGeo } from '@cogeotiff/core';
import path from 'path';

export const brokenTiffs = { noBounds: [] as string[], noEpsg: [] as string[], noSize: [] as string[] };

/**
* Attempts to extract a bounds set from the given Tiff object.
*
Expand Down Expand Up @@ -125,3 +125,95 @@ export function extractSizeFromTiff(tiff: Tiff, logger?: LogType): Size | null {
return null;
}
}

export interface TiffItem {
tiff: Tiff;
source: URL;
mapCode: string;
version: string;
bounds: Bounds;
epsg: Epsg;
size: Size;
latest?: string;
}

export interface TiffItems {
[epsg: string]: TiffItem[];
}

/**
* Groups a list of Tiff objects into a TiffItem
* based on each object's epsg, map code, and version information.
*
* This function assigns each tiff to a group based on its map code (e.g. "AT24").
* For each group, it then identifies the latest version and sets a copy aside. *
*
* @param tiffs: the list of Tiff objects to group by epsg, and map code, and version
* @returns a TiffItems
*/
export function extractAllTiffs(tiffs: Tiff[], logger?: LogType): TiffItems {
// group the tiffs by directory, epsg, and map code
const tiffItems: TiffItems = {};

// create items for each tiff and store them into 'all' by {epsg} and {map code}
for (const tiff of tiffs) {
const source = tiff.source.url;
const { mapCode, version } = extractMapCodeAndVersion(source.href, logger);

const bounds = extractBoundsFromTiff(tiff, logger);
const epsg = extractEpsgFromTiff(tiff, logger);
const size = extractSizeFromTiff(tiff, logger);

if (bounds == null || epsg == null || size == null) {
if (bounds == null) {
brokenTiffs.noBounds.push(`${mapCode}_${version}`);
logger?.warn({ mapCode, version }, 'Could not extract bounds from tiff');
}

if (epsg == null) {
brokenTiffs.noEpsg.push(`${mapCode}_${version}`);
logger?.warn({ mapCode, version }, 'Could not extract epsg from tiff');
}

if (size == null) {
brokenTiffs.noSize.push(`${mapCode}_${version}`);
logger?.warn({ mapCode, version }, 'Could not extract width or height from tiff');
}

continue;
}

const item: TiffItem = { tiff, source, mapCode, version, bounds, epsg, size };

// push the item into 'all'
const items = tiffItems[epsg.code];
if (items == null) {
tiffItems[epsg.code] = [item];
} else {
items.push(item);
}
}

return tiffItems;
}

/**
* Filter the latest tiffs from all tiffs based on the version
*
*/
export function extractLatestItem(tiffItems: TiffItems): Map<string, TiffItem> {
// Map latest from map code to version
const latest: Map<string, TiffItem> = new Map();

// identify the latest item by {version} and copy it to 'latest'
for (const items of Object.values(tiffItems)) {
for (const item of items) {
const mapCode = item.mapCode;
const latestItem = latest.get(mapCode);
if (latestItem == null || latestItem.version.localeCompare(item.version) < 0) {
latest.set(mapCode, item);
}
}
}
return latest;
}
101 changes: 0 additions & 101 deletions packages/cogify/src/cogify/topo/mapper.ts

This file was deleted.

21 changes: 21 additions & 0 deletions packages/cogify/src/cogify/topo/slug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { EpsgCode } from '@basemaps/geo';
import { LogType } from '@basemaps/shared';

const slugs: Partial<Record<EpsgCode, string>> = {
[EpsgCode.Nztm2000]: 'new-zealand-mainland',
[EpsgCode.Citm2000]: 'chatham-islands',
};

/**
* Attempts to map the given EpsgCode enum to a slug.
*
* @param epsg: The EpsgCode enum to map to a slug
*
* @returns if succeeded, a slug string. Otherwise, null.
*/
export function mapEpsgToSlug(epsg: EpsgCode, logger?: LogType): string | null {
const slug = slugs[epsg];

logger?.info({ found: slug != null }, 'mapEpsgToSlug()');
return slug ?? null;
}
35 changes: 20 additions & 15 deletions packages/cogify/src/cogify/topo/stac.creation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CliId, CliInfo } from '@basemaps/shared/build/cli/info.js';
import { GeoJSONPolygon } from 'stac-ts/src/types/geojson.js';

import { CogifyStacCollection, TopoStacItem } from '../stac.js';
import { TiffItem } from './types.js';
import { TiffItem } from './extract.js';

const CLI_DATE = new Date().toISOString();

Expand Down Expand Up @@ -87,35 +87,40 @@ export function createStacItems(
resolution: string,
tileMatrix: TileMatrixSet,
all: TiffItem[],
latest: TiffItem,
latest: Map<string, TiffItem>,
logger?: LogType,
): { all: TopoStacItem[]; latest: TopoStacItem } {
): { all: TopoStacItem[]; latest: TopoStacItem[] } {
const allStacItems = all.map((item) =>
createBaseStacItem(`${item.mapCode}_${item.version}`, item, tileMatrix, logger),
);

// add link to all items pointing to the latest version
// add link to all items pointing to the latest version and create stac for latest items
for (const item of allStacItems) {
const latestTiff = latest.get(item.properties.map_code);
if (latestTiff == null) throw new Error(`Failed to find latest item for map code '${item.properties.map_code}'`);
item.links.push({
href: `./${latest.mapCode}_${latest.version}.json`,
href: `./${latestTiff.mapCode}_${latestTiff.version}.json`,
rel: 'latest-version',
type: 'application/json',
});
}

const latestStacItem = createBaseStacItem(latest.mapCode, latest, tileMatrix);
const latestStacItems = Array.from(latest.values()).map((item) => {
const latestStacItem = createBaseStacItem(item.mapCode, item, tileMatrix, logger);
latestStacItem.links.push({
// from: <target>/<scale>_latest/<resolution>/<espg>
// ../../../ = <target>
// to: <target>/<scale>/<resolution>/<espg>
href: `../../../${scale}/${resolution}/${item.epsg.code}/${item.mapCode}_${item.version}.json`,
rel: 'derived-from',
type: 'application/json',
});
return latestStacItem;
});

// add link to the latest item referencing its copy that will live in the topo[50/250] directory
latestStacItem.links.push({
// from: <target>/<scale>_latest/<resolution>/<espg>
// ../../../ = <target>
// to: <target>/<scale>/<resolution>/<espg>
href: `../../../${scale}/${resolution}/${latest.epsg.code}/${latest.mapCode}_${latest.version}.json`,
rel: 'derived_from',
type: 'application/json',
});

return { latest: latestStacItem, all: allStacItems };
return { latest: latestStacItems, all: allStacItems };
}

export function createStacCollection(
Expand Down
Loading

0 comments on commit 78ca1db

Please sign in to comment.