Shapely: 3次元をドロップする機能を追加します

作成日 2019年05月05日  ·  3コメント  ·  ソース: Toblerity/Shapely

GIS Stack Exchangeには、3Dジオメトリを2Dに変換することに関する古い質問があります。3DWKTを2D ShapelyGeometryに変換します。 この機能はShapelyに含める必要があると思います。たとえば、次のように使用できます。

>>> from shapely.geometry import Polygon
>>> p = Polygon([(0, 0, 0), (1, 0, 0), (1, 1, 0)])
>>> p.wkt
'POLYGON Z ((0 0 0, 1 0 0, 1 1 0, 0 0 0))'
>>> p2 = p.drop_z
>>> p2.wkt
'POLYGON ((0 0, 1 0, 1 1, 0 0))'

回答の1つとドキュメントで、3次元は_幾何解析に影響を与えない_ため、 _この操作は不要_であることがわかりました。 しかし、分割ジオメトリの左側を決定するために独自の関数を実装する場合(これはまだ実装されていません:https://github.com/Toblerity/Shapely/issues/589)、この機能が便利であることがわかりました。

from shapely.geometry import (LinearRing, 
                              LineString, 
                              Polygon)


def is_left(polygon: Polygon,
            line: LineString) -> bool:
    """
    Determines if the polygon is on the left side of the line
    according to:
    https://stackoverflow.com/questions/50393718/determine-the-left-and-right-side-of-a-split-shapely-geometry
    """
    ring = LinearRing([*line.coords, *polygon.centroid.coords])
    return ring.is_ccw

このコードは、3Dジオメトリでは失敗します。

p = Polygon([(0, 0, 0), (1, 0, 0), (1, 1, 0)])
l = LineString([(0, 0, 0), (1, 0, 0)])
is_left(p, l)

このエラーが発生します:

AttributeError                            Traceback (most recent call last)
~/miniconda3/lib/python3.7/site-packages/shapely/speedups/_speedups.pyx in shapely.speedups._speedups.geos_linearring_from_py()

AttributeError: 'list' object has no attribute '__array_interface__'

During handling of the above exception, another exception occurred:

IndexError                                Traceback (most recent call last)
<ipython-input-55-555b9e2533fa> in <module>()
----> 1 is_left(p, l)

<ipython-input-52-7fad75b19ce3> in is_left(polygon, line)
      6     https://stackoverflow.com/questions/50393718/determine-the-left-and-right-side-of-a-split-shapely-geometry
      7     """
----> 8     ring = LinearRing([*line.coords, *polygon.centroid.coords])
      9     return ring.is_ccw

~/miniconda3/lib/python3.7/site-packages/shapely/geometry/polygon.py in __init__(self, coordinates)
     51         BaseGeometry.__init__(self)
     52         if coordinates is not None:
---> 53             self._set_coords(coordinates)
     54 
     55     <strong i="18">@property</strong>

~/miniconda3/lib/python3.7/site-packages/shapely/geometry/polygon.py in _set_coords(self, coordinates)
     66     def _set_coords(self, coordinates):
     67         self.empty()
---> 68         ret = geos_linearring_from_py(coordinates)
     69         if ret is not None:
     70             self._geom, self._ndim = ret

~/miniconda3/lib/python3.7/site-packages/shapely/speedups/_speedups.pyx in shapely.speedups._speedups.geos_linearring_from_py()

IndexError: tuple index out of range

これは、 Polygonの重心が常に2D(https://github.com/Toblerity/Shapely/issues/554)で返され、 LinearRingは返されないという事実によるものです。異なる次元数のポイントから構築されます。

drop_zメソッドがあった場合、 line = LineString([xy[:2] for xy in list(line.coords)])のようなものでコードを乱雑にしたり、そのための関数を実装したりする代わりに、 ring = LinearRing([*line.drop_z.coords, *polygon.centroid.coords])を書くだけです。 または、さらに良いことに、トップレベルのファイルから読み取った元の親ポリゴンのゼロのみで構成される冗長な3次元を削除するため、すべての子ジオメトリは2次元のみになります。


形の良いバージョン:1.6.4.post1、condaからインストール。

wontfix

最も参考になるコメント

グーグルからここに到着する他の人々のために、私は非常に簡単な方法を見つけました:

def _to_2d(x, y, z):
    return tuple(filter(None, [x, y]))

new_shape = shapely.ops.transform(_to_2d, shape)

(https://github.com/hotosm/tasking-manager/blob/master/server/services/grid/grid_service.py:heart :)から@feenster@ hunt3riへのクレジット

全てのコメント3件

@ LostFan123 Z値を削除する方法は、1.7の適切な追加だと思います。 それを提案してくれてありがとう。

グーグルからここに到着する他の人々のために、私は非常に簡単な方法を見つけました:

def _to_2d(x, y, z):
    return tuple(filter(None, [x, y]))

new_shape = shapely.ops.transform(_to_2d, shape)

(https://github.com/hotosm/tasking-manager/blob/master/server/services/grid/grid_service.py:heart :)から@feenster@ hunt3riへのクレジット

上記の2行のソリューションを優先して、この問題を解決します。 ありがとう@ Juanlu001

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

chivasblue picture chivasblue  ·  3コメント

mikedh picture mikedh  ·  6コメント

mromanie picture mromanie  ·  3コメント

doctor-ian picture doctor-ian  ·  4コメント

LostFan123 picture LostFan123  ·  5コメント