Shapely geometry objects can be stored in NumPy arrays using the object dtype. In general, one could create such an array from a list of geometries as follows:
Shapely几何对象可以使用对象dtype存储在NumPy数组中。一般来说,我们可以从一个几何对象的列表中创建这样一个数组,如下所示。
>>> from shapely.geometry import Point
>>> arr = np.array([Point(0, 0), Point(1, 1), Point(2, 2)])
>>> arr
array([<shapely.geometry.point.Point object at 0x7fb798407cd0>,
<shapely.geometry.point.Point object at 0x7fb7982831c0>,
<shapely.geometry.point.Point object at 0x7fb798283b80>],
dtype=object)
The above works for point geometries, but because in Shapely 1.x, some geometry types are sequence-like (see above), NumPy can try to “unpack” them when creating an array. Therefore, for more robust creation of a NumPy array from a list of geometries, it’s generally recommended to this in a two-step way (first creating an empty array and then filling it):
上述方法适用于点状几何对象,但由于在Shapely 1.x中,一些几何体类型是类似sequence的(见上文),NumPy在创建数组时可以尝试 “解包 “它们。因此,为了更稳健地从几何对象列表中创建一个NumPy数组,一般建议采用两步法(先创建一个空数组,然后再填充)。
geoms = [Point(0, 0), Point(1, 1), Point(2, 2)]
arr = np.empty(len(geoms), dtype="object")
arr[:] = geoms
This code snippet results in the same array as the example above, and works for all geometry types and Shapely/NumPy versions.
这段代码的结果与上面的例子相同,并且适用于所有的几何对象类型和Shapely/NumPy版本。
However, starting with Shapely 1.8, the above code will show deprecation warnings that cannot be avoided (depending on the geometry type, NumPy tries to access the array interface of the objects or check if an object is iterable or has a length, and those operations are all deprecated now. The end result is still correct, but the warnings appear nonetheless). Specifically in this case, it is fine to ignore those warnings (and the only way to make them go away):
然而,从Shapely 1.8开始,上面的代码会出现无法避免的弃用警告(根据几何对象类型,NumPy试图访问对象的数组接口,或者检查对象是否可迭代或有长度,而这些操作现在都被弃用了。最后的结果仍然是正确的,但警告还是出现了)。特别是在这种情况下,忽略这些警告就可以了(也是让它们消失的唯一方法)。
import warnings
from shapely.errors import ShapelyDeprecationWarning
geoms = [Point(0, 0), Point(1, 1), Point(2, 2)]
arr = np.empty(len(geoms), dtype="object")
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=ShapelyDeprecationWarning)
arr[:] = geoms
In Shapely 2.0, the geometry objects will no longer be sequence like and those deprecation warnings will be removed (and thus the filterwarnings
will no longer be necessary), and creation of NumPy arrays will generally be more robust.
在Shapely 2.0中,几何对象将不再像sequence类型那样,那些弃用警告将被删除(因此过滤警告将不再需要),而且NumPy数组的创建一般会更加稳健。
If you maintain code that depends on Shapely, and you want to have it work with multiple versions of Shapely, the above code snippet provides a context manager that can be copied into your project:
如果你维护的代码依赖于Shapely,并且你想让它在多个版本的Shapely中工作,上面的代码片段提供了一个上下文管理器,可以复制到你的项目中。
import contextlib
import shapely
import warnings
from packaging import version # https://packaging.pypa.io/
SHAPELY_GE_20 = version.parse(shapely.__version__) >= version.parse("2.0a1")
try:
from shapely.errors import ShapelyDeprecationWarning as shapely_warning
except ImportError:
shapely_warning = None
if shapely_warning is not None and not SHAPELY_GE_20:
@contextlib.contextmanager
def ignore_shapely2_warnings():
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=shapely_warning)
yield
else:
@contextlib.contextmanager
def ignore_shapely2_warnings():
yield
This can then be used when creating NumPy arrays (be careful to only use it for this specific purpose, and not generally suppress those warnings):
然后可以在创建NumPy数组时使用(注意只用于这一特定目的,而不是一般地禁止那些警告):
geoms = [...]
arr = np.empty(len(geoms), dtype="object")
with ignore_shapely2_warnings():
arr[:] = geoms