text-to-map 1.1.18 → 1.1.20

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.
@@ -0,0 +1,4 @@
1
+ import { Municipality } from "./types";
2
+ import { FeatureCollection, MultiPolygon, Polygon } from "@turf/helpers";
3
+ export declare const municipalityToPolygons: (municipality: Municipality) => Promise<FeatureCollection>;
4
+ export declare const createPolygons: (municipality: Municipality, cityPolygons: FeatureCollection<Polygon | MultiPolygon>[]) => FeatureCollection;
@@ -0,0 +1,95 @@
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 { Delaunay } from "d3-delaunay";
11
+ import { featureCollection, } from "@turf/helpers";
12
+ import intersect from "@turf/intersect";
13
+ import { toMercator, toWgs84 } from "@turf/projection";
14
+ import union from "@turf/union";
15
+ import { getCityPolygonGeojsons } from "../db/cities";
16
+ export const municipalityToPolygons = (municipality) => __awaiter(void 0, void 0, void 0, function* () {
17
+ const cityPolygons = yield getCityPolygonGeojsons(municipality.cityCodes);
18
+ return createPolygons(municipality, Object.values(cityPolygons));
19
+ });
20
+ export const createPolygons = (municipality, cityPolygons) => {
21
+ const citiesMultipolygon = createCitiesMultipolygon(cityPolygons);
22
+ const uniquePoints = new Map();
23
+ for (const school of municipality.schools) {
24
+ for (const point of school.addresses) {
25
+ if (!uniquePoints.has(point.address)) {
26
+ uniquePoints.set(point.address, {
27
+ type: "Feature",
28
+ geometry: {
29
+ type: "Point",
30
+ coordinates: [point.lng, point.lat],
31
+ },
32
+ properties: {
33
+ schools: [school.izo],
34
+ },
35
+ });
36
+ }
37
+ else {
38
+ uniquePoints.get(point.address).properties.schools.push(school.izo);
39
+ }
40
+ }
41
+ }
42
+ const points = {
43
+ type: "FeatureCollection",
44
+ features: Array.from(uniquePoints.values()),
45
+ };
46
+ const polygons = d3DelaunayVoronoi(points);
47
+ const unitedPolygons = [];
48
+ let colorIndex = 0;
49
+ for (const school of municipality.schools) {
50
+ const schoolPolygons = polygons.features.filter((polygon) => polygon.properties.schools.includes(school.izo));
51
+ const schoolPolygon = intersect(schoolPolygons.length > 1
52
+ ? union(featureCollection(schoolPolygons))
53
+ : schoolPolygons[0], citiesMultipolygon);
54
+ unitedPolygons.push(Object.assign(Object.assign({}, schoolPolygon), { properties: {
55
+ schoolIzo: school.izo,
56
+ colorIndex,
57
+ } }));
58
+ colorIndex++;
59
+ }
60
+ const { type } = polygons;
61
+ return {
62
+ type,
63
+ features: [...unitedPolygons],
64
+ };
65
+ };
66
+ const d3DelaunayVoronoi = (points) => {
67
+ const converted = points.features.map((p) => toMercator([p.geometry.coordinates[0], p.geometry.coordinates[1]]));
68
+ const bbox = [...toMercator([-180, -85]), ...toMercator([180, 85])];
69
+ const delaunay = new Delaunay(Float64Array.of(...converted.flat()));
70
+ const voronoi = delaunay.voronoi(bbox);
71
+ return {
72
+ type: "FeatureCollection",
73
+ features: Array.from(voronoi.cellPolygons()).map((polygon, i) => ({
74
+ type: "Feature",
75
+ geometry: {
76
+ type: "Polygon",
77
+ coordinates: [polygon.map((p) => toWgs84(p))],
78
+ },
79
+ properties: {
80
+ schools: points.features[i].properties.schools,
81
+ index: i,
82
+ neighbors: new Set(voronoi.neighbors(polygon.index)),
83
+ },
84
+ })),
85
+ };
86
+ };
87
+ const createCitiesMultipolygon = (cityPolygons) => {
88
+ const cityPolygonFeatures = cityPolygons.reduce((acc, cityPolygon) => {
89
+ acc.push(...cityPolygon.features.filter((f) => f.geometry.type === "Polygon" || f.geometry.type === "MultiPolygon"));
90
+ return acc;
91
+ }, []);
92
+ return cityPolygonFeatures.length > 1
93
+ ? union(featureCollection(cityPolygonFeatures))
94
+ : cityPolygonFeatures[0];
95
+ };
@@ -1,14 +1,17 @@
1
1
  import { Founder } from "../db/types";
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[]>;
4
- export declare const convertMunicipality: (municipality: MunicipalityWithFounder) => Municipality;
5
- export declare const getNewMunicipalityByName: (name: string) => Promise<{
6
- municipality: MunicipalityWithFounder;
7
- errors: SmdError[];
8
- }>;
9
- export declare const getNewMunicipalityByFounderId: (founderId: number) => Promise<{
10
- municipality: MunicipalityWithFounder;
11
- errors: SmdError[];
12
- }>;
13
- export declare const getNewSchool: (name: string, founder: Founder | null, lineNumber: number, onError: (params: ErrorCallbackParams) => void) => Promise<School>;
2
+ import { ErrorCallbackParams, IntermediateMunicipality, IntermediateSchool, Municipality, IntermediateMunicipalityResult, ProcessLineCallbackParams, SmdError, SmdState } from "./types";
3
+ interface ParseOrdinanceProps {
4
+ lines: string[];
5
+ initialState?: Partial<SmdState>;
6
+ onError?: (params: ErrorCallbackParams) => void;
7
+ onWarning?: (params: ErrorCallbackParams) => void;
8
+ onProcessedLine?: (params: ProcessLineCallbackParams) => void;
9
+ includeUnmappedAddressPoints: boolean;
10
+ }
11
+ export declare const parseOrdinanceToAddressPoints: ({ lines, initialState, onError, onWarning, onProcessedLine, includeUnmappedAddressPoints, }: ParseOrdinanceProps) => Promise<Municipality[]>;
12
+ export declare const convertMunicipality: (municipality: IntermediateMunicipality) => Municipality;
13
+ export declare const getNewMunicipalityByName: (name: string) => Promise<IntermediateMunicipalityResult>;
14
+ export declare const getNewMunicipalityByFounderId: (founderId: number) => Promise<IntermediateMunicipalityResult>;
15
+ export declare const getNewSchool: (name: string, founder: Founder | null, lineNumber: number, onError: (params: ErrorCallbackParams) => void) => Promise<IntermediateSchool>;
14
16
  export declare const wholeLineError: (message: string, line: string) => SmdError;
