初次提交

This commit is contained in:
2026-03-04 17:07:07 +08:00
commit af988ea7b9
37 changed files with 3674 additions and 0 deletions

81
tests/test_io.py Normal file
View File

@@ -0,0 +1,81 @@
"""tests/test_io.py —— IO 读写单元测试。"""
import pytest
import geopandas as gpd
from pathlib import Path
from geo_tools.io.readers import read_vector, read_gpkg, list_gpkg_layers, read_csv_points
from geo_tools.io.writers import write_vector, write_gpkg, write_csv
class TestReadVector:
def test_read_geojson(self, tmp_geojson_path):
gdf = read_vector(tmp_geojson_path)
assert isinstance(gdf, gpd.GeoDataFrame)
assert len(gdf) == 3
assert gdf.crs is not None
def test_read_with_crs_reprojection(self, tmp_geojson_path):
gdf = read_vector(tmp_geojson_path, crs="EPSG:3857")
assert gdf.crs.to_epsg() == 3857
def test_read_nonexistent_raises(self, tmp_path):
with pytest.raises(FileNotFoundError):
read_vector(tmp_path / "nonexistent.geojson")
def test_read_unsupported_format_raises(self, tmp_path):
bad_file = tmp_path / "data.xyz"
bad_file.write_text("dummy")
with pytest.raises(ValueError, match="不支持"):
read_vector(bad_file)
class TestWriteReadRoundtrip:
def test_geojson_roundtrip(self, sample_points_gdf, tmp_output_dir):
out = tmp_output_dir / "out.geojson"
write_vector(sample_points_gdf, out)
loaded = read_vector(out)
assert len(loaded) == len(sample_points_gdf)
assert list(loaded.columns) == list(sample_points_gdf.columns)
def test_gpkg_roundtrip(self, sample_points_gdf, tmp_output_dir):
out = tmp_output_dir / "out.gpkg"
write_gpkg(sample_points_gdf, out, layer="points")
loaded = read_gpkg(out, layer="points")
assert len(loaded) == len(sample_points_gdf)
def test_gpkg_multiple_layers(self, sample_points_gdf, sample_polygon_gdf, tmp_output_dir):
out = tmp_output_dir / "multi.gpkg"
write_gpkg(sample_points_gdf, out, layer="points")
write_gpkg(sample_polygon_gdf, out, layer="polygons", mode="a")
layers = list_gpkg_layers(out)
assert "points" in layers
assert "polygons" in layers
def test_csv_roundtrip(self, sample_points_gdf, tmp_output_dir):
out = tmp_output_dir / "out.csv"
write_csv(sample_points_gdf, out)
# CSV 写出的是 WKT geometry 列,用 pandas 读回验证
import pandas as pd
df = pd.read_csv(out)
assert "geometry" in df.columns # 存在 WKT 几何列
assert len(df) == len(sample_points_gdf) # 行数一致
# 再用 read_csv_points 以 WKT 模式读回
from geo_tools.io.readers import _read_csv_vector
from pathlib import Path
gdf_back = _read_csv_vector(Path(out), wkt_col="geometry")
assert len(gdf_back) == len(sample_points_gdf)
class TestReadCsvPoints:
def test_read_csv_with_latlon(self, tmp_path):
import pandas as pd
csv_path = tmp_path / "points.csv"
pd.DataFrame({
"longitude": [116.4, 121.5],
"latitude": [39.9, 31.2],
"name": ["北京", "上海"],
}).to_csv(csv_path, index=False)
gdf = read_csv_points(csv_path)
assert len(gdf) == 2
assert gdf.crs.to_epsg() == 4326