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

add all files

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

Too many changes to show.

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

{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Текущий файл",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}
\ No newline at end of file
{
"python.pythonPath": "C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python38\\python.exe"
}
\ No newline at end of file
import time
import logging
import pika
import json
import time
import datetime
import pytz
from threading import Thread
from queue import Queue, Empty
from ocm_fwk.ocm_mq import OcmMqBase
import config as cfg
'''
class MyJSONEncoder(json.JSONEncoder):
#Override the default method
def default(self, obj):
if isinstance(obj, (datetime.date, datetime.datetime)):
return obj.replace(tzinfo=datetime.timezone.utc).isoformat()
if isinstance(obj, np.ndarray):
return obj.tolist()
'''
class test_cons(OcmMqBase):
def __init__(self, settings, consumer_queue=None, consumer_routing_key=None, consume_only_routing_key=True,
message_ttl_ms=None):
super(test_cons, self).__init__(settings)
self.logger = logging.getLogger(__name__)
if consumer_queue is None:
raise TypeError
if consumer_routing_key is None:
raise TypeError
self.consumer_queue = consumer_queue
self.consumer_routing_key = consumer_routing_key
self.consume_only_routing_key = consume_only_routing_key
self.message_ttl_ms = message_ttl_ms
self._loop_thread = Thread(target=self._main_loop)
self._stop_flag = False
self.mms_main_query = Queue()
def consume(self, routing_key, message_object):
self.mms_main_query.put(message_object)
print("{} -> consume bu rout {} messege :{}".format(datetime.datetime.now(), routing_key, message_object))
return True
def get_lazy_data(self):
result = []
while self.mms_main_query.qsize() != 0:
result.append(self.mms_main_query.get())
return result
def _consumer_callback(self, ch, method, properties, body):
# проверка правильности подписки на routing_key
if self.consume_only_routing_key:
if isinstance(self.consumer_routing_key, str): # если routing key - одна строка
if self.consumer_routing_key != method.routing_key:
# сообщение не может быть обработано и посылать его повторно не нужно
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=False)
self.logger.warning('MQ: routing key({}) not proper'.format(method.routing_key))
return
elif isinstance(self.consumer_routing_key, tuple): # если routing key - кортеж строк
if method.routing_key not in self.consumer_routing_key:
# сообщение не может быть обработано и посылать его повторно не нужно
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=False)
self.logger.warning('MQ: routing key({}) not proper'.format(method.routing_key))
return
else:
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=False)
self.logger.warning('MQ: routing key has not proper type')
return
# преобразование сообщения в нативный объект
try:
obj = json.loads(body.decode('utf-8'))
except Exception:
self.logger.exception("MQ: json conversion error")
# сообщение не может быть обработано и посылать его повторно не нужно
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=False)
return
# callback может вернуть
# None - простым вызовом return или по завершению кода обработчика, то же самое, что False
# True - сообщение обработано, можно посылать ack - удаляет сообщение из очереди
# False - сообщение не обработано, нужно его отправить обратно в очередь - послать nack(requeue=True)
ack = None
try:
ack = self.consume(method.routing_key, obj)
except Exception:
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=False)
self.logger.exception("MQ: message not consumed")
raise
# если callback не возвратил логический тип, значит ack - False
if ack is None:
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True)
elif ack:
ch.basic_ack(delivery_tag=method.delivery_tag)
else:
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True)
def _main_loop(self):
while not self._stop_flag:
connection = None
ch_consumer = None
try:
connection = pika.BlockingConnection(self.parameters)
ch_consumer = connection.channel()
ch_consumer.basic_qos(prefetch_count=100) # todo: вынести в настройки
# определение очереди сообщений, в случае отсутствия, будет создана
if self.message_ttl_ms is not None:
queue = ch_consumer.queue_declare(
queue=self.consumer_queue,
durable=True,
exclusive=False,
arguments={'x-message-ttl': self.message_ttl_ms, },
).method.queue
else:
queue = ch_consumer.queue_declare(
queue=self.consumer_queue,
durable=True,
exclusive=False,
).method.queue
# привязка к очереди
if isinstance(self.consumer_routing_key, str): # если routing key - одна строка
ch_consumer.queue_bind(
exchange=self.EXCHANGE,
queue=queue,
routing_key=self.consumer_routing_key,
)
elif isinstance(self.consumer_routing_key, tuple): # если routing key - кортеж строк
for key in self.consumer_routing_key:
ch_consumer.queue_bind(
exchange=self.EXCHANGE,
queue=queue,
routing_key=key
)
else:
raise TypeError
# настройка обработчика получения сообщений
ch_consumer.basic_consume(
consumer_callback=self._consumer_callback,
queue=queue,
no_ack=False,
consumer_tag="ocm_mq_consumer"
)
self.consumer_queue = queue
# блокирующий вызов ожидания входящих сообщений
try:
ch_consumer.start_consuming()
except:
ch_consumer.stop_consuming()
raise
except Exception:
self.logger.exception('mq consuming error, attempting to reconnect...')
finally:
try:
ch_consumer.close()
except:
pass
try:
connection.close()
except:
pass
time.sleep(self.RECONNECT_SLEEP_SECONDS)
try:
ch_consumer.close()
except:
pass
try:
connection.close()
except:
pass
def start(self):
""" Запуск подписчика для шины ОКМ """
self._loop_thread.start()
def stop(self):
self._stop_flag = True
bus_TS = test_cons(cfg, "makeyev_L", "measurement.precipitation.*", consume_only_routing_key=False)
bus_LO = test_cons(cfg, "makeyev_C", "metering.rainfall", consume_only_routing_key=False)
print("begin...\n")
#cons.stop()
bus_LO.start()
bus_TS.start()
i = 0
while i < 100:
i = i + 1
print("Iterator={}\t\tdata:{}".format(i, bus_LO.get_lazy_data()))
print("Iterator={}\t\tdata:{}".format(i, bus_TS.get_lazy_data()))
time.sleep(30)
'''
АГК-34Д uuid = "0efefaee-eada-446f-a2a0-f95acabfc0a7" Л
АГК-77Д uuid = "c3f0ecb7-c65e-4273-93a9-6f39a65dcd4a" Л
АГК-141 uuid = "83b895ae-3a21-4585-8289-e28da5d0cc43" C
АГК-040 uuid = "a6f44e50-ad18-4ee9-a6bb-ffae6a85d2a3" С
АГК-286 uuid = "33ce9a80-27df-41dd-8dbe-cf3ec918b4c2" С
'''
import time
import logging
import pika
import json
import datetime
import pytz
from threading import Thread
from queue import Queue, Empty
from ocm_fwk.ocm_mq import OcmMqBase, OcmMqBlockingPublisher
import config as cfg
pub = OcmMqBlockingPublisher(cfg)
pub.publish("rk_1", 123)
pub.publish("rk_1", 666)
pub.publish("rk_1", 999)
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
#user_db_name = "web_forecast_7"
user_db_name = "qwer"
db_postgres_connection = dict(host="localhost",database=user_db_name, user="postgres", password="postgres")
redis_connection = dict(host='localhost', port=6379, db=0, password=None)
OCM_MQ = dict(
HOST = 'evolution.emercit.com',
PORT = 5672,
VIRTUAL_HOST = 'ocm',
EXCHANGE = 'monitoring',
USER = 'emercit',
PASSWORD = 'xfnLAW5pff3RpNFh')
Дата АГК-286М АГК-34 РАД-286М
29.01.2020 22:50 0 -0,10 0,000000
29.01.2020 23:00 0 -0,11 0,00000000
29.01.2020 23:10 0 -0,09 0,00000000
29.01.2020 23:20 0 -0,09 0,00000000
29.01.2020 23:30 0 -0,09 0,00000000
29.01.2020 23:40 0 -0,10 0,00000000
29.01.2020 23:50 0 -0,10 0,00000000
30.01.2020 0:00 0 -0,09 0,00000000
30.01.2020 0:10 0 -0,10 0,00000000
30.01.2020 0:20 0 -0,09 0,00000000
30.01.2020 0:30 0 -0,09 0,00000000
30.01.2020 0:40 0 -0,09 0,00000000
30.01.2020 0:50 0 -0,08 0,00000000
30.01.2020 1:00 0 -0,08 0,00000000
30.01.2020 1:10 0 -0,09 0,00000000
30.01.2020 1:20 0 -0,07 0,00000000
30.01.2020 1:30 0 -0,09 0,00000000
30.01.2020 1:40 0 -0,08 0,00000000
30.01.2020 1:50 0 -0,08 0,00000000
30.01.2020 2:00 0 -0,08 0,00000000
30.01.2020 2:10 0 -0,09 0,00000000
30.01.2020 2:20 0 -0,08 0,00000000
30.01.2020 2:30 0 -0,08 0,00000000
30.01.2020 2:40 0 -0,08 0,00000000
30.01.2020 2:50 0 -0,08 0,00000000
30.01.2020 3:00 0 -0,09 0,03417472
30.01.2020 3:10 0 -0,09 0,03417472
30.01.2020 3:20 0 -0,09 0,02959409
30.01.2020 3:30 0 -0,10 0,07017865
30.01.2020 3:40 0,3 -0,10 0,16641980
30.01.2020 3:50 0,1 -0,09 0,16641980
30.01.2020 4:00 0,5 -0,11 0,09358473
30.01.2020 4:10 0,5 -0,11 0,16641980
30.01.2020 4:20 0,8 -0,11 0,34174723
30.01.2020 4:30 0,2 -0,11 0,16641980
30.01.2020 4:40 0,7 -0,09 0,09358473
30.01.2020 4:50 0,3 -0,09 0,09358473
30.01.2020 5:00 0,1 -0,09 0,09358473
30.01.2020 5:10 0,1 -0,09 0,16641980
30.01.2020 5:20 0,1 -0,09 0,07017865
30.01.2020 5:30 0,1 -0,09 0,16641980
30.01.2020 5:40 0,1 -0,10 0,16641980
30.01.2020 5:50 0 -0,10 0,14411361
30.01.2020 6:00 0 -0,10 0,03417472
30.01.2020 6:10 0 -0,11 0,07017865
30.01.2020 6:20 0 -0,11 0,07017865
30.01.2020 6:30 0 -0,11 0,09358473
30.01.2020 6:40 0 -0,12 0,02959409
30.01.2020 6:50 0 -0,12 0,03417472
30.01.2020 7:00 0,1 -0,12 0,02959409
30.01.2020 7:10 0,2 -0,13 0,16641980
30.01.2020 7:20 0,2 -0,13 0,16641980
30.01.2020 7:30 0,1 -0,13 0,16641980
30.01.2020 7:40 0,1 -0,13 0,16641980
30.01.2020 7:50 0,3 -0,13 0,16641980
30.01.2020 8:00 0,2 -0,13 0,16641980
30.01.2020 8:10 0,1 -0,13 0,39464354
30.01.2020 8:20 0,1 -0,13 0,16641980
30.01.2020 8:30 0 -0,13 0,16641980
30.01.2020 8:40 0 -0,13 0,16641980
30.01.2020 8:50 0,1 -0,13 0,16641980
30.01.2020 9:00 0 -0,13 0,16641980
30.01.2020 9:10 0 -0,13 0,09358473
30.01.2020 9:20 0 -0,12 0,09358473
30.01.2020 9:30 0 -0,11 0,03946435
30.01.2020 9:40 0 -0,11 0,03417472
30.01.2020 9:50 0 -0,09 0,00000000
30.01.2020 10:00 0 -0,08 0,00000000
30.01.2020 10:10 0 -0,07 0,00000000
30.01.2020 10:20 0 -0,05 0,00000000
30.01.2020 10:30 0 -0,04 0,00000000
30.01.2020 10:40 0 -0,03 0,00000000
30.01.2020 10:50 0 -0,02 0,00000000
30.01.2020 11:00 0 -0,02 0,00000000
30.01.2020 11:10 0 -0,01 0,00000000
30.01.2020 11:20 0 -0,01 0,00000000
30.01.2020 11:30 0 0,00 0,00000000
30.01.2020 11:40 0 0,01 0,00000000
30.01.2020 11:50 0 0,01 0,02562743
30.01.2020 12:00 0 0,01 0,00000000
30.01.2020 12:10 0 0,01 0,04557273
30.01.2020 12:20 0 0,01 0,02562743
30.01.2020 12:30 0 0,02 0,04557273
30.01.2020 12:40 0 0,02 0,02562743
30.01.2020 12:50 0 0,02 0,03417472
30.01.2020 13:00 0 0,03 0,02562743
30.01.2020 13:10 0 0,03 0,03417472
30.01.2020 13:20 0 0,03 0,03417472
30.01.2020 13:30 0 0,04 0,03417472
30.01.2020 13:40 2,3 0,03 0,03417472
30.01.2020 13:50 2 0,03 0,04557273
30.01.2020 14:00 4,1 0,03 0,04557273
30.01.2020 14:10 1,6 0,03 0,16641980
30.01.2020 14:20 0,5 0,03 0,34174723
30.01.2020 14:30 0,4 0,03 0,14411361
30.01.2020 14:40 3,5 0,03 0,22192437
30.01.2020 14:50 1,2 0,03 0,70178649
30.01.2020 15:00 0,2 0,03 0,34174723
30.01.2020 15:10 0,8 0,03 0,14411361
30.01.2020 15:20 0,9 0,04 0,70178649
30.01.2020 15:30 0,2 0,05 0,39464354
30.01.2020 15:40 0,4 0,05 0,39464354
30.01.2020 15:50 0,3 0,06 0,19217859
30.01.2020 16:00 0,3 0,06 0,70178649
30.01.2020 16:10 0,4 0,07 0,16641980
30.01.2020 16:20 0,3 0,09 0,14411361
30.01.2020 16:30 0,7 0,15 0,16641980
30.01.2020 16:40 0,5 0,25 0,16641980
30.01.2020 16:50 0,7 0,37 0,09358473
30.01.2020 17:00 0,5 0,50 0,08104104
30.01.2020 17:10 0,3 0,60 0,09358473
30.01.2020 17:20 0,3 0,68 0,09358473
30.01.2020 17:30 0,5 0,74 0,09358473
30.01.2020 17:40 0,5 0,76 0,09358473
30.01.2020 17:50 0,4 0,78 0,16641980
30.01.2020 18:00 0,5 0,79 0,16641980
30.01.2020 18:10 0,5 0,81 0,16641980
30.01.2020 18:20 0,3 0,82 0,16641980
30.01.2020 18:30 0,2 0,82 0,09358473
30.01.2020 18:40 0,2 0,82 0,09358473
30.01.2020 18:50 0,2 0,82 0,09358473
30.01.2020 19:00 0,4 0,83 0,16641980
30.01.2020 19:10 0,2 0,84 0,00000000
30.01.2020 19:20 0,1 0,84 0,00000000
30.01.2020 19:30 0,1 0,85 0,00000000
30.01.2020 19:40 0,1 0,86 0,00000000
30.01.2020 19:50 0,1 0,88 0,00000000
30.01.2020 20:00 0,1 0,89 0,00000000
30.01.2020 20:10 0 0,89 0,00000000
30.01.2020 20:20 0 0,91 0,00000000
30.01.2020 20:30 0 0,92 0,00000000
30.01.2020 20:40 0 0,93 0,00000000
30.01.2020 20:50 0 0,94 0,00000000
30.01.2020 21:00 0 0,93 0,00000000
30.01.2020 21:10 0 0,93 0,00000000
30.01.2020 21:20 0 0,93 0,00000000
30.01.2020 21:30 0 0,94 0,00000000
30.01.2020 21:40 0 0,94 0,00000000
30.01.2020 21:50 0 0,94 0,00000000
30.01.2020 22:00 0 0,94 0,00000000
30.01.2020 22:10 0 0,94 0,00000000
30.01.2020 22:20 0 0,94 0,00000000
30.01.2020 22:30 0 0,92 0,00000000
30.01.2020 22:40 0 0,92 0,00000000
30.01.2020 22:50 0 0,90 0,00000000
30.01.2020 23:00 0 0,89 0,00000000
30.01.2020 23:10 0 0,86 0,00000000
30.01.2020 23:20 0 0,84 0,00000000
30.01.2020 23:30 0 0,82 0,00000000
30.01.2020 23:40 0 0,80 0,00000000
30.01.2020 23:50 0 0,78 0,00000000
31.01.2020 0:00 0 0,76 0,00000000
31.01.2020 0:10 0 0,74 0,00000000
31.01.2020 0:20 0 0,72 0,00000000
31.01.2020 0:30 0 0,70 0,00000000
31.01.2020 0:40 0 0,69 0,00000000
31.01.2020 0:50 0 0,68 0,00000000
31.01.2020 1:00 0 0,66 0,00000000
31.01.2020 1:10 0 0,65 0,00000000
31.01.2020 1:20 0 0,64 0,00000000
31.01.2020 1:30 0 0,63 0,00000000
31.01.2020 1:40 0 0,62 0,00000000
31.01.2020 1:50 0 0,61 0,00000000
31.01.2020 2:00 0 0,60 0,00000000
31.01.2020 2:10 0,1 0,58 0,00000000
31.01.2020 2:20 0 0,57 0,00000000
31.01.2020 2:30 0,1 0,56 0,00000000
31.01.2020 2:40 0 0,55 0,00000000
31.01.2020 2:50 0 0,54 0,00000000
31.01.2020 3:00 0 0,53 0,00000000
31.01.2020 3:10 0 0,51 0,00000000
31.01.2020 3:20 0 0,51 0,00000000
31.01.2020 3:30 0 0,49 0,00000000
31.01.2020 3:40 0 0,47 0,00000000
31.01.2020 3:50 0 0,46 0,00000000
31.01.2020 4:00 0 0,45 0,00000000
31.01.2020 4:10 0 0,44 0,00000000
31.01.2020 4:20 0 0,43 0,00000000
31.01.2020 4:30 0 0,42 0,00000000
31.01.2020 4:40 0 0,41 0,00000000
31.01.2020 4:50 0 0,39 0,00000000
31.01.2020 5:00 0 0,39 0,00000000
31.01.2020 5:10 0 0,37 0,00000000
31.01.2020 5:20 0 0,36 0,00000000
31.01.2020 5:30 0 0,35 0,00000000
31.01.2020 5:40 0 0,35 0,00000000
31.01.2020 5:50 0 0,33 0,00000000
31.01.2020 6:00 0 0,32 0,00000000
31.01.2020 6:10 0 0,32 0,00000000
31.01.2020 6:20 0 0,31 0,00000000
31.01.2020 6:30 0 0,30 0,00000000
31.01.2020 6:40 0 0,29 0,00000000
31.01.2020 6:50 0 0,28 0,00000000
31.01.2020 7:00 0 0,27 0,00000000
31.01.2020 7:10 0 0,27 0,00000000
31.01.2020 7:20 0 0,26 0,00000000
31.01.2020 7:30 0 0,25 0,00000000
31.01.2020 7:40 0 0,25 0,00000000
31.01.2020 7:50 0 0,24 0,00000000
31.01.2020 8:00 0 0,23 0,00000000
31.01.2020 8:10 0 0,22 0,00000000
31.01.2020 8:20 0 0,22 0,00000000
31.01.2020 8:30 0 0,21 0,00000000
31.01.2020 8:40 0 0,20 0,00000000
31.01.2020 8:50 0 0,19 0,00000000
31.01.2020 9:00 0 0,19 0,00000000
31.01.2020 9:10 0 0,18 0,09358473
31.01.2020 9:20 0 0,18 0,09358473
31.01.2020 9:30 0 0,17 0,09358473
31.01.2020 9:40 0 0,17 0,04557273
31.01.2020 9:50 0 0,16 0,03417472
31.01.2020 10:00 0 0,15 0,09358473
31.01.2020 10:10 0 0,15 0,04557273
31.01.2020 10:20 0 0,14 0,03417472
31.01.2020 10:30 0 0,13 0,03417472
31.01.2020 10:40 0 0,13 0,03417472
31.01.2020 10:50 0 0,13 0,03417472
31.01.2020 11:00 0 0,12 0,00000000
31.01.2020 11:10 0 0,12 0,03417472
31.01.2020 11:20 0 0,11 0,03417472
31.01.2020 11:30 0 0,10 0,03417472
31.01.2020 11:40 0 0,10 0,03417472
31.01.2020 11:50 0 0,09 0,03417472
31.01.2020 12:00 0 0,09 0,03417472
31.01.2020 12:10 0 0,09 0,03417472
31.01.2020 12:20 0 0,08 0,03417472
31.01.2020 12:30 0 0,08 0,03417472
31.01.2020 12:40 0 0,08 0,03417472
31.01.2020 12:50 0 0,07 0,03417472
31.01.2020 13:00 0 0,07 0,00000000
31.01.2020 13:10 0 0,06 0,03417472
31.01.2020 13:20 0 0,06 0,03417472
31.01.2020 13:30 0 0,06 0,03417472
31.01.2020 13:40 0 0,05 0,03417472
31.01.2020 13:50 0 0,05 0,03417472
31.01.2020 14:00 0 0,04 0,03417472
31.01.2020 14:10 0 0,04 0,03417472
31.01.2020 14:20 0 0,04 0,03417472
31.01.2020 14:30 0 0,03 0,03417472
31.01.2020 14:40 0 0,03 0,03417472
31.01.2020 14:50 0 0,03 0,03417472
31.01.2020 15:00 0 0,02 0,03417472
31.01.2020 15:10 0 0,02 0,02562743
31.01.2020 15:20 0 0,02 0,02562743
31.01.2020 15:30 0 0,01 0,02562743
31.01.2020 15:40 0 0,01 0,02562743
31.01.2020 15:50 0 0,01 0,02562743
31.01.2020 16:00 0 0,01 0,02562743
31.01.2020 16:10 0 0,00 0,02562743
31.01.2020 16:20 0 -0,01 0,02562743
31.01.2020 16:30 0 -0,01 0,03417472
31.01.2020 16:40 0 -0,01 0,02562743
31.01.2020 16:50 0 -0,01 0,00000000
31.01.2020 17:00 0 -0,01 0,00000000
31.01.2020 17:10 0 -0,02 0,00000000
31.01.2020 17:20 0 -0,02 0,00000000
31.01.2020 17:30 0 -0,02 0,00000000
31.01.2020 17:40 0 -0,02 0,00000000
31.01.2020 17:50 0 -0,03 0,00000000
31.01.2020 18:00 0 -0,03 0,00000000
31.01.2020 18:10 0 -0,03 0,00000000
31.01.2020 18:20 0 -0,04 0,00000000
31.01.2020 18:30 0 -0,03 0,00000000
31.01.2020 18:40 0 -0,04 0,00000000
31.01.2020 18:50 0 -0,05 0,00000000
31.01.2020 19:00 0 -0,05 0,00000000
31.01.2020 19:10 0 -0,05 0,00000000
31.01.2020 19:20 0 -0,05 0,00000000
31.01.2020 19:30 0 -0,06 0,00000000
31.01.2020 19:40 0 -0,06 0,00000000
31.01.2020 19:50 0 -0,06 0,00000000
31.01.2020 20:00 0 -0,07 0,00000000
31.01.2020 20:10 0 -0,07 0,00000000
31.01.2020 20:20 0 -0,07 0,00000000
31.01.2020 20:30 0 -0,08 0,00000000
31.01.2020 20:40 0 -0,09 0,00000000
31.01.2020 20:50 0 -0,10 0,00000000
31.01.2020 21:00 0 -0,10 0,00000000
31.01.2020 21:10 0 -0,10 0,00000000
31.01.2020 21:20 0 -0,10 0,00000000
31.01.2020 21:30 0 -0,10 0,00000000
31.01.2020 21:40 0 -0,10 0,00000000
31.01.2020 21:50 0 -0,11 0,00000000
31.01.2020 22:00 0 -0,11 0,00000000
31.01.2020 22:10 0 -0,11 0,00000000
31.01.2020 22:20 0 -0,12 0,00000000
31.01.2020 22:30 0 -0,11 0,00000000
31.01.2020 22:40 0 -0,13 0,00000000
31.01.2020 22:50 0 -0,12 0,00000000
31.01.2020 23:00 0 -0,12 0,00000000
31.01.2020 23:10 0 -0,12 0,00000000
31.01.2020 23:20 0 -0,13 0,00000000
31.01.2020 23:30 0 -0,13 0,00000000
31.01.2020 23:40 0 -0,13 0,00000000
31.01.2020 23:50 0 -0,13 0,00000000
01.02.2020 0:00 0 -0,13 0,00000000
01.02.2020 0:10 0 -0,13 0,00000000
01.02.2020 0:20 0 -0,13 0,00000000
01.02.2020 0:30 0 -0,13 0,00000000
01.02.2020 0:40 0 -0,14 0,00000000
01.02.2020 0:50 0 -0,14 0,00000000
01.02.2020 1:00 0 -0,14 0,00000000
01.02.2020 1:10 0 -0,14 0,00000000
01.02.2020 1:20 0 -0,14 0,00000000
01.02.2020 1:30 0 -0,14 0,00000000
01.02.2020 1:40 0 -0,14 0,00000000
01.02.2020 1:50 0 -0,15 0,00000000
01.02.2020 2:00 0 -0,15 0,00000000
01.02.2020 2:10 0 -0,15 0,00000000
01.02.2020 2:20 0 -0,15 0,03417472
01.02.2020 2:30 0 -0,15 0,00000000
01.02.2020 2:40 0 -0,16 0,04557273
01.02.2020 2:50 0 -0,16 0,00000000
01.02.2020 3:00 0 -0,16 0,00000000
01.02.2020 3:10 0 -0,17 0,00000000
01.02.2020 3:20 0 -0,17 0,00000000
01.02.2020 3:30 0 -0,16 0,00000000
01.02.2020 3:40 0 -0,16 0,00000000
01.02.2020 3:50 0 -0,16 0,00000000
01.02.2020 4:00 0 -0,17 0,00000000
01.02.2020 4:10 0 -0,17 0,00000000
01.02.2020 4:20 0 -0,17 0,00000000
01.02.2020 4:30 0 -0,17 0,00000000
01.02.2020 4:40 0 -0,18 0,00000000
01.02.2020 4:50 0 -0,17 0,03946435
01.02.2020 5:00 0 -0,17 0,03946435
01.02.2020 5:10 0 -0,18 0,00000000
01.02.2020 5:20 0 -0,18 0,00000000
01.02.2020 5:30 0 -0,17 0,00000000
01.02.2020 5:40 0 -0,17 0,00000000
01.02.2020 5:50 0 -0,18 0,00000000
01.02.2020 6:00 0 -0,18 0,00000000
01.02.2020 6:10 0 -0,18 0,00000000
01.02.2020 6:20 0 -0,18 0,00000000
01.02.2020 6:30 0 -0,18 0,00000000
01.02.2020 6:40 0 -0,18 0,00000000
01.02.2020 6:50 0 -0,18 0,00000000
01.02.2020 7:00 0 -0,19 0,00000000
01.02.2020 7:10 0 -0,18 0,00000000
01.02.2020 7:20 0 -0,18 0,00000000
01.02.2020 7:30 0 -0,19 0,00000000
01.02.2020 7:40 0 -0,18 0,00000000
01.02.2020 7:50 0 -0,18 0,00000000
01.02.2020 8:00 0 -0,18 0,00000000
01.02.2020 8:10 0 -0,18 0,00000000
01.02.2020 8:20 0 -0,17 0,00000000
01.02.2020 8:30 0 -0,18 0,00000000
01.02.2020 8:40 0 -0,17 0,00000000
01.02.2020 8:50 0 -0,18 0,00000000
01.02.2020 9:00 0 -0,17 0,00000000
01.02.2020 9:10 0 -0,18 0,00000000
01.02.2020 9:20 0 -0,17 0,00000000
01.02.2020 9:30 0 -0,15 0,03417472
01.02.2020 9:40 0 -0,16 0,04557273
01.02.2020 9:50 0 -0,17 0,02959409
01.02.2020 10:00 0 -0,17 0,03417472
01.02.2020 10:10 0 -0,17 0,09358473
01.02.2020 10:20 0 -0,18 0,04557273
01.02.2020 10:30 0 -0,16 0,04557273
01.02.2020 10:40 0 -0,17 0,02959409
01.02.2020 10:50 0 -0,16 0,16641980
01.02.2020 11:00 0 -0,16 0,39464354
01.02.2020 11:10 0 -0,17 0,04557273
01.02.2020 11:20 0 -0,18 0,03417472
01.02.2020 11:30 0 -0,17 0,04557273
01.02.2020 11:40 0 -0,18 0,00000000
01.02.2020 11:50 0 -0,18 0,00000000
01.02.2020 12:00 0 -0,17 0,00000000
01.02.2020 12:10 0 -0,18 0,00000000
01.02.2020 12:20 0 -0,18 0,00000000
01.02.2020 12:30 0 -0,18 0,00000000
01.02.2020 12:40 0 -0,18 0,00000000
01.02.2020 12:50 0 -0,18 0,03417472
01.02.2020 13:00 0 -0,19 0,00000000
01.02.2020 13:10 0 -0,19 0,00000000
01.02.2020 13:20 0 -0,18 0,00000000
01.02.2020 13:30 0 -0,19 0,00000000
01.02.2020 13:40 0 -0,18 0,00000000
01.02.2020 13:50 0 -0,18 0,00000000
01.02.2020 14:00 0 -0,18 0,00000000
01.02.2020 14:10 0 -0,17 0,00000000
01.02.2020 14:20 0 -0,17 0,00000000
01.02.2020 14:30 0 -0,17 0,00000000
01.02.2020 14:40 0 -0,17 0,00000000
01.02.2020 14:50 0 -0,18 0,00000000
01.02.2020 15:00 0 -0,18 0,00000000
01.02.2020 15:10 0 -0,17 0,04557273
01.02.2020 15:20 0 -0,17 0,00000000
01.02.2020 15:30 0 -0,16 0,00000000
01.02.2020 15:40 0 -0,16 0,00000000
01.02.2020 15:50 0 -0,17 0,00000000
01.02.2020 16:00 0 -0,16 0,00000000
01.02.2020 16:10 0 -0,16 0,00000000
01.02.2020 16:20 0 -0,16 0,00000000
01.02.2020 16:30 0 -0,15 0,00000000
01.02.2020 16:40 0 -0,15 0,00000000
01.02.2020 16:50 0 -0,15 0,00000000
01.02.2020 17:00 0 -0,15 0,04557273
01.02.2020 17:10 0 -0,14 0,07017865
01.02.2020 17:20 0 -0,14 0,04557273
01.02.2020 17:30 0 -0,14 0,08104104
01.02.2020 17:40 0 -0,12 0,09358473
01.02.2020 17:50 0 -0,13 0,09358473
01.02.2020 18:00 0 -0,13 0,03417472
01.02.2020 18:10 0 -0,14 0,04557273
01.02.2020 18:20 0 -0,14 0,16641980
01.02.2020 18:30 0 -0,13 0,04557273
01.02.2020 18:40 0 -0,14 0,03417472
01.02.2020 18:50 0 -0,14 0,09358473
01.02.2020 19:00 0,1 -0,13 0,09358473
01.02.2020 19:10 0,1 -0,14 0,09358473
01.02.2020 19:20 0,2 -0,12 0,09358473
01.02.2020 19:30 0 -0,11 0,09358473
01.02.2020 19:40 0,1 -0,13 0,00000000
01.02.2020 19:50 0,2 -0,11 0,00000000
01.02.2020 20:00 0,1 -0,11 0,00000000
01.02.2020 20:10 0,3 -0,13 0,09358473
01.02.2020 20:20 0,4 -0,12 0,16641980
01.02.2020 20:30 0,4 -0,12 0,09358473
01.02.2020 20:40 0,4 -0,13 0,16641980
01.02.2020 20:50 0,3 -0,10 0,09358473
01.02.2020 21:00 0,8 -0,13 0,16641980
01.02.2020 21:10 0,8 -0,13 0,16641980
01.02.2020 21:20 0,6 -0,13 0,16641980
01.02.2020 21:30 0,7 -0,10 0,16641980
01.02.2020 21:40 0,5 -0,11 0,16641980
01.02.2020 21:50 0,2 -0,11 0,16641980
01.02.2020 22:00 0 -0,11 0,09358473
01.02.2020 22:10 0,1 -0,14 0,09358473
01.02.2020 22:20 0,1 -0,13 0,09358473
01.02.2020 22:30 0,1 -0,13 0,16641980
01.02.2020 22:40 0,3 -0,10 0,00000000
01.02.2020 22:50 0,2 -0,11 0,16641980
01.02.2020 23:00 0,5 -0,09 0,16641980
01.02.2020 23:10 0,6 -0,10 0,16641980
01.02.2020 23:20 0,2 -0,11 0,14411361
01.02.2020 23:30 0,1 -0,11 0,16641980
01.02.2020 23:40 0,1 -0,12 0,16641980
01.02.2020 23:50 0,1 -0,09 0,39464354
02.02.2020 0:00 0,2 -0,10 0,19217859
02.02.2020 0:10 0,4 -0,11 0,39464354
02.02.2020 0:20 0,7 -0,09 0,16641980
02.02.2020 0:30 0,5 -0,10 0,16641980
02.02.2020 0:40 0 -0,10 0,16641980
02.02.2020 0:50 0,6 -0,10 0,09358473
02.02.2020 1:00 0,2 -0,09 0,09358473
02.02.2020 1:10 0,3 -0,09 0,16641980
02.02.2020 1:20 0,2 -0,08 0,16641980
02.02.2020 1:30 0,1 -0,04 0,09358473
02.02.2020 1:40 0,2 0,03 0,16641980
02.02.2020 1:50 0,2 0,09 0,16641980
02.02.2020 2:00 0,2 0,14 0,09358473
02.02.2020 2:10 0,1 0,17 0,16641980
02.02.2020 2:20 0,2 0,21 0,16641980
02.02.2020 2:30 0 0,25 0,16641980
02.02.2020 2:40 0,1 0,32 0,08104104
02.02.2020 2:50 0,1 0,39 0,08104104
02.02.2020 3:00 0,2 0,48 0,16641980
02.02.2020 3:10 0 0,55 0,09358473
02.02.2020 3:20 0 0,62 0,16641980
02.02.2020 3:30 0 0,68 0,09358473
02.02.2020 3:40 0 0,71 0,16641980
02.02.2020 3:50 0 0,74 0,16641980
02.02.2020 4:00 0 0,77 0,03417472
02.02.2020 4:10 0 0,77 0,14411361
02.02.2020 4:20 0 0,79 0,02959409
02.02.2020 4:30 0 0,79 0,03417472
02.02.2020 4:40 0 0,78 0,08104104
02.02.2020 4:50 0 0,78 0,09358473
02.02.2020 5:00 0 0,77 0,04557273
02.02.2020 5:10 0 0,76 0,04557273
02.02.2020 5:20 0 0,76 0,19217859
02.02.2020 5:30 0 0,76 0,19217859
02.02.2020 5:40 0 0,75 0,02959409
02.02.2020 5:50 0 0,75 0,02959409
02.02.2020 6:00 0 0,73 0,04557273
02.02.2020 6:10 0 0,72 0,03417472
02.02.2020 6:20 0 0,70 0,03417472
02.02.2020 6:30 0 0,68 0,02959409
02.02.2020 6:40 0 0,66 0,08104104
02.02.2020 6:50 0 0,64 0,02959409
02.02.2020 7:00 0 0,61 0,04557273
02.02.2020 7:10 0 0,59 0,00000000
02.02.2020 7:20 0 0,57 0,08104104
02.02.2020 7:30 0 0,55 0,16641980
02.02.2020 7:40 0 0,54 0,16641980
02.02.2020 7:50 0 0,52 0,03946435
02.02.2020 8:00 0 0,51 0,09358473
02.02.2020 8:10 0 0,50 0,02959409
02.02.2020 8:20 0 0,49 0,07017865
02.02.2020 8:30 0 0,48 0,16641980
02.02.2020 8:40 0 0,47 0,09358473
02.02.2020 8:50 0 0,45 0,09358473
02.02.2020 9:00 0 0,44 0,00000000
02.02.2020 9:10 0 0,43 0,00000000
02.02.2020 9:20 0 0,42 0,04557273
02.02.2020 9:30 0 0,41 0,16641980
02.02.2020 9:40 0 0,41 0,39464354
02.02.2020 9:50 0 0,39 0,14411361
02.02.2020 10:00 0 0,39 0,07017865
02.02.2020 10:10 0 0,39 0,07017865
02.02.2020 10:20 0 0,38 0,04557273
02.02.2020 10:30 0 0,37 0,04557273
02.02.2020 10:40 0 0,37 0,00000000
02.02.2020 10:50 0 0,36 0,16641980
02.02.2020 11:00 0 0,36 0,05262656
02.02.2020 11:10 0 0,35 0,16641980
02.02.2020 11:20 0 0,35 0,16641980
02.02.2020 11:30 0 0,35 0,14411361
02.02.2020 11:40 0 0,34 0,16641980
02.02.2020 11:50 0 0,35 0,00000000
02.02.2020 12:00 0 0,36 0,04557273
02.02.2020 12:10 0 0,36 0,00000000
02.02.2020 12:20 0 0,37 0,00000000
02.02.2020 12:30 0 0,38 0,00000000
02.02.2020 12:40 0 0,39 0,00000000
02.02.2020 12:50 0 0,40 0,00000000
02.02.2020 13:00 0 0,40 0,03417472
02.02.2020 13:10 0 0,42 0,03417472
02.02.2020 13:20 0 0,42 0,02959409
02.02.2020 13:30 0 0,43 0,03417472
02.02.2020 13:40 0 0,44 0,03417472
02.02.2020 13:50 0 0,44 0,16641980
02.02.2020 14:00 0 0,43 0,39464354
02.02.2020 14:10 0 0,43 0,39464354
02.02.2020 14:20 0 0,43 0,39464354
02.02.2020 14:30 0 0,42 0,39464354
02.02.2020 14:40 0 0,42 0,19217859
02.02.2020 14:50 0 0,42 0,19217859
02.02.2020 15:00 0 0,42 0,16641980
02.02.2020 15:10 0 0,41 0,16641980
02.02.2020 15:20 0 0,39 0,16641980
02.02.2020 15:30 0 0,39 0,39464354
02.02.2020 15:40 0 0,39 0,16641980
02.02.2020 15:50 0 0,38 0,16641980
02.02.2020 16:00 0 0,37 0,16641980
02.02.2020 16:10 0 0,37 0,08104104
02.02.2020 16:20 0 0,37 0,09358473
02.02.2020 16:30 0 0,37 0,16641980
02.02.2020 16:40 0 0,36 0,04557273
02.02.2020 16:50 0 0,36 0,04557273
02.02.2020 17:00 0 0,37 0,00000000
02.02.2020 17:10 0 0,38 0,03417472
02.02.2020 17:20 0 0,38 0,00000000
02.02.2020 17:30 0 0,39 0,00000000
02.02.2020 17:40 0 0,40 0,00000000
02.02.2020 17:50 0 0,41 0,00000000
02.02.2020 18:00 0 0,43 0,00000000
02.02.2020 18:10 0 0,44 0,00000000
02.02.2020 18:20 0 0,45 0,03417472
02.02.2020 18:30 0 0,46 0,08104104
02.02.2020 18:40 0 0,49 0,16641980
02.02.2020 18:50 0 0,49 0,04557273
02.02.2020 19:00 0 0,49 0,04557273
02.02.2020 19:10 0 0,49 0,04557273
02.02.2020 19:20 0 0,49 0,03417472
02.02.2020 19:30 0 0,48 0,03417472
02.02.2020 19:40 0 0,47 0,09358473
02.02.2020 19:50 0 0,46 0,03417472
02.02.2020 20:00 0 0,45 0,03417472
02.02.2020 20:10 0 0,44 0,04557273
02.02.2020 20:20 0 0,43 0,03417472
02.02.2020 20:30 0 0,41 0,03417472
02.02.2020 20:40 0 0,41 0,04557273
02.02.2020 20:50 0 0,39 0,05262656
02.02.2020 21:00 0 0,38 0,02959409
02.02.2020 21:10 0 0,38 0,03417472
02.02.2020 21:20 0 0,36 0,04557273
02.02.2020 21:30 0 0,34 0,04557273
02.02.2020 21:40 0 0,35 0,04557273
02.02.2020 21:50 0 0,33 0,04557273
02.02.2020 22:00 0 0,32 0,03417472
02.02.2020 22:10 0 0,31 0,03946435
02.02.2020 22:20 0 0,31 0,03417472
02.02.2020 22:30 0 0,30 0,02959409
02.02.2020 22:40 0 0,29 0,00000000
02.02.2020 22:50 0 0,28 0,03417472
02.02.2020 23:00 0 0,28 0,04557273
02.02.2020 23:10 0 0,28 0,03417472
02.02.2020 23:20 0 0,27 0,04557273
02.02.2020 23:30 0 0,28 0,03417472
02.02.2020 23:40 0 0,26 0,03417472
02.02.2020 23:50 0 0,25 0,03417472
03.02.2020 0:00 0 0,25 0,03417472
03.02.2020 0:10 0 0,25 0,03417472
03.02.2020 0:20 0 0,26 0,03417472
03.02.2020 0:30 0 0,24 0,03417472
03.02.2020 0:40 0 0,24 0,03417472
03.02.2020 0:50 0 0,22 0,03417472
03.02.2020 1:00 0 0,22 0,03417472
03.02.2020 1:10 0 0,23 0,03417472
03.02.2020 1:20 0 0,20 0,03417472
03.02.2020 1:30 0 0,22 0,03417472
03.02.2020 1:40 0 0,22 0,03417472
03.02.2020 1:50 0 0,23 0,00000000
03.02.2020 2:00 0 0,20 0,00000000
03.02.2020 2:10 0 0,21 0,03417472
03.02.2020 2:20 0 0,19 0,03417472
03.02.2020 2:30 0 0,20 0,04557273
03.02.2020 2:40 0 0,18 0,09358473
03.02.2020 2:50 0 0,18 0,16641980
03.02.2020 3:00 0 0,18 0,08104104
03.02.2020 3:10 0 0,18 0,70178649
03.02.2020 3:20 0 0,18 0,09358473
03.02.2020 3:30 0 0,17 0,16641980
03.02.2020 3:40 0 0,17 0,16641980
03.02.2020 3:50 0 0,17 0,16641980
03.02.2020 4:00 0 0,17 0,09358473
03.02.2020 4:10 0 0,18 0,03417472
03.02.2020 4:20 0 0,18 0,03417472
03.02.2020 4:30 0 0,18 0,02959409
03.02.2020 4:40 0 0,18 0,09358473
03.02.2020 4:50 0 0,16 0,39464354
03.02.2020 5:00 0 0,17 0,09358473
03.02.2020 5:10 0 0,16 0,39464354
03.02.2020 5:20 0 0,17 0,70178649
03.02.2020 5:30 0 0,16 0,39464354
03.02.2020 5:40 0 0,16 0,16641980
03.02.2020 5:50 0 0,16 0,16641980
03.02.2020 6:00 0 0,17 0,39464354
03.02.2020 6:10 0 0,18 0,14411361
03.02.2020 6:20 0 0,18 0,16641980
03.02.2020 6:30 0 0,18 0,22192437
03.02.2020 6:40 0 0,19 0,22192437
03.02.2020 6:50 0 0,20 0,39464354
03.02.2020 7:00 0 0,22 0,19217859
03.02.2020 7:10 0 0,25 0,29594091
03.02.2020 7:20 0 0,30 0,08104104
03.02.2020 7:30 0 0,47 0,09358473
03.02.2020 7:40 0 0,87 0,04557273
03.02.2020 7:50 0 1,20 0,00000000
03.02.2020 8:00 0 1,46 0,00000000
03.02.2020 8:10 0 1,61 0,00000000
03.02.2020 8:20 0 1,71 0,00000000
03.02.2020 8:30 0 1,78 0,00000000
03.02.2020 8:40 0 1,69 0,00000000
03.02.2020 8:50 0 1,67 0,00000000
03.02.2020 9:00 0 1,56 0,00000000
03.02.2020 9:10 0 1,51 0,00000000
03.02.2020 9:20 0 1,39 0,00000000
03.02.2020 9:30 0 1,32 0,00000000
03.02.2020 9:40 0 1,23 0,00000000
03.02.2020 9:50 0 1,15 0,00000000
03.02.2020 10:00 0 1,09 0,00000000
03.02.2020 10:10 0 1,03 0,00000000
03.02.2020 10:20 0 0,97 0,00000000
03.02.2020 10:30 0 0,93 0,03417472
03.02.2020 10:40 0 0,88 0,04557273
03.02.2020 10:50 0 0,84 0,02562743
03.02.2020 11:00 0 0,79 0,00000000
03.02.2020 11:10 0 0,76 0,00000000
03.02.2020 11:20 0 0,72 0,00000000
03.02.2020 11:30 0 0,69 0,03417472
03.02.2020 11:40 0 0,66 0,14411361
03.02.2020 11:50 0 0,64 0,02562743
03.02.2020 12:00 0 0,61 0,09358473
03.02.2020 12:10 0 0,59 0,04557273
03.02.2020 12:20 0 0,57 0,03417472
03.02.2020 12:30 0 0,55 0,04557273
03.02.2020 12:40 0 0,52 0,03417472
03.02.2020 12:50 0 0,51 0,02562743
03.02.2020 13:00 0 0,49 0,02562743
03.02.2020 13:10 0 0,48 0,04557273
03.02.2020 13:20 0 0,46 0,03417472
03.02.2020 13:30 0 0,44 0,03417472
03.02.2020 13:40 0 0,42 0,03417472
03.02.2020 13:50 0 0,42 0,04557273
03.02.2020 14:00 0 0,41 0,03946435
03.02.2020 14:10 0 0,40 0,02562743
03.02.2020 14:20 0 0,38 0,02562743
03.02.2020 14:30 0 0,36 0,02562743
03.02.2020 14:40 0 0,36 0,02562743
03.02.2020 14:50 0 0,34 0,02562743
03.02.2020 15:00 0 0,33 0,03946435
03.02.2020 15:10 0 0,32 0,03417472
03.02.2020 15:20 0 0,31 0,03417472
03.02.2020 15:30 0 0,31 0,03417472
03.02.2020 15:40 0 0,31 0,03417472
03.02.2020 15:50 0 0,29 0,03417472
03.02.2020 16:00 0 0,29 0,03417472
03.02.2020 16:10 0 0,29 0,03417472
03.02.2020 16:20 0 0,27 0,03417472
03.02.2020 16:30 0 0,27 0,03417472
03.02.2020 16:40 0 0,27 0,04557273
03.02.2020 16:50 0 0,26 0,03417472
03.02.2020 17:00 0 0,24 0,03417472
03.02.2020 17:10 0 0,24 0,03417472
03.02.2020 17:20 0,2 0,24 0,07017865
03.02.2020 17:30 0,1 0,24 0,09358473
03.02.2020 17:40 0,1 0,23 0,09358473
03.02.2020 17:50 0,2 0,23 0,16641980
03.02.2020 18:00 0,2 0,22 0,16641980
03.02.2020 18:10 0,2 0,21 0,16641980
03.02.2020 18:20 0,3 0,21 0,29594091
03.02.2020 18:30 0,8 0,20 0,34174723
03.02.2020 18:40 0,6 0,20 0,19217859
03.02.2020 18:50 0,7 0,20 0,16641980
03.02.2020 19:00 0,6 0,21 0,22192437
03.02.2020 19:10 0,6 0,21 0,34174723
03.02.2020 19:20 0,3 0,20 0,19217859
03.02.2020 19:30 1,5 0,22 0,39464354
03.02.2020 19:40 1 0,21 0,52626562
03.02.2020 19:50 1,8 0,22 0,19217859
03.02.2020 20:00 1,6 0,22 0,39464354
03.02.2020 20:10 3,4 0,22 0,39464354
03.02.2020 20:20 3 0,24 0,14411361
03.02.2020 20:30 2,2 0,26 0,29594091
03.02.2020 20:40 1,4 0,28 0,22192437
03.02.2020 20:50 2,4 0,29 0,39464354
03.02.2020 21:00 2,1 0,32 0,39464354
03.02.2020 21:10 3,4 0,37 0,70178649
03.02.2020 21:20 3,9 0,44 0,39464354
03.02.2020 21:30 4,2 0,61 0,22192437
03.02.2020 21:40 3,6 0,90 0,70178649
03.02.2020 21:50 2,3 1,27 0,22192437
03.02.2020 22:00 2,2 1,65 0,22192437
03.02.2020 22:10 3,6 2,03 0,70178649
03.02.2020 22:20 3,7 2,38 0,70178649
03.02.2020 22:30 1,4 2,85 0,70178649
03.02.2020 22:40 1,9 2,97 0,34174723
03.02.2020 22:50 1,6 3,18 0,16641980
03.02.2020 23:00 1,3 3,34 0,39464354
03.02.2020 23:10 0,8 3,45 0,39464354
03.02.2020 23:20 0 3,55 0,34174723
03.02.2020 23:30 1,5 3,60 0,19217859
03.02.2020 23:40 0,5 3,71 0,16641980
03.02.2020 23:50 0,4 3,73 0,16641980
04.02.2020 0:00 0,1 3,76 0,16641980
04.02.2020 0:10 0,1 3,78 0,09358473
04.02.2020 0:20 0,1 3,76 0,09358473
04.02.2020 0:30 0 3,70 0,09358473
04.02.2020 0:40 0 3,63 0,09358473
04.02.2020 0:50 0 3,49 0,09358473
04.02.2020 1:00 0 3,32 0,03417472
04.02.2020 1:10 0 3,15 0,03417472
04.02.2020 1:20 0 2,95 0,09358473
04.02.2020 1:30 0 2,72 0,10806996
04.02.2020 1:40 0 2,51 0,09358473
04.02.2020 1:50 0,1 2,32 0,16641980
04.02.2020 2:00 0 2,15 0,16641980
04.02.2020 2:10 0 2,01 0,16641980
04.02.2020 2:20 0 1,87 0,16641980
04.02.2020 2:30 0 1,76 0,16641980
04.02.2020 2:40 0 1,66 0,16641980
04.02.2020 2:50 0 1,58 0,39464354
04.02.2020 3:00 0,1 1,51 0,39464354
04.02.2020 3:10 0,1 1,43 0,14411361
04.02.2020 3:20 0,1 1,37 0,19217859
04.02.2020 3:30 0 1,31 0,16641980
04.02.2020 3:40 0 1,27 0,08104104
04.02.2020 3:50 0 1,23 0,03417472
04.02.2020 4:00 0 1,17 0,03417472
04.02.2020 4:10 0 1,15 0,03417472
04.02.2020 4:20 0 1,10 0,03417472
04.02.2020 4:30 0 1,07 0,03417472
04.02.2020 4:40 0 1,03 0,02562743
04.02.2020 4:50 0 1,01 0,02562743
04.02.2020 5:00 0 0,98 0,00000000
04.02.2020 5:10 0 0,95 0,02562743
04.02.2020 5:20 0 0,93 0,00000000
04.02.2020 5:30 0 0,90 0,00000000
04.02.2020 5:40 0 0,87 0,00000000
04.02.2020 5:50 0 0,84 0,00000000
04.02.2020 6:00 0 0,82 0,00000000
04.02.2020 6:10 0 0,79 0,00000000
04.02.2020 6:20 0 0,78 0,00000000
04.02.2020 6:30 0 0,75 0,00000000
04.02.2020 6:40 0 0,73 0,00000000
04.02.2020 6:50 0 0,72 0,00000000
04.02.2020 7:00 0 0,70 0,00000000
04.02.2020 7:10 0 0,68 0,00000000
04.02.2020 7:20 0 0,66 0,00000000
04.02.2020 7:30 0 0,65 0,00000000
04.02.2020 7:40 0 0,63 0,00000000
04.02.2020 7:50 0 0,62 0,00000000
04.02.2020 8:00 0 0,60 0,00000000
04.02.2020 8:10 0 0,59 0,00000000
04.02.2020 8:20 0 0,57 0,00000000
04.02.2020 8:30 0 0,55 0,00000000
04.02.2020 8:40 0 0,54 0,00000000
04.02.2020 8:50 0 0,53 0,00000000
04.02.2020 9:00 0 0,52 0,00000000
04.02.2020 9:10 0 0,50 0,00000000
04.02.2020 9:20 0 0,49 0,00000000
04.02.2020 9:30 0 0,48 0,00000000
04.02.2020 9:40 0 0,46 0,00000000
04.02.2020 9:50 0 0,46 0,00000000
04.02.2020 10:00 0 0,44 0,00000000
04.02.2020 10:10 0 0,43 0,00000000
04.02.2020 10:20 0 0,42 0,00000000
04.02.2020 10:30 0 0,41 0,00000000
04.02.2020 10:40 0 0,40 0,00000000
04.02.2020 10:50 0 0,40 0,00000000
04.02.2020 11:00 0 0,38 0,00000000
04.02.2020 11:10 0 0,37 0,00000000
04.02.2020 11:20 0 0,36 0,00000000
04.02.2020 11:30 0 0,35 0,00000000
04.02.2020 11:40 0 0,34 0,00000000
04.02.2020 11:50 0 0,33 0,00000000
04.02.2020 12:00 0 0,32 0,00000000
04.02.2020 12:10 0 0,32 0,00000000
04.02.2020 12:20 0 0,31 0,00000000
04.02.2020 12:30 0 0,30 0,00000000
04.02.2020 12:40 0 0,30 0,00000000
04.02.2020 12:50 0 0,29 0,00000000
04.02.2020 13:00 0 0,28 0,00000000
04.02.2020 13:10 0 0,28 0,00000000
04.02.2020 13:20 0 0,26 0,00000000
04.02.2020 13:30 0 0,26 0,00000000
04.02.2020 13:40 0 0,26 0,00000000
04.02.2020 13:50 0 0,25 0,00000000
04.02.2020 14:00 0 0,25 0,00000000
04.02.2020 14:10 0 0,24 0,00000000
04.02.2020 14:20 0 0,24 0,00000000
04.02.2020 14:30 0 0,23 0,00000000
04.02.2020 14:40 0 0,22 0,00000000
04.02.2020 14:50 0 0,22 0,00000000
04.02.2020 15:00 0 0,21 0,00000000
04.02.2020 15:10 0 0,21 0,00000000
04.02.2020 15:20 0 0,20 0,00000000
04.02.2020 15:30 0 0,20 0,00000000
04.02.2020 15:40 0 0,19 0,00000000
import urllib.request
import json
import os
import datetime
from imageio import imread
import cv2
import numpy as np
import loca_data
import duamel_model
import matplotlib.pyplot as plt
import sher_duam_class
import dateutil.parser
class DMRLPrecFile():
def __init__(self,
_geo_lan = 44.417242,
_geo_lon = 38.72287,
_size = 256,
_lan_scale = 79497.3714882,
_lon_scale = 111162.6,
_pixel_size = 152.8740566,
_polygon = [],
_corr_geo_lan = 44.417242,
_corr_geo_lon = 38.72287,
_radar_a = 200,
_radar_n = 1.6,
_FILE_MODE=False,
_UID = "1a69563a-4d37-45df-98c4-4e72370efb1e"):
self.FILE_MODE = _FILE_MODE # РЕЖИМ ЧТЕНИЯ ДАННЫХ ИЗ ФАЙЛОВ
self.UID = _UID # Уникальный идентификатор измерителя
self.geo_lan = _geo_lan # ГеоКоординаты центра (широта), число - CALC FROM POLYGON
self.geo_lon = _geo_lon # ГеоКоординаты (долгота), число - CALC FROM POLYGON
self.size = _size # Размеры квадратной картинки, пикселей по широте и высоте - CONST=256
self.lan_scale = _lan_scale # Длина дуги по широте (метров на градус) - CALC
self.lon_scale = _lon_scale # Длина дуги по долготе (метров на градус) - CALC
self.pixel_size = _pixel_size # Размер пикселя, метров на пиксель - CALC FROM SCALE
self.polygon = _polygon # Водосборный полигон, ([[id, name, lan, lon], [id, name, lan, lon], [id, name, lan, lon]...]) - INPUT
self.radar_a = _radar_a # Параметр А для расчёта осадков по ДБЗ - INPUT
self.radar_n = _radar_n # Параметр Н для расчета осадков по ДБЗ - INPUT
self.corr_geo_lan = _corr_geo_lan # Координаты АГК для корректировки (широта)
self.corr_geo_lon = _corr_geo_lon # Координаты АГК для корректировки (долгота)
self.xy_poligon = [] # Полигон в виде массива линейных координат (х, у) - CALC
self.grad_by_px_lon = 0 # Количество градусов в одном пикселе по долготе - CALC
self.grad_by_px_lan = 0 # Количество градусов в одном пикселе по широте - CALC
self.min_lon = 0 # Минимальная долгота картинки - CALC
self.min_lan = 0 # Минимальная широта картинки - CALC
self.max_lon = 0 # Максимальная долгота картинки - CALC
self.max_lan = 0 # Максимальная широта картинки - CALC
self.corr_x = -1 # Координаты корректировочного осадкомера (x)
self.corr_y = -1 # Координаты корректировочного осадкомера (y)
self.squere = 0.0 # Общая площадь водосбора
self.grad_by_px_lon = self.pixel_size / self.lon_scale # Количество градусов в одном пикселе по долготе
self.grad_by_px_lan = self.pixel_size / self.lan_scale # Количество градусов в одном пикселе по широте
self.min_lon = self.geo_lon - ((self.size / 2) * self.grad_by_px_lon) # Минимальная долгота картинки
self.min_lan = self.geo_lan - ((self.size / 2) * self.grad_by_px_lan) # Минимальная широта картинки
self.max_lon = self.geo_lon + ((self.size / 2) * self.grad_by_px_lon) # Максимальная долгота картинки
self.max_lan = self.geo_lan + ((self.size / 2) * self.grad_by_px_lan) # Максимальная широта картинки
# Параметры для корректировки
self.k_point_correction = 1 # Коэффициент корректировки точечный (интенсивность на осадкомере к интенсивносьти по радару в точке)
self.k_reserv_volume_store = dict(max_prec = -500.0, values = {}) # Резервное хранилище истории для поиска объёмов при отсутствии данных от ДМРЛ
# Определяем координаты Х,У для окорректировочного осадкомера
corr_point = self.GetXYPoint(self.corr_geo_lon, self.corr_geo_lan)
self.corr_x = corr_point["x"]
self.corr_y = corr_point["y"]
# Проверка параметров
self.CheckData()
# Генерируем полигон вида (х, у)
for point in self.polygon:
xy_point = self.GetXYPoint(point[3], point[2])
if xy_point["x"] != -1 and xy_point["y"] != -1:
self.xy_poligon.append((xy_point["x"], xy_point["y"] ))
# Считаем площадь водосбора
img = np.zeros((self.size,self.size,4), np.uint8)
for yy in img:
for xx in yy:
xx[0] = 100
xx[1] = 100
xx[2] = 100
xx[3] = 100
img_mask = np.zeros(img.shape, dtype=np.uint8)
img_roi_corners = np.array([self.xy_poligon], dtype=np.int32)
img_ignore_mask_color = (255,)*4
cv2.fillPoly(img_mask, img_roi_corners, img_ignore_mask_color)
img_masked_image = cv2.bitwise_and(img, img_mask)
###########################################
# TODO Delete!!!!
#cv2.imwrite(os.path.abspath(os.curdir) + r'\result\all_squere.png', img_masked_image)
###########################################
pcx_square_count = 0
counter = 0
for yy in img_masked_image:
for xx in yy:
counter = counter + 1
if xx[0] == 100:
pcx_square_count = pcx_square_count + 1
self.squere = self.pixel_size * self.pixel_size * pcx_square_count
# Проверка параметров
def CheckData(self):
if len(self.polygon) == 0:
raise BaseException("Полигон не указан")
if self.corr_geo_lan < 0 or self.corr_geo_lon < 0:
raise BaseException("Не удалось найти осадкомер с данными для корректировки")
if self.corr_geo_lon < self.min_lon or self.corr_geo_lon > self.max_lon or self.corr_geo_lan < self.min_lan or self.corr_geo_lan > self.max_lan:
raise BaseException("Координаты осадкомера для корректировки выходят за рамки исследуемой области:lon={}({}-{}), lan={}({}-{})".format(
self.corr_geo_lon, self.min_lon, self.max_lon, self.corr_geo_lan, self.min_lan, self.max_lan))
for point in self.polygon:
if point[3] < self.min_lon or point[3] > self.max_lon or point[2] < self.min_lan or point[2] > self.max_lan:
raise BaseException("Координаты одной из точки полигона {} выходят за рамки исследуемой области:lon={}({}-{}), lan={}({}-{})".format(
point[1], point[3], self.min_lon, self.max_lon, point[2], self.min_lan, self.max_lan))
return
# Получить осадки по значению dbZ
def GetPrecByDBZ(self, _dbz):
result = 0
if _dbz == 0 or _dbz > 127:
return result
step1 = (_dbz - 32) / 10
step2 = 10 ** step1
step3 = step2 / self.radar_a
step4 = step3 ** (1.0/self.radar_n)
result = step4
return result
# Получить точку (х, у) точке полигона в географических координатах
def GetXYPoint(self, _geo_lon, _geo_lan):
if _geo_lan < self.min_lan or _geo_lan > self.max_lan:
return dict(x = 0, y = -1)
if _geo_lon < self.min_lon or _geo_lon > self.max_lon:
return dict(x = -1, y = 0)
lon_delta = _geo_lon - self.min_lon
lan_delta = _geo_lan - self.max_lan
y_delta = lan_delta * self.lan_scale
x_delta = lon_delta * self.lon_scale
my = y_delta // self.pixel_size
mx = x_delta // self.pixel_size
result = dict(x = abs(mx), y = abs(my))
return result
# Получить матрицу (из файла или онлайн)
def GetMatrix(self, _datetime):
result = None
#############################################################
# Для файлового режима
if self.FILE_MODE == True:
# 1. Выделяем величину времени из даты
timestamp = int(_datetime.timestamp())
file_path = r"\png\dj_286m_{}.png".format(timestamp)
# 2. Ищем файл и формируем матрицу
if not os.path.exists(os.path.abspath(os.curdir) + file_path):
return result
result = imread(os.path.abspath(os.curdir) + file_path)
#############################################################
#############################################################
#############################################################
# Для web-режима
else:
# Определяем текущий тайм-слот
_datetime = datetime.datetime.now()
cur_min = (_datetime.minute // 10) * 10
current_ts = datetime.datetime(_datetime.year, _datetime.month, _datetime.day, _datetime.hour, cur_min, 0, 0)
current_ts_ts = current_ts.timestamp()
last_ts = int(current_ts.timestamp()) + 600
while datetime.datetime.now().timestamp() < last_ts:
time_result = None
time_url = 'https://tilecache.rainviewer.com/api/maps.json'
time_result = json.load(urllib.request.urlopen(time_url))
if time_result is None or len(time_result) < 1 or current_ts_ts not in time_result:
print("{} No data...".format(datetime.datetime.now()))
time.sleep(30)
continue
img = None
try:
png_data_url = 'https://tilecache.rainviewer.com/v2/radar/{time}/256/10/{lan}/{lon}/0/0_0.png'.format(
time=current_ts_ts,
lan=self.geo_lan,
lon=self.geo_lon)
img = imread(png_data_url)
except:
continue
if img is not None:
result = img
if result is not None:
try:
mask = np.zeros(result.shape, dtype=np.uint8)
roi_corners = np.array([self.xy_poligon], dtype=np.int32)
l_shape = len(result.shape)
channel_count = result.shape[l_shape - 1] # i.e. 3 or 4 depending on your image
ignore_mask_color = (255,)*channel_count
cv2.fillPoly(mask, roi_corners, ignore_mask_color)
masked_image = cv2.bitwise_and(result, mask)
result = masked_image
except(BaseException):
print("ERROR in file {}".format(os.path.abspath(os.curdir) + file_path))
print(str(BaseException))
return None
return result
# Получить данные по осадкам при отсутствии данных от ДМРЛ
def GetReservDataByPrec(self, _prec_value):
result = 0.0
if _prec_value == 0.32:
print("kosyak....")
x1 = -1.0
x2 = -1.0
y1 = -1.0
y2 = -1.0
u_sort_keys = sorted(self.k_reserv_volume_store["values"].keys(), reverse=True)
sort_keys = sorted(self.k_reserv_volume_store["values"].keys(), reverse=False)
if _prec_value > self.k_reserv_volume_store["max_prec"]:
x1 = u_sort_keys[1]
x2 = u_sort_keys[0]
else:
if _prec_value in sort_keys:
result = self.k_reserv_volume_store["values"][_prec_value]["volume"]
return result
else:
counter = -1
for key in sort_keys:
if key > _prec_value:
x1 = sort_keys[counter]
x2 = key
break
counter = counter + 1
y1 = self.k_reserv_volume_store["values"][x1]["volume"]
y2 = self.k_reserv_volume_store["values"][x2]["volume"]
result = ((x2 * y1 - x1 * y2) / (x2 - x1)) - (y1 - y2) * _prec_value
result = (((y2-y1)/(x2-x1)) * (_prec_value - x1)) + y1
if result < 0.0:
result = 0.0
return result
# Добавить в историю резервных коэффициентов новое значение
def SetNewReservKoefficient(self, _prec, _volume):
if _prec == 0 and _volume == 0:
return
if _prec > self.k_reserv_volume_store["max_prec"]:
self.k_reserv_volume_store["max_prec"] = _prec
# 1. Если такого показателя осадков нет
if _prec not in self.k_reserv_volume_store["values"].keys():
self.k_reserv_volume_store["values"][_prec] = dict(volume = _volume, counter = 1)
return
if _prec in self.k_reserv_volume_store["values"].keys():
ex_volume = self.k_reserv_volume_store["values"][_prec]["volume"]
ex_counter = self.k_reserv_volume_store["values"][_prec]["counter"]
new_volume = ((ex_volume * ex_counter) + _volume) / (ex_counter + 1)
self.k_reserv_volume_store["values"][_prec]["volume"] = new_volume
self.k_reserv_volume_store["values"][_prec]["counter"] = ex_counter + 1
return
return
# Конвертор для даты и времени в ДжСОН
def MyDateJsonConverter(self, o):
if isinstance(o, datetime.datetime):
return o.__str__()
# Получить результаты расчёта
def GetResult(self, _prec, _test_datetime=None):
"""
_prec это JSON вида:
{"time": "2020-03-20T10:00:00Z",
"period": 600,
"sum": 0.0,
"intensity": 0.0,
"type": 0}
"""
result = None
if _prec["sum"] == " ":
_prec = None
#self.k_point_correction = 1 # Коэффициент корректировки точечный (интенсивность на осадкомере к интенсивносьти по радару в точке)
#self.k_reserv_volume_prec = 1 # Резервный коэффициент (объем воды / текущие осадки на осадкомере)
temp_datetime = datetime.datetime.now()
temp_cur_min = (temp_datetime.minute // 10) * 10
cur_datetime = datetime.datetime(temp_datetime.year, temp_datetime.month, temp_datetime.day, temp_datetime.hour, temp_cur_min, 0, 0)
if _prec is not None:
cur_datetime = dateutil.parser.parse(_prec["time"])
if _test_datetime is not None:
cur_datetime = _test_datetime
matrix = self.GetMatrix(cur_datetime)
#####################################
# TODO Delete!!!!
#temp_val = int(cur_datetime.timestamp())
#temp_f_p = os.path.abspath(os.curdir) + '\\result\\{}.png'.format(int(cur_datetime.timestamp()))
#cv2.imwrite(temp_f_p, matrix)
#####################################
# 1. Если ДМРЛ нет и нет осадков
if matrix is None and (_prec is None or _prec["sum"] == " "):
result = dict(time = cur_datetime.__str__(),
water_volume = -1.0,
prec_square = -1.0,
all_square = -1.0,
dmrl_prec = -1.0)
return json.dumps(result)
# 2. Если ДМРЛ нет, но есть осадки
if matrix is None and _prec is not None:
temp_volume = self.GetReservDataByPrec(float(_prec["sum"]))
result = dict(time = cur_datetime.__str__(),
water_volume = temp_volume,
prec_square = self.squere,
all_square = -1.0,
dmrl_prec = -1.0)
return json.dumps(result)
# 3-4. Если есть ДМРЛ и есть (или нет) осадков с АГК - ОБЫЧНЫЙ АЛГОРИТМ
# Определяем коэффициент корреляции, если оба значения есть и отличны от нуля
cur_prec_value = 0
dmrl_prec = -1.0
if _prec is not None:
cur_prec_value = float(_prec["sum"])
test = matrix[0]
test = test[0]
test = test[0]
value = matrix[int(self.corr_y)][int(self.corr_x)][0]
dmrl_prec = self.GetPrecByDBZ(value)
dmrl_prec = dmrl_prec / 6
if dmrl_prec > 0 and cur_prec_value > 0:
self.k_point_correction = cur_prec_value / dmrl_prec
sum_squere = 0.0
vol_water = 0.0
pixel_counter = 0.0
for yy in matrix:
for xx in yy:
lm_value = xx[0]
m_prec = self.GetPrecByDBZ(lm_value) / 6.0
vol_local = self.pixel_size * self.pixel_size * (1.0/1000.0) * m_prec * self.k_point_correction
vol_water = vol_water + vol_local
if vol_local > 0.0:
sum_squere = sum_squere + 1.0
pixel_counter += 1.0
sum_squere = sum_squere * self.pixel_size * self.pixel_size
result = dict(time = cur_datetime.__str__(),
water_volume = vol_water,
prec_square = sum_squere,
all_square = self.squere,
dmrl_prec = dmrl_prec)
self.SetNewReservKoefficient(cur_prec_value, vol_water)
return json.dumps(result)
########################################################################
import urllib.request
import json
import os
import datetime
from imageio import imread
import cv2
import numpy as np
import loca_data
import duamel_model
import matplotlib.pyplot as plt
import sher_duam_class
import dateutil.parser
import dmrl_prec_file
class DMRLPrecFile_3SC(dmrl_prec_file.DMRLPrecFile):
# Получить результаты расчёта
def GetResult(self, _prec, _test_datetime=None):
"""
_prec это JSON вида:
{"time": "2020-03-20T10:00:00Z",
"period": 600,
"sum": 0.0,
"intensity": 0.0,
"type": 0}
"""
result = None
if _prec["sum"] == " ":
_prec = None
"""
result это JSON вида:
{"time": "2020-03-20T10:00:00Z", - время расчета
"water_volume": 0.0, - общее воличество выпавшей воды в м^3
"prec_square": 0.0, - площадь выпадения осадков в м^2
"all_square": 0.0} - общая площадь водосбора в м^2
"""
#self.k_point_correction = 1 # Коэффициент корректировки точечный (интенсивность на осадкомере к интенсивносьти по радару в точке)
#self.k_reserv_volume_prec = 1 # Резервный коэффициент (объем воды / текущие осадки на осадкомере)
temp_datetime = datetime.datetime.now()
temp_cur_min = (temp_datetime.minute // 10) * 10
cur_datetime = datetime.datetime(temp_datetime.year, temp_datetime.month, temp_datetime.day, temp_datetime.hour, temp_cur_min, 0, 0)
if _prec is not None:
#cur_datetime = dateutil.parser.parse(_prec["time"], ignoretz=False).replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)
cur_datetime = dateutil.parser.parse(_prec["time"])
if _test_datetime is not None:
cur_datetime = _test_datetime
matrix = self.GetMatrix(cur_datetime)
#####################################
# TODO Delete!!!!
#temp_val = int(cur_datetime.timestamp())
#temp_f_p = os.path.abspath(os.curdir) + '\\result\\{}.png'.format(int(cur_datetime.timestamp()))
#cv2.imwrite(temp_f_p, matrix)
#####################################
# 1. Если ДМРЛ нет и нет осадков
if matrix is None and _prec is None:
result = dict(time = cur_datetime.__str__(),
water_volume = -1.0,
prec_square = -1.0,
all_square = -1.0,
dmrl_prec = -1.0)
return json.dumps(result)
# 2. Если ДМРЛ нет, но есть осадки
if matrix is None and _prec is not None:
temp_volume = self.GetReservDataByPrec(float(_prec["sum"]))
result = dict(time = cur_datetime.__str__(),
water_volume = temp_volume,
prec_square = self.squere,
all_square = -1.0)
return json.dumps(result)
# 3-4. Если есть ДМРЛ и есть (или нет) осадков с АГК - ОБЫЧНЫЙ АЛГОРИТМ
# Определяем коэффициент корреляции, если оба значения есть и отличны от нуля
cur_prec_value = 0
if _prec is not None:
cur_prec_value = float(_prec["sum"])
test = matrix[0]
test = test[0]
test = test[0]
value = matrix[int(self.corr_y)][int(self.corr_x)][0]
dmrl_prec = self.GetPrecByDBZ(value)
dmrl_prec = dmrl_prec / 6
####################################################################
# Работаем с коэффициентами корректировки
temp_k_point_correction = 1
if dmrl_prec > 0 and cur_prec_value > 0:
temp_k_point_correction = cur_prec_value / dmrl_prec
if self.k_point_correction == 1 and self.k_count_point_correction == 0:
self.k_count_point_correction = 1
self.k_math_waiting = temp_k_point_correction
self.k_dispersion = 0
self.k_point_correction = temp_k_point_correction
else:
new_count = self.k_count_point_correction + 1 # Новое количество успешных попыток
mval1 = self.k_math_waiting * self.k_count_point_correction # сумма всех старых значений
mval2 = mval1 + self.k_point_correction # новая сумма значеий
mval3 = mval2 / new_count # Новое среднее (матожидание)
dval1 = (self.k_dispersion ** 2) * self.k_count_point_correction # сумма всех квадратов дельт старых
dval2 = (mval3 - temp_k_point_correction) ** 2 # новый квадрат дельты
dval4 = (dval1 + dval2) / new_count # общая сумма к общему кол-ву новая
dval5 = dval4 ** 0.5 # новое среднеквадратичное отклонение (типа дисперсия)
cval1 = temp_k_point_correction - mval3 # новое отклонение с учетом данной попытки
# Проверка на 3 сигмы
if abs(cval1) > abs(dval5) * 3.0:
temp_k_point_correction = mval3 + abs(dval5) * 3.0 * np.sign(cval1)
self.k_point_correction = temp_k_point_correction
####################################################################
sum_squere = 0.0
vol_water = 0.0
pixel_counter = 0.0
for yy in matrix:
for xx in yy:
lm_value = xx[0]
m_prec = self.GetPrecByDBZ(lm_value) / 6.0
vol_local = self.pixel_size * self.pixel_size * (1.0/1000.0) * m_prec * self.k_point_correction
vol_water = vol_water + vol_local
if vol_local > 0.0:
sum_squere = sum_squere + 1.0
pixel_counter += 1.0
sum_squere = sum_squere * self.pixel_size * self.pixel_size
result = dict(time = cur_datetime.__str__(),
water_volume = vol_water,
prec_square = sum_squere,
all_square = self.squere)
self.SetNewReservKoefficient(cur_prec_value, vol_water)
return json.dumps(result)
########################################################################
import urllib.request
import json
import os
import datetime
from imageio import imread
import cv2
import numpy as np
import loca_data
import duamel_model
import matplotlib.pyplot as plt
import sher_duam_class
import dateutil.parser
import dmrl_prec_file
class DMRLPrecFile_WOC(dmrl_prec_file.DMRLPrecFile):
# Получить результаты расчёта
def GetResult(self, _prec, _test_datetime=None):
"""
_prec это JSON вида:
{"time": "2020-03-20T10:00:00Z",
"period": 600,
"sum": 0.0,
"intensity": 0.0,
"type": 0}
"""
result = None
if _prec["sum"] == " ":
_prec = None
temp_datetime = datetime.datetime.now()
temp_cur_min = (temp_datetime.minute // 10) * 10
cur_datetime = datetime.datetime(temp_datetime.year, temp_datetime.month, temp_datetime.day, temp_datetime.hour, temp_cur_min, 0, 0)
if _prec is not None:
cur_datetime = dateutil.parser.parse(_prec["time"])
if _test_datetime is not None:
cur_datetime = _test_datetime
matrix = self.GetMatrix(cur_datetime)
# 1. Если ДМРЛ нет и нет осадков
if matrix is None:
result = dict(time = cur_datetime.__str__(),
water_volume = 0.0,
prec_square = 0.0,
all_square = -1.0,
dmrl_prec = -1.0)
return json.dumps(result)
# 3-4. Если есть ДМРЛ и есть (или нет) осадков с АГК - ОБЫЧНЫЙ АЛГОРИТМ
# Определяем коэффициент корреляции, если оба значения есть и отличны от нуля
cur_prec_value = 0
dmrl_prec = -1.0
sum_squere = 0.0
vol_water = 0.0
vol_water_wc = 0.0
pixel_counter = 0.0
for yy in matrix:
for xx in yy:
lm_value = xx[0]
m_prec = self.GetPrecByDBZ(lm_value) / 6.0
vol_local_wc = self.pixel_size * self.pixel_size * (1.0/1000.0) * m_prec
vol_water_wc = vol_water_wc + vol_local_wc
if vol_water_wc > 0.0:
sum_squere = sum_squere + 1.0
pixel_counter += 1.0
sum_squere = sum_squere * self.pixel_size * self.pixel_size
if self.squere != 0.0:
dmrl_prec = vol_water_wc / self.squere
result = dict(
time = cur_datetime.__str__(), # Дата
water_volume = vol_water_wc, # объём воды (метры в кубе)
prec_square = sum_squere, # площадь выпадения осадков
all_square = self.squere, # общая площадь водосбора
dmrl_prec = dmrl_prec) # осадки (в мм) ОБЪЕМ ПРИВЕДЕННЫЙ К ОБЩЕЙ ПЛОЩАДИ ВОДОСБОРА
return json.dumps(result)
########################################################################
import math
# Общие константы
DELTA_CONST = 1e-6
MIN_PART_DELTA_VAL = 1e-4
MIN_DUML_INGRL_VAL = 1e-4
# Единичный интеграл дюамеля
class DuhamelPart():
def __init__(self, _beg_time, _amp, _t_per):
self.beg_time = _beg_time
self.amp = _amp
self.t_per = _t_per
self.is_const = False
def part_step(self, _calc_time):
if self.is_const:
return self.amp
exp_val = math.exp( (self.beg_time - _calc_time)/self.t_per )
self.is_const = exp_val < DELTA_CONST
return self.amp * (1. - exp_val)
def const_part(self):
return self.is_const
# совокупность интегралов дюамеля
class DuhamelIntegral():
def __init__(self, _up_per = 1.0, _down_per = 20.0):
# параметры интеграла
# вроде как вначале одинаковые для всех
self.curr_time = -1.0
self.curr_src_val = 0.0
# непосредственно влияющие на интеграл
self.up_per = _up_per
self.down_per = _down_per
self.parts_set = []
self.duml_val = 0.0
def add_part(self, delta):
if abs(delta) < MIN_PART_DELTA_VAL:
return
if delta > 0:
self.parts_set.append(DuhamelPart(self.curr_time, delta, self.up_per))
else:
self.parts_set.append(DuhamelPart(self.curr_time, delta, self.down_per))
def calc_step(self, calc_time):
self.duml_val = 0.
for part in self.parts_set:
self.duml_val += part.part_step(calc_time)
return self.duml_val
def duml_step(self, time, value):
self.add_part(value - self.curr_src_val)
self.curr_time = time
self.curr_src_val = value
return self.calc_step(self.curr_time)
def clear_parts_set(self):
if abs(self.duml_val) >= MIN_DUML_INGRL_VAL:
return
for part in self.parts_set:
if not part.const_part():
return
self.parts_set = []
# Полная модель интегралов дюамеля с учетом корректирующих коэффициентов
class DumlRiverModel:
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):
self.duml_intgrl = DuhamelIntegral(_down_per=_dmi_down_per, _up_per=_dmi_up_per)
self.k_n = _k_n # константный коэффициент коррекции результата
self.save_k_n = self.k_n
self.k_korr = _k_korr # настраиваемый коэффициент коррекции результата
self.save_k_korr = self.k_korr
self.res_add_val = _res_add_val # аддитивная величина коррекции результата
self.save_add_val = self.res_add_val
def model_step(self, time, value):
return self.k_n * self.k_korr * self.duml_intgrl.duml_step(time, value) + self.res_add_val
# Расчёт стока с водосборов
class CatchmentArea():
def __init__(self, _capacity = 22.2, _in_filter = 1.0, _out_filter = 0.009):
# параметры водосбора
self.capacity = _capacity # вместимость водосбора, мм
self.in_filter = _in_filter # инфильтрация в почву за ед. периода, мм (за 10 мин)
self.out_filter = _out_filter # фильтрация из почвы за ед. периода, мм (за 10 мин)
self.level_delta = self.capacity
def calc_surface_flow(self, _rainfall):
мах_in = min(_rainfall, self.in_filter)
if мах_in <= self.level_delta:
self.level_delta -= мах_in
self.level_delta += self.out_filter
if self.level_delta > self.capacity:
self.level_delta = self.capacity
else:
self.level_delta += self.out_filter
if self.level_delta > self.capacity:
self.level_delta = self.capacity
мах_in = min(мах_in, self.level_delta)
self.level_delta -= мах_in
return _rainfall - мах_in
# реализация метода ньютона-рафсона
def newton_raphson(study_func, target_val, start_x, max_iter_count=10, max_err=1e-3, delta_x=1e-6):
# начальное значение аргумента
finded_x = start_x
# Цикл нахождения решения
iter_count = 0
err_y = 1e20
# цикл поиска решения
while (iter_count <= max_iter_count) and (abs(err_y) > max_err):
# Вычисляем производную dy/dx в точке x
# dfdx в принципе нам может быть известен аналитически, и в таком случае
# предпочтительно использовать аналитическое выражение.
dfdx = (study_func(finded_x + 0.5 * delta_x) - study_func(finded_x - 0.5 * delta_x)) / delta_x
# Находим приращение по y
err_y = study_func(finded_x) - target_val
# и по x
err_x = err_y / dfdx
# Получаем новое решение
finded_x = finded_x - err_x
# меняем к - во итераций
iter_count += 1
return finded_x
# для расчёта уровня воды по расходу в створе
class RiverCrossSection():
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):
# параметры трапеции
self._zero_wlevel = _zero_bsv
self._trap_a = _left_slope # ширина левого склона трапеции русла
self._trap_b = _bottom # ширина дна трапеции русла
self._trap_c = _right_slope # ширина правого склона трапеции русла
self._trap_d = _max_h # высота трапеции русла
if self._trap_d >= 0:
self._trap_leftCtg = self._trap_a / self._trap_d # котангенс левого угла трапеции русла
self._trap_rightCtg = self._trap_c / self._trap_d # котангенс правого угла трапеции русла
else:
self._trap_leftCtg = 0 # котангенс левого угла трапеции русла
self._trap_rightCtg = 0 # котангенс правого угла трапеции русла
self._i_rb_part = _i_bias # уклон русла
self._n_rb_part = _n_roughness # шероховатость русла
# площадь сечения (м^2)
def f_trap_area(self, h):
return self._trap_b * h + (self._trap_leftCtg + self._trap_rightCtg) * h * h / 2
# смоченный периметр (м)
def f_trap_perimetr(self, h):
return self._trap_b + \
math.sqrt(self._trap_leftCtg ** 2 + 1) * h + \
math.sqrt(self._trap_rightCtg ** 2 + 1) * h
# гидрологический радиус
def f_hydro_r(self, h):
return self.f_trap_area(h) / self.f_trap_perimetr(h)
# скорость потока (м/с)
def f_flow_speed(self, h):
return self.f_hydro_r(h)**(2./3) * math.sqrt(self._i_rb_part) / self._n_rb_part
# расход воды (м^3/с)
def f_flow_rate(self, h):
if h <= 0.:
return 0.
return self.f_trap_area(h) * self.f_flow_speed(h)
# расход воды (м^3/с)
def f_flow_rate_by_bs_h(self, bs_h):
return self.f_flow_rate(bs_h - self._zero_wlevel)
# уровень воды (м), определяемый по расходу воды (м^3/с)
def high_by_flow_rate(self, flow_rate):
if flow_rate <= 0.:
return 0.
return newton_raphson(self.f_flow_rate, flow_rate, 1.)
# уровень воды (м), определяемый по расходу воды (м^3/с) по балтийской системе высот
def bs_water_level(self, flow_rate):
return self.high_by_flow_rate(flow_rate) + self._zero_wlevel
import urllib.request
import json
import os
import datetime
from imageio import imread
import cv2
import numpy as np
import loca_data
import duamel_model
import matplotlib.pyplot as plt
import sher_duam_class
data_store = dict(max_prec = -500.0, values = {})
prec_store = []
prec_store.append([0.0, 0.0])
prec_store.append([1.0, 2.0])
prec_store.append([2.0, 4.0])
prec_store.append([6.0, 12.0])
prec_store.append([3.0, 6.0])
prec_store.append([4.0, 8.0])
prec_store.append([5.0, 10.0])
for p in prec_store:
if p[0] > data_store["max_prec"]:
data_store["max_prec"] = p[0]
key = p[0]
sd = data_store["values"]
sd[key] = p[1]
print(data_store)
print(sorted(data_store["values"].keys()))
value = 0.0
new_prec = 4.32
x1 = -1.0
x2 = -1.0
y1 = -1.0
y2 = -1.0
u_sort_keys = sorted(data_store["values"].keys(), reverse=True)
sort_keys = sorted(data_store["values"].keys(), reverse=False)
if new_prec > data_store["max_prec"]:
x1 = u_sort_keys[1]
x2 = u_sort_keys[0]
data_store["max_prec"] = new_prec
else:
if new_prec in sort_keys:
value = data_store["values"][new_prec]
print(value)
exit()
else:
counter = 0
for key in sort_keys:
if key > new_prec:
x1 = sort_keys[counter-1]
x2 = key
break
counter = counter + 1
y1 = data_store["values"][x1]
y2 = data_store["values"][x2]
value = ((x2 * y1 - x1 * y2) / (x2 - x1)) - (y1 - y2) * new_prec
print(value)
#print("{}|{}^^{}|{}".format(x1, y1, x2, y2))
#
import urllib.request
import json
import os
import datetime
from imageio import imread
import cv2
import numpy as np
import loca_data
png_path = r"d:\PYTHON\tests\test1\png"
lenght_lan = 79497.3714882
lenght_lon = 111162.6
base_pixel_len = 152.8740566
str_limiter = '||'
d1plan_g = base_pixel_len / lenght_lan
d1plon_g = base_pixel_len / lenght_lon
x286lon = 38.72287
x286lan = 44.417242
base_lon = x286lon - (128 * d1plon_g)
min_lon = x286lon - (128 * d1plon_g)
max_lon = x286lon + (128 * d1plon_g)
base_lan = x286lan + (128 * d1plan_g)
min_lan = x286lan - (128 * d1plan_g)
max_lan = x286lan + (128 * d1plan_g)
pol_store = []
prec_meas = []
# Генерировать измерители всех типов
def GenerateMeasurements():
#l_dlan = d1plan_g * 48
#l_dlon = d1plon_g * 48
# Точки для полигонов
result = []
result.append(GetMeas(0, 'TEST_00', x286lan, x286lon))
result.append(GetMeas(1, 'TEST_01', 44.3251277777778, 38.6788694444444))
result.append(GetMeas(2, 'TEST_02', 44.3727555555556, 38.7005))
result.append(GetMeas(3, 'TEST_03', 44.4186305555556, 38.6651361111111))
result.append(GetMeas(4, 'TEST_04', 44.4545888888889, 38.6328638888889))
result.append(GetMeas(5, 'TEST_05', 44.4508222222222, 38.6833333333333))
result.append(GetMeas(6, 'TEST_06', 44.4329277777778, 38.7327722222222))
result.append(GetMeas(7, 'TEST_07', 44.4106166666667, 38.7633277777778))
result.append(GetMeas(8, 'TEST_08', 44.3846138888889, 38.7533722222222))
result.append(GetMeas(9, 'TEST_09', 44.3416583333333, 38.735175))
prec_meas.append(GetMeas(5, 'X286|s0_d0', x286lan+0, x286lon-0))
pol_store.append(GeneratePolygons([result[0], result[3], result[4], result[5], result[6]], 1, "Verh"))
pol_store.append(GeneratePolygons([result[0], result[6], result[7], result[8], result[9], result[1], result[2]], 2, "Nige_Polkovnichego"))
return
# получить измеритель (имя, номер, х-коорд картинки и у-коорд картинки) из широты и долготы
def GetMeas(_number, _name, _lan, _lon):
if _lan <= min_lan or _lan >= max_lan:
print("MeasUnit named {} have not current lan ({})".format(_name, _lan))
return None
if _lon <= min_lon or _lon >= max_lon:
print("MeasUnit named {} have not current lon ({})".format(_name, _lon))
return None
lan_delta = _lan - base_lan
lon_delta = _lon - base_lon
y_delta = lan_delta * lenght_lan
x_delta = lon_delta * lenght_lon
my = y_delta // base_pixel_len
mx = x_delta // base_pixel_len
result = dict(number = _number, name = _name, x = abs(mx), y = abs(my))
return result
# Получить осадки по значению dbZ
def GetPrecByDBZ_2(_dbz):
result = 0
if _dbz == 0 or _dbz > 127:
return result
step1 = (_dbz - 32) / 10
step2 = 10 ** step1
step3 = step2 / 200
step4 = step3 ** 0.625
result = step4
return result
# Сгенерировать полигон по набору геокоординат
def GeneratePolygons(_meas_list, _number, _name):
# Максимальные значения координат Х и У для полигона
max_x = 0
max_y = 0
min_x = 256
min_y = 256
#Временный полигон
tmp_pol = []
# Перебрать измерители последовательно и сформировать полигон как набор пар (х, у) плюс данные о границах полигона (прямоугольных)
for imeas in _meas_list:
mx =imeas["x"]
my = imeas["y"]
# Ищем прямоугольные границы полигона
if mx > max_x:
max_x = mx
if my > max_y:
max_y = my
if mx < min_x:
min_x = mx
if my < min_y:
min_y = my
tmp_pol.append((mx, my))
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)
result["pol"] = tmp_pol
return result
# Получить "обрезанную" матрицу по полигону
def GetCuttedMatrix(_image, _mpolygon):
matrix = _mpolygon["pol"]
max_x = int(_mpolygon["max_x"])
max_y = int(_mpolygon["max_y"])
min_x = int(_mpolygon["min_x"])
min_y = int(_mpolygon["min_y"])
mask = np.zeros(_image.shape, dtype=np.uint8)
roi_corners = np.array([matrix], dtype=np.int32)
channel_count = _image.shape[2] # i.e. 3 or 4 depending on your image
ignore_mask_color = (255,)*channel_count
cv2.fillPoly(mask, roi_corners, ignore_mask_color)
masked_image = cv2.bitwise_and(_image, mask)
masked_image = masked_image[min_y:max_y, min_x:max_x]
return masked_image
# Получаем все файлы из директории с сохранёнными изображениями
png_files = os.listdir(png_path)
print(png_files)
print("Lan border = {} - {}".format(min_lan, max_lan))
print("Lon border = {} - {}".format(min_lon, max_lon))
# Сформировать массив "матрица картинки-время" (время из названия файла)
store = []
for png_f in png_files:
dt_value = png_f.replace('dj_286m_', '').replace('.png', '')
dt_value = int(dt_value)
dt_value = datetime.datetime.fromtimestamp(dt_value)
date_diff = datetime.timedelta(hours=0)
dt_value = dt_value + date_diff
file_data = imread(png_path + '\\' + png_f)
st_unit = dict(
datetime = dt_value,
matrix = file_data
)
store.append(st_unit)
# Генерируем измерители
GenerateMeasurements()
# Формируем данные
main_data = "Дата||АГК-286М||АГК-34||РАД-286М||RAD286(cor)||Сумма верх||Сумма верх(кор)||Объём верх||Объём верх(кор)||Сумма низ||Сумма низ(кор)||Объём низ||Объём низ(кор)\n"
# Последниё интервал расчёта
last_datetime = store[0]["datetime"]
# Дельта (служебная) между интервалами расчёта
dt = datetime.timedelta(minutes=10)
# Интервал времени
datetime_min = datetime.datetime(2020, 1, 29, 22, 50, 0)
datetime_max = datetime.datetime(2020, 2, 4, 15, 40, 0)
# Реальные 286М и 34
real286 = loca_data.GetPrec286M()
real34 = loca_data.GetLevel34()
# Пробегаемся по всем датам в хранилище реальных осадков
for rdata_key in real286.keys():
koef_multy_re_d_rad = 1
koef_addit_re_m_rad = 0
prec_data = None
lmatrix = None
ldatetime = rdata_key
print(ldatetime)
local_data = ""
local_data += ldatetime.__str__() + str_limiter
# 0. Осадки реальные
real_prec = real286[rdata_key]
local_data += real_prec.__str__() + str_limiter
# 0.1 Уровень реальный реальные
real_level = real34[rdata_key]
local_data += real_level.__str__() + str_limiter
for imgmatrix in store:
if imgmatrix["datetime"] == rdata_key:
lmatrix = imgmatrix["matrix"]
if lmatrix is None:
local_data += "0||0||0||0||0||0||0||0||0||0||"
main_data += local_data + "\n"
continue
# 1. Расчёт осадков по координатам
# Формируем для каждого измерителя оасдки в точке, согласно его прямоугольным координатам относительно картинки
mes = prec_meas[0]
y = int(mes["y"])
x = int(mes["x"])
value = lmatrix[y][x][0]
dmrl_prec = GetPrecByDBZ_2(value)
dmrl_prec = dmrl_prec / 6
local_data += dmrl_prec.__str__() + str_limiter
# 1.1 Считаем коэффициенты
if dmrl_prec > 0 and real_prec > 0:
koef_multy_re_d_rad = real_prec / dmrl_prec
koef_addit_re_m_rad = 0
elif dmrl_prec == 0 and real_prec > 0:
koef_multy_re_d_rad = 1
koef_addit_re_m_rad = real_prec - dmrl_prec
elif dmrl_prec > 0 and real_prec == 0:
koef_multy_re_d_rad = 1
koef_addit_re_m_rad = 0
#local_data += koef_multy_re_d_rad.__str__() + str_limiter
#local_data += koef_addit_re_m_rad.__str__() + str_limiter
# 1.2 Считаем осадки после корректировки
dmrl_prec_cor = (dmrl_prec * koef_multy_re_d_rad) + koef_addit_re_m_rad
local_data += dmrl_prec_cor.__str__() + str_limiter
# 2. Расчет площадей и осадков на площадях
for pol in pol_store:
masked_image = GetCuttedMatrix(lmatrix, pol)
sum_prec = 0
sum_squere = 0
sum_prec_cor = 0
vol_water = 0
vol_water_cor = 0
for yy in masked_image:
for xx in yy:
lm_value = xx[0]
m_prec = GetPrecByDBZ_2(lm_value)
m_prec = m_prec / 6
if m_prec > 0:
sum_squere += 1
sum_prec += m_prec
m_prec_cor = ((m_prec * koef_multy_re_d_rad) + koef_addit_re_m_rad)
sum_prec_cor = sum_prec_cor + m_prec_cor
vol_local = base_pixel_len * base_pixel_len * 1/1000 * m_prec
vol_water += vol_local
vol_local_cor = base_pixel_len * base_pixel_len * 1/1000 * m_prec_cor
vol_water_cor += vol_local_cor
local_data += sum_prec.__str__() + str_limiter
local_data += sum_prec_cor.__str__() + str_limiter
local_data += vol_water.__str__() + str_limiter
local_data += vol_water_cor.__str__() + str_limiter
#local_data += sum_squere.__str__() + str_limiter
# Вываливаем данные
main_data += local_data + "\n"
# Заменяем временные разделители и прочие символы для правильного отобраежния в Эксель
main_data = main_data.replace("||", "\t")
#main_data = main_data.replace(".", ",")
# Пишем результат в текстовый файл
f = open('result.txt', 'w')
f.write(main_data)
f.close()
"""
1. Для каждого измерителя ищем разницу в широте и долготе лот базовых координат
1.1 Проверяем на выход за предельные значения
2. По здначениям дельты и длинам градусов ищем разницу в метрах
3. По разнице в метрах и базовому размеру пикселя ищем нужный квадрат как количество целых делений дельты в метрах на базовую длину градуса
"""
import urllib.request
import json
import os
import datetime
from imageio import imread
import cv2
import numpy as np
import loca_data
import duamel_model
import matplotlib.pyplot as plt
import sher_duam_class
png_path = r"d:\PYTHON\tests\test1\png"
lenght_lan = 79497.3714882
lenght_lon = 111162.6
base_pixel_len = 152.8740566
str_limiter = '||'
d1plan_g = base_pixel_len / lenght_lan
d1plon_g = base_pixel_len / lenght_lon
x286lon = 38.72287
x286lan = 44.417242
base_lon = x286lon - (128 * d1plon_g)
min_lon = x286lon - (128 * d1plon_g)
max_lon = x286lon + (128 * d1plon_g)
base_lan = x286lan + (128 * d1plan_g)
min_lan = x286lan - (128 * d1plan_g)
max_lan = x286lan + (128 * d1plan_g)
pol_store = []
prec_meas = []
duamel = duamel_model.DumlRiverModel(_k_n=1.0, _k_korr=25.0, _res_add_val=20.0, _dmi_up_per=1.0, _dmi_down_per=20.0)
duamelk1 = duamel_model.DumlRiverModel(_k_n=1.65, _k_korr=25.0, _res_add_val=25.0, _dmi_up_per=0.00001, _dmi_down_per=20.0)
flow_rate = duamel_model.CatchmentArea(_capacity=22.2, _in_filter=1.0, _out_filter=0.09)
flow_rate1 = duamel_model.CatchmentArea(_capacity=100.0, _in_filter=2.0, _out_filter=0.09)
level_calc = duamel_model.RiverCrossSection(_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)
sher_duam = sher_duam_class.TestSherDuamel(_k_up=0.7, _k_down=25.0, _k_multy=120.0, _k_addit=40.0, _zero_level=2.20)
# Генерировать измерители всех типов
def GenerateMeasurements():
# Точки для полигонов
result = []
all_result = []
# Получение координат полигона водосбора Джубги
pcs = loca_data.GetGeoCoordPolygon()
# Последняя запись - для отбрасывания дублей пикселей
p_last = dict(x = -1.0, y = 0.0)
# Получаем список точек полигона
for pc in pcs:
p = GetMeas(pc[0], pc[1], pc[2], pc[3])
if p_last['x'] == -1.0:
p_last['x'] = p['x']
p_last['y'] = p['y']
all_result.append(p)
else:
if p_last['x'] != p['x'] and p_last['y'] != p['y']:
all_result.append(p)
p_last['x'] = p['x']
p_last['y'] = p['y']
result.append(GetMeas(0, 'TEST_00', x286lan, x286lon))
result.append(GetMeas(1, 'TEST_01', 44.3251277777778, 38.6788694444444))
result.append(GetMeas(2, 'TEST_02', 44.3727555555556, 38.7005))
result.append(GetMeas(3, 'TEST_03', 44.4186305555556, 38.6651361111111))
result.append(GetMeas(4, 'TEST_04', 44.4545888888889, 38.6328638888889))
result.append(GetMeas(5, 'TEST_05', 44.4508222222222, 38.6833333333333))
result.append(GetMeas(6, 'TEST_06', 44.4329277777778, 38.7327722222222))
result.append(GetMeas(7, 'TEST_07', 44.4106166666667, 38.7633277777778))
result.append(GetMeas(8, 'TEST_08', 44.3846138888889, 38.7533722222222))
result.append(GetMeas(9, 'TEST_09', 44.3416583333333, 38.735175))
prec_meas.append(GetMeas(5, 'X286|s0_d0', x286lan+0, x286lon-0))
pol_store.append(GeneratePolygons(all_result, 0, "All"))
#pol_store.append(GeneratePolygons([result[0], result[3], result[4], result[5], result[6]], 1, "Verh"))
#pol_store.append(GeneratePolygons([result[0], result[6], result[7], result[8], result[9], result[1], result[2]], 2, "Nige_Polkovnichego"))
return
# получить измеритель (имя, номер, х-коорд картинки и у-коорд картинки) из широты и долготы
def GetMeas(_number, _name, _lan, _lon):
if _lan <= min_lan or _lan >= max_lan:
print("MeasUnit named {} have not current lan ({})".format(_name, _lan))
return None
if _lon <= min_lon or _lon >= max_lon:
print("MeasUnit named {} have not current lon ({})".format(_name, _lon))
return None
lan_delta = _lan - base_lan
lon_delta = _lon - base_lon
y_delta = lan_delta * lenght_lan
x_delta = lon_delta * lenght_lon
my = y_delta // base_pixel_len
mx = x_delta // base_pixel_len
result = dict(number = _number, name = _name, x = abs(mx), y = abs(my))
return result
# Получить осадки по значению dbZ
def GetPrecByDBZ_2(_dbz):
result = 0
if _dbz == 0 or _dbz > 127:
return result
step1 = (_dbz - 32) / 10
step2 = 10 ** step1
step3 = step2 / 200
step4 = step3 ** 0.625
result = step4
return result
# Сгенерировать полигон по набору геокоординат
def GeneratePolygons(_meas_list, _number, _name):
# Максимальные значения координат Х и У для полигона
max_x = 0
max_y = 0
min_x = 256
min_y = 256
#Временный полигон
tmp_pol = []
# Перебрать измерители последовательно и сформировать полигон как набор пар (х, у) плюс данные о границах полигона (прямоугольных)
for imeas in _meas_list:
mx =imeas["x"]
my = imeas["y"]
# Ищем прямоугольные границы полигона
if mx > max_x:
max_x = mx
if my > max_y:
max_y = my
if mx < min_x:
min_x = mx
if my < min_y:
min_y = my
tmp_pol.append((mx, my))
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)
result["pol"] = tmp_pol
return result
# Получить "обрезанную" матрицу по полигону
def GetCuttedMatrix(_image, _mpolygon):
matrix = _mpolygon["pol"]
max_x = int(_mpolygon["max_x"])
max_y = int(_mpolygon["max_y"])
min_x = int(_mpolygon["min_x"])
min_y = int(_mpolygon["min_y"])
mask = np.zeros(_image.shape, dtype=np.uint8)
roi_corners = np.array([matrix], dtype=np.int32)
channel_count = _image.shape[2] # i.e. 3 or 4 depending on your image
ignore_mask_color = (255,)*channel_count
cv2.fillPoly(mask, roi_corners, ignore_mask_color)
masked_image = cv2.bitwise_and(_image, mask)
masked_image = masked_image[min_y:max_y, min_x:max_x]
return masked_image
# Получаем все файлы из директории с сохранёнными изображениями
png_files = os.listdir(png_path)
print(png_files)
print("Lan border = {} - {}".format(min_lan, max_lan))
print("Lon border = {} - {}".format(min_lon, max_lon))
# Сформировать массив "матрица картинки-время" (время из названия файла)
store = []
for png_f in png_files:
dt_value = png_f.replace('dj_286m_', '').replace('.png', '')
dt_value = int(dt_value)
dt_value = datetime.datetime.fromtimestamp(dt_value)
date_diff = datetime.timedelta(hours=0)
dt_value = dt_value + date_diff
file_data = imread(png_path + '\\' + png_f)
st_unit = dict(
datetime = dt_value,
matrix = file_data
)
store.append(st_unit)
# Генерируем измерители
GenerateMeasurements()
# Формируем данные
main_data = "Дата||АГК-286М||АГК-34||РАД-286М||RAD286(cor)||Сумма ВСЕГО||Сумма ВСЕГО(кор)||Сумма ВСЕГО ОБ||Сумма ВСЕГО ОБ(кор)||Flow||Duamel||DuamLevel||\n"
# Последниё интервал расчёта
last_datetime = store[0]["datetime"]
# Дельта (служебная) между интервалами расчёта
dt = datetime.timedelta(minutes=10)
# Интервал времени
datetime_min = datetime.datetime(2020, 1, 29, 22, 50, 0)
datetime_max = datetime.datetime(2020, 2, 4, 15, 40, 0)
# Реальные 286М и 34
real286 = loca_data.GetPrec286M()
real34 = loca_data.GetLevel34()
dtcounter = -1
# Для графиков
mas_x = [] #time
mas_real = [] #real water level
mas_duam = [] #duamel water level
mas_duam1 = [] #duamel water level
mas_sher_duam = [] #дюамель от шержукова
mas_wvol = [] #water volume
# Пробегаемся по всем датам в хранилище реальных осадков
for rdata_key in real286.keys():
dtcounter = dtcounter + 1
mas_x.append(dtcounter)
koef_multy_re_d_rad = 1
koef_addit_re_m_rad = 0
prec_data = None
lmatrix = None
ldatetime = rdata_key
print(ldatetime)
local_data = ""
local_data += ldatetime.__str__() + str_limiter
# 0. Осадки реальные
real_prec = real286[rdata_key]
local_data += real_prec.__str__() + str_limiter
# 0.1 Уровень реальный
real_level = real34[rdata_key]
local_data += real_level.__str__() + str_limiter
mas_real.append(real_level)
for imgmatrix in store:
if imgmatrix["datetime"] == rdata_key:
lmatrix = imgmatrix["matrix"]
if lmatrix is None:
local_data += "0||0||0||0||"
rain_corr = real_prec
flow = flow_rate.calc_surface_flow(rain_corr)
flow1 = flow_rate1.calc_surface_flow(rain_corr)
duam_value = duamel.model_step(dtcounter, flow)
duam_valk1 = duamelk1.model_step(dtcounter, flow)
wlevel = level_calc.bs_water_level(duam_value)
wlevel1 = level_calc.bs_water_level(duam_valk1)
mas_duam.append(wlevel)
mas_duam1.append(wlevel1)
test_sher_level = sher_duam.CalculateLevel(rain_corr, dtcounter)
mas_sher_duam.append(test_sher_level)
mas_wvol.append(0.0)
local_data += flow.__str__() + str_limiter
local_data += duam_value.__str__() + str_limiter
local_data += wlevel.__str__() + str_limiter
main_data += local_data + "\n"
continue
# 1. Расчёт осадков по координатам
# Формируем для каждого измерителя оасдки в точке, согласно его прямоугольным координатам относительно картинки
mes = prec_meas[0]
y = int(mes["y"])
x = int(mes["x"])
value = lmatrix[y][x][0]
dmrl_prec = GetPrecByDBZ_2(value)
dmrl_prec = dmrl_prec / 6
local_data += dmrl_prec.__str__() + str_limiter
# 1.1 Считаем коэффициенты
if dmrl_prec > 0 and real_prec > 0:
koef_multy_re_d_rad = real_prec / dmrl_prec
koef_addit_re_m_rad = 0
elif dmrl_prec == 0 and real_prec > 0:
koef_multy_re_d_rad = 1
koef_addit_re_m_rad = real_prec - dmrl_prec
elif dmrl_prec > 0 and real_prec == 0:
koef_multy_re_d_rad = 1
koef_addit_re_m_rad = 0
# 1.2 Считаем осадки после корректировки
dmrl_prec_cor = (dmrl_prec * koef_multy_re_d_rad) + koef_addit_re_m_rad
local_data += dmrl_prec_cor.__str__() + str_limiter
# 2. Расчет площадей и осадков на площадях
for pol in pol_store:
masked_image = GetCuttedMatrix(lmatrix, pol)
sum_prec = 0
sum_squere = 0
sum_prec_cor = 0
vol_water = 0
vol_water_cor = 0
for yy in masked_image:
for xx in yy:
lm_value = xx[0]
m_prec = GetPrecByDBZ_2(lm_value)
m_prec = m_prec / 6
if m_prec > 0:
sum_squere += 1
sum_prec += m_prec
m_prec_cor = ((m_prec * koef_multy_re_d_rad) + koef_addit_re_m_rad)
sum_prec_cor = sum_prec_cor + m_prec_cor
vol_local = base_pixel_len * base_pixel_len * 1/1000 * m_prec
vol_water += vol_local
vol_local_cor = base_pixel_len * base_pixel_len * 1/1000 * m_prec_cor
vol_water_cor += vol_local_cor
local_data += sum_prec.__str__() + str_limiter
local_data += sum_prec_cor.__str__() + str_limiter
local_data += vol_water.__str__() + str_limiter
local_data += vol_water_cor.__str__() + str_limiter
rain_corr = vol_water * 0.0000099471691 * 8
mas_wvol.append(rain_corr)
flow = flow_rate.calc_surface_flow(rain_corr)
flow1 = flow_rate1.calc_surface_flow(rain_corr)
duam_value = duamel.model_step(dtcounter, flow)
duam_valk1 = duamelk1.model_step(dtcounter, flow)
wlevel = level_calc.bs_water_level(duam_value)
wlevel1 = level_calc.bs_water_level(duam_valk1)
test_sher_level = sher_duam.CalculateLevel(flow1, dtcounter)
mas_duam.append(wlevel)
mas_duam1.append(wlevel1)
mas_sher_duam.append(test_sher_level)
local_data += flow.__str__() + str_limiter
local_data += duam_value.__str__() + str_limiter
local_data += wlevel.__str__() + str_limiter
local_data += sum_squere.__str__() + str_limiter
#local_data += sum_squere.__str__() + str_limiter
# Вываливаем данные
main_data += local_data + "\n"
# Заменяем временные разделители и прочие символы для правильного отобраежния в Эксель
main_data = main_data.replace("||", "\t")
# Пишем результат в текстовый файл
f = open('result.txt', 'w')
f.write(main_data)
f.close()
fig, ax = plt.subplots()
ax.plot(mas_x, mas_real, label = 'AGK-34')
ax.plot(mas_x, mas_duam, label = 'DUAM')
ax.plot(mas_x, mas_duam1, label = 'DUAM_2')
ax.plot(mas_x, mas_sher_duam, label = 'SHER_DUAM')
ax.legend()
plt.show()
"""
1. Для каждого измерителя ищем разницу в широте и долготе лот базовых координат
1.1 Проверяем на выход за предельные значения
2. По здначениям дельты и длинам градусов ищем разницу в метрах
3. По разнице в метрах и базовому размеру пикселя ищем нужный квадрат как количество целых делений дельты в метрах на базовую длину градуса
"""
import cv2
import numpy as np
# original image
# -1 loads as-is so if it will be 3 or 4 channel as the original
image = cv2.imread('test.png', -1)
# mask defaulting to black for 3-channel and transparent for 4-channel
# (of course replace corners with yours)
mask = np.zeros(image.shape, dtype=np.uint8)
roi_corners = np.array([[(10,10), (20,20), (10,30)]], dtype=np.int32)
# fill the ROI so it doesn't get wiped out when the mask is applied
channel_count = image.shape[2] # i.e. 3 or 4 depending on your image
ignore_mask_color = (255,)*channel_count
cv2.fillPoly(mask, roi_corners, ignore_mask_color)
# from Masterfool: use cv2.fillConvexPoly if you know it's convex
# apply the mask
masked_image = cv2.bitwise_and(image, mask)
# save the result
cv2.imwrite('image_masked.png', masked_image)
\ No newline at end of file
import urllib.request
import json
import os
import datetime
from imageio import imread
import cv2
import numpy as np
import loca_data
import duamel_model
import matplotlib.pyplot as plt
import sher_duam_class
import dateutil.parser
import psycopg2
import pathlib
def get_connection():
DBConnection = psycopg2.connect(
host="localhost",
port = "15432",
database="wf71",
user="wf71",
password="wf71")
print("Connect is success!")
DBConnection.autocommit = True
return DBConnection
def write_png(filename = "test.png", px_array = None):
if px_array is None:
px_array = np.zeros(10,10)
path = pathlib.Path(__file__).parent.absolute()
path = str(path) + filename
cv2.imwrite(path, px_array)
def get_png_data_from_db():
DBConnection = get_connection()
print("Connect is success!")
cur = DBConnection.cursor()
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'"
cur.execute(query)
result = cur.fetchall()
radar_a = 200
radar_n = 1.6
for_txt = []
for var in result:
matrix = []
m_dt = var[0]
mx = json.loads(var[1])
value = 0.0
error = mx.get("error", False)
if error == "Radar matrix is not exist":
value = 0.0
else:
matrix = mx["matrix"]
if len(matrix) > 1:
_dbz = matrix[143][107]
if _dbz == 0 or _dbz > 127:
value = 0.0
else:
step1 = (_dbz - 32) / 10
step2 = 10 ** step1
step3 = step2 / radar_a
step4 = step3 ** (1.0/radar_n)
step5 = step4 / 6.0
value = step5
#delta_dt = datetime.timedelta(hours=3)
#m_dt = datetime.datetime.strptime(str(m_dt), '%Y-%m-%d %H:%M:%S') - delta_dt
for_txt.append([str(m_dt), value])
cur.close()
f = open('result_from_db.txt', 'w')
f.write(str(for_txt))
f.close()
def get_png_picture_from_db():
DBConnection = get_connection()
print("Connect is success!")
cur = DBConnection.cursor()
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'"
cur.execute(query)
result = cur.fetchall()
i = -1
for var in result:
matrix = []
m_dt = var[0]
td = datetime.timedelta(hours=3)
m_dt = m_dt+td
print(m_dt)
mx = json.loads(var[1])
img = np.zeros((256,256, 4),dtype=np.uint8)
error = mx.get("error", False)
if error == "Radar matrix is not exist":
continue
else:
matrix = mx["matrix"]
if len(matrix) > 1:
#png_data = []
#for line in matrix:
# new_line = []
# for column in line:
# new_line.append([column, column, column, 255])
# png_data.append(new_line)
#png_data = np.array(png_data)
x = -1
for line in matrix:
x = x + 1
y = -1
for column in line:
y = y + 1
img[x][y] = [column, column, column, 255]
fn_dt = '{}_{}_{}__{}_{}.png'.format(m_dt.timetuple()[0], m_dt.timetuple()[1], m_dt.timetuple()[2], m_dt.timetuple()[3], m_dt.timetuple()[4])
#write_png(filename=r"/png_07/{}".format(fn_dt), px_array=png_data)
write_png(filename=r"/png_07/{}".format(fn_dt), px_array=img)
cur.close()
#get_png_picture_from_db
#get_png_data_from_db()
get_png_picture_from_db()
import urllib.request
import json
import os
import datetime
from imageio import imread
import cv2
import numpy as np
import loca_data
import duamel_model
import matplotlib.pyplot as plt
import sher_duam_class
png_path = r"d:\PYTHON\tests\test1\test_png\dj_286m_1580308200.png"
save_path = r"d:\PYTHON\tests\test1\test_png\test.png"
lenght_lan = 79497.3714882
lenght_lon = 111162.6
base_pixel_len = 152.8740566
str_limiter = '||'
d1plan_g = base_pixel_len / lenght_lan
d1plon_g = base_pixel_len / lenght_lon
x286lon = 38.72287
x286lan = 44.417242
base_lon = x286lon - (128 * d1plon_g)
min_lon = x286lon - (128 * d1plon_g)
max_lon = x286lon + (128 * d1plon_g)
base_lan = x286lan + (128 * d1plan_g)
min_lan = x286lan - (128 * d1plan_g)
max_lan = x286lan + (128 * d1plan_g)
pol_store = []
prec_meas = []
# Сгенерировать полигон по набору геокоординат
def GeneratePolygons(_meas_list, _number, _name):
# Максимальные значения координат Х и У для полигона
max_x = 0
max_y = 0
min_x = 256
min_y = 256
#Временный полигон
tmp_pol = []
# Перебрать измерители последовательно и сформировать полигон как набор пар (х, у) плюс данные о границах полигона (прямоугольных)
for imeas in _meas_list:
mx =imeas["x"]
my = imeas["y"]
# Ищем прямоугольные границы полигона
if mx > max_x:
max_x = mx
if my > max_y:
max_y = my
if mx < min_x:
min_x = mx
if my < min_y:
min_y = my
tmp_pol.append((mx, my))
#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)
result = tmp_pol
return result
# получить измеритель (имя, номер, х-коорд картинки и у-коорд картинки) из широты и долготы
def GetMeas(_number, _name, _lan, _lon):
if _lan <= min_lan or _lan >= max_lan:
print("MeasUnit named {} have not current lan ({})".format(_name, _lan))
return None
if _lon <= min_lon or _lon >= max_lon:
print("MeasUnit named {} have not current lon ({})".format(_name, _lon))
return None
lan_delta = _lan - base_lan
lon_delta = _lon - base_lon
y_delta = lan_delta * lenght_lan
x_delta = lon_delta * lenght_lon
my = y_delta // base_pixel_len
mx = x_delta // base_pixel_len
result = dict(number = _number, name = _name, x = abs(mx), y = abs(my))
return result
_image = imread(png_path)
# Получение координат полигона водосбора Джубги
pcs = loca_data.GetGeoCoordPolygon()
# Последняя запись - для отбрасывания дублей пикселей
p_last = dict(x = -1.0, y = 0.0)
all_result = []
# Получаем список точек полигона
for pc in pcs:
p = GetMeas(pc[0], pc[1], pc[2], pc[3])
if p_last['x'] == -1.0:
p_last['x'] = p['x']
p_last['y'] = p['y']
all_result.append(p)
else:
if p_last['x'] != p['x'] and p_last['y'] != p['y']:
all_result.append(p)
p_last['x'] = p['x']
p_last['y'] = p['y']
polygon = GeneratePolygons(all_result, 0, "All")
#polygon = all_result
##################################################
# пробуем создать пустое изображение и заполнить его полигоном
img = np.zeros((256,256,4), np.uint8)
for yy in img:
for xx in yy:
xx[0] = 255
xx[1] = 0
xx[2] = 0
xx[3] = 255
img_mask = np.zeros(img.shape, dtype=np.uint8)
img_roi_corners = np.array([polygon], dtype=np.int32)
img_ignore_mask_color = (255,)*4
cv2.fillPoly(img_mask, img_roi_corners, img_ignore_mask_color)
img_masked_image = cv2.bitwise_and(img, img_mask)
cv2.imwrite(save_path, img_masked_image)
pcx_square_count = 0
for yy in img_masked_image:
for xx in yy:
if xx[0] == 255:
pcx_square_count = pcx_square_count + 1
print(pcx_square_count)
squere = base_pixel_len * base_pixel_len * pcx_square_count
print(squere)
##################################################
'''mask = np.zeros(_image.shape, dtype=np.uint8)
roi_corners = np.array([polygon], dtype=np.int32)
channel_count = _image.shape[2] # i.e. 3 or 4 depending on your image
ignore_mask_color = (255,)*channel_count
cv2.fillPoly(mask, roi_corners, ignore_mask_color)
masked_image = cv2.bitwise_and(_image, mask)'''
import urllib.request
import json
import os
import datetime
from imageio import imread
png_path = r"d:\PYTHON\tests\test1\png"
lenght_lan = 79497.3714882
lenght_lon = 111162.6
base_pixel_len = 152.8740566
str_limiter = '||'
d1plan_g = base_pixel_len / lenght_lan
d1plon_g = base_pixel_len / lenght_lon
x286lon = 38.72287
x286lan = 44.417242
base_lon = x286lon - (128 * d1plon_g)
min_lon = x286lon - (128 * d1plon_g)
max_lon = x286lon + (128 * d1plon_g)
base_lan = x286lan + (128 * d1plan_g)
min_lan = x286lan - (128 * d1plan_g)
max_lan = x286lan + (128 * d1plan_g)
# Генерировать измерители
def GenerateMeasurements():
result = []
l_dlan = d1plan_g * 48
l_dlon = d1plon_g * 48
result.append(GetMeas(1, 'X286|sp_dm', x286lan+l_dlan, x286lon-l_dlon))
result.append(GetMeas(2, 'X286|sp_d0', x286lan+l_dlan, x286lon-0))
result.append(GetMeas(3, 'X286|sp_dp', x286lan+l_dlan, x286lon+l_dlon))
result.append(GetMeas(4, 'X286|s0_dm', x286lan+0, x286lon-l_dlon))
result.append(GetMeas(5, 'X286|s0_d0', x286lan+0, x286lon-0))
result.append(GetMeas(6, 'X286|s0_dp', x286lan+0, x286lon+l_dlon))
result.append(GetMeas(7, 'X286|sm_dm', x286lan-l_dlan, x286lon-l_dlon))
result.append(GetMeas(8, 'X286|sm_d0', x286lan-l_dlan, x286lon-0))
result.append(GetMeas(9, 'X286|sm_dp', x286lan-l_dlan, x286lon+l_dlon))
'''
result.append(GetMeas(1, 'TEST_01', 44.3251277777778, 38.6788694444444))
result.append(GetMeas(2, 'TEST_02', 44.3727555555556, 38.7005))
result.append(GetMeas(3, 'TEST_03', 44.4186305555556, 38.6651361111111))
result.append(GetMeas(4, 'TEST_04', 44.4545888888889, 38.6328638888889))
result.append(GetMeas(5, 'TEST_05', 44.4508222222222, 38.6833333333333))
result.append(GetMeas(6, 'TEST_06', 44.4329277777778, 38.7327722222222))
result.append(GetMeas(7, 'TEST_07', 44.4106166666667, 38.7633277777778))
result.append(GetMeas(8, 'TEST_08', 44.3846138888889, 38.7533722222222))
result.append(GetMeas(9, 'TEST_09', 44.3416583333333, 38.735175))
'''
return result
# получить измеритель (имя, номер, х-коорд картинки и у-коорд картинки) из широты и долготы
def GetMeas(_number, _name, _lan, _lon):
if _lan <= min_lan or _lan >= max_lan:
print("MeasUnit named {} have not current lan ({})".format(_name, _lan))
return None
if _lon <= min_lon or _lon >= max_lon:
print("MeasUnit named {} have not current lon ({})".format(_name, _lon))
return None
lan_delta = _lan - base_lan
lon_delta = _lon - base_lon
y_delta = lan_delta * lenght_lan
x_delta = lon_delta * lenght_lon
my = y_delta // base_pixel_len
mx = x_delta // base_pixel_len
result = dict(number = _number, name = _name, x = abs(mx), y = abs(my))
return result
# Получить осадки по значению dbZ
def GetPrecByDBZ_2(_dbz):
result = 0
if _dbz == 0 or _dbz > 127:
return result
step1 = (_dbz - 32) / 10
step2 = 10 ** step1
step3 = step2 / 200
step4 = step3 ** 0.625
result = step4
return result
# Получаем все файлы из директории с сохранёнными изображениями
png_files = os.listdir(png_path)
print(png_files)
print("Lan border = {} - {}".format(min_lan, max_lan))
print("Lon border = {} - {}".format(min_lon, max_lon))
# Сформировать массив "матрица картинки-время" (время из названия файла)
store = []
for png_f in png_files:
dt_value = png_f.replace('dj_286m_', '').replace('.png', '')
dt_value = int(dt_value)
dt_value = datetime.datetime.fromtimestamp(dt_value)
date_diff = datetime.timedelta(hours=0)
dt_value = dt_value + date_diff
file_data = imread(png_path + '\\' + png_f)
st_unit = dict(
datetime = dt_value,
matrix = file_data
)
store.append(st_unit)
# Генерируем тестовые измерители
prec_meas = GenerateMeasurements()
# Болванка для шапки в Эксель
shapka = 'Date\t'
x_y = ''
# Формируем шапку для Экселя
for mes in prec_meas:
if mes is not None:
shapka += mes["name"] + str_limiter
x_y += "N={} X={} Y={}{}".format(mes["number"], mes["x"], mes["y"], str_limiter)
print(shapka)
# Формируем данные
main_data = ""
# Последниё интервал расчёта
last_datetime = store[0]["datetime"]
# Дельта (служебная) между интервалами расчёта
dt = datetime.timedelta(minutes=10)
# Пробегаемся по всем картинкам в хранилище
for prec_data in store:
# Формируем локальные переменные для цикла
lmatrix = prec_data["matrix"]
ldatetime = prec_data["datetime"]
date_diff = ldatetime - last_datetime
local_data = ""
# Фиксим (пустой строкой) промежутки между измерениями, если таковые имеются
while date_diff.seconds >= 1200:
local_data = ""
last_datetime = last_datetime + dt
local_data += last_datetime.__str__() + str_limiter
main_data += local_data + "\n"
date_diff = ldatetime - last_datetime
# Формируем для каждого измерителя оасдки в точке, согласно его прямоугольным координатам относительно картинки
local_data = ""
local_data += ldatetime.__str__() + str_limiter
for mes in prec_meas:
y = int(mes["y"])
x = int(mes["x"])
value = lmatrix[y][x][0]
prec = GetPrecByDBZ_2(value)
local_data += prec.__str__() + str_limiter
# Ищем максимум осадков на картинке
prec_max = 0
'''
for yy in lmatrix:
for xx in yy:
lm_value = xx[0]
m_prec = GetPrecByDBZ_2(lm_value)
if m_prec > prec_max:
prec_max = m_prec
local_data += prec_max.__str__() + str_limiter
'''
# Вываливаем данные
main_data += local_data + "\n"
last_datetime = ldatetime
# Заменяем временные разделители и прочие символы для правильного отобраежния в Эксель
main_data = main_data.replace("||", "\t")
main_data = main_data.replace(".", ",")
# Пишем результат в текстовый файл
f = open('result.txt', 'w')
f.write(main_data)
f.close()
"""
1. Для каждого измерителя ищем разницу в широте и долготе лот базовых координат
1.1 Проверяем на выход за предельные значения
2. По здначениям дельты и длинам градусов ищем разницу в метрах
3. По разнице в метрах и базовому размеру пикселя ищем нужный квадрат как количество целых делений дельты в метрах на базовую длину градуса
"""
import sys
import os
import time
import datetime
import json
import jsonpickle
import importlib
import urllib.request
from imageio import imread
import redis
import requests
import dateutil.parser
time_result = None
try:
time_url = 'https://tilecache.rainviewer.com/api/maps.json'
time_result = json.load(urllib.request.urlopen(time_url))
except Exception as e:
print("ERROR::{er}".format(er=e))
exit()
if time_result is None or len(time_result) < 1:
print("time result is empty")
exit()
itime = time_result[0]
last_number = len(time_result) - 1
last = 0
for in_dt in time_result:
dt_value = datetime.datetime.fromtimestamp(in_dt)
print("{}-{}".format(in_dt, dt_value))
print("DELTA = {}".format(in_dt - last))
last = in_dt
dt_value = datetime.datetime.fromtimestamp(time_result[last_number])
print("Текущий - {} -> {}".format(time_result[last_number], dt_value))
# Определяем текущий тайм-слот
_datetime = datetime.datetime.now()
cur_min = (_datetime.minute // 10) * 10
current_ts = datetime.datetime(_datetime.year, _datetime.month, _datetime.day, _datetime.hour, cur_min, 0, 0)
current_ts_ts = current_ts.timestamp()
last_ts = int(current_ts.timestamp()) + 600
'''
while datetime.datetime.now().timestamp() < last_ts:
time_result = None
time_url = 'https://tilecache.rainviewer.com/api/maps.json'
time_result = json.load(urllib.request.urlopen(time_url))
if time_result is None or len(time_result) < 1 or current_ts_ts not in time_result:
print("{} No data...".format(datetime.datetime.now()))
time.sleep(30)
continue
png_data_url = 'https://tilecache.rainviewer.com/v2/radar/{time}/256/10/{lan}/{lon}/0/0_0.png'.format(time=itime,
lan="44.417242",
lon="38.72287")
img = imread(png_data_url)
'''
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'
ocm_data = requests.get(url_ocm)
print(ocm_data.json())
data = ocm_data.json()
for data_item in data:
print("value = time-{}, sum - {}".format(data_item["time"], data_item["sum"]))
#cur_cs = datetime.datetime.fromisoformat(data_item["time"])
str = data_item["time"]
cur_cs = datetime.datetime.strptime(data_item["time"], '%Y-%m-%dT%H:%M:%SZ')
cs2 = dateutil.parser.parse(str, ignoretz=False)
cs3 = cs2.replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)
cs4 = dateutil.parser.parse(str, ignoretz=False).replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)
#dateutil.parser.parse(data_item["time"])
print(cur_cs)
print(cs2)
print(cs3)
print(cs4)
import urllib.request
import json
import os
import datetime
from imageio import imread
import cv2
import numpy as np
png_path = r"d:\PYTHON\tests\test1\png"
png_result_path = r"d:\PYTHON\tests\test1\cutted"
lenght_lan = 79497.3714882
lenght_lon = 111162.6
base_pixel_len = 152.8740566
str_limiter = '||'
d1plan_g = base_pixel_len / lenght_lan
d1plon_g = base_pixel_len / lenght_lon
x286lon = 38.72287
x286lan = 44.417242
base_lon = x286lon - (128 * d1plon_g)
min_lon = x286lon - (128 * d1plon_g)
max_lon = x286lon + (128 * d1plon_g)
base_lan = x286lan + (128 * d1plan_g)
min_lan = x286lan - (128 * d1plan_g)
max_lan = x286lan + (128 * d1plan_g)
# Генерировать измерители
def GenerateMeasurements():
result = []
l_dlan = d1plan_g * 48
l_dlon = d1plon_g * 48
'''
result.append(GetMeas(1, 'X286|sp_dm', x286lan+l_dlan, x286lon-l_dlon))
result.append(GetMeas(2, 'X286|sp_d0', x286lan+l_dlan, x286lon-0))
result.append(GetMeas(3, 'X286|sp_dp', x286lan+l_dlan, x286lon+l_dlon))
result.append(GetMeas(4, 'X286|s0_dm', x286lan+0, x286lon-l_dlon))
result.append(GetMeas(5, 'X286|s0_d0', x286lan+0, x286lon-0))
result.append(GetMeas(6, 'X286|s0_dp', x286lan+0, x286lon+l_dlon))
result.append(GetMeas(7, 'X286|sm_dm', x286lan-l_dlan, x286lon-l_dlon))
result.append(GetMeas(8, 'X286|sm_d0', x286lan-l_dlan, x286lon-0))
result.append(GetMeas(9, 'X286|sm_dp', x286lan-l_dlan, x286lon+l_dlon))
'''
result.append(GetMeas(0, 'TEST_00', x286lan, x286lon))
result.append(GetMeas(1, 'TEST_01', 44.3251277777778, 38.6788694444444))
result.append(GetMeas(2, 'TEST_02', 44.3727555555556, 38.7005))
result.append(GetMeas(3, 'TEST_03', 44.4186305555556, 38.6651361111111))
result.append(GetMeas(4, 'TEST_04', 44.4545888888889, 38.6328638888889))
result.append(GetMeas(5, 'TEST_05', 44.4508222222222, 38.6833333333333))
result.append(GetMeas(6, 'TEST_06', 44.4329277777778, 38.7327722222222))
result.append(GetMeas(7, 'TEST_07', 44.4106166666667, 38.7633277777778))
result.append(GetMeas(8, 'TEST_08', 44.3846138888889, 38.7533722222222))
result.append(GetMeas(9, 'TEST_09', 44.3416583333333, 38.735175))
return result
# получить измеритель (имя, номер, х-коорд картинки и у-коорд картинки) из широты и долготы
def GetMeas(_number, _name, _lan, _lon):
if _lan <= min_lan or _lan >= max_lan:
print("MeasUnit named {} have not current lan ({})".format(_name, _lan))
return None
if _lon <= min_lon or _lon >= max_lon:
print("MeasUnit named {} have not current lon ({})".format(_name, _lon))
return None
lan_delta = _lan - base_lan
lon_delta = _lon - base_lon
y_delta = lan_delta * lenght_lan
x_delta = lon_delta * lenght_lon
my = y_delta // base_pixel_len
mx = x_delta // base_pixel_len
result = dict(number = _number, name = _name, x = abs(mx), y = abs(my))
return result
# Получить осадки по значению dbZ
def GetPrecByDBZ_2(_dbz):
result = 0
if _dbz == 0 or _dbz > 127:
return result
step1 = (_dbz - 32) / 10
step2 = 10 ** step1
step3 = step2 / 200
step4 = step3 ** 0.625
result = step4
return result
# Сгенерировать полигон по набору геокоординат
def GeneratePolygons(_meas_list, _number, _name):
# Максимальные значения координат Х и У для полигона
max_x = 0
max_y = 0
min_x = 256
min_y = 256
#Временный полигон
tmp_pol = []
# Перебрать измерители последовательно и сформировать полигон как набор пар (х, у) плюс данные о границах полигона (прямоугольных)
for imeas in _meas_list:
mx =imeas["x"]
my = imeas["y"]
# Ищем прямоугольные границы полигона
if mx > max_x:
max_x = mx
if my > max_y:
max_y = my
if mx < min_x:
min_x = mx
if my < min_y:
min_y = my
tmp_pol.append((mx, my))
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)
result["pol"] = tmp_pol
return result
# Получить "обрезанную" матрицу по полигону
def GetCuttedMatrix(_image, _mpolygon):
matrix = _mpolygon["pol"]
max_x = int(_mpolygon["max_x"])
max_y = int(_mpolygon["max_y"])
min_x = int(_mpolygon["min_x"])
min_y = int(_mpolygon["min_y"])
mask = np.zeros(_image.shape, dtype=np.uint8)
roi_corners = np.array([matrix], dtype=np.int32)
channel_count = _image.shape[2] # i.e. 3 or 4 depending on your image
ignore_mask_color = (255,)*channel_count
cv2.fillPoly(mask, roi_corners, ignore_mask_color)
masked_image = cv2.bitwise_and(_image, mask)
masked_image = masked_image[min_y:max_y, min_x:max_x]
return masked_image
# Получаем все файлы из директории с сохранёнными изображениями
png_files = os.listdir(png_path)
print(png_files)
print("Lan border = {} - {}".format(min_lan, max_lan))
print("Lon border = {} - {}".format(min_lon, max_lon))
# Сформировать массив "матрица картинки-время" (время из названия файла)
store = []
for png_f in png_files:
dt_value = png_f.replace('dj_286m_', '').replace('.png', '')
dt_value = int(dt_value)
dt_value = datetime.datetime.fromtimestamp(dt_value)
date_diff = datetime.timedelta(hours=2)
dt_value = dt_value + date_diff
file_data = imread(png_path + '\\' + png_f)
st_unit = dict(
datetime = dt_value,
matrix = file_data
)
store.append(st_unit)
# Генерируем тестовые измерители
prec_meas = GenerateMeasurements()
# Формируем данные
main_data = ""
################################################################
# TEST - генерация обрезанных файлов
main_pol = GeneratePolygons([prec_meas[0], prec_meas[3], prec_meas[4], prec_meas[5], prec_meas[6]], 1, "Verh")
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")
pol_store = []
pol_store.append(main_pol)
cutted_store = []
'''
for m_image in store:
image = m_image["matrix"]
masked_image = GetCuttedMatrix(image, main_pol)
path_to_save = "d:\\PYTHON\\tests\\test1\\cutted\\{name}_{dt}.png".format(name = main_pol["name"], dt = m_image["datetime"].timestamp())
#cv2.imwrite(path_to_save, masked_image)
cutted_store.append(masked_image)
'''
################################################################
# Последниё интервал расчёта
last_datetime = store[0]["datetime"]
# Дельта (служебная) между интервалами расчёта
dt = datetime.timedelta(minutes=10)
# Пробегаемся по всем картинкам в хранилище
for prec_data in store:
# Формируем локальные переменные для цикла
lmatrix = prec_data["matrix"]
ldatetime = prec_data["datetime"]
date_diff = ldatetime - last_datetime
local_data = ""
# Фиксим (пустой строкой) промежутки между измерениями, если таковые имеются
while date_diff.seconds >= 1200:
local_data = ""
last_datetime = last_datetime + dt
local_data += last_datetime.__str__() + str_limiter
main_data += local_data + "\n"
date_diff = ldatetime - last_datetime
# Формируем для каждого полигона осадки, согласно его прямоугольным координатам относительно картинки
local_data = ""
local_data += ldatetime.__str__() + str_limiter
for pol in pol_store:
masked_image = GetCuttedMatrix(lmatrix, pol)
sum_prec = 0
for yy in masked_image:
for xx in yy:
lm_value = xx[0]
m_prec = GetPrecByDBZ_2(lm_value)
sum_prec += m_prec
local_data += sum_prec.__str__() + str_limiter
# Вываливаем данные
main_data += local_data + "\n"
last_datetime = ldatetime
# Заменяем временные разделители и прочие символы для правильного отобраежния в Эксель
main_data = main_data.replace("||", "\t")
main_data = main_data.replace(".", ",")
# Пишем результат в текстовый файл
f = open('result.txt', 'w')
f.write(main_data)
f.close()
"""
1. Для каждого измерителя ищем разницу в широте и долготе лот базовых координат
1.1 Проверяем на выход за предельные значения
2. По здначениям дельты и длинам градусов ищем разницу в метрах
3. По разнице в метрах и базовому размеру пикселя ищем нужный квадрат как количество целых делений дельты в метрах на базовую длину градуса
"""

