Skip to content

Commit d719d96

Browse files
authored
Merge pull request #416 from koordinates/add-geostyler-as-format
feat: add geostyler style as a format
2 parents e705de2 + bc0cc03 commit d719d96

File tree

2 files changed

+80
-84
lines changed

2 files changed

+80
-84
lines changed

src/index.ts

Lines changed: 71 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
readdirSync
1515
} from 'fs';
1616
import minimist from 'minimist';
17-
import { StyleParser } from 'geostyler-style';
17+
import { StyleParser, ReadStyleResult, WriteStyleResult } from 'geostyler-style';
1818
import ora, { Ora } from 'ora';
1919
import {
2020
logHelp,
@@ -48,33 +48,26 @@ const getParserFromFormat = (inputString: string): StyleParser | undefined => {
4848
case 'qgis':
4949
case 'qml':
5050
return new QGISParser();
51-
default:
51+
case 'geostyler':
5252
return undefined;
53+
default:
54+
throw new Error(`Unrecognized format: ${inputString}`)
5355
}
5456
};
5557

56-
const getParserFromFilename = (fileName: string): StyleParser | undefined => {
58+
const getFormatFromFilename = (fileName: string): string | undefined => {
5759
if (!fileName) {
5860
return undefined;
5961
}
60-
const fileEnding = fileName.split('.')[1];
62+
let fileEnding = fileName.split('.').pop();
6163
if (!fileEnding) {
6264
return undefined;
6365
}
64-
switch (fileEnding.toLowerCase()) {
65-
case 'lyrx':
66-
return new LyrxParser();
67-
case 'mapbox':
68-
return new MapboxParser();
69-
case 'map':
70-
return new MapfileParser();
71-
case 'sld':
72-
return new SLDParser();
73-
case 'qml':
74-
return new QGISParser();
75-
default:
76-
return undefined;
66+
fileEnding = fileEnding.toLowerCase();
67+
if (['lyrx', 'mapbox', 'map', 'sld', 'qml', 'geostyler'].includes(fileEnding)) {
68+
return fileEnding;
7769
}
70+
return undefined;
7871
};
7972

8073
const getExtensionFromFormat = (format: string): string => {
@@ -156,75 +149,61 @@ function collectPaths(basePath: string, isFile: boolean): string[] {
156149
}
157150
}
158151

152+
function handleResult(result: ReadStyleResult | WriteStyleResult, parser: StyleParser, stage: 'Source' | 'Target') {
153+
const { output, errors, warnings, unsupportedProperties } = result;
154+
if (errors && errors.length > 0) {
155+
throw errors;
156+
}
157+
if (warnings) {
158+
warnings.map(console.warn);
159+
}
160+
if (unsupportedProperties) {
161+
console.log(`${stage} parser ${parser.title} does not support the following properties:`);
162+
console.log(unsupportedProperties);
163+
}
164+
return output;
165+
}
166+
159167
async function writeFile(
160-
sourceFile: string, sourceParser: StyleParser,
168+
sourceFile: string, sourceParser: StyleParser | undefined,
161169
targetFile: string, targetParser: StyleParser | undefined,
162170
oraIndicator: Ora
163171
) {
172+
if (targetParser instanceof LyrxParser) {
173+
throw new Error('LyrxParser is not supported as target parser.');
174+
}
175+
if (targetParser instanceof MapfileParser) {
176+
throw new Error('MapfileParser is not supported as target parser.');
177+
}
178+
164179
let inputFileData = await promises.readFile(sourceFile, 'utf-8');
165180
const indicator = oraIndicator; // for linter.
166181

167-
// LyrxParser expects a JSON object as input
168-
if (sourceParser instanceof LyrxParser) {
182+
// If no sourceParser is set, just parse it as JSON - it should already be in geostyler format.
183+
// LyrxParser expects a JSON object as input, so we need to parse it as an extra step.
184+
if (!sourceParser || sourceParser instanceof LyrxParser) {
169185
inputFileData = JSON.parse(inputFileData);
170186
}
171187

172188
try {
173189
indicator.text = `Reading from ${sourceFile}`;
174-
const {
175-
errors: readErrors,
176-
warnings: readWarnings,
177-
unsupportedProperties: readUnsupportedProperties,
178-
output: readOutput
179-
} = await sourceParser.readStyle(inputFileData);
180-
if (readErrors && readErrors.length > 0) {
181-
throw readErrors;
182-
}
183-
if (readWarnings) {
184-
readWarnings.map(console.warn);
185-
}
186-
if (readUnsupportedProperties) {
187-
console.log(`Source parser ${sourceParser.title} does not support the following properties:`);
188-
console.log(readUnsupportedProperties);
189-
}
190-
if (readOutput) {
191-
let output;
192-
indicator.text = `Writing to ${targetFile}`;
193-
if (targetParser) {
194-
if (targetParser instanceof LyrxParser) {
195-
throw new Error('LyrxParser is not supported as target parser.');
196-
}
197-
if (targetParser instanceof MapfileParser) {
198-
throw new Error('MapfileParser is not supported as target parser.');
199-
}
200-
201-
const {
202-
output: writeOutput,
203-
errors: writeErrors,
204-
warnings: writeWarnings,
205-
unsupportedProperties: writeUnsupportedProperties
206-
} = await targetParser.writeStyle(readOutput);
207-
if (writeErrors) {
208-
throw writeErrors;
209-
}
210-
if (writeWarnings) {
211-
writeWarnings.map(console.warn);
212-
}
213-
if (writeUnsupportedProperties) {
214-
console.log(`Target parser ${targetParser.title} does not support the following properties:`);
215-
console.log(writeUnsupportedProperties);
216-
}
217-
output = typeof writeOutput === 'object' ? JSON.stringify(writeOutput, undefined, 2) : writeOutput;
218-
} else {
219-
output = JSON.stringify(readOutput, undefined, 2);
220-
}
221-
if (targetFile) {
222-
await promises.writeFile(targetFile, output, 'utf-8');
223-
indicator.succeed(`File "${sourceFile}" translated successfully. Output written to ${targetFile}`);
224-
} else {
225-
indicator.succeed(`File "${sourceFile}" translated successfully. Output written to stdout:\n`);
226-
console.log(output);
227-
}
190+
const readOutput = sourceParser
191+
? handleResult(await sourceParser.readStyle(inputFileData as any), sourceParser, 'Source')
192+
: inputFileData;
193+
194+
indicator.text = `Writing to ${targetFile}`;
195+
const writeOutput = targetParser
196+
? handleResult(await targetParser.writeStyle(readOutput), targetParser, 'Target')
197+
: readOutput;
198+
199+
const finalOutput = typeof writeOutput === 'object' ? JSON.stringify(writeOutput, undefined, 2) : writeOutput;
200+
201+
if (targetFile) {
202+
await promises.writeFile(targetFile, finalOutput, 'utf-8');
203+
indicator.succeed(`File "${sourceFile}" translated successfully. Output written to ${targetFile}`);
204+
} else {
205+
indicator.succeed(`File "${sourceFile}" translated successfully. Output written to stdout:\n`);
206+
console.log(finalOutput);
228207
}
229208
} catch (error) {
230209
indicator.fail(`Error during translation of file "${sourceFile}": ${error}`);
@@ -260,8 +239,8 @@ async function main() {
260239

261240
// Assign args
262241
const sourcePath: string = unnamedArgs[0];
263-
const sourceFormat: string = s || source || sourcePath;
264-
const targetFormat: string = t || target;
242+
let sourceFormat: string | undefined = s || source;
243+
let targetFormat: string | undefined = t || target;
265244
const outputPath: string = o || output;
266245

267246
// Instantiate progress indicator
@@ -290,17 +269,25 @@ async function main() {
290269
return;
291270
}
292271

293-
// Get source and target parser.
294-
const sourceParser = sourceFormat && getParserFromFormat(sourceFormat)
295-
|| (sourceIsFile && getParserFromFilename(sourcePath));
296-
const targetParser = targetFormat && getParserFromFormat(targetFormat) || getParserFromFilename(outputPath);
297-
if (!sourceParser) {
298-
indicator.fail('No sourceparser was specified.');
299-
return;
272+
// Get source parser.
273+
if (!sourceFormat && sourceIsFile) {
274+
sourceFormat = getFormatFromFilename(sourcePath)
275+
}
276+
if (!sourceFormat) {
277+
indicator.info('No sourceparser was specified. Input will be parsed as a GeoStyler object.');
278+
sourceFormat = 'geostyler';
279+
}
280+
const sourceParser = getParserFromFormat(sourceFormat)
281+
282+
// Get target parser.
283+
if (!targetFormat && targetIsFile) {
284+
targetFormat = getFormatFromFilename(outputPath)
300285
}
301-
if (!targetParser) {
286+
if (!targetFormat) {
302287
indicator.info('No targetparser was specified. Output will be a GeoStyler object.');
288+
targetFormat = 'geostyler';
303289
}
290+
const targetParser = getParserFromFormat(targetFormat);
304291

305292
// Get source(s) path(s).
306293
const sourcePaths = collectPaths(sourcePath, sourceIsFile);

test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ function runAllTests() {
5252
success = false;
5353
}
5454

55+
// test geostyler to mapbox
56+
outputFile = 'output.mapbox';
57+
args = ['start', '--', '-s', 'geostyler', '-o', outputFile, 'testdata/point_simplepoint.geostyler'];
58+
runTest(args, outputFile);
59+
60+
if (checkFileCreated(outputFile) === false) {
61+
success = false;
62+
}
63+
5564
// test folder output
5665
args = ['start', '--', '-s', 'sld', '-t', 'qgis', '-o', './output-bulk', 'testdata/sld'];
5766
runTest(args, outputFile);

0 commit comments

Comments
 (0)