text-to-map 1.0.7 → 1.1.0
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/dist/bin/clear-all.js +21 -4
- package/dist/bin/init-db.d.ts +1 -0
- package/dist/bin/init-db.js +18 -0
- package/dist/bin/parse-ordinance.js +56 -42
- package/dist/bin/schools.js +1 -1
- package/dist/db/address-points.d.ts +13 -13
- package/dist/db/address-points.js +93 -77
- package/dist/db/db.d.ts +19 -10
- package/dist/db/db.js +124 -50
- package/dist/db/founders.d.ts +7 -7
- package/dist/db/founders.js +187 -135
- package/dist/db/meta.d.ts +3 -4
- package/dist/db/meta.js +23 -16
- package/dist/db/migrations/20230704125715_initial.d.ts +3 -0
- package/dist/db/migrations/20230704125715_initial.js +251 -0
- package/dist/db/regions.d.ts +5 -5
- package/dist/db/regions.js +40 -28
- package/dist/db/schools.d.ts +3 -2
- package/dist/db/schools.js +30 -14
- package/dist/db/street-sync.d.ts +4 -4
- package/dist/db/street-sync.js +26 -17
- package/dist/index.d.ts +3 -2
- package/dist/index.js +4 -2
- package/dist/open-data-sync/address-points.d.ts +0 -1
- package/dist/open-data-sync/address-points.js +35 -25
- package/dist/open-data-sync/regions.js +13 -5
- package/dist/open-data-sync/schools.js +19 -15
- package/dist/open-data-sync/streets.js +46 -33
- package/dist/street-markdown/municipality.d.ts +2 -2
- package/dist/street-markdown/municipality.js +46 -14
- package/dist/street-markdown/smd-line-parser.d.ts +1 -1
- package/dist/street-markdown/smd-line-parser.js +21 -8
- package/dist/street-markdown/smd.d.ts +8 -5
- package/dist/street-markdown/smd.js +100 -86
- package/dist/street-markdown/token-definition.js +6 -6
- package/dist/street-markdown/types.d.ts +8 -3
- package/dist/utils/helpers.d.ts +0 -1
- package/dist/utils/helpers.js +1 -8
- package/package.json +9 -5
|
@@ -11,8 +11,9 @@ import { parse } from "csv-parse";
|
|
|
11
11
|
import iconv from "iconv-lite";
|
|
12
12
|
import fetch from "node-fetch";
|
|
13
13
|
import { pipeline } from "stream/promises";
|
|
14
|
-
import { initDb, prepareOptions, } from "../utils/helpers";
|
|
15
14
|
import { insertRegionsAndOrps } from "../db/regions";
|
|
15
|
+
import { prepareOptions } from "../utils/helpers";
|
|
16
|
+
import { disconnectKnex } from "../db/db";
|
|
16
17
|
const downloadAndImportDataToDb = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
18
|
console.log("Downloading regions and ORP data...");
|
|
18
19
|
const response = yield fetch(options.regionsCsvUrl);
|
|
@@ -32,11 +33,18 @@ const downloadAndImportDataToDb = (options) => __awaiter(void 0, void 0, void 0,
|
|
|
32
33
|
// @ts-ignore
|
|
33
34
|
const schema = yield schemaResponse.json();
|
|
34
35
|
console.log("Parsing completed. Starting to import data to DB...");
|
|
35
|
-
|
|
36
|
-
insertRegionsAndOrps(rows, schema);
|
|
36
|
+
yield insertRegionsAndOrps(rows, schema);
|
|
37
37
|
console.log(`Import completed. Total imported rows: ${rows.length}`);
|
|
38
38
|
});
|
|
39
39
|
export const downloadAndImportRegions = (options = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
try {
|
|
41
|
+
const completeOptions = prepareOptions(options);
|
|
42
|
+
yield downloadAndImportDataToDb(completeOptions);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.log(error);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
yield disconnectKnex();
|
|
49
|
+
}
|
|
42
50
|
});
|
|
@@ -8,15 +8,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { createReadStream, createWriteStream, existsSync, rmSync } from "fs";
|
|
11
|
+
import fetch from "node-fetch";
|
|
11
12
|
import { join } from "path";
|
|
12
13
|
import sax from "sax";
|
|
13
|
-
import fetch from "node-fetch";
|
|
14
|
-
import { setDbConfig } from "../db/db";
|
|
15
|
-
import { prepareOptions, } from "../utils/helpers";
|
|
16
14
|
import { pipeline } from "stream/promises";
|
|
17
|
-
import {
|
|
18
|
-
import { insertSchools } from "../db/schools";
|
|
15
|
+
import { disconnectKnex } from "../db/db";
|
|
19
16
|
import { insertFounders } from "../db/founders";
|
|
17
|
+
import { insertSchools } from "../db/schools";
|
|
18
|
+
import { MunicipalityType } from "../db/types";
|
|
19
|
+
import { prepareOptions, } from "../utils/helpers";
|
|
20
20
|
const downloadXml = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
21
|
if (existsSync(getXmlFilePath(options))) {
|
|
22
22
|
return;
|
|
@@ -293,21 +293,25 @@ const importDataToDb = (options, saveFoundersToCsv = false, saveSchoolsWithoutRu
|
|
|
293
293
|
});
|
|
294
294
|
csv.end();
|
|
295
295
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
initFilePath: options.dbInitFilePath,
|
|
299
|
-
});
|
|
300
|
-
insertSchools(schools);
|
|
301
|
-
insertFounders(Array.from(founders.values()));
|
|
296
|
+
yield insertSchools(schools);
|
|
297
|
+
yield insertFounders(Array.from(founders.values()));
|
|
302
298
|
});
|
|
303
299
|
const getXmlFilePath = (options) => {
|
|
304
300
|
return join(options.tmpDir, options.schoolsXmlFileName);
|
|
305
301
|
};
|
|
306
302
|
export const downloadAndImportSchools = (options, saveFoundersToCsv = false, saveSchoolsWithoutRuianToCsv = false) => __awaiter(void 0, void 0, void 0, function* () {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
303
|
+
try {
|
|
304
|
+
const runOptions = prepareOptions(options);
|
|
305
|
+
yield downloadXml(runOptions);
|
|
306
|
+
yield importDataToDb(runOptions, saveFoundersToCsv, saveSchoolsWithoutRuianToCsv);
|
|
307
|
+
deleteSchoolsXmlFile(runOptions);
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
console.error(error);
|
|
311
|
+
}
|
|
312
|
+
finally {
|
|
313
|
+
yield disconnectKnex();
|
|
314
|
+
}
|
|
311
315
|
});
|
|
312
316
|
export const deleteSchoolsXmlFile = (options = {}) => {
|
|
313
317
|
const runOptions = prepareOptions(options);
|
|
@@ -7,15 +7,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import fetch from "node-fetch";
|
|
11
|
-
import { createWriteStream, rmSync, existsSync, mkdirSync } from "fs";
|
|
12
|
-
import { pipeline } from "stream/promises";
|
|
13
|
-
import { join } from "path";
|
|
14
10
|
import AdmZip from "adm-zip";
|
|
11
|
+
import { createWriteStream, existsSync, mkdirSync, rmSync } from "fs";
|
|
12
|
+
import fetch from "node-fetch";
|
|
15
13
|
import parseDBF from "parsedbf";
|
|
16
|
-
import {
|
|
14
|
+
import { join } from "path";
|
|
15
|
+
import { pipeline } from "stream/promises";
|
|
17
16
|
import { deleteStreets, getAllSyncedStreets, insertStreetsFromDbf, setStreetAsSynced, } from "../db/street-sync";
|
|
18
17
|
import { getAllUrlsFromAtomFeed, getLatestUrlFromAtomFeed, } from "../utils/atom";
|
|
18
|
+
import { prepareOptions, } from "../utils/helpers";
|
|
19
|
+
import { disconnectKnex } from "../db/db";
|
|
20
|
+
import { areAddressPointsSynced } from "../db/address-points";
|
|
19
21
|
const prepareFolders = (options) => {
|
|
20
22
|
const tempFolder = getTempFolder(options);
|
|
21
23
|
if (!existsSync(tempFolder)) {
|
|
@@ -43,36 +45,47 @@ const importDataToDb = (data) => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
43
45
|
if (data.length === 0) {
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
46
|
-
insertStreetsFromDbf(data);
|
|
48
|
+
yield insertStreetsFromDbf(data);
|
|
47
49
|
});
|
|
48
50
|
export const downloadAndImportStreets = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const allDatasetFeedLinks = yield getAllUrlsFromAtomFeed(completeOptions.streetsAtomUrl);
|
|
54
|
-
console.log(`Total of ${allDatasetFeedLinks.length} links to ZIP files.`);
|
|
55
|
-
const syncedStreetLinks = getAllSyncedStreets();
|
|
56
|
-
const toDelete = [];
|
|
57
|
-
// remove all deprecated links (not in the new list)
|
|
58
|
-
syncedStreetLinks.forEach((link) => {
|
|
59
|
-
if (!allDatasetFeedLinks.includes(link)) {
|
|
60
|
-
toDelete.push(link);
|
|
61
|
-
delete syncedStreetLinks[link];
|
|
51
|
+
try {
|
|
52
|
+
// first check if address points are already synced
|
|
53
|
+
if (!(yield areAddressPointsSynced())) {
|
|
54
|
+
throw new Error("Address points are not synced yet. First run 'npm run address-points' and then try again.");
|
|
62
55
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
56
|
+
console.log("Starting to download and import streets. This takes up to 1 hour.");
|
|
57
|
+
const completeOptions = prepareOptions(options);
|
|
58
|
+
prepareFolders(completeOptions);
|
|
59
|
+
const allDatasetFeedLinks = yield getAllUrlsFromAtomFeed(completeOptions.streetsAtomUrl);
|
|
60
|
+
console.log(`Total of ${allDatasetFeedLinks.length} links to ZIP files.`);
|
|
61
|
+
const syncedStreetLinks = yield getAllSyncedStreets();
|
|
62
|
+
const toDelete = [];
|
|
63
|
+
// remove all deprecated links (not in the new list)
|
|
64
|
+
syncedStreetLinks.forEach((link) => {
|
|
65
|
+
if (!allDatasetFeedLinks.includes(link)) {
|
|
66
|
+
toDelete.push(link);
|
|
67
|
+
delete syncedStreetLinks[link];
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
yield deleteStreets(toDelete);
|
|
71
|
+
let done = syncedStreetLinks.size;
|
|
72
|
+
console.log(`Total of ${done} links to ZIP files already stored.`);
|
|
73
|
+
// get all links not yet stored
|
|
74
|
+
const newLinks = allDatasetFeedLinks.filter((link) => !syncedStreetLinks.has(link));
|
|
75
|
+
console.log(`Loading ${newLinks.length} new links to ZIP files.`);
|
|
76
|
+
for (const link of newLinks) {
|
|
77
|
+
const zipLink = yield getLatestUrlFromAtomFeed(link);
|
|
78
|
+
const dbfObject = yield downloadZipAndParseDbfFile(zipLink, done, completeOptions);
|
|
79
|
+
yield importDataToDb(dbfObject);
|
|
80
|
+
yield setStreetAsSynced(link);
|
|
81
|
+
done++;
|
|
82
|
+
console.log(`Loaded links: ${done}/${allDatasetFeedLinks.length}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.log(error);
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
yield disconnectKnex();
|
|
77
90
|
}
|
|
78
91
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DbMunicipalityResult } from "./types";
|
|
2
2
|
export declare const isMunicipalitySwitch: (line: string) => boolean;
|
|
3
|
-
export declare const getSwitchMunicipality: (line: string) => DbMunicipalityResult
|
|
3
|
+
export declare const getSwitchMunicipality: (line: string) => Promise<DbMunicipalityResult>;
|
|
4
4
|
export declare const isWholeMunicipality: (line: string) => boolean;
|
|
5
|
-
export declare const getWholeMunicipality: (line: string) => DbMunicipalityResult
|
|
5
|
+
export declare const getWholeMunicipality: (line: string) => Promise<DbMunicipalityResult>;
|
|
@@ -1,37 +1,69 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
import { findMunicipalityByNameAndType } from "../db/founders";
|
|
2
11
|
import { MunicipalityType } from "../db/types";
|
|
12
|
+
const municipalitySwitchStartPattern = /^navíc ulice /;
|
|
3
13
|
const municipalitySwitchPattern = /^navíc ulice (z )?(?<type>městské části|městského obvodu|obce|města) (?<name>.+):$/;
|
|
14
|
+
const wholeMunicipalityStartPattern = /^území /;
|
|
4
15
|
const wholeMunicipalityPattern = /^území (?<type>městské části|městského obvodu|obce|města) (?<name>.+)$/;
|
|
5
16
|
export const isMunicipalitySwitch = (line) => {
|
|
6
|
-
return
|
|
17
|
+
return municipalitySwitchStartPattern.test(line);
|
|
7
18
|
};
|
|
8
|
-
export const getSwitchMunicipality = (line) => {
|
|
19
|
+
export const getSwitchMunicipality = (line) => __awaiter(void 0, void 0, void 0, function* () {
|
|
9
20
|
const match = municipalitySwitchPattern.exec(line);
|
|
10
21
|
if (match === null) {
|
|
11
|
-
|
|
22
|
+
return {
|
|
23
|
+
errors: [
|
|
24
|
+
{
|
|
25
|
+
message: "Neplatný zápis pro dočasnou změnu obce v definici ulic. Správný zápis je: navíc ulice <typ> <název obce>. Např.: 'navíc ulice obce Mokrá Lhota:' (název obce musí být v 1. pádě).",
|
|
26
|
+
startOffset: 0,
|
|
27
|
+
endOffset: line.length + 1,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
municipality: null,
|
|
31
|
+
};
|
|
12
32
|
}
|
|
13
33
|
const { type, name } = match.groups;
|
|
14
|
-
return getMunicipalityResult(type, name);
|
|
15
|
-
};
|
|
34
|
+
return yield getMunicipalityResult(type, name, line);
|
|
35
|
+
});
|
|
16
36
|
export const isWholeMunicipality = (line) => {
|
|
17
|
-
return
|
|
37
|
+
return wholeMunicipalityStartPattern.test(line);
|
|
18
38
|
};
|
|
19
|
-
export const getWholeMunicipality = (line) => {
|
|
39
|
+
export const getWholeMunicipality = (line) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
40
|
const match = wholeMunicipalityPattern.exec(line);
|
|
21
41
|
if (match === null) {
|
|
22
|
-
return {
|
|
42
|
+
return {
|
|
43
|
+
errors: [
|
|
44
|
+
{
|
|
45
|
+
message: "Neplatný zápis pro přidání celé obce. Správný zápis je: území <typ> <název obce>. Např.: 'území obce Kladno' (název obce musí být v 1. pádě).",
|
|
46
|
+
startOffset: 0,
|
|
47
|
+
endOffset: line.length + 1,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
municipality: null,
|
|
51
|
+
};
|
|
23
52
|
}
|
|
24
53
|
const { type, name } = match.groups;
|
|
25
|
-
return getMunicipalityResult(type, name);
|
|
26
|
-
};
|
|
27
|
-
const getMunicipalityResult = (type, name) => {
|
|
54
|
+
return yield getMunicipalityResult(type, name, line);
|
|
55
|
+
});
|
|
56
|
+
const getMunicipalityResult = (type, name, line) => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
57
|
const typeValue = getMunicipalityType(type);
|
|
29
|
-
const { municipality, errors } = findMunicipalityByNameAndType(name, typeValue);
|
|
58
|
+
const { municipality, errors } = yield findMunicipalityByNameAndType(name, typeValue);
|
|
59
|
+
const startOffset = line.indexOf(name);
|
|
60
|
+
const endOffset = startOffset + name.length + 1;
|
|
30
61
|
return {
|
|
31
62
|
municipality,
|
|
32
|
-
errors,
|
|
63
|
+
errors: errors.map((error) => (Object.assign(Object.assign({}, error), { startOffset,
|
|
64
|
+
endOffset }))),
|
|
33
65
|
};
|
|
34
|
-
};
|
|
66
|
+
});
|
|
35
67
|
const getMunicipalityType = (type) => {
|
|
36
68
|
switch (type) {
|
|
37
69
|
case "městské části":
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { SmdParser } from "./smd-parser";
|
|
2
2
|
import { ProcessedSmdLines } from "./types";
|
|
3
3
|
export declare const smdParser: SmdParser;
|
|
4
|
-
export declare const parseLine: (text: string) => ProcessedSmdLines;
|
|
4
|
+
export declare const parseLine: (text: string, showDebug?: boolean) => ProcessedSmdLines;
|
|
@@ -1,29 +1,42 @@
|
|
|
1
1
|
import { Lexer } from "chevrotain";
|
|
2
2
|
import { SmdParser } from "./smd-parser";
|
|
3
|
-
// const token_definition = require("token_definition");
|
|
4
3
|
import { tokenVocabulary, smdTokens, resetTokenState, prepareLine, } from "./token-definition";
|
|
5
4
|
const printLexingResultInfo = (lexingResult) => {
|
|
6
|
-
// console.error(JSON.stringify(lexingResult, null, "\t"));
|
|
7
5
|
const tokens = lexingResult.tokens.map((token) => "'" + token.image + "' (" + token.tokenType.name + ")");
|
|
8
6
|
console.error(tokens);
|
|
9
7
|
};
|
|
10
8
|
const smdLexer = new Lexer(smdTokens, { positionTracking: "onlyOffset" });
|
|
11
9
|
export const smdParser = new SmdParser(tokenVocabulary);
|
|
12
|
-
export const parseLine = (text) => {
|
|
10
|
+
export const parseLine = (text, showDebug = false) => {
|
|
13
11
|
resetTokenState(); // this is needed to reset the token state between lines
|
|
14
12
|
const errors = [];
|
|
15
13
|
const lexingResult = smdLexer.tokenize(prepareLine(text));
|
|
16
14
|
if (lexingResult.errors.length > 0) {
|
|
17
|
-
errors.push(...lexingResult.errors.map((error) =>
|
|
18
|
-
|
|
15
|
+
errors.push(...lexingResult.errors.map((error) => ({
|
|
16
|
+
message: `Neočekávaný znak na tomto místě.`,
|
|
17
|
+
startOffset: error.offset,
|
|
18
|
+
endOffset: error.offset + error.length + 1,
|
|
19
|
+
})));
|
|
20
|
+
if (showDebug) {
|
|
21
|
+
printLexingResultInfo(lexingResult);
|
|
22
|
+
}
|
|
19
23
|
return { smdLines: [], errors };
|
|
20
24
|
}
|
|
21
|
-
// printLexingResultInfo(lexingResult);
|
|
22
25
|
smdParser.input = lexingResult.tokens;
|
|
23
26
|
const smdLines = smdParser.street();
|
|
24
27
|
if (smdParser.errors.length > 0) {
|
|
25
|
-
errors.push(...smdParser.errors.map((error) =>
|
|
26
|
-
|
|
28
|
+
errors.push(...smdParser.errors.map((error) => {
|
|
29
|
+
var _a;
|
|
30
|
+
return ({
|
|
31
|
+
message: `Nesprávný zápis pravidla - nevynechali jste něco?`,
|
|
32
|
+
startOffset: error.token.startOffset,
|
|
33
|
+
endOffset: (_a = error.token.endOffset) !== null && _a !== void 0 ? _a : text.length,
|
|
34
|
+
});
|
|
35
|
+
}));
|
|
36
|
+
if (showDebug) {
|
|
37
|
+
printLexingResultInfo(lexingResult);
|
|
38
|
+
}
|
|
39
|
+
return { smdLines: [], errors };
|
|
27
40
|
}
|
|
28
41
|
return { smdLines, errors };
|
|
29
42
|
};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Founder } from "../db/types";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export declare const parseOrdinanceToAddressPoints: (lines: string[], options?: OpenDataSyncOptionsPartial, initialState?: Partial<SmdState>, onError?: (params: ErrorCallbackParams) => void, onWarning?: (params: ErrorCallbackParams) => void, onProcessedLine?: (params: ProcessLineCallbackParams) => void) => Municipality[];
|
|
2
|
+
import { ErrorCallbackParams, Municipality, MunicipalityWithFounder, ProcessLineCallbackParams, School, SmdError, SmdState } from "./types";
|
|
3
|
+
export declare const parseOrdinanceToAddressPoints: (lines: string[], initialState?: Partial<SmdState>, onError?: (params: ErrorCallbackParams) => void, onWarning?: (params: ErrorCallbackParams) => void, onProcessedLine?: (params: ProcessLineCallbackParams) => void) => Promise<Municipality[]>;
|
|
5
4
|
export declare const convertMunicipality: (municipality: MunicipalityWithFounder) => Municipality;
|
|
6
|
-
export declare const getNewMunicipality: (name: string
|
|
7
|
-
|
|
5
|
+
export declare const getNewMunicipality: (name: string) => Promise<{
|
|
6
|
+
municipality: MunicipalityWithFounder;
|
|
7
|
+
errors: SmdError[];
|
|
8
|
+
}>;
|
|
9
|
+
export declare const getNewSchool: (name: string, founder: Founder | null, lineNumber: number, onError: (params: ErrorCallbackParams) => void) => Promise<School>;
|
|
10
|
+
export declare const wholeLineError: (message: string, line: string) => SmdError;
|
|
@@ -1,43 +1,54 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
import { checkStreetExists, findAddressPoints, getAddressPointById, } from "../db/address-points";
|
|
2
|
-
import {
|
|
11
|
+
import { disconnectKnex } from "../db/db";
|
|
3
12
|
import { findFounder } from "../db/founders";
|
|
4
13
|
import { findSchool } from "../db/schools";
|
|
5
14
|
import { founderToMunicipality } from "../db/types";
|
|
6
|
-
import { prepareOptions } from "../utils/helpers";
|
|
7
15
|
import { getSwitchMunicipality, getWholeMunicipality, isMunicipalitySwitch, isWholeMunicipality, } from "./municipality";
|
|
8
16
|
import { parseLine } from "./smd-line-parser";
|
|
9
17
|
import { isAddressPoint, } from "./types";
|
|
10
|
-
export const parseOrdinanceToAddressPoints = (lines,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
lineNumber,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (state.currentMunicipality == null) {
|
|
32
|
-
state.currentMunicipality = getNewMunicipality("");
|
|
18
|
+
export const parseOrdinanceToAddressPoints = (lines, initialState = {}, onError = () => { }, onWarning = () => { }, onProcessedLine = () => { }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
+
try {
|
|
20
|
+
const state = Object.assign({ currentMunicipality: null, currentFilterMunicipality: null, currentSchool: null, municipalities: [] }, initialState);
|
|
21
|
+
let lineNumber = 1;
|
|
22
|
+
for (const rawLine of lines) {
|
|
23
|
+
const line = cleanLine(rawLine);
|
|
24
|
+
yield processOneLine({
|
|
25
|
+
line,
|
|
26
|
+
state,
|
|
27
|
+
lineNumber,
|
|
28
|
+
onError,
|
|
29
|
+
onWarning,
|
|
30
|
+
});
|
|
31
|
+
onProcessedLine({ lineNumber, line });
|
|
32
|
+
lineNumber++;
|
|
33
|
+
}
|
|
34
|
+
if (state.currentSchool != null) {
|
|
35
|
+
if (state.currentMunicipality == null) {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
state.currentMunicipality.schools.push(mapSchoolForExport(state.currentSchool));
|
|
33
39
|
}
|
|
34
|
-
state.currentMunicipality
|
|
40
|
+
if (state.currentMunicipality != null) {
|
|
41
|
+
state.municipalities.push(convertMunicipality(state.currentMunicipality));
|
|
42
|
+
}
|
|
43
|
+
return state.municipalities;
|
|
35
44
|
}
|
|
36
|
-
|
|
37
|
-
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error(error);
|
|
38
47
|
}
|
|
39
|
-
|
|
40
|
-
|
|
48
|
+
finally {
|
|
49
|
+
yield disconnectKnex();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
41
52
|
const filterOutSchoolAddressPoint = (addressPoints, school) => {
|
|
42
53
|
const schoolPosition = school.position;
|
|
43
54
|
return schoolPosition && isAddressPoint(schoolPosition)
|
|
@@ -50,10 +61,10 @@ export const convertMunicipality = (municipality) => {
|
|
|
50
61
|
schools: municipality.schools,
|
|
51
62
|
};
|
|
52
63
|
};
|
|
53
|
-
const processOneLine = (params) => {
|
|
64
|
+
const processOneLine = (params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
65
|
const { line, state } = params;
|
|
55
66
|
if (line[0] === "#") {
|
|
56
|
-
processMunicipalityLine(params);
|
|
67
|
+
yield processMunicipalityLine(params);
|
|
57
68
|
return;
|
|
58
69
|
}
|
|
59
70
|
if (line === "") {
|
|
@@ -65,20 +76,20 @@ const processOneLine = (params) => {
|
|
|
65
76
|
return;
|
|
66
77
|
}
|
|
67
78
|
if (state.currentSchool === null) {
|
|
68
|
-
processSchoolLine(params);
|
|
79
|
+
yield processSchoolLine(params);
|
|
69
80
|
return;
|
|
70
81
|
}
|
|
71
82
|
if (isMunicipalitySwitch(line)) {
|
|
72
83
|
processMunicipalitySwitchLine(params);
|
|
73
84
|
}
|
|
74
85
|
else if (isWholeMunicipality(line)) {
|
|
75
|
-
processWholeMunicipalityLine(params);
|
|
86
|
+
yield processWholeMunicipalityLine(params);
|
|
76
87
|
}
|
|
77
88
|
else {
|
|
78
|
-
processAddressPointLine(params);
|
|
89
|
+
yield processAddressPointLine(params);
|
|
79
90
|
}
|
|
80
|
-
};
|
|
81
|
-
const processMunicipalityLine = ({ line, state }) => {
|
|
91
|
+
});
|
|
92
|
+
const processMunicipalityLine = ({ line, state, onError, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
93
|
if (state.currentSchool !== null) {
|
|
83
94
|
state.currentMunicipality.schools.push(state.currentSchool);
|
|
84
95
|
state.currentSchool = null;
|
|
@@ -86,97 +97,95 @@ const processMunicipalityLine = ({ line, state }) => {
|
|
|
86
97
|
if (state.currentMunicipality !== null) {
|
|
87
98
|
state.municipalities.push(convertMunicipality(state.currentMunicipality));
|
|
88
99
|
}
|
|
89
|
-
|
|
100
|
+
const { municipality, errors } = yield getNewMunicipality(line);
|
|
101
|
+
state.currentMunicipality = municipality;
|
|
90
102
|
state.currentFilterMunicipality = founderToMunicipality(state.currentMunicipality.founder);
|
|
91
103
|
state.currentSchool = null;
|
|
92
|
-
};
|
|
104
|
+
});
|
|
93
105
|
const processEmptyLine = ({ state }) => {
|
|
94
106
|
if (state.currentSchool !== null) {
|
|
95
107
|
state.currentMunicipality.schools.push(state.currentSchool);
|
|
96
108
|
state.currentSchool = null;
|
|
97
109
|
}
|
|
98
110
|
};
|
|
99
|
-
const processSchoolLine = ({ line, lineNumber, state }) => {
|
|
111
|
+
const processSchoolLine = ({ line, lineNumber, state, onError, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
100
112
|
if (state.currentMunicipality === null) {
|
|
101
|
-
|
|
113
|
+
onError({
|
|
114
|
+
lineNumber,
|
|
115
|
+
line,
|
|
116
|
+
errors: [
|
|
117
|
+
wholeLineError("Definici školy musí předcházet definice zřizovatele (uvozená '#', např. '# Strakonice').", line),
|
|
118
|
+
],
|
|
119
|
+
});
|
|
120
|
+
return;
|
|
102
121
|
}
|
|
103
|
-
state.currentSchool = getNewSchool(line, state.currentMunicipality.founder);
|
|
122
|
+
state.currentSchool = yield getNewSchool(line, state.currentMunicipality.founder, lineNumber, onError);
|
|
104
123
|
state.currentFilterMunicipality = founderToMunicipality(state.currentMunicipality.founder);
|
|
105
|
-
};
|
|
106
|
-
const processMunicipalitySwitchLine = ({ line, state, lineNumber, onError, }) => {
|
|
107
|
-
const { municipality, errors } = getSwitchMunicipality(line);
|
|
124
|
+
});
|
|
125
|
+
const processMunicipalitySwitchLine = ({ line, state, lineNumber, onError, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
126
|
+
const { municipality, errors } = yield getSwitchMunicipality(line);
|
|
108
127
|
if (errors.length > 0) {
|
|
109
128
|
onError({ lineNumber, line, errors });
|
|
110
129
|
}
|
|
111
130
|
else {
|
|
112
131
|
state.currentFilterMunicipality = municipality;
|
|
113
132
|
}
|
|
114
|
-
};
|
|
115
|
-
const processWholeMunicipalityLine = ({ line, state, lineNumber, onError, }) => {
|
|
116
|
-
const { municipality, errors } = getWholeMunicipality(line);
|
|
133
|
+
});
|
|
134
|
+
const processWholeMunicipalityLine = ({ line, state, lineNumber, onError, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
135
|
+
const { municipality, errors } = yield getWholeMunicipality(line);
|
|
117
136
|
if (errors.length > 0) {
|
|
118
137
|
onError({ lineNumber, line, errors });
|
|
119
138
|
}
|
|
120
139
|
else {
|
|
121
|
-
const addressPoints = findAddressPoints({ wholeMunicipality: true, street: "", numberSpec: [] }, municipality);
|
|
140
|
+
const addressPoints = yield findAddressPoints({ wholeMunicipality: true, street: "", numberSpec: [] }, municipality);
|
|
122
141
|
state.currentSchool.addresses.push(...filterOutSchoolAddressPoint(addressPoints, state.currentSchool).map(mapAddressPointForExport));
|
|
123
142
|
}
|
|
124
|
-
};
|
|
125
|
-
const processAddressPointLine = ({ line, state, lineNumber, onError, onWarning, }) => {
|
|
143
|
+
});
|
|
144
|
+
const processAddressPointLine = ({ line, state, lineNumber, onError, onWarning, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
126
145
|
const { smdLines, errors } = parseLine(line);
|
|
127
146
|
if (errors.length > 0) {
|
|
128
147
|
onError({ lineNumber, line, errors });
|
|
129
148
|
}
|
|
130
149
|
else {
|
|
131
|
-
|
|
132
|
-
const { exists, errors } = checkStreetExists(smdLine.street, state.currentMunicipality.founder);
|
|
150
|
+
for (const smdLine of smdLines) {
|
|
151
|
+
const { exists, errors } = yield checkStreetExists(smdLine.street, state.currentMunicipality.founder);
|
|
133
152
|
if (errors.length > 0) {
|
|
134
153
|
onWarning({ lineNumber, line, errors });
|
|
135
154
|
}
|
|
136
155
|
if (exists) {
|
|
137
|
-
let addressPoints = findAddressPoints(smdLine, state.currentFilterMunicipality);
|
|
156
|
+
let addressPoints = yield findAddressPoints(smdLine, state.currentFilterMunicipality);
|
|
138
157
|
state.currentSchool.addresses.push(...filterOutSchoolAddressPoint(addressPoints, state.currentSchool).map(mapAddressPointForExport));
|
|
139
158
|
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
export const getNewMunicipality = (name, options) => {
|
|
144
|
-
if (options) {
|
|
145
|
-
options = prepareOptions(options);
|
|
146
|
-
setDbConfig({
|
|
147
|
-
filePath: options.dbFilePath,
|
|
148
|
-
initFilePath: options.dbInitFilePath,
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
const { founder, errors } = findFounder(name);
|
|
152
|
-
if (errors.length > 0) {
|
|
153
|
-
errors.forEach(console.error);
|
|
159
|
+
}
|
|
154
160
|
}
|
|
161
|
+
});
|
|
162
|
+
export const getNewMunicipality = (name) => __awaiter(void 0, void 0, void 0, function* () {
|
|
163
|
+
const { founder, errors } = yield findFounder(name);
|
|
155
164
|
return {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
165
|
+
municipality: {
|
|
166
|
+
municipalityName: founder ? founder.name : "Neznámá obec",
|
|
167
|
+
founder,
|
|
168
|
+
schools: [],
|
|
169
|
+
},
|
|
170
|
+
errors,
|
|
159
171
|
};
|
|
160
|
-
};
|
|
161
|
-
export const getNewSchool = (name, founder,
|
|
162
|
-
if (options) {
|
|
163
|
-
options = prepareOptions(options);
|
|
164
|
-
setDbConfig({
|
|
165
|
-
filePath: options.dbFilePath,
|
|
166
|
-
initFilePath: options.dbInitFilePath,
|
|
167
|
-
});
|
|
168
|
-
}
|
|
172
|
+
});
|
|
173
|
+
export const getNewSchool = (name, founder, lineNumber, onError) => __awaiter(void 0, void 0, void 0, function* () {
|
|
169
174
|
let exportSchool = {
|
|
170
|
-
name
|
|
175
|
+
name,
|
|
171
176
|
izo: "",
|
|
172
177
|
addresses: [],
|
|
173
178
|
};
|
|
174
179
|
if (founder !== null) {
|
|
175
|
-
const { school } = findSchool(name, founder.schools);
|
|
180
|
+
const { school, errors } = findSchool(name, founder.schools);
|
|
181
|
+
if (errors.length > 0) {
|
|
182
|
+
onError({ lineNumber, line: name, errors });
|
|
183
|
+
}
|
|
176
184
|
if (school) {
|
|
177
|
-
|
|
185
|
+
exportSchool.name = school.name;
|
|
186
|
+
exportSchool.izo = school.izo || "";
|
|
178
187
|
if (school.locations.length > 0) {
|
|
179
|
-
const position = getAddressPointById(school.locations[0].addressPointId);
|
|
188
|
+
const position = yield getAddressPointById(school.locations[0].addressPointId);
|
|
180
189
|
if (position !== null) {
|
|
181
190
|
exportSchool.position = position;
|
|
182
191
|
}
|
|
@@ -184,7 +193,7 @@ export const getNewSchool = (name, founder, options) => {
|
|
|
184
193
|
}
|
|
185
194
|
}
|
|
186
195
|
return exportSchool;
|
|
187
|
-
};
|
|
196
|
+
});
|
|
188
197
|
const mapAddressPointForExport = (addressPoint) => {
|
|
189
198
|
return {
|
|
190
199
|
address: addressPoint.address,
|
|
@@ -196,8 +205,13 @@ const mapSchoolForExport = (school) => ({
|
|
|
196
205
|
name: school.name,
|
|
197
206
|
izo: school.izo,
|
|
198
207
|
addresses: school.addresses,
|
|
199
|
-
position: mapAddressPointForExport(school.position),
|
|
208
|
+
position: school.position ? mapAddressPointForExport(school.position) : null,
|
|
200
209
|
});
|
|
201
210
|
const cleanLine = (line) => {
|
|
202
211
|
return line.trim().replace(/–/g, "-");
|
|
203
212
|
};
|
|
213
|
+
export const wholeLineError = (message, line) => ({
|
|
214
|
+
message,
|
|
215
|
+
startOffset: 0,
|
|
216
|
+
endOffset: line.length + 1,
|
|
217
|
+
});
|