text-to-map 1.1.19 → 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,5 +1,5 @@
1
1
  import { Founder } from "../db/types";
2
- import { ErrorCallbackParams, Municipality, MunicipalityWithFounder, MunicipalityWithFounderResult, ProcessLineCallbackParams, School, SmdError, SmdState } from "./types";
2
+ import { ErrorCallbackParams, IntermediateMunicipality, IntermediateSchool, Municipality, IntermediateMunicipalityResult, ProcessLineCallbackParams, SmdError, SmdState } from "./types";
3
3
  interface ParseOrdinanceProps {
4
4
  lines: string[];
5
5
  initialState?: Partial<SmdState>;
@@ -9,9 +9,9 @@ interface ParseOrdinanceProps {
9
9
  includeUnmappedAddressPoints: boolean;
10
10
  }
11
11
  export declare const parseOrdinanceToAddressPoints: ({ lines, initialState, onError, onWarning, onProcessedLine, includeUnmappedAddressPoints, }: ParseOrdinanceProps) => Promise<Municipality[]>;
12
- export declare const convertMunicipality: (municipality: MunicipalityWithFounder) => Municipality;
13
- export declare const getNewMunicipalityByName: (name: string) => Promise<MunicipalityWithFounderResult>;
14
- export declare const getNewMunicipalityByFounderId: (founderId: number) => Promise<MunicipalityWithFounderResult>;
15
- export declare const getNewSchool: (name: string, founder: Founder | null, lineNumber: number, onError: (params: ErrorCallbackParams) => void) => Promise<School>;
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>;
16
16
  export declare const wholeLineError: (message: string, line: string) => SmdError;
17
17
  export {};
@@ -11,18 +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
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,
25
+ wholeMunicipalitySchool: {
26
+ izo: null,
27
+ lineNumber: null,
28
+ },
24
29
  includeUnmappedAddressPoints,
25
- }, municipalities: [] }, initialState);
30
+ }, cityCodes: [], municipalities: [] }, initialState);
26
31
  let lineNumber = 1;
27
32
  for (const rawLine of lines) {
28
33
  const line = cleanLine(rawLine);
@@ -51,22 +56,26 @@ export const parseOrdinanceToAddressPoints = ({ lines, initialState = {}, onErro
51
56
  finally {
52
57
  yield disconnectKnex();
53
58
  }
59
+ return [];
54
60
  });
55
- const filterOutSchoolAddressPoint = (addressPoints, school) => {
56
- const schoolPosition = school.position;
57
- return schoolPosition && isAddressPoint(schoolPosition)
58
- ? (addressPoints = addressPoints.filter((ap) => ap.id !== schoolPosition.id))
59
- : addressPoints;
60
- };
61
61
  export const convertMunicipality = (municipality) => {
62
62
  return {
63
63
  municipalityName: municipality.municipalityName,
64
- 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)],
65
74
  unmappedPoints: municipality.unmappedPoints,
66
75
  };
67
76
  };
68
77
  const processOneLine = (params) => __awaiter(void 0, void 0, void 0, function* () {
69
- const { line, state } = params;
78
+ const { line, lineNumber, state } = params;
70
79
  if (line[0] === "#") {
71
80
  yield processMunicipalityLine(params);
72
81
  return;
@@ -90,20 +99,27 @@ const processOneLine = (params) => __awaiter(void 0, void 0, void 0, function* (
90
99
  yield processWholeMunicipalityLine(params);
91
100
  }
92
101
  else if (isRestWithNoStreetNameLine(line)) {
93
- state.rests.noStreetNameSchoolIzo = state.currentSchool.izo;
102
+ state.rests.noStreetNameSchool = {
103
+ izo: state.currentSchool.izo,
104
+ lineNumber,
105
+ };
94
106
  }
95
107
  else if (isRestOfMunicipalityLine(line)) {
96
- state.rests.wholeMunicipalitySchoolIzo = state.currentSchool.izo;
108
+ state.rests.wholeMunicipalitySchool = {
109
+ izo: state.currentSchool.izo,
110
+ lineNumber,
111
+ };
97
112
  }
98
113
  else if (isRestOfMunicipalityPartLine(line)) {
99
114
  const { municipalityPartCode, errors } = yield getRestOfMunicipalityPart(line, state.currentMunicipality.founder);
100
115
  if (errors.length > 0) {
101
- params.onError({ lineNumber: params.lineNumber, line, errors });
116
+ params.onError({ lineNumber: lineNumber, line, errors });
102
117
  }
103
118
  else {
104
119
  state.rests.municipalityParts.push({
105
120
  municipalityPartCode,
106
121
  schoolIzo: state.currentSchool.izo,
122
+ lineNumber: lineNumber,
107
123
  });
108
124
  }
109
125
  }
@@ -157,6 +173,12 @@ const processMunicipalitySwitchLine = ({ line, state, lineNumber, onError, }) =>
157
173
  onError({ lineNumber, line, errors });
158
174
  }
159
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
+ }
160
182
  state.currentFilterMunicipality = municipality;
161
183
  }
162
184
  });
