>>> from env_helper import info; info()
页面更新时间: 2023-04-15 20:02:57
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-7-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

7.3. 谓词

谓词,用来描述或判定客体性质、特征或者客体之间关系的词项。根据《现代汉语》的定义,汉语的体词包括名词,数词,量词;汉语的谓词包括动词和形容词。

7.3.1. 一元谓词

标准的一元谓词被作为只读属性实施。

所有的例子将会被显示。

一般的一元谓词

object.has_z: 如果要素不仅有x和y,还有z,则返回为‘True’。

>>> from shapely.geometry import Point
>>> Point(0, 0).has_z
>>> Point(0, 0, 0).has_z
True

object.is_ccw : 如果坐标是逆时针的,返回为真 (用正面标记的面积来框定区域)。这种方法仅适用于线性对象。

LinearRing([(1,0), (1,1), (0,0)]).is_ccw

非预期方向的环可以像这样反转:

>>> from shapely.geometry import LinearRing
>>> ring = LinearRing([(0,0), (1,1), (1,0)])
>>> ring.is_ccw
>>> ring.coords = list(ring.coords)[::-1]
>>> ring.is_ccw
/usr/lib/python3/dist-packages/shapely/geometry/base.py:250: ShapelyDeprecationWarning: Setting the 'coords' to mutate a Geometry in place is deprecated, and will not be possible any more in Shapely 2.0
  super().__setattr__(name, value)
True

object.is_empty

如果要素的内部与边界(在点集方面)和空集相配合,则返回为真。

>>> from shapely.geometry import Point
>>> Point().is_empty
>>> Point(0, 0).is_empty
False

注意:

operator模块的attrgetter()函数的帮助,一元谓词例如 is_empty能够轻松地用作 filter()或者itertools.ifilter()内建的谓词。

>>> from operator import attrgetter
>>> empties = filter(attrgetter('is_empty'), [Point(), Point(0, 0)])
>>> # len(empties)

object.is_ring: 如果要素被闭合了,则返回为真。 一个关闭的要素的边界算是空集。

>>> from shapely.geometry import LineString
>>> LineString([(0, 0), (1, 1), (1, -1)]).is_ring
False
>>> from shapely.geometry import LinearRing
>>> LinearRing([(0, 0), (1, 1), (1, -1)]).is_ring
True

这属性适用于线(LineString)和线环(LinearRing)实例, 但是对于其它是毫无意义的。

object.is_simple : 如果要素不是自相交的,则返回为真。

>>> from shapely.geometry import LineString
>>> LineString([(0, 0), (1, 1), (1, -1), (0, 1)]).is_simple
False

Shapely完全支持线环(LineStrings)的操作。

object.is_valid: 如果一个要素是有效的,返回真。

一个有效的线环不能跨越它本身或者在一个单点接触。 一个有效的多边形可能拥有任何重叠的外部环或内部环。 一个有效的多元多边形可能不会搜集任何重叠的多边形。 基于无效要素进行的操作可能会失败。

>>> from shapely.geometry import MultiPolygon
>>> MultiPolygon([Point(0, 0).buffer(2.0), Point(1, 1).buffer(2.0)]).is_valid
False

以上2点接近,缓冲区操作产生的多边形将会重叠。(在下一节解释)

注意:

is_valid谓词可以用来写一个验证修饰, 可以确保唯一有效的对象从构造函数中返回。

7.3.2. 二元谓词

在Shapely中,标准的二元谓词通过Python的实现方法。这些谓词评估拓扑与集合论之间的关系。 在少数情况下,结果可能不是人们从不同假设中预期的那样。

所有二元谓词(方法)将另一个几何对象作为参数,且返回为真或为假。

object.almost_equals( other[, decimal=6])

如果对象的点在指定位精度上约等于另外对象的所有点, 则返回为真。

object.contains(other)

如果对象的内部包含另外一个对象的边界和内部, 并且两个对象的边界一点儿也不接触,则返回为真。

这种谓词适用于所有类型,并且逆于 a.contains(b) == b.within(a)的表达,常常被评定为真。

