get_polygon_square.py 4.82 KB
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)'''