UNPKG

text-to-map

Version:

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ě zpra

68 lines 12.7 kB
import AdmZip from "adm-zip"; import { parse } from "csv-parse"; import { createReadStream, createWriteStream, readdirSync, rmSync } from "fs"; import iconv from "iconv-lite"; import fetch from "node-fetch"; import { join } from "path"; import { pipeline } from "stream/promises"; import chunk from "lodash/chunk"; import { commitAddressPoints, removeDeprecatedAddressPoints, } from "../db/address-points"; import { SyncPart } from "../db/types"; import { getLatestUrlFromAtomFeed } from "../utils/atom"; import { prepareOptions, } from "../utils/helpers"; import { runSyncPart } from "./common"; const maxBufferSize = 1000; const downloadAndUnzip = async (url, options) => { const zipFilePath = join(options.tmpDir, options.addressPointsZipFileName); console.log("Downloading a large ZIP file with RUIAN data (~65 MB)..."); const response = await fetch(url); if (response.status !== 200) { throw new Error(`The ZIP file could not be downloaded. HTTP Code: ${response.status}`); } await pipeline(response.body, createWriteStream(zipFilePath)); console.log("Finished downloading."); const zip = new AdmZip(zipFilePath); console.log(`Starting to unzip CSV files to '${options.tmpDir}'`); zip.extractAllTo(options.tmpDir, true); console.log("Unzip completed."); rmSync(zipFilePath); console.log("Removed the ZIP file."); }; const importDataToDb = async (options) => { const extractionFolder = getExtractionFolder(options); const files = readdirSync(extractionFolder); let total = 0; let next = 0; console.log("Initiating import of RUIAN data to search DB (~3 million rows to be imported)."); const allIds = new Set(); for (const [i, file] of files.entries()) { const rows = []; const parseStream = parse({ delimiter: ";", fromLine: 2 }).on("data", async (data) => { rows.push(data); allIds.add(parseInt(data[0])); }); await pipeline(createReadStream(join(extractionFolder, file)), iconv.decodeStream("win1250"), parseStream); const chunks = chunk(rows, maxBufferSize); await Promise.all(chunks.map(async (chunk) => { total += await commitAddressPoints(chunk); if (total - next >= 100000) { next += 100000; console.log(`Total imported rows: ${next}`); } })); console.log(`${i + 1}/${files.length} files imported.`); } await removeDeprecatedAddressPoints(allIds); console.log(`Import completed. Total imported rows: ${total}`); }; const getExtractionFolder = (options) => join(options.tmpDir, options.addressPointsCsvFolderName); export const downloadAndImportAddressPoints = async (options = {}) => { await runSyncPart(SyncPart.AddressPoints, [], async () => { const completeOptions = prepareOptions(options); const datasetFeedLink = await getLatestUrlFromAtomFeed(completeOptions.addressPointsAtomUrl); const zipUrl = await getLatestUrlFromAtomFeed(datasetFeedLink); // await downloadAndUnzip(zipUrl, completeOptions); await importDataToDb(completeOptions); }); }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkcmVzcy1wb2ludHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3Blbi1kYXRhLXN5bmMvYWRkcmVzcy1wb2ludHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sU0FBUyxDQUFDO0FBQzdCLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDOUUsT0FBTyxLQUFLLE1BQU0sWUFBWSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLFlBQVksQ0FBQztBQUMvQixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEtBQUssTUFBTSxjQUFjLENBQUM7QUFDakMsT0FBTyxFQUNMLG1CQUFtQixFQUNuQiw2QkFBNkIsR0FDOUIsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6RCxPQUFPLEVBR0wsY0FBYyxHQUNmLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUV2QyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUM7QUFFM0IsTUFBTSxnQkFBZ0IsR0FBRyxLQUFLLEVBQzVCLEdBQVcsRUFDWCxPQUE0QixFQUNiLEVBQUU7SUFDakIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFFM0UsT0FBTyxDQUFDLEdBQUcsQ0FBQywwREFBMEQsQ0FBQyxDQUFDO0lB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QUMsTUFBTSxDQUFDLENBQUM7SUFFNUMsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQ0FBMEMsS0FBSyxFQUFFLENBQUMsQ0FBQztBQUNqRSxDQUFDLENBQUM7QUFFRixNQUFNLG1CQUFtQixHQUFHLENBQUMsT0FBNEIsRUFBRSxFQUFFLENBQzNELElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO0FBRTNELE1BQU0sQ0FBQyxNQUFNLDhCQUE4QixHQUFHLEtBQUssRUFDakQsVUFBc0MsRUFBRSxFQUN6QixFQUFFO0lBQ2pCLE1BQU0sV0FBVyxDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsRUFBRSxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3ZELE1BQU0sZUFBZSxHQUFHLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNoRCxNQUFNLGVBQWUsR0FBRyxNQUFNLHdCQUF3QixDQUNwRCxlQUFlLENBQUMsb0JBQW9CLENBQ3JDLENBQUM7UUFDRixNQUFNLE1BQU0sR0FBRyxNQUFNLHdCQUF3QixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQy9ELG1EQUFtRDtRQUNuRCxNQUFNLGNBQWMsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUN4QyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBBZG1aaXAgZnJvbSBcImFkbS16aXBcIjtcclxuaW1wb3J0IHsgcGFyc2UgfSBmcm9tIFwiY3N2LXBhcnNlXCI7XHJcbmltcG9ydCB7IGNyZWF0ZVJlYWRTdHJlYW0sIGNyZWF0ZVdyaXRlU3RyZWFtLCByZWFkZGlyU3luYywgcm1TeW5jIH0gZnJvbSBcImZzXCI7XHJcbmltcG9ydCBpY29udiBmcm9tIFwiaWNvbnYtbGl0ZVwiO1xyXG5pbXBvcnQgZmV0Y2ggZnJvbSBcIm5vZGUtZmV0Y2hcIjtcclxuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJwYXRoXCI7XHJcbmltcG9ydCB7IHBpcGVsaW5lIH0gZnJvbSBcInN0cmVhbS9wcm9taXNlc1wiO1xyXG5pbXBvcnQgY2h1bmsgZnJvbSBcImxvZGFzaC9jaHVua1wiO1xyXG5pbXBvcnQge1xyXG4gIGNvbW1pdEFkZHJlc3NQb2ludHMsXHJcbiAgcmVtb3ZlRGVwcmVjYXRlZEFkZHJlc3NQb2ludHMsXHJcbn0gZnJvbSBcIi4uL2RiL2FkZHJlc3MtcG9pbnRzXCI7XHJcbmltcG9ydCB7IFN5bmNQYXJ0IH0gZnJvbSBcIi4uL2RiL3R5cGVzXCI7XHJcbmltcG9ydCB7IGdldExhdGVzdFVybEZyb21BdG9tRmVlZCB9IGZyb20gXCIuLi91dGlscy9hdG9tXCI7XHJcbmltcG9ydCB7XHJcbiAgT3BlbkRhdGFTeW5jT3B0aW9ucyxcclxuICBPcGVuRGF0YVN5bmNPcHRpb25zUGFydGlhbCxcclxuICBwcmVwYXJlT3B0aW9ucyxcclxufSBmcm9tIFwiLi4vdXRpbHMvaGVscGVyc1wiO1xyXG5pbXBvcnQgeyBydW5TeW5jUGFydCB9IGZyb20gXCIuL2NvbW1vblwiO1xyXG5cclxuY29uc3QgbWF4QnVmZmVyU2l6ZSA9IDEwMDA7XHJcblxyXG5jb25zdCBkb3dubG9hZEFuZFVuemlwID0gYXN5bmMgKFxyXG4gIHVybDogc3RyaW5nLFxyXG4gIG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnNcclxuKTogUHJvbWlzZTx2b2lkPiA9PiB7XHJcbiAgY29uc3QgemlwRmlsZVBhdGggPSBqb2luKG9wdGlvbnMudG1wRGlyLCBvcHRpb25zLmFkZHJlc3NQb2ludHNaaXBGaWxlTmFtZSk7XHJcblxyXG4gIGNvbnNvbGUubG9nKFwiRG93bmxvYWRpbmcgYSBsYXJnZSBaSVAgZmlsZSB3aXRoIFJVSUFOIGRhdGEgKH42NSBNQikuLi5cIik7XHJcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpO1xyXG4gIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IDIwMCkge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKFxyXG4gICAgICBgVGhlIFpJUCBmaWxlIGNvdWxkIG5vdCBiZSBkb3dubG9hZGVkLiBIVFRQIENvZGU6ICR7cmVzcG9uc2Uuc3RhdHVzfWBcclxuICAgICk7XHJcbiAgfVxyXG4gIGF3YWl0IHBpcGVsaW5lKHJlc3BvbnNlLmJvZHksIGNyZWF0ZVdyaXRlU3RyZWFtKHppcEZpbGVQYXRoKSk7XHJcblxyXG4gIGNvbnNvbGUubG9nKFwiRmluaXNoZWQgZG93bmxvYWRpbmcuXCIpO1xyXG4gIGNvbnN0IHppcCA9IG5ldyBBZG1aaXAoemlwRmlsZVBhdGgpO1xyXG5cclxuICBjb25zb2xlLmxvZyhgU3RhcnRpbmcgdG8gdW56aXAgQ1NWIGZpbGVzIHRvICcke29wdGlvbnMudG1wRGlyfSdgKTtcclxuICB6aXAuZXh0cmFjdEFsbFRvKG9wdGlvbnMudG1wRGlyLCB0cnVlKTtcclxuICBjb25zb2xlLmxvZyhcIlVuemlwIGNvbXBsZXRlZC5cIik7XHJcblxyXG4gIHJtU3luYyh6aXBGaWxlUGF0aCk7XHJcbiAgY29uc29sZS5sb2coXCJSZW1vdmVkIHRoZSBaSVAgZmlsZS5cIik7XHJcbn07XHJcblxyXG5jb25zdCBpbXBvcnREYXRhVG9EYiA9IGFzeW5jIChvcHRpb25zOiBPcGVuRGF0YVN5bmNPcHRpb25zKSA9PiB7XHJcbiAgY29uc3QgZXh0cmFjdGlvbkZvbGRlciA9IGdldEV4dHJhY3Rpb25Gb2xkZXIob3B0aW9ucyk7XHJcblxyXG4gIGNvbnN0IGZpbGVzID0gcmVhZGRpclN5bmMoZXh0cmFjdGlvbkZvbGRlcik7XHJcblxyXG4gIGxldCB0b3RhbCA9IDA7XHJcbiAgbGV0IG5leHQgPSAwO1xyXG5cclxuICBjb25zb2xlLmxvZyhcclxuICAgIFwiSW5pdGlhdGluZyBpbXBvcnQgb2YgUlVJQU4gZGF0YSB0byBzZWFyY2ggREIgKH4zIG1pbGxpb24gcm93cyB0byBiZSBpbXBvcnRlZCkuXCJcclxuICApO1xyXG5cclxuICBjb25zdCBhbGxJZHMgPSBuZXcgU2V0PG51bWJlcj4oKTtcclxuXHJcbiAgZm9yIChjb25zdCBbaSwgZmlsZV0gb2YgZmlsZXMuZW50cmllcygpKSB7XHJcbiAgICBjb25zdCByb3dzOiBzdHJpbmdbXVtdID0gW107XHJcbiAgICBjb25zdCBwYXJzZVN0cmVhbSA9IHBhcnNlKHsgZGVsaW1pdGVyOiBcIjtcIiwgZnJvbUxpbmU6IDIgfSkub24oXHJcbiAgICAgIFwiZGF0YVwiLFxyXG4gICAgICBhc3luYyAoZGF0YSkgPT4ge1xyXG4gICAgICAgIHJvd3MucHVzaChkYXRhKTtcclxuICAgICAgICBhbGxJZHMuYWRkKHBhcnNlSW50KGRhdGFbMF0pKTtcclxuICAgICAgfVxyXG4gICAgKTtcclxuXHJcbiAgICBhd2FpdCBwaXBlbGluZShcclxuICAgICAgY3JlYXRlUmVhZFN0cmVhbShqb2luKGV4dHJhY3Rpb25Gb2xkZXIsIGZpbGUpKSxcclxuICAgICAgaWNvbnYuZGVjb2RlU3RyZWFtKFwid2luMTI1MFwiKSxcclxuICAgICAgcGFyc2VTdHJlYW1cclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgY2h1bmtzID0gY2h1bmsocm93cywgbWF4QnVmZmVyU2l6ZSk7XHJcblxyXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXHJcbiAgICAgIGNodW5rcy5tYXAoYXN5bmMgKGNodW5rKSA9PiB7XHJcbiAgICAgICAgdG90YWwgKz0gYXdhaXQgY29tbWl0QWRkcmVzc1BvaW50cyhjaHVuayk7XHJcblxyXG4gICAgICAgIGlmICh0b3RhbCAtIG5leHQgPj0gMTAwMDAwKSB7XHJcbiAgICAgICAgICBuZXh0ICs9IDEwMDAwMDtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKGBUb3RhbCBpbXBvcnRlZCByb3dzOiAke25leHR9YCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zb2xlLmxvZyhgJHtpICsgMX0vJHtmaWxlcy5sZW5ndGh9IGZpbGVzIGltcG9ydGVkLmApO1xyXG4gIH1cclxuXHJcbiAgYXdhaXQgcmVtb3ZlRGVwcmVjYXRlZEFkZHJlc3NQb2ludHMoYWxsSWRzKTtcclxuXHJcbiAgY29uc29sZS5sb2coYEltcG9ydCBjb21wbGV0ZWQuIFRvdGFsIGltcG9ydGVkIHJvd3M6ICR7dG90YWx9YCk7XHJcbn07XHJcblxyXG5jb25zdCBnZXRFeHRyYWN0aW9uRm9sZGVyID0gKG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnMpID0+XHJcbiAgam9pbihvcHRpb25zLnRtcERpciwgb3B0aW9ucy5hZGRyZXNzUG9pbnRzQ3N2Rm9sZGVyTmFtZSk7XHJcblxyXG5leHBvcnQgY29uc3QgZG93bmxvYWRBbmRJbXBvcnRBZGRyZXNzUG9pbnRzID0gYXN5bmMgKFxyXG4gIG9wdGlvbnM6IE9wZW5EYXRhU3luY09wdGlvbnNQYXJ0aWFsID0ge31cclxuKTogUHJvbWlzZTx2b2lkPiA9PiB7XHJcbiAgYXdhaXQgcnVuU3luY1BhcnQoU3luY1BhcnQuQWRkcmVzc1BvaW50cywgW10sIGFzeW5jICgpID0+IHtcclxuICAgIGNvbnN0IGNvbXBsZXRlT3B0aW9ucyA9IHByZXBhcmVPcHRpb25zKG9wdGlvbnMpO1xyXG4gICAgY29uc3QgZGF0YXNldEZlZWRMaW5rID0gYXdhaXQgZ2V0TGF0ZXN0VXJsRnJvbUF0b21GZWVkKFxyXG4gICAgICBjb21wbGV0ZU9wdGlvbnMuYWRkcmVzc1BvaW50c0F0b21VcmxcclxuICAgICk7XHJcbiAgICBjb25zdCB6aXBVcmwgPSBhd2FpdCBnZXRMYXRlc3RVcmxGcm9tQXRvbUZlZWQoZGF0YXNldEZlZWRMaW5rKTtcclxuICAgIC8vIGF3YWl0IGRvd25sb2FkQW5kVW56aXAoemlwVXJsLCBjb21wbGV0ZU9wdGlvbnMpO1xyXG4gICAgYXdhaXQgaW1wb3J0RGF0YVRvRGIoY29tcGxldGVPcHRpb25zKTtcclxuICB9KTtcclxufTtcclxuIl19