>>> from shapely.geometry import Point, LineString
>>> coords = [(0, 0), (1, 1)]
>>> LineString(coords).contains(Point(0.5, 0.5))
True
>>> from shapely.geometry import LineString
>>> Point(0.5, 0.5).within(LineString(coords))
True

线的端点是边界的一部分, 因此不包含。例如:

>>> LineString(coords).contains(Point(1.0, 1.0))
False

注意:

二元谓词可以直接用作filter()itertools.ifilter()的谓词。例如:

>>> line = LineString(coords)
>>> contained = filter(line.contains, [Point(), Point(0.5, 0.5)])
>>> # len(contained)

object.crosses(other)

如果对象的内部与另外对象的内部相交但并不包含它,并且相交的维数少于它本身或另一个维数,则返回为真。

>>> LineString(coords).crosses(LineString([(0, 1), (1, 0)]))
True

一条线不跨越它包含的点。

>>> LineString(coords).crosses(Point(0.5, 0.5))
False

object.disjoint(other)

如果对象的边界和内部与其它对象一点儿也不相交,则返回为真。

>>> Point(0, 0).disjoint(Point(1, 1))
True

这种谓词适用于所有类型并且逆于 intersects().

object.equals(other)

如果对象的集合论的边界、内部和外部与其它重合,则返回为真。

传递给对象构造的是这些集合, 并且决定它们,但是不是这些集的全部。 这对新用户来说是一个潜在的“疑难杂症”。 比如等值线,可以不这样被构造。

>>> from shapely.geometry import LineString
>>> a = LineString([(0, 0), (1, 1)])
>>> b = LineString([(0, 0), (0.5, 0.5), (1, 1)])
>>> c = LineString([(0, 0), (0, 0), (1, 1)])
>>> a.equals(b)
True
>>> b.equals(c)
True

这个谓词不应该被误认为是Python的==或者是构造。

object.intersects(other)

如果对象的边界和内部与其它的以任何形式相交,则返回真。

这个谓词不同于 contains()crosses()equals()touches()within()

object.touches( other)

如果对象的边界仅仅与另一个对象的边界相交,并且不与另一个的任何部分相交,则返回为真。

叠置要素不是touch, 另一个潜在的“疑难杂症”。 例如,下面的线在(1,1)相接触,但是并不重叠。

>>> a = LineString([(0, 0), (1, 1)])
>>> b = LineString([(1, 1), (2, 2)])
>>> a.touches(b)
True

object.within(other)

如果对象的边界和内部仅仅与另一个内部(不是边界或者外部)相交,则返回为真。

这适用于所有的类型并且逆于 contains().

用于sorted()的关键词, within() 使它很容易在空间上进行分类。 比方说,我们有4种定型的要素: 一个被一个多边形包含的点,这个多边形被另一个多边形包含 和一个不被其它点包含的点。

>>> from shapely.geometry import Point
>>> from shapely.geometry import Polygon
>>> a = Point(2, 2)
>>> b = Polygon([[1, 1], [1, 3], [3, 3], [3, 1]])
>>> c = Polygon([[0, 0], [0, 4], [4, 4], [4, 0]])
>>> d = Point(-1, -1)

和列表中收集到的副本

>>> features = [c, a, d, b, c]

列表中,我们更喜欢按照(d, c, c, b, a)的反向遏制秩序。 正如在Python中解释的那样, Sorting HowTo, 我们可以定义一个运行在每一个列表上的关键要素, 返回一个值用于比较。我们的关键要素将是一个封装类 用Shapely的二进制谓词实施。

二进制 within() 谓词。

>>> from shapely.geometry import asShape
>>> class Within(object):
>>>     def __init__(self, o):
>>>         self.o = o
>>>     def __lt__(self, other):
>>>         return self.o.within(other.o)

正如howto所说的,小于比较的在排序中常被使用。 那正是我们空间排序中我们所依靠的东西, within() 和我们反向使用within() contains(). 而不是用contains()的原因。 在要素d和c上试验, 我们看到它工作了。

d > c
>>> Within(d) > Within(c)
False

它对列表上的要素同样有效,并产生我们想要的顺序。

>>> # features = [a,b,c,d]
>>> # sorted(features, key=Within, reverse=True)
>>> [d, c, c, b, a] == sorted(features, key=Within, reverse=True)
True