Skip to content

Commit

Permalink
feat(tileindex-validate): detect when tiffs are not in EPSG:2193 and …
Browse files Browse the repository at this point in the history
…error (#448)
  • Loading branch information
blacha authored May 19, 2023
1 parent 67390a6 commit e9d57b7
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { CogTiff } from '@cogeotiff/core';

export const DuplicateInput = [
{ source: { uri: 's3://test-path-one' }, images: [{ origin: [1492000, 6234000] }] },
{ source: { uri: 's3://test-path-two' }, images: [{ origin: [1684000, 6018000] }] },
{ source: { uri: 's3://duplicate' }, images: [{ origin: [1492000, 6234000] }] },
{ source: { uri: 's3://test-path-one' }, images: [{ origin: [1492000, 6234000], epsg: 2193 }] },
{ source: { uri: 's3://test-path-two' }, images: [{ origin: [1684000, 6018000], epsg: 2193 }] },
{ source: { uri: 's3://duplicate' }, images: [{ origin: [1492000, 6234000], epsg: 2193 }] },
] as unknown as CogTiff[];

export const DuplicateOutput = [{ tileName: 'AS21_1000_0101', uris: ['s3://test-path-one', 's3://duplicate'] }];

export const NoDuplicateInput = [
{ source: { uri: 's3://test-path-one' }, images: [{ origin: [1492000, 6234000] }] },
{ source: { uri: 's3://test-path-two' }, images: [{ origin: [1684000, 6018000] }] },
{ source: { uri: 's3://test-path-three' }, images: [{ origin: [1732000, 5766000] }] },
{ source: { uri: 's3://test-path-one' }, images: [{ origin: [1492000, 6234000], epsg: 2193 }] },
{ source: { uri: 's3://test-path-two' }, images: [{ origin: [1684000, 6018000], epsg: 2193 }] },
{ source: { uri: 's3://test-path-three' }, images: [{ origin: [1732000, 5766000], epsg: 2193 }] },
] as unknown as CogTiff[];
59 changes: 34 additions & 25 deletions src/commands/tileindex-validate/__test__/tileindex.validate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import o from 'ospec';
import { MapSheetData } from '../../../utils/__test__/mapsheet.data.js';
import { findDuplicates, getTileName, roundWithCorrection } from '../tileindex.validate.js';
import { DuplicateInput, DuplicateOutput, NoDuplicateInput } from './tileindex.validate.data.js';
import { CogTiff } from '@cogeotiff/core';

o.spec('roundWithCorrectionValid', () => {
o('should round up (15 decimal places)', async () => {
Expand All @@ -10,54 +11,62 @@ o.spec('roundWithCorrectionValid', () => {
o('Should round up (2 decimal places)', async () => {
o(roundWithCorrection(1643679.99)).equals(1643680);
});
o('should round down', async function () {
o('should round down', async () => {
o(roundWithCorrection(1643680.01)).equals(1643680);
});
o('.05 should not round', async function () {
o('.05 should not round', async () => {
o(roundWithCorrection(1643680.05)).equals(1643680.05);
});
o('Should round to 2 decimal places (.969 to .97)', async function () {
o('Should round to 2 decimal places (.969 to .97)', async () => {
o(roundWithCorrection(1643679.969)).equals(1643679.97);
});
o('Should round to 2 decimal places (.051 to .05)', async function () {
o('Should round to 2 decimal places (.051 to .05)', async () => {
o(roundWithCorrection(5444160.051)).equals(5444160.05);
});
o('Should round down to whole number', async function () {
o('Should round down to whole number', async () => {
o(roundWithCorrection(5444160.015)).equals(5444160);
});
o('Should round up to whole number', async function () {
o('Should round up to whole number', async () => {
o(roundWithCorrection(5444160.985)).equals(5444161);
});
});

o('alignmentGeneratesCorrectName', async function () {
o(getTileName([1236640, 4837560], 500)).equals('CG10_500_080037');
});
o('alignmentGeneratesCorrectNameWithDrift', async function () {
o(getTileName([1643679.999967818148434, 5444159.999954843893647], 1000)).equals('BP27_1000_4817');
});
o('alignmentBuildsCorrectSheetCode', async function () {
MapSheetData.forEach(function (f) {
o(getTileName([f.origin.x, f.origin.y], 500).split('_')[0]).equals(f.code);
o.spec('getTileName', () => {
o('should generate correct name', async () => {
o(getTileName([1236640, 4837560], 500)).equals('CG10_500_080037');
});
});

o.spec('InvalidOriginException', () => {
o('Should throw error for Invalid Origin', function () {
o('should generate correct name with drift', async () => {
o(getTileName([1643679.999967818148434, 5444159.999954843893647], 1000)).equals('BP27_1000_4817');
});
o('should guilds correct sheet code', async () => {
for (const f of MapSheetData) {
o(getTileName([f.origin.x, f.origin.y], 500).split('_')[0]).equals(f.code);
}
});
o('Should throw error for Invalid Origin', () => {
o(() => {
getTileName([1643679, 5444159.01535345], 1000);
}).throws(Error);
});
o('Also Should throw error for Invalid Origin', function () {
o('Should also throw error for Invalid Origin', () => {
o(() => {
getTileName([1643679.984567, 5444159], 1000);
}).throws(Error);
});
});

o('findDuplicates', async function () {
o(findDuplicates(DuplicateInput, 1000)).deepEquals(DuplicateOutput);
});
o('findNoDuplicates', async function () {
o(findDuplicates(NoDuplicateInput, 1000)).deepEquals([]);
o.spec('findDuplicates', () => {
o('should find duplicates', async () => {
o(findDuplicates(DuplicateInput, 1000)).deepEquals(DuplicateOutput);
});
o('find no duplicates', async () => {
o(findDuplicates(NoDuplicateInput, 1000)).deepEquals([]);
});

o('should throw if imagery is not in ESPG:2193', () => {
const brokenImages = [
{ source: { uri: 's3://test-path-one' }, images: [{ origin: [1492000, 6234000], epsg: 3857 }] },
] as unknown as CogTiff[];
o(() => findDuplicates(brokenImages, 1000)).throws(Error);
});
});
17 changes: 16 additions & 1 deletion src/commands/tileindex-validate/tileindex.validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,21 @@ export const commandTileIndexValidate = command({
if (tiffFiles.length === 0) throw new Error('No Files found');
if (tiffFiles[0]) await fsa.head(tiffFiles[0]);
const tiffs = await Promise.all(tiffFiles.map((f: string) => new CogTiff(fsa.source(f)).init(true)));
logger.info({ duration: performance.now() - readTiffStartTime }, 'TileIndex: All Files Read');

const projections = new Set(tiffs.map((t) => t.getImage(0).epsg));
logger.info(
{
tiffCount: tiffs.length,
projections: [...projections],
duration: performance.now() - readTiffStartTime,
},
'TileIndex: All Files Read',
);

if (projections.size > 1) {
logger.warn({ projections: [...projections] }, 'TileIndex:InconsistentProjections');
}

const findDuplicatesStartTime = performance.now();
const duplicates = findDuplicates(tiffs, args.scale);
logger.info(
Expand All @@ -84,6 +98,7 @@ export function findDuplicates(tiffs: CogTiff[], scale: number): FileList[] {
const uri = f.source.uri;
const firstImage = f.images[0];
if (firstImage == null) throw new Error(`Failed to parse tiff: ${f.source.uri}`);
if (firstImage.epsg !== 2193) throw new Error(`Invalid projection tiff: ${f.source.uri} EPSG:${firstImage.epsg}`);
const tileName = getTileName(firstImage.origin, scale);
const existingUri = seen.get(tileName) ?? [];
existingUri.push(uri);
Expand Down

0 comments on commit e9d57b7

Please sign in to comment.