feat: import new reservoir data, add lake management scripts, and update overview UI components
continuous-integration/drone/push Build encountered an error

This commit is contained in:
David Fencl
2026-06-06 20:14:36 +02:00
parent cf05e844d8
commit a67a2247c3
55 changed files with 265428 additions and 441 deletions
+99
View File
@@ -0,0 +1,99 @@
import fs from 'fs';
import path from 'path';
export interface LakeConfig {
id: string;
text: string;
priority?: boolean;
coords: [number, number];
maxVolume?: number;
minLevel?: number;
maxLevel?: number;
storageLevel?: number;
navigationForbidden?: boolean;
}
// Preserve existing minLevel, maxLevel, storageLevel that were scraped from PVL.
// Only update maxVolume, coords, and navigationForbidden.
import { lakesConfig as oldConfig } from './lakesConfig';
const exactData: Record<string, Partial<LakeConfig>> = {
"VLL1|1": { maxVolume: 306.0, coords: [48.6322, 14.2215], navigationForbidden: false },
"VLL2|1": { maxVolume: 1.6, coords: [48.6250, 14.3180], navigationForbidden: false },
"VLHN|1": { maxVolume: 21.1, coords: [49.1830, 14.4440], navigationForbidden: false },
"VLKO|1": { maxVolume: 2.8, coords: [49.2550, 14.3980], navigationForbidden: false },
"VLOR|2": { maxVolume: 716.5, coords: [49.6060, 14.1700], navigationForbidden: false },
"VLSL|2": { maxVolume: 269.3, coords: [49.8220, 14.4360], navigationForbidden: false },
"VLST|2": { maxVolume: 11.2, coords: [49.8450, 14.4120], navigationForbidden: false },
"MARI|1": { maxVolume: 33.8, coords: [48.8470, 14.4870], navigationForbidden: true },
"MZHR|3": { maxVolume: 56.7, coords: [49.7890, 13.1550], navigationForbidden: false },
"ZESV|2": { maxVolume: 266.6, coords: [49.7040, 15.1150], navigationForbidden: true },
"VLKA|2": { maxVolume: 12.8, coords: [49.6380, 14.2580], navigationForbidden: false },
"VLVE|2": { maxVolume: 11.1, coords: [49.9390, 14.3910], navigationForbidden: false },
"BLHU|1": { maxVolume: 5.7, coords: [49.0270, 13.9870], navigationForbidden: true },
"UHNY|3": { maxVolume: 16.0, coords: [49.2610, 13.1230], navigationForbidden: true },
"KCKC|3": { maxVolume: 9.3, coords: [50.0630, 13.9310], navigationForbidden: true },
"KLKL|3": { maxVolume: 1.5, coords: [49.7540, 13.5640], navigationForbidden: false },
"RACU|3": { maxVolume: 5.5, coords: [49.7150, 13.3640], navigationForbidden: false },
"TRTR|2": { maxVolume: 4.1, coords: [49.5260, 15.1950], navigationForbidden: false },
"HESE|2": { maxVolume: 1.9, coords: [49.5070, 15.2630], navigationForbidden: false },
"MZLU|3": { maxVolume: 2.3, coords: [49.8050, 12.6390], navigationForbidden: true },
"STZL|3": { maxVolume: 14.5, coords: [50.0930, 13.1360], navigationForbidden: true },
"PPPI|3": { maxVolume: 1.6, coords: [49.6910, 13.9570], navigationForbidden: true },
"LILA|3": { maxVolume: 0.8, coords: [49.6640, 13.8820], navigationForbidden: true },
"OPOB|3": { maxVolume: 0.6, coords: [49.7110, 13.9370], navigationForbidden: true },
"STST|2": { maxVolume: 1.0, coords: [49.7910, 14.0040], navigationForbidden: false },
"HEVR|2": { maxVolume: 0.5, coords: [49.5070, 15.2440], navigationForbidden: false },
"CRSO|1": { maxVolume: 1.4, coords: [48.7750, 14.5360], navigationForbidden: false },
"SCHU|1": { maxVolume: 0.8, coords: [48.7840, 14.7350], navigationForbidden: false },
"SVSV|2": { maxVolume: 1.2, coords: [49.5750, 15.9520], navigationForbidden: true },
"SAPI|2": { maxVolume: 1.5, coords: [49.5930, 15.9320], navigationForbidden: false },
"SMSM|3": { maxVolume: 0.7, coords: [49.8970, 14.0580], navigationForbidden: false },
"CPZA|3": { maxVolume: 0.5, coords: [49.8050, 13.8510], navigationForbidden: false },
"BIBI|1": { maxVolume: 0.3, coords: [49.1670, 14.0410], navigationForbidden: false },
"SPKA|1": { maxVolume: 0.3, coords: [48.9740, 14.5450], navigationForbidden: false },
"SPNE|2": { maxVolume: 0.4, coords: [49.7710, 15.1760], navigationForbidden: false },
"SPZH|1": { maxVolume: 0.2, coords: [49.2310, 15.3120], navigationForbidden: true },
"KLDP|3": { maxVolume: 0.5, coords: [49.6640, 13.7530], navigationForbidden: true },
"KLHP|3": { maxVolume: 0.7, coords: [49.6550, 13.7610], navigationForbidden: true },
"CPDR|3": { maxVolume: 0.1, coords: [49.8050, 13.8550], navigationForbidden: false },
};
function main() {
const updated = oldConfig.map(lake => {
const fresh = exactData[lake.id];
if (fresh) {
return {
...lake,
maxVolume: fresh.maxVolume,
coords: fresh.coords,
navigationForbidden: fresh.navigationForbidden
};
}
return lake;
});
let newContent = `export interface LakeConfig {
id: string;
text: string;
priority?: boolean;
coords: [number, number];
maxVolume?: number;
minLevel?: number;
maxLevel?: number;
storageLevel?: number;
navigationForbidden?: boolean;
}
export const lakesConfig: LakeConfig[] = [
`;
updated.forEach((l, idx) => {
newContent += ` { id: "${l.id}", text: "${l.text}", ${l.priority ? 'priority: true, ' : ''}coords: [${l.coords[0].toFixed(4)}, ${l.coords[1].toFixed(4)}], maxVolume: ${l.maxVolume}, minLevel: ${l.minLevel}, maxLevel: ${l.maxLevel}, storageLevel: ${l.storageLevel}, navigationForbidden: ${l.navigationForbidden} }${idx === updated.length - 1 ? '' : ','}\n`;
});
newContent += `];\n`;
fs.writeFileSync(path.resolve('./scripts/lakesConfig.ts'), newContent);
console.log("lakesConfig.ts updated with precise static data and navigation limits!");
}
main();
+79
View File
@@ -0,0 +1,79 @@
import axios from 'axios';
import * as cheerio from 'cheerio';
import https from 'https';
const ALL_LAKES = [
{"href": "Mereni.aspx?id=BIBI&oid=1", "text": "VD Bílsko"},
{"href": "Mereni.aspx?id=RACU&oid=3", "text": "VD České Údolí"},
{"href": "Mereni.aspx?id=KLDP&oid=3", "text": "VD Dolejší Padrťský rybník"},
{"href": "Mereni.aspx?id=CPDR&oid=3", "text": "VD Dráteník"},
{"href": "Mereni.aspx?id=KLHP&oid=3", "text": "VD Hořejší Padrťský rybník"},
{"href": "Mereni.aspx?id=SCHU&oid=1", "text": "VD Humenice"},
{"href": "Mereni.aspx?id=BLHU&oid=1", "text": "VD Husinec"},
{"href": "Mereni.aspx?id=VLKA&oid=2", "text": "VD Kamýk"},
{"href": "Mereni.aspx?id=SPKA&oid=1", "text": "VD Karhof"},
{"href": "Mereni.aspx?id=KLKL&oid=3", "text": "VD Klabava"},
{"href": "Mereni.aspx?id=KCKC&oid=3", "text": "VD Klíčava"},
{"href": "Mereni.aspx?id=LILA&oid=3", "text": "VD Láz"},
{"href": "Mereni.aspx?id=MZLU&oid=3", "text": "VD Lučina"},
{"href": "Mereni.aspx?id=SPNE&oid=2", "text": "VD Němčice"},
{"href": "Mereni.aspx?id=UHNY&oid=3", "text": "VD Nýrsko"},
{"href": "Mereni.aspx?id=OPOB&oid=3", "text": "VD Obecnice"},
{"href": "Mereni.aspx?id=PPPI&oid=3", "text": "VD Pilská (u Příbramě)"},
{"href": "Mereni.aspx?id=SAPI&oid=2", "text": "VD Pilská u Žďáru"},
{"href": "Mereni.aspx?id=HESE&oid=2", "text": "VD Sedlice"},
{"href": "Mereni.aspx?id=CRSO&oid=1", "text": "VD Soběnov"},
{"href": "Mereni.aspx?id=SVSV&oid=2", "text": "VD Staviště"},
{"href": "Mereni.aspx?id=STST&oid=2", "text": "VD Strž"},
{"href": "Mereni.aspx?id=SMSM&oid=3", "text": "VD Suchomasty"},
{"href": "Mereni.aspx?id=ZESV&oid=2", "text": "VD Švihov (Želivka)"},
{"href": "Mereni.aspx?id=TRTR&oid=2", "text": "VD Trnávka"},
{"href": "Mereni.aspx?id=VLVE&oid=2", "text": "VD Vrané"},
{"href": "Mereni.aspx?id=HEVR&oid=2", "text": "VD Vřesník"},
{"href": "Mereni.aspx?id=CPZA&oid=3", "text": "VD Záskalská"},
{"href": "Mereni.aspx?id=SPZH&oid=1", "text": "VD Zhejral"},
{"href": "Mereni.aspx?id=STZL&oid=3", "text": "VD Žlutice"}
];
async function checkLakes() {
const agent = new https.Agent({ rejectUnauthorized: false });
const validLakes: any[] = [];
for (const lake of ALL_LAKES) {
const url = `https://www.pvl.cz/portal/nadrze/cz/pc/${lake.href}`;
try {
const response = await axios.get(url, {
httpsAgent: agent,
headers: { 'User-Agent': 'Mozilla/5.0' }
});
const $ = cheerio.load(response.data);
let hasHistory = false;
let hasInflow = false;
$('table').each((i, tbl) => {
const text = $(tbl).text();
if (text.includes('Aktuální hodnoty') && text.includes('Přítok')) {
hasInflow = true;
}
if (text.includes('Datum') && text.includes('Odtok')) {
const rows = $(tbl).find('tr').length;
if (rows > 2) hasHistory = true;
}
});
if (hasHistory && hasInflow) {
validLakes.push(lake);
console.log(`[VALID] ${lake.text}`);
} else {
console.log(`[INVALID] ${lake.text} (Hist:${hasHistory}, In:${hasInflow})`);
}
} catch (err: any) {
console.error(`[ERROR] ${lake.text}: ${err.message}`);
}
}
console.log('\\n--- SUMMARY OF VALID LAKES ---');
console.log(JSON.stringify(validLakes, null, 2));
}
checkLakes();
+29
View File
@@ -0,0 +1,29 @@
import axios from 'axios';
import * as cheerio from 'cheerio';
import https from 'https';
async function checkMap() {
const agent = new https.Agent({ rejectUnauthorized: false });
try {
const response = await axios.get('https://www.pvl.cz/portal/nadrze/cz/pc/Prehled.aspx', {
httpsAgent: agent,
headers: { 'User-Agent': 'Mozilla/5.0' }
});
const html = response.data;
// Look for variables or inline JSON with coordinates
const scriptMatches = html.match(/<script\\b[^>]*>([\\s\\S]*?)<\\/script>/gi);
if (scriptMatches) {
scriptMatches.forEach((m: string, i: number) => {
if (m.includes('lat') || m.includes('Lng') || m.includes('Points') || m.includes('Markers')) {
console.log("Found something in script " + i);
console.log(m.substring(0, 500)); // preview
}
});
}
} catch (e: any) {
console.error(e.message);
}
}
checkMap();
+33
View File
@@ -0,0 +1,33 @@
import axios from 'axios';
import * as cheerio from 'cheerio';
import https from 'https';
async function fetchLakes() {
const agent = new https.Agent({ rejectUnauthorized: false });
try {
const response = await axios.get('https://www.pvl.cz/portal/nadrze/cz/pc/Prehled.aspx', {
httpsAgent: agent,
headers: {
'User-Agent': 'Mozilla/5.0'
}
});
const $ = cheerio.load(response.data);
const lakes: any[] = [];
// Links to lakes usually look like Mereni.aspx?oid=xxx&id=yyy
$('a[href^="Mereni.aspx"]').each((i, el) => {
const href = $(el).attr('href');
const text = $(el).text().trim();
if (href && text) {
lakes.push({ href, text });
}
});
console.log(JSON.stringify(lakes, null, 2));
} catch (err: any) {
console.error('Error:', err.message);
}
}
fetchLakes();
+103
View File
@@ -0,0 +1,103 @@
import axios from 'axios';
import * as cheerio from 'cheerio';
import https from 'https';
import fs from 'fs';
import path from 'path';
import { lakesConfig } from './lakesConfig';
async function fixLevels() {
const agent = new https.Agent({ rejectUnauthorized: false });
const updatedConfig = [...lakesConfig];
for (let i = 0; i < updatedConfig.length; i++) {
const lake = updatedConfig[i];
// id is like SPKA|1 -> internalId is SPKA, oid is 1
const parts = lake.id.split('|');
if (parts.length !== 2) continue;
const internalId = parts[0];
const oid = parts[1];
const url = `https://www.pvl.cz/portal/nadrze/cz/pc/Mereni.aspx?id=${internalId}&oid=${oid}`;
try {
const response = await axios.get(url, {
httpsAgent: agent,
headers: { 'User-Agent': 'Mozilla/5.0' }
});
const $ = cheerio.load(response.data);
let maxRet: number | null = null;
let minStale: number | null = null;
let maxVol: number | null = null;
$('table').each((_, tbl) => {
const text = $(tbl).text();
// Parse levels
if (text.includes('Maximální retenční hladina:')) {
$(tbl).find('tr').each((_, row) => {
const rowText = $(row).text().replace(/\\s+/g, ' ');
if (rowText.includes('Maximální retenční hladina:')) {
const val = parseFloat(rowText.replace('Maximální retenční hladina:', '').replace('[m n.m.]', '').replace(',', '.').trim());
if (!isNaN(val)) maxRet = val;
}
if (rowText.includes('Hladina stálého nadržení:')) {
const val = parseFloat(rowText.replace('Hladina stálého nadržení:', '').replace('[m n.m.]', '').replace(',', '.').trim());
if (!isNaN(val)) minStale = val;
}
});
}
// Parse volume (this is current volume, wait, does PVL show max volume? Usually no, but current volume might be bigger than our guessed maxVolume)
if (text.includes('Aktuální hodnoty') && text.includes('Objem')) {
$(tbl).find('tr').each((_, row) => {
const rowText = $(row).text().replace(/\\s+/g, ' ');
if (rowText.includes('Objem [mil. m3]')) {
const valStr = $(row).find('td').eq(1).text().trim().replace(',', '.');
const val = parseFloat(valStr);
if (!isNaN(val)) maxVol = val; // We will just use the current volume as a baseline if it's bigger than our maxVolume
}
});
}
});
if (maxRet) updatedConfig[i].maxLevel = maxRet;
if (minStale) updatedConfig[i].minLevel = minStale;
// For volume, if the current volume is larger than the configured maxVolume, increase maxVolume
if (maxVol && updatedConfig[i].maxVolume && maxVol > updatedConfig[i].maxVolume!) {
updatedConfig[i].maxVolume = Math.ceil(maxVol * 1.2 * 10) / 10; // add 20% buffer
} else if (maxVol && !updatedConfig[i].maxVolume) {
updatedConfig[i].maxVolume = Math.ceil(maxVol * 1.5 * 10) / 10;
}
console.log(`Updated ${lake.text}: min=${minStale}, max=${maxRet}, vol=${maxVol} -> newMaxVol=${updatedConfig[i].maxVolume}`);
} catch (err: any) {
console.error(`Failed for ${lake.text}: ${err.message}`);
}
}
// Generate new file content
let newContent = `export interface LakeConfig {
id: string;
text: string;
priority?: boolean;
coords: [number, number];
maxVolume?: number;
minLevel?: number;
maxLevel?: number;
storageLevel?: number;
}
export const lakesConfig: LakeConfig[] = [
`;
updatedConfig.forEach((l, idx) => {
newContent += ` { id: "${l.id}", text: "${l.text}", ${l.priority ? 'priority: true, ' : ''}coords: [${l.coords[0].toFixed(4)}, ${l.coords[1].toFixed(4)}], maxVolume: ${l.maxVolume}, minLevel: ${l.minLevel}, maxLevel: ${l.maxLevel}, storageLevel: ${l.storageLevel} }${idx === updatedConfig.length - 1 ? '' : ','}\\n`;
});
newContent += `];\\n`;
fs.writeFileSync(path.resolve('./scripts/lakesConfig.ts'), newContent);
console.log("lakesConfig.ts updated!");
}
fixLevels();
+101
View File
@@ -0,0 +1,101 @@
import axios from 'axios';
import * as cheerio from 'cheerio';
import https from 'https';
import fs from 'fs';
import path from 'path';
import { lakesConfig } from './lakesConfig';
async function fixStorageLevels() {
const agent = new https.Agent({ rejectUnauthorized: false });
const updatedConfig = [...lakesConfig];
for (let i = 0; i < updatedConfig.length; i++) {
const lake = updatedConfig[i];
const parts = lake.id.split('|');
if (parts.length !== 2) continue;
const internalId = parts[0];
const oid = parts[1];
const url = `https://www.pvl.cz/portal/nadrze/cz/pc/Mereni.aspx?id=${internalId}&oid=${oid}`;
try {
const response = await axios.get(url, {
httpsAgent: agent,
headers: { 'User-Agent': 'Mozilla/5.0' }
});
const $ = cheerio.load(response.data);
let storageLevelFound: number | null = null;
let maxVol: number | null = null;
$('table').each((_, tbl) => {
const text = $(tbl).text();
// Parse storage level
if (text.includes('Hladina zásobního prostoru:')) {
$(tbl).find('tr').each((_, row) => {
const rowText = $(row).text().replace(/\\s+/g, ' ');
if (rowText.includes('Hladina zásobního prostoru:')) {
const val = parseFloat(rowText.replace('Hladina zásobního prostoru:', '').replace('[m n.m.]', '').replace(',', '.').trim());
if (!isNaN(val)) storageLevelFound = val;
}
});
}
// Parse current volume
if (text.includes('Aktuální hodnoty') && text.includes('Objem')) {
$(tbl).find('tr').each((_, row) => {
const rowText = $(row).text().replace(/\\s+/g, ' ');
if (rowText.includes('Objem [mil. m3]')) {
const valStr = $(row).find('td').eq(1).text().trim().replace(',', '.');
const val = parseFloat(valStr);
if (!isNaN(val)) maxVol = val;
}
});
}
});
if (storageLevelFound !== null) {
updatedConfig[i].storageLevel = storageLevelFound;
} else {
// if PVL doesn't have it, remove our fake guess so we fallback to maxLevel
delete updatedConfig[i].storageLevel;
}
// Fix maxVolume if current volume exceeds it
if (maxVol && updatedConfig[i].maxVolume && maxVol > updatedConfig[i].maxVolume!) {
updatedConfig[i].maxVolume = Math.ceil(maxVol * 1.05 * 10) / 10;
} else if (maxVol && !updatedConfig[i].maxVolume) {
updatedConfig[i].maxVolume = Math.ceil(maxVol * 1.05 * 10) / 10;
}
console.log(`Updated ${lake.text}: storageLevel=${storageLevelFound}, currVol=${maxVol} -> newMaxVol=${updatedConfig[i].maxVolume}`);
} catch (err: any) {
console.error(`Failed for ${lake.text}: ${err.message}`);
}
}
let newContent = `export interface LakeConfig {
id: string;
text: string;
priority?: boolean;
coords: [number, number];
maxVolume?: number;
minLevel?: number;
maxLevel?: number;
storageLevel?: number;
navigationForbidden?: boolean;
}
export const lakesConfig: LakeConfig[] = [
`;
updatedConfig.forEach((l, idx) => {
newContent += ` { id: "${l.id}", text: "${l.text}", ${l.priority ? 'priority: true, ' : ''}coords: [${l.coords[0].toFixed(4)}, ${l.coords[1].toFixed(4)}], maxVolume: ${l.maxVolume}, minLevel: ${l.minLevel}, maxLevel: ${l.maxLevel}, ${l.storageLevel ? 'storageLevel: ' + l.storageLevel + ', ' : ''}navigationForbidden: ${l.navigationForbidden} }${idx === updatedConfig.length - 1 ? '' : ','}\n`;
});
newContent += `];\n`;
fs.writeFileSync(path.resolve('./scripts/lakesConfig.ts'), newContent);
console.log("lakesConfig.ts updated with precise storage levels!");
}
fixStorageLevels();
+40 -9
View File
@@ -7,16 +7,47 @@ export interface LakeConfig {
minLevel?: number;
maxLevel?: number;
storageLevel?: number;
navigationForbidden?: boolean;
}
export const lakesConfig: LakeConfig[] = [
{ id: "VLL1|1", text: "VD Lipno 1 - Vltava", priority: true, coords: [48.6322, 14.2215], maxVolume: 306.0, minLevel: 715.00, maxLevel: 725.60, storageLevel: 724.9 },
{ id: "VLL2|1", text: "VD Lipno II - Vltava", priority: true, coords: [48.6250, 14.3180], maxVolume: 1.5, minLevel: 557.0, maxLevel: 562.5, storageLevel: 560.5 },
{ id: "VLHN|1", text: "VD Hněvkovice - Vltava", priority: true, coords: [49.1830, 14.4440], maxVolume: 21.1, minLevel: 365.0, maxLevel: 370.5, storageLevel: 370.1 },
{ id: "VLKO|1", text: "VD Kořensko - Vltava", priority: true, coords: [49.2550, 14.3980], maxVolume: 2.8, minLevel: 352.0, maxLevel: 353.5, storageLevel: 352.6 },
{ id: "VLOR|2", text: "VD Orlík - Vltava", priority: true, coords: [49.6060, 14.1700], maxVolume: 716.5, minLevel: 330.00, maxLevel: 354.00, storageLevel: 349.9 },
{ id: "VLSL|2", text: "VD Slapy - Vltava", priority: true, coords: [49.8220, 14.4360], maxVolume: 269.3, minLevel: 265.50, maxLevel: 271.10, storageLevel: 270.6 },
{ id: "VLST|2", text: "VD Štěchovice - Vltava", priority: true, coords: [49.8450, 14.4120], maxVolume: 11.2, minLevel: 217.0, maxLevel: 219.5, storageLevel: 219.4 },
{ id: "MARI|1", text: "VD Římov - Malše", priority: true, coords: [48.8470, 14.4870], maxVolume: 33.8, minLevel: 458.0, maxLevel: 471.0, storageLevel: 470.65 },
{ id: "MZHR|3", text: "VD Hracholusky - Mže", priority: true, coords: [49.7890, 13.1550], maxVolume: 56.7, minLevel: 350.5, maxLevel: 371.0, storageLevel: 369.5 }
{ id: "VLL1|1", text: "VD Lipno 1 - Vltava", priority: true, coords: [48.6322, 14.2215], maxVolume: 306, minLevel: 716.1, maxLevel: 725.6, storageLevel: 724.9, navigationForbidden: false },
{ id: "VLL2|1", text: "VD Lipno II - Vltava", priority: true, coords: [48.6250, 14.3180], maxVolume: 1.6, minLevel: 557.6, maxLevel: 563.35, storageLevel: 562.7, navigationForbidden: false },
{ id: "VLHN|1", text: "VD Hněvkovice - Vltava", priority: true, coords: [49.1830, 14.4440], maxVolume: 21.1, minLevel: 364.6, maxLevel: 370.1, storageLevel: 370.1, navigationForbidden: false },
{ id: "VLKO|1", text: "VD Kořensko - Vltava", priority: true, coords: [49.2550, 14.3980], maxVolume: 2.8, minLevel: 347.8, maxLevel: 353.6, storageLevel: 352.6, navigationForbidden: false },
{ id: "VLOR|2", text: "VD Orlík - Vltava", priority: true, coords: [49.6060, 14.1700], maxVolume: 716.5, minLevel: 329.6, maxLevel: 353.6, storageLevel: 349.9, navigationForbidden: false },
{ id: "VLSL|2", text: "VD Slapy - Vltava", priority: true, coords: [49.8220, 14.4360], maxVolume: 269.3, minLevel: 246.6, maxLevel: 270.6, storageLevel: 270.6, navigationForbidden: false },
{ id: "VLST|2", text: "VD Štěchovice - Vltava", priority: true, coords: [49.8450, 14.4120], maxVolume: 11.2, minLevel: 215.8, maxLevel: 219.4, storageLevel: 219.4, navigationForbidden: false },
{ id: "MARI|1", text: "VD Římov - Malše", priority: true, coords: [48.8470, 14.4870], maxVolume: 33.8, minLevel: 442.5, maxLevel: 471.48, storageLevel: 470.65, navigationForbidden: true },
{ id: "MZHR|3", text: "VD Hracholusky - Mže", priority: true, coords: [49.7890, 13.1550], maxVolume: 56.7, minLevel: 339.6, maxLevel: 357.97, storageLevel: 354.1, navigationForbidden: false },
{ id: "ZESV|2", text: "VD Švihov (Želivka)", priority: true, coords: [49.7040, 15.1150], maxVolume: 266.6, minLevel: 343.1, maxLevel: 379.8, storageLevel: 377, navigationForbidden: true },
{ id: "VLKA|2", text: "VD Kamýk", coords: [49.6380, 14.2580], maxVolume: 12.8, minLevel: 282.1, maxLevel: 284.6, storageLevel: 284.6, navigationForbidden: false },
{ id: "VLVE|2", text: "VD Vrané", coords: [49.9390, 14.3910], maxVolume: 11.1, minLevel: 199.1, maxLevel: 200.1, storageLevel: 200.1, navigationForbidden: false },
{ id: "BLHU|1", text: "VD Husinec", coords: [49.0270, 13.9870], maxVolume: 5.7, minLevel: 515.33, maxLevel: 529.88, storageLevel: 522.33, navigationForbidden: true },
{ id: "UHNY|3", text: "VD Nýrsko", coords: [49.2610, 13.1230], maxVolume: 16, minLevel: 501.2, maxLevel: 524.25, storageLevel: 521.55, navigationForbidden: true },
{ id: "KCKC|3", text: "VD Klíčava", coords: [50.0630, 13.9310], maxVolume: 9.3, minLevel: 267.6, maxLevel: 296.91, storageLevel: 293.7, navigationForbidden: true },
{ id: "KLKL|3", text: "VD Klabava", coords: [49.7540, 13.5640], maxVolume: 1.5, minLevel: 344.4, maxLevel: 351.1, storageLevel: 345.7, navigationForbidden: false },
{ id: "RACU|3", text: "VD České Údolí", coords: [49.7150, 13.3640], maxVolume: 5.5, minLevel: 310.6, maxLevel: 315.2, storageLevel: 313.6, navigationForbidden: false },
{ id: "TRTR|2", text: "VD Trnávka", coords: [49.5260, 15.1950], maxVolume: 5.6, minLevel: 412, maxLevel: 414.5, storageLevel: 413.2, navigationForbidden: false },
{ id: "HESE|2", text: "VD Sedlice", coords: [49.5070, 15.2630], maxVolume: 1.9, minLevel: 443.9, maxLevel: 448.64, storageLevel: 447.4, navigationForbidden: false },
{ id: "MZLU|3", text: "VD Lučina", coords: [49.8050, 12.6390], maxVolume: 2.3, minLevel: 523, maxLevel: 534.68, storageLevel: 532.1, navigationForbidden: true },
{ id: "STZL|3", text: "VD Žlutice", coords: [50.0930, 13.1360], maxVolume: 14.5, minLevel: 493.6, maxLevel: 509.72, storageLevel: 507.05, navigationForbidden: true },
{ id: "PPPI|3", text: "VD Pilská (u Příbramě)", coords: [49.6910, 13.9570], maxVolume: 1.6, minLevel: 661.7, maxLevel: 672.7, storageLevel: 671.4, navigationForbidden: true },
{ id: "LILA|3", text: "VD Láz", coords: [49.6640, 13.8820], maxVolume: 0.8, minLevel: 630, maxLevel: 642.15, storageLevel: 641.35, navigationForbidden: true },
{ id: "OPOB|3", text: "VD Obecnice", coords: [49.7110, 13.9370], maxVolume: 0.6, minLevel: 555.65, maxLevel: 565.87, storageLevel: 564.55, navigationForbidden: true },
{ id: "STST|2", text: "VD Strž", coords: [49.7910, 14.0040], maxVolume: 1, minLevel: 586.6, maxLevel: 589.2, storageLevel: 588.6, navigationForbidden: false },
{ id: "HEVR|2", text: "VD Vřesník", coords: [49.5070, 15.2440], maxVolume: 0.5, minLevel: 406.85, maxLevel: 409.08, storageLevel: 407.6, navigationForbidden: false },
{ id: "CRSO|1", text: "VD Soběnov", coords: [48.7750, 14.5360], maxVolume: 1.4, minLevel: 579.81, maxLevel: 583.26, storageLevel: 582.21, navigationForbidden: false },
{ id: "SCHU|1", text: "VD Humenice", coords: [48.7840, 14.7350], maxVolume: 0.8, minLevel: 531, maxLevel: 544, storageLevel: 536, navigationForbidden: false },
{ id: "SVSV|2", text: "VD Staviště", coords: [49.5750, 15.9520], maxVolume: 1.2, minLevel: 574.6, maxLevel: 581.6, storageLevel: 580.6, navigationForbidden: true },
{ id: "SAPI|2", text: "VD Pilská u Žďáru", coords: [49.5930, 15.9320], maxVolume: 1.5, minLevel: 571.8, maxLevel: 577.3, storageLevel: 576.6, navigationForbidden: false },
{ id: "SMSM|3", text: "VD Suchomasty", coords: [49.8970, 14.0580], maxVolume: 0.7, minLevel: 249.8, maxLevel: 260.9, storageLevel: 260.1, navigationForbidden: false },
{ id: "CPZA|3", text: "VD Záskalská", coords: [49.8050, 13.8510], maxVolume: 0.5, minLevel: 440.54, maxLevel: 449.39, storageLevel: 448.79, navigationForbidden: false },
{ id: "BIBI|1", text: "VD Bílsko", coords: [49.1670, 14.0410], maxVolume: 0.3, minLevel: 463.03, maxLevel: 471.6, storageLevel: 464.03, navigationForbidden: false },
{ id: "SPKA|1", text: "VD Karhof", coords: [48.9740, 14.5450], maxVolume: 0.3, minLevel: 666.8, maxLevel: 669.1, storageLevel: 668.4, navigationForbidden: false },
{ id: "SPNE|2", text: "VD Němčice", coords: [49.7710, 15.1760], maxVolume: 0.4, minLevel: 384.5, maxLevel: 386.4, storageLevel: 385, navigationForbidden: false },
{ id: "SPZH|1", text: "VD Zhejral", coords: [49.2310, 15.3120], maxVolume: 0.2, minLevel: 675.2, maxLevel: 679.7, storageLevel: 678.6, navigationForbidden: true },
{ id: "KLDP|3", text: "VD Dolejší Padrťský rybník", coords: [49.6640, 13.7530], maxVolume: 0.5, minLevel: 632.69, maxLevel: 634.29, storageLevel: 632.89, navigationForbidden: true },
{ id: "KLHP|3", text: "VD Hořejší Padrťský rybník", coords: [49.6550, 13.7610], maxVolume: 0.7, minLevel: 635.76, maxLevel: 637.56, storageLevel: 636.36, navigationForbidden: true },
{ id: "CPDR|3", text: "VD Dráteník", coords: [49.8050, 13.8550], maxVolume: 0.1, minLevel: 413.75, maxLevel: 417.91, storageLevel: 416.68, navigationForbidden: false }
];
+32
View File
@@ -0,0 +1,32 @@
import axios from 'axios';
import * as cheerio from 'cheerio';
import https from 'https';
async function checkLake() {
const agent = new https.Agent({ rejectUnauthorized: false });
// Check Lipno 1
const url = `https://www.pvl.cz/portal/nadrze/cz/pc/Mereni.aspx?id=VLL1&oid=1`;
try {
const response = await axios.get(url, {
httpsAgent: agent,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
}
});
const $ = cheerio.load(response.data);
let hasData = false;
$('table').each((i, tbl) => {
const firstRowText = $(tbl).find('tr').first().text();
console.log(`Table ${i} first row:`, firstRowText.trim().replace(/\\s+/g, ' '));
if (firstRowText.includes('Datum a čas') || firstRowText.includes('Hladina')) {
hasData = true;
}
});
console.log(`hasData=${hasData}`);
} catch (err: any) {
console.error(err.message);
}
}
checkLake();