TXT / Excel(CSV) / SHP 三种格式任意互转
支持 WGS84 / CGCS2000 / Xian80 / Beijing54 / Web Mercator 坐标系转换
由 Mapo 🗺️ 自动生成
69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
"""
|
|
Coordinate transformation engine — wraps pyproj for all CRS conversions.
|
|
"""
|
|
import pyproj
|
|
from typing import Tuple
|
|
|
|
# Well-known EPSG codes
|
|
WELL_KNOWN = {
|
|
"WGS84": "EPSG:4326",
|
|
"CGCS2000": "EPSG:4490",
|
|
"Xian80": "EPSG:4610",
|
|
"Beijing54": "EPSG:4214",
|
|
"WebMercator": "EPSG:3857",
|
|
"PseudoMercator": "EPSG:3857",
|
|
}
|
|
|
|
|
|
def resolve_epsg(name: str) -> str:
|
|
"""Resolve a well-known name or return as-is if already EPSG:xxxx."""
|
|
name = name.strip()
|
|
if name.upper() in WELL_KNOWN:
|
|
return WELL_KNOWN[name.upper()]
|
|
if name.upper().startswith("EPSG:"):
|
|
return name.upper()
|
|
return f"EPSG:{name}"
|
|
|
|
|
|
class CoordTransformer:
|
|
"""Convert coordinates between any two CRS using pyproj."""
|
|
|
|
def __init__(self, from_crs: str, to_crs: str):
|
|
self.from_crs = resolve_epsg(from_crs)
|
|
self.to_crs = resolve_epsg(to_crs)
|
|
if self.from_crs == self.to_crs:
|
|
self._is_identity = True
|
|
self._transformer = None
|
|
else:
|
|
self._is_identity = False
|
|
self._transformer = pyproj.Transformer.from_crs(
|
|
self.from_crs, self.to_crs, always_xy=True
|
|
)
|
|
|
|
def transform(self, x: float, y: float) -> Tuple[float, float]:
|
|
if self._is_identity:
|
|
return x, y
|
|
return self._transformer.transform(x, y)
|
|
|
|
def transform_batch(self, xs: list[float], ys: list[float]) -> Tuple[list[float], list[float]]:
|
|
if self._is_identity:
|
|
return xs, ys
|
|
results = self._transformer.transform(xs, ys)
|
|
return results[0], results[1]
|
|
|
|
@property
|
|
def description(self) -> str:
|
|
if self._is_identity:
|
|
return f"{self.from_crs} (无转换)"
|
|
return f"{self.from_crs} → {self.to_crs}"
|
|
|
|
@staticmethod
|
|
def list_supported() -> list[dict]:
|
|
return [
|
|
{"name": "WGS84", "epsg": "EPSG:4326", "desc": "GPS / Google Earth"},
|
|
{"name": "CGCS2000", "epsg": "EPSG:4490", "desc": "2000国家大地坐标系"},
|
|
{"name": "Xian80", "epsg": "EPSG:4610", "desc": "西安80坐标系"},
|
|
{"name": "Beijing54", "epsg": "EPSG:4214", "desc": "北京54坐标系"},
|
|
{"name": "Web Mercator","epsg": "EPSG:3857", "desc": "互联网地图投影"},
|
|
]
|