mirror of
https://github.com/wassname/geopandas.git
synced 2026-09-21 13:00:14 +08:00
BUG: fix geometry methods to handle single MultiGeoms output (#1134)
This commit is contained in:
+30
-19
@@ -112,8 +112,9 @@ def from_wkb(data):
|
||||
geom = None
|
||||
out.append(geom)
|
||||
|
||||
out = np.array(out, dtype=object)
|
||||
return GeometryArray(out)
|
||||
aout = np.empty(n, dtype=object)
|
||||
aout[:] = out
|
||||
return GeometryArray(aout)
|
||||
|
||||
|
||||
def to_wkb(geoms):
|
||||
@@ -146,8 +147,9 @@ def from_wkt(data):
|
||||
geom = None
|
||||
out.append(geom)
|
||||
|
||||
out = np.array(out, dtype=object)
|
||||
return GeometryArray(out)
|
||||
aout = np.empty(n, dtype=object)
|
||||
aout[:] = out
|
||||
return GeometryArray(aout)
|
||||
|
||||
|
||||
def to_wkt(geoms):
|
||||
@@ -197,8 +199,9 @@ def points_from_xy(x, y, z=None):
|
||||
if z is not None:
|
||||
z = np.asarray(z, dtype="float64")
|
||||
out = _points_from_xy(x, y, z)
|
||||
out = np.array(out, dtype=object)
|
||||
return GeometryArray(out)
|
||||
aout = np.empty(len(x), dtype=object)
|
||||
aout[:] = out
|
||||
return GeometryArray(aout)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -384,14 +387,16 @@ def _affinity_method(op, left, *args, **kwargs):
|
||||
# affine_transform itself works (as well as translate), but rotate, scale
|
||||
# and skew fail (they try to unpack the bounds).
|
||||
# Here: consistently returning empty geom for input empty geom
|
||||
data = []
|
||||
out = []
|
||||
for geom in left.data:
|
||||
if geom is None or geom.is_empty:
|
||||
res = geom
|
||||
else:
|
||||
res = getattr(shapely.affinity, op)(geom, *args, **kwargs)
|
||||
data.append(res)
|
||||
return GeometryArray(np.array(data, dtype=object))
|
||||
out.append(res)
|
||||
data = np.empty(len(left), dtype=object)
|
||||
data[:] = out
|
||||
return GeometryArray(data)
|
||||
|
||||
|
||||
class GeometryArray(ExtensionArray):
|
||||
@@ -547,8 +552,9 @@ class GeometryArray(ExtensionArray):
|
||||
"Only Polygon objects have interior rings. For other "
|
||||
"geometry types, None is returned."
|
||||
)
|
||||
|
||||
return np.array(inner_rings, dtype=object)
|
||||
data = np.empty(len(self), dtype=object)
|
||||
data[:] = inner_rings
|
||||
return data
|
||||
|
||||
def representative_point(self):
|
||||
# method and not a property -> can't use _unary_geo
|
||||
@@ -620,39 +626,44 @@ class GeometryArray(ExtensionArray):
|
||||
return _binary_op_float("distance", self, other)
|
||||
|
||||
def buffer(self, distance, resolution=16, **kwargs):
|
||||
data = data = np.empty(len(self), dtype=object)
|
||||
if isinstance(distance, np.ndarray):
|
||||
if len(distance) != len(self):
|
||||
raise ValueError(
|
||||
"Length of distance sequence does not match "
|
||||
"length of the GeoSeries"
|
||||
)
|
||||
data = [
|
||||
|
||||
data[:] = [
|
||||
geom.buffer(dist, resolution, **kwargs) if geom is not None else None
|
||||
for geom, dist in zip(self.data, distance)
|
||||
]
|
||||
return GeometryArray(np.array(data, dtype=object))
|
||||
return GeometryArray(data)
|
||||
|
||||
data = [
|
||||
data[:] = [
|
||||
geom.buffer(distance, resolution, **kwargs) if geom is not None else None
|
||||
for geom in self.data
|
||||
]
|
||||
return GeometryArray(np.array(data, dtype=object))
|
||||
return GeometryArray(data)
|
||||
|
||||
def interpolate(self, distance, normalized=False):
|
||||
data = data = np.empty(len(self), dtype=object)
|
||||
if isinstance(distance, np.ndarray):
|
||||
if len(distance) != len(self):
|
||||
raise ValueError(
|
||||
"Length of distance sequence does not match "
|
||||
"length of the GeoSeries"
|
||||
)
|
||||
data = [
|
||||
data[:] = [
|
||||
geom.interpolate(dist, normalized=normalized)
|
||||
for geom, dist in zip(self.data, distance)
|
||||
]
|
||||
return GeometryArray(np.array(data, dtype=object))
|
||||
return GeometryArray(data)
|
||||
|
||||
data = [geom.interpolate(distance, normalized=normalized) for geom in self.data]
|
||||
return GeometryArray(np.array(data, dtype=object))
|
||||
data[:] = [
|
||||
geom.interpolate(distance, normalized=normalized) for geom in self.data
|
||||
]
|
||||
return GeometryArray(data)
|
||||
|
||||
def simplify(self, *args, **kwargs):
|
||||
# method and not a property -> can't use _unary_geo
|
||||
|
||||
@@ -133,6 +133,13 @@ def test_from_wkb():
|
||||
assert res[-1] is None
|
||||
assert res[-2] is None
|
||||
|
||||
# single MultiPolygon
|
||||
multi_poly = shapely.geometry.MultiPolygon(
|
||||
[shapely.geometry.box(0, 0, 1, 1), shapely.geometry.box(3, 3, 4, 4)]
|
||||
)
|
||||
res = from_wkb([multi_poly.wkb])
|
||||
assert res[0] == multi_poly
|
||||
|
||||
|
||||
def test_to_wkb():
|
||||
P = from_shapely(points_no_missing)
|
||||
@@ -179,6 +186,13 @@ def test_from_wkt(string_type):
|
||||
assert res[-1] is None
|
||||
assert res[-2] is None
|
||||
|
||||
# single MultiPolygon
|
||||
multi_poly = shapely.geometry.MultiPolygon(
|
||||
[shapely.geometry.box(0, 0, 1, 1), shapely.geometry.box(3, 3, 4, 4)]
|
||||
)
|
||||
res = from_wkt([f(multi_poly.wkt)])
|
||||
assert res[0] == multi_poly
|
||||
|
||||
|
||||
def test_to_wkt():
|
||||
P = from_shapely(points_no_missing)
|
||||
@@ -667,3 +681,16 @@ def test_raise_on_bad_sizes():
|
||||
assert "lengths" in str(info.value).lower()
|
||||
assert "12" in str(info.value)
|
||||
assert "21" in str(info.value)
|
||||
|
||||
|
||||
def test_buffer_single_multipolygon():
|
||||
# https://github.com/geopandas/geopandas/issues/1130
|
||||
multi_poly = shapely.geometry.MultiPolygon(
|
||||
[shapely.geometry.box(0, 0, 1, 1), shapely.geometry.box(3, 3, 4, 4)]
|
||||
)
|
||||
arr = from_shapely([multi_poly])
|
||||
result = arr.buffer(1)
|
||||
expected = [multi_poly.buffer(1)]
|
||||
equal_geometries(result, expected)
|
||||
result = arr.buffer(np.array([1]))
|
||||
equal_geometries(result, expected)
|
||||
|
||||
Reference in New Issue
Block a user