我试图弄清楚如何仅使用多边形的角坐标来缩小多边形。例如,如果我有以下带角[(0, 0), (0, 100), (20, 100), (30, 60), (40, 100), (60, 100), (60, 0), (40, 10), (40, 40), (20, 40), (20, 10)]
的形状,则形状如下所示:
如果我将这个多边形缩小一些宽度和高度因子,我想找到角坐标。例如,如果我想将其宽度缩小 10%,将高度缩小 20%,那么这可以显示为如下所示:
我试图cv2.resize()
通过调整大小后无法获得角落来做到这一点。我一直在尝试寻找一种用于调整多边形大小或缩小多边形大小的算法,但找不到有关如何执行此操作的任何信息。是否存在用于执行此类操作的任何算法或软件包?
据我所知,您正在从 postgis搜索ST_Buffer的功能,但使用不同的因素。不幸的是,这不容易实现(请参阅qgis-stack 中的一个问题有关更多信息,)。
但是,如果使用相同的 x 和 y 因子(或作为更复杂算法的开始)已经有帮助,那么您可以:
在 python 中可以访问 ST_Buffer 函数的一个库是匀称的。
(如果您需要更多地理数据特定功率geoalchemy2可能是更好的选择。在这种情况下要注意 crs/srid 的变化)
from shapely import geometry
import matplotlib.pyplot as plt
# your variables
coords = [(0, 0), (0, 100), (20, 100), (30, 60), (40, 100), (60, 100), (60, 0), (40, 10), (40, 40), (20, 40), (20, 10)]
lines = [[coords[i-1], coords[i]] for i in range(len(coords))]
# your factor of 10%
# Note: with 20% the polygon becomes a multi-polygon, so a loop for plotting would be needed.
factor = 0.1
# code from nathan
xs = [i[0] for i in coords]
ys = [i[1] for i in coords]
x_center = 0.5 * min(xs) + 0.5 * max(xs)
y_center = 0.5 * min(ys) + 0.5 * max(ys)
min_corner = geometry.Point(min(xs), min(ys))
max_corner = geometry.Point(max(xs), max(ys))
center = geometry.Point(x_center, y_center)
shrink_distance = center.distance(min_corner)*factor
assert abs(shrink_distance - center.distance(max_corner)) < 0.0001
my_polygon = geometry.Polygon(coords)
my_polygon_shrunken = my_polygon.buffer(-shrink_distance)
x, y = my_polygon.exterior.xy
plt.plot(x,y)
x, y = my_polygon_shrunken.exterior.xy
plt.plot(x,y)
# to net let the image be distorted along the axis
plt.axis('equal')
plt.show()
Run Code Online (Sandbox Code Playgroud)
我已经在加利福尼亚州的 1200 多个现实生活中的建筑多边形上测试了这个解决方案,它的效果非常好。
还有一件事是,同样的方法也同样适用于扩大多边形。可以按原样使用以下方法:
def shrink_or_swell_shapely_polygon(my_polygon, factor=0.10, swell=False):
''' returns the shapely polygon which is smaller or bigger by passed factor.
If swell = True , then it returns bigger polygon, else smaller '''
from shapely import geometry
#my_polygon = mask2poly['geometry'][120]
shrink_factor = 0.10 #Shrink by 10%
xs = list(my_polygon.exterior.coords.xy[0])
ys = list(my_polygon.exterior.coords.xy[1])
x_center = 0.5 * min(xs) + 0.5 * max(xs)
y_center = 0.5 * min(ys) + 0.5 * max(ys)
min_corner = geometry.Point(min(xs), min(ys))
max_corner = geometry.Point(max(xs), max(ys))
center = geometry.Point(x_center, y_center)
shrink_distance = center.distance(min_corner)*0.10
if swell:
my_polygon_resized = my_polygon.buffer(shrink_distance) #expand
else:
my_polygon_resized = my_polygon.buffer(-shrink_distance) #shrink
#visualize for debugging
#x, y = my_polygon.exterior.xy
#plt.plot(x,y)
#x, y = my_polygon_shrunken.exterior.xy
#plt.plot(x,y)
## to net let the image be distorted along the axis
#plt.axis('equal')
#plt.show()
return my_polygon_resized
Run Code Online (Sandbox Code Playgroud)
我误读了这个问题,我留下了答案,因为它可能对某人有帮助,但我意识到最终的输出不是所需的输出
要在收缩后获得多边形的新坐标,您可以将所有坐标(位置向量)与收缩因子相乘,如下所示:
x_shrink = 0.1
y_shrink = 0.2
coords = [(0, 0), (0, 100), (20, 100), (30, 60), (40, 100), (60, 100), (60, 0), (40, 10), (40, 40), (20, 40), (20, 10)]
xs = [i[0] for i in coords]
ys = [i[1] for i in coords]
# simplistic way of calculating a center of the graph, you can choose your own system
x_center = 0.5 * min(xs) + 0.5 * max(xs)
y_center = 0.5 * min(ys) + 0.5 * max(ys)
# shrink figure
new_xs = [(i - x_center) * (1 - x_shrink) + x_center for i in xs]
new_ys = [(i - y_center) * (1 - y_shrink) + y_center for i in ys]
# create list of new coordinates
new_coords = zip(new_xs, new_ys)
Run Code Online (Sandbox Code Playgroud)
这输出以下内容(蓝色是原始的,绿色是缩小的多边形)