初次提交
This commit is contained in:
110
tests/test_geometry.py
Normal file
110
tests/test_geometry.py
Normal file
@@ -0,0 +1,110 @@
|
||||
"""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)
|
||||
Reference in New Issue
Block a user