вторник, 31 марта 2015 г.

Геомагнитная активность Земли за последние 30 дней. NOAA (National Weather Service USA)

...есть такой центр космических исследований (NOAA, Space Weather Prediction Center) по наблюдению и сбору статистических данных за состоянием нашей планеты и солнца. Так вот эти данные доступны по FTP. Конкретно данные по геомагнитной обстановке за последние 30 дней каждые три часа складываются в файлик 'DGD.txt'. А значит его можно считать, пропарсить и наглядно вывести, т.е. визуализировать. Нас будет интересовать параметр амплитуды геомагнитного индекса - Planetary K-indices. Если его величина не будет превышать 3 единиц - норма, от 3 до 4 - критический, свыше 4-х - опасный уровень.


 
Этот файл <DGD.txt> имеет, собственно, следующую структуру:
 :Product: Daily Geomagnetic Data DGD.txt
 :Issued: 1530 UT 20 Aug 2011
 #
 # Prepared by the U.S. Dept. of Commerce, NOAA, Space Weather Prediction Center
 # Please send comment and suggestions to SWPC.Webmaster@noaa.gov
 #
 # Last 30 Days Daily Geomagnetic Data
 #
 #
 # Middle Latitude High Latitude Estimated
 # - Fredericksburg - ---- College ---- --- Planetary ---
 # Date A K-indices A K-indices A K-indices
 2011 07 22 10 3 3 3 2 2 2 2 2 20 3 4 6 3 2 2 1 2 10 2 3 3 1 2 3 2 2
 2011 07 23 6 2 2 2 2 2 1 1 2 7 2 3 2 3 1 1 1 0 8 3 3 2 2 1 1 2 2
 2011 07 24 3 0 1 0 1 1 1 1 2 3 0 1 1 2 0 1 1 1 4 2 0 0 1 1 1 2 2
 2011 07 25 10 3 2 2 2 3 2 3 2 20 2 3 4 5 5 2 2 2 12 2 3 3 2 3 2 3 2
 2011 07 26 5 2 2 2 1 2 0 1 1 7 2 3 3 1 1 1 1 1 5 2 2 2 1 1 1 1 1
 2011 07 27 2 1 1 0 0 0 1 0 1 2 1 2 0 1 0 0 0 1 4 1 2 0 0 1 1 0 2
 2011 07 28 3 1 2 0 0 1 1 1 1 1 1 1 0 0 0 0 0 1 3 1 2 0 0 0 0 1 2
 2011 07 29 3 0 1 0 1 2 1 1 1 3 1 1 0 0 1 3 1 0 5 1 1 0 0 2 2 2 1
 2011 07 30 10 0 0 1 2 3 3 4 3 16 0 1 1 3 5 4 3 3 16 1 1 1 2 3 4 5 4
 2011 07 31 7 3 2 2 1 2 1 2 2 14 4 3 3 4 1 2 2 2 8 3 2 2 1 1 2 2 3
 2011 08 01 6 2 3 2 1 1 1 1 2 7 2 3 3 2 0 1 0 2 9 3 3 3 1 1 2 1 3
 2011 08 02 3 2 1 1 1 1 1 1 0 2 2 1 0 1 1 1 0 0 3 2 1 0 0 1 1 0 1
 2011 08 03 3 1 0 0 0 2 2 1 0 2 1 0 0 0 0 1 1 1 3 1 0 0 0 1 1 1 1
 2011 08 04 3 0 0 1 0 1 1 0 3 2 0 1 0 0 1 1 0 2 4 1 0 0 0 1 2 1 3
 2011 08 05 32 3 1 0 0 1 3 6 7 18 2 2 0 0 0 1 5 6 49 3 2 0 0 1 2 8 7
 2011 08 06 14 3 3 4 3 3 2 1 3 33 5 5 5 4 5 4 2 2 31 6 5 4 4 3 3 2 3
 2011 08 07 6 3 2 2 1 1 0 1 2 7 2 1 3 2 2 1 2 2 7 3 2 2 1 1 1 1 2
 2011 08 08 8 3 2 1 3 2 1 1 2 24 2 2 2 6 6 1 1 1 10 3 3 2 3 3 2 2 2
 2011 08 09 5 2 2 2 2 0 1 1 1 8 2 3 3 3 0 1 2 1 9 3 3 3 2 1 1 2 2
 2011 08 10 8 1 2 4 1 1 1 3 0 15 2 3 5 4 3 0 2 1 7 2 2 3 2 1 0 2 1
 2011 08 11 3 1 1 1 1 1 0 1 2 3 1 1 2 1 1 0 1 1 6 1 1 1 1 1 1 2 3
 2011 08 12 3 1 2 1 1 1 1 1 1 4 1 1 0 3 2 1 1 0 5 1 2 1 2 1 1 2 2
 2011 08 13 4 1 2 1 0 1 1 1 2 2 1 1 1 0 0 0 0 1 5 1 2 1 0 1 1 1 3
 2011 08 14 8 2 2 2 2 2 2 2 3 10 2 2 3 2 1 3 3 2 9 2 2 2 2 1 2 2 3
 2011 08 15 9 4 2 1 2 1 1 2 3 10 4 2 1 3 2 2 2 2 13 4 3 1 2 2 3 3 3
 2011 08 16 6 2 2 2 2 2 1 1 1 12 2 3 3 4 4 1 1 0 8 2 2 2 2 3 1 2 2
 2011 08 17 6 2 1 2 1 1 1 2 1 8 2 1 2 3 4 1 1 0 6 3 1 2 1 2 1 1 1
 2011 08 18 1 0 0 0 0 1 1 1 0 2 1 0 0 0 1 1 1 0 3 1 0 0 0 1 1 2 1
 2011 08 19 1 0 0 0 0 1 0 1 1 1 0 1 0 0 0 0 0 1 2 0 0 0 0 0 0 0 1
 2011 08 20 -1 -1-1-1-1-1-1-1-1 -1 -1-1-1-1-1-1-1-1 -1 1 1 0 0 2-1-1-1