17
+ export {};
@@ -11,17 +11,23 @@ import { checkStreetExists, findAddressPoints, getAddressPointById, } from "../d
11
11
  import { disconnectKnex } from "../db/db";
12
12
  import { findFounder, getFounderById } from "../db/founders";
13
13
  import { findSchool } from "../db/schools";
14
- import { founderToMunicipality } from "../db/types";
14
+ import { MunicipalityType, founderToMunicipality } from "../db/types";
15
15
  import { getMunicipalityPartResult, getRestOfMunicipalityPart, getSwitchMunicipality, getWholeMunicipality, isMunicipalitySwitch, isRestOfMunicipalityLine, isRestOfMunicipalityPartLine, isRestWithNoStreetNameLine, isWholeMunicipality, } from "./municipality";
16
16
  import { parseLine } from "./smd-line-parser";
17
- import { isAddressPoint, } from "./types";
18
- export const parseOrdinanceToAddressPoints = (lines, initialState = {}, onError = () => { }, onWarning = () => { }, onProcessedLine = () => { }) => __awaiter(void 0, void 0, void 0, function* () {
17
+ export const parseOrdinanceToAddressPoints = ({ lines, initialState = {}, onError = () => { }, onWarning = () => { }, onProcessedLine = () => { }, includeUnmappedAddressPoints = false, }) => __awaiter(void 0, void 0, void 0, function* () {
19
18
  try {
20
19
  const state = Object.assign({ currentMunicipality: null, currentFilterMunicipality: null, currentSchool: null, rests: {
21
- noStreetNameSchoolIzo: null,
20
+ noStreetNameSchool: {
21
+ izo: null,
22
+ lineNumber: null,
23
+ },
22
24
  municipalityParts: [],
23
- wholeMunicipalitySchoolIzo: null,
24
- }, municipalities: [] }, initialState);
25
+ wholeMunicipalitySchool: {
26
+ izo: null,
27
+ lineNumber: null,
28
+ },
29
+ includeUnmappedAddressPoints,
30
+ }, cityCodes: [], municipalities: [] }, initialState);
25
31
  let lineNumber = 1;
26
32
  for (const rawLine of lines) {
27
33
  const line = cleanLine(rawLine);
@@ -50,21 +56,26 @@ export const parseOrdinanceToAddressPoints = (lines, initialState = {}, onError
50
56
  finally {
51
57
  yield disconnectKnex();
52
58
  }
59
+ return [];
53
60
  });
54
- const filterOutSchoolAddressPoint = (addressPoints, school) => {
55
- const schoolPosition = school.position;
56
- return schoolPosition && isAddressPoint(schoolPosition)
57
- ? (addressPoints = addressPoints.filter((ap) => ap.id !== schoolPosition.id))
58
- : addressPoints;
59
- };
60
61
  export const convertMunicipality = (municipality) => {
61
62
  return {
62
63
  municipalityName: municipality.municipalityName,
63
- schools: municipality.schools,
64
+ schools: municipality.schools.map((school) => {
65
+ return {
66
+ name: school.name,
67
+ izo: school.izo,
68
+ addresses: Array.from(school.addressMap.values()),
69
+ position: school.position,
70
+ };
71
+ }),
72
+ cityCodes: [...new Set(municipality.cityCodes)],
73
+ districtCodes: [...new Set(municipality.districtCodes)],
74
+ unmappedPoints: municipality.unmappedPoints,
64
75
  };
65
76
  };
66
77
  const processOneLine = (params) => __awaiter(void 0, void 0, void 0, function* () {
67
- const { line, state } = params;
78
+ const { line, lineNumber, state } = params;
68
79
  if (line[0] === "#") {
69
80
  yield processMunicipalityLine(params);
70
81
  return;
@@ -88,20 +99,27 @@ const processOneLine = (params) => __awaiter(void 0, void 0, void 0, function* (
88
99
  yield processWholeMunicipalityLine(params);
89
100
  }
90
101
  else if (isRestWithNoStreetNameLine(line)) {
91
- state.rests.noStreetNameSchoolIzo = state.currentSchool.izo;
102
+ state.rests.noStreetNameSchool = {
103
+ izo: state.currentSchool.izo,
104
+ lineNumber,
105
+ };
92
106
  }
93
107
  else if (isRestOfMunicipalityLine(line)) {
94
- state.rests.wholeMunicipalitySchoolIzo = state.currentSchool.izo;
108
+ state.rests.wholeMunicipalitySchool = {
109
+ izo: state.currentSchool.izo,
110
+ lineNumber,
111
+ };
95
112
  }
96
113
  else if (isRestOfMunicipalityPartLine(line)) {
97
114
  const { municipalityPartCode, errors } = yield getRestOfMunicipalityPart(line, state.currentMunicipality.founder);
98
115
  if (errors.length > 0) {
99
- params.onError({ lineNumber: params.lineNumber, line, errors });
116
+ params.onError({ lineNumber: lineNumber, line, errors });
100
117
  }
101
118
  else {
102
119
  state.rests.municipalityParts.push({
103
120
  municipalityPartCode,
104
121
  schoolIzo: state.currentSchool.izo,
122
+ lineNumber: lineNumber,
105
123
  });
106
124
  }
107
125
  }
@@ -155,6 +173,12 @@ const processMunicipalitySwitchLine = ({ line, state, lineNumber, onError, }) =>
155
173
  onError({ lineNumber, line, errors });
156
174
  }
157
175
  else {
176
+ if (municipality.type === MunicipalityType.City) {
177
+ state.currentMunicipality.cityCodes.push(municipality.code);
178
+ }
179
+ else {
180
+ state.currentMunicipality.districtCodes.push(municipality.code);
181
+ }
158
182
  state.currentFilterMunicipality = municipality;
159
183
  }
160
184
  });
@@ -164,13 +188,29 @@ const processWholeMunicipalityLine = ({ line, state, lineNumber, onError, }) =>
164
188
  onError({ lineNumber, line, errors });
165
189
  }
166
190
  else {
191
+ if (municipality.type === MunicipalityType.City) {
192
+ state.currentMunicipality.cityCodes.push(municipality.code);
193
+ }
194
+ else {
195
+ state.currentMunicipality.districtCodes.push(municipality.code);
196
+ }
167
197
  const addressPoints = yield findAddressPoints({
168
198
  type: "wholeMunicipality",
169
199
  municipality,
170
200
  });
171
- state.currentSchool.addresses.push(...filterOutSchoolAddressPoint(addressPoints, state.currentSchool).map(mapAddressPointForExport));
201
+ addAddressPointsToSchool(state.currentSchool, addressPoints, lineNumber);
172
202
  }
173
203
  });