650 Bytes

943 Bytes

This diff could not be displayed because it is too large.
import urllib.request
import json
import os
import datetime
from imageio import imread
import cv2
import numpy as np
import loca_data
import duamel_model
import matplotlib.pyplot as plt
import sher_duam_class
png_path = r"d:\PYTHON\tests\test1\png"
lenght_lan = 79497.3714882
lenght_lon = 111162.6
base_pixel_len = 152.8740566
str_limiter = '||'
d1plan_g = base_pixel_len / lenght_lan
d1plon_g = base_pixel_len / lenght_lon
x286lon = 38.72287
x286lan = 44.417242
base_lon = x286lon - (128 * d1plon_g)
min_lon = x286lon - (128 * d1plon_g)
max_lon = x286lon + (128 * d1plon_g)
base_lan = x286lan + (128 * d1plan_g)
min_lan = x286lan - (128 * d1plan_g)
max_lan = x286lan + (128 * d1plan_g)
pol_store = []
prec_meas = []
'''
duamel = duamel_model.DumlRiverModel(_k_n=1.0, _k_korr=25.0, _res_add_val=20.0, _dmi_up_per=1.0, _dmi_down_per=20.0)
duamelk1 = duamel_model.DumlRiverModel(_k_n=1.65, _k_korr=25.0, _res_add_val=25.0, _dmi_up_per=0.00001, _dmi_down_per=20.0)
flow_rate = duamel_model.CatchmentArea(_capacity=22.2, _in_filter=1.0, _out_filter=0.09)
flow_rate1 = duamel_model.CatchmentArea(_capacity=100.0, _in_filter=2.0, _out_filter=0.09)
level_calc = duamel_model.RiverCrossSection(_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)
sher_duam = sher_duam_class.TestSherDuamel(_k_up=0.7, _k_down=25.0, _k_multy=120.0, _k_addit=40.0, _zero_level=2.20)
'''
duamel = duamel_model.DumlRiverModel(_k_n = 1.0, _k_korr = 15.0, _res_add_val = 20.0, _dmi_up_per = 0.1, _dmi_down_per = 40.0)
duamel1 = duamel_model.DumlRiverModel()
flow_rate = duamel_model.CatchmentArea(_capacity = 50, _in_filter = 5.0, _out_filter = 0.045)
flow_rate1 = duamel_model.CatchmentArea()
level_calc = duamel_model.RiverCrossSection()
level_calc1 = duamel_model.RiverCrossSection()
sher_duam = sher_duam_class.TestSherDuamel()
sher_duam1 = sher_duam_class.TestSherDuamel()
# Генерировать измерители всех типов
def GenerateMeasurements():
# Точки для полигонов
result = []
all_result = []
# Получение координат полигона водосбора Джубги
pcs = loca_data.GetGeoCoordPolygon()
# Последняя запись - для отбрасывания дублей пикселей
p_last = dict(x = -1.0, y = 0.0)
# Получаем список точек полигона
for pc in pcs:
p = GetMeas(pc[0], pc[1], pc[2], pc[3])
if p_last['x'] == -1.0:
p_last['x'] = p['x']
p_last['y'] = p['y']
all_result.append(p)
else:
if p_last['x'] != p['x'] and p_last['y'] != p['y']:
all_result.append(p)
p_last['x'] = p['x']
p_last['y'] = p['y']
result.append(GetMeas(0, 'TEST_00', x286lan, x286lon))
result.append(GetMeas(1, 'TEST_01', 44.3251277777778, 38.6788694444444))
result.append(GetMeas(2, 'TEST_02', 44.3727555555556, 38.7005))
result.append(GetMeas(3, 'TEST_03', 44.4186305555556, 38.6651361111111))
result.append(GetMeas(4, 'TEST_04', 44.4545888888889, 38.6328638888889))
result.append(GetMeas(5, 'TEST_05', 44.4508222222222, 38.6833333333333))
result.append(GetMeas(6, 'TEST_06', 44.4329277777778, 38.7327722222222))
result.append(GetMeas(7, 'TEST_07', 44.4106166666667, 38.7633277777778))
result.append(GetMeas(8, 'TEST_08', 44.3846138888889, 38.7533722222222))
result.append(GetMeas(9, 'TEST_09', 44.3416583333333, 38.735175))
prec_meas.append(GetMeas(5, 'X286|s0_d0', x286lan+0, x286lon-0))
pol_store.append(GeneratePolygons(all_result, 0, "All"))
#pol_store.append(GeneratePolygons([result[0], result[3], result[4], result[5], result[6]], 1, "Verh"))
#pol_store.append(GeneratePolygons([result[0], result[6], result[7], result[8], result[9], result[1], result[2]], 2, "Nige_Polkovnichego"))
return
# получить измеритель (имя, номер, х-коорд картинки и у-коорд картинки) из широты и долготы
def GetMeas(_number, _name, _lan, _lon):
if _lan <= min_lan or _lan >= max_lan:
print("MeasUnit named {} have not current lan ({})".format(_name, _lan))
return None
if _lon <= min_lon or _lon >= max_lon:
print("MeasUnit named {} have not current lon ({})".format(_name, _lon))
return None
lan_delta = _lan - base_lan
lon_delta = _lon - base_lon
y_delta = lan_delta * lenght_lan
x_delta = lon_delta * lenght_lon
my = y_delta // base_pixel_len
mx = x_delta // base_pixel_len
result = dict(number = _number, name = _name, x = abs(mx), y = abs(my))
return result
# Получить осадки по значению dbZ
def GetPrecByDBZ_2(_dbz):
result = 0
if _dbz == 0 or _dbz > 127:
return result
step1 = (_dbz - 32) / 10
step2 = 10 ** step1
step3 = step2 / 200
step4 = step3 ** 0.625
result = step4
return result
# Сгенерировать полигон по набору геокоординат
def GeneratePolygons(_meas_list, _number, _name):
# Максимальные значения координат Х и У для полигона
max_x = 0
max_y = 0
min_x = 256
min_y = 256
#Временный полигон
tmp_pol = []
# Перебрать измерители последовательно и сформировать полигон как набор пар (х, у) плюс данные о границах полигона (прямоугольных)
for imeas in _meas_list:
mx =imeas["x"]
my = imeas["y"]
# Ищем прямоугольные границы полигона
if mx > max_x:
max_x = mx
if my > max_y:
max_y = my
if mx < min_x:
min_x = mx
if my < min_y:
min_y = my
tmp_pol.append((mx, my))
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)
result["pol"] = tmp_pol
return result
# Получить "обрезанную" матрицу по полигону
def GetCuttedMatrix(_image, _mpolygon):
matrix = _mpolygon["pol"]
max_x = int(_mpolygon["max_x"])
max_y = int(_mpolygon["max_y"])
min_x = int(_mpolygon["min_x"])
min_y = int(_mpolygon["min_y"])
mask = np.zeros(_image.shape, dtype=np.uint8)
roi_corners = np.array([matrix], dtype=np.int32)
channel_count = _image.shape[2] # i.e. 3 or 4 depending on your image
ignore_mask_color = (255,)*channel_count
cv2.fillPoly(mask, roi_corners, ignore_mask_color)
masked_image = cv2.bitwise_and(_image, mask)
masked_image = masked_image[min_y:max_y, min_x:max_x]
return masked_image
# Получаем все файлы из директории с сохранёнными изображениями
png_files = os.listdir(png_path)
print(png_files)
print("Lan border = {} - {}".format(min_lan, max_lan))
print("Lon border = {} - {}".format(min_lon, max_lon))
# Сформировать массив "матрица картинки-время" (время из названия файла)
store = []
for png_f in png_files:
dt_value = png_f.replace('dj_286m_', '').replace('.png', '')
dt_value = int(dt_value)
dt_value = datetime.datetime.fromtimestamp(dt_value)
date_diff = datetime.timedelta(hours=0)
dt_value = dt_value + date_diff
file_data = imread(png_path + '\\' + png_f)
st_unit = dict(
datetime = dt_value,
matrix = file_data
)
store.append(st_unit)
# Генерируем измерители
GenerateMeasurements()
# Формируем данные
main_data = "Дата||АГК-286М||АГК-34||РАД-286М||RAD286(cor)||Сумма ВСЕГО||Сумма ВСЕГО(кор)||Сумма ВСЕГО ОБ||Сумма ВСЕГО ОБ(кор)||Flow||Duamel||DuamLevel||\n"
# Последниё интервал расчёта
last_datetime = store[0]["datetime"]
# Дельта (служебная) между интервалами расчёта
dt = datetime.timedelta(minutes=10)
# Интервал времени
datetime_min = datetime.datetime(2020, 1, 29, 22, 50, 0)
datetime_max = datetime.datetime(2020, 2, 4, 15, 40, 0)
# Реальные 286М и 34
real286 = loca_data.GetPrec286M()
real34 = loca_data.GetLevel34()
dtcounter = -1
# Для графиков
mas_x = [] #time
mas_real = [] #real water level
mas_prec = [] #real prec
mas_vol = [] #calc water volume
mas_vol1 = [] #calc water volume (corr)
mas_vol_k = [] #calc volume with reserv k
mas_vol1_k = [] #calc volume with reserv k (corr)
mas_duam = [] #duamel water level
mas_duam1 = [] #duamel water level (корр)
mas_sher_duam = [] #дюамель от шержукова
mas_sher_duam1 = [] #дюамель от шержукова (корр)
mas_wvol = [] #water volume
reserv_volume_koef = 1.0
reserv_volume_koef_corr = 1.0
# Пробегаемся по всем датам в хранилище реальных осадков
for rdata_key in real286.keys():
dtcounter = dtcounter + 1
mas_x.append(dtcounter)
koef_multy_re_d_rad = 1
koef_addit_re_m_rad = 0
prec_data = None
lmatrix = None
ldatetime = rdata_key
print("{}\t{}\t{}".format(ldatetime, reserv_volume_koef, reserv_volume_koef_corr))
local_data = ""
local_data += ldatetime.__str__() + str_limiter
# 0. Осадки реальные
real_prec = real286[rdata_key]
local_data += real_prec.__str__() + str_limiter
# 0.1 Уровень реальный
real_level = real34[rdata_key]
local_data += real_level.__str__() + str_limiter
mas_real.append(real_level)
for imgmatrix in store:
if imgmatrix["datetime"] == rdata_key:
lmatrix = imgmatrix["matrix"]
if lmatrix is None:
local_data += "0||0||0||0||"
rain_corr = real_prec
vol_water = real_prec * reserv_volume_koef
vol_water_corr = real_prec * reserv_volume_koef_corr
mas_vol.append(0.0)
mas_vol1.append(0.0)
mas_vol_k.append(vol_water)
mas_vol1_k.append(vol_water_corr)
rain = vol_water * 0.0000099471691 * 8
rain_corr = vol_water_corr * 0.0000099471691 * 8
flow = flow_rate.calc_surface_flow(rain_corr)
flow1 = flow_rate1.calc_surface_flow(rain_corr)
duam_value = duamel.model_step(dtcounter, flow)
duam_value1 = duamel1.model_step(dtcounter, flow1)
wlevel = level_calc.bs_water_level(duam_value)
wlevel1 = level_calc.bs_water_level(duam_value1)
mas_duam.append(wlevel)
mas_duam1.append(wlevel1)
test_sher_level = sher_duam.CalculateLevel(flow, dtcounter)
test_sher_level1 = sher_duam.CalculateLevel(flow1, dtcounter)
mas_sher_duam.append(test_sher_level)
mas_sher_duam1.append(test_sher_level1)
mas_wvol.append(0.0)
local_data += flow.__str__() + str_limiter
local_data += duam_value.__str__() + str_limiter
local_data += duam_value.__str__() + str_limiter
local_data += wlevel.__str__() + str_limiter
main_data += local_data + "\n"
continue
# 1. Расчёт осадков по координатам
# Формируем для каждого измерителя оасдки в точке, согласно его прямоугольным координатам относительно картинки
mes = prec_meas[0]
y = int(mes["y"])
x = int(mes["x"])
value = lmatrix[y][x][0]
dmrl_prec = GetPrecByDBZ_2(value)
dmrl_prec = dmrl_prec / 6
local_data += dmrl_prec.__str__() + str_limiter
# 1.1 Считаем коэффициенты
if dmrl_prec > 0 and real_prec > 0:
koef_multy_re_d_rad = real_prec / dmrl_prec
koef_addit_re_m_rad = 0
elif dmrl_prec == 0 and real_prec > 0:
koef_multy_re_d_rad = 1
koef_addit_re_m_rad = real_prec - dmrl_prec
elif dmrl_prec > 0 and real_prec == 0:
koef_multy_re_d_rad = 1
koef_addit_re_m_rad = 0
# 1.2 Считаем осадки после корректировки
dmrl_prec_cor = (dmrl_prec * koef_multy_re_d_rad) + koef_addit_re_m_rad
local_data += dmrl_prec_cor.__str__() + str_limiter
# 2. Расчет площадей и осадков на площадях
for pol in pol_store:
masked_image = GetCuttedMatrix(lmatrix, pol)
sum_prec = 0
sum_squere = 0
sum_prec_cor = 0
vol_water = 0
vol_water_cor = 0
for yy in masked_image:
for xx in yy:
lm_value = xx[0]
m_prec = GetPrecByDBZ_2(lm_value)
m_prec = m_prec / 6
if m_prec > 0:
sum_squere += 1
sum_prec += m_prec
m_prec_cor = ((m_prec * koef_multy_re_d_rad) + koef_addit_re_m_rad)
sum_prec_cor = sum_prec_cor + m_prec_cor
vol_local = base_pixel_len * base_pixel_len * 1/1000 * m_prec
vol_water += vol_local
vol_local_cor = base_pixel_len * base_pixel_len * 1/1000 * m_prec_cor
vol_water_cor += vol_local_cor
mas_vol.append(vol_water)
mas_vol1.append(vol_water_cor)
mas_vol_k.append(vol_water)
mas_vol1_k.append(vol_water_cor)
#расчет резервных коэффициентов
tmp_reserv_volume_koef = 0
tmp_reserv_volume_koef_corr = 0
if real_prec != 0:
tmp_reserv_volume_koef = vol_water / real_prec
tmp_reserv_volume_koef_corr = vol_water_cor / real_prec
date_diff = rdata_key - datetime_min
if date_diff.seconds == 0:
reserv_volume_koef = tmp_reserv_volume_koef
reserv_volume_koef_corr = tmp_reserv_volume_koef_corr
else:
per_num = date_diff.seconds / 600
tmp_mult = ((reserv_volume_koef * per_num) + tmp_reserv_volume_koef) / (per_num + 1)
tmp_mult_corr = ((reserv_volume_koef * per_num) + reserv_volume_koef_corr) / (per_num + 1)
reserv_volume_koef = tmp_mult
reserv_volume_koef_corr = tmp_mult_corr
local_data += sum_prec.__str__() + str_limiter
local_data += sum_prec_cor.__str__() + str_limiter
local_data += vol_water.__str__() + str_limiter
local_data += vol_water_cor.__str__() + str_limiter
rain = vol_water * 0.0000099471691 * 8
rain_corr = vol_water_cor * 0.0000099471691 * 8
mas_wvol.append(rain_corr)
flow = flow_rate.calc_surface_flow(rain)
flow1 = flow_rate1.calc_surface_flow(rain_corr)
duam_value = duamel.model_step(dtcounter, flow)
duam_valk1 = duamel1.model_step(dtcounter, flow1)
wlevel = level_calc.bs_water_level(duam_value)
wlevel1 = level_calc.bs_water_level(duam_valk1)
test_sher_level = sher_duam.CalculateLevel(flow, dtcounter)
test_sher_level1 = sher_duam.CalculateLevel(flow1, dtcounter)
mas_duam.append(wlevel)
mas_duam1.append(wlevel1)
mas_sher_duam.append(test_sher_level)
mas_sher_duam1.append(test_sher_level1)
local_data += flow.__str__() + str_limiter
local_data += duam_value.__str__() + str_limiter
local_data += wlevel.__str__() + str_limiter
local_data += wlevel1.__str__() + str_limiter
# Вываливаем данные
main_data += local_data + "\n"
# Заменяем временные разделители и прочие символы для правильного отобраежния в Эксель
main_data = main_data.replace("||", "\t")
# Пишем результат в текстовый файл
f = open('result.txt', 'w')
f.write(main_data)
f.close()
fig, ax = plt.subplots()
#ax.plot(mas_x, mas_real, label = 'AGK-34')
ax.plot(mas_x, mas_vol, label = 'VOL')
ax.plot(mas_x, mas_vol1, label = 'VOL_C')
ax.plot(mas_x, mas_vol, label = 'VOL_K')
ax.plot(mas_x, mas_vol, label = 'VOL_C_K')
#ax.plot(mas_x, mas_duam, label = 'DUAM')
#ax.plot(mas_x, mas_duam1, label = 'DUAM_corr')
#ax.plot(mas_x, mas_sher_duam, label = 'SHER_DUAM')
#ax.plot(mas_x, mas_sher_duam1, label = 'SHER_DUAM_corr')
ax.legend()
plt.show()
"""
1. Для каждого измерителя ищем разницу в широте и долготе лот базовых координат
1.1 Проверяем на выход за предельные значения
2. По здначениям дельты и длинам градусов ищем разницу в метрах
3. По разнице в метрах и базовому размеру пикселя ищем нужный квадрат как количество целых делений дельты в метрах на базовую длину градуса
"""
Проект "Треугольные осадки"
I ЭТАП - ОТРАБОТКА ОБЩЕГО МАТЕМАТИЧСКОГО РЕШЕНИЯ
. Задать три точки с координатами Р1, Р2, Р3 - (х1у1с1, х2у2с2, х3у3с3)
. Определить "площадь решения" в виде плоского рисунка
. Нарисовать треугольник Т по трём точкам Рх
. Определить формулу плоскости ПЛ по трем точкам Рх
. Определить формулу принадлежности произвольной точки Рн треугольнику Р1Р2Р3
. Пройтись по каждой точке Рпр площади решения и определить, принадлежит ли выбранная точка треугольнику Т
. Если принадлежит - то определить цвет по формуле ПЛ и установить его на площади решения
. Сохранить результат в виде рисунка png
import numpy as np
import matplotlib.pyplot as plt
import datetime
import os.path
import loca_data
import math
'''
# реализация метода ньютона-рафсона
def newton_raphson(study_func, target_val, start_x, max_iter_count=10, max_err=1e-3, delta_x=1e-6):
# начальное значение аргумента
finded_x = start_x
# Цикл нахождения решения
iter_count = 0
err_y = 1e20
# цикл поиска решения
while (iter_count <= max_iter_count) and (abs(err_y) > max_err):
# Вычисляем производную dy/dx в точке x
# dfdx в принципе нам может быть известен аналитически, и в таком случае
# предпочтительно использовать аналитическое выражение.
dfdx = (study_func(finded_x + 0.5 * delta_x) - study_func(finded_x - 0.5 * delta_x)) / delta_x
# Находим приращение по y
err_y = study_func(finded_x) - target_val
# и по x
err_x = err_y / dfdx
# Получаем новое решение
finded_x = finded_x - err_x
# меняем к - во итераций
iter_count += 1
return finded_x
'''
'''
x = np.random.randint(low=1, high=11, size=50)
y = x + np.random.randint(1, 5, size=x.size)
data = np.column_stack((x, y))
fig, (ax1, ax2) = plt.subplots(
nrows=1, ncols=2,
figsize=(8, 4)
)
ax1.scatter(x=x, y=y, marker='o', c='r', edgecolor='b')
ax1.set_title('Scatter: $x$ versus $y$')
ax1.set_xlabel('$x$')
ax1.set_ylabel('$y$')
ax2.hist(
data, bins=np.arange(data.min(), data.max()),
label=('x', 'y')
)
ax2.legend(loc=(0.65, 0.8))
ax2.set_title('Frequencies of $x$ and $y$')
ax2.yaxis.tick_right()
x = [0,1,2,3,4,5]
y1 = [1,1,2,2,4,0]
y2 = [5,1,3,6,4,10]
y3 = [0,1,3,2,6,8]
fig, ax = plt.subplots()
ax.plot(x, y1, label = 'TEST1')
ax.plot(x, y2, label = 'ЕУЫЕ2')
ax.plot(x, y3, label = 'tmp3')
ax.legend()
#fig.set_figheight(5)
#fig.set_figwidth(8)
plt.show()
class Test():
def __init__(self, _id, _data1, _data2):
self.id = _id
self.data1 = _data1
self.data2 = _data2
res = {
1:Test(1, "12345", "54321"),
2:Test(2, "11111", "aaaaa"),
3:Test(3, "ddddd", "qwqwqw")
}
for val in res.keys():
print(res[val].data1)
datetime_min = datetime.datetime(2020, 1, 29, 22, 50, 0)
timestamp = int(datetime_min.timestamp())
png_path = r"d:\PYTHON\tests\test1\png"
file_path = "{}\\dj_286m_{}.png".format(png_path, timestamp)
print(file_path)
print(os.path.exists(file_path))
zero = -1.06
class RiverCrossSection():
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):
# параметры трапеции
self._zero_wlevel = _zero_bsv
self._trap_a = _left_slope # ширина левого склона трапеции русла
self._trap_b = _bottom # ширина дна трапеции русла
self._trap_c = _right_slope # ширина правого склона трапеции русла
self._trap_d = _max_h # высота трапеции русла
if self._trap_d >= 0:
self._trap_leftCtg = self._trap_a / self._trap_d # котангенс левого угла трапеции русла
self._trap_rightCtg = self._trap_c / self._trap_d # котангенс правого угла трапеции русла
else:
self._trap_leftCtg = 0 # котангенс левого угла трапеции русла
self._trap_rightCtg = 0 # котангенс правого угла трапеции русла
self._i_rb_part = _i_bias # уклон русла
self._n_rb_part = _n_roughness # шероховатость русла
# площадь сечения (м^2)
def f_trap_area(self, h):
return self._trap_b * h + (self._trap_leftCtg + self._trap_rightCtg) * h * h / 2
# смоченный периметр (м)
def f_trap_perimetr(self, h):
return self._trap_b + \
math.sqrt(self._trap_leftCtg ** 2 + 1) * h + \
math.sqrt(self._trap_rightCtg ** 2 + 1) * h
# гидрологический радиус
def f_hydro_r(self, h):
return self.f_trap_area(h) / self.f_trap_perimetr(h)
# скорость потока (м/с)
def f_flow_speed(self, h):
return self.f_hydro_r(h)**(2./3) * math.sqrt(self._i_rb_part) / self._n_rb_part
# расход воды (м^3/с)
def f_flow_rate(self, h):
if h <= 0.:
return 0.
return self.f_trap_area(h) * self.f_flow_speed(h)
# расход воды (м^3/с)
def f_flow_rate_by_bs_h(self, bs_h):
return self.f_flow_rate(bs_h - self._zero_wlevel)
# уровень воды (м), определяемый по расходу воды (м^3/с)
def high_by_flow_rate(self, flow_rate):
if flow_rate <= 0.:
return 0.
return newton_raphson(self.f_flow_rate, flow_rate, 1.)
# уровень воды (м), определяемый по расходу воды (м^3/с) по балтийской системе высот
def bs_water_level(self, flow_rate):
return self.high_by_flow_rate(flow_rate) + self._zero_wlevel
real34 = loca_data.GetLevel34()
get_flow = RiverCrossSection()
min_flow = 100
max_flow = 0
for key in real34.keys():
real_level = real34[key]
#real_level = real_level - zero
flow = get_flow.f_flow_rate_by_bs_h(real_level)
if flow < min_flow:
min_flow = flow
if flow > max_flow:
max_flow = flow
print("{}-{}".format(real_level, flow))
print("{}-{}".format(min_flow, max_flow))
datetime_min = datetime.datetime(2020, 1, 29, 22, 50, 0)
datetime_max = datetime.datetime(2020, 2, 1, 0, 0, 0)
date_diff = datetime_max - datetime_min
print(date_diff.seconds / 600)
'''
first_dic = dict(a = "123", b = 1.9, c = 567)
first_dic1 = dict(a = "124", b = 2.9, c = 1567)
first_dic2 = dict(a = "125", b = 3.9, c = 2567)
first_dic3 = dict(a = "126", b = 4.9, c = 3567)
first_dic35 = None
first_dic4 = dict(a = "127", b = 5.9, c = 4567)
secon_dic = dict(aa = "qwe", bb = 0.0, cc = 3214)
def GetAllValues(_dict_with_pref):
key_store = []
value_store = []
for dwp_k in _dict_with_pref.keys():
dwp = _dict_with_pref[dwp_k]
if dwp is not None:
for k in dwp.keys():
key_store.append(str(dwp_k) + "_" + str(k))
value_store.append(str(dwp[k]))
return key_store, value_store
ks, vs = GetAllValues(dict(fd = first_dic, sd = secon_dic))
#print("\t".join(ks))
#print("\t".join(vs))
#timestamp = int(_datetime.timestamp())
#file_path = r"\png\dj_286m_{}.png".format(timestamp)
#print(os.listdir('.\\png\\'))
files = os.listdir('.\\png\\')
for f in files:
ts = int(f.replace("dj_286m_","").replace(".png",""))
dt = datetime.datetime.fromtimestamp(ts)
print(dt)
# 2. Ищем файл и формируем матрицу
#if not os.path.exists(os.path.abspath(os.curdir) + file_path):
# return result