text-to-map 1.0.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/LICENSE +21 -0
- package/README.md +20 -0
- package/dist/bin/address-points-import-only.d.ts +1 -0
- package/dist/bin/address-points-import-only.js +14 -0
- package/dist/bin/address-points.d.ts +1 -0
- package/dist/bin/address-points.js +14 -0
- package/dist/bin/clear-all.d.ts +1 -0
- package/dist/bin/clear-all.js +5 -0
- package/dist/bin/generate-syntax-diagrams.d.ts +1 -0
- package/dist/bin/generate-syntax-diagrams.js +19 -0
- package/dist/bin/parse-ordinance.d.ts +1 -0
- package/dist/bin/parse-ordinance.js +20 -0
- package/dist/bin/schools.d.ts +1 -0
- package/dist/bin/schools.js +8 -0
- package/dist/bin/streets.d.ts +1 -0
- package/dist/bin/streets.js +14 -0
- package/dist/db/address-points.d.ts +38 -0
- package/dist/db/address-points.js +312 -0
- package/dist/db/db.d.ts +23 -0
- package/dist/db/db.js +90 -0
- package/dist/db/founders.d.ts +9 -0
- package/dist/db/founders.js +191 -0
- package/dist/db/meta.d.ts +3 -0
- package/dist/db/meta.js +17 -0
- package/dist/db/schools.d.ts +6 -0
- package/dist/db/schools.js +61 -0
- package/dist/db/street-sync.d.ts +5 -0
- package/dist/db/street-sync.js +18 -0
- package/dist/db/types.d.ts +34 -0
- package/dist/db/types.js +12 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/open-data-sync/address-points.d.ts +4 -0
- package/dist/open-data-sync/address-points.js +73 -0
- package/dist/open-data-sync/schools.d.ts +3 -0
- package/dist/open-data-sync/schools.js +308 -0
- package/dist/open-data-sync/streets.d.ts +2 -0
- package/dist/open-data-sync/streets.js +77 -0
- package/dist/smd-to-csv/json-to-csv.d.ts +1 -0
- package/dist/smd-to-csv/json-to-csv.js +153 -0
- package/dist/smd-to-csv/ordinance-to-csv-rules.d.ts +1 -0
- package/dist/smd-to-csv/ordinance-to-csv-rules.js +31 -0
- package/dist/smd-to-csv/txt-to-json.d.ts +1 -0
- package/dist/smd-to-csv/txt-to-json.js +102 -0
- package/dist/street-markdown/municipality.d.ts +5 -0
- package/dist/street-markdown/municipality.js +44 -0
- package/dist/street-markdown/roman-numerals.d.ts +1 -0
- package/dist/street-markdown/roman-numerals.js +67 -0
- package/dist/street-markdown/smd-line-parser.d.ts +4 -0
- package/dist/street-markdown/smd-line-parser.js +29 -0
- package/dist/street-markdown/smd-parser.d.ts +21 -0
- package/dist/street-markdown/smd-parser.js +343 -0
- package/dist/street-markdown/smd.d.ts +9 -0
- package/dist/street-markdown/smd.js +182 -0
- package/dist/street-markdown/token-definition.d.ts +23 -0
- package/dist/street-markdown/token-definition.js +154 -0
- package/dist/street-markdown/types.d.ts +83 -0
- package/dist/street-markdown/types.js +18 -0
- package/dist/utils/addressBuilder.d.ts +8 -0
- package/dist/utils/addressBuilder.js +101 -0
- package/dist/utils/atom.d.ts +2 -0
- package/dist/utils/atom.js +65 -0
- package/dist/utils/helpers.d.ts +34 -0
- package/dist/utils/helpers.js +157 -0
- package/package.json +82 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { checkStreetExists, findAddressPoints, getAddressPointById, } from "../db/address-points";
|
|
2
|
+
import { setDbConfig } from "../db/db";
|
|
3
|
+
import { findFounder } from "../db/founders";
|
|
4
|
+
import { findSchool } from "../db/schools";
|
|
5
|
+
import { founderToMunicipality, } from "../db/types";
|
|
6
|
+
import { prepareOptions } from "../utils/helpers";
|
|
7
|
+
import { getSwitchMunicipality, getWholeMunicipality, isMunicipalitySwitch, isWholeMunicipality, } from "./municipality";
|
|
8
|
+
import { parseLine } from "./smd-line-parser";
|
|
9
|
+
import { isAddressPoint, } from "./types";
|
|
10
|
+
const getNewMunicipality = (name) => {
|
|
11
|
+
const { founder, errors } = findFounder(name);
|
|
12
|
+
if (errors.length > 0) {
|
|
13
|
+
errors.forEach(console.error);
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
municipalityName: founder ? founder.name : "Neznámá obec",
|
|
17
|
+
founder,
|
|
18
|
+
schools: [],
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
const getNewSchool = (name, founder) => {
|
|
22
|
+
let exportSchool = {
|
|
23
|
+
name: name,
|
|
24
|
+
izo: "",
|
|
25
|
+
addresses: [],
|
|
26
|
+
};
|
|
27
|
+
if (founder !== null) {
|
|
28
|
+
const { school } = findSchool(name, founder.schools);
|
|
29
|
+
if (school) {
|
|
30
|
+
school.izo = school.izo || "";
|
|
31
|
+
if (school.locations.length > 0) {
|
|
32
|
+
const position = getAddressPointById(school.locations[0].addressPointId);
|
|
33
|
+
if (position !== null) {
|
|
34
|
+
exportSchool.position = position;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return exportSchool;
|
|
40
|
+
};
|
|
41
|
+
const mapAddressPointForExport = (addressPoint) => {
|
|
42
|
+
return {
|
|
43
|
+
address: addressPoint.address,
|
|
44
|
+
lat: addressPoint.lat,
|
|
45
|
+
lng: addressPoint.lng,
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
const mapSchoolForExport = (school) => ({
|
|
49
|
+
name: school.name,
|
|
50
|
+
izo: school.izo,
|
|
51
|
+
addresses: school.addresses,
|
|
52
|
+
position: mapAddressPointForExport(school.position),
|
|
53
|
+
});
|
|
54
|
+
const cleanLine = (line) => {
|
|
55
|
+
return line.trim().replace(/–/g, "-");
|
|
56
|
+
};
|
|
57
|
+
export const parseOrdinanceToAddressPoints = (lines, options = {}) => {
|
|
58
|
+
const readyOptions = prepareOptions(options);
|
|
59
|
+
setDbConfig({
|
|
60
|
+
filePath: readyOptions.dbFilePath,
|
|
61
|
+
initFilePath: readyOptions.dbInitFilePath,
|
|
62
|
+
});
|
|
63
|
+
let errorCount = 0;
|
|
64
|
+
const errorLines = [];
|
|
65
|
+
let warningCount = 0;
|
|
66
|
+
let lineNumber = 1;
|
|
67
|
+
let municipalities = [];
|
|
68
|
+
let currentMunicipality = null;
|
|
69
|
+
let currentFilterMunicipality = null;
|
|
70
|
+
let currentSchool = null;
|
|
71
|
+
const reportErrors = (line, errors) => {
|
|
72
|
+
errors.forEach(console.error);
|
|
73
|
+
console.error(`Invalid street definition on line ${lineNumber}: ${line}`);
|
|
74
|
+
errorCount++;
|
|
75
|
+
errorLines.push(`line ${lineNumber}: ${line}`);
|
|
76
|
+
};
|
|
77
|
+
lines.forEach((rawLine) => {
|
|
78
|
+
let line = cleanLine(rawLine);
|
|
79
|
+
if (line[0] === "#") {
|
|
80
|
+
// a new municipality
|
|
81
|
+
if (currentSchool !== null) {
|
|
82
|
+
currentMunicipality.schools.push(currentSchool);
|
|
83
|
+
currentSchool = null;
|
|
84
|
+
}
|
|
85
|
+
if (currentMunicipality !== null) {
|
|
86
|
+
municipalities.push(convertMunicipality(currentMunicipality));
|
|
87
|
+
}
|
|
88
|
+
currentMunicipality = getNewMunicipality(line.substring(1).trim());
|
|
89
|
+
currentFilterMunicipality = founderToMunicipality(currentMunicipality.founder);
|
|
90
|
+
currentSchool = null;
|
|
91
|
+
}
|
|
92
|
+
else if (line === "") {
|
|
93
|
+
// empty line (end of school)
|
|
94
|
+
if (currentSchool !== null) {
|
|
95
|
+
currentMunicipality.schools.push(currentSchool);
|
|
96
|
+
currentSchool = null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
if (currentSchool === null) {
|
|
101
|
+
if (currentMunicipality === null) {
|
|
102
|
+
throw new Error("No municipality defined on line " + lineNumber);
|
|
103
|
+
}
|
|
104
|
+
currentSchool = getNewSchool(line, currentMunicipality.founder);
|
|
105
|
+
currentFilterMunicipality = founderToMunicipality(currentMunicipality.founder);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
if (line[0] !== "!") {
|
|
109
|
+
if (isMunicipalitySwitch(line)) {
|
|
110
|
+
const { municipality, errors } = getSwitchMunicipality(line);
|
|
111
|
+
if (errors.length > 0) {
|
|
112
|
+
reportErrors(line, errors);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
currentFilterMunicipality = municipality;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else if (isWholeMunicipality(line)) {
|
|
119
|
+
const { municipality, errors } = getWholeMunicipality(line);
|
|
120
|
+
if (errors.length > 0) {
|
|
121
|
+
reportErrors(line, errors);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
const addressPoints = findAddressPoints({ wholeMunicipality: true, street: "", numberSpec: [] }, municipality);
|
|
125
|
+
currentSchool.addresses.push(...filterOutSchoolAddressPoint(addressPoints, currentSchool).map(mapAddressPointForExport));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
// address point
|
|
130
|
+
const { smdLines, errors } = parseLine(line);
|
|
131
|
+
if (errors.length > 0) {
|
|
132
|
+
reportErrors(line, errors);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
smdLines.forEach((smdLine) => {
|
|
136
|
+
const { exists, errors } = checkStreetExists(smdLine.street, currentMunicipality.founder);
|
|
137
|
+
if (errors.length > 0) {
|
|
138
|
+
errors.map((error) => {
|
|
139
|
+
console.error(`Line ${lineNumber}: ${error}`);
|
|
140
|
+
});
|
|
141
|
+
warningCount++;
|
|
142
|
+
}
|
|
143
|
+
if (exists) {
|
|
144
|
+
let addressPoints = findAddressPoints(smdLine, currentFilterMunicipality);
|
|
145
|
+
currentSchool.addresses.push(...filterOutSchoolAddressPoint(addressPoints, currentSchool).map(mapAddressPointForExport));
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
lineNumber++;
|
|
154
|
+
});
|
|
155
|
+
if (currentSchool != null) {
|
|
156
|
+
if (currentMunicipality == null) {
|
|
157
|
+
currentMunicipality = getNewMunicipality("");
|
|
158
|
+
}
|
|
159
|
+
currentMunicipality.schools.push(mapSchoolForExport(currentSchool));
|
|
160
|
+
}
|
|
161
|
+
if (currentMunicipality != null) {
|
|
162
|
+
municipalities.push(convertMunicipality(currentMunicipality));
|
|
163
|
+
}
|
|
164
|
+
console.log(`Parsed ${lineNumber} lines, ${errorCount} errors, ${warningCount} warnings.`);
|
|
165
|
+
if (errorCount > 0) {
|
|
166
|
+
console.log("Errors:");
|
|
167
|
+
errorLines.forEach((line) => console.log(line));
|
|
168
|
+
}
|
|
169
|
+
return municipalities;
|
|
170
|
+
};
|
|
171
|
+
const filterOutSchoolAddressPoint = (addressPoints, school) => {
|
|
172
|
+
const schoolPosition = school.position;
|
|
173
|
+
return schoolPosition && isAddressPoint(schoolPosition)
|
|
174
|
+
? (addressPoints = addressPoints.filter((ap) => ap.id !== schoolPosition.id))
|
|
175
|
+
: addressPoints;
|
|
176
|
+
};
|
|
177
|
+
export const convertMunicipality = (municipality) => {
|
|
178
|
+
return {
|
|
179
|
+
municipalityName: municipality.municipalityName,
|
|
180
|
+
schools: municipality.schools,
|
|
181
|
+
};
|
|
182
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TokenVocabulary } from "chevrotain";
|
|
2
|
+
export declare const resetTokenState: () => void;
|
|
3
|
+
export declare const prepareLine: (text: string) => string;
|
|
4
|
+
export declare const streetNameMatcher: (text: string, startOffset: number) => RegExpExecArray | [string] | null;
|
|
5
|
+
declare const MainSeparator: import("chevrotain").TokenType;
|
|
6
|
+
declare const From: import("chevrotain").TokenType;
|
|
7
|
+
declare const To: import("chevrotain").TokenType;
|
|
8
|
+
declare const AndAbove: import("chevrotain").TokenType;
|
|
9
|
+
declare const AndBelow: import("chevrotain").TokenType;
|
|
10
|
+
declare const Separator: import("chevrotain").TokenType;
|
|
11
|
+
declare const DescriptiveType: import("chevrotain").TokenType;
|
|
12
|
+
declare const AllType: import("chevrotain").TokenType;
|
|
13
|
+
declare const OddType: import("chevrotain").TokenType;
|
|
14
|
+
declare const EvenType: import("chevrotain").TokenType;
|
|
15
|
+
declare const Without: import("chevrotain").TokenType;
|
|
16
|
+
declare const StreetName: import("chevrotain").TokenType;
|
|
17
|
+
declare const Number: import("chevrotain").TokenType;
|
|
18
|
+
declare const Hyphen: import("chevrotain").TokenType;
|
|
19
|
+
declare const Slash: import("chevrotain").TokenType;
|
|
20
|
+
declare const Space: import("chevrotain").TokenType;
|
|
21
|
+
declare const smdTokens: import("chevrotain").TokenType[];
|
|
22
|
+
declare const tokenVocabulary: TokenVocabulary;
|
|
23
|
+
export { MainSeparator, Separator, OddType, EvenType, DescriptiveType, AllType, Number, From, To, AndAbove, AndBelow, Without, Hyphen, Slash, Space, StreetName, smdTokens, tokenVocabulary, };
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { createToken, Lexer } from "chevrotain";
|
|
2
|
+
let streetNameWasMatched = false;
|
|
3
|
+
export const resetTokenState = () => {
|
|
4
|
+
streetNameWasMatched = false;
|
|
5
|
+
};
|
|
6
|
+
export const prepareLine = (text) => {
|
|
7
|
+
return text
|
|
8
|
+
.replace(/([IVXLCDM]+) - ([IVXLCDM]+)/, "$1-$2")
|
|
9
|
+
.replace(/;/g, ",")
|
|
10
|
+
.replace(/,$/, "");
|
|
11
|
+
};
|
|
12
|
+
const tokenBlockerFactory = (pattern) => {
|
|
13
|
+
const stickyPattern = new RegExp(pattern, "y");
|
|
14
|
+
return (text, startOffset) => {
|
|
15
|
+
if (streetNameWasMatched) {
|
|
16
|
+
stickyPattern.lastIndex = startOffset;
|
|
17
|
+
return stickyPattern.exec(text);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
const interruptPatterns = [
|
|
25
|
+
"lichá",
|
|
26
|
+
"sudá",
|
|
27
|
+
"č.",
|
|
28
|
+
"od",
|
|
29
|
+
"do",
|
|
30
|
+
"pouze",
|
|
31
|
+
"všechna",
|
|
32
|
+
"bez",
|
|
33
|
+
"vyjma",
|
|
34
|
+
"mimo",
|
|
35
|
+
"s výjimkou",
|
|
36
|
+
"kromě",
|
|
37
|
+
];
|
|
38
|
+
const streetNamePattern = /[^ -]+([ -]?[^ -]+)*/;
|
|
39
|
+
export const streetNameMatcher = (text, startOffset) => {
|
|
40
|
+
if (streetNameWasMatched || startOffset > 0) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const result = streetNamePattern.exec(text);
|
|
45
|
+
if (result !== null) {
|
|
46
|
+
streetNameWasMatched = true;
|
|
47
|
+
const firstIndex = interruptPatterns.reduce((currentMin, pattern) => {
|
|
48
|
+
const index = text.search(new RegExp(` ${pattern}( |$)`));
|
|
49
|
+
return index >= 0 ? Math.min(index, currentMin) : currentMin;
|
|
50
|
+
}, Infinity);
|
|
51
|
+
if (firstIndex < Infinity) {
|
|
52
|
+
return [result[0].substring(0, firstIndex).trim()];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const MainSeparator = createToken({ name: "MainSeparator", pattern: / - / });
|
|
59
|
+
const From = createToken({ name: "From", pattern: /od/ });
|
|
60
|
+
const To = createToken({ name: "To", pattern: /do/ });
|
|
61
|
+
const AndAbove = createToken({
|
|
62
|
+
name: "AndAbove",
|
|
63
|
+
pattern: / (a )?(výše?|vyšší)/,
|
|
64
|
+
});
|
|
65
|
+
const AndBelow = createToken({
|
|
66
|
+
name: "AndBelow",
|
|
67
|
+
pattern: / a (níže?|nižší)/,
|
|
68
|
+
});
|
|
69
|
+
const Separator = createToken({
|
|
70
|
+
name: "Separator",
|
|
71
|
+
pattern: /,| a /,
|
|
72
|
+
longer_alt: [AndAbove, AndBelow],
|
|
73
|
+
});
|
|
74
|
+
const DescriptiveType = createToken({
|
|
75
|
+
name: "CPType",
|
|
76
|
+
pattern: /(pouze |všechna )?č. ?p./,
|
|
77
|
+
});
|
|
78
|
+
const AllType = createToken({
|
|
79
|
+
name: "AllType",
|
|
80
|
+
pattern: /(pouze |všechna )?(č(\.|ísla)( ?o\.)?|lichá i sudá)/,
|
|
81
|
+
longer_alt: DescriptiveType,
|
|
82
|
+
});
|
|
83
|
+
const OddType = createToken({
|
|
84
|
+
name: "OddType",
|
|
85
|
+
pattern: /(pouze |všechna )?(lich([áé]|ých)( č(\.|ísla))?( ?o\.)?|č(\.|ísla)( ?o\.)? lich[áé])/,
|
|
86
|
+
longer_alt: AllType,
|
|
87
|
+
});
|
|
88
|
+
const EvenType = createToken({
|
|
89
|
+
name: "EvenType",
|
|
90
|
+
pattern: /(pouze |všechna )?(sud([áé]|ých)( č(\.|ísla))?( ?o\.)?|č(\.|ísla)( ?o\.)? sud[áé])/,
|
|
91
|
+
});
|
|
92
|
+
const Without = createToken({
|
|
93
|
+
name: "Without",
|
|
94
|
+
pattern: /bez|vyjma|mimo|s výjimkou|kromě/,
|
|
95
|
+
});
|
|
96
|
+
const StreetName = createToken({
|
|
97
|
+
name: "StreetName",
|
|
98
|
+
pattern: streetNameMatcher,
|
|
99
|
+
});
|
|
100
|
+
const Number = createToken({
|
|
101
|
+
name: "Number",
|
|
102
|
+
pattern: tokenBlockerFactory(/\d+[a-zA-Z]?/),
|
|
103
|
+
});
|
|
104
|
+
const Hyphen = createToken({ name: "Hyphen", pattern: /-|až/ });
|
|
105
|
+
const Slash = createToken({ name: "Hyphen", pattern: /\// });
|
|
106
|
+
const Space = createToken({
|
|
107
|
+
name: "Space",
|
|
108
|
+
pattern: / +/,
|
|
109
|
+
longer_alt: [MainSeparator, Separator],
|
|
110
|
+
group: Lexer.SKIPPED,
|
|
111
|
+
});
|
|
112
|
+
const Colon = createToken({
|
|
113
|
+
name: "Colon",
|
|
114
|
+
pattern: /:/,
|
|
115
|
+
group: Lexer.SKIPPED,
|
|
116
|
+
});
|
|
117
|
+
const smdTokens = [
|
|
118
|
+
MainSeparator,
|
|
119
|
+
Separator,
|
|
120
|
+
OddType,
|
|
121
|
+
EvenType,
|
|
122
|
+
DescriptiveType,
|
|
123
|
+
AllType,
|
|
124
|
+
Number,
|
|
125
|
+
From,
|
|
126
|
+
To,
|
|
127
|
+
AndAbove,
|
|
128
|
+
AndBelow,
|
|
129
|
+
Without,
|
|
130
|
+
Hyphen,
|
|
131
|
+
Slash,
|
|
132
|
+
Space,
|
|
133
|
+
Colon,
|
|
134
|
+
StreetName,
|
|
135
|
+
];
|
|
136
|
+
MainSeparator.LABEL = "' - '";
|
|
137
|
+
Separator.LABEL = "','";
|
|
138
|
+
Hyphen.LABEL = "'-'";
|
|
139
|
+
Slash.LABEL = "'/'";
|
|
140
|
+
From.LABEL = "'od'";
|
|
141
|
+
To.LABEL = "'do'";
|
|
142
|
+
AndAbove.LABEL = "'a výše'";
|
|
143
|
+
AndBelow.LABEL = "'a níže'";
|
|
144
|
+
Space.LABEL = "' '";
|
|
145
|
+
OddType.LABEL = "'lichá č.'";
|
|
146
|
+
EvenType.LABEL = "'sudá č.'";
|
|
147
|
+
DescriptiveType.LABEL = "'č. p.'";
|
|
148
|
+
AllType.LABEL = "'č.'";
|
|
149
|
+
Without.LABEL = "'bez'";
|
|
150
|
+
const tokenVocabulary = {};
|
|
151
|
+
smdTokens.forEach((tokenType) => {
|
|
152
|
+
tokenVocabulary[tokenType.name] = tokenType;
|
|
153
|
+
});
|
|
154
|
+
export { MainSeparator, Separator, OddType, EvenType, DescriptiveType, AllType, Number, From, To, AndAbove, AndBelow, Without, Hyphen, Slash, Space, StreetName, smdTokens, tokenVocabulary, };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Municipality as DbMunicipality } from "../db/types";
|
|
2
|
+
export interface ProcessedSmdLines {
|
|
3
|
+
smdLines: SmdLine[];
|
|
4
|
+
errors: string[];
|
|
5
|
+
}
|
|
6
|
+
export interface SmdLine {
|
|
7
|
+
street: string;
|
|
8
|
+
numberSpec: SeriesSpec[] | NegativeSeriesSpec;
|
|
9
|
+
}
|
|
10
|
+
export interface WholeMunicipalitySmdLine extends SmdLine {
|
|
11
|
+
wholeMunicipality: true;
|
|
12
|
+
street: string;
|
|
13
|
+
numberSpec: SeriesSpec[] | NegativeSeriesSpec;
|
|
14
|
+
}
|
|
15
|
+
export declare const isWholeMunicipalitySmdLine: (something: SmdLine | WholeMunicipalitySmdLine) => something is WholeMunicipalitySmdLine;
|
|
16
|
+
export interface SeriesSpec {
|
|
17
|
+
type: SeriesType;
|
|
18
|
+
ranges: (RangeSpec | FullStreetNumber)[];
|
|
19
|
+
}
|
|
20
|
+
export interface NegativeSeriesSpec extends SeriesSpec {
|
|
21
|
+
negative: true;
|
|
22
|
+
}
|
|
23
|
+
export declare const isSeriesSpecArray: (something: SeriesSpec[] | NegativeSeriesSpec) => something is SeriesSpec[];
|
|
24
|
+
export declare const isNegativeSeriesSpec: (something: SeriesSpec[] | NegativeSeriesSpec) => something is SeriesSpec[];
|
|
25
|
+
export interface RangeSpec {
|
|
26
|
+
from?: RichNumber;
|
|
27
|
+
to?: RichNumber;
|
|
28
|
+
}
|
|
29
|
+
export interface RichNumber {
|
|
30
|
+
number: number;
|
|
31
|
+
letter?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface FullStreetNumber {
|
|
34
|
+
descriptiveNumber: RichNumber;
|
|
35
|
+
orientationalNumber: RichNumber;
|
|
36
|
+
}
|
|
37
|
+
export declare const isFullStreetNumber: (something: RangeSpec | FullStreetNumber) => something is FullStreetNumber;
|
|
38
|
+
export declare const isRange: (something: RangeSpec | FullStreetNumber) => something is RangeSpec;
|
|
39
|
+
export declare enum SeriesType {
|
|
40
|
+
Even = 0,
|
|
41
|
+
Odd = 1,
|
|
42
|
+
All = 2,
|
|
43
|
+
Descriptive = 3
|
|
44
|
+
}
|
|
45
|
+
export declare enum AddressPointType {
|
|
46
|
+
Descriptive = 0,
|
|
47
|
+
Registration = 1
|
|
48
|
+
}
|
|
49
|
+
export interface AddressPoint {
|
|
50
|
+
id: number;
|
|
51
|
+
address: string;
|
|
52
|
+
type: AddressPointType;
|
|
53
|
+
street?: string;
|
|
54
|
+
descriptiveNumber: number;
|
|
55
|
+
orientationalNumber?: number;
|
|
56
|
+
orientationalNumberLetter?: string;
|
|
57
|
+
postalCode: string;
|
|
58
|
+
city: string;
|
|
59
|
+
district?: string;
|
|
60
|
+
municipalityPart?: string;
|
|
61
|
+
lat: number;
|
|
62
|
+
lng: number;
|
|
63
|
+
}
|
|
64
|
+
export interface ExportAddressPoint {
|
|
65
|
+
address: string;
|
|
66
|
+
lat: number;
|
|
67
|
+
lng: number;
|
|
68
|
+
}
|
|
69
|
+
export declare const isAddressPoint: (something: AddressPoint | ExportAddressPoint) => something is AddressPoint;
|
|
70
|
+
export interface School {
|
|
71
|
+
name: string;
|
|
72
|
+
izo: string;
|
|
73
|
+
position?: AddressPoint | ExportAddressPoint;
|
|
74
|
+
addresses: ExportAddressPoint[];
|
|
75
|
+
}
|
|
76
|
+
export interface Municipality {
|
|
77
|
+
municipalityName: string;
|
|
78
|
+
schools: School[];
|
|
79
|
+
}
|
|
80
|
+
export interface DbMunicipalityResult {
|
|
81
|
+
municipality: DbMunicipality;
|
|
82
|
+
errors: string[];
|
|
83
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const isWholeMunicipalitySmdLine = (something) => something.hasOwnProperty("wholeMunicipality");
|
|
2
|
+
export const isSeriesSpecArray = (something) => Array.isArray(something);
|
|
3
|
+
export const isNegativeSeriesSpec = (something) => something.hasOwnProperty("negative");
|
|
4
|
+
export const isFullStreetNumber = (something) => something.hasOwnProperty("orientationNumber");
|
|
5
|
+
export const isRange = (something) => !something.hasOwnProperty("orientationNumber");
|
|
6
|
+
export var SeriesType;
|
|
7
|
+
(function (SeriesType) {
|
|
8
|
+
SeriesType[SeriesType["Even"] = 0] = "Even";
|
|
9
|
+
SeriesType[SeriesType["Odd"] = 1] = "Odd";
|
|
10
|
+
SeriesType[SeriesType["All"] = 2] = "All";
|
|
11
|
+
SeriesType[SeriesType["Descriptive"] = 3] = "Descriptive";
|
|
12
|
+
})(SeriesType || (SeriesType = {}));
|
|
13
|
+
export var AddressPointType;
|
|
14
|
+
(function (AddressPointType) {
|
|
15
|
+
AddressPointType[AddressPointType["Descriptive"] = 0] = "Descriptive";
|
|
16
|
+
AddressPointType[AddressPointType["Registration"] = 1] = "Registration";
|
|
17
|
+
})(AddressPointType || (AddressPointType = {}));
|
|
18
|
+
export const isAddressPoint = (something) => something.hasOwnProperty("id");
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AddressPoint } from "../street-markdown/types";
|
|
2
|
+
export interface ThreeRowsAddress {
|
|
3
|
+
firstRow: string;
|
|
4
|
+
secondRow: string;
|
|
5
|
+
thirdRow: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const buildInline: (address: AddressPoint) => string;
|
|
8
|
+
export declare const build: (address: AddressPoint) => ThreeRowsAddress;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Taken from https://github.com/letomas/RUIAN-search and rewritten to typescript.
|
|
3
|
+
|
|
4
|
+
MIT License
|
|
5
|
+
|
|
6
|
+
Copyright (c) 2020 Tomáš Le
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
in the Software without restriction, including without limitation the rights
|
|
11
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
furnished to do so, subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included in all
|
|
16
|
+
copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
SOFTWARE.
|
|
25
|
+
*/
|
|
26
|
+
import { AddressPointType } from "../street-markdown/types";
|
|
27
|
+
export const buildInline = (address) => {
|
|
28
|
+
const addressInRows = build(address);
|
|
29
|
+
let result = addressInRows.firstRow + ", " + addressInRows.secondRow;
|
|
30
|
+
if (addressInRows.thirdRow) {
|
|
31
|
+
result += ", " + addressInRows.thirdRow;
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
export const build = (address) => {
|
|
36
|
+
const result = {
|
|
37
|
+
firstRow: "",
|
|
38
|
+
secondRow: "",
|
|
39
|
+
thirdRow: "",
|
|
40
|
+
};
|
|
41
|
+
if (!!address.street && !districtEqualsCity(address)) {
|
|
42
|
+
result.secondRow = address.district;
|
|
43
|
+
}
|
|
44
|
+
if (!address.street) {
|
|
45
|
+
if (address.city === address.district) {
|
|
46
|
+
let buildingType = address.type === AddressPointType.Registration ? " č. ev. " : "č. p. ";
|
|
47
|
+
result.firstRow = buildingType + address.descriptiveNumber;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
result.firstRow = address.district;
|
|
51
|
+
result.firstRow += " " + buildHouseNumber(address);
|
|
52
|
+
}
|
|
53
|
+
result.firstRow += buildOrientationalNumber(address);
|
|
54
|
+
buildLastRow(result, address);
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
result.firstRow = address.street;
|
|
58
|
+
result.firstRow += " " + buildHouseNumber(address);
|
|
59
|
+
result.firstRow += buildOrientationalNumber(address);
|
|
60
|
+
buildLastRow(result, address);
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
const buildHouseNumber = (address) => {
|
|
64
|
+
if (address.type === AddressPointType.Registration) {
|
|
65
|
+
return "č. ev. " + address.descriptiveNumber;
|
|
66
|
+
}
|
|
67
|
+
return address.descriptiveNumber;
|
|
68
|
+
};
|
|
69
|
+
const buildOrientationalNumber = (address) => {
|
|
70
|
+
var _a;
|
|
71
|
+
if (address.orientationalNumber) {
|
|
72
|
+
return ("/" +
|
|
73
|
+
address.orientationalNumber +
|
|
74
|
+
((_a = address.orientationalNumberLetter) !== null && _a !== void 0 ? _a : ""));
|
|
75
|
+
}
|
|
76
|
+
return "";
|
|
77
|
+
};
|
|
78
|
+
const buildLastRow = (result, address) => {
|
|
79
|
+
// if (!result.secondRow) {
|
|
80
|
+
// if (address.city === "Praha") {
|
|
81
|
+
// result.secondRow = address.postalCode + " " + address.pragueBoroughName;
|
|
82
|
+
// } else {
|
|
83
|
+
// result.secondRow = address.postalCode + " " + address.cityName;
|
|
84
|
+
// }
|
|
85
|
+
// } else {
|
|
86
|
+
// if (address.cityName === "Praha") {
|
|
87
|
+
// result.thirdRow = address.postalCode + " " + address.pragueBoroughName;
|
|
88
|
+
// } else {
|
|
89
|
+
// result.thirdRow = address.postalCode + " " + address.cityName;
|
|
90
|
+
// }
|
|
91
|
+
// }
|
|
92
|
+
if (!result.secondRow) {
|
|
93
|
+
result.secondRow = address.postalCode + " " + address.city;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
result.thirdRow = address.postalCode + " " + address.city;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const districtEqualsCity = (address) => {
|
|
100
|
+
return address.district === address.city;
|
|
101
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
};
|
|
10
|
+
import FeedParser from "feedparser";
|
|
11
|
+
import fetch from "node-fetch";
|
|
12
|
+
import { pipeline } from "stream/promises";
|
|
13
|
+
export const getLatestUrlFromAtomFeed = (atomFeedUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
|
+
const response = yield fetch(atomFeedUrl);
|
|
15
|
+
const feedparser = new FeedParser({});
|
|
16
|
+
let link = null;
|
|
17
|
+
if (response.status !== 200) {
|
|
18
|
+
throw new Error(`The Atom feed from atom.cuzk.cz not working. HTTP status ${response.status}`);
|
|
19
|
+
}
|
|
20
|
+
feedparser.on("error", (error) => {
|
|
21
|
+
throw new Error(`The Atom feed from atom.cuzk.cz could not be loaded.`);
|
|
22
|
+
});
|
|
23
|
+
feedparser.on("readable", function () {
|
|
24
|
+
let item;
|
|
25
|
+
let maxDate = new Date();
|
|
26
|
+
maxDate.setFullYear(1990);
|
|
27
|
+
while ((item = this.read())) {
|
|
28
|
+
if (item.date > maxDate) {
|
|
29
|
+
maxDate = item.date;
|
|
30
|
+
link = item.link;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
yield pipeline(response.body, feedparser);
|
|
35
|
+
if (link != null) {
|
|
36
|
+
return link;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
throw new Error("Could not find any dataset feed link.");
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
export const getAllUrlsFromAtomFeed = (atomFeedUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
const response = yield fetch(atomFeedUrl);
|
|
44
|
+
const feedparser = new FeedParser({});
|
|
45
|
+
const links = [];
|
|
46
|
+
if (response.status !== 200) {
|
|
47
|
+
throw new Error(`The Atom feed from atom.cuzk.cz not working. HTTP status ${response.status}`);
|
|
48
|
+
}
|
|
49
|
+
feedparser.on("error", (error) => {
|
|
50
|
+
throw new Error(`The Atom feed from atom.cuzk.cz could not be loaded.`);
|
|
51
|
+
});
|
|
52
|
+
feedparser.on("readable", function () {
|
|
53
|
+
let item;
|
|
54
|
+
while ((item = this.read())) {
|
|
55
|
+
links.push(item.link);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
yield pipeline(response.body, feedparser);
|
|
59
|
+
if (links.length > 0) {
|
|
60
|
+
return links;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
throw new Error("Could not find any dataset feed link.");
|
|
64
|
+
}
|
|
65
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Founder } from "../db/types";
|
|
2
|
+
export interface OpenDataSyncOptions {
|
|
3
|
+
tmpDir?: string;
|
|
4
|
+
dataDir?: string;
|
|
5
|
+
dbFilePath?: string;
|
|
6
|
+
dbInitFilePath?: string;
|
|
7
|
+
addressPointsAtomUrl?: string;
|
|
8
|
+
addressPointsZipFileName?: string;
|
|
9
|
+
addressPointsCsvFolderName?: string;
|
|
10
|
+
streetsAtomUrl?: string;
|
|
11
|
+
streetZipFolderName?: string;
|
|
12
|
+
streetDbfFileName?: string;
|
|
13
|
+
schoolsXmlUrl?: string;
|
|
14
|
+
schoolsXmlFileName?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface OpenDataSyncOptionsNotEmpty {
|
|
17
|
+
tmpDir: string;
|
|
18
|
+
dataDir: string;
|
|
19
|
+
dbFilePath: string;
|
|
20
|
+
dbInitFilePath: string;
|
|
21
|
+
addressPointsAtomUrl: string;
|
|
22
|
+
addressPointsZipFileName: string;
|
|
23
|
+
addressPointsCsvFolderName: string;
|
|
24
|
+
streetsAtomUrl: string;
|
|
25
|
+
streetFolderName: string;
|
|
26
|
+
streetDbfFileName: string;
|
|
27
|
+
schoolsXmlUrl: string;
|
|
28
|
+
schoolsXmlFileName: string;
|
|
29
|
+
}
|
|
30
|
+
export declare const getAppDataDirPath: () => string;
|
|
31
|
+
export declare const prepareOptions: (options: OpenDataSyncOptions) => OpenDataSyncOptionsNotEmpty;
|
|
32
|
+
export declare const initDb: (options: OpenDataSyncOptionsNotEmpty) => void;
|
|
33
|
+
export declare const extractMunicipalityName: (founder: Founder) => string;
|
|
34
|
+
export declare const findClosestString: (str: string, arr: string[]) => string;
|