Commit 44f2f095 44f2f095770785cb978192b0ab2d097d510c6b17 by Максим Макеев

add all files

1 parent 9f9f1b9b
Showing 1000 changed files with 1880 additions and 0 deletions

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

1 {
2 // Use IntelliSense to learn about possible attributes.
3 // Hover to view descriptions of existing attributes.
4 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 "version": "0.2.0",
6 "configurations": [
7 {
8 "name": "Python: Текущий файл",
9 "type": "python",
10 "request": "launch",
11 "program": "${file}",
12 "console": "integratedTerminal"
13 }
14 ]
15 }
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "python.pythonPath": "C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python38\\python.exe"
3 }
...\ No newline at end of file ...\ No newline at end of file
1 import time
2 import logging
3 import pika
4 import json
5 import time
6 import datetime
7 import pytz
8
9 from threading import Thread
10 from queue import Queue, Empty
11 from ocm_fwk.ocm_mq import OcmMqBase
12
13 import config as cfg
14
15 '''
16 class MyJSONEncoder(json.JSONEncoder):
17 #Override the default method
18 def default(self, obj):
19 if isinstance(obj, (datetime.date, datetime.datetime)):
20 return obj.replace(tzinfo=datetime.timezone.utc).isoformat()
21 if isinstance(obj, np.ndarray):
22 return obj.tolist()
23 '''
24
25 class test_cons(OcmMqBase):
26
27 def __init__(self, settings, consumer_queue=None, consumer_routing_key=None, consume_only_routing_key=True,
28 message_ttl_ms=None):
29 super(test_cons, self).__init__(settings)
30 self.logger = logging.getLogger(__name__)
31
32 if consumer_queue is None:
33 raise TypeError
34 if consumer_routing_key is None:
35 raise TypeError
36
37 self.consumer_queue = consumer_queue
38 self.consumer_routing_key = consumer_routing_key
39 self.consume_only_routing_key = consume_only_routing_key
40 self.message_ttl_ms = message_ttl_ms
41
42 self._loop_thread = Thread(target=self._main_loop)
43 self._stop_flag = False
44
45 self.mms_main_query = Queue()
46
47 def consume(self, routing_key, message_object):
48 self.mms_main_query.put(message_object)
49 print("{} -> consume bu rout {} messege :{}".format(datetime.datetime.now(), routing_key, message_object))
50 return True
51
52 def get_lazy_data(self):
53 result = []
54 while self.mms_main_query.qsize() != 0:
55 result.append(self.mms_main_query.get())
56 return result
57
58 def _consumer_callback(self, ch, method, properties, body):
59 # проверка правильности подписки на routing_key
60 if self.consume_only_routing_key:
61 if isinstance(self.consumer_routing_key, str): # если routing key - одна строка
62 if self.consumer_routing_key != method.routing_key:
63 # сообщение не может быть обработано и посылать его повторно не нужно
64 ch.basic_nack(delivery_tag=method.delivery_tag, requeue=False)
65 self.logger.warning('MQ: routing key({}) not proper'.format(method.routing_key))
66 return
67 elif isinstance(self.consumer_routing_key, tuple): # если routing key - кортеж строк
68 if method.routing_key not in self.consumer_routing_key:
69 # сообщение не может быть обработано и посылать его повторно не нужно
70 ch.basic_nack(delivery_tag=method.delivery_tag, requeue=False)
71 self.logger.warning('MQ: routing key({}) not proper'.format(method.routing_key))
72 return
73 else:
74 ch.basic_nack(delivery_tag=method.delivery_tag, requeue=False)
75 self.logger.warning('MQ: routing key has not proper type')
76 return
77
78 # преобразование сообщения в нативный объект
79 try:
80 obj = json.loads(body.decode('utf-8'))
81 except Exception:
82 self.logger.exception("MQ: json conversion error")
83 # сообщение не может быть обработано и посылать его повторно не нужно
84 ch.basic_nack(delivery_tag=method.delivery_tag, requeue=False)
85 return
86
87 # callback может вернуть
88 # None - простым вызовом return или по завершению кода обработчика, то же самое, что False
89 # True - сообщение обработано, можно посылать ack - удаляет сообщение из очереди
90 # False - сообщение не обработано, нужно его отправить обратно в очередь - послать nack(requeue=True)
91 ack = None
92 try:
93 ack = self.consume(method.routing_key, obj)
94 except Exception:
95 ch.basic_nack(delivery_tag=method.delivery_tag, requeue=False)
96 self.logger.exception("MQ: message not consumed")
97 raise
98
99 # если callback не возвратил логический тип, значит ack - False
100 if ack is None:
101 ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True)
102 elif ack:
103 ch.basic_ack(delivery_tag=method.delivery_tag)
104 else:
105 ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True)
106
107 def _main_loop(self):
108 while not self._stop_flag:
109 connection = None
110 ch_consumer = None
111 try:
112 connection = pika.BlockingConnection(self.parameters)
113 ch_consumer = connection.channel()
114 ch_consumer.basic_qos(prefetch_count=100) # todo: вынести в настройки
115
116 # определение очереди сообщений, в случае отсутствия, будет создана
117 if self.message_ttl_ms is not None:
118 queue = ch_consumer.queue_declare(
119 queue=self.consumer_queue,
120 durable=True,
121 exclusive=False,
122 arguments={'x-message-ttl': self.message_ttl_ms, },
123 ).method.queue
124 else:
125 queue = ch_consumer.queue_declare(
126 queue=self.consumer_queue,
127 durable=True,
128 exclusive=False,
129 ).method.queue
130
131 # привязка к очереди
132 if isinstance(self.consumer_routing_key, str): # если routing key - одна строка
133 ch_consumer.queue_bind(
134 exchange=self.EXCHANGE,
135 queue=queue,
136 routing_key=self.consumer_routing_key,
137 )
138 elif isinstance(self.consumer_routing_key, tuple): # если routing key - кортеж строк
139 for key in self.consumer_routing_key:
140 ch_consumer.queue_bind(
141 exchange=self.EXCHANGE,
142 queue=queue,
143 routing_key=key
144 )
145 else:
146 raise TypeError
147
148 # настройка обработчика получения сообщений
149 ch_consumer.basic_consume(
150 consumer_callback=self._consumer_callback,
151 queue=queue,
152 no_ack=False,
153 consumer_tag="ocm_mq_consumer"
154 )
155
156 self.consumer_queue = queue
157
158 # блокирующий вызов ожидания входящих сообщений
159 try:
160 ch_consumer.start_consuming()
161 except:
162 ch_consumer.stop_consuming()
163 raise
164
165 except Exception:
166 self.logger.exception('mq consuming error, attempting to reconnect...')
167 finally:
168 try:
169 ch_consumer.close()
170 except:
171 pass
172
173 try:
174 connection.close()
175 except:
176 pass
177
178 time.sleep(self.RECONNECT_SLEEP_SECONDS)
179
180 try:
181 ch_consumer.close()
182 except:
183 pass
184
185 try:
186 connection.close()
187 except:
188 pass
189
190 def start(self):
191 """ Запуск подписчика для шины ОКМ """
192 self._loop_thread.start()
193
194 def stop(self):
195 self._stop_flag = True
196
197 bus_TS = test_cons(cfg, "makeyev_L", "measurement.precipitation.*", consume_only_routing_key=False)
198 bus_LO = test_cons(cfg, "makeyev_C", "metering.rainfall", consume_only_routing_key=False)
199 print("begin...\n")
200 #cons.stop()
201 bus_LO.start()
202 bus_TS.start()
203
204 i = 0
205
206 while i < 100:
207 i = i + 1
208 print("Iterator={}\t\tdata:{}".format(i, bus_LO.get_lazy_data()))
209 print("Iterator={}\t\tdata:{}".format(i, bus_TS.get_lazy_data()))
210 time.sleep(30)
211
212
213
214 '''
215 АГК-34Д uuid = "0efefaee-eada-446f-a2a0-f95acabfc0a7" Л
216 АГК-77Д uuid = "c3f0ecb7-c65e-4273-93a9-6f39a65dcd4a" Л
217 АГК-141 uuid = "83b895ae-3a21-4585-8289-e28da5d0cc43" C
218 АГК-040 uuid = "a6f44e50-ad18-4ee9-a6bb-ffae6a85d2a3" С
219 АГК-286 uuid = "33ce9a80-27df-41dd-8dbe-cf3ec918b4c2" С
220 '''
221
1 import time
2 import logging
3 import pika
4 import json
5 import datetime
6 import pytz
7
8 from threading import Thread
9 from queue import Queue, Empty
10 from ocm_fwk.ocm_mq import OcmMqBase, OcmMqBlockingPublisher
11
12 import config as cfg
13
14 pub = OcmMqBlockingPublisher(cfg)
15 pub.publish("rk_1", 123)
16 pub.publish("rk_1", 666)
17 pub.publish("rk_1", 999)
18
19
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
1 #user_db_name = "web_forecast_7"
2 user_db_name = "qwer"
3 db_postgres_connection = dict(host="localhost",database=user_db_name, user="postgres", password="postgres")
4 redis_connection = dict(host='localhost', port=6379, db=0, password=None)
5 OCM_MQ = dict(
6 HOST = 'evolution.emercit.com',
7 PORT = 5672,
8 VIRTUAL_HOST = 'ocm',
9 EXCHANGE = 'monitoring',
10 USER = 'emercit',
11 PASSWORD = 'xfnLAW5pff3RpNFh')
1 import urllib.request
2 import json
3 import os
4 import datetime
5 from imageio import imread
6 import cv2
7 import numpy as np
8 import loca_data
9 import duamel_model
10 import matplotlib.pyplot as plt
11 import sher_duam_class
12 import dateutil.parser
13 import dmrl_prec_file
14
15 class DMRLPrecFile_3SC(dmrl_prec_file.DMRLPrecFile):
16
17 # Получить результаты расчёта
18 def GetResult(self, _prec, _test_datetime=None):
19 """
20 _prec это JSON вида:
21 {"time": "2020-03-20T10:00:00Z",
22 "period": 600,
23 "sum": 0.0,
24 "intensity": 0.0,
25 "type": 0}
26 """
27
28 result = None
29 if _prec["sum"] == " ":
30 _prec = None
31
32 """
33 result это JSON вида:
34 {"time": "2020-03-20T10:00:00Z", - время расчета
35 "water_volume": 0.0, - общее воличество выпавшей воды в м^3
36 "prec_square": 0.0, - площадь выпадения осадков в м^2
37 "all_square": 0.0} - общая площадь водосбора в м^2
38 """
39
40 #self.k_point_correction = 1 # Коэффициент корректировки точечный (интенсивность на осадкомере к интенсивносьти по радару в точке)
41 #self.k_reserv_volume_prec = 1 # Резервный коэффициент (объем воды / текущие осадки на осадкомере)
42 temp_datetime = datetime.datetime.now()
43 temp_cur_min = (temp_datetime.minute // 10) * 10
44 cur_datetime = datetime.datetime(temp_datetime.year, temp_datetime.month, temp_datetime.day, temp_datetime.hour, temp_cur_min, 0, 0)
45
46 if _prec is not None:
47 #cur_datetime = dateutil.parser.parse(_prec["time"], ignoretz=False).replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)
48 cur_datetime = dateutil.parser.parse(_prec["time"])
49
50 if _test_datetime is not None:
51 cur_datetime = _test_datetime
52
53 matrix = self.GetMatrix(cur_datetime)
54
55 #####################################
56 # TODO Delete!!!!
57 #temp_val = int(cur_datetime.timestamp())
58 #temp_f_p = os.path.abspath(os.curdir) + '\\result\\{}.png'.format(int(cur_datetime.timestamp()))
59 #cv2.imwrite(temp_f_p, matrix)
60 #####################################
61
62 # 1. Если ДМРЛ нет и нет осадков
63 if matrix is None and _prec is None:
64 result = dict(time = cur_datetime.__str__(),
65 water_volume = -1.0,
66 prec_square = -1.0,
67 all_square = -1.0,
68 dmrl_prec = -1.0)
69 return json.dumps(result)
70
71
72 # 2. Если ДМРЛ нет, но есть осадки
73 if matrix is None and _prec is not None:
74 temp_volume = self.GetReservDataByPrec(float(_prec["sum"]))
75
76 result = dict(time = cur_datetime.__str__(),
77 water_volume = temp_volume,
78 prec_square = self.squere,
79 all_square = -1.0)
80 return json.dumps(result)
81
82 # 3-4. Если есть ДМРЛ и есть (или нет) осадков с АГК - ОБЫЧНЫЙ АЛГОРИТМ
83 # Определяем коэффициент корреляции, если оба значения есть и отличны от нуля
84 cur_prec_value = 0
85 if _prec is not None:
86 cur_prec_value = float(_prec["sum"])
87
88 test = matrix[0]
89 test = test[0]
90 test = test[0]
91
92 value = matrix[int(self.corr_y)][int(self.corr_x)][0]
93 dmrl_prec = self.GetPrecByDBZ(value)
94 dmrl_prec = dmrl_prec / 6
95
96 ####################################################################
97 # Работаем с коэффициентами корректировки
98 temp_k_point_correction = 1
99
100 if dmrl_prec > 0 and cur_prec_value > 0:
101 temp_k_point_correction = cur_prec_value / dmrl_prec
102
103 if self.k_point_correction == 1 and self.k_count_point_correction == 0:
104 self.k_count_point_correction = 1
105 self.k_math_waiting = temp_k_point_correction
106 self.k_dispersion = 0
107 self.k_point_correction = temp_k_point_correction
108 else:
109 new_count = self.k_count_point_correction + 1 # Новое количество успешных попыток
110
111 mval1 = self.k_math_waiting * self.k_count_point_correction # сумма всех старых значений
112 mval2 = mval1 + self.k_point_correction # новая сумма значеий
113 mval3 = mval2 / new_count # Новое среднее (матожидание)
114
115 dval1 = (self.k_dispersion ** 2) * self.k_count_point_correction # сумма всех квадратов дельт старых
116 dval2 = (mval3 - temp_k_point_correction) ** 2 # новый квадрат дельты
117 dval4 = (dval1 + dval2) / new_count # общая сумма к общему кол-ву новая
118 dval5 = dval4 ** 0.5 # новое среднеквадратичное отклонение (типа дисперсия)
119
120 cval1 = temp_k_point_correction - mval3 # новое отклонение с учетом данной попытки
121
122 # Проверка на 3 сигмы
123 if abs(cval1) > abs(dval5) * 3.0:
124 temp_k_point_correction = mval3 + abs(dval5) * 3.0 * np.sign(cval1)
125
126 self.k_point_correction = temp_k_point_correction
127
128 ####################################################################
129
130 sum_squere = 0.0
131 vol_water = 0.0
132 pixel_counter = 0.0
133 for yy in matrix:
134 for xx in yy:
135 lm_value = xx[0]
136 m_prec = self.GetPrecByDBZ(lm_value) / 6.0
137
138 vol_local = self.pixel_size * self.pixel_size * (1.0/1000.0) * m_prec * self.k_point_correction
139 vol_water = vol_water + vol_local
140
141 if vol_local > 0.0:
142 sum_squere = sum_squere + 1.0
143 pixel_counter += 1.0
144
145 sum_squere = sum_squere * self.pixel_size * self.pixel_size
146
147 result = dict(time = cur_datetime.__str__(),
148 water_volume = vol_water,
149 prec_square = sum_squere,
150 all_square = self.squere)
151
152 self.SetNewReservKoefficient(cur_prec_value, vol_water)
153
154 return json.dumps(result)
155 ########################################################################
1 import urllib.request
2 import json
3 import os
4 import datetime
5 from imageio import imread
6 import cv2
7 import numpy as np
8 import loca_data
9 import duamel_model
10 import matplotlib.pyplot as plt
11 import sher_duam_class
12 import dateutil.parser
13 import dmrl_prec_file
14
15 class DMRLPrecFile_WOC(dmrl_prec_file.DMRLPrecFile):
16
17 # Получить результаты расчёта
18 def GetResult(self, _prec, _test_datetime=None):
19 """
20 _prec это JSON вида:
21 {"time": "2020-03-20T10:00:00Z",
22 "period": 600,
23 "sum": 0.0,
24 "intensity": 0.0,
25 "type": 0}
26 """
27
28 result = None
29 if _prec["sum"] == " ":
30 _prec = None
31
32 temp_datetime = datetime.datetime.now()
33 temp_cur_min = (temp_datetime.minute // 10) * 10
34 cur_datetime = datetime.datetime(temp_datetime.year, temp_datetime.month, temp_datetime.day, temp_datetime.hour, temp_cur_min, 0, 0)
35
36 if _prec is not None:
37 cur_datetime = dateutil.parser.parse(_prec["time"])
38
39 if _test_datetime is not None:
40 cur_datetime = _test_datetime
41
42 matrix = self.GetMatrix(cur_datetime)
43
44 # 1. Если ДМРЛ нет и нет осадков
45 if matrix is None:
46 result = dict(time = cur_datetime.__str__(),
47 water_volume = 0.0,
48 prec_square = 0.0,
49 all_square = -1.0,
50 dmrl_prec = -1.0)
51 return json.dumps(result)
52
53 # 3-4. Если есть ДМРЛ и есть (или нет) осадков с АГК - ОБЫЧНЫЙ АЛГОРИТМ
54 # Определяем коэффициент корреляции, если оба значения есть и отличны от нуля
55 cur_prec_value = 0
56 dmrl_prec = -1.0
57
58 sum_squere = 0.0
59 vol_water = 0.0
60 vol_water_wc = 0.0
61 pixel_counter = 0.0
62 for yy in matrix:
63 for xx in yy:
64 lm_value = xx[0]
65 m_prec = self.GetPrecByDBZ(lm_value) / 6.0
66
67 vol_local_wc = self.pixel_size * self.pixel_size * (1.0/1000.0) * m_prec
68
69 vol_water_wc = vol_water_wc + vol_local_wc
70
71 if vol_water_wc > 0.0:
72 sum_squere = sum_squere + 1.0
73 pixel_counter += 1.0
74
75 sum_squere = sum_squere * self.pixel_size * self.pixel_size
76
77 if self.squere != 0.0:
78 dmrl_prec = vol_water_wc / self.squere
79
80 result = dict(
81 time = cur_datetime.__str__(), # Дата
82 water_volume = vol_water_wc, # объём воды (метры в кубе)
83 prec_square = sum_squere, # площадь выпадения осадков
84 all_square = self.squere, # общая площадь водосбора
85 dmrl_prec = dmrl_prec) # осадки (в мм) ОБЪЕМ ПРИВЕДЕННЫЙ К ОБЩЕЙ ПЛОЩАДИ ВОДОСБОРА
86
87 return json.dumps(result)
88 ########################################################################
1 import math
2
3 # Общие константы
4 DELTA_CONST = 1e-6
5 MIN_PART_DELTA_VAL = 1e-4
6 MIN_DUML_INGRL_VAL = 1e-4
7
8 # Единичный интеграл дюамеля
9 class DuhamelPart():
10
11 def __init__(self, _beg_time, _amp, _t_per):
12 self.beg_time = _beg_time
13 self.amp = _amp
14 self.t_per = _t_per
15 self.is_const = False
16
17 def part_step(self, _calc_time):
18 if self.is_const:
19 return self.amp
20 exp_val = math.exp( (self.beg_time - _calc_time)/self.t_per )
21 self.is_const = exp_val < DELTA_CONST
22 return self.amp * (1. - exp_val)
23
24 def const_part(self):
25 return self.is_const
26
27
28 # совокупность интегралов дюамеля
29 class DuhamelIntegral():
30
31 def __init__(self, _up_per = 1.0, _down_per = 20.0):
32 # параметры интеграла
33 # вроде как вначале одинаковые для всех
34 self.curr_time = -1.0
35 self.curr_src_val = 0.0
36
37 # непосредственно влияющие на интеграл
38 self.up_per = _up_per
39 self.down_per = _down_per
40
41 self.parts_set = []
42 self.duml_val = 0.0
43
44 def add_part(self, delta):
45 if abs(delta) < MIN_PART_DELTA_VAL:
46 return
47 if delta > 0:
48 self.parts_set.append(DuhamelPart(self.curr_time, delta, self.up_per))
49 else:
50 self.parts_set.append(DuhamelPart(self.curr_time, delta, self.down_per))
51
52 def calc_step(self, calc_time):
53 self.duml_val = 0.
54 for part in self.parts_set:
55 self.duml_val += part.part_step(calc_time)
56
57 return self.duml_val
58
59 def duml_step(self, time, value):
60 self.add_part(value - self.curr_src_val)
61 self.curr_time = time
62 self.curr_src_val = value
63 return self.calc_step(self.curr_time)
64
65 def clear_parts_set(self):
66 if abs(self.duml_val) >= MIN_DUML_INGRL_VAL:
67 return
68 for part in self.parts_set:
69 if not part.const_part():
70 return
71 self.parts_set = []
72
73 # Полная модель интегралов дюамеля с учетом корректирующих коэффициентов
74 class DumlRiverModel:
75
76 def __init__(self, _k_n = 1.0, _k_korr = 25.0, _res_add_val = 20.0, _dmi_up_per = 1.0, _dmi_down_per = 20.0):
77
78 self.duml_intgrl = DuhamelIntegral(_down_per=_dmi_down_per, _up_per=_dmi_up_per)
79
80 self.k_n = _k_n # константный коэффициент коррекции результата
81 self.save_k_n = self.k_n
82
83 self.k_korr = _k_korr # настраиваемый коэффициент коррекции результата
84 self.save_k_korr = self.k_korr
85
86 self.res_add_val = _res_add_val # аддитивная величина коррекции результата
87 self.save_add_val = self.res_add_val
88
89 def model_step(self, time, value):
90 return self.k_n * self.k_korr * self.duml_intgrl.duml_step(time, value) + self.res_add_val
91
92 # Расчёт стока с водосборов
93 class CatchmentArea():
94 def __init__(self, _capacity = 22.2, _in_filter = 1.0, _out_filter = 0.009):
95 # параметры водосбора
96 self.capacity = _capacity # вместимость водосбора, мм
97 self.in_filter = _in_filter # инфильтрация в почву за ед. периода, мм (за 10 мин)
98 self.out_filter = _out_filter # фильтрация из почвы за ед. периода, мм (за 10 мин)
99 self.level_delta = self.capacity
100
101 def calc_surface_flow(self, _rainfall):
102 мах_in = min(_rainfall, self.in_filter)
103 if мах_in <= self.level_delta:
104 self.level_delta -= мах_in
105 self.level_delta += self.out_filter
106 if self.level_delta > self.capacity:
107 self.level_delta = self.capacity
108 else:
109 self.level_delta += self.out_filter
110 if self.level_delta > self.capacity:
111 self.level_delta = self.capacity
112 мах_in = min(мах_in, self.level_delta)
113 self.level_delta -= мах_in
114
115 return _rainfall - мах_in
116
117 # реализация метода ньютона-рафсона
118 def newton_raphson(study_func, target_val, start_x, max_iter_count=10, max_err=1e-3, delta_x=1e-6):
119
120 # начальное значение аргумента
121 finded_x = start_x
122
123 # Цикл нахождения решения
124 iter_count = 0
125 err_y = 1e20
126
127 # цикл поиска решения
128 while (iter_count <= max_iter_count) and (abs(err_y) > max_err):
129
130 # Вычисляем производную dy/dx в точке x
131 # dfdx в принципе нам может быть известен аналитически, и в таком случае
132 # предпочтительно использовать аналитическое выражение.
133 dfdx = (study_func(finded_x + 0.5 * delta_x) - study_func(finded_x - 0.5 * delta_x)) / delta_x
134
135 # Находим приращение по y
136 err_y = study_func(finded_x) - target_val
137 # и по x
138 err_x = err_y / dfdx
139 # Получаем новое решение
140 finded_x = finded_x - err_x
141
142 # меняем к - во итераций
143 iter_count += 1
144
145 return finded_x
146
147 # для расчёта уровня воды по расходу в створе
148 class RiverCrossSection():
149
150 def __init__(self, _left_slope = 5.0, _bottom = 18.0, _right_slope = 5.0, _max_h = 3.6, _zero_bsv = -1.06, _n_roughness = 0.035, _i_bias = 0.00244):
151 # параметры трапеции
152 self._zero_wlevel = _zero_bsv
153 self._trap_a = _left_slope # ширина левого склона трапеции русла
154 self._trap_b = _bottom # ширина дна трапеции русла
155 self._trap_c = _right_slope # ширина правого склона трапеции русла
156 self._trap_d = _max_h # высота трапеции русла
157 if self._trap_d >= 0:
158 self._trap_leftCtg = self._trap_a / self._trap_d # котангенс левого угла трапеции русла
159 self._trap_rightCtg = self._trap_c / self._trap_d # котангенс правого угла трапеции русла
160 else:
161 self._trap_leftCtg = 0 # котангенс левого угла трапеции русла
162 self._trap_rightCtg = 0 # котангенс правого угла трапеции русла
163
164 self._i_rb_part = _i_bias # уклон русла
165 self._n_rb_part = _n_roughness # шероховатость русла
166
167 # площадь сечения (м^2)
168 def f_trap_area(self, h):
169 return self._trap_b * h + (self._trap_leftCtg + self._trap_rightCtg) * h * h / 2
170
171 # смоченный периметр (м)
172 def f_trap_perimetr(self, h):
173 return self._trap_b + \
174 math.sqrt(self._trap_leftCtg ** 2 + 1) * h + \
175 math.sqrt(self._trap_rightCtg ** 2 + 1) * h
176
177 # гидрологический радиус
178 def f_hydro_r(self, h):
179 return self.f_trap_area(h) / self.f_trap_perimetr(h)
180
181 # скорость потока (м/с)
182 def f_flow_speed(self, h):
183 return self.f_hydro_r(h)**(2./3) * math.sqrt(self._i_rb_part) / self._n_rb_part
184
185 # расход воды (м^3/с)
186 def f_flow_rate(self, h):
187 if h <= 0.:
188 return 0.
189 return self.f_trap_area(h) * self.f_flow_speed(h)
190
191 # расход воды (м^3/с)
192 def f_flow_rate_by_bs_h(self, bs_h):
193 return self.f_flow_rate(bs_h - self._zero_wlevel)
194
195 # уровень воды (м), определяемый по расходу воды (м^3/с)
196 def high_by_flow_rate(self, flow_rate):
197 if flow_rate <= 0.:
198 return 0.
199 return newton_raphson(self.f_flow_rate, flow_rate, 1.)
200
201 # уровень воды (м), определяемый по расходу воды (м^3/с) по балтийской системе высот
202 def bs_water_level(self, flow_rate):
203 return self.high_by_flow_rate(flow_rate) + self._zero_wlevel
1 import urllib.request
2 import json
3 import os
4 import datetime
5 from imageio import imread
6 import cv2
7 import numpy as np
8 import loca_data
9 import duamel_model
10 import matplotlib.pyplot as plt
11 import sher_duam_class
12
13 data_store = dict(max_prec = -500.0, values = {})
14
15 prec_store = []
16 prec_store.append([0.0, 0.0])
17 prec_store.append([1.0, 2.0])
18 prec_store.append([2.0, 4.0])
19 prec_store.append([6.0, 12.0])
20 prec_store.append([3.0, 6.0])
21 prec_store.append([4.0, 8.0])
22 prec_store.append([5.0, 10.0])
23
24
25 for p in prec_store:
26 if p[0] > data_store["max_prec"]:
27 data_store["max_prec"] = p[0]
28
29 key = p[0]
30 sd = data_store["values"]
31 sd[key] = p[1]
32
33 print(data_store)
34 print(sorted(data_store["values"].keys()))
35
36 value = 0.0
37 new_prec = 4.32
38
39 x1 = -1.0
40 x2 = -1.0
41 y1 = -1.0
42 y2 = -1.0
43 u_sort_keys = sorted(data_store["values"].keys(), reverse=True)
44 sort_keys = sorted(data_store["values"].keys(), reverse=False)
45
46 if new_prec > data_store["max_prec"]:
47 x1 = u_sort_keys[1]
48 x2 = u_sort_keys[0]
49 data_store["max_prec"] = new_prec
50 else:
51 if new_prec in sort_keys:
52 value = data_store["values"][new_prec]
53 print(value)
54 exit()
55 else:
56 counter = 0
57 for key in sort_keys:
58 if key > new_prec:
59 x1 = sort_keys[counter-1]
60 x2 = key
61 break
62 counter = counter + 1
63
64 y1 = data_store["values"][x1]
65 y2 = data_store["values"][x2]
66
67 value = ((x2 * y1 - x1 * y2) / (x2 - x1)) - (y1 - y2) * new_prec
68 print(value)
69
70
71
72
73
74 #print("{}|{}^^{}|{}".format(x1, y1, x2, y2))
75 #
76
77
78
1 import cv2
2 import numpy as np
3
4 # original image
5 # -1 loads as-is so if it will be 3 or 4 channel as the original
6 image = cv2.imread('test.png', -1)
7 # mask defaulting to black for 3-channel and transparent for 4-channel
8 # (of course replace corners with yours)
9 mask = np.zeros(image.shape, dtype=np.uint8)
10 roi_corners = np.array([[(10,10), (20,20), (10,30)]], dtype=np.int32)
11 # fill the ROI so it doesn't get wiped out when the mask is applied
12 channel_count = image.shape[2] # i.e. 3 or 4 depending on your image
13 ignore_mask_color = (255,)*channel_count
14 cv2.fillPoly(mask, roi_corners, ignore_mask_color)
15 # from Masterfool: use cv2.fillConvexPoly if you know it's convex
16
17 # apply the mask
18 masked_image = cv2.bitwise_and(image, mask)
19
20 # save the result
21 cv2.imwrite('image_masked.png', masked_image)
...\ No newline at end of file ...\ No newline at end of file
1 import urllib.request
2 import json
3 import os
4 import datetime
5 from imageio import imread
6 import cv2
7 import numpy as np
8 import loca_data
9 import duamel_model
10 import matplotlib.pyplot as plt
11 import sher_duam_class
12 import dateutil.parser
13 import psycopg2
14 import pathlib
15
16
17 def get_connection():
18 DBConnection = psycopg2.connect(
19 host="localhost",
20 port = "15432",
21 database="wf71",
22 user="wf71",
23 password="wf71")
24 print("Connect is success!")
25 DBConnection.autocommit = True
26 return DBConnection
27
28 def write_png(filename = "test.png", px_array = None):
29 if px_array is None:
30 px_array = np.zeros(10,10)
31 path = pathlib.Path(__file__).parent.absolute()
32 path = str(path) + filename
33 cv2.imwrite(path, px_array)
34
35 def get_png_data_from_db():
36 DBConnection = get_connection()
37 print("Connect is success!")
38 cur = DBConnection.cursor()
39 query = "select measuretime, additional_info from md_precipitation where measurer_uuid = '1bc2b71c-d505-4034-a939-df0252b3f7c6' and measuretime >= '2020-07-08 07:00:00' and measuretime <= '2020-07-09 07:00:00'"
40 cur.execute(query)
41 result = cur.fetchall()
42 radar_a = 200
43 radar_n = 1.6
44 for_txt = []
45
46 for var in result:
47 matrix = []
48 m_dt = var[0]
49 mx = json.loads(var[1])
50 value = 0.0
51
52 error = mx.get("error", False)
53
54 if error == "Radar matrix is not exist":
55 value = 0.0
56 else:
57 matrix = mx["matrix"]
58 if len(matrix) > 1:
59 _dbz = matrix[143][107]
60 if _dbz == 0 or _dbz > 127:
61 value = 0.0
62 else:
63 step1 = (_dbz - 32) / 10
64 step2 = 10 ** step1
65 step3 = step2 / radar_a
66 step4 = step3 ** (1.0/radar_n)
67 step5 = step4 / 6.0
68 value = step5
69
70 #delta_dt = datetime.timedelta(hours=3)
71 #m_dt = datetime.datetime.strptime(str(m_dt), '%Y-%m-%d %H:%M:%S') - delta_dt
72 for_txt.append([str(m_dt), value])
73
74 cur.close()
75 f = open('result_from_db.txt', 'w')
76 f.write(str(for_txt))
77 f.close()
78
79 def get_png_picture_from_db():
80 DBConnection = get_connection()
81 print("Connect is success!")
82 cur = DBConnection.cursor()
83 query = "select measuretime, additional_info from md_precipitation where measurer_uuid = '1bc2b71c-d505-4034-a939-df0252b3f7c6' and measuretime >= '2020-07-08 07:00:00' and measuretime <= '2020-07-09 07:00:00'"
84 cur.execute(query)
85 result = cur.fetchall()
86 i = -1
87
88
89 for var in result:
90 matrix = []
91 m_dt = var[0]
92 td = datetime.timedelta(hours=3)
93 m_dt = m_dt+td
94 print(m_dt)
95 mx = json.loads(var[1])
96 img = np.zeros((256,256, 4),dtype=np.uint8)
97
98 error = mx.get("error", False)
99
100 if error == "Radar matrix is not exist":
101 continue
102 else:
103 matrix = mx["matrix"]
104 if len(matrix) > 1:
105 #png_data = []
106 #for line in matrix:
107 # new_line = []
108 # for column in line:
109 # new_line.append([column, column, column, 255])
110 # png_data.append(new_line)
111 #png_data = np.array(png_data)
112 x = -1
113 for line in matrix:
114 x = x + 1
115 y = -1
116 for column in line:
117 y = y + 1
118 img[x][y] = [column, column, column, 255]
119
120 fn_dt = '{}_{}_{}__{}_{}.png'.format(m_dt.timetuple()[0], m_dt.timetuple()[1], m_dt.timetuple()[2], m_dt.timetuple()[3], m_dt.timetuple()[4])
121 #write_png(filename=r"/png_07/{}".format(fn_dt), px_array=png_data)
122 write_png(filename=r"/png_07/{}".format(fn_dt), px_array=img)
123 cur.close()
124 #get_png_picture_from_db
125
126
127 #get_png_data_from_db()
128 get_png_picture_from_db()
129
1 import urllib.request
2 import json
3 import os
4 import datetime
5 from imageio import imread
6 import cv2
7 import numpy as np
8 import loca_data
9 import duamel_model
10 import matplotlib.pyplot as plt
11 import sher_duam_class
12
13
14 png_path = r"d:\PYTHON\tests\test1\test_png\dj_286m_1580308200.png"
15 save_path = r"d:\PYTHON\tests\test1\test_png\test.png"
16
17 lenght_lan = 79497.3714882
18 lenght_lon = 111162.6
19 base_pixel_len = 152.8740566
20 str_limiter = '||'
21
22 d1plan_g = base_pixel_len / lenght_lan
23 d1plon_g = base_pixel_len / lenght_lon
24 x286lon = 38.72287
25 x286lan = 44.417242
26
27 base_lon = x286lon - (128 * d1plon_g)
28 min_lon = x286lon - (128 * d1plon_g)
29 max_lon = x286lon + (128 * d1plon_g)
30
31 base_lan = x286lan + (128 * d1plan_g)
32 min_lan = x286lan - (128 * d1plan_g)
33 max_lan = x286lan + (128 * d1plan_g)
34
35 pol_store = []
36 prec_meas = []
37
38 # Сгенерировать полигон по набору геокоординат
39 def GeneratePolygons(_meas_list, _number, _name):
40 # Максимальные значения координат Х и У для полигона
41 max_x = 0
42 max_y = 0
43 min_x = 256
44 min_y = 256
45
46 #Временный полигон
47 tmp_pol = []
48
49 # Перебрать измерители последовательно и сформировать полигон как набор пар (х, у) плюс данные о границах полигона (прямоугольных)
50 for imeas in _meas_list:
51 mx =imeas["x"]
52 my = imeas["y"]
53 # Ищем прямоугольные границы полигона
54 if mx > max_x:
55 max_x = mx
56 if my > max_y:
57 max_y = my
58 if mx < min_x:
59 min_x = mx
60 if my < min_y:
61 min_y = my
62 tmp_pol.append((mx, my))
63
64 #result = dict(number = _number, name = _name, max_x = max_x, max_y = max_y, min_x = min_x, min_y = min_y, pol = tmp_pol)
65 result = tmp_pol
66 return result
67
68 # получить измеритель (имя, номер, х-коорд картинки и у-коорд картинки) из широты и долготы
69 def GetMeas(_number, _name, _lan, _lon):
70 if _lan <= min_lan or _lan >= max_lan:
71 print("MeasUnit named {} have not current lan ({})".format(_name, _lan))
72 return None
73 if _lon <= min_lon or _lon >= max_lon:
74 print("MeasUnit named {} have not current lon ({})".format(_name, _lon))
75 return None
76
77 lan_delta = _lan - base_lan
78 lon_delta = _lon - base_lon
79
80 y_delta = lan_delta * lenght_lan
81 x_delta = lon_delta * lenght_lon
82
83 my = y_delta // base_pixel_len
84 mx = x_delta // base_pixel_len
85
86 result = dict(number = _number, name = _name, x = abs(mx), y = abs(my))
87 return result
88
89 _image = imread(png_path)
90
91 # Получение координат полигона водосбора Джубги
92 pcs = loca_data.GetGeoCoordPolygon()
93
94 # Последняя запись - для отбрасывания дублей пикселей
95 p_last = dict(x = -1.0, y = 0.0)
96
97 all_result = []
98
99 # Получаем список точек полигона
100 for pc in pcs:
101 p = GetMeas(pc[0], pc[1], pc[2], pc[3])
102
103 if p_last['x'] == -1.0:
104 p_last['x'] = p['x']
105 p_last['y'] = p['y']
106 all_result.append(p)
107 else:
108 if p_last['x'] != p['x'] and p_last['y'] != p['y']:
109 all_result.append(p)
110
111 p_last['x'] = p['x']
112 p_last['y'] = p['y']
113
114 polygon = GeneratePolygons(all_result, 0, "All")
115 #polygon = all_result
116
117
118 ##################################################
119 # пробуем создать пустое изображение и заполнить его полигоном
120 img = np.zeros((256,256,4), np.uint8)
121
122 for yy in img:
123 for xx in yy:
124 xx[0] = 255
125 xx[1] = 0
126 xx[2] = 0
127 xx[3] = 255
128
129 img_mask = np.zeros(img.shape, dtype=np.uint8)
130 img_roi_corners = np.array([polygon], dtype=np.int32)
131 img_ignore_mask_color = (255,)*4
132 cv2.fillPoly(img_mask, img_roi_corners, img_ignore_mask_color)
133 img_masked_image = cv2.bitwise_and(img, img_mask)
134
135 cv2.imwrite(save_path, img_masked_image)
136
137 pcx_square_count = 0
138
139 for yy in img_masked_image:
140 for xx in yy:
141 if xx[0] == 255:
142 pcx_square_count = pcx_square_count + 1
143
144 print(pcx_square_count)
145
146 squere = base_pixel_len * base_pixel_len * pcx_square_count
147
148 print(squere)
149
150
151
152 ##################################################
153
154
155 '''mask = np.zeros(_image.shape, dtype=np.uint8)
156
157 roi_corners = np.array([polygon], dtype=np.int32)
158
159 channel_count = _image.shape[2] # i.e. 3 or 4 depending on your image
160
161 ignore_mask_color = (255,)*channel_count
162
163 cv2.fillPoly(mask, roi_corners, ignore_mask_color)
164
165 masked_image = cv2.bitwise_and(_image, mask)'''
166
167
1 import urllib.request
2 import json
3 import os
4 import datetime
5 from imageio import imread
6
7
8 png_path = r"d:\PYTHON\tests\test1\png"
9
10 lenght_lan = 79497.3714882
11 lenght_lon = 111162.6
12 base_pixel_len = 152.8740566
13 str_limiter = '||'
14
15 d1plan_g = base_pixel_len / lenght_lan
16 d1plon_g = base_pixel_len / lenght_lon
17 x286lon = 38.72287
18 x286lan = 44.417242
19
20 base_lon = x286lon - (128 * d1plon_g)
21 min_lon = x286lon - (128 * d1plon_g)
22 max_lon = x286lon + (128 * d1plon_g)
23
24 base_lan = x286lan + (128 * d1plan_g)
25 min_lan = x286lan - (128 * d1plan_g)
26 max_lan = x286lan + (128 * d1plan_g)
27
28 # Генерировать измерители
29 def GenerateMeasurements():
30
31 result = []
32 l_dlan = d1plan_g * 48
33 l_dlon = d1plon_g * 48
34 result.append(GetMeas(1, 'X286|sp_dm', x286lan+l_dlan, x286lon-l_dlon))
35 result.append(GetMeas(2, 'X286|sp_d0', x286lan+l_dlan, x286lon-0))
36 result.append(GetMeas(3, 'X286|sp_dp', x286lan+l_dlan, x286lon+l_dlon))
37 result.append(GetMeas(4, 'X286|s0_dm', x286lan+0, x286lon-l_dlon))
38 result.append(GetMeas(5, 'X286|s0_d0', x286lan+0, x286lon-0))
39 result.append(GetMeas(6, 'X286|s0_dp', x286lan+0, x286lon+l_dlon))
40 result.append(GetMeas(7, 'X286|sm_dm', x286lan-l_dlan, x286lon-l_dlon))
41 result.append(GetMeas(8, 'X286|sm_d0', x286lan-l_dlan, x286lon-0))
42 result.append(GetMeas(9, 'X286|sm_dp', x286lan-l_dlan, x286lon+l_dlon))
43
44 '''
45 result.append(GetMeas(1, 'TEST_01', 44.3251277777778, 38.6788694444444))
46 result.append(GetMeas(2, 'TEST_02', 44.3727555555556, 38.7005))
47 result.append(GetMeas(3, 'TEST_03', 44.4186305555556, 38.6651361111111))
48 result.append(GetMeas(4, 'TEST_04', 44.4545888888889, 38.6328638888889))
49 result.append(GetMeas(5, 'TEST_05', 44.4508222222222, 38.6833333333333))
50 result.append(GetMeas(6, 'TEST_06', 44.4329277777778, 38.7327722222222))
51 result.append(GetMeas(7, 'TEST_07', 44.4106166666667, 38.7633277777778))
52 result.append(GetMeas(8, 'TEST_08', 44.3846138888889, 38.7533722222222))
53 result.append(GetMeas(9, 'TEST_09', 44.3416583333333, 38.735175))
54 '''
55
56 return result
57
58 # получить измеритель (имя, номер, х-коорд картинки и у-коорд картинки) из широты и долготы
59 def GetMeas(_number, _name, _lan, _lon):
60 if _lan <= min_lan or _lan >= max_lan:
61 print("MeasUnit named {} have not current lan ({})".format(_name, _lan))
62 return None
63 if _lon <= min_lon or _lon >= max_lon:
64 print("MeasUnit named {} have not current lon ({})".format(_name, _lon))
65 return None
66
67 lan_delta = _lan - base_lan
68 lon_delta = _lon - base_lon
69
70 y_delta = lan_delta * lenght_lan
71 x_delta = lon_delta * lenght_lon
72
73 my = y_delta // base_pixel_len
74 mx = x_delta // base_pixel_len
75
76 result = dict(number = _number, name = _name, x = abs(mx), y = abs(my))
77 return result
78
79 # Получить осадки по значению dbZ
80 def GetPrecByDBZ_2(_dbz):
81 result = 0
82
83 if _dbz == 0 or _dbz > 127:
84 return result
85
86 step1 = (_dbz - 32) / 10
87 step2 = 10 ** step1
88 step3 = step2 / 200
89 step4 = step3 ** 0.625
90 result = step4
91 return result
92
93 # Получаем все файлы из директории с сохранёнными изображениями
94 png_files = os.listdir(png_path)
95 print(png_files)
96 print("Lan border = {} - {}".format(min_lan, max_lan))
97 print("Lon border = {} - {}".format(min_lon, max_lon))
98
99 # Сформировать массив "матрица картинки-время" (время из названия файла)
100 store = []
101 for png_f in png_files:
102 dt_value = png_f.replace('dj_286m_', '').replace('.png', '')
103 dt_value = int(dt_value)
104 dt_value = datetime.datetime.fromtimestamp(dt_value)
105 date_diff = datetime.timedelta(hours=0)
106 dt_value = dt_value + date_diff
107 file_data = imread(png_path + '\\' + png_f)
108 st_unit = dict(
109 datetime = dt_value,
110 matrix = file_data
111 )
112 store.append(st_unit)
113
114 # Генерируем тестовые измерители
115 prec_meas = GenerateMeasurements()
116
117 # Болванка для шапки в Эксель
118 shapka = 'Date\t'
119 x_y = ''
120
121 # Формируем шапку для Экселя
122 for mes in prec_meas:
123 if mes is not None:
124 shapka += mes["name"] + str_limiter
125 x_y += "N={} X={} Y={}{}".format(mes["number"], mes["x"], mes["y"], str_limiter)
126
127 print(shapka)
128
129 # Формируем данные
130 main_data = ""
131
132 # Последниё интервал расчёта
133 last_datetime = store[0]["datetime"]
134
135 # Дельта (служебная) между интервалами расчёта
136 dt = datetime.timedelta(minutes=10)
137
138 # Пробегаемся по всем картинкам в хранилище
139 for prec_data in store:
140
141 # Формируем локальные переменные для цикла
142 lmatrix = prec_data["matrix"]
143 ldatetime = prec_data["datetime"]
144 date_diff = ldatetime - last_datetime
145 local_data = ""
146
147 # Фиксим (пустой строкой) промежутки между измерениями, если таковые имеются
148 while date_diff.seconds >= 1200:
149 local_data = ""
150 last_datetime = last_datetime + dt
151 local_data += last_datetime.__str__() + str_limiter
152 main_data += local_data + "\n"
153 date_diff = ldatetime - last_datetime
154
155 # Формируем для каждого измерителя оасдки в точке, согласно его прямоугольным координатам относительно картинки
156 local_data = ""
157 local_data += ldatetime.__str__() + str_limiter
158 for mes in prec_meas:
159 y = int(mes["y"])
160 x = int(mes["x"])
161 value = lmatrix[y][x][0]
162 prec = GetPrecByDBZ_2(value)
163 local_data += prec.__str__() + str_limiter
164
165 # Ищем максимум осадков на картинке
166 prec_max = 0
167 '''
168 for yy in lmatrix:
169 for xx in yy:
170 lm_value = xx[0]
171 m_prec = GetPrecByDBZ_2(lm_value)
172 if m_prec > prec_max:
173 prec_max = m_prec
174
175 local_data += prec_max.__str__() + str_limiter
176 '''
177 # Вываливаем данные
178 main_data += local_data + "\n"
179 last_datetime = ldatetime
180
181 # Заменяем временные разделители и прочие символы для правильного отобраежния в Эксель
182 main_data = main_data.replace("||", "\t")
183 main_data = main_data.replace(".", ",")
184
185 # Пишем результат в текстовый файл
186 f = open('result.txt', 'w')
187 f.write(main_data)
188 f.close()
189
190
191 """
192 1. Для каждого измерителя ищем разницу в широте и долготе лот базовых координат
193 1.1 Проверяем на выход за предельные значения
194 2. По здначениям дельты и длинам градусов ищем разницу в метрах
195 3. По разнице в метрах и базовому размеру пикселя ищем нужный квадрат как количество целых делений дельты в метрах на базовую длину градуса
196 """
197
1 import sys
2 import os
3 import time
4 import datetime
5 import json
6 import jsonpickle
7 import importlib
8 import urllib.request
9 from imageio import imread
10 import redis
11 import requests
12 import dateutil.parser
13
14 time_result = None
15
16 try:
17 time_url = 'https://tilecache.rainviewer.com/api/maps.json'
18 time_result = json.load(urllib.request.urlopen(time_url))
19 except Exception as e:
20 print("ERROR::{er}".format(er=e))
21 exit()
22
23 if time_result is None or len(time_result) < 1:
24 print("time result is empty")
25 exit()
26
27 itime = time_result[0]
28 last_number = len(time_result) - 1
29
30 last = 0
31 for in_dt in time_result:
32 dt_value = datetime.datetime.fromtimestamp(in_dt)
33 print("{}-{}".format(in_dt, dt_value))
34 print("DELTA = {}".format(in_dt - last))
35 last = in_dt
36
37 dt_value = datetime.datetime.fromtimestamp(time_result[last_number])
38 print("Текущий - {} -> {}".format(time_result[last_number], dt_value))
39
40
41 # Определяем текущий тайм-слот
42 _datetime = datetime.datetime.now()
43 cur_min = (_datetime.minute // 10) * 10
44 current_ts = datetime.datetime(_datetime.year, _datetime.month, _datetime.day, _datetime.hour, cur_min, 0, 0)
45 current_ts_ts = current_ts.timestamp()
46 last_ts = int(current_ts.timestamp()) + 600
47
48 '''
49 while datetime.datetime.now().timestamp() < last_ts:
50
51 time_result = None
52 time_url = 'https://tilecache.rainviewer.com/api/maps.json'
53 time_result = json.load(urllib.request.urlopen(time_url))
54
55 if time_result is None or len(time_result) < 1 or current_ts_ts not in time_result:
56 print("{} No data...".format(datetime.datetime.now()))
57 time.sleep(30)
58 continue
59
60 png_data_url = 'https://tilecache.rainviewer.com/v2/radar/{time}/256/10/{lan}/{lon}/0/0_0.png'.format(time=itime,
61 lan="44.417242",
62 lon="38.72287")
63
64 img = imread(png_data_url)
65 '''
66
67 url_ocm = r'http://10.110.0.37:8888/monitoring/rest/precipitation-measurements/33ce9a80-27df-41dd-8dbe-cf3ec918b4c2?time-from=2020-03-20 10:00:00&time-to=2020-03-20 16:00:00'
68 ocm_data = requests.get(url_ocm)
69 print(ocm_data.json())
70 data = ocm_data.json()
71
72 for data_item in data:
73 print("value = time-{}, sum - {}".format(data_item["time"], data_item["sum"]))
74 #cur_cs = datetime.datetime.fromisoformat(data_item["time"])
75 str = data_item["time"]
76 cur_cs = datetime.datetime.strptime(data_item["time"], '%Y-%m-%dT%H:%M:%SZ')
77 cs2 = dateutil.parser.parse(str, ignoretz=False)
78
79 cs3 = cs2.replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)
80 cs4 = dateutil.parser.parse(str, ignoretz=False).replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)
81
82 #dateutil.parser.parse(data_item["time"])
83 print(cur_cs)
84 print(cs2)
85 print(cs3)
86 print(cs4)
87
1 import urllib.request
2 import json
3 import os
4 import datetime
5 from imageio import imread
6 import cv2
7 import numpy as np
8
9
10
11 png_path = r"d:\PYTHON\tests\test1\png"
12 png_result_path = r"d:\PYTHON\tests\test1\cutted"
13
14 lenght_lan = 79497.3714882
15 lenght_lon = 111162.6
16 base_pixel_len = 152.8740566
17 str_limiter = '||'
18
19 d1plan_g = base_pixel_len / lenght_lan
20 d1plon_g = base_pixel_len / lenght_lon
21 x286lon = 38.72287
22 x286lan = 44.417242
23
24 base_lon = x286lon - (128 * d1plon_g)
25 min_lon = x286lon - (128 * d1plon_g)
26 max_lon = x286lon + (128 * d1plon_g)
27
28 base_lan = x286lan + (128 * d1plan_g)
29 min_lan = x286lan - (128 * d1plan_g)
30 max_lan = x286lan + (128 * d1plan_g)
31
32 # Генерировать измерители
33 def GenerateMeasurements():
34
35 result = []
36 l_dlan = d1plan_g * 48
37 l_dlon = d1plon_g * 48
38 '''
39 result.append(GetMeas(1, 'X286|sp_dm', x286lan+l_dlan, x286lon-l_dlon))
40 result.append(GetMeas(2, 'X286|sp_d0', x286lan+l_dlan, x286lon-0))
41 result.append(GetMeas(3, 'X286|sp_dp', x286lan+l_dlan, x286lon+l_dlon))
42 result.append(GetMeas(4, 'X286|s0_dm', x286lan+0, x286lon-l_dlon))
43 result.append(GetMeas(5, 'X286|s0_d0', x286lan+0, x286lon-0))
44 result.append(GetMeas(6, 'X286|s0_dp', x286lan+0, x286lon+l_dlon))
45 result.append(GetMeas(7, 'X286|sm_dm', x286lan-l_dlan, x286lon-l_dlon))
46 result.append(GetMeas(8, 'X286|sm_d0', x286lan-l_dlan, x286lon-0))
47 result.append(GetMeas(9, 'X286|sm_dp', x286lan-l_dlan, x286lon+l_dlon))
48
49 '''
50 result.append(GetMeas(0, 'TEST_00', x286lan, x286lon))
51 result.append(GetMeas(1, 'TEST_01', 44.3251277777778, 38.6788694444444))
52 result.append(GetMeas(2, 'TEST_02', 44.3727555555556, 38.7005))
53 result.append(GetMeas(3, 'TEST_03', 44.4186305555556, 38.6651361111111))
54 result.append(GetMeas(4, 'TEST_04', 44.4545888888889, 38.6328638888889))
55 result.append(GetMeas(5, 'TEST_05', 44.4508222222222, 38.6833333333333))
56 result.append(GetMeas(6, 'TEST_06', 44.4329277777778, 38.7327722222222))
57 result.append(GetMeas(7, 'TEST_07', 44.4106166666667, 38.7633277777778))
58 result.append(GetMeas(8, 'TEST_08', 44.3846138888889, 38.7533722222222))
59 result.append(GetMeas(9, 'TEST_09', 44.3416583333333, 38.735175))
60
61
62 return result
63
64 # получить измеритель (имя, номер, х-коорд картинки и у-коорд картинки) из широты и долготы
65 def GetMeas(_number, _name, _lan, _lon):
66 if _lan <= min_lan or _lan >= max_lan:
67 print("MeasUnit named {} have not current lan ({})".format(_name, _lan))
68 return None
69 if _lon <= min_lon or _lon >= max_lon:
70 print("MeasUnit named {} have not current lon ({})".format(_name, _lon))
71 return None
72
73 lan_delta = _lan - base_lan
74 lon_delta = _lon - base_lon
75
76 y_delta = lan_delta * lenght_lan
77 x_delta = lon_delta * lenght_lon
78
79 my = y_delta // base_pixel_len
80 mx = x_delta // base_pixel_len
81
82 result = dict(number = _number, name = _name, x = abs(mx), y = abs(my))
83 return result
84
85 # Получить осадки по значению dbZ
86 def GetPrecByDBZ_2(_dbz):
87 result = 0
88
89 if _dbz == 0 or _dbz > 127:
90 return result
91
92 step1 = (_dbz - 32) / 10
93 step2 = 10 ** step1
94 step3 = step2 / 200
95 step4 = step3 ** 0.625
96 result = step4
97 return result
98
99 # Сгенерировать полигон по набору геокоординат
100 def GeneratePolygons(_meas_list, _number, _name):
101 # Максимальные значения координат Х и У для полигона
102 max_x = 0
103 max_y = 0
104 min_x = 256
105 min_y = 256
106
107 #Временный полигон
108 tmp_pol = []
109
110 # Перебрать измерители последовательно и сформировать полигон как набор пар (х, у) плюс данные о границах полигона (прямоугольных)
111 for imeas in _meas_list:
112 mx =imeas["x"]
113 my = imeas["y"]
114 # Ищем прямоугольные границы полигона
115 if mx > max_x:
116 max_x = mx
117 if my > max_y:
118 max_y = my
119 if mx < min_x:
120 min_x = mx
121 if my < min_y:
122 min_y = my
123 tmp_pol.append((mx, my))
124
125 result = dict(number = _number, name = _name, max_x = max_x, max_y = max_y, min_x = min_x, min_y = min_y, pol = tmp_pol)
126 result["pol"] = tmp_pol
127 return result
128
129 # Получить "обрезанную" матрицу по полигону
130 def GetCuttedMatrix(_image, _mpolygon):
131 matrix = _mpolygon["pol"]
132 max_x = int(_mpolygon["max_x"])
133 max_y = int(_mpolygon["max_y"])
134 min_x = int(_mpolygon["min_x"])
135 min_y = int(_mpolygon["min_y"])
136 mask = np.zeros(_image.shape, dtype=np.uint8)
137 roi_corners = np.array([matrix], dtype=np.int32)
138 channel_count = _image.shape[2] # i.e. 3 or 4 depending on your image
139 ignore_mask_color = (255,)*channel_count
140 cv2.fillPoly(mask, roi_corners, ignore_mask_color)
141 masked_image = cv2.bitwise_and(_image, mask)
142 masked_image = masked_image[min_y:max_y, min_x:max_x]
143 return masked_image
144
145
146 # Получаем все файлы из директории с сохранёнными изображениями
147 png_files = os.listdir(png_path)
148 print(png_files)
149 print("Lan border = {} - {}".format(min_lan, max_lan))
150 print("Lon border = {} - {}".format(min_lon, max_lon))
151
152 # Сформировать массив "матрица картинки-время" (время из названия файла)
153 store = []
154 for png_f in png_files:
155 dt_value = png_f.replace('dj_286m_', '').replace('.png', '')
156 dt_value = int(dt_value)
157 dt_value = datetime.datetime.fromtimestamp(dt_value)
158 date_diff = datetime.timedelta(hours=2)
159 dt_value = dt_value + date_diff
160 file_data = imread(png_path + '\\' + png_f)
161 st_unit = dict(
162 datetime = dt_value,
163 matrix = file_data
164 )
165 store.append(st_unit)
166
167 # Генерируем тестовые измерители
168 prec_meas = GenerateMeasurements()
169
170 # Формируем данные
171 main_data = ""
172
173 ################################################################
174 # TEST - генерация обрезанных файлов
175
176 main_pol = GeneratePolygons([prec_meas[0], prec_meas[3], prec_meas[4], prec_meas[5], prec_meas[6]], 1, "Verh")
177 main_pol = GeneratePolygons([prec_meas[0], prec_meas[6], prec_meas[7], prec_meas[8], prec_meas[9], prec_meas[1], prec_meas[2]], 2, "Nige_Polkovnichego")
178 pol_store = []
179 pol_store.append(main_pol)
180 cutted_store = []
181
182 '''
183 for m_image in store:
184 image = m_image["matrix"]
185 masked_image = GetCuttedMatrix(image, main_pol)
186 path_to_save = "d:\\PYTHON\\tests\\test1\\cutted\\{name}_{dt}.png".format(name = main_pol["name"], dt = m_image["datetime"].timestamp())
187 #cv2.imwrite(path_to_save, masked_image)
188 cutted_store.append(masked_image)
189 '''
190 ################################################################
191
192 # Последниё интервал расчёта
193 last_datetime = store[0]["datetime"]
194
195 # Дельта (служебная) между интервалами расчёта
196 dt = datetime.timedelta(minutes=10)
197
198 # Пробегаемся по всем картинкам в хранилище
199 for prec_data in store:
200
201 # Формируем локальные переменные для цикла
202 lmatrix = prec_data["matrix"]
203 ldatetime = prec_data["datetime"]
204 date_diff = ldatetime - last_datetime
205 local_data = ""
206
207 # Фиксим (пустой строкой) промежутки между измерениями, если таковые имеются
208 while date_diff.seconds >= 1200:
209 local_data = ""
210 last_datetime = last_datetime + dt
211 local_data += last_datetime.__str__() + str_limiter
212 main_data += local_data + "\n"
213 date_diff = ldatetime - last_datetime
214
215 # Формируем для каждого полигона осадки, согласно его прямоугольным координатам относительно картинки
216 local_data = ""
217 local_data += ldatetime.__str__() + str_limiter
218 for pol in pol_store:
219 masked_image = GetCuttedMatrix(lmatrix, pol)
220 sum_prec = 0
221 for yy in masked_image:
222 for xx in yy:
223 lm_value = xx[0]
224 m_prec = GetPrecByDBZ_2(lm_value)
225 sum_prec += m_prec
226 local_data += sum_prec.__str__() + str_limiter
227 # Вываливаем данные
228 main_data += local_data + "\n"
229 last_datetime = ldatetime
230
231 # Заменяем временные разделители и прочие символы для правильного отобраежния в Эксель
232 main_data = main_data.replace("||", "\t")
233 main_data = main_data.replace(".", ",")
234
235 # Пишем результат в текстовый файл
236 f = open('result.txt', 'w')
237 f.write(main_data)
238 f.close()
239
240
241 """
242 1. Для каждого измерителя ищем разницу в широте и долготе лот базовых координат
243 1.1 Проверяем на выход за предельные значения
244 2. По здначениям дельты и длинам градусов ищем разницу в метрах
245 3. По разнице в метрах и базовому размеру пикселя ищем нужный квадрат как количество целых делений дельты в метрах на базовую длину градуса
246 """
247

650 Bytes

943 Bytes

This diff is collapsed. Click to expand it.
1 Проект "Треугольные осадки"
2 I ЭТАП - ОТРАБОТКА ОБЩЕГО МАТЕМАТИЧСКОГО РЕШЕНИЯ
3 . Задать три точки с координатами Р1, Р2, Р3 - (х1у1с1, х2у2с2, х3у3с3)
4 . Определить "площадь решения" в виде плоского рисунка
5 . Нарисовать треугольник Т по трём точкам Рх
6 . Определить формулу плоскости ПЛ по трем точкам Рх
7 . Определить формулу принадлежности произвольной точки Рн треугольнику Р1Р2Р3
8 . Пройтись по каждой точке Рпр площади решения и определить, принадлежит ли выбранная точка треугольнику Т
9 . Если принадлежит - то определить цвет по формуле ПЛ и установить его на площади решения
10 . Сохранить результат в виде рисунка png
1 import numpy as np
2 import matplotlib.pyplot as plt
3 import datetime
4 import os.path
5 import loca_data
6 import math
7
8 '''
9 # реализация метода ньютона-рафсона
10 def newton_raphson(study_func, target_val, start_x, max_iter_count=10, max_err=1e-3, delta_x=1e-6):
11
12 # начальное значение аргумента
13 finded_x = start_x
14
15 # Цикл нахождения решения
16 iter_count = 0
17 err_y = 1e20
18
19 # цикл поиска решения
20 while (iter_count <= max_iter_count) and (abs(err_y) > max_err):
21
22 # Вычисляем производную dy/dx в точке x
23 # dfdx в принципе нам может быть известен аналитически, и в таком случае
24 # предпочтительно использовать аналитическое выражение.
25 dfdx = (study_func(finded_x + 0.5 * delta_x) - study_func(finded_x - 0.5 * delta_x)) / delta_x
26
27 # Находим приращение по y
28 err_y = study_func(finded_x) - target_val
29 # и по x
30 err_x = err_y / dfdx
31 # Получаем новое решение
32 finded_x = finded_x - err_x
33
34 # меняем к - во итераций
35 iter_count += 1
36
37 return finded_x
38 '''
39 '''
40 x = np.random.randint(low=1, high=11, size=50)
41 y = x + np.random.randint(1, 5, size=x.size)
42 data = np.column_stack((x, y))
43
44 fig, (ax1, ax2) = plt.subplots(
45 nrows=1, ncols=2,
46 figsize=(8, 4)
47 )
48
49 ax1.scatter(x=x, y=y, marker='o', c='r', edgecolor='b')
50 ax1.set_title('Scatter: $x$ versus $y$')
51 ax1.set_xlabel('$x$')
52 ax1.set_ylabel('$y$')
53
54 ax2.hist(
55 data, bins=np.arange(data.min(), data.max()),
56 label=('x', 'y')
57 )
58
59 ax2.legend(loc=(0.65, 0.8))
60 ax2.set_title('Frequencies of $x$ and $y$')
61 ax2.yaxis.tick_right()
62
63 x = [0,1,2,3,4,5]
64 y1 = [1,1,2,2,4,0]
65 y2 = [5,1,3,6,4,10]
66 y3 = [0,1,3,2,6,8]
67
68 fig, ax = plt.subplots()
69
70 ax.plot(x, y1, label = 'TEST1')
71 ax.plot(x, y2, label = 'ЕУЫЕ2')
72 ax.plot(x, y3, label = 'tmp3')
73
74 ax.legend()
75
76 #fig.set_figheight(5)
77 #fig.set_figwidth(8)
78 plt.show()
79
80
81 class Test():
82 def __init__(self, _id, _data1, _data2):
83 self.id = _id
84 self.data1 = _data1
85 self.data2 = _data2
86
87 res = {
88 1:Test(1, "12345", "54321"),
89 2:Test(2, "11111", "aaaaa"),
90 3:Test(3, "ddddd", "qwqwqw")
91 }
92
93 for val in res.keys():
94 print(res[val].data1)
95
96 datetime_min = datetime.datetime(2020, 1, 29, 22, 50, 0)
97 timestamp = int(datetime_min.timestamp())
98 png_path = r"d:\PYTHON\tests\test1\png"
99 file_path = "{}\\dj_286m_{}.png".format(png_path, timestamp)
100 print(file_path)
101 print(os.path.exists(file_path))
102
103 zero = -1.06
104 class RiverCrossSection():
105
106 def __init__(self, _left_slope = 5.0, _bottom = 18.0, _right_slope = 5.0, _max_h = 3.6, _zero_bsv = -1.06, _n_roughness = 0.035, _i_bias = 0.00244):
107 # параметры трапеции
108 self._zero_wlevel = _zero_bsv
109 self._trap_a = _left_slope # ширина левого склона трапеции русла
110 self._trap_b = _bottom # ширина дна трапеции русла
111 self._trap_c = _right_slope # ширина правого склона трапеции русла
112 self._trap_d = _max_h # высота трапеции русла
113 if self._trap_d >= 0:
114 self._trap_leftCtg = self._trap_a / self._trap_d # котангенс левого угла трапеции русла
115 self._trap_rightCtg = self._trap_c / self._trap_d # котангенс правого угла трапеции русла
116 else:
117 self._trap_leftCtg = 0 # котангенс левого угла трапеции русла
118 self._trap_rightCtg = 0 # котангенс правого угла трапеции русла
119
120 self._i_rb_part = _i_bias # уклон русла
121 self._n_rb_part = _n_roughness # шероховатость русла
122
123 # площадь сечения (м^2)
124 def f_trap_area(self, h):
125 return self._trap_b * h + (self._trap_leftCtg + self._trap_rightCtg) * h * h / 2
126
127 # смоченный периметр (м)
128 def f_trap_perimetr(self, h):
129 return self._trap_b + \
130 math.sqrt(self._trap_leftCtg ** 2 + 1) * h + \
131 math.sqrt(self._trap_rightCtg ** 2 + 1) * h
132
133 # гидрологический радиус
134 def f_hydro_r(self, h):
135 return self.f_trap_area(h) / self.f_trap_perimetr(h)
136
137 # скорость потока (м/с)
138 def f_flow_speed(self, h):
139 return self.f_hydro_r(h)**(2./3) * math.sqrt(self._i_rb_part) / self._n_rb_part
140
141 # расход воды (м^3/с)
142 def f_flow_rate(self, h):
143 if h <= 0.:
144 return 0.
145 return self.f_trap_area(h) * self.f_flow_speed(h)
146
147 # расход воды (м^3/с)
148 def f_flow_rate_by_bs_h(self, bs_h):
149 return self.f_flow_rate(bs_h - self._zero_wlevel)
150
151 # уровень воды (м), определяемый по расходу воды (м^3/с)
152 def high_by_flow_rate(self, flow_rate):
153 if flow_rate <= 0.:
154 return 0.
155 return newton_raphson(self.f_flow_rate, flow_rate, 1.)
156
157 # уровень воды (м), определяемый по расходу воды (м^3/с) по балтийской системе высот
158 def bs_water_level(self, flow_rate):
159 return self.high_by_flow_rate(flow_rate) + self._zero_wlevel
160
161
162 real34 = loca_data.GetLevel34()
163 get_flow = RiverCrossSection()
164 min_flow = 100
165 max_flow = 0
166 for key in real34.keys():
167 real_level = real34[key]
168 #real_level = real_level - zero
169 flow = get_flow.f_flow_rate_by_bs_h(real_level)
170
171 if flow < min_flow:
172 min_flow = flow
173
174 if flow > max_flow:
175 max_flow = flow
176
177 print("{}-{}".format(real_level, flow))
178
179 print("{}-{}".format(min_flow, max_flow))
180
181
182 datetime_min = datetime.datetime(2020, 1, 29, 22, 50, 0)
183 datetime_max = datetime.datetime(2020, 2, 1, 0, 0, 0)
184
185 date_diff = datetime_max - datetime_min
186 print(date_diff.seconds / 600)
187 '''
188
189 first_dic = dict(a = "123", b = 1.9, c = 567)
190 first_dic1 = dict(a = "124", b = 2.9, c = 1567)
191 first_dic2 = dict(a = "125", b = 3.9, c = 2567)
192 first_dic3 = dict(a = "126", b = 4.9, c = 3567)
193 first_dic35 = None
194 first_dic4 = dict(a = "127", b = 5.9, c = 4567)
195 secon_dic = dict(aa = "qwe", bb = 0.0, cc = 3214)
196
197
198 def GetAllValues(_dict_with_pref):
199 key_store = []
200 value_store = []
201 for dwp_k in _dict_with_pref.keys():
202 dwp = _dict_with_pref[dwp_k]
203 if dwp is not None:
204 for k in dwp.keys():
205 key_store.append(str(dwp_k) + "_" + str(k))
206 value_store.append(str(dwp[k]))
207
208 return key_store, value_store
209
210 ks, vs = GetAllValues(dict(fd = first_dic, sd = secon_dic))
211
212 #print("\t".join(ks))
213 #print("\t".join(vs))
214
215 #timestamp = int(_datetime.timestamp())
216 #file_path = r"\png\dj_286m_{}.png".format(timestamp)
217
218 #print(os.listdir('.\\png\\'))
219
220 files = os.listdir('.\\png\\')
221
222 for f in files:
223 ts = int(f.replace("dj_286m_","").replace(".png",""))
224 dt = datetime.datetime.fromtimestamp(ts)
225 print(dt)
226
227 # 2. Ищем файл и формируем матрицу
228 #if not os.path.exists(os.path.abspath(os.curdir) + file_path):
229 # return result