
File name
Commit message
Commit date
2023-06-14
File name
Commit message
Commit date
import numpy as np
from itertools import compress
from geopandas import points_from_xy
from scipy.spatial import Voronoi, voronoi_plot_2d
from scipy.spatial.distance import cdist
def extract(lst, i):
return [item[i] for item in lst]
def extract_coord(lst):
return [item.coords[:] for item in lst]
def coord_lister(geom):
coords = list(geom.exterior.coords)
return (coords)
# def vor_ver(furthest_pnt, i):
# return furthest_pnt[i].vertices
def get_lecc(shp):
"""
This functions finds largest enclosed circle center from shape file.
It is used for optimizing text placement and size using Voronoi diagram in this project
Arguments:
shp -- shape object
returns -
lecc : which is largest enclosed circle
lecc_dist : which is radius of largest enclosed circle
"""
num_area = len(shp)
polygons_coord = shp.geometry.apply(coord_lister)
furthest_pnt = [None] * num_area
voronoi_ori = [None] * num_area
for i, points in enumerate(polygons_coord):
voronoi_ori[i] = Voronoi(points, furthest_site=False)
furthest_pnt[i] = voronoi_ori[i].vertices
voronoi_nodes = [None] * num_area
leccc = [None] * num_area
# get voronoi nodes that is inside the polygon.
for i in range(num_area):
voronoi_nodes[i] = points_from_xy(extract(furthest_pnt[i], 0), extract(furthest_pnt[i], 1))
voronoi_nodes_if_inside = shp.geometry[i].contains(voronoi_nodes[i])
voronoi_nodes[i] = list(compress(voronoi_nodes[i], voronoi_nodes_if_inside))
leccc[i] = [item for sublist in extract_coord(voronoi_nodes[i]) for item in sublist]
dist = [None] * num_area
for i, points in enumerate(polygons_coord):
# explaining this mess : I need to get the LEC from candidate I got before, but the thing is,
# cdist from scipy only accepts exact dimension with array like object,
# which means I need to explicitly set the shape of ndarray, convert list of points into ndarray
dist[i] = cdist(np.array([list(item) for item in points]), np.array([list(item) for item in leccc[i]]))
lecc = [None] * num_area
lecc_dist = [None] * num_area
for i in range(num_area):
voronoi_nodes_dist = [None] * (dist[i].shape[1])
for j in range(dist[i].shape[1]):
voronoi_nodes_dist[j] = min(dist[i][:, j])
lecc_ind = np.argmax(voronoi_nodes_dist)
lecc[i] = leccc[i][lecc_ind]
lecc_dist[i] = np.max(voronoi_nodes_dist)
return lecc, lecc_dist