204
+ const addAddressPointsToSchool = (school, addressPoints, lineNumber) => {
205
+ for (const point of addressPoints) {
206
+ if (school.addressMap.has(point.id)) {
207
+ school.addressMap.get(point.id).lineNumbers.push(lineNumber - 1);
208
+ }
209
+ else {
210
+ school.addressMap.set(point.id, mapAddressPointForExport(point, lineNumber));
211
+ }
212
+ }
213
+ };
174
214
  const processAddressPointLine = ({ line, state, lineNumber, onError, onWarning, }) => __awaiter(void 0, void 0, void 0, function* () {
175
215
  const { smdLines, errors } = parseLine(line);
176
216
  if (errors.length > 0) {
@@ -189,7 +229,7 @@ const processAddressPointLine = ({ line, state, lineNumber, onError, onWarning,
189
229
  smdLine,
190
230
  municipality: state.currentFilterMunicipality,
191
231
  });
192
- state.currentSchool.addresses.push(...filterOutSchoolAddressPoint(addressPoints, state.currentSchool).map(mapAddressPointForExport));
232
+ addAddressPointsToSchool(state.currentSchool, addressPoints, lineNumber);
193
233
  }
194
234
  }
195
235
  else if (smdLine.type === "municipalityPart") {
@@ -204,35 +244,38 @@ const processAddressPointLine = ({ line, state, lineNumber, onError, onWarning,
204
244
  municipality: state.currentFilterMunicipality,
205
245
  municipalityPartCode,
206
246
  });
207
- state.currentSchool.addresses.push(...filterOutSchoolAddressPoint(addressPoints, state.currentSchool).map(mapAddressPointForExport));
247
+ addAddressPointsToSchool(state.currentSchool, addressPoints, lineNumber);
208
248
  }
209
249
  }
