用shapely判断两个图形的包含相交关系

shapely介绍

shapely是专门做图形计算的包,基本上图形线段,点的判断包里都有,shapely里主要由Point,LineString,Polygon这三类组成,在shapely里点,线,面之间都是可以做判断的,比如说计算点到线段的距离,点到面之间的距离,点与点之间的距离,点是否在一个图形的内部或外部,或边界上,线是否在图形的内部等。。。
特点

  • z轴在实例化对象时可以使用,但图形分析中没有用,所有的操作都在x-y平面完成
  • shapely拥有(点、曲线、面 interior, boundary, exterior)这样的概念
    • 点的内部是一个点、没有边界、所有其他点都是外部
    • 曲线的内部是沿线的无数个电、边界是两个端点、外部是其他所有的点
    • 面的内部是面上的无数个点、边界是一个或多个曲线、外部是其他所有点

shapely安装

我之前的博客已经介绍过shapely的安装,有兴趣的朋友可以去看看。

shapely的导入

from shapely.geometry import  Point, LineString, Polygon

Point、LineString、Polygon的通用属性

object.area   返回对象的面积
object.bounds 返回包含对象的x、y的最大值最小值的元组
object.length 返回对象的长度
object.geom_type 返回图形的类型 字符串
object.distance(other) 返回两个对象的最小距离
object.hausdorff_distance(other) 返回两个对象之间的哈多夫距离
object.representative_point() 返回一个保证在对象上的点

Point对象

point = Point(0, 1)  # 创建点对象,可以是三维的
print(point.area) # 0.0
print(point.length)  # 0.0
print(point.bounds)  # (0.0, 1.0, 0.0, 1.0)
print(point.geom_type)  # Point
print(point.coords)  # <shapely.coords.CoordinateSequence object at 0x000001E64DE38518>
print(point.coords[:])  # [(0.0, 1.0)]
print(list(point.coords))  # [(0.0, 1.0)]
print(point.x, point.y) # 0.0 1.0
0.0
0.0
(0.0, 1.0, 0.0, 1.0)
Point
<shapely.coords.CoordinateSequence object at 0x00000201F7A18518>
[(0.0, 1.0)]
[(0.0, 1.0)]
0.0 1.0

LineString对象

# 可以自己相交
line = LineString([(0, 0), (1, 1)])
print(line.area)  # 0.0
print(line.length)  # 1.4142135623730951
print(line.bounds)  # (0.0, 0.0, 1.0, 1.0)
print(line.geom_type)  # LineString
print(line.coords)  # <shapely.coords.CoordinateSequence object at 0x0000028D59BC0518>
print(line.coords[:], type(line.coords[:]))  # [(0.0, 0.0), (1.0, 1.0)] <class 'list'>
0.0
1.4142135623730951
(0.0, 0.0, 1.0, 1.0)
LineString
<shapely.coords.CoordinateSequence object at 0x0000028D59BC0518>
[(0.0, 0.0), (1.0, 1.0)] <class 'list'>

Polygon对象

# 可以传入两个参数,第一个是有序的外边缘轮廓,第二个是无序的内边缘轮廓,多边形内所有的环形最多只能有一个焦点,否则都是无效的
poly = Polygon([(0, 0), (-1, 1), (2, 1), (3, -2)])
print(poly.area)
print(poly.length)
print(poly.bounds)
x_min, y_min, x_max, y_max = poly.bounds
print(x_min, y_min, x_max, y_max)
print(poly.geom_type)
print(poly.exterior.coords)
print(poly.exterior.coords[:])
print(poly.interiors)
print(poly.interiors[:])

5.0
11.182042498005464
(-1.0, -2.0, 3.0, 1.0)
-1.0 -2.0 3.0 1.0
Polygon
<shapely.coords.CoordinateSequence object at 0x0000018A43B629E8>
[(0.0, 0.0), (-1.0, 1.0), (2.0, 1.0), (3.0, -2.0), (0.0, 0.0)]
<shapely.geometry.polygon.InteriorRingSequence object at 0x0000018A4398DB70>
[]

box对象

from shapely.geometry import box
# box可以穿件矩形多边形,ccw参数选择顺时针或逆时针
b = box(0, 1, 2, 3, ccw=False) # 是以前两个参数作为左下角的点,后两个参数作为右上角的点
print(b.geom_type)
print(b.bounds)
print(b.exterior.coords[:])
# 获取多边形点的顺序
print(sgp.orient(b, sign=1)) # 顺时针
print(sgp.orient(b, sign=-1)) # 逆时针
Polygon
(1.0, 0.0, 2.0, 3.0)
[(1.0, 0.0), (1.0, 3.0), (2.0, 3.0), (2.0, 0.0), (1.0, 0.0)]
POLYGON ((1 0, 2 0, 2 3, 1 3, 1 0))
POLYGON ((1 0, 1 3, 2 3, 2 0, 1 0))

