parser-storm
/
StormConv.php
365 строк · 17.3 Кб
1<?php
2/*
3## Transforming the decoding result of RF6/04 WAREP
4
5### Parent class reference:
6http://dev.hsdn.org/wdparser/metar/
7
8### License:
9Copyright (C) 2024, Spin Opel
10Copyright (C) 2013-2020, Information Networks, Ltd.
11Copyright (C) 2001-2006, Mark Woodward
12*/
13
14class StormConv extends Storm
15{
16public $observed_date_time; //Дата и время
17public $desc_clouds = ""; //Облачность
18public $desc_weather = null; //Метеорологическое явление
19
20//Пост обработка полученных результатов
21//DATAS` date NOT NULL DEFAULT '1000-01-01'
22//echo "\n\n"."Дата получения данных"."\n";
23private function convDate($dayr) {
24date_default_timezone_set('UTC'); //временная зона по умолчанию
25if (isset($dayr)) {
26$d_now = new DateTime(); //текущая дата сводки
27$d_part = $d_now->format('Y-m');
28$date_chg = $d_part."-".$dayr; //формат даты в виде Y-m-d
29} else {
30$date_chg = null;
31}
32return $date_chg;
33}
34
35//TIMES` time NOT NULL DEFAULT '00:00:00'
36//echo "\n"."Срок наблюдения, UTC"."\n";
37private function convTime($date_time) {
38date_default_timezone_set('UTC'); //временная зона по умолчанию
39if (isset($date_time)) {
40$time_stamp = strtotime($date_time); // timestamp from RFC 2822
41$date_chg = date('H:i:s', $time_stamp);
42} else {
43$date_chg = null;
44}
45return $date_chg;
46}
47
48//Speed` varchar(5) DEFAULT NULL
49//echo "\n"."Скорость ветра, м/с"."\n";
50private function convWindSpeed($speed) {
51if (is_numeric($speed)) {
52$speed_chg = round($speed, 0);
53} else {
54$speed_chg = null;
55}
56return $speed_chg;
57}
58
59//Dir` enum('Северный','Южный','Западный','Восточный','С-З','С-В','Ю-З','Ю-В','Переменный') DEFAULT NULL
60//echo "\n"."Направление ветра"."\n";
61//преобразование угла в направление ветра
62private function convWindDir($angle, $str) {
63if (is_numeric($angle)) {
64//$compass = array('N','NE','E','SE','S','SW','W','NW');
65$compass = array('Северный','С-В','Восточный','Ю-В','Южный','Ю-З','Западный','С-З');
66$direction = $compass[round($angle / 45) % 8];
67} else {
68$direction = null;
69}
70
71//поиск значения "VRB", которое не учтено в родительском классе
72if (stripos($str, "VRB") !== false) {
73$direction = 'Переменный';
74}
75return $direction;
76}
77
78//Clouds` enum('Малооблачно','Переменная облачность','Облачно с прояснениями','Сплошная облачность','') NOT NULL DEFAULT ''
79//echo "\n"."Облачность"."\n";
80private function convClouds($amount) {
81$arr_clouds = array(
82'NSW' => '', //никакой существенной погоды не наблюдается //no significant weather are observed
83'NCD' => '', //облака не обнаружены //nil cloud detected
84'NOBS'=> '', //нет наблюдений //no observation
85'SKC' => 'Ясно', //Чистое небо или Ясно или Безоблачно //clear skies
86'CLR' => 'Ясно', //Чистое небо или Ясно или Безоблачно //clear skies
87'FEW' => 'Малооблачно', //Малооблачно //partly cloudy
88'SCT' => 'Переменная облачность', //Рассеянные облака или Переменная облачность //scattered clouds
89'BKN' => 'Облачно с прояснениями', //В основном облачно или Облачно с прояснениями //mostly cloudy
90'BKM' => 'Облачно с прояснениями', //В основном облачно или Облачно с прояснениями //mostly cloudy
91'NSC' => 'Облачно с прояснениями', //В основном облачно или Облачно с прояснениями //mostly cloudy
92'OVC' => 'Сплошная облачность', //Пасмурная погода или Сплошная облачность //overcast
93'VV' => 'Вертикальная видимость', //Вертикальная видимость //vertical visibility
94'' => ''
95);
96return $arr_clouds[$amount];
97}
98
99//weather` varchar(64) DEFAULT NULL
100//echo "\n"."Метеорологическое явление"."\n";
101private function convWeather($wxcode) {
102$arr_weather = array(
103'VC' => 'Неподалеку', //неподалеку //nearby
104'MI' => 'Мелкий', //мелкий //shallow
105'PR' => 'Частичный', //частичный //partial
106'BC' => 'Кусочки', //кусочки или пятна //patches of
107'DR' => 'Позёмка', //позёмка //low drifting
108'BL' => 'Ветрено', //ветрено //blowing
109'SH' => 'Ливневый', //ливневый //showers
110'TS' => 'Гроза', //гроза //thunderstorm
111'FZ' => 'Охлажденный', //охлажденный или гололед //freezing
112'DZ' => 'Морось', //морось //drizzle
113'RA' => 'Дождь', //дождь //rain
114'SN' => 'Снег', //снег //snow
115'SG' => 'Снежные зерна', //снежные зерна //snow grains
116'IC' => 'Ледяные кристаллы', //ледяные кристаллы //ice crystals
117'PE' => 'Ледяная крупа', //ледяная крупа //ice pellets
118'GR' => 'Град', //град //hail
119'GS' => 'Снежная крупа', //мелкий град и/или снежная крупа //small hail
120'UP' => 'Неизвестное явление', //неизвестное явление //unknown
121'BR' => 'Дымка', //дымка или мгла //mist
122'FG' => 'Туман', //туман //fog
123'FU' => 'Дым', //дым //smoke
124'VA' => 'Вулканический пепел', //вулканический пепел //volcanic ash
125'DU' => 'Пыль, взвешенная в воздухе', //пыль, взвешенная в воздухе //widespread dust
126'SA' => 'Песок', //песок //sand
127'HZ' => 'Легкий туман', //легкий туман //haze
128'PY' => 'Водяная пыль', //водяная пыль //spray
129'PO' => 'Песчаные вихри', //хорошо развитые пылевые или песчаные вихри //well-developed dust/sand whirls
130'SQ' => 'Шквал', //шквал //squalls
131'FC' => 'Смерч', //воронкообразное облако, смерч или смерч //funnel cloud, tornado, or waterspout
132'SS' => 'Песчаная буря', //песчаная буря или пыльная буря //sandstorm/duststorm
133'' => null
134);
135return $arr_weather[$wxcode];
136}
137
138private function convVisibility($dist) {
139//$dist_chg = $dist/1000; // перевод значения в километры
140$dist_chg = $dist; // перевод значения в километры
141if (empty($dist_chg)) {
142$dist_chg = null;
143} elseif ($dist_chg > 10) {
144$dist_chg = 10;
145}
146return $dist_chg;
147}
148
149//Trend` varchar(75) DEFAULT NULL
150//echo "\n"."Изменение погоды"."\n";
151private function convCloudsReport($str) {
152//пример описания изменения погоды
153//Broken sky at 1006 meters, cumulonimbus; overcast sky at 2012 meters
154
155//приведение строки к нижнему регистру
156$str = strtolower($str);
157//echo $str;
158
159//список поисковых фраз
160$arr_phrases = array(
161//cloud_codes
162'особых погодных условий не наблюдается' => 'no significant weather are observed',
163'' => 'no significant clouds are observed', //существенных облаков не наблюдается
164'облака не обнаружены' => 'nil cloud detected',
165'безоблачно' => 'no significant changes expected',
166'чистое небо' => 'clear skies',
167'существенных изменений не ожидается' => 'no observation',
168//
169'малооблачно' => 'a few',
170'переменная облачность' => 'scattered',
171'облачно с прояснениями' => 'broken sky',
172'сплошная облачность' => 'overcast sky',
173//
174'вертикальная видимость' => 'vertical visibility',
175//cloud cover type codes
176'кучево-дождевые облака' => 'cumulonimbus',
177'возвышающиеся кучевые облака' => 'towering cumulus',
178//runway visual range tendency codes
179'убывание' => 'decreasing',
180'увеличение' => 'increasing',
181'нет тенденции' => 'no tendency',
182//runway visual range prefix codes
183'более' => 'more',
184'менее' => 'less',
185//runway runway deposits codes
186'чисто и сухо' => 'clear and dry',
187'испарения' => 'damp',
188'влажно или водяные пятна' => 'wet or water patches',
189'изморозь или покрытый инеем' => 'rime or frost covered',
190'сухой снег' => 'dry snow',
191'мокрый снег' => 'wet snow',
192'слякоть' => 'slush',
193'лед' => 'ice',
194'утрамбованный или раскатанный снег' => 'compacted or rolled snow',
195'замерзшая колея или гребни' => 'frozen ruts or ridges',
196//runway runway deposits extent codes
197'от 10% или менее' => 'from 10% or less',
198'от 11% до 25%' => 'from 11% to 25%',
199'от 26% до 50%' => 'from 26% to 50%',
200'от 51% до 100%' => 'from 51% to 100%',
201//runway runway deposits depth codes
202'менее 1 мм' => 'less than 1 mm',
203'10 см' => '10 cm',
204'15 см' => '15 cm',
205'20 см' => '20 cm',
206'25 см' => '25 cm',
207'30 см' => '30 cm',
208'35 см' => '35 cm',
209'40 см или более' => '40 cm or more',
210//runway runway friction codes
211'плохой' => 'poor',
212'средний/плохой' => 'medium/poor',
213'средний' => 'medium',
214'средний/хороший' => 'medium/good',
215'хороший' => 'good',
216'цифры недостоверны' => 'figures unreliable',
217//trends flag codes
218'ожидается, что скоро возникнет' => 'expected to arise soon',
219'ожидается, что возникнет временно' => 'expected to arise temporarily',
220'ожидается, что возникнет с перерывами' => 'expected to arise intermittent',
221'предварительный прогноз' => 'provisional forecast',
222'отмененный прогноз' => 'cancelled forecast',
223'нулевой прогноз' => 'nil forecast',
224//measurement units
225'м' => 'meters', //метрах
226//trends flag codes
227'' => 'BECMG', //ожидается, что скоро возникнет //expected to arise soon
228'' => 'TEMPO', //жидается временное возникновение //expected to arise temporarily
229'' => 'INTER', //ожидается прерывистое возникновение //expected to arise intermittent
230'' => 'PROV', //предварительный прогноз //provisional forecast
231'' => 'CNL', //прогноз отменен //cancelled forecast
232'' => 'NIL', //нулевой прогноз //nil forecast
233//trends time codes
234'на' => ' at ',
235'от' => ' from ',
236'до' => ' until '
237);
238
239//положение поисковых фраз в массиве
240foreach ($arr_phrases as $k => $v) {
241$str_offset = 0;
242$count_symbols = substr_count($str, $v);
243//в случае дублирования поисковых фраз
244for ($p = 1; $p <= $count_symbols; $p++) {
245//позиция поисковой фразы
246$pos = stripos($str, $v, $str_offset);
247if ($pos !== false) {
248$arr_convStr[$pos] = $k; //заменяем значение массива на его ключ (перевод слова на русский)
249$str_offset = $pos + strlen($v);
250//echo $str_offset.PHP_EOL;
251}
252}
253}
254
255//положение цифровых значений в массиве
256preg_match_all('/(\d+)/', $str, $matches);
257foreach ($matches[0] as $v) {
258$str_offset = 0;
259$count_symbols = substr_count($str, $v);
260//в случае дублирования поисковых фраз
261for ($d = 1; $d <= $count_symbols; $d++) {
262//позиция поисковой фразы
263$pos_digit = stripos($str, $v, $str_offset);
264if ($pos_digit !== false) {
265$arr_convStr[$pos_digit] = $v;
266$str_offset = $pos_digit + strlen($v);
267//echo $str_offset.PHP_EOL;
268}
269}
270}
271
272//положение разделителей в массиве
273$arr_separators = array(",", ";"); //список разделителей
274foreach ($arr_separators as $val) {
275$str_offset = 0;
276$count_symbols = substr_count($str, $val);
277//в случае дублирования разделителей
278for ($s = 1; $s <= $count_symbols; $s++) {
279//позиция разделителя
280$pos_separator = strpos($str, $val, $str_offset);
281if ($pos_separator !== false) {
282$arr_convStr[$pos_separator] = $val;
283$str_offset = $pos_separator + 1;
284//echo $str_offset.PHP_EOL;
285}
286}
287}
288//var_dump($arr_convStr);
289
290if (empty($arr_convStr)) {
291$str_translated = null;
292} else {
293ksort($arr_convStr);
294$str_translated = implode(" ", $arr_convStr); //объединяем элементы массива в строку
295$pattern = '/\s+('.implode("|", $arr_separators).')\s+/i';
296$replacement = '$1 ';
297$str_translated = preg_replace($pattern, $replacement, $str_translated); //удаляем пробел перед знаком разделителя
298$str_translated = mb_strtoupper(substr($str_translated, 0, 2), "UTF-8").substr($str_translated, 2); //регистр первой буквы на UTF-8
299}
300return $str_translated;
301}
302
303public function convParam() {
304//Пост обработка результатов, полученных из родительского класса
305//DATAS` date NOT NULL DEFAULT '1000-01-01'
306//echo "\n\n"."Дата начала/окончания телеграммы"."\n";
307//$this->observed_date = $this->convDate($this->observed_date);
308$this->observed_date = $this->convDate($this->monthdayr);
309
310//TIMES` time NOT NULL DEFAULT '00:00:00'
311//echo "\n"."Время начала/окончания телеграммы, UTC"."\n";
312//$this->observed_time = $this->convTime($this->observed_time);
313$this->observed_time = $this->hourr.":".$this->minuter.":00";
314
315//DateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
316//echo "\n"."Дата и время"."\n";
317//echo $this->observed_date;
318$this->observed_date_time = $this->observed_date." ".$this->observed_time;
319
320//ID_STATION` varchar(5) NOT NULL DEFAULT ''
321//echo "\n"."Тип НЯ или ОЯ (обобщенный)"."\n";
322$arr_warep = array($this->storm_code_1, $this->storm_code_2, $this->storm_code_3, $this->storm_code_4, $this->storm_code_5, $this->storm_code_6, $this->storm_code_7, $this->storm_code_8, $this->storm_code_9);
323$first_warep = null;
324foreach ($arr_warep as $val_w) {
325if (!is_null($val_w)) {
326$first_warep = $val_w;
327break;
328}
329}
330$this->storm_code_combine = $first_warep;
331
332//Speed` varchar(5) DEFAULT NULL
333//echo "\n"."Скорость ветра, м/с"."\n";
334$this->wind_speed = $this->convWindSpeed($this->wind_speed);
335
336//Dir` enum('Северный','Южный','Западный','Восточный','С-З','С-В','Ю-З','Ю-В','Переменный') DEFAULT NULL
337//echo "\n"."Направление ветра"."\n";
338//преобразование угла в направление ветра
339//$this->wind_direction = $this->convWindDir($this->wind_direction, $this->raw);
340
341//Clouds` enum('Малооблачно','Переменная облачность','Облачно с прояснениями','Сплошная облачность','') NOT NULL DEFAULT ''
342//echo "\n"."Облачность"."\n";
343//echo $this->clouds[0]['amount'];
344if (isset($this->clouds[0]['amount'])) {
345$this->desc_clouds = $this->convClouds($this->clouds[0]['amount']);
346}
347
348//weather` varchar(64) DEFAULT NULL
349//echo "\n"."Метеорологическое явление"."\n";
350//echo $this->present_weather[0]['types'][0];
351if (isset($this->present_weather[0]['types'][0])) {
352$this->desc_weather = $this->convWeather($this->present_weather[0]['types'][0]);
353}
354
355//Visib` varchar(5) DEFAULT NULL
356//echo "\n"."Видимость, км"."\n";
357//$this->visibility = $this->convVisibility($this->visibility, $this->raw);
358$this->visibility = $this->convVisibility($this->visibility);
359
360//Trend` varchar(75) DEFAULT NULL
361//echo "\n"."Изменение погоды"."\n";
362$this->clouds_report = $this->convCloudsReport($this->clouds_report);
363}
364}
365?>