Skip to content

Commit 6a91b16

Browse files
committed
[Frontend] uid character box
1 parent 982ce09 commit 6a91b16

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import {
2+
fileLoaderString,
3+
loadAllFilesOfElementAsStringWithCallback
4+
} from '../../util/fileLoader';
5+
import {
6+
boundingBoxesOpts
7+
8+
} from './util';
9+
import {
10+
createUidLookupMap
11+
} from '../../util/char_text_map';
12+
import {
13+
determineCorrectParserSettings
14+
} from '../../util/parserSettingsGenerator';
15+
import type {
16+
ImportCharacterBoundingBoxDto
17+
} from '@/types/dtos/ImportCharacterBoundingBoxDto';
18+
import type {
19+
ImportConfig
20+
} from '@/types/import';
21+
import {
22+
MissingFilesError
23+
} from '../../util/errors';
24+
25+
export const boundingBoxImporter: ImportConfig<ImportCharacterBoundingBoxDto[]> = {
26+
'display': 'Text UID based Bounding Box Creation ',
27+
'options': {
28+
...boundingBoxesOpts,
29+
'textuid': {
30+
'display': 'Text UID',
31+
'value': 'text_uid',
32+
'input': 'string',
33+
'searchTerms': [
34+
'text_uid',
35+
'textuid'
36+
]
37+
},
38+
'association': {
39+
'display': 'Text to generate associations from', // TODO: Update name, this is for texts.csv file
40+
'value': null,
41+
'input': 'file'
42+
},
43+
'assTextUID': {
44+
'display': 'Text UID', // TODO: Update name, this is for texts.csv file
45+
'value': 'text_uid',
46+
'input': 'string'
47+
},
48+
'assTextID': {
49+
'display': 'Text ID', // TODO: Update name, this is for texts.csv file
50+
'value': 'text_id',
51+
'input': 'string'
52+
},
53+
'assLang': {
54+
'display': 'Language', // TODO: Update name, this is for texts.csv file
55+
'value': 'lang',
56+
'input': 'string'
57+
}
58+
},
59+
'parse': async ( inputElement: HTMLInputElement, _textId: string, lang: string ): Promise<ImportCharacterBoundingBoxDto[]> => {
60+
if ( !inputElement.files || !inputElement.files[0] ) throw new MissingFilesError();
61+
62+
const assocFile = boundingBoxImporter.options.association?.value as File | null;
63+
const uidCol = boundingBoxImporter.options.assTextUID?.value as string | undefined;
64+
const idCol = boundingBoxImporter.options.assTextID?.value as string | undefined;
65+
66+
if ( !assocFile || !uidCol || !idCol ) {
67+
throw new MissingFilesError();
68+
}
69+
70+
// build lookup from textuid -> textid
71+
const textUidLookup = createUidLookupMap(
72+
await fileLoaderString( assocFile ),
73+
uidCol,
74+
idCol
75+
);
76+
const boundingBoxStore: ImportCharacterBoundingBoxDto[] = [];
77+
78+
await loadAllFilesOfElementAsStringWithCallback( inputElement, async ( data: string ) => {
79+
const lines = data.split( /\r?\n/ ).filter( l => l.trim() !== '' );
80+
const header = lines.shift()!.split( ',' ).map( h => h.trim() );
81+
const textUidIndex = header.indexOf( boundingBoxImporter.options.textuid!.value as string );
82+
const charIndex = header.indexOf( boundingBoxesOpts.char!.value as string );
83+
const xMinIndex = header.indexOf( boundingBoxesOpts.xMin!.value as string );
84+
const xMaxIndex = header.indexOf( boundingBoxesOpts.xMax!.value as string );
85+
const yMinIndex = header.indexOf( boundingBoxesOpts.yMin!.value as string );
86+
const yMaxIndex = header.indexOf( boundingBoxesOpts.yMax!.value as string );
87+
const langIndex = header.indexOf( boundingBoxesOpts.lang!.value as string );
88+
89+
if ( textUidIndex < 0 )
90+
throw new Error( 'text UID column not found' );
91+
92+
if ( charIndex < 0 )
93+
throw new Error( 'character column not found' );
94+
95+
if ( xMinIndex < 0 || xMaxIndex < 0 || yMinIndex < 0 || yMaxIndex < 0 )
96+
throw new Error( 'bounding box coordinate columns not found' );
97+
98+
lines.forEach( line => {
99+
const cols = line.split( ',' );
100+
101+
if ( lang === 'undefined' || ( langIndex > -1 ? cols[langIndex]! === lang : true ) ) {
102+
const uid = cols[textUidIndex]!;
103+
const mappedId = textUidLookup.get( uid );
104+
105+
if ( mappedId ) {
106+
const x1 = Number( cols[xMinIndex] );
107+
const x2 = Number( cols[xMaxIndex] );
108+
const y1 = Number( cols[yMinIndex] );
109+
const y2 = Number( cols[yMaxIndex] );
110+
111+
boundingBoxStore.push( {
112+
'foreignId': Number( mappedId ),
113+
'character': String( cols[charIndex] ),
114+
'xMin': x1 < x2 ? x1 : x2,
115+
'xMax': x1 < x2 ? x2 : x1,
116+
'yMin': y1 < y2 ? y1 : y2,
117+
'yMax': y1 < y2 ? y2 : y1
118+
} );
119+
}
120+
}
121+
} );
122+
} );
123+
124+
return boundingBoxStore;
125+
},
126+
'canParse': ( header: string[] ) => {
127+
return determineCorrectParserSettings( header, boundingBoxImporter );
128+
}
129+
};

0 commit comments

Comments
 (0)