Что следует сделать в первую очередь? Правильно, загрузим его. Добавим простейший FTP клиент:
procedure GetFTP(ftp_server, ftp_dir, ftp_file, local_file: string);
var
  ftp: TIdFTP;
begin
 ftp:= TIdFTP.Create(nil);
 try
   try
     ftp.Host     := ftp_server;
     ftp.Port     := 21;
     ftp.Username := 'anonymous';
     ftp.Password := ' ';
     ftp.Connect;
     AssErt(ftp.Connected);
     ftp.ChangeDir(ftp_dir);
     ftp.GET(ftp_file, local_file, true, true);
   finally
     ftp.Free
   end except
 end
end;

 ...
 GetFTP('ftp.swpc.noaa.gov', 'pub/latest/', 'DGD.txt', 'DGD.txt');

Как видно из набора данных, между блоками цифр разное количество пробелов. Но не беда, нормализуем (избавившись от лишних пробелов):
// парсер
function get_num(num: integer; txt: string): string;
var i, k: integer;
    tmp, temp: string;
    t: tstringlist;
begin

 result:= ''; k:= 0; tmp:= '';
 for i:= 1 to length(txt) do begin
  if txt[i]<>' ' then tmp:= tmp + txt[i]
   else begin
    if txt[i+1]<>' ' then inc(k);
    if k = num then result:= tmp;
    tmp:= '';
  end
 end;
end;
...
Полный код парсинга данных:
var k: integer;
    en: boolean;
    //
    pn, temp, z, t: string;
    fl: textfile;
    tmr: tdatetime;
begin
 GetFTP('ftp.swpc.noaa.gov', 'pub/latest/', 'DGD.txt', 'DGD.txt');

 // парсер-
 pn:= 'DGD.txt';
 AssignFile(fl,pn);
 Reset(fl);
 pn:= ''; temp:= ''; en:= false;
 repeat
  ReadLn(fl, pn);

  pn:= stringreplace(pn, '-', ' -', [rfReplaceAll]);
  while pos('  ', pn)>0 do begin
   k:= pos('  ', pn);
   delete(pn,k,1);
  end;
  pn:= pn+ ' ';
  k:= 0;
  temp:= '';
  if en then begin
   for k:= 0 to 7 do begin
    z:= get_num(23+ k, pn);
    if z='-1' then break;

    temp:= temp + z + ' ';

    t:= get_num(3, pn) + '.' + get_num(2, pn) + '.' + get_num(1, pn);
    tmr:= strtodate(t) + strtotime(inttostr(k*3));
    series1.AddY(strtointdef(z, 0), FormatDateTime('dd.mm.yy hh:nn', tmr), cllime);
   end;
   memo1.Lines.Add(get_num(3, pn) + '.' + get_num(2, pn) + '.' + get_num(1, pn) + ' - ' + temp);
  end;
 
  if pos('# Date', pn)>0 then en:= true
 until eof(fl);
 CloseFile(fl)
end;
В принципе все, можно тестировать.


забрать

Комментариев нет:

Отправить комментарий

В комментариях уважайте собеседника, внимательно читайте посты и не додумывайте. Просьбы и предложения из разряда: «можно ваш Skype/Viber/телефон», «напишите мне в vk/FB», а также другие им подобные — игнорируются. Выход новых версий ПО, внешняя ссылка, переставшая работать с течением времени и т.п. не является основанием для претензий. Желающие спокойно подискутировать и высказаться — Welcome. Желающие спонсировать блог — Donate. Нарушение этих простых правил ведет к бану и удалению комментариев без предупреждения.