Spaces:
Sleeping
Sleeping
import numpy as np | |
from collections import defaultdict | |
import shapely | |
import shapely.wkt | |
from shapely.geometry import LineString, MultiLineString, Polygon, Point, MultiPoint | |
from shapely.prepared import prep | |
def list_duplicates(seq): | |
tally = defaultdict(list) | |
for i,item in enumerate(seq): | |
tally[item].append(i) | |
return ((key,locs) for key,locs in tally.items() if len(locs)>1) | |
# clean wall and wkt | |
# wall = ((IOOI)) | |
# wkt = 'POLYGON ((x0 y0, x1 y1, x2 y2, x3 y3, x0 y0))' | |
def read_wall_wkt(wall, wkt): | |
# wall to list | |
# print('wall:', wall) | |
wall_l = wall.split("), (")[0] | |
wall_l = wall_l.split("((")[1] | |
wall_l = wall_l.split("))")[0] | |
wall_c = [*wall_l] | |
#clean wkt | |
wkt_l = wkt.split("((")[1] | |
wkt_l = wkt_l.split("))")[0] | |
wkt_l = wkt_l.split("), (") | |
if len(wkt_l) == 1: | |
wkt_c = wkt | |
else: | |
wkt_c = "POLYGON ((" + wkt_l[0] + "))" | |
wkt_c = wkt_c.split("((")[1] | |
wkt_c = wkt_c.split("))")[0] | |
wkt_c = wkt_c.split(", ") | |
# remove duplicate point | |
num_p = len(wkt_c) - 1 | |
remove_index = [] | |
for dup in sorted(list_duplicates(wkt_c)): | |
dup_index = dup[1] | |
if 0 in dup_index and num_p in dup_index and len(dup_index) == 2: | |
pass | |
elif 0 in dup_index and num_p in dup_index and len(dup_index) > 2: | |
dup_index_num = len(dup_index)-1 | |
for j in range(1, dup_index_num): | |
ri = dup_index[j] | |
remove_index.append(ri) | |
else: | |
dup_index_num = len(dup_index)-1 | |
for j in range(dup_index_num): | |
ri = dup_index[j] | |
remove_index.append(ri) | |
re_num = len(remove_index) | |
rest_num = len(wkt_c) - re_num - 1 | |
wall_num = len(wall_c) | |
wkt_wall = len(wkt_c) - 1 | |
wall_f = [] | |
wkt_f = [] | |
for p in range(len(wkt_c)): | |
if p not in remove_index: | |
wkt_u = wkt_c[p] | |
wkt_f.append(wkt_u) | |
if wall_num == wkt_wall: | |
if p < (len(wkt_c)-1): | |
wall_u = wall_c[p] | |
wall_f.append(wall_u) | |
if wall_num == rest_num: | |
wall_ff = wall_c | |
else: | |
wall_ff = wall_f | |
wkt_f = ", ".join(wkt_f) | |
wkt_f = "POLYGON ((" + wkt_f + "))" | |
# print('wall_ff:', wall_ff) | |
# print("wkt_c:", len(wkt_c)) | |
# print("remove_index:", remove_index) | |
# print("wall_num:", wall_num) | |
# print("rest_num:", rest_num) | |
return wall_ff, wkt_f | |
def clean_geometry(wall, wkt): | |
# load geometry | |
# print('wall:', wall) | |
geo = shapely.wkt.loads(wkt) | |
# move to (0,0) | |
geo_centroid = geo.centroid | |
translation_vector = (-geo_centroid.x, -geo_centroid.y) | |
moved_coords = [(x + translation_vector[0], y + translation_vector[1]) for x, y in geo.exterior.coords] | |
moved_geo = shapely.wkt.loads('POLYGON ((' + ', '.join([f'{x} {y}' for x, y in moved_coords]) + '))') | |
# if counterclockwise | |
if moved_geo.exterior.is_ccw: | |
geo_ccw = moved_geo | |
wall_ccw = wall | |
else: | |
geo_ccw = shapely.geometry.polygon.orient(moved_geo, 1) | |
walltypes = len(list(set(wall))) | |
if walltypes == 1: | |
wall_ccw = wall | |
else: | |
wall_ccw = wall[::-1] | |
# print('wall_ccw:', wall_ccw) | |
# ccw_geo | |
coor_ccw = geo_ccw.exterior.coords | |
coor_ccw = list(coor_ccw) | |
coor_ccw = coor_ccw[:-1] | |
coor_ccw_num = len(coor_ccw) | |
coor_ccw_xpy_lst = [] | |
for i in range(coor_ccw_num): | |
coor_ccw_x = coor_ccw[i][0] | |
coor_ccw_y = coor_ccw[i][1] | |
coor_ccw_xpy = coor_ccw_x + coor_ccw_y | |
coor_ccw_xpy_lst.append(coor_ccw_xpy) | |
coor_ccw_xpy_min_index = np.array(coor_ccw_xpy_lst).argmin() | |
coor_ccw_sort_index = [] | |
for i in range(len(coor_ccw_xpy_lst)): | |
index_max = len(coor_ccw_xpy_lst) - 1 - coor_ccw_xpy_min_index | |
if i <= index_max: | |
sort_index = coor_ccw_xpy_min_index + i | |
else: | |
sort_index = i - len(coor_ccw_xpy_lst) + coor_ccw_xpy_min_index | |
coor_ccw_sort_index.append(sort_index) | |
# print(coor_ccw_sort_index) | |
# print(len(coor_ccw_sort_index)) | |
# print(wall_ccw) | |
# print(len(wall_ccw)) | |
coor_sort_lst = [] | |
wall_sort_lst = [] | |
for i in range(len(coor_ccw_sort_index)): | |
sort_index = coor_ccw_sort_index[i] | |
sort_coor = coor_ccw[sort_index] | |
sort_wall = wall_ccw[sort_index] | |
coor_sort_lst.append(sort_coor) | |
wall_sort_lst.append(sort_wall) | |
geo_s = Polygon(coor_sort_lst) | |
wall_s = wall_sort_lst | |
return wall_s, geo_s | |
def segments(polyline): | |
return list(map(LineString, zip(polyline.coords[:-1], polyline.coords[1:]))) | |
def points4cv(x, y, xmin_abs, ymin_abs, scale): | |
points = [] | |
for j in range(len(x)): | |
xp =x[j] | |
yp =y[j] | |
xp = (xp + xmin_abs +1) * scale | |
yp = (yp + ymin_abs +1) * scale | |
p = [int(xp), int(yp)] | |
points.append(p) | |
p_4_cv = np.array(points) | |
return p_4_cv | |
def gridpoints(apa_geo, size): | |
latmin, lonmin, latmax, lonmax = apa_geo.bounds | |
prep_moved_apa_geo = prep(apa_geo) | |
# construct a rectangular mesh | |
gp = [] | |
for lat in np.arange(latmin, latmax, size): | |
for lon in np.arange(lonmin, lonmax, size): | |
gp.append(Point((round(lat,5), round(lon,5)))) | |
gps = prep_moved_apa_geo.contains(gp) | |
gpf = [i for indx,i in enumerate(gp) if gps[indx] == True] | |
grid_points = MultiPoint(gpf) | |
return grid_points | |
def exterior_wall(apa_line, apa_wall): | |
apa_wall_O = [i for indx,i in enumerate(segments(apa_line)) if apa_wall[indx] == "O"] | |
apa_wall_O = MultiLineString(apa_wall_O) | |
return apa_wall_O | |
def geo_coor(apa_geo): | |
apa_coor = apa_geo.exterior.coords | |
apa_coor = list(apa_coor) | |
return apa_coor | |