一元判定

# has_z  判断是否有z坐标
p = Point(0, 0)
print(p.has_z)  # False
p = Point(0, 0, 0)
print(p.has_z)  # True

# is_ccw  判断是否是逆时针的
lr = LinearRing([(1, 0), (1, 1), (0, 0)])
print(lr.is_ccw)  # True
lr.coords = list(lr.coords)[::-1]
print(lr.is_ccw)  # False

# is_empty 返回TRUE如果内部和边界都是空
p = Point()
print(p.is_empty)  # True
p = Point(0, 0)
print(p.is_empty)  # False

# is_ring 闭合返回TRUE 
line = LineString([(0, 0), (1, 1), (1, 0)])
print(line.is_ring) # False
line = LineString([(0, 0), (1, 1), (1, 0), (0, 0)])
print(line.is_ring) # True
lr = LinearRing([(0, 0), (1, 1), (1, 0)])
print(lr.is_ring) # True
lr = LinearRing([(0, 0), (1, 1), (1, 0), (0, 0)])
print(lr.is_ring) # True

# is_simple 自己不相交,返回TRUE
line = LineString([(0, 0), (1, 1), (1, -1), (0, 1)])
print(line.is_simple) # False
line = LineString([(0, 0),  (0, 1), (1, 1), (1, 0)])
print(line.is_simple) # True

is_valid
LinearRing 不相交或者只有一个交点是有效的
Polygon 同上
Note:可以写成验证装饰器,根据特定内容判断他是否是有效的

二元判定

object.__eq__(other) # 类型和坐标点相同返回TRUE
object.equals(other)  #boundary, interior, and exterior完全相同返回TRUE
object.almost_equals(other[, decimal=6]) # 近似相等返回TRUE decimal是小数点的位数完全相同
object.contains(other) # other里没有点在object的exterior,且other的interior里至少有一个点在object的interior
object.crosses(other) # object的interior与other的interior相交,且不包含他
object.disjoint(other) # object的interior和boundary 和other的interior和boundary都不想交 返回True
object.intersects(other) # object的interior或者boundary和other的interior或者boundary相交 返回TRUE
object.overlaps(other) # object的interior或者boundary和other的interior或者boundary相交,且不包含他, 返回TRUE
object.touches(other) # other和object至少有一个共同的点,且他们的interior不相交

object.__eq__(other) # 类型和坐标点相同返回TRUE,和左边点顺序有关

object = LineString([(0, 0), (1, 1)])
other = LineString([(0, 0), (1, 1)])
print(object.__eq__(other)) # True
object = Point((0, 0))
other = Point((0, 0))
print(object.__eq__(other)) # True
object = Polygon([(0, 0), (0, 1), (1, 1)])
other = Polygon([(0, 0), (0, 1), (1, 1)])
print(object.__eq__(other)) # True
object = Polygon([(0, 0), (0, 1), (1, 1)])
other = Polygon([(0, 1), (1, 1), (0, 0)])
print(object.equals(other))  # False

object.equals(other) #boundary, interior, and exterior完全相同返回TRUE,和坐标点顺序无关

object = LineString([(0, 0), (1, 1)])
other = LineString([(0, 0), (1, 1)])
print(object.equals(other)) # True
object = Point((0, 0))
other = Point((0, 0))
print(object.equals(other))  # True
object = Polygon([(0, 0), (0, 1), (1, 1)])
other = Polygon([(0, 0), (0, 1), (1, 1)])
print(object.equals(other))  # True
object = Polygon([(0, 0), (0, 1), (1, 1)])
other = Polygon([(0, 1), (1, 1), (0, 0)])
print(object.equals(other))  # True

object.almost_equals(other[, decimal=6]) 近似相等返回TRUE decimal是小数点的位数完全相同,和坐标点的顺序有关

