Files
geo_tools/tests/test_geometry.py
2026-03-04 17:07:07 +08:00

111 lines
3.1 KiB
Python

"""tests/test_geometry.py —— 几何运算单元测试。"""
import pytest
from shapely.geometry import LineString, Point, Polygon
import geo_tools
from geo_tools.core.geometry import (
buffer_geometry,
bounding_box,
centroid,
contains,
convex_hull,
difference,
distance_between,
fix_geometry,
intersect,
intersects,
is_valid_geometry,
unary_union,
union,
within,
)
class TestIsValidGeometry:
def test_valid_polygon(self):
poly = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
assert is_valid_geometry(poly) is True
def test_none_returns_false(self):
assert is_valid_geometry(None) is False
def test_invalid_self_intersecting(self):
# 蝴蝶形(自相交)
bowtie = Polygon([(0, 0), (1, 1), (1, 0), (0, 1)])
assert is_valid_geometry(bowtie) is False
class TestFixGeometry:
def test_fix_bowtie(self):
bowtie = Polygon([(0, 0), (1, 1), (1, 0), (0, 1)])
assert not bowtie.is_valid
fixed = fix_geometry(bowtie)
assert fixed is not None
assert fixed.is_valid
def test_valid_geometry_unchanged(self):
poly = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
fixed = fix_geometry(poly)
assert fixed.is_valid
assert fixed.area == pytest.approx(poly.area)
def test_none_returns_none(self):
assert fix_geometry(None) is None
class TestBufferGeometry:
def test_point_buffer(self):
pt = Point(0, 0)
buf = buffer_geometry(pt, 1.0)
assert buf.area > 3.0 # π * r² ≈ 3.14
def test_zero_distance_returns_point_like(self):
pt = Point(0, 0)
buf = buffer_geometry(pt, 0.0)
# buffer(0) on point may return empty or point
assert buf is not None
class TestSetOperations:
@pytest.fixture
def poly_a(self):
return Polygon([(0, 0), (2, 0), (2, 2), (0, 2)])
@pytest.fixture
def poly_b(self):
return Polygon([(1, 0), (3, 0), (3, 2), (1, 2)])
def test_intersection(self, poly_a, poly_b):
result = intersect(poly_a, poly_b)
assert result.area == pytest.approx(2.0)
def test_union(self, poly_a, poly_b):
result = union(poly_a, poly_b)
assert result.area == pytest.approx(6.0)
def test_difference(self, poly_a, poly_b):
result = difference(poly_a, poly_b)
assert result.area == pytest.approx(2.0)
def test_unary_union(self, poly_a, poly_b):
result = unary_union([poly_a, poly_b])
assert result.area == pytest.approx(6.0)
class TestSpatialRelations:
def test_contains_true(self):
big = Polygon([(0, 0), (10, 0), (10, 10), (0, 10)])
small = Polygon([(1, 1), (2, 1), (2, 2), (1, 2)])
assert contains(big, small) is True
def test_within(self):
big = Polygon([(0, 0), (10, 0), (10, 10), (0, 10)])
small = Polygon([(1, 1), (2, 1), (2, 2), (1, 2)])
assert within(small, big) is True
def test_distance(self):
p1 = Point(0, 0)
p2 = Point(3, 4)
assert distance_between(p1, p2) == pytest.approx(5.0)