summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2015-11-17 13:31:40 +0100
committerErich Eckner <git@eckner.net>2015-11-17 13:31:40 +0100
commitb80559044ffc627e897bba6df2c15c1b28d732de (patch)
tree65b77f7cf8347c98744405982bb383e8849e527a
parentb861e26f594e1fd8472d513430da1296eed023ba (diff)
downloadFH-Wetter-b80559044ffc627e897bba6df2c15c1b28d732de.tar.xz
soweit lauffähig
ToDo: Taskbaricon
-rw-r--r--fhunit.pas583
-rw-r--r--pegelunit.pas143
-rw-r--r--unit1.lfm1
-rw-r--r--unit1.pas53
-rw-r--r--wetter.konf2
-rw-r--r--wetter.lps164
6 files changed, 766 insertions, 180 deletions
diff --git a/fhunit.pas b/fhunit.pas
index 02c9d6d..fcfa1b6 100644
--- a/fhunit.pas
+++ b/fhunit.pas
@@ -5,19 +5,91 @@ unit fhunit;
interface
uses
- Classes, SysUtils, Graphics;
+ CThreads, Classes, SysUtils, Graphics, ExtCtrls, Process, lowLevelUnit;
type
- tMessgroesze = (mgTemperatur,mgLuftfeuchte,mgWindgeschwindigkeit,mgWindrichtung,
+ tMessGroesze = (mgTemperatur,mgLuftfeuchte,mgWindgeschwindigkeit,mgWindrichtung,
mgNiederschlag,mgGlobalstrahlung,mgLuftdruck);
- tZeitgroesze = (zgJahr,zgMonat,zgTag,zgStunde,zgMin10);
- tMesswerte = array[tMessgroesze] of extended;
- tZeit = array[tZeitgroesze] of integer;
- tMesspunkt = record
- zeit: tZeit;
- mW: tMesswerte;
+ tMessGroeszenSet = set of tMessGroesze;
+ tZeitGroesze = (zgJahr,zgMonat,zgTag,zgStunde,zgMin10);
+ tMessWerte = array[tMessGroesze] of extended;
+ tMessWerteExtPoints = array[tMessGroesze] of tExtPoint;
+ tZeit = array[tZeitGroesze] of word;
+
+ tMessPunkte = class;
+
+ tMessPunkt = class
+ private
+ _mZeit: tZeit;
+ _uZeit: extended;
+ _mW: tMessWerte;
+ procedure setzeUZeit; inline;
+ procedure setzeZeit; inline;
+ function rMW(mG: tMessGroesze): extended; inline;
+ public
+ constructor create;
+ destructor destroy; override;
+ function lade(s: string): boolean;
+ function schreibe: string;
+ property zeit: extended
+ read _uZeit;
+ property mW[mG: tMessGroesze]: extended
+ read rMW;
+ end;
+
+ tMessPunkteListe = class
+ private
+ inhalt: tFPList;
+ function rItem(i: longint): tMessPunkt;
+ function bisekt(zeit: extended): longint;
+ public
+ constructor create;
+ destructor destroy; override;
+ function add(s: string): boolean;
+ function last: tMessPunkt;
+ function count: longint;
+ property items[i: longint]: tMessPunkt
+ read rItem; default;
+ function minMaxY(startZeit,stopZeit: extended): tMessWerteExtPoints;
+ end;
+
+ tMessPunkteUpdateThread = class(tThread)
+ private
+ _besitzer: tMessPunkte;
+ antwort: string;
+ ladeProzess: tProcess;
+ beendet,
+ warGueltig: boolean;
+ nZeit: extended;
+ _tNum,_tAnz: longint;
+ procedure uebernehmen;
+ procedure nZeitNullen; inline;
+ public
+ beenden: boolean;
+ constructor create(besitzer: tMessPunkte; tNum,tAnz: longint);
+ destructor destroy; override;
+ procedure execute; override;
+ end;
+
+ tMessPunkte = class
+ private
+ bild: tImage;
+ werte: tMessPunkteListe;
+ muts: array of tMessPunkteUpdateThread;
+ public
+ constructor create(zeichenFlaeche: tImage);
+ destructor destroy; override;
+ function einlesen(was: string): boolean;
+ procedure laden(von: string);
+ procedure speichern(nach: string);
+ procedure achsenZeichnen(zuZeichnen: tMessGroeszenSet; startZeit,stopZeit: extended);
+ procedure graphenZeichnen(zuZeichnen: tMessGroeszenSet; startZeit,stopZeit: extended);
+ procedure mutBeenden;
end;
+procedure uZeit2mZeit(uZ: extended; out mZ: tZeit); inline;
+function strZuMZeit(s: string; out mZ: tZeit): boolean;
+
const
messNamen: array[tMessgroesze] of string =
('Temperatur','Luftfeuchte','Windgeschwindigkeit','Windrichtung',
@@ -25,12 +97,505 @@ const
maszEinheit: array[tMessgroesze] of string =
('°C','%','m/s','°','mm','W/m²','mbar');
monatsNamen: array[1..12] of string =
- ('Januar','Februar','März','April','Mai','Juni','Juli',
+ ('Januar','Februar','M'#$e4'rz','April','Mai','Juni','Juli',
'August','September','Oktober','November','Dezember');
farben: array[tMessgroesze] of tColor =
($0000DF,$CFAF7F,$007FFF,$FF00FF,$FFAF3F,$3FAFAF,$AFAFAF);
implementation
+uses unit1, math, systemUnit;
+
+// tMessPunkt ******************************************************************
+
+constructor tMessPunkt.create;
+var
+ zg: tZeitGroesze;
+ mg: tMessGroesze;
+begin
+ inherited create;
+ for zg:=low(zg) to high(zg) do
+ _mZeit[zg]:=0;
+ _uZeit:=0;
+ for mg:=low(mg) to high(mg) do
+ _mW[mg]:=0;
+end;
+
+destructor tMessPunkt.destroy;
+begin
+ inherited destroy;
+end;
+
+procedure tMessPunkt.setzeUZeit;
+begin
+ _uZeit:=
+ encodeDate(_mZeit[zgJahr],_mZeit[zgMonat],_mZeit[zgTag])+
+ encodeTime(_mZeit[zgStunde],_mZeit[zgMin10]*10,0,0)
+end;
+
+procedure tMessPunkt.setzeZeit;
+begin
+ uZeit2mZeit(_uZeit,_mZeit);
+end;
+
+function tMessPunkt.rMW(mG: tMessGroesze): extended;
+begin
+ result:=_mW[mG];
+end;
+
+function tMessPunkt.lade(s: string): boolean;
+var
+ zG: tZeitGroesze;
+ mG: tMessGroesze;
+ t: string;
+ istZahl: boolean;
+ i: longint;
+begin
+ result:=false;
+ if pos('<html>',s)=0 then begin // Format wie in letztes_Wetter.txt
+ {$WARNINGS-}
+ if decimalSeparator<>',' then
+ while pos(',',s)>0 do
+ s[pos(',',s)]:=decimalSeparator;
+ {$WARNINGS+}
+ for zG:=low(zG) to high(zG) do
+ _mZeit[zG]:=strtoint(erstesArgument(s,#9));
+ for mG:=high(mG) downto low(mG) do
+ _mW[mG]:=strtofloat(erstesArgument(s,#9));
+ while _mZeit[zgStunde]>=24 do begin
+ _mZeit[zgStunde]:=_mZeit[zgStunde]-24;
+ inc(_mZeit[zgTag]);
+ if _mZeit[zgTag]>30+byte(_mZeit[zgMonat] in [1,3,5,7,8,10,12])-(2-byte(_mZeit[zgJahr] mod 4 = 0))*byte(_mZeit[zgMonat]=2) then begin
+ _mZeit[zgTag]:=1;
+ inc(_mZeit[zgMonat]);
+ if _mZeit[zgMonat]>12 then begin
+ _mZeit[zgMonat]:=1;
+ inc(_mZeit[zgJahr]);
+ end;
+ end;
+ end;
+ setzeUZeit;
+ end
+ else begin // Format wie im Netz
+
+ delete(s,1,pos('<BODY',uppercase(s))-1);
+ s:=copy(s,1,pos('</BODY>',uppercase(s)));
+ delete(s,1,pos('<CENTER>',uppercase(s)));
+ delete(s,1,pos('>',s));
+ s:=trim(s);
+ t:=trim(leftStr(s,pos('<',s)-1));
+ if not strZuMZeit(t,_mZeit) then
+ exit;
+ {$WARNINGS-}
+ if decimalSeparator<>'.' then
+ while pos('.',s)>0 do
+ s[pos('.',s)]:=decimalSeparator;
+ {$WARNINGS+}
+ for mG:=low(mG) to high(mG) do begin
+ delete(s,1,pos(uppercase(messNamen[mG]),uppercase(s)));
+ delete(s,1,pos('>',s));
+ t:=trim(leftStr(s,pos('<',S)-1));
+ istZahl:=t<>'';
+ for i:=1 to length(t) do
+ istZahl:=istZahl and (t[i] in ['0'..'9','.',',','-']);
+ if not istZahl then
+ exit;
+ _mW[mG]:=strtofloat(t);
+ end;
+ setzeUZeit;
+ end;
+ result:=true;
+end;
+
+function tMessPunkt.schreibe: string;
+var
+ zG: tZeitGroesze;
+ mG: tMessGroesze;
+begin
+ result:='';
+ for zG:=low(zG) to high(zG) do
+ result:=result+#9+inttostr(_mZeit[zG]);
+ for mG:=high(mG) downto low(mG) do
+ result:=result+#9+floattostr(mW[mG]);
+ result:=trim(result);
+end;
+
+// tMessPunkteListe ************************************************************
+
+constructor tMessPunkteListe.create;
+begin
+ inherited create;
+ inhalt:=tFPList.create;
+end;
+
+destructor tMessPunkteListe.destroy;
+begin
+ inhalt.free;
+ inherited destroy;
+end;
+
+function tMessPunkteListe.rItem(i: longint): tMessPunkt;
+begin
+ result:=tMessPunkt(inhalt[i]);
+end;
+
+function tMessPunkteListe.bisekt(zeit: extended): longint;
+var
+ mi,ma,neu: longint;
+begin
+ mi:=0;
+ neu:=mi;
+ ma:=count;
+ while mi<ma do begin
+ neu:=(mi+ma) div 2;
+ if (neu>=count) or (items[neu].zeit<zeit) then begin
+ inc(neu);
+ mi:=neu;
+ continue;
+ end;
+ if items[neu].zeit>zeit then begin
+ ma:=neu;
+ continue;
+ end;
+ result:=neu;
+ exit;
+ end;
+ result:=neu;
+end;
+
+function tMessPunkteListe.add(s: string): boolean;
+var
+ nm: tMessPunkt;
+ i: longint;
+begin
+ result:=false;
+ nm:=tMessPunkt.create;
+ if not nm.lade(s) then begin
+ nm.free;
+ exit;
+ end;
+ i:=bisekt(nm.zeit);
+ result:=true;
+ if (i>=count) or (items[i].zeit<>nm.zeit) then
+ inhalt.Insert(i,nm)
+ else
+ nm.free;
+end;
+
+function tMessPunkteListe.last: tMessPunkt;
+begin
+ result:=items[count-1];
+end;
+
+function tMessPunkteListe.count: longint;
+begin
+ result:=inhalt.count;
+end;
+
+function tMessPunkteListe.minMaxY(startZeit,stopZeit: extended): tMessWerteExtPoints;
+var
+ i: longint;
+ mG: tMessGroesze;
+begin
+ i:=bisekt(startZeit);
+ for mG:=low(mG) to high(mG) do begin
+ result[mG,'x']:=items[i].mW[mG];
+ result[mG,'y']:=result[mG,'x'];
+ end;
+ while (i<count) and (items[i].zeit<=stopZeit) do begin
+ for mG:=low(mG) to high(mG) do begin
+ result[mG,'x']:=min(result[mG,'x'],items[i].mW[mG]);
+ result[mG,'y']:=max(result[mG,'y'],items[i].mW[mG]);
+ end;
+ inc(i);
+ end;
+end;
+
+// tMessPunkteUpdateThread *****************************************************
+
+constructor tMessPunkteUpdateThread.create(besitzer: tMessPunkte; tNum,tAnz: longint);
+begin
+ inherited create(true);
+ _besitzer:=besitzer;
+ fillchar(antwort,sizeof(antwort),#0);
+ setlength(antwort,0);
+ ladeProzess:=nil;
+ beendet:=false;
+ _tNum:=tNum;
+ _tAnz:=tAnz;
+ beenden:=false;
+ warGueltig:=false;
+ nZeitNullen;
+ suspended:=false;
+end;
+
+destructor tMessPunkteUpdateThread.destroy;
+begin
+ while not beendet do
+ sleep(100);
+ setlength(antwort,0);
+ inherited destroy;
+end;
+
+procedure tMessPunkteUpdateThread.uebernehmen;
+begin
+ if beenden then exit;
+ warGueltig:=_besitzer.einlesen(antwort);
+ setlength(antwort,0);
+ if (not warGueltig) or (20*random<1) then
+ form1.zeichnen;
+end;
+
+procedure tMessPunkteUpdateThread.nZeitNullen;
+var
+ lIch: longint;
+begin
+ if beenden then exit;
+ lIch:=_besitzer.werte.count-1;
+ while round(_besitzer.werte[lIch].zeit*24*6) mod _tAnz <> _tNum do
+ dec(lIch);
+ nZeit:=_besitzer.werte[lIch].zeit + _tAnz*1/24/6;
+end;
+
+procedure tMessPunkteUpdateThread.execute;
+var
+ bytesToRead,bytesRead,cnt: longint;
+ mZeit: tZeit;
+begin
+ while not beenden do begin
+ ladeProzess:=tProcess.create(nil);
+ ladeProzess.options:=[poUsePipes];
+ ladeProzess.executable:='/usr/bin/curl';
+ ladeProzess.parameters.add('-o');
+ ladeProzess.parameters.add('-');
+ ladeProzess.parameters.add('--data');
+ uZeit2mZeit(nZeit,mZeit);
+ ladeProzess.parameters.add(
+ 'tag='+inttostr(mZeit[zgTag])+'&'+
+ 'monat='+Monatsnamen[mZeit[zgMonat]]+'&'+
+ 'jahr='+inttostr(mZeit[zgJahr])+'&'+
+ 'stunde='+inttostr(mZeit[zgStunde])+'&'+
+ 'minute='+inttostr(10*mZeit[zgMin10])+'&'+
+ 'submit=Abfrage starten');
+ ladeProzess.parameters.add('http://wetter.mb.fh-jena.de/station/datenbank/php_alt/abfrage1.php');
+ bytesRead:=0;
+ ladeProzess.execute;
+ ladeProzess.closeInput;
+ ladeProzess.closeStderr;
+ while (ladeProzess.running) or (ladeProzess.output.numBytesAvailable>0) do begin
+ if beenden then
+ ladeProzess.terminate(0);
+ bytesToRead:=ladeProzess.output.numBytesAvailable;
+ if bytesToRead>0 then begin
+ setlength(antwort,bytesRead + bufLengMin);
+ bytesRead:=bytesRead+ladeProzess.output.read(antwort[bytesRead+1],min(bytesToRead,length(antwort)-bytesRead));
+ end
+ else
+ sleep(10);
+ end;
+ ladeProzess.closeOutput;
+ ladeProzess.free;
+
+ if not beenden then begin
+ setlength(antwort,bytesRead);
+
+ synchronize(@uebernehmen);
+
+ if (nZeit<=now) or warGueltig then
+ nZeit:=nZeit + _tAnz*1/24/6
+ else begin
+ synchronize(@nZeitNullen);
+ for cnt:=0 to 599 do begin
+ if beenden then
+ break;
+ sleep(100);
+ end;
+ end;
+ end;
+ end;
+ ladeProzess:=nil;
+ beendet:=true;
+end;
+
+// tMessPunkte *****************************************************************
+
+constructor tMessPunkte.create(zeichenFlaeche: tImage);
+begin
+ inherited create;
+ bild:=zeichenFlaeche;
+ werte:=tMessPunkteListe.create;
+ fillchar(muts,sizeof(muts),#0);
+ setlength(muts,0);
+end;
+
+destructor tMessPunkte.destroy;
+var
+ i: longint;
+begin
+ werte.free;
+ for i:=0 to length(muts)-1 do
+ muts[i].free;
+ setlength(muts,0);
+ inherited destroy;
+end;
+
+function tMessPunkte.einlesen(was: string): boolean;
+begin
+ result:=werte.add(was);
+end;
+
+procedure tMessPunkte.laden(von: string);
+var
+ f: textfile;
+ s: string;
+ i: longint;
+begin
+ if not fileexists(von) then begin
+ writeln('Messwertedatei '''+von+''' existiert nicht!');
+ raise exception.create('Messwertedatei '''+von+''' existiert nicht!');
+ exit;
+ end;
+ assignfile(f,von);
+ reset(f);
+ while not eof(f) do begin
+ readln(f,s);
+ werte.add(s);
+ end;
+ closefile(f);
+ if length(muts)=0 then begin
+ setlength(muts,20);
+ for i:=0 to length(muts)-1 do
+ muts[i]:=tMessPunkteUpdateThread.create(self,i,length(muts));
+ end;
+end;
+
+procedure tMessPunkte.speichern(nach: string);
+var
+ dateischonda: boolean;
+ f: textfile;
+ i: longint;
+begin
+ dateischonda:=fileexists(nach);
+ if dateischonda then
+ assignfile(f,mkTemp(nach+'.XXXXXX'))
+ else
+ assignfile(f,nach);
+ rewrite(f);
+ for i:=0 to werte.count-1 do
+ writeln(f,werte[i].schreibe);
+ closefile(f);
+ if dateischonda then begin
+ deletefile(nach);
+ rename(f,nach);
+ end;
+end;
+
+procedure tMessPunkte.achsenZeichnen(zuZeichnen: tMessGroeszenSet; startZeit,stopZeit: extended);
+var
+ mG: tMessGroesze;
+ miMa: tMessWerteExtPoints;
+ dY,cY: extended;
+begin
+ miMa:=werte.minMaxY(startZeit,stopZeit);
+ for mG:=high(mG) downto low(mG) do
+ if mG in zuZeichnen then begin
+ bild.canvas.pen.color:=farben[mG];
+ dY:=power(10,ceil(ln(max(1e-9,miMa[mG,'y']-miMa[mG,'x']))/ln(10)));
+ repeat
+ if max(1e-9,miMa[mG,'y']-miMa[mG,'x'])/dY>=3 then continue;
+ dY:=dY/10*3;
+ if max(1e-9,miMa[mG,'y']-miMa[mG,'x'])/dY>=3 then continue;
+ dY:=dY/3;
+ until max(1e-9,miMa[mG,'y']-miMa[mG,'x'])/dY>=3;
+ cY:=ceil(miMa[mG,'x']/dY)*dY;
+ while cY<=miMa[mG,'y'] do begin
+ bild.canvas.moveTo(-10,wertZuY(cY,miMa[mG],bild.height));
+ bild.canvas.lineTo(bild.width+10,wertZuY(cY,miMa[mG],bild.height));
+ cY:=cY+dY;
+ end;
+ end;
+end;
+
+procedure tMessPunkte.graphenZeichnen(zuZeichnen: tMessGroeszenSet; startZeit,stopZeit: extended);
+var
+ mG: tMessGroesze;
+ miMa: tMessWerteExtPoints;
+ i: longint;
+begin
+ miMa:=werte.minMaxY(startZeit,stopZeit);
+ for mG:=high(mG) downto low(mG) do
+ if mG in zuZeichnen then begin
+ bild.canvas.pen.color:=farben[mG];
+ i:=werte.bisekt(startZeit);
+ bild.canvas.moveTo(
+ -10,
+ wertZuY(werte[i].mW[mG],miMa[mG],bild.height)
+ );
+ while (i<werte.count) and (werte[i].zeit<=stopZeit) do begin
+ bild.canvas.lineTo(
+ wertZuX(werte[i].zeit,startZeit,stopZeit,bild.width),
+ wertZuY(werte[i].mW[mG],miMa[mG],bild.height)
+ );
+ inc(i);
+ end;
+ end;
+end;
+
+procedure tMessPunkte.mutBeenden;
+var
+ i: longint;
+begin
+ for i:=0 to length(muts)-1 do
+ muts[i].beenden:=true;
+end;
+
+// allgemeine Funktionen *******************************************************
+
+procedure uZeit2mZeit(uZ: extended; out mZ: tZeit); inline;
+var
+ mi,se,hu: word;
+begin
+ decodeDate(uZ,mZ[zgJahr],mZ[zgMonat],mZ[zgTag]);
+ decodeTime(uZ,mZ[zgStunde],mi,se,hu);
+ mZ[zgMin10]:=round(mi/10);
+end;
+
+function strZuMZeit(s: string; out mZ: tZeit): boolean;
+var
+ t: string;
+ i: longint;
+begin
+ result:=false;
+ s:=trim(s);
+ if pos('.',s)=0 then exit;
+ t:=erstesArgument(s,'.');
+ if t='' then exit;
+ for i:=1 to length(t) do
+ if not (t[i] in ['0'..'9']) then exit;
+ mZ[zgTag]:=strtoint(t);
+ t:=erstesArgument(s);
+ mZ[zgMonat]:=1;
+ while (mZ[zgMonat]<=12) and (monatsNamen[mZ[zgMonat]]<>t) do
+ inc(mZ[zgMonat]);
+ if mZ[zgMonat]>12 then
+ exit;
+ t:=erstesArgument(s);
+ if t='' then exit;
+ for i:=1 to length(t) do
+ if not (t[i] in ['0'..'9']) then exit;
+ mZ[zgJahr]:=strtoint(t);
+ t:=erstesArgument(s,':');
+ if t='' then exit;
+ for i:=1 to length(t) do
+ if not (t[i] in ['0'..'9']) then exit;
+ mZ[zgStunde]:=strtoint(t);
+ t:=erstesArgument(s);
+ if t='' then exit;
+ for i:=1 to length(t) do
+ if not (t[i] in ['0'..'9']) then exit;
+ mZ[zgMin10]:=strtoint(t) div 10;
+ result:=(strtoint(t) mod 10) = 0;
+end;
+
end.
diff --git a/pegelunit.pas b/pegelunit.pas
index 3fe1529..033ea3d 100644
--- a/pegelunit.pas
+++ b/pegelunit.pas
@@ -106,7 +106,6 @@ const
(130,170,210,230),(200,230,260,290),(130,150,170,190),(0,0,0,0));
pegelFarben: array[tPegelstation] of tColor =
($000000,$000000,$000000,$FF0000,$7F0000,$000000,$000000,$000000,$000000,$000000,$000000,$000000);
- bufLengMin = 1024*1024;
// tPegelStand *****************************************************************
@@ -362,6 +361,76 @@ begin
inherited destroy;
end;
+procedure tPegelStaende.einlesen(was: string);
+var
+ t: string;
+ PS: TPegelstation;
+ psda,wsda,gefunden: boolean;
+ i: longint;
+begin
+ while pos(#13,was)>0 do
+ delete(was,pos(#13,was),1);
+ psda:=false;
+ wsda:=false;
+ pS:=low(tPegelStation);
+ while was<>'' do begin
+ t:=myUtf8Encode(erstesArgument(was,#10));
+ if length(t)=0 then continue;
+ if startetMit('Pegelname:',t) then begin
+ pS:=low(tPegelStation);
+ gefunden:=false;
+ while pS<=high(tPegelStation) do begin
+ for i:=0 to length(pegelStationsNamen[psBlankenstein])-1 do
+ gefunden:=gefunden or ((pegelStationsNamen[pS,i]<>'') and (pegelStationsNamen[pS,i]=t));
+ if gefunden then break;
+ inc(pS);
+ end;
+ if not gefunden then begin
+ writeln('Unbekannter Pegelname: '''+t+'''!');
+ for i:=1 to length(t) do
+ write(ord(t[i]),' ');
+ writeln;
+ for i:=1 to length(pegelStationsNamen[psSaalfeld,0]) do
+ write(ord(pegelStationsNamen[psSaalfeld,0][i]),' ');
+ writeln;
+ raise exception.create('Unbekannter Pegelname: '''+t+'''!');
+ end;
+ psda:=true;
+ continue;
+ end;
+ if t='Durchfluss [m3/s]' then begin
+ wsda:=false;
+ continue;
+ end;
+ if t='Wasserstand [cm]' then begin
+ wsda:=true;
+ continue;
+ end;
+ if not (wsda and psda) then continue;
+ if pos('Fluss: ',t)=1 then continue;
+ if pos('Flusseinzugsgebiet: ',t)=1 then continue;
+ if startetMit('Stationsnummer: ',t) then begin
+ {$WARNINGS-}
+ if decimalSeparator<>'.' then
+ while pos('.',t)>0 do
+ t[pos('.',t)]:=decimalSeparator;
+ {$WARNINGS+}
+ if round(10*strtofloat(t))<>round(10*pegelStationsNummern[pS]) then begin
+ writeln(
+ 'erwartete Pegelstationsnummer ('+floattostr(pegelStationsNummern[pS])+
+ ') für '+pegelStationsNamen[pS,0]+' ist verschieden von der angegebenen Nummer ('+t+')!');
+ raise exception.create(
+ 'erwartete Pegelstationsnummer ('+floattostr(pegelStationsNummern[pS])+
+ ') für '+pegelStationsNamen[pS,0]+' ist verschieden von der angegebenen Nummer ('+t+')!');
+ end;
+ continue;
+ end;
+ if pos('Hinweise: ',t)=1 then continue;
+ if pos('keine Werte',t)>0 then continue;
+ werte[pS].add(t);
+ end;
+end;
+
procedure tPegelStaende.laden(von: string);
var
f: textfile;
@@ -426,7 +495,7 @@ begin
for ps:=low(tPegelStation) to high(tPegelStation) do begin
writeln(f,'Station: '+Pegelstationsnamen[ps,0]);
for i:=0 to werte[ps].Count-1 do
- writeln(f,tPegelStand(werte[ps][i]).schreibe);
+ writeln(f,werte[ps][i].schreibe);
end;
closefile(f);
if dateischonda then begin
@@ -474,76 +543,6 @@ begin
end;
end;
-procedure tPegelStaende.einlesen(was: string);
-var
- t: string;
- PS: TPegelstation;
- psda,wsda,gefunden: boolean;
- i: longint;
-begin
- while pos(#13,was)>0 do
- delete(was,pos(#13,was),1);
- psda:=false;
- wsda:=false;
- pS:=low(tPegelStation);
- while was<>'' do begin
- t:=myUtf8Encode(erstesArgument(was,#10));
- if length(t)=0 then continue;
- if startetMit('Pegelname:',t) then begin
- pS:=low(tPegelStation);
- gefunden:=false;
- while pS<=high(tPegelStation) do begin
- for i:=0 to length(pegelStationsNamen[psBlankenstein])-1 do
- gefunden:=gefunden or ((pegelStationsNamen[pS,i]<>'') and (pegelStationsNamen[pS,i]=t));
- if gefunden then break;
- inc(pS);
- end;
- if not gefunden then begin
- writeln('Unbekannter Pegelname: '''+t+'''!');
- for i:=1 to length(t) do
- write(ord(t[i]),' ');
- writeln;
- for i:=1 to length(pegelStationsNamen[psSaalfeld,0]) do
- write(ord(pegelStationsNamen[psSaalfeld,0][i]),' ');
- writeln;
- raise exception.create('Unbekannter Pegelname: '''+t+'''!');
- end;
- psda:=true;
- continue;
- end;
- if t='Durchfluss [m3/s]' then begin
- wsda:=false;
- continue;
- end;
- if t='Wasserstand [cm]' then begin
- wsda:=true;
- continue;
- end;
- if not (wsda and psda) then continue;
- if pos('Fluss: ',t)=1 then continue;
- if pos('Flusseinzugsgebiet: ',t)=1 then continue;
- if startetMit('Stationsnummer: ',t) then begin
- {$WARNINGS-}
- if decimalSeparator<>'.' then
- while pos('.',t)>0 do
- t[pos('.',t)]:=decimalSeparator;
- {$WARNINGS+}
- if round(10*strtofloat(t))<>round(10*pegelStationsNummern[pS]) then begin
- writeln(
- 'erwartete Pegelstationsnummer ('+floattostr(pegelStationsNummern[pS])+
- ') für '+pegelStationsNamen[pS,0]+' ist verschieden von der angegebenen Nummer ('+t+')!');
- raise exception.create(
- 'erwartete Pegelstationsnummer ('+floattostr(pegelStationsNummern[pS])+
- ') für '+pegelStationsNamen[pS,0]+' ist verschieden von der angegebenen Nummer ('+t+')!');
- end;
- continue;
- end;
- if pos('Hinweise: ',t)=1 then continue;
- if pos('keine Werte',t)>0 then continue;
- werte[pS].add(t);
- end;
-end;
-
procedure tPegelStaende.putBeenden;
begin
put.beenden:=true;
diff --git a/unit1.lfm b/unit1.lfm
index 473c24c..8f439a6 100644
--- a/unit1.lfm
+++ b/unit1.lfm
@@ -3,6 +3,7 @@ object Form1: TForm1
Height = 204
Top = 256
Width = 713
+ BorderStyle = bsNone
Caption = 'Form1'
ClientHeight = 204
ClientWidth = 713
diff --git a/unit1.pas b/unit1.pas
index a86e19d..4790e65 100644
--- a/unit1.pas
+++ b/unit1.pas
@@ -3,7 +3,8 @@ unit Unit1;
interface
uses
- Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, pegelUnit;
+ Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
+ pegelUnit, fhUnit, lowLevelUnit;
type
@@ -17,9 +18,10 @@ type
procedure FormDestroy(Sender: TObject);
private
{ private declarations }
- datenZeitRaum: extended;
- pegel: tPegelStaende;
- pegelDatei: string;
+ datenZeitRaum: extended;
+ pegel: tPegelStaende;
+ wetter: tMessPunkte;
+ pegelDatei,wetterDatei: string;
public
{ public declarations }
procedure zeichnen;
@@ -31,10 +33,7 @@ var
fehler: boolean;
const
-
- DateiName = 'letztes_Wetter.txt';
- PegelDateiName = 'letzte_Pegel.txt';
- anzDaten = 7*24*6*4;
+ bufLengMin = 1024*1024;
(*
@@ -49,14 +48,16 @@ function letzterMonat(t: TDateTime): TPoint; // x=Monat, y=Jahr
function MyIntToStr(I,Ziff: longint): string;
*)
-function wertZuX(w: extended; startZeit,stopZeit: extended; breite: longint): longint;
-function wertZuY(w: extended; miMa: tPoint; hoehe: longint): longint;
+function wertZuX(w: extended; startZeit,stopZeit: extended; breite: longint): longint; inline;
+function wertZuY(w: extended; miMa: tPoint; hoehe: longint): longint; inline; overload;
+function wertZuY(w: extended; miMa: tExtPoint; hoehe: longint): longint; inline; overload;
+function wertZuY(w: extended; mi,ma: extended; hoehe: longint): longint; inline; overload;
implementation
{$R *.lfm}
-uses process, myStringListUnit, lowLevelUnit, systemUnit, matheunit, math;
+uses process, myStringListUnit, systemUnit, matheunit, math;
{ TForm1 }
@@ -67,17 +68,18 @@ var
fi: textfile;
args: array of string;
begin
+ fehler:=true;
__ausgabenMaske:=1;
pidDatei:='';
pegelDatei:='';
datenZeitRaum:=1;
- fehler:=true;
s:=extractfilepath(application.exename)+'wetter.konf';
t:='';
if not fileexists(s) then
raise exception.create('Kann Konfigurationsdatei '''+s+''' nicht finden!');
pegel:=tPegelStaende.create(image1);
+ wetter:=tMessPunkte.create(image1);
f:=tMyStringList.create;
f.loadFromFile(s);
f.unfoldMacros;
@@ -118,6 +120,13 @@ begin
pegel.laden(pegelDatei);
continue;
end;
+ if startetMit('wetterDatei:',s) then begin
+ wetterDatei:=s;
+ if pos('/',wetterDatei)=0 then
+ wetterDatei:=extractFilePath(application.exename)+wetterDatei;
+ wetter.laden(wetterDatei);
+ continue;
+ end;
if startetMit('datenZeitRaum:',s) then begin
datenZeitRaum:=exprtofloat(false,s,nil,nil);
continue;
@@ -136,6 +145,7 @@ end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
pegel.putBeenden;
+ wetter.mutBeenden;
end;
procedure TForm1.FormDestroy(Sender: TObject);
@@ -145,8 +155,11 @@ begin
if not fehler then begin
if pegelDatei<>'' then
pegel.speichern(pegelDatei);
+ if wetterDatei<>'' then
+ wetter.speichern(wetterDatei);
end;
pegel.free;
+ wetter.free;
end;
procedure TForm1.zeichnen;
@@ -160,6 +173,7 @@ begin
startZeit:=stopZeit-datenZeitRaum;
pegel.achsenZeichnen([psRudolstadt,psRothenstein],startZeit,stopZeit);
+ wetter.achsenZeichnen([mgTemperatur],startZeit,stopZeit);
image1.canvas.pen.color:=$000000;
tmp:=floor(startZeit);
@@ -170,6 +184,7 @@ begin
end;
pegel.graphenZeichnen([psRudolstadt,psRothenstein],now-datenZeitRaum,now);
+ wetter.graphenZeichnen([mgTemperatur,mgLuftfeuchte,mgNiederschlag,mgGlobalstrahlung,mgLuftdruck],now-datenZeitRaum,now);
fehler:=false;
end;
@@ -182,12 +197,22 @@ var
tmp: extended;
begin
tmp:=(w-startZeit)/(stopZeit-startZeit);
- result:=round(-breite*ln(1+tmp*(exp(-xScale)-1))/xScale);
+ result:=1+round(-(breite-2)*ln(1+tmp*(exp(-xScale)-1))/xScale);
end;
function wertZuY(w: extended; miMa: tPoint; hoehe: longint): longint;
begin
- result:=round((w-miMa.x)/(miMa.y-miMa.x)*hoehe);
+ result:=wertZuY(w,miMa.x,miMa.y,hoehe);
+end;
+
+function wertZuY(w: extended; miMa: tExtPoint; hoehe: longint): longint;
+begin
+ result:=wertZuY(w,miMa['x'],miMa['y'],hoehe);
+end;
+
+function wertZuY(w: extended; mi,ma: extended; hoehe: longint): longint;
+begin
+ result:=hoehe-1-round((w-mi)/(ma-mi)*(hoehe-2));
end;
end.
diff --git a/wetter.konf b/wetter.konf
index 2f3e5cb..264a14e 100644
--- a/wetter.konf
+++ b/wetter.konf
@@ -1,4 +1,4 @@
pidDatei: /tmp/wetter.pid
-#wetterDatei: letztes_Wetter.txt
+wetterDatei: letztes_Wetter.txt
pegelDatei: letzte_Pegel.txt
datenZeitRaum: 7*4
diff --git a/wetter.lps b/wetter.lps
index 82b47ab..b89aa0e 100644
--- a/wetter.lps
+++ b/wetter.lps
@@ -9,7 +9,7 @@
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="12" Y="6"/>
- <UsageCount Value="33"/>
+ <UsageCount Value="42"/>
</Unit0>
<Unit1>
<Filename Value="unit1.pas"/>
@@ -18,9 +18,10 @@
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="Unit1"/>
- <TopLine Value="135"/>
- <CursorPos X="20" Y="138"/>
- <UsageCount Value="33"/>
+ <IsVisibleTab Value="True"/>
+ <TopLine Value="179"/>
+ <CursorPos X="49" Y="215"/>
+ <UsageCount Value="42"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit1>
@@ -28,31 +29,29 @@
<Filename Value="original/pegelunit.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
- <UsageCount Value="33"/>
+ <UsageCount Value="42"/>
</Unit2>
<Unit3>
<Filename Value="fhunit.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="2"/>
- <CursorPos X="28" Y="30"/>
- <UsageCount Value="33"/>
+ <UsageCount Value="42"/>
<Loaded Value="True"/>
</Unit3>
<Unit4>
<Filename Value="original/Unit1.pas"/>
<EditorIndex Value="4"/>
- <TopLine Value="209"/>
- <CursorPos X="53" Y="108"/>
- <UsageCount Value="17"/>
+ <TopLine Value="665"/>
+ <CursorPos X="120" Y="465"/>
+ <UsageCount Value="21"/>
<Loaded Value="True"/>
</Unit4>
<Unit5>
<Filename Value="pegelunit.pas"/>
- <IsVisibleTab Value="True"/>
<EditorIndex Value="3"/>
- <TopLine Value="289"/>
- <CursorPos X="56" Y="296"/>
- <UsageCount Value="17"/>
+ <TopLine Value="393"/>
+ <CursorPos Y="432"/>
+ <UsageCount Value="21"/>
<Loaded Value="True"/>
</Unit5>
<Unit6>
@@ -60,13 +59,13 @@
<EditorIndex Value="-1"/>
<TopLine Value="116"/>
<CursorPos Y="159"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
</Unit6>
<Unit7>
<Filename Value="wetter.konf"/>
<EditorIndex Value="1"/>
- <CursorPos X="18" Y="4"/>
- <UsageCount Value="17"/>
+ <CursorPos X="13" Y="2"/>
+ <UsageCount Value="21"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="None"/>
</Unit7>
@@ -75,7 +74,7 @@
<EditorIndex Value="-1"/>
<TopLine Value="157"/>
<CursorPos X="73" Y="178"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
</Unit8>
<Unit9>
<Filename Value="/usr/lib/lazarus/components/lazutils/lazutf8.pas"/>
@@ -83,150 +82,147 @@
<EditorIndex Value="-1"/>
<TopLine Value="150"/>
<CursorPos X="3" Y="171"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
</Unit9>
<Unit10>
<Filename Value="../units/mystringlistunit.pas"/>
<EditorIndex Value="-1"/>
<CursorPos X="47" Y="8"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
</Unit10>
<Unit11>
<Filename Value="../units/lowlevelunit.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="697"/>
<CursorPos X="43" Y="843"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
</Unit11>
<Unit12>
<Filename Value="letzte_Pegel.txt"/>
<EditorIndex Value="-1"/>
<TopLine Value="949303"/>
<CursorPos X="17" Y="949336"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
<DefaultSyntaxHighlighter Value="None"/>
</Unit12>
</Units>
- <JumpHistory Count="30" HistoryIndex="29">
+ <JumpHistory Count="29" HistoryIndex="28">
<Position1>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="54" Column="18" TopLine="43"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="184" Column="37" TopLine="164"/>
</Position1>
<Position2>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="255" Column="31" TopLine="241"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="185" Column="19" TopLine="179"/>
</Position2>
<Position3>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="286" Column="17" TopLine="255"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="534" Column="36" TopLine="532"/>
</Position3>
<Position4>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="283" Column="23" TopLine="265"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="89" Column="36" TopLine="78"/>
</Position4>
<Position5>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="106" Column="26" TopLine="78"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="481" Column="49" TopLine="433"/>
</Position5>
<Position6>
- <Filename Value="original/Unit1.pas"/>
- <Caret Line="1069" Column="76" TopLine="1043"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="76" Column="20" TopLine="62"/>
</Position6>
<Position7>
- <Filename Value="original/Unit1.pas"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="424" Column="21" TopLine="393"/>
</Position7>
<Position8>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="288" Column="60" TopLine="264"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="437" Column="14" TopLine="430"/>
</Position8>
<Position9>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="291" Column="78" TopLine="264"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="454" Column="67" TopLine="435"/>
</Position9>
<Position10>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="281" Column="14" TopLine="275"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="68" Column="45" TopLine="41"/>
</Position10>
<Position11>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="300" Column="39" TopLine="79"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="64" Column="27" TopLine="45"/>
</Position11>
<Position12>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="310" Column="30" TopLine="281"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="325" Column="14" TopLine="314"/>
</Position12>
<Position13>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="298" Column="44" TopLine="281"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="352" Column="47" TopLine="339"/>
</Position13>
<Position14>
- <Filename Value="unit1.pas"/>
- <Caret Line="3" Column="4"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="355" Column="31" TopLine="332"/>
</Position14>
<Position15>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="391" Column="36" TopLine="357"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="537" Column="30" TopLine="512"/>
</Position15>
<Position16>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="501" Column="3" TopLine="475"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="219" Column="56" TopLine="190"/>
</Position16>
<Position17>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="499" Column="22" TopLine="476"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="165" TopLine="130"/>
</Position17>
<Position18>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="224" Column="56" TopLine="196"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="88" Column="83" TopLine="73"/>
</Position18>
<Position19>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="166" Column="22" TopLine="146"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="524" Column="49" TopLine="504"/>
</Position19>
<Position20>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="482" Column="20" TopLine="449"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="97" TopLine="78"/>
</Position20>
<Position21>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="8" Column="59"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="160" TopLine="159"/>
</Position21>
<Position22>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="305" Column="45" TopLine="290"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="165" Column="19" TopLine="153"/>
</Position22>
<Position23>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="271" TopLine="255"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="12" Column="63"/>
</Position23>
<Position24>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="358" Column="44" TopLine="295"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="165" TopLine="146"/>
</Position24>
<Position25>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="81" TopLine="55"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="542" Column="24" TopLine="516"/>
</Position25>
<Position26>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="550" Column="3" TopLine="514"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="16" Column="57"/>
</Position26>
<Position27>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="80" Column="18" TopLine="60"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="107" Column="29" TopLine="81"/>
</Position27>
<Position28>
- <Filename Value="pegelunit.pas"/>
- <Caret Line="550" Column="6" TopLine="514"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="8" Column="73"/>
</Position28>
<Position29>
- <Filename Value="unit1.pas"/>
- <Caret Line="150" TopLine="122"/>
+ <Filename Value="fhunit.pas"/>
+ <Caret Line="535" TopLine="525"/>
</Position29>
- <Position30>
- <Filename Value="original/Unit1.pas"/>
- <Caret Line="374" Column="49" TopLine="368"/>
- </Position30>
</JumpHistory>
</ProjectSession>
</CONFIG>