本系列文章是根据Shapely
官方文档翻译整理,学习任何一个Python第三方库,其官方文档都是最好的学习资料。相比网络搜索得到的一些资料,官方文档是权威的一手资料,其内容全面、准确可靠。通过官方文档入手,能够保证学习认知不会有大偏差。在学习完官方文档后,可以在寻找其他资料进一步学习。
点击“阅读原文”或者直接访问下方链接,查看翻译整理的“Shapely 2.0.0 中文文档”。
https://www.mizhushare.com/docs/shapely-2-0-0-%e4%b8%ad%e6%96%87%e6%96%87%e6%a1%a3/
-
可以通过百度网盘获取,需要在本地配置代码运行环境:
链接:https://pan.baidu.com/s/1iWGGhB4kra9V7bUj-CWR0w?pwd=mnsj
提取码:mnsj
-
前往GitHub详情页面,单击 code 按钮,选择Download ZIP选项:
https://github.com/returu/Shapely
Shapely
中标准的二元谓词通过方法实现。这些谓词评估拓扑与集合论的关系。所有的方法都以另一个几何对象作为参数,并返回True
或 False
。方法 |
说明 |
object.__eq__(other) |
如果两个对象的几何类型相同,并且两个对象的坐标精确匹配,则返回True |
object.equals(other) |
如果对象的集合边界、内部和外部与另一个对象的边界、内部和外部重合,则返回True 。 |
object.equals_exact(other, tolerance) |
如果对象在所有点上都近似等于另一个对象,并达到指定的小数位精度,则返回True 。 |
object.contains(other) |
如果对象的内部包含另外一个对象的边界和内部,并且两个对象的边界不接触,则返回True 。 |
object.covers(other) |
如果对象的内部包含另外一个对象的边界和内部,则返回True 。这与object.contains(other) 相似,只是其没有对内部点的要求。 |
object.covered_by(other) |
如果对象的每一个点都是其他对象的内部或边界上的一个点,则返回真。其等价于other.covers(object) 。 |
object.crosses(other) |
如果该对象的内部与另一对象的内部相交但不包含该对象,并且相交处的维数其本身或另一个维度,则返回True 。 |
object.disjoint(other) |
如果该对象的边界和内部与其他对象不相交(按集合论,没有任何同样的元素),则返回True 。 |
object.intersects(other) |
如果该对象的边界或内部以任何方式与另一对象的边界或内部相交,则返回True 。 |
object.overlaps(other) |
如果几何要素有一个以上但不是所有的共同点,具有相同的维数,并且几何要素内部的交点与几何要素本身具有相同的维数,则返回True 。 |
object.touches(other) |
如果对象的边界仅与另一个对象的边界相交,并且不与另一个对象的其他部分相交,则返回True 。 |
object.within(other) |
如果对象的边界和内部仅与另一个对象的内部相交(而不是其边界或外部),则返回True 。 |
需要注意的是,在少数情况下,结果可能不是人们所期望的那样。这就需要多练习和查看官方文档。
-
object.__eq__(other)
:
如果两个对象的几何类型相同,并且两个对象的坐标精确匹配,则返回True
。
1>>> a = LineString([(0, 0), (1, 1)])
2>>> b = LineString([(0.0, 0.0), (1.0, 1.0)])
3
4>>> a.__eq__(b)
5True
-
object.equals(other):
如果对象的集合边界、内部和外部与另一个对象的边界、内部和外部重合,则返回True
。
因为传递给对象构造函数的坐标可以有多种方式,因此这可能会对用户造成一个潜在的 “麻烦”。
例如,相同的线,可以用不同的方式构造。
1>>> a = LineString([(0, 0), (1, 1)])
2>>> b = LineString([(0, 0), (0.5, 0.5), (1, 1)])
3>>> c = LineString([(0, 0), (0, 0), (1, 1)])
4
5>>> a.equals(b)
6True
7>>> a == b
8False
9
10>>> b.equals(c)
11True
12>>> b == c
13False
-
object.equals_exact(other, tolerance):
如果对象在所有点上都近似等于另一个对象,并达到指定的小数位精度,则返回True
。
1>>> a = LineString([(0, 0), (1, 1)])
2>>> b = LineString([(0.1, 0.1), (1.1, 1.1)])
3
4>>> a.equals_exact(b , tolerance=0.2)
5True
6
7>>> a.equals_exact(b , tolerance=0.1)
8False
-
object.contains(other):
如果对象的内部包含另外一个对象的边界和内部,并且两个对象的边界不接触,则返回True
,适用于所有类型,并且与后续介绍的within()
相反。表达式a.contains(b) == b.within(a)
结果总为True
。
1>>> LineString([(0, 0), (1, 1)]).contains(Point(0.5, 0.5))
2True
3
4>>> Point(0.5, 0.5).within(LineString([(0, 0), (1, 1)]))
5True
需要注意的是,一条线的端点是其边界的一部分,因此不包含在内。
1>>> LineString([(0, 0), (1, 1)]).contains(Point(1.0, 1.0))
2False
另外,二元谓词可以直接作为filter()
或itertools.ifilter()
的谓词使用。
1>>> line = LineString([(0, 0), (1, 1)])
2>>> line
3<LINESTRING (0 0, 1 1)>
4
5>>> contained = list(filter(line.contains, [Point(), Point(1.0, 1.0) , Point(0.5, 0.5)]))
6>>> contained
7[<POINT (0.5 0.5)>]
-
object.covers(other):
如果对象的内部包含另外一个对象的边界和内部,则返回True
。这与object.contains(other)
相似,只是其没有对内部点的要求。
1>>> LineString([(0, 0), (1, 1)]).covers(Point(1.0, 1.0))
2True
-
object.covered_by(other):
如果对象的每一个点都是其他对象的内部或边界上的一个点,则返回True
。其等价于other.covers(object)
。
-
object.crosses(other):
如果该对象的内部与另一对象的内部相交但不包含该对象,并且相交处的维数少于其本身或另一个对象的维度,则返回True
。
1>>> LineString([(0, 0), (1, 1)]).crosses(LineString([(0, 1), (1, 0)]))
2True
一条线不跨越它所包含的点。
1>>> LineString([(0, 0), (1, 1)]).crosses(Point(0.5, 0.5))
2False
-
object.disjoint(other):
如果该对象的边界和内部与其他对象不相交(按集合论,没有任何同样的元素),则返回True
,适用于所有类型,可以视为下面介绍的intersects()
的逆向。
1# 点要素
2>>> Point(0, 0).disjoint(Point(1, 1))
3True
4
5# 线要素
6>>> line1 = LineString([(0, 0), (1, 1)])
7>>> line2 = LineString([(0, 2), (2, 0)])
8
9>>> line1.disjoint(line2)
10False
两个线要素的相对关系图如下所示:
-
object.intersects(other):
如果该对象的边界或内部以任何方式与另一对象的边界或内部相交,则返回True。换句话说,如果几何对象有任何边界或内部的共同点,它们就会相交。
以上面的线要素为例,两者disjoint
结果为False
,intersects
结果为True
。
1>>> line1 = LineString([(0, 0), (1, 1)])
2>>> line2 = LineString([(0, 2), (2, 0)])
3
4>>> line1.intersects(line2)
5True
-
object.overlaps(other):
如果几何要素有一个以上但不是所有的共同点,具有相同的维数,并且几何要素内部的交点与几何要素本身具有相同的维数,则返回True
。
也就是两个对象的intersects()
为Ture
,但是相互之间的within()
为False
,则返回Ture
。
1>>> line1 = LineString([(0, 0), (1, 1)])
2>>> line2 = LineString([(0, 1), (1, 0)])
3>>> line3 = LineString([(0, 1), (0.5, 0.5), (1, 1), (2, 0)])
4
5>>> line1.overlaps(line2)
6False
7
8>>> line1.overlaps(line3)
9True
三个线要素的相对关系图如下所示:
-
object.touches(other):
如果对象的边界仅与另一个对象的边界相交,并且不与另一个对象的其他部分相交,则返回True
。
重叠(Overlapping )的要素不会接触(touch),这是另一个潜在的 “麻烦”。例如,下面的线条在(1,1)处接触(touches
)和相交(intersects
),但不重叠(overlaps
)。
1>>> a = LineString([(0, 0), (1, 1)])
2>>> b = LineString([(1, 1), (2, 2)])
3>>> a.touches(b) , a.intersects(b) , a.overlaps(b)
4(True, True, False)
-
object.within(other):
如果对象的边界和内部仅与另一个对象的内部相交(而不是其边界或外部),则返回True
。适用于所有类型,是contains()
的逆运算。
在sorted()
键中使用,within()
使对象的空间排序变得容易。假设我们有4个要素:一个被一个多边形所包含的点,而这个多边形本身又被另一个多边形所包含,以及一个没有被包含的自由点。
1>>> a = Point(2, 2)
2>>> b = Polygon([[1, 1], [1, 3], [3, 3], [3, 1]])
3>>> c = Polygon([[0, 0], [0, 4], [4, 4], [4, 0]])
4>>> d = Point(-1, -1)
这些对象的相对关系图若下所示:
然后将这些对象收集到一个列表中:
1>>> features = [c, a, d, b, c]
我们倾向于将其排序为 [d, c, c, b, a]
的反向包含顺序。正如在 Python Sorting HowTo 中所解释的,我们可以定义一个键函数,对每个列表元素进行操作,并返回一个值进行比较。我们的键函数将是一个包装类,它使用 Shapely
的二进制 within()
谓词实现 。
1>>> class Within:
2... def __init__(self , o):
3... self.o = o
4... def __lt__(self , other): # python内置的比较运算符 __lt__(self, other) --> 定义小于号的行为:x < y 调用 x.__lt__(y)
5... return self.o.within(other.o)
6...
正如Python Sorting HowTo 中所解释的,小于的比较是保证在排序中使用的。这就是我们要依靠的空间排序。在特征d和c上试了一下,我们发现它是有效的。
1>>> Within(d) < Within(c) # 调用 d.__lt__(c) --> d.within(c)
2False
它也在功能列表上工作,产生我们想要的顺序。
1>>> [d, c, c, b, a] == sorted(features, key=Within, reverse=True)
2True
END
本篇文章来源于微信公众号: 码农设计师