@@ -166,13 +188,29 @@ const processWholeMunicipalityLine = ({ line, state, lineNumber, onError, }) =>
166
188
  onError({ lineNumber, line, errors });
167
189
  }
168
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
+ }
169
197
  const addressPoints = yield findAddressPoints({
170
198
  type: "wholeMunicipality",
171
199
  municipality,
172
200
  });
173
- state.currentSchool.addresses.push(...filterOutSchoolAddressPoint(addressPoints, state.currentSchool).map(mapAddressPointForExport));
201
+ addAddressPointsToSchool(state.currentSchool, addressPoints, lineNumber);
174
202
  }
175
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
+ };
176
214
  const processAddressPointLine = ({ line, state, lineNumber, onError, onWarning, }) => __awaiter(void 0, void 0, void 0, function* () {
177
215
  const { smdLines, errors } = parseLine(line);
178
216
  if (errors.length > 0) {
@@ -191,7 +229,7 @@ const processAddressPointLine = ({ line, state, lineNumber, onError, onWarning,
191
229
  smdLine,
192
230
  municipality: state.currentFilterMunicipality,
193
231
  });
194
- state.currentSchool.addresses.push(...filterOutSchoolAddressPoint(addressPoints, state.currentSchool).map(mapAddressPointForExport));
232
+ addAddressPointsToSchool(state.currentSchool, addressPoints, lineNumber);
195
233
  }
196
234
  }
197
235
  else if (smdLine.type === "municipalityPart") {
@@ -206,38 +244,38 @@ const processAddressPointLine = ({ line, state, lineNumber, onError, onWarning,
206
244
  municipality: state.currentFilterMunicipality,
207
245
  municipalityPartCode,
208
246
  });
209
- state.currentSchool.addresses.push(...filterOutSchoolAddressPoint(addressPoints, state.currentSchool).map(mapAddressPointForExport));
247
+ addAddressPointsToSchool(state.currentSchool, addressPoints, lineNumber);
210
248
  }
211
249
  }
212
250
  }
213
251
  }
214
252
  });
