Linux下C++用libproj 6.3.1转换EPSG:2180时坐标互换问题求助
解决libproj 6.3.1中EPSG:2180坐标转换东/北向互换问题
问题背景
Linux环境下运行的C++程序使用libproj 6.3.1做坐标转换,当目标CRS为EPSG:2180时,转换结果的东向(Easting)和北向(Northing)坐标位置互换,不符合预期。
命令行测试验证
- 执行
projinfo获取EPSG:2180的投影字符串,基于该字符串转换WGS84(EPSG:4326)坐标时,结果东向坐标在前 - 直接执行
cs2cs epsg:4326 epsg:2180命令转换时,结果东、北向坐标互换
代码现状
使用proj_create_crs_to_crs创建转换对象,调用proj_normalize_for_visualization无法解决轴顺序问题,输出结果中东向坐标始终不在result.x位置。
测试代码及结果
#include <cstdlib> #include <cstdio> #include <proj.h> int main(int argc, char** argv) { PJ_CONTEXT* projContext_m = proj_context_create(); // hardcode epsg (in reality it is user defined) int epsg_p = 2180; char _buff[100]; snprintf(_buff, sizeof (_buff), "EPSG:%d", epsg_p); PJ* projEPSG_m = proj_create_crs_to_crs(projContext_m, "EPSG:4326", _buff, NULL); if (projEPSG_m != nullptr) { proj_normalize_for_visualization(projContext_m, projEPSG_m); } // fake input (in reality it is user defined) PJ_COORD input_p; input_p.xy.x = 55.12578267; input_p.xy.y = 16.77291767; PJ_COORD result = proj_trans(projEPSG_m, PJ_FWD, input_p); // input_p is the coordinate we need to transform // we assume `result.x` is the Easting printf("Easting: %f, Northing %f", result.xy.x, result.xy.y); return 0; }
实际输出:
Easting: 809219.172518, Northing 358037.808510
预期输出:
Easting: 358037.808510, Northing 809219.172518
解决方案
问题根源是EPSG:2180的原生轴顺序为「北向-东向」(Northing, Easting),libproj默认保留原CRS的轴顺序,而非强制使用东-北的常规顺序。以下两种方案可解决该问题:
方案1:强制指定目标CRS轴顺序
在构造目标CRS字符串时,添加+axis=enu参数,强制使用「东-北-上」的轴顺序。
修改后的核心代码:
char _buff[100]; // 添加+axis=enu参数强制东-北顺序 snprintf(_buff, sizeof (_buff), "EPSG:%d +axis=enu", epsg_p); PJ* projEPSG_m = proj_create_crs_to_crs(projContext_m, "EPSG:4326", _buff, NULL);
方案2:动态查询轴信息调整结果
如果需要兼容所有CRS(而非仅针对EPSG:2180),可通过libproj的API查询目标CRS的轴信息,判断东、北向对应的位置后动态调整结果。
示例代码片段:
// 创建目标CRS对象用于查询轴信息 PJ* target_crs = proj_create(projContext_m, _buff); if (target_crs) { int axis_count = proj_crs_get_axis_count(projContext_m, target_crs); bool easting_is_x = false; for (int i = 0; i < axis_count; i++) { const PJ_AREA* area = nullptr; const char* axis_name = proj_crs_get_axis_name(projContext_m, target_crs, i, &area); // 判断第i个轴是否为东向 if (strcmp(axis_name, "east") == 0) { easting_is_x = (i == 0); break; } } proj_destroy(target_crs); // 根据轴顺序调整输出 double final_easting, final_northing; if (easting_is_x) { final_easting = result.xy.x; final_northing = result.xy.y; } else { final_easting = result.xy.y; final_northing = result.xy.x; } printf("Easting: %f, Northing %f\n", final_easting, final_northing); }
说明
proj_normalize_for_visualization函数仅用于简化转换管道的可视化展示,不会修改CRS的轴顺序,因此无法解决该问题。
内容的提问来源于stack exchange,提问作者zerocukor287
相关产品推荐
相关产品推荐