210
250
  }
211
251
  }
212
252
  });
213
- const addRestToSchool = (restPoints, schoolIzo, state) => __awaiter(void 0, void 0, void 0, function* () {
214
- const addressPoints = state.currentMunicipality.schools.flatMap((school) => school.addresses);
253
+ const addRestToSchool = (restPoints, schoolIzo, lineNumber, state) => {
254
+ const addressPointsIds = getAllAddressPointsIds(state.currentMunicipality);
215
255
  // filter out address points already present
216
- const remainingPoints = restPoints.filter((point) => !addressPoints.some((ap) => ap.address === point.address));
256
+ const remainingPoints = restPoints.filter((point) => !addressPointsIds.has(point.id));
217
257
  // find the right school and add the remaining address points
218
258
  const schoolIndex = state.currentMunicipality.schools.findIndex((school) => school.izo === schoolIzo);
219
- state.currentMunicipality.schools[schoolIndex].addresses.push(...remainingPoints);
220
- });
259
+ addAddressPointsToSchool(state.currentMunicipality.schools[schoolIndex], remainingPoints, lineNumber);
260
+ };
221
261
  const addRests = (state) => __awaiter(void 0, void 0, void 0, function* () {
222
- if (state.rests.noStreetNameSchoolIzo) {
223
- yield addRestWithNoStreetNameToSchool(state);
262
+ if (state.rests.noStreetNameSchool.izo) {
263
+ yield addRestWithNoStreetNameToSchool(state.rests.noStreetNameSchool.lineNumber, state);
224
264
  }
225
- if (state.rests.wholeMunicipalitySchoolIzo) {
226
- yield addRestOfMunicipality(state);
265
+ if (state.rests.wholeMunicipalitySchool.izo) {
266
+ yield addRestOfMunicipality(state.rests.wholeMunicipalitySchool.lineNumber, state);
227
267
  }
228
268
  for (const rest of state.rests.municipalityParts) {
229
- yield addRestOfMunicipalityPart(state, rest.municipalityPartCode, rest.schoolIzo);
269
+ yield addRestOfMunicipalityPart(state, rest.municipalityPartCode, rest.schoolIzo, rest.lineNumber);
270
+ }
271
+ if (state.rests.includeUnmappedAddressPoints) {
272
+ yield addRestOfMunicipalityToUnmappedPoints(state);
230
273
  }
231
- state.rests.noStreetNameSchoolIzo = null;
232
- state.rests.wholeMunicipalitySchoolIzo = null;
274
+ state.rests.noStreetNameSchool.izo = null;
275
+ state.rests.wholeMunicipalitySchool.izo = null;
233
276
  state.rests.municipalityParts = [];
234
277
  });
235
- const addRestWithNoStreetNameToSchool = (state) => __awaiter(void 0, void 0, void 0, function* () {
278
+ const addRestWithNoStreetNameToSchool = (lineNumber, state) => __awaiter(void 0, void 0, void 0, function* () {
236
279
  // get all address points without street name for current municipality
237
280
  const pointsNoStreetName = yield findAddressPoints({
238
281
  type: "wholeMunicipalityNoStreetName",
@@ -241,9 +284,15 @@ const addRestWithNoStreetNameToSchool = (state) => __awaiter(void 0, void 0, voi
241
284
  type: state.currentMunicipality.founder.municipalityType,
242
285
  },
243
286
  });
244
- yield addRestToSchool(pointsNoStreetName, state.rests.noStreetNameSchoolIzo, state);
287
+ addRestToSchool(pointsNoStreetName, state.rests.noStreetNameSchool.izo, lineNumber, state);
245
288
  });
246
- const addRestOfMunicipality = (state) => __awaiter(void 0, void 0, void 0, function* () {
289
+ const addRestOfMunicipality = (lineNumber, state) => __awaiter(void 0, void 0, void 0, function* () {
290
+ addRestToSchool(yield getRestOfMunicipality(state), state.rests.wholeMunicipalitySchool.izo, lineNumber, state);
291
+ });
292
+ const addRestOfMunicipalityToUnmappedPoints = (state) => __awaiter(void 0, void 0, void 0, function* () {
293
+ state.currentMunicipality.unmappedPoints = (yield getRestOfMunicipality(state)).map(mapAddressPointForExport);
294
+ });
295
+ const getRestOfMunicipality = (state) => __awaiter(void 0, void 0, void 0, function* () {
247
296
  // get all address points for current municipality
248
297
  const allPoints = yield findAddressPoints({
249
298
  type: "wholeMunicipality",
@@ -252,15 +301,17 @@ const addRestOfMunicipality = (state) => __awaiter(void 0, void 0, void 0, funct
252
301
  type: state.currentMunicipality.founder.municipalityType,
253
302
  },
254
303
  });
255
- yield addRestToSchool(allPoints, state.rests.wholeMunicipalitySchoolIzo, state);
304
+ // filter out address points already present
305
+ const addressPointsIds = getAllAddressPointsIds(state.currentMunicipality);
306
+ return allPoints.filter((point) => !addressPointsIds.has(point.id));
256
307
  });
257
- const addRestOfMunicipalityPart = (state, municipalityPartCode, schoolIzo) => __awaiter(void 0, void 0, void 0, function* () {
308
+ const addRestOfMunicipalityPart = (state, municipalityPartCode, schoolIzo, lineNumber) => __awaiter(void 0, void 0, void 0, function* () {
258
309
  // get all address points for current municipality
259
310
  const allPoints = yield findAddressPoints({
260
311
  type: "wholeMunicipalityPart",
261
312
  municipalityPartCode,
262
313
  });
263
- yield addRestToSchool(allPoints, schoolIzo, state);
314
+ addRestToSchool(allPoints, schoolIzo, lineNumber, state);
264
315
  });
265
316
  export const getNewMunicipalityByName = (name) => __awaiter(void 0, void 0, void 0, function* () {
266
317
  const { founder, errors } = yield findFounder(name);
@@ -275,6 +326,13 @@ const getNewMunicipality = (founder, errors) => ({
275
326
  municipalityName: founder ? founder.name : "Neznámá obec",
276
327
  founder,
277
328
  schools: [],
329
+ cityCodes: founder.municipalityType === MunicipalityType.City
330
+ ? [founder.cityOrDistrictCode]
331
+ : [],
332
+ districtCodes: founder.municipalityType === MunicipalityType.District
333
+ ? [founder.cityOrDistrictCode]
334
+ : [],
335
+ unmappedPoints: [],
278
336
  },
279
337
  errors,
280
338
  });
@@ -300,21 +358,21 @@ export const getNewSchool = (name, founder, lineNumber, onError) => __awaiter(vo
300
358
  }
301
359
  }
302
360
  }
303
- return exportSchool;
361
+ return Object.assign(Object.assign({}, exportSchool), { addressMap: new Map() });
304
362
  });
305
- const mapAddressPointForExport = (addressPoint) => {
306
- return {
307
- address: addressPoint.address,
308
- lat: addressPoint.lat,
309
- lng: addressPoint.lng,
310
- };
363
+ const getAllAddressPointsIds = (municipality) => {
364
+ const addressPointsIds = new Set();
365
+ for (const school of municipality.schools) {
366
+ for (const id of school.addressMap.keys()) {
367
+ addressPointsIds.add(id);
368
+ }
369
+ }
370
+ return addressPointsIds;
311
371
  };
312
- const mapSchoolForExport = (school) => ({
313
- name: school.name,
314
- izo: school.izo,
315
- addresses: school.addresses,
316
- position: school.position ? mapAddressPointForExport(school.position) : null,
317
- });
372
+ const mapAddressPointForExport = (addressPoint, lineNumber) => {
373
+ return Object.assign({ address: addressPoint.address, lat: addressPoint.lat, lng: addressPoint.lng }, (lineNumber ? { lineNumbers: [lineNumber - 1] } : {}));
374
+ };
375
+ const mapSchoolForExport = (school) => (Object.assign(Object.assign({}, school), { position: school.position ? mapAddressPointForExport(school.position) : null }));
318
376
  const cleanLine = (line) => {
319
377
  return line.trim().replace(/–/g, "-");
320
378
  };
@@ -53,6 +53,7 @@ export interface ExportAddressPoint {
53
53
  address: string;
54
54
  lat: number;
55
55
  lng: number;
56
+ lineNumbers?: number[];
56
57
  }
57
58
  export declare const isAddressPoint: (something: AddressPoint | ExportAddressPoint) => something is AddressPoint;
58
59
  export interface School {
@@ -61,9 +62,15 @@ export interface School {
61
62
  position?: AddressPoint | ExportAddressPoint;
62
63
  addresses: ExportAddressPoint[];
63
64
  }
65
+ export interface IntermediateSchool extends School {
66
+ addressMap: Map<number, ExportAddressPoint>;
67
+ }
64
68
  export interface Municipality {
65
69
  municipalityName: string;
70
+ cityCodes: number[];
71
+ districtCodes: number[];
66
72
  schools: School[];
73
+ unmappedPoints: ExportAddressPoint[];
67
74
  }
68
75
  export interface DbMunicipalityResult {
69
76
  municipality: DbMunicipality;
@@ -76,18 +83,34 @@ export interface MunicipalityPartResult {
76
83
  export interface MunicipalityWithFounder extends Municipality {
77
84
  founder: Founder | null;
78
85
  }
86
+ export interface IntermediateMunicipality extends MunicipalityWithFounder {
87
+ schools: IntermediateSchool[];
88
+ }
89
+ export interface IntermediateMunicipalityResult {
90
+ municipality: IntermediateMunicipality;
91
+ errors: SmdError[];
92
+ }
79
93
  export interface SmdState {
80
- currentMunicipality: MunicipalityWithFounder;
94
+ currentMunicipality: IntermediateMunicipality;
81
95
  currentFilterMunicipality: DbMunicipality;
82
- currentSchool: School;
96
+ currentSchool: IntermediateSchool;
83
97
  rests: {
84
- noStreetNameSchoolIzo: string;
98
+ noStreetNameSchool: {
99
+ izo: string;
100
+ lineNumber: number;
101
+ };
85
102
  municipalityParts: {
86
103
  municipalityPartCode: number;
87
104
  schoolIzo: string;
105
+ lineNumber: number;
88
106
  }[];
89
- wholeMunicipalitySchoolIzo: string;
107
+ wholeMunicipalitySchool: {
108
+ izo: string;
109
+ lineNumber: number;
110
+ };
111
+ includeUnmappedAddressPoints: boolean;
90
112
  };
113
+ cityCodes: number[];
91
114
  municipalities: Municipality[];
92
115
  }
93
116
  export interface ProcessLineCallbackParams {
@@ -10,6 +10,7 @@ export interface OpenDataSyncOptions {
10
10
  streetsAtomUrl: string;
11
11
  streetZipFolderName: string;
12
12
  streetDbfFileName: string;
13
+ polygonShpFileName: string;
13
14
  schoolsXmlUrl: string;
14
15
  schoolsXmlFileName: string;
15
16
  regionsCsvUrl: string;
@@ -31,6 +31,7 @@ export const prepareOptions = (options) => {
31
31
  streetsAtomUrl: "https://atom.cuzk.cz/RUIAN-OBCE-SHP/RUIAN-OBCE-SHP.xml",
32
32
  streetZipFolderName: "streets",
33
33
  streetDbfFileName: "UL_L.dbf",
34
+ polygonShpFileName: "OBEC_P.shp",
34
35
  schoolsXmlUrl: "https://rejstriky.msmt.cz/opendata/vrejcelk.xml",
35
36
  schoolsXmlFileName: "school-register.xml",
36
37
  regionsCsvUrl: "https://www.czso.cz/documents/10180/23208674/struktura_uzemi_cr.csv",
@@ -73,8 +73,12 @@ export default function jtsk2wgs84(x, y, h = 200) {
73
73
  return {
74
74
  jtsk_x: originalX,
75
75
  jtsk_y: originalY,
76
- lat: (B / Math.PI) * 180,
77
- lon: (L / Math.PI) * 180,
76
+ lat: roundToNDecimalPlaces((B / Math.PI) * 180, 6),
77
+ lon: roundToNDecimalPlaces((L / Math.PI) * 180, 6),
78
78
  altitude: Math.round(h * 100) / 100,
79
79
  };
80
80
  }
81
+ function roundToNDecimalPlaces(toRound, decimalPlaces) {
82
+ return (Math.round(toRound * Math.pow(10, decimalPlaces)) /
83
+ Math.pow(10, decimalPlaces));
84
+ }
package/package.json CHANGED
@@ -2,13 +2,21 @@
2
2
  "type": "module",
3
3
  "dependencies": {
4
4
  "@turf/distance": "^6.5.0",
5
+ "@turf/helpers": "^6.5.0",
6
+ "@turf/intersect": "^6.5.0",
7
+ "@turf/meta": "^7.0.0-alpha.110",
8
+ "@turf/projection": "^7.0.0-alpha.2",
9
+ "@turf/union": "^7.0.0-alpha.113",
5
10
  "adm-zip": "^0.5.9",
6
11
  "better-sqlite3": "^8.0.1",
7
12
  "chevrotain": "^10.4.2",
8
13
  "csv-parse": "^5.3.3",
9
14
  "czech-address": "^1.0.1",
15
+ "d3-delaunay": "^6.0.4",
10
16
  "dotenv": "^16.3.1",
11
17
  "feedparser": "^2.2.10",
18
+ "geojson": "^0.5.0",
19
+ "graphlib": "^2.1.8",
12
20
  "iconv-lite": "^0.6.3",
13
21
  "knex": "^2.4.2",
14
22
  "lodash": "^4.17.21",
@@ -17,6 +25,7 @@
17
25
  "parsedbf": "^1.1.1",
18
26
  "pg": "^8.11.1",
19
27
  "sax": "^1.2.4",
28
+ "shp-to-geojson": "^1.0.0",
20
29
  "typescript": "^4.9.4"
21
30
  },
22
31
  "devDependencies": {
@@ -24,6 +33,7 @@
24
33
  "@jest/globals": "^29.5.0",
25
34
  "@types/adm-zip": "^0.5.0",
26
35
  "@types/better-sqlite3": "^7.6.3",
36
+ "@types/d3-delaunay": "^6.0.4",
27
37
  "@types/feedparser": "^2.2.5",
28
38
  "@types/lodash": "^4.14.196",
29
39
  "@types/node": "^18.11.17",
@@ -39,6 +49,7 @@
39
49
  "address-points": "ts-node --experimental-specifier-resolution=node --esm src/bin/address-points.ts",
40
50
  "regions": "ts-node --experimental-specifier-resolution=node --esm src/bin/regions.ts",
41
51
  "cities": "ts-node --experimental-specifier-resolution=node --esm src/bin/cities.ts",
52
+ "polygons": "ts-node --experimental-specifier-resolution=node --esm src/bin/polygons.ts",
42
53
  "schools": "ts-node --experimental-specifier-resolution=node --esm src/bin/schools.ts",
43
54
  "streets": "ts-node --experimental-specifier-resolution=node --esm src/bin/streets.ts",
44
55
  "diagrams": "ts-node --experimental-specifier-resolution=node --esm src/bin/generate-syntax-diagrams.ts",
@@ -57,7 +68,7 @@
57
68
  },
58
69
  "name": "text-to-map",
59
70
  "description": "Text To Map usiluje o lepší, strojově zpracovatelné využití částí vyhlášek s výčtem ulic a dalších lokací. Jde o rozšiřitelnou sadu konceptů a nástrojů, které zajistí hladký převod výčtu ulic a jejich rozsahů v lidsky srozumitelném jazyce do strojově zpracovatelného, uchopitelného formátu.",
60
- "version": "1.1.18",
71
+ "version": "1.1.20",
61
72
  "main": "dist/index.js",
62
73
  "types": "dist/index.d.ts",
63
74
  "files": [