python - 查找点是否位于多边形的内部或边界上(Python - Shapely)
问题描述
好吧,我需要检查一个点是否在多边形的边界内或位于多边形的边界上,但对于这种特殊情况,我无法让它工作。首先是一些函数和变量:
from matplotlib import pyplot as plt
from shapely.geometry import Polygon,Point,LinearRing,LineString
from math import sqrt
from shapely import affinity
from descartes.patch import PolygonPatch
GM = (sqrt(5)-1.0)/2.0
W = 8.0
H = W*GM
SIZE = (W, H)
BLUE = '#6699cc'
GRAY = '#999999'
DARKGRAY = '#333333'
YELLOW = '#ffcc33'
GREEN = '#339933'
RED = '#ff3333'
BLACK = '#000000'
COLOR_ISVALID = {
True: BLUE,
False: RED,
}
def plot_line(ax, ob, color=GRAY, zorder=1, linewidth=3, alpha=1):
x, y = ob.xy
ax.plot(x, y, color=color, linewidth=linewidth, solid_capstyle='round', zorder=zorder, alpha=alpha)
def plot_coords(ax, ob, color=GRAY, zorder=1, alpha=1):
x, y = ob.xy
ax.plot(x, y, 'o', color=color, zorder=zorder, alpha=alpha)
def color_isvalid(ob, valid=BLUE, invalid=RED):
if ob.is_valid:
return valid
else:
return invalid
def color_issimple(ob, simple=BLUE, complex=YELLOW):
if ob.is_simple:
return simple
else:
return complex
def plot_line_isvalid(ax, ob, **kwargs):
kwargs["color"] = color_isvalid(ob)
plot_line(ax, ob, **kwargs)
def plot_line_issimple(ax, ob, **kwargs):
kwargs["color"] = color_issimple(ob)
plot_line(ax, ob, **kwargs)
def plot_bounds(ax, ob, zorder=1, alpha=1):
x, y = zip(*list((p.x, p.y) for p in ob.boundary))
ax.plot(x, y, 'o', color=BLACK, zorder=zorder, alpha=alpha)
def add_origin(ax, geom, origin):
x, y = xy = affinity.interpret_origin(geom, origin, 2)
ax.plot(x, y, 'o', color=GRAY, zorder=1)
ax.annotate(str(xy), xy=xy, ha='center',
textcoords='offset points', xytext=(0, 8))
def set_limits(ax, x0, xN, y0, yN):
ax.set_xlim(x0, xN)
ax.set_xticks(range(x0, xN+1))
ax.set_ylim(y0, yN)
ax.set_yticks(range(y0, yN+1))
ax.set_aspect("equal")
这是我的代码:
pts_tri = [(23.5, 40.703193977868615), (6.5, 11.258330249197702), (19.650283067421512,12.213053056663625)]
test = (8.258506615, 14.304153051823665)
poly = Polygon(pts_tri)
linearring = LinearRing(list(poly.exterior.coords))
fig = plt.figure(figsize=(10,5))
ax2 = plt.subplot(1,2,1)
for point in pts_tri:
plt.plot(point[0],point[1],'o',color='black')
plot_coords(ax2, poly.exterior)
patch = PolygonPatch(poly, facecolor=color_isvalid(poly), edgecolor=color_isvalid(poly, valid=BLUE), alpha=0.5, zorder=2)
ax2.add_patch(patch)
plt.plot(test[0],test[1],'o', color='red')
plt.show()
print((poly.contains(Point(test))),(poly.touches(Point(test))),linearring.intersects(Point(test)),poly.overlaps(Point(test)))
打印结果为: False False False False
该点正好位于多边形边界,但我能得到的只是 False。我应该怎么办?提前致谢。
解决方案
由于浮点精度问题,Shapely intersects 可能会出现意外行为。如果我圆你的test
观点...
test = (round(8.258506615, 14), round(14.304153051823665, 14))
然后我可以得到
poly.contains(Point(test))
到True
和
poly.intersection(Point(test))
至POINT (8.258506615 14.30415305182366)
更好的方法可能是只检查距离
epsilon = 1e-15
print(Point(test).distance(poly) < epsilon)
>>> True
更多技术解释可以在这里找到
推荐阅读
- javascript - 如何让 CloudFlare 工作人员响应来自用户的传入 HTTP 请求?
- python-3.x - 从 SQLAlchemy 会话对象获取原始 psycopg2 游标对象
- javascript - 我想知道如何通过简单地点击一个 div 我想得到他的 ID
- r - R中多边形的核密度估计
- php - 内部 php 脚本将可靠的电子邮件发送到垃圾邮件 (Outlook)
- ruby-on-rails - Rails:条件子查询 MAX(effective_date)
- google-apps-script - Google 表格 - 构建模板的问题(隐藏/取消隐藏行、列和选项卡)
- dataframe - 自定义数据集和数据加载器
- node.js - 在本地为 Angular 8 应用程序生成 rss.xml 可以正常工作,但不能在 prod 上
- swift - 无法在 Swift 中运行带参数的函数