diff --git a/lib/types/basemap.ts b/lib/types/basemap.ts index 9de1d01..9d6fe20 100644 --- a/lib/types/basemap.ts +++ b/lib/types/basemap.ts @@ -1,29 +1,44 @@ import { Type } from '@sinclair/typebox'; +/** + * Type Schema for Basemap Map Source Configuration + * Compatible with Mobile Atlas Creator (MOBAC) Custom XML Map Sources + * @link https://mobac.sourceforge.io/wiki/index.php/Custom_XML_Map_Sources + */ + export const BasemapMapSource = Type.Object({ name: Type.Object({ _text: Type.String() - }), + }, { description: 'The name of the map source' }), minZoom: Type.Object({ _text: Type.Integer() - }), + }, { description: 'The minimum zoom level provided by the map source' }), maxZoom: Type.Object({ _text: Type.Integer() - }), + }, { description: 'The maximum zoom level provided by the map source' }), tileType: Type.Object({ _text: Type.String() - }), + }, { description: 'The image type provided by the map source' }), tileUpdate: Type.Optional(Type.Object({ _text: Type.String({ default: 'None' }) - })), + }, { description: 'The server capabilities for conditional downloading of new/updated tiles' })), url: Type.Optional(Type.Object({ _text: Type.String() - })), + }, { description: 'The URL for the tiles of the map source' })), + invertYCoordinate: Type.Optional(Type.Object({ + _text: Type.String() + }, { description: 'Inverts the y coordinate so that it starts south' })), backgroundColor: Type.Optional(Type.Object({ _text: Type.String() - })), + }, { description: 'The background color of a map' })), + ignoreErrors: Type.Optional(Type.Object({ + _text: Type.Boolean() + }, { description: 'Handling of missing tiles' })), + serverParts: Type.Optional(Type.Object({ + _text: Type.Optional(Type.String()) + }, { description: 'Use multiple servers for the map source' })) }) export default Type.Object({ diff --git a/lib/xml/basemap.ts b/lib/xml/basemap.ts index 01c9ee7..3bcfde1 100644 --- a/lib/xml/basemap.ts +++ b/lib/xml/basemap.ts @@ -33,10 +33,11 @@ export class Basemap extends XMLDocument { tileType: string | undefined; tileUpdate: string | undefined; backgroundColor: string | undefined; + serverParts: string | undefined; } { if (!this.raw.customMapSource) throw new Err(400, null, 'Unknown Basemap Type'); if (!this.raw.customMapSource.url) throw new Err(400, null, 'Unknown Basemap Type - Missing URL'); - + return { name: this.raw.customMapSource.name ? this.raw.customMapSource.name._text : undefined, url: this.raw.customMapSource.url._text, @@ -44,7 +45,8 @@ export class Basemap extends XMLDocument { maxZoom: this.raw.customMapSource.maxZoom ? Number(this.raw.customMapSource.maxZoom._text) : undefined, tileType: this.raw.customMapSource.tileType ? this.raw.customMapSource.tileType._text : undefined, tileUpdate: this.raw.customMapSource.tileUpdate ? this.raw.customMapSource.tileUpdate._text : undefined, - backgroundColor: this.raw.customMapSource.backgroundColor ? this.raw.customMapSource.backgroundColor._text : undefined + backgroundColor: this.raw.customMapSource.backgroundColor ? this.raw.customMapSource.backgroundColor._text : undefined, + serverParts: this.raw.customMapSource.serverParts ? this.raw.customMapSource.serverParts._text : undefined, } } } diff --git a/test/basemaps.test.ts b/test/basemaps.test.ts index 6b9013f..e9ca690 100644 --- a/test/basemaps.test.ts +++ b/test/basemaps.test.ts @@ -9,10 +9,25 @@ for (const fixturename of await fs.readdir(new URL('./basemaps/', import.meta.ur const fixture = String(await fs.readFile(path.join(path.parse(fileURLToPath(import.meta.url)).dir, 'basemaps/', fixturename))); const container = await Basemap.parse(fixture); - t.ok(container.raw.customMapSource.name._text.length) + t.ok(container.raw.customMapSource.name._text.length, 'Ensure raw xml name exists') const json = container.to_json(); - t.ok(json.name && json.name.length); + t.ok(json.name && json.name.length, 'Ensure JSON name exists'); + t.ok(json.url && json.url.length, 'Ensure JSON url exists'); + t.ok(typeof json.minZoom === 'number', 'Ensure JSON minZoom is a number'); + t.ok(typeof json.maxZoom === 'number', 'Ensure JSON maxZoom is a number'); + t.ok(typeof json.tileType === 'string' && json.tileType.length, 'Ensure JSON tileType is a string'); + + t.deepEqual(Object.keys(json), [ + 'name', + 'url', + 'minZoom', + 'maxZoom', + 'tileType', + 'tileUpdate', + 'backgroundColor', + 'serverParts' + ], 'Ensure JSON keys match expected structure') t.end(); }); diff --git a/test/basemaps/opentopomap.xml b/test/basemaps/opentopomap.xml index 7539c71..5d880f9 100644 --- a/test/basemaps/opentopomap.xml +++ b/test/basemaps/opentopomap.xml @@ -7,4 +7,4 @@ IfNoneMatch a b c https://{$serverpart}.tile.opentopomap.org/{$z}/{$x}/{$y}.png - \ No newline at end of file +