Shapely 多边形质心负值

huangapple go评论64阅读模式
英文:

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.

Shapely 多边形质心负值

答案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

绘制多边形(原始的无效版本)

Shapely 多边形质心负值

绘制多多边形(有效版本)

Shapely 多边形质心负值

英文:

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)

Shapely 多边形质心负值

Plot multipolygon (valid version)

Shapely 多边形质心负值

huangapple
  • 本文由 发表于 2023年5月6日 18:01:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76188279.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定