MSSQL中Geometry转经纬度及Python转换、CRS获取咨询
解决Geometry坐标转换为经纬度的问题
我来帮你拆解这个问题——你用STY/STX拿到的是投影坐标系下的米级坐标(比如Web Mercator、UTM这类以米为单位的投影),不是咱们常用的WGS84地理坐标系的经纬度(度为单位),所以数值会是几十万甚至几百万的量级。下面分步骤解决你的所有疑问:
一、先获取数据的CRS(坐标系)
转换的前提是知道你的Geometry数据用的是什么坐标系(SRID,空间参考ID),这是核心。
在SQL Server中获取SRID
因为你用了.STY/.STX,应该是SQL Server的Geometry类型,直接执行下面的语句就能拿到数据的SRID:
SELECT DISTINCT geom.STSrid AS source_srid FROM YourTable;
- 如果返回的是具体数字(比如3857、32631、4326),那就是对应的坐标系编码;
- 如果返回0,说明数据没有指定SRID,你得去查数据的来源/元数据(比如导出数据的系统、文档),这一步不能省,否则转换结果完全错误。
常见的SRID对应:
- WGS84经纬度:EPSG:4326
- Web Mercator(很多地图平台用):EPSG:3857
- UTM分带(比如北半球31带):EPSG:32631
二、在SQL中直接转换为经纬度
如果已经拿到了源SRID,直接用SQL Server的STTransform函数转成WGS84(EPSG:4326)就行,一步到位:
SELECT geom.STTransform(4326).STY AS latitude, -- 转换后的纬度(-90~90) geom.STTransform(4326).STX AS longitude -- 转换后的经度(-180~180) FROM YourTable;
这里4326是WGS84的SRID,转换后得到的就是你需要的经纬度范围数值。
三、用Python实现转换
如果需要在Python里处理,分两种场景:
场景1:直接读取数据库中的二进制Geometry并转换
先安装依赖包:
pip install shapely pyproj pyodbc
然后用下面的代码读取并转换:
import pyodbc from shapely.wkb import loads from pyproj import Transformer # 1. 连接数据库(替换成你的数据库连接字符串) conn_str = "DRIVER={SQL Server};SERVER=your_server;DATABASE=your_db;UID=your_user;PWD=your_pwd" conn = pyodbc.connect(conn_str) cursor = conn.cursor() # 2. 查询Geometry数据 cursor.execute("SELECT geom FROM YourTable") rows = cursor.fetchall() # 3. 定义转换器:源CRS转WGS84(替换source_srid为你查到的实际SRID,比如3857) transformer = Transformer.from_crs(f"EPSG:{source_srid}", "EPSG:4326", always_xy=True) # 4. 遍历转换每一条数据 for idx, row in enumerate(rows, 1): # 从二进制WKB加载Shapely几何对象 geom = loads(row[0]) # 获取投影坐标系下的X(东向)、Y(北向) proj_x, proj_y = geom.x, geom.y # 转换为WGS84经纬度(lon, lat) lon, lat = transformer.transform(proj_x, proj_y) print(f"第{idx}条:纬度 {lat:.6f}, 经度 {lon:.6f}") # 关闭连接 conn.close()
场景2:已经拿到SQL返回的(Y,X)数值,直接转换
如果已经从SQL拿到了STY和STX的米级数值,直接用pyproj转换即可:
from pyproj import Transformer # 替换source_srid为实际的源坐标系SRID transformer = Transformer.from_crs("EPSG:3857", "EPSG:4326", always_xy=True) # 假设从SQL拿到的STY=5058449.313,STX=对应的X值 proj_y = 5058449.313 proj_x = 1234567.89 # 替换为你的实际STX数值 # 转换为经纬度 lon, lat = transformer.transform(proj_x, proj_y) print(f"转换结果:纬度 {lat:.6f}, 经度 {lon:.6f}")
关键注意事项
- SRID一定要准确:这是转换的核心,错了的话结果完全不对;
- 坐标顺序:地理坐标系是(经度,纬度),投影坐标系是(X,Y)对应(东向,北向),
pyproj的always_xy=True会确保转换时用正确的顺序,避免搞混经纬度。
内容的提问来源于stack exchange,提问作者NaHa
相关产品推荐
相关产品推荐