215
- const addRestToSchool = (restPoints, schoolIzo, state) => {
216
- const addressPoints = state.currentMunicipality.schools.flatMap((school) => school.addresses);
253
+ const addRestToSchool = (restPoints, schoolIzo, lineNumber, state) => {
254
+ const addressPointsIds = getAllAddressPointsIds(state.currentMunicipality);
217
255
  // filter out address points already present
218
- const remainingPoints = restPoints.filter((point) => !addressPoints.some((ap) => ap.address === point.address));
256
+ const remainingPoints = restPoints.filter((point) => !addressPointsIds.has(point.id));
219
257
  // find the right school and add the remaining address points
220
258
  const schoolIndex = state.currentMunicipality.schools.findIndex((school) => school.izo === schoolIzo);
221
- state.currentMunicipality.schools[schoolIndex].addresses.push(...remainingPoints);
259
+ addAddressPointsToSchool(state.currentMunicipality.schools[schoolIndex], remainingPoints, lineNumber);
222
260
  };
223
261
  const addRests = (state) => __awaiter(void 0, void 0, void 0, function* () {
224
- if (state.rests.noStreetNameSchoolIzo) {
225
- yield addRestWithNoStreetNameToSchool(state);
262
+ if (state.rests.noStreetNameSchool.izo) {
263
+ yield addRestWithNoStreetNameToSchool(state.rests.noStreetNameSchool.lineNumber, state);
226
264
  }
227
- if (state.rests.wholeMunicipalitySchoolIzo) {
228
- yield addRestOfMunicipality(state);
265
+ if (state.rests.wholeMunicipalitySchool.izo) {
266
+ yield addRestOfMunicipality(state.rests.wholeMunicipalitySchool.lineNumber, state);
229
267
  }
230
268
  for (const rest of state.rests.municipalityParts) {
231
- yield addRestOfMunicipalityPart(state, rest.municipalityPartCode, rest.schoolIzo);
269
+ yield addRestOfMunicipalityPart(state, rest.municipalityPartCode, rest.schoolIzo, rest.lineNumber);
232
270
  }
233
271
  if (state.rests.includeUnmappedAddressPoints) {
234
272
  yield addRestOfMunicipalityToUnmappedPoints(state);
235
273
  }
236
- state.rests.noStreetNameSchoolIzo = null;
237
- state.rests.wholeMunicipalitySchoolIzo = null;
274
+ state.rests.noStreetNameSchool.izo = null;
275
+ state.rests.wholeMunicipalitySchool.izo = null;
238
276
  state.rests.municipalityParts = [];
239
277
  });
240
- const addRestWithNoStreetNameToSchool = (state) => __awaiter(void 0, void 0, void 0, function* () {
278
+ const addRestWithNoStreetNameToSchool = (lineNumber, state) => __awaiter(void 0, void 0, void 0, function* () {
241
279
  // get all address points without street name for current municipality
242
280
  const pointsNoStreetName = yield findAddressPoints({
243
281
  type: "wholeMunicipalityNoStreetName",
@@ -246,31 +284,34 @@ const addRestWithNoStreetNameToSchool = (state) => __awaiter(void 0, void 0, voi
246
284
  type: state.currentMunicipality.founder.municipalityType,
247
285
  },
248
286
  });
249
- addRestToSchool(pointsNoStreetName, state.rests.noStreetNameSchoolIzo, state);
287
+ addRestToSchool(pointsNoStreetName, state.rests.noStreetNameSchool.izo, lineNumber, state);
250
288
  });
251
- const addRestOfMunicipality = (state) => __awaiter(void 0, void 0, void 0, function* () {
252
- addRestToSchool(yield getRestOfMunicipality(state), state.rests.wholeMunicipalitySchoolIzo, state);
289
+ const addRestOfMunicipality = (lineNumber, state) => __awaiter(void 0, void 0, void 0, function* () {
290
+ addRestToSchool(yield getRestOfMunicipality(state), state.rests.wholeMunicipalitySchool.izo, lineNumber, state);
253
291
  });
254
292
  const addRestOfMunicipalityToUnmappedPoints = (state) => __awaiter(void 0, void 0, void 0, function* () {
255
293
  state.currentMunicipality.unmappedPoints = (yield getRestOfMunicipality(state)).map(mapAddressPointForExport);
256
294
  });
257
295
  const getRestOfMunicipality = (state) => __awaiter(void 0, void 0, void 0, function* () {
258
296
  // get all address points for current municipality
259
- return yield findAddressPoints({
297
+ const allPoints = yield findAddressPoints({
260
298
  type: "wholeMunicipality",
261
299
  municipality: {
262
300
  code: state.currentMunicipality.founder.cityOrDistrictCode,
263
301
  type: state.currentMunicipality.founder.municipalityType,
264
302
  },
265
303
  });
304
+ // filter out address points already present
305
+ const addressPointsIds = getAllAddressPointsIds(state.currentMunicipality);
306
+ return allPoints.filter((point) => !addressPointsIds.has(point.id));
266
307
  });
267
- 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* () {
268
309
  // get all address points for current municipality
269
310
  const allPoints = yield findAddressPoints({
270
311
  type: "wholeMunicipalityPart",
271
312
  municipalityPartCode,
272
313
  });
273
- addRestToSchool(allPoints, schoolIzo, state);
314
+ addRestToSchool(allPoints, schoolIzo, lineNumber, state);
274
315
  });
275
316
  export const getNewMunicipalityByName = (name) => __awaiter(void 0, void 0, void 0, function* () {
276
317
  const { founder, errors } = yield findFounder(name);
@@ -285,6 +326,12 @@ const getNewMunicipality = (founder, errors) => ({
285
326
  municipalityName: founder ? founder.name : "Neznámá obec",
286
327
  founder,
287
328
  schools: [],
329
+ cityCodes: founder.municipalityType === MunicipalityType.City
330
+ ? [founder.cityOrDistrictCode]
331
+ : [],
332
+ districtCodes: founder.municipalityType === MunicipalityType.District
333
+ ? [founder.cityOrDistrictCode]
334
+ : [],
288
335
  unmappedPoints: [],
289
336
  },
290
337
  errors,
@@ -311,21 +358,21 @@ export const getNewSchool = (name, founder, lineNumber, onError) => __awaiter(vo
311
358
  }
312
359
  }
313
360
  }
314
- return exportSchool;
361
+ return Object.assign(Object.assign({}, exportSchool), { addressMap: new Map() });
315
362
  });
316
- const mapAddressPointForExport = (addressPoint) => {
317
- return {
318
- address: addressPoint.address,
319
- lat: addressPoint.lat,
320
- lng: addressPoint.lng,
321
- };
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;
322
371
  };
323
- const mapSchoolForExport = (school) => ({
324
- name: school.name,
325
- izo: school.izo,
326
- addresses: school.addresses,
327
- position: school.position ? mapAddressPointForExport(school.position) : null,
328
- });
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 }));
329
376
  const cleanLine = (line) => {
330
377
  return line.trim().replace(/–/g, "-");
331
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,8 +62,13 @@ 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[];
67
73
  unmappedPoints: ExportAddressPoint[];
68
74
  }
@@ -77,23 +83,34 @@ export interface MunicipalityPartResult {
77
83
  export interface MunicipalityWithFounder extends Municipality {
78
84
  founder: Founder | null;
79
85
  }
80
- export interface MunicipalityWithFounderResult {
81
- municipality: MunicipalityWithFounder;
86
+ export interface IntermediateMunicipality extends MunicipalityWithFounder {
87
+ schools: IntermediateSchool[];
88
+ }
89
+ export interface IntermediateMunicipalityResult {
90
+ municipality: IntermediateMunicipality;
82
91
  errors: SmdError[];
83
92
  }
84
93
  export interface SmdState {
85
- currentMunicipality: MunicipalityWithFounder;
94
+ currentMunicipality: IntermediateMunicipality;
86
95
  currentFilterMunicipality: DbMunicipality;
87
- currentSchool: School;
96
+ currentSchool: IntermediateSchool;
88
97
  rests: {
89
- noStreetNameSchoolIzo: string;
98
+ noStreetNameSchool: {
99
+ izo: string;
100
+ lineNumber: number;
101
+ };
90
102
  municipalityParts: {
91
103
  municipalityPartCode: number;
92
104
  schoolIzo: string;
105
+ lineNumber: number;
93
106
  }[];
94
- wholeMunicipalitySchoolIzo: string;
107
+ wholeMunicipalitySchool: {
108
+ izo: string;
109
+ lineNumber: number;
110
+ };
95
111
  includeUnmappedAddressPoints: boolean;
96
112
  };
113
+ cityCodes: number[];
97
114
  municipalities: Municipality[];
98
115
  }
99
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.19",
71
+ "version": "1.1.20",
61
72
  "main": "dist/index.js",
62
73
  "types": "dist/index.d.ts",
63
74
  "files": [