06-GIS坐标系实战排错-4326-3857-本地投影-GCJ02-BD09

发布时间:2026/9/3 20:51:51
06-GIS坐标系实战排错-4326-3857-本地投影-GCJ02-BD09 GIS 项目里最容易让业务开发困惑的不是 GeoServer 页面怎么点而是坐标系。常见现象包括WFS 返回了数据但前端地图上看不到。 WMS 图片能出来但叠到底图上位置不对。 点位整体偏移几百米。 经纬度看起来正常但长度计算结果很怪。 数据库里 x/y 是几十万、几百万前端却按经纬度使用。这些问题大多和坐标系有关。一、先分清几类坐标业务 GIS 项目里经常同时出现几类坐标EPSG:4326 WGS84 经纬度。 EPSG:3857 Web Mercator互联网地图常用显示坐标系。 本地投影坐标系 例如城市、区域、行业测绘成果使用的米制投影坐标。 GCJ-02 国内部分互联网地图常用坐标。 BD-09 百度地图常用坐标。它们不是同一种东西。同一个真实位置用不同坐标系表示时数字可能完全不同。二、EPSG:4326 是什么EPSG:4326 通常就是大家说的 WGS84 经纬度。典型形式longitude 120.123456 latitude 30.123456特点单位是度。 适合 GPS、接口传参、GeoJSON 对外输出。 人容易理解。 跨系统交换方便。但它不适合直接做米级距离计算。原因是经度 1 度对应的实际距离会随纬度变化。 纬度 1 度也不是业务系统里常说的米。所以如果你用EPSG:4326的 geometry 直接ST_Length(geom)结果单位不是米很容易误用。三、EPSG:3857 是什么EPSG:3857 是 Web Mercator互联网地图最常见的显示坐标系。Google Map、OSM、很多 Mapbox/MapLibre 底图都使用或兼容这个坐标系。典型形式x 13300000 y 3500000特点单位近似是米。 适合 Web 地图切片和显示。 不是严格测绘计算坐标。 高纬度变形明显。前端地图框架里地图 View 很多默认就是EPSG:3857例如 OpenLayers 默认 View projection 常用EPSG:3857。四、本地投影坐标系是什么很多测绘数据不会直接用经纬度而会使用本地投影坐标系。典型形式x 505000 y 3349000特点单位通常是米。 适合计算长度、距离、面积。 常见于 CAD、测绘成果、管网数据、市政数据。 不同地区可能使用不同投影。这类坐标非常适合放在 PostGIS 里做计算。例如SELECTST_Length(geom)FROMbiz_schema.biz_line;如果geom是米制投影坐标系ST_Length结果就更适合直接作为米来理解。五、GCJ-02 和 BD-09 是什么这是国内地图开发非常重要的一块。常见坐标体系WGS84 GPS 原始坐标、国际通用经纬度。 GCJ-02 国内部分互联网地图使用的加偏坐标也常被称为火星坐标。 BD-09 百度地图使用的坐标体系在 GCJ-02 基础上又做了一层转换。常见组合GPS 设备 通常输出 WGS84。 高德地图 / 腾讯地图 通常使用 GCJ-02。 百度地图 通常使用 BD-09。 Google Map 海外 通常使用 WGS84/Web Mercator。如果你把 WGS84 点直接放到 GCJ-02 底图上国内区域可能会出现整体偏移。如果你把 GCJ-02 点当 WGS84 入库后续再叠加 GeoServer 或其他底图也会继续偏。六、推荐坐标分工一个业务 GIS 项目可以采用这套规则数据库 PostGIS geom 使用适合本地计算的投影坐标系。 后端 API 输入输出 尽量统一 EPSG:4326。 GeoServer 图层 Native SRS 使用数据库 geom 的真实 SRID。 GeoServer WFS 输出 按需要 srsNameEPSG:4326。 GeoServer WMS/WMTS 显示 跟随前端底图常见是 EPSG:3857。 前端地图 View 通常 EPSG:3857。如果涉及国内互联网地图还要额外明确前端底图到底是 WGS84 体系还是 GCJ-02 / BD-09 体系。 业务坐标入库前是否需要纠偏。 GeoServer 输出坐标叠加到底图前是否需要转换。七、PostGIS 中如何转换常见转换-- 4326 经纬度点转本地投影SELECTST_Transform(ST_SetSRID(ST_MakePoint(:longitude,:latitude),4326),4549);-- 本地投影 geom 转 4326 GeoJSONSELECTST_AsGeoJSON(ST_Transform(geom,4326))FROMbiz_schema.biz_point;-- 本地投影 geom 转 3857SELECTST_AsGeoJSON(ST_Transform(geom,3857))FROMbiz_schema.biz_point;注意ST_SetSRID 只是声明坐标系不改变坐标数字。 ST_Transform 才是真正坐标转换。这是一个非常常见的坑。错误理解-- 只改 SRID不会把坐标变成目标坐标系SELECTST_SetSRID(geom,4326);正确理解-- 从原坐标系转换到目标坐标系SELECTST_Transform(geom,4326);前提是geom原本 SRID 是正确的。八、GeoServer 中如何处理坐标发布 PostGIS 图层时Native SRS 数据库 geom 的真实 SRID。 Declared SRS 通常和 Native SRS 一致。 SRS handling 一般选择 Force declared。如果数据库里的geom是本地投影坐标GeoServer 图层就不要硬声明成EPSG:4326。正确做法图层声明真实 SRID。 前端请求时通过 WFS srsName 或 WMS srs/crs 请求目标坐标系。例如 WFS 输出经纬度serviceWFS requestGetFeature typeNameexample_ws:biz_points outputFormatapplication/json srsNameEPSG:4326例如 WMS 叠加到 Web Mercator 底图serviceWMS requestGetMap layersexample_ws:biz_lines srsEPSG:3857 bbox3857坐标范围 formatimage/png transparenttrue重点WMS 请求 srs 是什么bbox 就必须是什么坐标系。九、前端中如何处理坐标以 OpenLayers 为例如果地图 View 是EPSG:3857而 WFS 返回EPSG:4326读取 GeoJSON 时要写清楚constfeaturesnewol.format.GeoJSON().readFeatures(geojson,{dataProjection:EPSG:4326,featureProjection:EPSG:3857});含义dataProjection GeoJSON 数据本身是什么坐标系。 featureProjection 地图上要渲染成什么坐标系。如果这里不写或者写反图层就可能看不到。如果前端需要把点击坐标传给后端constlonLatol.proj.toLonLat(evt.coordinate);evt.coordinate通常是地图 View 坐标也就是EPSG:3857。toLonLat后才是经纬度EPSG:4326。十、国内底图偏移怎么排查如果底图是国内互联网地图坐标偏移要重点排查。常见判断GPS 点、GeoServer WFS 4326 点、PostGIS 转 4326 点 通常属于 WGS84 体系。 高德/腾讯底图上的点 可能需要 GCJ-02。 百度底图上的点 可能需要 BD-09。排查顺序1. 先不用底图只在空白地图上显示 WFS 4326 数据。 2. 确认 WFS 4326 经纬度是否落在正确城市范围。 3. 切换 OSM 或 Google 海外底图确认是否对齐。 4. 切换国内底图观察是否整体偏移。 5. 如果只在国内底图偏重点怀疑 WGS84/GCJ-02/BD-09 问题。经验判断整体偏几百米 常见于 WGS84 和 GCJ-02 混用。 整体偏得非常离谱看不到 常见于 4326、3857、本地投影坐标混用。 只有个别点偏 更像数据录入错误或飞点。十一、长度和面积计算怎么选坐标系如果要计算管线长度。 巡检覆盖长度。 缓冲区半径。 两点距离。 面积。优先使用米制投影坐标系。例如SELECTST_Length(geom)FROMbiz_schema.biz_line;如果geom是EPSG:4326直接ST_Length的结果不是米。也可以临时转换SELECTST_Length(ST_Transform(geom,4549))FROMbiz_schema.biz_line;但长期项目中建议数据库空间表直接使用适合计算的投影坐标系减少误用。十二、常见错误清单错误一把投影坐标当经纬度。x 505000 y 3349000这明显不是经纬度。经纬度一般是lon 120.x lat 30.x错误二只用ST_SetSRID做转换。ST_SetSRID 只是贴标签。 ST_Transform 才是换坐标。错误三WMS 的 bbox 坐标系和 srs 不一致。srsEPSG:3857 bbox120,30,121,31这种就是错的。错误四WFS 输出 4549前端按 4326 读。GeoJSON coordinates [505000,3349000]前端不能当经纬度。错误五国内底图不考虑 GCJ-02 / BD-09。WGS84 数据叠加到 GCJ-02 底图可能整体偏移。十三、排错 checklist遇到坐标问题时按这个顺序查1. 数据库 ST_SRID(geom) 是多少。 2. GeoServer Native SRS 是否等于数据库 SRID。 3. GeoServer Declared SRS 是否合理。 4. WFS 不带 srsName 输出是什么。 5. WFS 带 srsNameEPSG:4326 输出是否是经纬度。 6. 前端读取 GeoJSON 时 dataProjection 是否正确。 7. 前端地图 View projection 是否是 EPSG:3857。 8. WMS 请求 srs 和 bbox 是否一致。 9. 底图是否使用 GCJ-02 或 BD-09。 10. 是否把属性 x/y 当成 geometry.coordinates 使用。十四、总结坐标系问题不要靠猜。比较稳的原则是数据入库前确认来源坐标系。 PostGIS geom 保存真实 SRID。 GeoServer 声明真实 Native SRS。 前端请求时明确目标坐标系。 接口对外统一经纬度更容易协作。 米级计算使用投影坐标。 国内底图额外确认 GCJ-02/BD-09。只要把这些规则固定下来GIS 项目里大部分“偏移、看不到、算不准”的问题都能快速定位。