英文:
Shapely Polygon centroid negative values
问题
I am using Shapely to find the coordinates of the centroid of a polygon with all positive points. But I am getting negative values of the coordinates of the centroid.
from shapely.geometry import Polygon
poly = Polygon([[263.84, 256.29], [268.6, 253.5], [269.57, 260.44], [277.2, 253.1], [278.94, 252.69], [278.56, 260.02], [278.76, 275.95], [288.99, 269.15], [263.84, 256.29]])
centroid = poly.centroid
print(centroid.x, centroid.y)
The answer that I get is -120.68 and -311.53, which is weird! I would appreciate some inputs on this.
英文:
I am using Shapely to find the coordinates of the centroid of a polygon with all positive points. But I am getting negative values of the coordinates of the centroid.
from shapely.geometry import Polygon
poly = Polygon([[263.84, 256.29], [268.6, 253.5], [269.57, 260.44], [277.2, 253.1], [278.94, 252.69], [278.56, 260.02], [278.76, 275.95], [288.99, 269.15], [263.84, 256.29]])
centroid = poly.centroid
print(centroid.x, centroid.y)
The answer that I get is -120.68 and -311.53, which is weird! I would appreciate some inputs on this.
答案1
得分: 3
这个多边形是无效的:它具有自交点,大多数空间操作对无效输入会产生错误的结果。
您可以使用Shapely的is_valid
几何属性来检查几何体是否有效(示例在下面的脚本中)。
您还可以要求Shapely将其转换为有效形状,使用shapely.make_valid()
函数。在这种情况下,它将多边形转换为3个部分的多多边形,并将得到一个合理的质心(脚本中也有示例)。
我还直接检查了底层支持Shapely的C++库geos的结果,结果相同。
geosop -a "POLYGON ((263.84 256.29, 268.6 253.5, 269.57 260.44, 277.2 253.1, 278.94 252.69, 278.56 260.02, 278.76 275.95, 288.99 269.15, 263.84 256.29))" centroid -f wkt
POINT (-120.6802662207054 -311.5377745805696)
绘制多边形的脚本
from matplotlib import pyplot as plt
from shapely.geometry import Polygon
import shapely.plotting
poly = Polygon(
[
[263.84, 256.29],
[268.6, 253.5],
[269.57, 260.44],
[277.2, 253.1],
[278.94, 252.69],
[278.56, 260.02],
[278.76, 275.95],
[288.99, 269.15],
[263.84, 256.29],
]
)
centroid = poly.centroid
print(poly.wkt)
print(f"centroid: {centroid.x}, {centroid.y}")
print(f"poly.is_valid: {poly.is_valid}")
shapely.plotting.plot_polygon(poly)
plt.show()
poly_valid = shapely.make_valid(poly)
centroid_valid = poly_valid.centroid
print(poly_valid.wkt)
print(f"centroid_valid: {centroid_valid.x}, {centroid_valid.y}")
print(f"poly_valid.is_valid: {poly_valid.is_valid}")
shapely.plotting.plot_polygon(poly_valid)
plt.show()
脚本输出
POLYGON ((263.84 256.29, 268.6 253.5, 269.57 260.44, 277.2 253.1, 278.94 252.69, 278.56 260.02, 278.76 275.95, 288.99 269.15, 263.84 256.29))
centroid: -120.6802662207054 -311.5377745805696
poly.is_valid: False
MULTIPOLYGON (((269.38634635224486 259.12602441709225, 268.6 253.5, 263.84 256.29, 269.38634635224486 259.12602441709225)), ((277.2 253.1, 270.39810534205236 259.6433691729143, 278.6079766371281 263.84133914725516, 278.56 260.02, 278.94 252.69, 277.2 253.1)), ((269.38634635224486 259.12602441709225, 269.57 260.44, 270.39810534205236 259.6433691729143, 269.38634635224486 259.12602441709225)), ((278.6079766371281 263.84133914725516, 278.76 275.95, 288.99 269.15, 278.6079766371281 263.84133914725516)))
centroid_valid: 277.9350361986902 263.6861518747837
poly_valid.is_valid: True
绘制多边形(原始的无效版本)
绘制多多边形(有效版本)
英文:
This polygon is invalid: it has self intersections, and most spatial operations will give wrong results for invalid input.
You can check if a geometry is valid using shapely with the is_valid
geometry property (example in script below).
You can also ask shapely to make it valid using the shapely.make_valid()
function. In this case this will convert the polygon to a multipolygon of 3 pieces and will result in a reasonable centroid (also example in script below).
I also checked the result of geos, the c++ library that powers shapely under the hood, directly, and this is the same.
geosop -a "POLYGON ((263.84 256.29, 268.6 253.5, 269.57 260.44, 277.2 253.1, 278.94 252.69, 278.56 260.02, 278.76 275.95, 288.99 269.15, 263.84 256.29))" centroid -f wkt
POINT (-120.6802662207054 -311.5377745805696)
Script that plots the polygon
from matplotlib import pyplot as plt
from shapely.geometry import Polygon
import shapely.plotting
poly = Polygon(
[
[263.84, 256.29],
[268.6, 253.5],
[269.57, 260.44],
[277.2, 253.1],
[278.94, 252.69],
[278.56, 260.02],
[278.76, 275.95],
[288.99, 269.15],
[263.84, 256.29],
]
)
centroid = poly.centroid
print(poly.wkt)
print(f"centroid: {centroid.x}, {centroid.y}")
print(f"poly.is_valid: {poly.is_valid}")
shapely.plotting.plot_polygon(poly)
plt.show()
poly_valid = shapely.make_valid(poly)
centroid_valid = poly_valid.centroid
print(poly_valid.wkt)
print(f"centroid_valid: {centroid_valid.x}, {centroid_valid.y}")
print(f"poly_valid.is_valid: {poly_valid.is_valid}")
shapely.plotting.plot_polygon(poly_valid)
plt.show()
Script output
POLYGON ((263.84 256.29, 268.6 253.5, 269.57 260.44, 277.2 253.1, 278.94 252.69, 278.56 260.02, 278.76 275.95, 288.99 269.15, 263.84 256.29))
centroid: -120.6802662207054 -311.5377745805696
poly.is_valid: False
MULTIPOLYGON (((269.38634635224486 259.12602441709225, 268.6 253.5, 263.84 256.29, 269.38634635224486 259.12602441709225)), ((277.2 253.1, 270.39810534205236 259.6433691729143, 278.6079766371281 263.84133914725516, 278.56 260.02, 278.94 252.69, 277.2 253.1)), ((269.38634635224486 259.12602441709225, 269.57 260.44, 270.39810534205236 259.6433691729143, 269.38634635224486 259.12602441709225)), ((278.6079766371281 263.84133914725516, 278.76 275.95, 288.99 269.15, 278.6079766371281 263.84133914725516)))
centroid_valid: 277.9350361986902 263.6861518747837
poly_valid.is_valid: True
Plot polygon (original, invalid version)
Plot multipolygon (valid version)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论