object = LineString([(0, 0), (1, 1)])
other = LineString([(0, 0), (1, 1)])
print(object.almost_equals(other)) # True
object = Point((0, 0))
other = Point((0, 0))
print(object.almost_equals(other)) # True
object = Polygon([(0, 0), (0, 1), (1, 1)])
other = Polygon([(0, 0), (0, 1), (1, 1)])
print(object.almost_equals(other)) # True
object = Polygon([(0, 0), (0, 1), (1, 1)])
other = Polygon([(0, 1), (1, 1), (0, 0)])
print(object.almost_equals(other)) # False

object.contains(other) other里没有点在object的exterior,且other的interior里至少有一个点在object的interior,和坐标点的顺序无关

object = LineString([(0, 0), (1, 1)])
other = LineString([(0, 0), (1, 1)])
print(object.contains(other)) # True
object = Point((0, 0))
other = Point((0, 0))
print(object.contains(other)) # True
object = Polygon([(0, 0), (0, 1), (1, 1)])
other = Polygon([(0, 0), (0, 1), (1, 1)])
print(object.contains(other)) # True
object = Polygon([(0, 0), (0, 1), (1, 1)])
other = Polygon([(0, 1), (1, 2), (0, 0)])
print(object.contains(other)) # False

object.crosses(other) object的interior与other的interior相交,且不包含他,该判断只适用于图形与线之间的判定

object = LineString([(0, 0), (1, 1)])
other = LineString([(0, 0), (1, 1)])
print(object.crosses(other)) # False
object = LineString([(0, 0), (2, 2)])
other = LineString([(0, 0), (1, 1)])
print(object.crosses(other)) # False
object = Point((0, 0))
other = Point((0, 0))
print(object.crosses(other)) # False
object = Polygon([(0, 0), (0, 1), (1, 1)])
other = Polygon([(0, 0), (0, 1), (1, 1)])
print(object.crosses(other)) # False
object = Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])
other = LineString([(0.5, 0.5), (2, 2)])
print(object.crosses(other)) # True
print(other.crosses(object)) # True
object = Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])
other = Polygon([(0.5, 0.5), (0.5, 2), (2, 2), (2, 0.5)])
print(object.crosses(other)) # False
print(other.crosses(object)) # False

object.disjoint(other) object的interior和boundary 和other的interior和boundary都不想交 返回True,完全不相交才返回True,有一个点都不行

object = LineString([(0, 0), (1, 1)])
other = LineString([(0, 0), (1, 1)])
print(object.disjoint(other)) # False
object = LineString([(0, 0), (1, 1)])
other = LineString([(2, 2), (3, 3)])
print(object.disjoint(other)) # True
object = Point((0, 0))
other = Point((1, 1))
print(object.disjoint(other)) # True
object = Polygon([(0, 0), (0, 1), (1, 1)])
other = Polygon([(0, 0), (0, -1), (-1, -1)])
print(object.disjoint(other)) # False,,有一个点相交了,都不想交才是True
object = Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])
other = LineString([(2, 2), (3, 3)])
print(object.disjoint(other)) # True
print(other.disjoint(object)) # True
object = Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])
other = Polygon([(2,2), (2,4), (4,4), (4, 2)])
print(object.disjoint(other)) # True
print(other.disjoint(object)) # True

object.intersects(other) object的interior或者boundary和other的interior或者boundary相交 返回TRUE

object = LineString([(0, 0), (1, 1)])
other = LineString([(0, 0), (1, 1)])
print(object.intersects(other)) # True
object = LineString([(0, 0), (1, 1)])
other = LineString([(1, 1), (0, 0)])
print(object.intersects(other)) # True
object = Point((0, 0))
other = Point((1, 1))
print(object.intersects(other)) # False
object = Polygon([(0, 0), (0, 1), (1, 1)])
other = Polygon([(0, 0), (0, -1), (-1, -1)])
print(object.intersects(other)) # True
object = Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])
other = LineString([(0, 0), (3, 3)])
print(object.intersects(other)) # True
object = Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])
other = Polygon([(2,2), (2,4), (4,4), (4, 2)])
print(object.intersects(other)) # False

object.touches(other) other和object至少有一个共同的点,且他们的interior不相交,也就是说在边界上

object = LineString([(0, 0), (1, 1)])
other = LineString([(1, 1), (2, 2)])
print(object.touches(other)) # True
object = LineString([(0, 0), (1, 1)])
other = Point(0, 0)
print(object.touches(other)) # True
object = Point((0, 0))
other = Point((0, 0))
print(object.touches(other)) # False
object = Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])
other = Point((0, 0))
print(object.touches(other)) # True
object = Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])
other = LineString([(0.1, 0), (0.2, 0)])
print(object.touches(other)) # True
print(other.touches(object)) # True
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值