Skip to content

Commit

Permalink
added force_3d factory
Browse files Browse the repository at this point in the history
  • Loading branch information
whisk committed Nov 5, 2023
1 parent e077f1f commit 9856893
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
35 changes: 35 additions & 0 deletions pygeoif/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,40 @@ def force_2d(
return shape(geometry)


def force_3d(
context: Union[GeoType, GeoCollectionType],
z: float = 0,
) -> Union[Geometry, GeometryCollection]:
"""
Force the dimensionality of a geometry to 3D.
>>> force_3d(Point(0, 0))
Point(0, 0, 0)
>>> force_3d(Point(0, 0), 1)
Point(0, 0, 1)
>>> force_3d(Point(0, 0, 0))
Point(0, 0, 0)
>>> force_3d(LineString([(0, 0), (0, 1), (1, 1)]))
LineString(((0, 0, 0), (0, 1, 0), (1, 1, 0)))
"""
geometry = context if isinstance(context, dict) else mapping(context)
if not geometry:
msg = "Object does not implement __geo_interface__"
raise TypeError(msg)
if geometry["type"] == "GeometryCollection":
return GeometryCollection(
force_3d(g, z) # type: ignore [arg-type]
for g in geometry["geometries"] # type: ignore [typeddict-item]
)

geometry["coordinates"] = move_coordinates( # type: ignore [typeddict-unknown-key]
geometry["coordinates"], # type: ignore [typeddict-item]
(0, 0, 0),
z,
)
return shape(geometry)


def get_oriented_ring(ring: LineType, ccw: bool) -> LineType: # noqa: FBT001
s = 1.0 if ccw else -1.0
return ring if signed_area(ring) / s >= 0 else ring[::-1]
Expand Down Expand Up @@ -363,6 +397,7 @@ def mapping(


__all__ = [
"force_3d",
"box",
"from_wkt",
"mapping",
Expand Down
27 changes: 27 additions & 0 deletions tests/test_factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,33 @@ def test_force2d_collection() -> None:
assert list(gc2d.geoms) == [geometry.Point(-1, 1), geometry.Point(-2, 2)]


def test_force_3d_point() -> None:
p = geometry.Point(0, 0)
p3d = factories.force_3d(p)
assert p3d.x == 0
assert p3d.y == 0
assert p3d.z == 0
assert p3d.has_z


def test_force_3d_point_with_z() -> None:
p = geometry.Point(0, 0, 1)
p3d = factories.force_3d(p)
assert p3d.x == 0
assert p3d.y == 0
assert p3d.z == 1
assert p3d.has_z


def test_force_3d_point_3d() -> None:
p = geometry.Point(1, 2, 3)
p3d = factories.force_3d(p)
assert p3d.x == 1
assert p3d.y == 2
assert p3d.z == 3
assert p3d.has_z


def test_orient_true() -> None:
ext = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)]
int_1 = [(0.5, 0.25), (1.5, 0.25), (1.5, 1.25), (0.5, 1.25), (0.5, 0.25)]
Expand Down

0 comments on commit 9856893

Please sign in to comment.