text-to-map 1.0.8 → 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 +55 -42
- package/dist/bin/schools.js +1 -1
- package/dist/db/address-points.d.ts +11 -11
- package/dist/db/address-points.js +88 -76
- package/dist/db/db.d.ts +19 -10
- package/dist/db/db.js +124 -52
- package/dist/db/founders.d.ts +6 -6
- package/dist/db/founders.js +165 -134
- 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 +1 -1
- package/dist/db/schools.js +24 -12
- 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 +18 -9
- package/dist/street-markdown/smd-line-parser.js +8 -5
- package/dist/street-markdown/smd.d.ts +4 -5
- package/dist/street-markdown/smd.js +72 -78
- package/dist/utils/helpers.d.ts +0 -1
- package/dist/utils/helpers.js +1 -8
- package/package.json +9 -5
package/dist/db/db.js
CHANGED
|
@@ -1,32 +1,108 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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 { configDotenv } from "dotenv";
|
|
11
|
+
import knex from "knex";
|
|
3
12
|
import { dirname, join } from "path";
|
|
4
13
|
import { fileURLToPath } from "url";
|
|
5
|
-
let _db;
|
|
6
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
7
15
|
const __dirname = dirname(__filename);
|
|
16
|
+
export var SupportedDbType;
|
|
17
|
+
(function (SupportedDbType) {
|
|
18
|
+
SupportedDbType["sqlite"] = "sqlite";
|
|
19
|
+
SupportedDbType["postgres"] = "postgres";
|
|
20
|
+
})(SupportedDbType || (SupportedDbType = {}));
|
|
8
21
|
const defaults = {
|
|
22
|
+
dbType: SupportedDbType.sqlite,
|
|
9
23
|
filePath: "address_points.db",
|
|
10
24
|
initFilePath: join(__dirname, "..", "address_points_init.db"),
|
|
11
25
|
verbose: false,
|
|
12
26
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
27
|
+
let _knexDb = undefined;
|
|
28
|
+
let _knexDbConfig = undefined;
|
|
29
|
+
export const getKnexDb = (config = {}) => {
|
|
30
|
+
if (_knexDb === undefined) {
|
|
31
|
+
_knexDbConfig = Object.assign(Object.assign(Object.assign({}, defaults), getEnvConfig()), config);
|
|
32
|
+
if (_knexDbConfig.dbType === SupportedDbType.sqlite) {
|
|
33
|
+
_knexDb = knex({
|
|
34
|
+
client: "better-sqlite3",
|
|
35
|
+
connection: {
|
|
36
|
+
filename: _knexDbConfig.filePath,
|
|
37
|
+
},
|
|
38
|
+
useNullAsDefault: true,
|
|
39
|
+
debug: _knexDbConfig.verbose,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
else if (_knexDbConfig.dbType === SupportedDbType.postgres) {
|
|
43
|
+
_knexDb = knex({
|
|
44
|
+
client: "pg",
|
|
45
|
+
connection: _knexDbConfig.pgConnectionString,
|
|
46
|
+
useNullAsDefault: true,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
throw new Error(`Unsupported DB type: ${_knexDbConfig.dbType}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return _knexDb;
|
|
54
|
+
};
|
|
55
|
+
export const isPostgres = () => {
|
|
56
|
+
return isDbType(SupportedDbType.postgres);
|
|
57
|
+
};
|
|
58
|
+
export const isSqlite = () => {
|
|
59
|
+
return isDbType(SupportedDbType.sqlite);
|
|
60
|
+
};
|
|
61
|
+
const isDbType = (type) => {
|
|
62
|
+
if (_knexDbConfig === undefined) {
|
|
63
|
+
throw new Error("DB not initialized");
|
|
64
|
+
}
|
|
65
|
+
return _knexDbConfig.dbType === type;
|
|
66
|
+
};
|
|
67
|
+
const getMigrationConfig = () => {
|
|
68
|
+
return { directory: join(__dirname, "migrations") };
|
|
16
69
|
};
|
|
17
|
-
export const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
70
|
+
export const initDb = (config = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
|
+
const knex = getKnexDb(config);
|
|
72
|
+
yield knex.migrate.latest(getMigrationConfig());
|
|
73
|
+
return knex;
|
|
74
|
+
});
|
|
75
|
+
export const clearDb = (config = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
76
|
+
const knex = getKnexDb(config);
|
|
77
|
+
yield knex.migrate.rollback(getMigrationConfig(), true);
|
|
78
|
+
yield knex.migrate.latest(getMigrationConfig());
|
|
79
|
+
return knex;
|
|
80
|
+
});
|
|
81
|
+
export const disconnectKnex = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
|
+
if (_knexDb) {
|
|
83
|
+
yield _knexDb.destroy();
|
|
84
|
+
_knexDb = undefined;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
const getEnvConfig = () => {
|
|
88
|
+
configDotenv({ path: ".env.local" });
|
|
89
|
+
const envConfig = {};
|
|
90
|
+
if (process.env.TEXTTOMAP_DB_TYPE &&
|
|
91
|
+
Object.values(SupportedDbType).includes(process.env.TEXTTOMAP_DB_TYPE)) {
|
|
92
|
+
envConfig.dbType = process.env.TEXTTOMAP_DB_TYPE;
|
|
93
|
+
if (envConfig.dbType === SupportedDbType.postgres) {
|
|
94
|
+
if (!process.env.TEXTTOMAP_PG_CONNECTION_STRING) {
|
|
95
|
+
throw new Error("Environmental variable 'TEXTTOMAP_PG_CONNECTION_STRING' must be set for PostgreSQL.");
|
|
96
|
+
}
|
|
97
|
+
envConfig.pgConnectionString = process.env.TEXTTOMAP_PG_CONNECTION_STRING;
|
|
98
|
+
}
|
|
99
|
+
else if (envConfig.dbType === SupportedDbType.sqlite) {
|
|
100
|
+
if (process.env.TEXTTOMAP_SQLITE_PATH) {
|
|
101
|
+
envConfig.filePath = process.env.TEXTTOMAP_SQLITE_PATH;
|
|
102
|
+
}
|
|
22
103
|
}
|
|
23
|
-
const dbSettings = options.verbose ? { verbose: console.log } : {};
|
|
24
|
-
_db = new Database(options.filePath, dbSettings);
|
|
25
|
-
_db.pragma("journal_mode = WAL");
|
|
26
|
-
// @ts-ignore
|
|
27
|
-
_db.filePath = options.filePath;
|
|
28
104
|
}
|
|
29
|
-
return
|
|
105
|
+
return envConfig;
|
|
30
106
|
};
|
|
31
107
|
export const nonEmptyOrNull = (value) => {
|
|
32
108
|
return value ? value : null;
|
|
@@ -35,50 +111,46 @@ export const nonEmptyOrNull = (value) => {
|
|
|
35
111
|
* Efficiently insert multiple rows. If preventDuplicatesByFirstColumn is true, the first
|
|
36
112
|
* column should be unique (PK or UNIQUE).
|
|
37
113
|
*/
|
|
38
|
-
export const insertMultipleRows = (rows, table, columnNames, preventDuplicatesByFirstColumn = true) => {
|
|
39
|
-
const db = getDb();
|
|
114
|
+
export const insertMultipleRows = (rows, table, columnNames, preventDuplicatesByFirstColumn = true) => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
115
|
if (rows.length === 0) {
|
|
41
116
|
return 0;
|
|
42
117
|
}
|
|
43
|
-
if (preventDuplicatesByFirstColumn) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
const insertPlaceholders =
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
118
|
+
// if (preventDuplicatesByFirstColumn) {
|
|
119
|
+
// rows = await clearDuplicates(rows, table, columnNames);
|
|
120
|
+
// if (rows.length === 0) {
|
|
121
|
+
// return 0;
|
|
122
|
+
// }
|
|
123
|
+
// }
|
|
124
|
+
const insertPlaceholders = generate2DPlaceholders(columnNames.length, rows.length);
|
|
125
|
+
const onConfict = preventDuplicatesByFirstColumn ? `ON CONFLICT (${columnNames[0]}) DO NOTHING` : '';
|
|
126
|
+
yield getKnexDb().raw(`INSERT INTO ${table} (${columnNames.join(",")}) VALUES ${insertPlaceholders} ${onConfict}`, rows.flat());
|
|
127
|
+
return rows.length;
|
|
128
|
+
});
|
|
53
129
|
/**
|
|
54
130
|
* Insert a single row and return the autoincremented ID.
|
|
55
131
|
*/
|
|
56
|
-
export const insertAutoincrementRow = (row, table, columnNames) => {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
132
|
+
export const insertAutoincrementRow = (row, table, columnNames) => __awaiter(void 0, void 0, void 0, function* () {
|
|
133
|
+
const data = columnNames.reduce((obj, columnName, index) => {
|
|
134
|
+
obj[columnName] = row[index];
|
|
135
|
+
return obj;
|
|
136
|
+
}, {});
|
|
137
|
+
const result = yield getKnexDb().insert(data).into(table);
|
|
138
|
+
return result ? Number(result) : null;
|
|
139
|
+
});
|
|
140
|
+
export const deleteMultipleRowsKnex = (keys, table, keyColumnName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
141
|
if (keys.length === 0) {
|
|
65
142
|
return;
|
|
66
143
|
}
|
|
67
|
-
|
|
68
|
-
};
|
|
69
|
-
export const clearDuplicates = (rows, table, columnNames) => {
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return rows.filter((row) => !existing.includes(row[0]));
|
|
78
|
-
};
|
|
79
|
-
export const disconnect = () => {
|
|
80
|
-
getDb().close();
|
|
81
|
-
};
|
|
144
|
+
yield getKnexDb().from(table).whereIn(keyColumnName, keys).del();
|
|
145
|
+
});
|
|
146
|
+
export const clearDuplicates = (rows, table, columnNames) => __awaiter(void 0, void 0, void 0, function* () {
|
|
147
|
+
const existing = yield getKnexDb()
|
|
148
|
+
.select(columnNames[0])
|
|
149
|
+
.from(table)
|
|
150
|
+
.whereIn(columnNames[0], rows.map((row) => row[0]));
|
|
151
|
+
const keys = existing.map((row) => row[columnNames[0]].toString());
|
|
152
|
+
return rows.filter((row) => !keys.includes(row[0]));
|
|
153
|
+
});
|
|
82
154
|
const generateRepetitiveString = (value, glue, n) => {
|
|
83
155
|
return new Array(n).fill(value).join(glue);
|
|
84
156
|
};
|
package/dist/db/founders.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Founder, MunicipalityType } from "./types";
|
|
2
1
|
import { DbMunicipalityResult, SmdError } from "../street-markdown/types";
|
|
3
|
-
|
|
4
|
-
export declare const
|
|
2
|
+
import { Founder, MunicipalityType } from "./types";
|
|
3
|
+
export declare const insertFounders: (founders: Founder[]) => Promise<number>;
|
|
4
|
+
export declare const findFounder: (nameWithHashtag: string) => Promise<{
|
|
5
5
|
founder: Founder;
|
|
6
6
|
errors: SmdError[];
|
|
7
|
-
}
|
|
8
|
-
export declare const getFounderCityCode: (founder: Founder) => number
|
|
9
|
-
export declare const findMunicipalityByNameAndType: (name: string, type: MunicipalityType) => DbMunicipalityResult
|
|
7
|
+
}>;
|
|
8
|
+
export declare const getFounderCityCode: (founder: Founder) => Promise<number>;
|
|
9
|
+
export declare const findMunicipalityByNameAndType: (name: string, type: MunicipalityType) => Promise<DbMunicipalityResult>;
|
package/dist/db/founders.js
CHANGED
|
@@ -1,40 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
+
};
|
|
4
10
|
import distance from "@turf/distance";
|
|
5
11
|
import { wholeLineError } from "../street-markdown/smd";
|
|
12
|
+
import { extractMunicipalityName, findClosestString, sanitizeMunicipalityName, } from "../utils/helpers";
|
|
13
|
+
import { getKnexDb, insertAutoincrementRow, insertMultipleRows } from "./db";
|
|
14
|
+
import { MunicipalityType, } from "./types";
|
|
6
15
|
const cityTypeCode = 261;
|
|
7
16
|
const cityDistrictTypeCode = 263;
|
|
8
|
-
export const insertFounders = (founders) => {
|
|
9
|
-
|
|
10
|
-
const selectCityStatement = db.prepare(`SELECT c.name, c.code FROM school s
|
|
11
|
-
JOIN school_location l ON s.izo = l.school_izo
|
|
12
|
-
JOIN address_point a ON l.address_point_id = a.id
|
|
13
|
-
JOIN city c ON a.city_code = c.code
|
|
14
|
-
WHERE s.izo = ?
|
|
15
|
-
LIMIT 1`);
|
|
16
|
-
const selectDistrictStatement = db.prepare(`SELECT d.name, d.code FROM school s
|
|
17
|
-
JOIN school_location l ON s.izo = l.school_izo
|
|
18
|
-
JOIN address_point a ON l.address_point_id = a.id
|
|
19
|
-
JOIN city_district d ON a.city_district_code = d.code
|
|
20
|
-
WHERE s.izo = ?
|
|
21
|
-
LIMIT 1`);
|
|
17
|
+
export const insertFounders = (founders) => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
+
var _a;
|
|
22
19
|
let insertedFounders = 0;
|
|
23
20
|
const schoolFounderConnectionData = [];
|
|
24
|
-
|
|
25
|
-
var _a;
|
|
21
|
+
for (const founder of founders) {
|
|
26
22
|
if (founder.municipalityType !== MunicipalityType.City &&
|
|
27
23
|
founder.municipalityType !== MunicipalityType.District) {
|
|
28
|
-
|
|
24
|
+
continue;
|
|
29
25
|
}
|
|
30
26
|
const extractedMunicipalityName = extractMunicipalityName(founder);
|
|
31
27
|
// check if the extracted municipality name is the same as in all the schools' locations
|
|
32
28
|
let differingSchools = [];
|
|
33
29
|
let municipalityCode = -1;
|
|
34
|
-
founder.schools
|
|
35
|
-
const result = (founder.municipalityType === MunicipalityType.City
|
|
36
|
-
?
|
|
37
|
-
:
|
|
30
|
+
for (const school of founder.schools) {
|
|
31
|
+
const result = yield (founder.municipalityType === MunicipalityType.City
|
|
32
|
+
? getCityOfSchool(school.izo)
|
|
33
|
+
: getDistrictOfSchool(school.izo));
|
|
38
34
|
if (!result) {
|
|
39
35
|
console.log(`izo: ${school.izo}, extracted: ${extractedMunicipalityName}, RUIAN: UNDEFINED`);
|
|
40
36
|
differingSchools.push(school);
|
|
@@ -48,8 +44,8 @@ export const insertFounders = (founders) => {
|
|
|
48
44
|
// store municipalityCode even if the names don't match, we will use it later
|
|
49
45
|
municipalityCode = parseInt(code);
|
|
50
46
|
}
|
|
51
|
-
}
|
|
52
|
-
municipalityCode = fixFounderProblems(founder, municipalityCode, differingSchools, extractedMunicipalityName);
|
|
47
|
+
}
|
|
48
|
+
municipalityCode = yield fixFounderProblems(founder, municipalityCode, differingSchools, extractedMunicipalityName);
|
|
53
49
|
const cityDistrictCode = founder.municipalityType === MunicipalityType.District
|
|
54
50
|
? municipalityCode.toString()
|
|
55
51
|
: null;
|
|
@@ -58,46 +54,80 @@ export const insertFounders = (founders) => {
|
|
|
58
54
|
cityCode = (_a = municipalityCode === null || municipalityCode === void 0 ? void 0 : municipalityCode.toString()) !== null && _a !== void 0 ? _a : null;
|
|
59
55
|
}
|
|
60
56
|
else {
|
|
61
|
-
cityCode = getCityCodeByDistrictCode(municipalityCode)
|
|
57
|
+
cityCode = yield getCityCodeByDistrictCode(municipalityCode);
|
|
62
58
|
}
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
59
|
+
const existing = yield getKnexDb()
|
|
60
|
+
.select("*")
|
|
61
|
+
.from("founder")
|
|
62
|
+
.where({
|
|
63
|
+
name: sanitizeMunicipalityName(founder.name),
|
|
64
|
+
ico: founder.ico,
|
|
65
|
+
});
|
|
66
|
+
if (existing.length === 0) {
|
|
67
|
+
const founderId = yield insertAutoincrementRow([
|
|
68
|
+
sanitizeMunicipalityName(founder.name),
|
|
69
|
+
sanitizeMunicipalityName(extractedMunicipalityName),
|
|
70
|
+
founder.ico,
|
|
71
|
+
String(founder.originalType),
|
|
72
|
+
cityCode,
|
|
73
|
+
cityDistrictCode,
|
|
74
|
+
], "founder", [
|
|
75
|
+
"name",
|
|
76
|
+
"short_name",
|
|
77
|
+
"ico",
|
|
78
|
+
"founder_type_code",
|
|
79
|
+
"city_code",
|
|
80
|
+
"city_district_code",
|
|
81
|
+
]);
|
|
74
82
|
insertedFounders++;
|
|
75
83
|
founder.schools.forEach((school) => {
|
|
76
84
|
schoolFounderConnectionData.push([school.izo, founderId]);
|
|
77
85
|
});
|
|
78
86
|
}
|
|
79
|
-
}
|
|
80
|
-
const insertedConnections = insertMultipleRows(schoolFounderConnectionData, "school_founder", ["school_izo", "founder_id"]);
|
|
87
|
+
}
|
|
88
|
+
const insertedConnections = yield insertMultipleRows(schoolFounderConnectionData, "school_founder", ["school_izo", "founder_id"]);
|
|
81
89
|
return insertedFounders + insertedConnections;
|
|
82
|
-
};
|
|
83
|
-
const
|
|
90
|
+
});
|
|
91
|
+
const getCityOfSchool = (izo) => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
+
return yield getKnexDb()
|
|
93
|
+
.select("c.name", "c.code")
|
|
94
|
+
.from("school as s")
|
|
95
|
+
.join("school_location as l", "s.izo", "l.school_izo")
|
|
96
|
+
.join("address_point as a", "l.address_point_id", "a.id")
|
|
97
|
+
.join("city as c", "a.city_code", "c.code")
|
|
98
|
+
.where("s.izo", izo)
|
|
99
|
+
.limit(1)
|
|
100
|
+
.first();
|
|
101
|
+
});
|
|
102
|
+
const getDistrictOfSchool = (izo) => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
|
+
return yield getKnexDb()
|
|
104
|
+
.select("d.name", "d.code")
|
|
105
|
+
.from("school as s")
|
|
106
|
+
.join("school_location as l", "s.izo", "l.school_izo")
|
|
107
|
+
.join("address_point as a", "l.address_point_id", "a.id")
|
|
108
|
+
.join("city_district as d", "a.city_district_code", "d.code")
|
|
109
|
+
.where("s.izo", izo)
|
|
110
|
+
.limit(1)
|
|
111
|
+
.first();
|
|
112
|
+
});
|
|
113
|
+
const fixFounderProblems = (founder, municipalityCode, differingSchools, extractedMunicipalityName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
84
114
|
if (differingSchools.length === 0 ||
|
|
85
115
|
differingSchools.length < founder.schools.length) {
|
|
86
116
|
return municipalityCode;
|
|
87
117
|
}
|
|
88
118
|
// either the school does not have a position (invalid RUIAN or missing building)
|
|
89
119
|
// or the school is not in the same municipality as the founder
|
|
90
|
-
const db = getDb();
|
|
91
120
|
// find all cities and their position with the same name as municipalityName
|
|
92
|
-
const municipalities = findMunicipalitiesAndPositionsByNameAndType(extractedMunicipalityName, founder.municipalityType);
|
|
121
|
+
const municipalities = yield findMunicipalitiesAndPositionsByNameAndType(extractedMunicipalityName, founder.municipalityType);
|
|
93
122
|
// get one school position (if there are more schools, they should be close to each other)
|
|
94
|
-
const schoolPosition =
|
|
95
|
-
.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
.
|
|
123
|
+
const schoolPosition = yield getKnexDb()
|
|
124
|
+
.select("address_point.wgs84_latitude", "address_point.wgs84_longitude")
|
|
125
|
+
.from("school")
|
|
126
|
+
.join("school_location", "school.izo", "school_location.school_izo")
|
|
127
|
+
.join("address_point", "school_location.address_point_id", "address_point.id")
|
|
128
|
+
.whereIn("school.izo", differingSchools.map((school) => school.izo))
|
|
129
|
+
.limit(1)
|
|
130
|
+
.first();
|
|
101
131
|
if (schoolPosition) {
|
|
102
132
|
if (municipalities.length === 0) {
|
|
103
133
|
if (municipalityCode === -1) {
|
|
@@ -142,43 +172,38 @@ const fixFounderProblems = (founder, municipalityCode, differingSchools, extract
|
|
|
142
172
|
return null;
|
|
143
173
|
}
|
|
144
174
|
}
|
|
145
|
-
};
|
|
146
|
-
const getCityCodeByDistrictCode = (districtCode) => {
|
|
147
|
-
|
|
148
|
-
const result =
|
|
149
|
-
.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
const findMunicipalitiesAndPositionsByNameAndType = (name, type) => {
|
|
162
|
-
const db = getDb();
|
|
175
|
+
});
|
|
176
|
+
const getCityCodeByDistrictCode = (districtCode) => __awaiter(void 0, void 0, void 0, function* () {
|
|
177
|
+
var _b;
|
|
178
|
+
const result = yield getKnexDb()
|
|
179
|
+
.first("city.code")
|
|
180
|
+
.from("city_district")
|
|
181
|
+
.join("city", "city_district.city_code", "city.code")
|
|
182
|
+
.where("city_district.code", districtCode)
|
|
183
|
+
.limit(1);
|
|
184
|
+
return (_b = result === null || result === void 0 ? void 0 : result.code) !== null && _b !== void 0 ? _b : null;
|
|
185
|
+
});
|
|
186
|
+
const findMunicipalitiesAndPositionsByNameAndType = (name, type) => __awaiter(void 0, void 0, void 0, function* () {
|
|
187
|
+
const knex = getKnexDb();
|
|
163
188
|
return (type === MunicipalityType.City
|
|
164
|
-
?
|
|
165
|
-
.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
.
|
|
170
|
-
:
|
|
171
|
-
.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
.
|
|
189
|
+
? yield knex
|
|
190
|
+
.select("city.name", "city.code", "address_point.wgs84_latitude", "address_point.wgs84_longitude")
|
|
191
|
+
.from("city")
|
|
192
|
+
.join("address_point", "city.code", "address_point.city_code")
|
|
193
|
+
.where("city.name", name)
|
|
194
|
+
.groupBy("city.code")
|
|
195
|
+
: yield knex
|
|
196
|
+
.select("city_district.name", "city_district.code", "address_point.wgs84_latitude", "address_point.wgs84_longitude")
|
|
197
|
+
.from("city_district")
|
|
198
|
+
.join("address_point", "city_district.code", "address_point.city_district_code")
|
|
199
|
+
.where("city_district.name", name)
|
|
200
|
+
.groupBy("city_district.code")).map((row) => ({
|
|
176
201
|
code: row.code,
|
|
177
202
|
type,
|
|
178
203
|
lat: row.wgs84_latitude,
|
|
179
204
|
lng: row.wgs84_longitude,
|
|
180
205
|
}));
|
|
181
|
-
};
|
|
206
|
+
});
|
|
182
207
|
const extractFounderName = (line) => {
|
|
183
208
|
if (line[0] === "#") {
|
|
184
209
|
return line.substring(1).trim();
|
|
@@ -187,20 +212,23 @@ const extractFounderName = (line) => {
|
|
|
187
212
|
return line.trim();
|
|
188
213
|
}
|
|
189
214
|
};
|
|
190
|
-
export const findFounder = (nameWithHashtag) => {
|
|
215
|
+
export const findFounder = (nameWithHashtag) => __awaiter(void 0, void 0, void 0, function* () {
|
|
191
216
|
const errors = [];
|
|
192
|
-
const db = getDb();
|
|
193
217
|
const name = extractFounderName(nameWithHashtag);
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
218
|
+
const result = yield getKnexDb()
|
|
219
|
+
.select("f.id", "f.name", "f.ico", "f.founder_type_code", "f.city_code", "f.city_district_code")
|
|
220
|
+
.from("founder as f")
|
|
221
|
+
.leftJoin("city as c", "c.code", "f.city_code")
|
|
222
|
+
.leftJoin("city_district as d", "d.code", "f.city_district_code")
|
|
223
|
+
.where("f.name", name)
|
|
224
|
+
.orWhere("c.name", name)
|
|
225
|
+
.orWhere("d.name", name)
|
|
226
|
+
.first();
|
|
199
227
|
if (result) {
|
|
200
|
-
return { founder: resultToFounder(result), errors };
|
|
228
|
+
return { founder: yield resultToFounder(result), errors };
|
|
201
229
|
}
|
|
202
230
|
else {
|
|
203
|
-
const allFounderNames = getAllFounderNames();
|
|
231
|
+
const allFounderNames = yield getAllFounderNames();
|
|
204
232
|
const namesList = allFounderNames
|
|
205
233
|
.map((row) => row.founderName)
|
|
206
234
|
.concat(allFounderNames.map((row) => row.municipalityName));
|
|
@@ -215,34 +243,36 @@ export const findFounder = (nameWithHashtag) => {
|
|
|
215
243
|
};
|
|
216
244
|
}
|
|
217
245
|
errors.push(wholeLineError(`Zřizovatel '${name}' neexistuje, mysleli jste '${bestMatch}'?`, nameWithHashtag));
|
|
218
|
-
const
|
|
219
|
-
|
|
246
|
+
const founder = yield getKnexDb()
|
|
247
|
+
.select("id", "name", "ico", "founder_type_code", "city_code", "city_district_code")
|
|
248
|
+
.from("founder")
|
|
249
|
+
.where("id", bestMatchRow.id)
|
|
250
|
+
.first();
|
|
220
251
|
return {
|
|
221
|
-
founder: resultToFounder(
|
|
252
|
+
founder: yield resultToFounder(founder),
|
|
222
253
|
errors,
|
|
223
254
|
};
|
|
224
255
|
}
|
|
225
|
-
};
|
|
256
|
+
});
|
|
226
257
|
let cachedCityCode = null;
|
|
227
258
|
let cityCodeFounder = null;
|
|
228
|
-
export const getFounderCityCode = (founder) => {
|
|
229
|
-
const db = getDb();
|
|
259
|
+
export const getFounderCityCode = (founder) => __awaiter(void 0, void 0, void 0, function* () {
|
|
230
260
|
if (founder.municipalityType === MunicipalityType.District) {
|
|
231
261
|
if (cityCodeFounder !== founder) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
262
|
+
cityCodeFounder = founder;
|
|
263
|
+
cachedCityCode = yield getKnexDb()
|
|
264
|
+
.pluck("city_code")
|
|
265
|
+
.from("city_district")
|
|
266
|
+
.where("code", founder.cityOrDistrictCode)
|
|
267
|
+
.first();
|
|
238
268
|
}
|
|
239
269
|
return cachedCityCode;
|
|
240
270
|
}
|
|
241
271
|
else {
|
|
242
272
|
return founder.cityOrDistrictCode;
|
|
243
273
|
}
|
|
244
|
-
};
|
|
245
|
-
const resultToFounder = (result) => {
|
|
274
|
+
});
|
|
275
|
+
const resultToFounder = (result) => __awaiter(void 0, void 0, void 0, function* () {
|
|
246
276
|
return {
|
|
247
277
|
name: result.name,
|
|
248
278
|
ico: result.ico,
|
|
@@ -253,16 +283,17 @@ const resultToFounder = (result) => {
|
|
|
253
283
|
cityOrDistrictCode: result.founder_type_code === cityTypeCode
|
|
254
284
|
? result.city_code
|
|
255
285
|
: result.city_district_code,
|
|
256
|
-
schools: getSchoolsByFounderId(parseInt(result.id)),
|
|
286
|
+
schools: yield getSchoolsByFounderId(parseInt(result.id)),
|
|
257
287
|
};
|
|
258
|
-
};
|
|
259
|
-
const getSchoolsByFounderId = (founderId) => {
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
288
|
+
});
|
|
289
|
+
const getSchoolsByFounderId = (founderId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
290
|
+
const result = yield getKnexDb()
|
|
291
|
+
.select("s.izo", "s.redizo", "s.name", "s.capacity", "sl.address_point_id")
|
|
292
|
+
.from("school as s")
|
|
293
|
+
.join("school_founder as sf", "s.izo", "sf.school_izo")
|
|
294
|
+
.join("school_location as sl", "s.izo", "sl.school_izo")
|
|
295
|
+
.where("sf.founder_id", founderId);
|
|
296
|
+
return result.map((row) => ({
|
|
266
297
|
izo: String(row.izo),
|
|
267
298
|
redizo: String(row.redizo),
|
|
268
299
|
name: String(row.name),
|
|
@@ -273,29 +304,30 @@ const getSchoolsByFounderId = (founderId) => {
|
|
|
273
304
|
},
|
|
274
305
|
],
|
|
275
306
|
}));
|
|
276
|
-
};
|
|
277
|
-
const getAllFounderNames = () => {
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
307
|
+
});
|
|
308
|
+
const getAllFounderNames = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
309
|
+
const result = yield getKnexDb()
|
|
310
|
+
.select("f.id", "f.name as founder_name", "c.name as city_name", "d.name as city_district_name")
|
|
311
|
+
.from("founder as f")
|
|
312
|
+
.leftJoin("city as c", "c.code", "f.city_code")
|
|
313
|
+
.leftJoin("city_district as d", "d.code", "f.city_district_code");
|
|
283
314
|
return result.map((row) => ({
|
|
284
315
|
id: parseInt(row.id),
|
|
285
316
|
founderName: String(row.founder_name),
|
|
286
317
|
municipalityName: String(row.city_name ? row.city_name : row.city_district_name),
|
|
287
318
|
}));
|
|
288
|
-
};
|
|
289
|
-
export const findMunicipalityByNameAndType = (name, type) => {
|
|
319
|
+
});
|
|
320
|
+
export const findMunicipalityByNameAndType = (name, type) => __awaiter(void 0, void 0, void 0, function* () {
|
|
290
321
|
const errors = [];
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
322
|
+
const result = yield getKnexDb()
|
|
323
|
+
.first("code")
|
|
324
|
+
.from(type === MunicipalityType.City ? "city" : "city_district")
|
|
325
|
+
.where("name", name);
|
|
294
326
|
if (result) {
|
|
295
327
|
return { municipality: { code: result.code, type }, errors };
|
|
296
328
|
}
|
|
297
329
|
else {
|
|
298
|
-
const allNames = getAllMunicipalityNames(type);
|
|
330
|
+
const allNames = yield getAllMunicipalityNames(type);
|
|
299
331
|
const namesList = allNames.map((row) => row.name);
|
|
300
332
|
const bestMatch = findClosestString(name, namesList);
|
|
301
333
|
const bestMatchRow = allNames.find((municipality) => municipality.name === bestMatch);
|
|
@@ -309,13 +341,12 @@ export const findMunicipalityByNameAndType = (name, type) => {
|
|
|
309
341
|
errors,
|
|
310
342
|
};
|
|
311
343
|
}
|
|
312
|
-
};
|
|
313
|
-
const getAllMunicipalityNames = (type) => {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
return result.map((row) => ({
|
|
344
|
+
});
|
|
345
|
+
const getAllMunicipalityNames = (type) => __awaiter(void 0, void 0, void 0, function* () {
|
|
346
|
+
return (yield getKnexDb()
|
|
347
|
+
.select("name", "code")
|
|
348
|
+
.from(type === MunicipalityType.City ? "city" : "city_district")).map((row) => ({
|
|
318
349
|
name: row.name,
|
|
319
350
|
code: row.code,
|
|
320
351
|
}));
|
|
321
|
-
};
|
|
352
|
+
});
|