tileflow 0.1.0-alpha.21 → 0.1.0-alpha.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -20
- package/REFERENCE.md +429 -0
- package/dist/build-RQF35KW6.js +21 -0
- package/dist/chunk-43VQMAQO.js +52 -0
- package/dist/chunk-5U4J6E6Y.js +4911 -0
- package/dist/chunk-EXDH7EHK.js +2803 -0
- package/dist/chunk-GPPOECR5.js +16 -0
- package/dist/chunk-JVTGXPGV.js +382 -0
- package/dist/cli-main-K3PKVCIP.js +10835 -0
- package/dist/errors-C3VZMCM5.js +20 -0
- package/dist/index.js +8 -12121
- package/dist/inspect-source-5CD3AV5J.js +227 -0
- package/dist/recipe-3BPMNDPX.js +23 -0
- package/dist/tileset-entry-V5RUQGZG.js +26 -0
- package/package.json +16 -7
- package/schemas/tileset-recipe.v1.json +171 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FeatureIngest,
|
|
3
|
+
FeatureSpool,
|
|
4
|
+
GeoPackageLayer,
|
|
5
|
+
SpoolDirectory,
|
|
6
|
+
ZippedKml,
|
|
7
|
+
ZippedShapefile,
|
|
8
|
+
checkContainerFormat,
|
|
9
|
+
checkInputSignature,
|
|
10
|
+
chooseCrsStatement,
|
|
11
|
+
chooseLayer,
|
|
12
|
+
csvColumnNames,
|
|
13
|
+
csvColumnsNameCoordinates,
|
|
14
|
+
detectFormat,
|
|
15
|
+
fileChunks,
|
|
16
|
+
isKmz,
|
|
17
|
+
isZip,
|
|
18
|
+
readCsv,
|
|
19
|
+
readGeojson,
|
|
20
|
+
readGeojsonSequence,
|
|
21
|
+
readGpx,
|
|
22
|
+
readKml,
|
|
23
|
+
readShapefile
|
|
24
|
+
} from "./chunk-5U4J6E6Y.js";
|
|
25
|
+
import {
|
|
26
|
+
recipeFromSettings,
|
|
27
|
+
resolveCrs
|
|
28
|
+
} from "./chunk-JVTGXPGV.js";
|
|
29
|
+
import {
|
|
30
|
+
SampleComplete,
|
|
31
|
+
TilesetBuildError
|
|
32
|
+
} from "./chunk-43VQMAQO.js";
|
|
33
|
+
import "./chunk-GPPOECR5.js";
|
|
34
|
+
|
|
35
|
+
// src/tileset-build/inspect-source.ts
|
|
36
|
+
import { mkdtempSync, rmSync, statSync } from "fs";
|
|
37
|
+
import { tmpdir } from "os";
|
|
38
|
+
import { join, resolve } from "path";
|
|
39
|
+
var defaultSampleFeatures = 1e4;
|
|
40
|
+
var maximumSampleCoordinates = 2e3;
|
|
41
|
+
async function inspectTilesetSource(options) {
|
|
42
|
+
const input = resolve(options.input);
|
|
43
|
+
if (!statSync(input, { throwIfNoEntry: false })?.isFile()) {
|
|
44
|
+
throw new TilesetBuildError(
|
|
45
|
+
"TF_TILESET_BUILD_INPUT_MISSING",
|
|
46
|
+
"input",
|
|
47
|
+
`Input file not found: ${options.input}.`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const format = options.format ?? detectFormat(input);
|
|
51
|
+
const zipped = isZip(input);
|
|
52
|
+
const kmz = isKmz(input);
|
|
53
|
+
checkContainerFormat(format, zipped, kmz);
|
|
54
|
+
checkInputSignature(input, format, zipped ? "zip" : kmz ? "kmz" : null);
|
|
55
|
+
const base = { command: "tileset build --inspect", format, schemaVersion: 1 };
|
|
56
|
+
let zip = null;
|
|
57
|
+
let zippedKml = null;
|
|
58
|
+
let geopackage = null;
|
|
59
|
+
try {
|
|
60
|
+
zip = zipped ? await ZippedShapefile.open(input, options.zipEntry) : null;
|
|
61
|
+
zippedKml = kmz ? await ZippedKml.open(input, options.zipEntry) : null;
|
|
62
|
+
geopackage = format === "geopackage" ? GeoPackageLayer.open(input, options.inputLayer) : null;
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (error instanceof TilesetBuildError && error.choices) {
|
|
65
|
+
const option = error.path === "inputLayer" ? "inputLayer" : "zipEntry";
|
|
66
|
+
return { ...base, choices: { names: error.choices.slice(0, 1e3), option } };
|
|
67
|
+
}
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
const temporary = mkdtempSync(join(tmpdir(), "tileflow-tileset-inspect-"));
|
|
71
|
+
try {
|
|
72
|
+
const shapefile = zip ? await zip.extractProjection(temporary) : input;
|
|
73
|
+
const statement = await chooseCrsStatement(format, shapefile, options, geopackage);
|
|
74
|
+
if (format === "csv" && !await csvColumnsNameCoordinates(input, options)) {
|
|
75
|
+
return {
|
|
76
|
+
...base,
|
|
77
|
+
columns: await csvColumnNames(input),
|
|
78
|
+
crs: { label: statement.label, status: "unknown" }
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const reading = coordinateProbe(statement);
|
|
82
|
+
if (zip) await zip.extractData(temporary);
|
|
83
|
+
const directory = new SpoolDirectory(temporary);
|
|
84
|
+
const ingest = new FeatureIngest(
|
|
85
|
+
new FeatureSpool(directory),
|
|
86
|
+
{ exclude: null, include: null },
|
|
87
|
+
reading.transform
|
|
88
|
+
);
|
|
89
|
+
ingest.stopAfter = options.sampleFeatures ?? defaultSampleFeatures;
|
|
90
|
+
let complete = true;
|
|
91
|
+
try {
|
|
92
|
+
await readSample(format, input, shapefile, ingest, options, zippedKml, geopackage);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
if (!(error instanceof SampleComplete)) throw error;
|
|
95
|
+
complete = false;
|
|
96
|
+
}
|
|
97
|
+
const layer = chooseLayer(options.layer, options.inputLayer, input);
|
|
98
|
+
const crs = reading.crs();
|
|
99
|
+
const recipe = recipeFromSettings(
|
|
100
|
+
{ ...options, ...crs.status === "needs-reproject" ? { reproject: true } : {} },
|
|
101
|
+
layer
|
|
102
|
+
);
|
|
103
|
+
if (ingest.featureCount === 0) {
|
|
104
|
+
return {
|
|
105
|
+
...base,
|
|
106
|
+
crs,
|
|
107
|
+
recipe,
|
|
108
|
+
sample: {
|
|
109
|
+
bounds: null,
|
|
110
|
+
complete,
|
|
111
|
+
coordinates: reading.coordinates(),
|
|
112
|
+
features: 0,
|
|
113
|
+
sourceBounds: reading.bounds()
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const summary = ingest.finish();
|
|
118
|
+
return {
|
|
119
|
+
...base,
|
|
120
|
+
crs,
|
|
121
|
+
fields: summary.fields,
|
|
122
|
+
geometryTypes: summary.geometryTypes,
|
|
123
|
+
recipe,
|
|
124
|
+
sample: {
|
|
125
|
+
bounds: crs.status === "wgs84" || crs.status === "needs-reproject" ? summary.bounds : null,
|
|
126
|
+
complete,
|
|
127
|
+
coordinates: reading.coordinates(),
|
|
128
|
+
features: summary.features,
|
|
129
|
+
sourceBounds: reading.bounds()
|
|
130
|
+
},
|
|
131
|
+
warnings: summary.warnings
|
|
132
|
+
};
|
|
133
|
+
} finally {
|
|
134
|
+
zip?.close();
|
|
135
|
+
zippedKml?.close();
|
|
136
|
+
geopackage?.close();
|
|
137
|
+
rmSync(temporary, { force: true, recursive: true });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async function readSample(format, input, shapefile, ingest, options, zippedKml, geopackage) {
|
|
141
|
+
switch (format) {
|
|
142
|
+
case "csv":
|
|
143
|
+
return readCsv(input, ingest, options);
|
|
144
|
+
case "geojson":
|
|
145
|
+
return readGeojson(input, ingest, () => {
|
|
146
|
+
});
|
|
147
|
+
case "geojsonseq":
|
|
148
|
+
return readGeojsonSequence(input, ingest);
|
|
149
|
+
case "geopackage":
|
|
150
|
+
return geopackage.read(ingest, options.sourceCrs === void 0);
|
|
151
|
+
case "gpx":
|
|
152
|
+
return readGpx(fileChunks(input), ingest);
|
|
153
|
+
case "kml":
|
|
154
|
+
return readKml(zippedKml ? zippedKml.chunks() : fileChunks(input), ingest);
|
|
155
|
+
case "shapefile":
|
|
156
|
+
return readShapefile(shapefile, ingest);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function coordinateProbe(statement) {
|
|
160
|
+
let minX = Infinity;
|
|
161
|
+
let minY = Infinity;
|
|
162
|
+
let maxX = -Infinity;
|
|
163
|
+
let maxY = -Infinity;
|
|
164
|
+
let outOfRange = false;
|
|
165
|
+
const coordinates = [];
|
|
166
|
+
let seen = 0;
|
|
167
|
+
let stride = 1;
|
|
168
|
+
let real = null;
|
|
169
|
+
let crs;
|
|
170
|
+
if (statement.definition === null) {
|
|
171
|
+
crs = { label: statement.label, status: "unknown" };
|
|
172
|
+
} else {
|
|
173
|
+
try {
|
|
174
|
+
const resolved = resolveCrs(statement, true);
|
|
175
|
+
real = resolved.transform;
|
|
176
|
+
crs = { label: resolved.label, status: resolved.transform ? "needs-reproject" : "wgs84" };
|
|
177
|
+
} catch (error) {
|
|
178
|
+
if (!(error instanceof TilesetBuildError)) throw error;
|
|
179
|
+
crs = {
|
|
180
|
+
label: statement.label,
|
|
181
|
+
problem: { code: error.code, message: error.message },
|
|
182
|
+
status: "unsupported"
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const usable = crs.status === "wgs84" || crs.status === "needs-reproject";
|
|
187
|
+
const transform = (x, y) => {
|
|
188
|
+
if (x < minX) minX = x;
|
|
189
|
+
if (y < minY) minY = y;
|
|
190
|
+
if (x > maxX) maxX = x;
|
|
191
|
+
if (y > maxY) maxY = y;
|
|
192
|
+
if (seen % stride === 0) {
|
|
193
|
+
if (coordinates.length === maximumSampleCoordinates) {
|
|
194
|
+
for (let index = 0; index < coordinates.length / 2; index += 1) {
|
|
195
|
+
coordinates[index] = coordinates[index * 2];
|
|
196
|
+
}
|
|
197
|
+
coordinates.length /= 2;
|
|
198
|
+
stride *= 2;
|
|
199
|
+
}
|
|
200
|
+
if (seen % stride === 0) coordinates.push([x, y]);
|
|
201
|
+
}
|
|
202
|
+
seen += 1;
|
|
203
|
+
if (!usable) return [0, 0];
|
|
204
|
+
const [longitude, latitude] = real ? real(x, y) : [x, y];
|
|
205
|
+
if (!Number.isFinite(longitude) || !Number.isFinite(latitude) || Math.abs(longitude) > 180 || Math.abs(latitude) > 90) {
|
|
206
|
+
outOfRange = true;
|
|
207
|
+
return [0, 0];
|
|
208
|
+
}
|
|
209
|
+
return [longitude, latitude];
|
|
210
|
+
};
|
|
211
|
+
return {
|
|
212
|
+
coordinates: () => coordinates,
|
|
213
|
+
bounds: () => Number.isFinite(minX) ? [minX, minY, maxX, maxY] : null,
|
|
214
|
+
crs: () => outOfRange ? {
|
|
215
|
+
label: crs.label,
|
|
216
|
+
problem: {
|
|
217
|
+
code: "TF_TILESET_BUILD_COORDINATES_OUT_OF_RANGE",
|
|
218
|
+
message: `Some coordinates are not valid longitude and latitude under ${crs.label}. The stated CRS is probably wrong.`
|
|
219
|
+
},
|
|
220
|
+
status: "out-of-range"
|
|
221
|
+
} : crs,
|
|
222
|
+
transform
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
export {
|
|
226
|
+
inspectTilesetSource
|
|
227
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
layerNamePattern,
|
|
3
|
+
maximumZoom,
|
|
4
|
+
parseTilesetRecipe,
|
|
5
|
+
readTilesetRecipe,
|
|
6
|
+
recipeFromSettings,
|
|
7
|
+
recipeHash,
|
|
8
|
+
settingsFromRecipe,
|
|
9
|
+
tilesetRecipeJsonSchema,
|
|
10
|
+
tilesetRecipeSchemaUrl
|
|
11
|
+
} from "./chunk-JVTGXPGV.js";
|
|
12
|
+
import "./chunk-43VQMAQO.js";
|
|
13
|
+
export {
|
|
14
|
+
layerNamePattern,
|
|
15
|
+
maximumZoom,
|
|
16
|
+
parseTilesetRecipe,
|
|
17
|
+
readTilesetRecipe,
|
|
18
|
+
recipeFromSettings,
|
|
19
|
+
recipeHash,
|
|
20
|
+
settingsFromRecipe,
|
|
21
|
+
tilesetRecipeJsonSchema,
|
|
22
|
+
tilesetRecipeSchemaUrl
|
|
23
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createCliProgram,
|
|
3
|
+
isRestoreJsonCommand,
|
|
4
|
+
loadAuthConfig,
|
|
5
|
+
parseRestoreJson,
|
|
6
|
+
registerTilesetCommands
|
|
7
|
+
} from "./chunk-EXDH7EHK.js";
|
|
8
|
+
|
|
9
|
+
// src/tileset-entry.ts
|
|
10
|
+
import pc from "picocolors";
|
|
11
|
+
import { defaultTileflowApiUrl } from "@tileflow/dev/config";
|
|
12
|
+
async function runTilesetCli() {
|
|
13
|
+
const program = createCliProgram();
|
|
14
|
+
registerTilesetCommands(program, { defaultApiUrl: defaultTileflowApiUrl, loadAuthConfig });
|
|
15
|
+
if (isRestoreJsonCommand(process.argv.slice(2))) return parseRestoreJson(program);
|
|
16
|
+
try {
|
|
17
|
+
await program.parseAsync();
|
|
18
|
+
} catch (error) {
|
|
19
|
+
const message = error instanceof Error ? error.message : "Command failed.";
|
|
20
|
+
console.error(`${pc.red("Error:")} ${message.split("\n")[0]}`);
|
|
21
|
+
process.exitCode = 1;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
runTilesetCli
|
|
26
|
+
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tileflow",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.23",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
-
"description": "CLI-only tools for Tileflow config, capture, visual testing, and deploy.",
|
|
5
|
+
"description": "CLI-only tools for Tileflow config, capture, visual testing, tiling, and deploy.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://tileflow.dev",
|
|
8
8
|
"repository": {
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
27
|
"dist",
|
|
28
|
+
"schemas",
|
|
29
|
+
"REFERENCE.md",
|
|
28
30
|
"LICENSE"
|
|
29
31
|
],
|
|
30
32
|
"bin": {
|
|
@@ -35,23 +37,30 @@
|
|
|
35
37
|
},
|
|
36
38
|
"dependencies": {
|
|
37
39
|
"@hono/node-server": "2.1.3",
|
|
38
|
-
"@tileflow/capture": ">=0.1.0-alpha.
|
|
40
|
+
"@tileflow/capture": ">=0.1.0-alpha.38 <0.1.0-beta.0",
|
|
39
41
|
"@tileflow/coordinates": ">=0.1.0-alpha.3 <0.1.0-beta.0",
|
|
40
42
|
"@tileflow/coordinates-runtime": ">=0.1.0-alpha.6 <0.1.0-beta.0",
|
|
41
|
-
"@tileflow/core": ">=0.1.0-alpha.
|
|
42
|
-
"@tileflow/dev": ">=0.1.0-alpha.
|
|
43
|
-
"@tileflow/maps": ">=0.1.0-alpha.
|
|
43
|
+
"@tileflow/core": ">=0.1.0-alpha.48 <0.1.0-beta.0",
|
|
44
|
+
"@tileflow/dev": ">=0.1.0-alpha.43 <0.1.0-beta.0",
|
|
45
|
+
"@tileflow/maps": ">=0.1.0-alpha.20 <0.1.0-beta.0",
|
|
44
46
|
"commander": "^15.0.0",
|
|
47
|
+
"fflate": "0.8.3",
|
|
45
48
|
"hono": "4.13.14",
|
|
46
49
|
"picocolors": "^1.1.1",
|
|
50
|
+
"pmtiles": "4.5.0",
|
|
51
|
+
"proj4": "2.22.0",
|
|
52
|
+
"yauzl": "3.4.0",
|
|
47
53
|
"zod": "^4.6.7"
|
|
48
54
|
},
|
|
49
55
|
"devDependencies": {
|
|
56
|
+
"@mapbox/vector-tile": "3.0.0",
|
|
50
57
|
"@types/pngjs": "6.0.5",
|
|
58
|
+
"@types/yauzl": "3.4.0",
|
|
59
|
+
"pbf": "5.1.2",
|
|
51
60
|
"pngjs": "7.0.0"
|
|
52
61
|
},
|
|
53
62
|
"scripts": {
|
|
54
|
-
"build": "tsup src/index.ts --format esm --clean --
|
|
63
|
+
"build": "tsup src/index.ts --format esm --clean --splitting --platform node",
|
|
55
64
|
"cli": "tsx src/index.ts",
|
|
56
65
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
57
66
|
"lint": "tsc -p tsconfig.json --noEmit",
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$id": "https://tileflow.dev/schemas/tileset-recipe/v1.json",
|
|
3
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"$schema": {
|
|
7
|
+
"type": "string"
|
|
8
|
+
},
|
|
9
|
+
"layers": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"propertyNames": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,191}$"
|
|
14
|
+
},
|
|
15
|
+
"additionalProperties": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"properties": {
|
|
18
|
+
"featureId": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"properties": {
|
|
21
|
+
"field": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"minLength": 1
|
|
24
|
+
},
|
|
25
|
+
"hash": {
|
|
26
|
+
"type": "boolean"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"required": ["field"],
|
|
30
|
+
"additionalProperties": false
|
|
31
|
+
},
|
|
32
|
+
"fields": {
|
|
33
|
+
"type": "object",
|
|
34
|
+
"properties": {
|
|
35
|
+
"exclude": {
|
|
36
|
+
"type": "array",
|
|
37
|
+
"items": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"minLength": 1
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"include": {
|
|
43
|
+
"type": "array",
|
|
44
|
+
"items": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"minLength": 1
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"additionalProperties": false
|
|
51
|
+
},
|
|
52
|
+
"maxzoom": {
|
|
53
|
+
"anyOf": [
|
|
54
|
+
{
|
|
55
|
+
"type": "string",
|
|
56
|
+
"const": "auto"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"type": "integer",
|
|
60
|
+
"minimum": 0,
|
|
61
|
+
"maximum": 16
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
"minzoom": {
|
|
66
|
+
"type": "integer",
|
|
67
|
+
"minimum": 0,
|
|
68
|
+
"maximum": 16
|
|
69
|
+
},
|
|
70
|
+
"rank": {
|
|
71
|
+
"type": "object",
|
|
72
|
+
"properties": {
|
|
73
|
+
"by": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"minLength": 1
|
|
76
|
+
},
|
|
77
|
+
"order": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"enum": ["ascending", "descending"]
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"required": ["by"],
|
|
83
|
+
"additionalProperties": false
|
|
84
|
+
},
|
|
85
|
+
"source": {
|
|
86
|
+
"type": "string",
|
|
87
|
+
"minLength": 1
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"required": ["source"],
|
|
91
|
+
"additionalProperties": false
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"metadata": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"properties": {
|
|
97
|
+
"attribution": {
|
|
98
|
+
"type": "string",
|
|
99
|
+
"minLength": 1
|
|
100
|
+
},
|
|
101
|
+
"description": {
|
|
102
|
+
"type": "string",
|
|
103
|
+
"minLength": 1
|
|
104
|
+
},
|
|
105
|
+
"name": {
|
|
106
|
+
"type": "string",
|
|
107
|
+
"minLength": 1
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"additionalProperties": false
|
|
111
|
+
},
|
|
112
|
+
"sources": {
|
|
113
|
+
"type": "object",
|
|
114
|
+
"propertyNames": {
|
|
115
|
+
"type": "string",
|
|
116
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,191}$"
|
|
117
|
+
},
|
|
118
|
+
"additionalProperties": {
|
|
119
|
+
"type": "object",
|
|
120
|
+
"properties": {
|
|
121
|
+
"crs": {
|
|
122
|
+
"type": "object",
|
|
123
|
+
"properties": {
|
|
124
|
+
"from": {
|
|
125
|
+
"type": "string",
|
|
126
|
+
"minLength": 1
|
|
127
|
+
},
|
|
128
|
+
"reproject": {
|
|
129
|
+
"type": "boolean"
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
"additionalProperties": false
|
|
133
|
+
},
|
|
134
|
+
"csv": {
|
|
135
|
+
"type": "object",
|
|
136
|
+
"properties": {
|
|
137
|
+
"lat": {
|
|
138
|
+
"type": "string",
|
|
139
|
+
"minLength": 1
|
|
140
|
+
},
|
|
141
|
+
"lon": {
|
|
142
|
+
"type": "string",
|
|
143
|
+
"minLength": 1
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
"additionalProperties": false
|
|
147
|
+
},
|
|
148
|
+
"format": {
|
|
149
|
+
"type": "string",
|
|
150
|
+
"enum": ["csv", "geojson", "geojsonseq", "geopackage", "gpx", "kml", "shapefile"]
|
|
151
|
+
},
|
|
152
|
+
"layer": {
|
|
153
|
+
"type": "string",
|
|
154
|
+
"minLength": 1
|
|
155
|
+
},
|
|
156
|
+
"zipEntry": {
|
|
157
|
+
"type": "string",
|
|
158
|
+
"minLength": 1
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
"additionalProperties": false
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
"version": {
|
|
165
|
+
"type": "number",
|
|
166
|
+
"const": 1
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
"required": ["layers", "sources", "version"],
|
|
170
|
+
"additionalProperties": false
|
|
171
|
+
}
|