Last active
June 14, 2025 11:44
-
-
Save AndreasKueck/984f2ef3b18620ba872a14fe44a58551 to your computer and use it in GitHub Desktop.
Akvonivelo en Rechtenfleth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Akvonivelo | |
// Tiu chi Ghavoskripto-programo kalkulas la akvonivelon de rivero Weser en Rechtenfleth sekve de la interagoj de Tero, Luno kaj Suno surbaze de la harmona metodo. Referenco estas la akvonivela nulo ("Pegelnullpunkt", PNP). | |
// Bazo: | |
// 1) Kumm, Werner: "Gezeitenkunde : Theorie und Praxis", Delius-Klasing, Bielefeld, 1992, paghoj 126-129. | |
// 2) Datumoj donitaj en | |
// a) a) https://gezeiten.bsh.de/rechtenfleth kaj | |
// b) Hart-Davis, Michael G; Dettmering, Denise; Seitz, Florian (2022): TICON-3: Tidal Constants based on GESLA-3 sea-level records from globally distributed tide gauges including gauge type information (data) [dataset]. PANGAEA, https://doi.org/10.1594/PANGAEA.951610 | |
// c) https://legacy.iho.int/mtg_docs/com_wg/IHOTC/IHOTC8/Product_Spec_for_Exchange_of_HCs.pdf (por la Doodson-nombroj) | |
// 3) https://refmar.shom.fr/sites/default/files/2024-01/TIPE_formulation.pdf | |
// Noto: La datumoj de BSH estas kalkulitaj ne per la harmona metodo, sed per la metodo de la harmona prezento de la neegalajhoj. Tial kaj krome pro la malnoveco de la datumoj de 3) diferencoj inter la eligoj de tiu chi programo kaj la indikoj de BSH estas vershajnaj. Kiam ekzaktaj indikoj estas necesaj, oni chiam konsultu la indikojn de BSH. | |
// Precipe por aktualaj indikoj ankau jena retpagho estas konsultinda: | |
// https://www.pegelonline.wsv.de/gast/stammdaten?pegelnr=4970030. | |
// La akvonivelo rilatas al la ""Pegelnullpunkt" (PNP). | |
// Ekzemplaj eligoj por kontrolo: | |
// A) jaro = 2024, monato = 8, tago = 29, zt = 13.4; eligo: 4.169816 | |
// B) jaro = 2024, monato = 8, tago = 29, zt = -1; eligo: | |
// 03:05 MET 3,5 m | |
// 15:43 MET 3,4 m | |
// 09:13 MET 6,5 m | |
// 21:53 MET 6,4 m | |
var jaro = {lv=jaro}; | |
var monato = {lv=monato}; | |
var tago = {lv=tago}; | |
var zt = {lv=horo}; // En hh.mm; se negativa zt estas enigita, tiam la tempoj de akvoniveloj minimumaj kaj maksimumaj estas eligataj. | |
// var jaro = 2025; | |
// var monato = 5; | |
// var tago = 20; | |
// var zt = -1 | |
var w=[]; | |
var z=[]; | |
var h=[]; | |
var nw=[]; | |
var hw=[]; | |
var min = []; | |
var max=[]; | |
function main() { | |
var nvo = -999.9; | |
var zt1 = zt; | |
var zt2 = 0.0; | |
var rezulto = ''; | |
var i = 0; | |
var j = 0; | |
var k = 0; | |
var nwminh1 = 999.9; | |
var nwminz1 = ''; | |
var nwminh2 = 999.9; | |
var nwminz2 = ''; | |
var hwmaxh1 = -999.9; | |
var hwmaxz1 = ''; | |
var hwmaxh2 = -999.9; | |
var hwmaxz2 = ''; | |
if (zt>=0.0) { | |
zt1 = zt; | |
nvo = niv(zt1, 0); | |
} else { | |
for (i=-1;i<1442;i++) { | |
zt1 = i*0.01*5.0/3.0; | |
zt2 = (zt1 - Math.floor(zt1)) * 3/5 + Math.floor(zt1); | |
z[i] = zt1; | |
h[i] = niv(zt2, 0.0); | |
} | |
for (i=0;i<1441;i++) { | |
if (h[i]<(h[i-1]) && h[i]<h[i+1]) { | |
nw[j] = z[i]; | |
min[j] = h[i]; | |
j++; | |
} | |
if (h[i]>h[i-1] && h[i]>h[i+1]) { | |
hw[k] = z[i]; | |
max[k] = h[i]; | |
k++; | |
} | |
} | |
var lj = nw.length; | |
var lj1 = Math.floor(lj/2.0); | |
for (i=0;i<lj1;i++) { | |
if (min[i]<nwminh1) { | |
nwminh1 = min[i]; | |
nwminz1 = nw[i]; | |
} | |
} | |
for (i=lj1;i<lj;i++) { | |
if (min[i]<nwminh2) { | |
nwminh2 = min[i]; | |
nwminz2 = nw[i]; | |
} | |
} | |
var lk = hw.length; | |
var lk1 = Math.floor(lk/2.0); | |
for (i=0;i<lk1;i++) { | |
if (max[i]>hwmaxh1) { | |
hwmaxh1 = max[i]; | |
hwmaxz1 = hw[i]; | |
} | |
} | |
for (i=lk1;i<lk;i++) { | |
if (max[i]>hwmaxh2) { | |
hwmaxh2 = max[i]; | |
hwmaxz2 = hw[i]; | |
} | |
} | |
nwminz1 = (nwminz1 - Math.floor(nwminz1)) * 3/5 + Math.floor(nwminz1); | |
nwminz2 = (nwminz2 - Math.floor(nwminz2)) * 3/5 + Math.floor(nwminz2); | |
hwmaxz1 = (hwmaxz1 - Math.floor(hwmaxz1)) * 3/5 + Math.floor(hwmaxz1); | |
hwmaxz2 = (hwmaxz2 - Math.floor(hwmaxz2)) * 3/5 + Math.floor(hwmaxz2); | |
var rnwz1 = Math.round(nwminz1*100)/100 + " MET "; | |
var rnwz2 = Math.round(nwminz2*100)/100 + " MET "; | |
var rhwz1 = Math.round(hwmaxz1*100)/100 + " MET "; | |
var rhwz2 = Math.round(hwmaxz2*100)/100 + " MET "; | |
var rnwh1 = Math.round(nwminh1*10)/10 + " m"; | |
var rnwh2 = Math.round(nwminh2*10)/10 + " m"; | |
var rhwh1 = Math.round(hwmaxh1*10)/10 + " m"; | |
var rhwh2 = Math.round(hwmaxh2*10)/10 + " m"; | |
var srnwz1 = rnwz1.replace(/\./, ":"); | |
var srnwz2 = rnwz2.replace(/\./, ":"); | |
var srhwz1 = rhwz1.replace(/\./, ":"); | |
var srhwz2 = rhwz2.replace(/\./, ":"); | |
var srnwh1 = rnwh1.replace(/\./, ","); | |
var srnwh2 = rnwh2.replace(/\./, ","); | |
var srhwh1 = rhwh1.replace(/\./, ","); | |
var srhwh2 = rhwh2.replace(/\./, ","); | |
if (/999/.test(srnwh1)) { | |
srnwh1 = ""; | |
srnwz1 = ""; | |
} | |
if (/999/.test(srnwh2)) { | |
srnwh2 = ""; | |
srnwz2 = ""; | |
} | |
if (/999/.test(srhwh1)) { | |
srhwh1 = ""; | |
srhwz1 = ""; | |
} | |
if (/999/.test(srhwh2)) { | |
srhwh2 = ""; | |
srhwz2 = ""; | |
} | |
if (/\:\d MET/.test(srnwz1)) {srnwz1 = srnwz1.replace(/ MET/, "0 MET");} | |
if (/\:\d MET/.test(srnwz2)) {srnwz2 = srnwz2.replace(/ MET/, "0 MET");} | |
if (/\:\d MET/.test(srhwz1)) {srhwz1 = srhwz1.replace(/ MET/, "0 MET");} | |
if (/\:\d MET/.test(srhwz2)) {srhwz2 = srhwz2.replace(/ MET/, "0 MET");} | |
if (!(/\:/.test(srnwz1))) {srnwz1 = srnwz1.replace(/ MET/, ":00 MET");} | |
if (!(/\:/.test(srnwz2))) {srnwz2 = srnwz2.replace(/ MET/, ":00 MET");} | |
if (!(/\:/.test(srhwz1))) {srhwz1 = srhwz1.replace(/ MET/, ":00 MET");} | |
if (!(/\:/.test(srhwz2))) {srhwz2 = srhwz2.replace(/ MET/, ":00 MET");} | |
if (!(/\d\,\d m/.test(srnwh1))) {srnwh1 = srnwh1.replace(/ m/, ",0 m");} | |
if (!(/\d\,\d m/.test(srnwh2))) {srnwh2 = srnwh2.replace(/ m/, ",0 m");} | |
if (!(/\d\,\d m/.test(srhwh1))) {srhwh1 = srhwh1.replace(/ m/, ",0 m");} | |
if (!(/\d\,\d m/.test(srhwh2))) {srhwh2 = srhwh2.replace(/ m/, ",0 m");} | |
srnwz1 = srnwz1.replace(/(\d+):60 MET /, function(match, horo60) {return (parseInt(horo60) + 1) + ":00 MET ";}); | |
srnwz2 = srnwz2.replace(/(\d+):60 MET /, function(match, horo60) {return (parseInt(horo60) + 1) + ":00 MET ";}); | |
srhwz1 = srhwz1.replace(/(\d+):60 MET /, function(match, horo60) {return (parseInt(horo60) + 1) + ":00 MET ";}); | |
srhwz2 = srhwz2.replace(/(\d+):60 MET /, function(match, horo60) {return (parseInt(horo60) + 1) + ":00 MET ";}); | |
if (srnwz1.length == 9) {srnwz1 = "0" + srnwz1;} | |
if (srnwz2.length == 9) {srnwz2 = "0" + srnwz2;} | |
if (srhwz1.length == 9) {srhwz1 = "0" + srhwz1;} | |
if (srhwz2.length == 9) {srhwz2 = "0" + srhwz2;} | |
rezulto = srnwz1 + srnwh1 + '\n' + srnwz2 + srnwh2 + '\n' + srhwz1 + srhwh1 + '\n' + srhwz2 + srhwh2; | |
} | |
if (zt>=0.0) { | |
console.log(Math.round(nvo*1000000)/1000000); | |
} else { | |
console.log(rezulto); | |
} | |
} | |
function niv(zt1, td) { | |
var zp = (zt1 - Math.floor(zt1)) * 5 / 3 + Math.floor(zt1) + td; | |
var gt = Math.floor(30.6001 * (1 + monato + 12 * Math.floor(1 / (monato + 1) + 0.7))) + Math.floor(365.25 * (jaro - Math.floor(1 / (monato + 1) + 0.7))) + tago + zp / 24 - 723258; | |
var s = 78.16001 + 13.17639673 * gt; | |
var h0 = 279.82 + 0.98564734 * gt; | |
var pp = 349.5 + 0.11140408 * gt; | |
var ns = 208.1 + 0.05295392 * gt; | |
var n90 = 90; | |
var q = 282.6 + 0.000047069 * gt; | |
const datumoj =`M2 170.994 32.168 2 0 0 0 0 0 0 | |
K1 7.079 67.901 1 1 0 0 0 0 1 | |
N2 26.154 7.637 2 -1 0 1 0 0 0 | |
O1 9.099 274.716 1 -1 0 0 0 0 -1 | |
P1 3.146 73.706 1 1 -2 0 0 0 -1 | |
Q1 2.673 214.107 1 -2 0 1 0 0 -1 | |
K2 12.562 107.871 2 2 0 0 0 0 0 | |
S2 42.584 110.784 2 2 -2 0 0 0 0 | |
S1 1.618 78.700 1 1 -1 0 0 0 0 | |
SA 6.124 305.594 0 0 1 0 0 0 0 | |
T2 2.463 87.256 2 2 -3 0 0 1 0 | |
MF 0.662 95.833 0 2 0 0 0 0 0 | |
MM 0.770 159.332 0 1 0 -1 0 0 0 | |
2N2 3.061 343.032 2 -2 0 2 0 0 0 | |
M4 11.868 252.373 4 0 0 0 0 0 0 | |
J1 0.382 203.130 1 2 0 -1 0 0 1 | |
SSA 2.838 225.394 0 0 2 0 0 0 0 | |
MSF 2.968 68.827 0 2 -2 0 0 0 0 | |
EP2 4.467 88.707 2 -3 2 1 0 0 0 | |
L2 15.189 48.411 2 1 0 -1 0 0 2 | |
M3 0.422 295.548 3 0 0 0 0 0 2 | |
R2 0.158 55.811 2 2 -1 0 0 -1 2 | |
MI2 21.532 112.726 2 -2 2 0 0 0 0 | |
NI2 10.807 345.123 2 -1 2 -1 0 0 0 | |
LM2 7.039 46.572 2 1 -2 1 0 0 2 | |
MN4 3.586 231.057 4 -1 0 1 0 0 0 | |
MS4 8.538 336.398 4 2 -2 0 0 0 0 | |
N4 0.770 205.363 4 -2 0 2 0 0 0 | |
M6 7.894 150.388 6 0 0 0 0 0 0 | |
M8 1.693 93.473 8 0 0 0 0 0 0 | |
S4 1.215 124.545 4 4 -4 0 0 0 0 | |
2Q1 0.541 162.254 1 -3 0 2 0 0 -1 | |
OO1 0.237 256.226 1 3 0 0 0 0 1 | |
S3 0.076 159.368 3 3 -3 0 0 0 2 | |
MA2 5.354 354.443 2 0 -1 0 0 0 0 | |
MB2 1.376 121.698 2 0 1 0 0 0 0 | |
M1 0.764 59.622 1 0 0 0 0 0 0 | |
MSQ 0.522 56.085 0 4 -2 0 0 0 0 | |
MTM 0.347 218.454 0 3 -2 1 0 0 0 | |
MKS 2.230 189.855 2 0 2 0 0 0 0` | |
const components = datumoj | |
.trim() | |
.split('\n') | |
.map(line => { | |
const p = line.trim().split(/\s+/); | |
return | |
nomo: p[0], | |
a: parseFloat(p[1]), | |
u: parseFloat(p[2]) * Math.PI/180, | |
kh0s: parseFloat(p[3]), | |
ks: parseFloat(p[4]), | |
kh0: parseFloat(p[5]), | |
kpp: parseFloat(p[6]), | |
kns: parseFloat(p[7]), | |
kq: parseFloat(p[8]), | |
kn90: parseFloat(p[9]) | |
}; | |
}); | |
let h2 = 0; | |
for (let c of components) { | |
h2 += c.a * Math.cos((c.kh0s*zp*15 + s*(c.ks-c.kh0s) + h0*(c.kh0+c.kh0s) + pp*c.kpp + ns*c.kns + q*c.kq + n90*c.kn90) * Math.PI/180 - c.u); | |
// Nodaj korektoj por M2, O1, K1 kaj K2 lau bazo n-ro 3 (por la nodaj korektoj de K2 estas uzata S2) | |
if (c.nomo == 'M2') { | |
h2 = h2 - c.a/27 * Math.cos((c.kh0s*zp*15 + s*(c.ks-c.kh0s) + h0*(c.kh0+c.kh0s) + pp*c.kpp + ns*(c.kns-1) + q*c.kq + n90*c.kn90) * Math.PI/180 - c.u); | |
} | |
if (c.nomo == 'O1') { | |
h2 = h2 + c.a/5.3 * Math.cos((c.kh0s*zp*15 + s*(c.ks-c.kh0s) + h0*(c.kh0+c.kh0s) + pp*c.kpp + ns*(c.kns-1) + q*c.kq + n90*c.kn90) * Math.PI/180 - c.u); | |
} | |
if (c.nomo == 'K1') { | |
h2 = h2 + c.a/7.4 * Math.cos((c.kh0s*zp*15 + s*(c.ks-c.kh0s) + h0*(c.kh0+c.kh0s) + pp*c.kpp + ns*(c.kns+1) + q*c.kq + n90*c.kn90) * Math.PI/180 - c.u); | |
} | |
if (c.nomo == 'S2') { | |
h2 = h2 + c.a/12 * Math.cos((c.kh0s*zp*15 + s*(c.ks-c.kh0s) + h0*(c.kh0+c.kh0s+2) + pp*c.kpp + ns*(c.kns+1) + q*c.kq + n90*c.kn90) * Math.PI/180 - c.u); | |
} | |
}; | |
// h2 estas la akvonivelo en metroj; referenco: akvonivela nulo ("Pegelnullpunkt", PNP). | |
h2 = h2 / 100 + 507.5 / 100; | |
return h2; | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
La supra algoritmo estas efektivigita en jenaj Snapchat-lensoj: