GDAL地图功能:如何正确指定经纬度的海拔(C代码) 简介我开始也是用AI搜索了一番结果都报错了。我仔细研究了数据过程发现与另外一个坐标转换的数据有点相关。于是重新设置了流程完全正确。这个肯定不是全网首发只是完整代码。提示不同ZOOM得到的海拔不一样。具体代码int wgs584_to_web(double* plon, double* plat, double* ph) { if (plon NULL || plat NULL) { return -1; } // 1. 创建源与目标的空间参考对象 OGRSpatialReferenceH hSrcSRS OSRNewSpatialReference(NULL); OGRSpatialReferenceH hDstSRS OSRNewSpatialReference(NULL); // 2. 设置为 WGS84 (EPSG:4326) 和 Web Mercator (EPSG:3857) // 这一步实际上会建立带权威定义包含坐标轴顺序的CRS OSRSetWellKnownGeogCS(hSrcSRS, WGS84); OSRSetWellKnownGeogCS(hDstSRS, WGS84); // 先设为WGS84然后下面再调整 // 更准确地设置目标CRS为Web Mercator // 注意使用 EPSG:3857 或 WGS84 投影方法但为了明确可以直接从EPSG导入。 // 但由于我们下面要用 OSRSetAxisMappingStrategy这里先用 SetWellKnownGeogCS // 再通过投影设置将其变为Web Mercator。更标准的方式是使用 OSRImportFromEPSG。 // 为清晰起见我们演示标准方式 OSRDestroySpatialReference(hSrcSRS); OSRDestroySpatialReference(hDstSRS); hSrcSRS OSRNewSpatialReference(NULL); hDstSRS OSRNewSpatialReference(NULL); OSRImportFromEPSG(hSrcSRS, 4326); OSRImportFromEPSG(hDstSRS, 3857); // 3. 【关键步骤】强制设置坐标轴映射策略为传统的GIS顺序 (经度, 纬度) // 这确保我们的输入是 (longitude, latitude)而不是 (latitude, longitude) OSRSetAxisMappingStrategy(hSrcSRS, OAMS_TRADITIONAL_GIS_ORDER); OSRSetAxisMappingStrategy(hDstSRS, OAMS_TRADITIONAL_GIS_ORDER); // 4. 创建坐标转换对象 OGRCoordinateTransformationH hTransform OCTNewCoordinateTransformation(hSrcSRS, hDstSRS); if (!hTransform) { printf(创建坐标转换失败\n); return 1; } // 5. 待转换的 WGS84 经纬度 (经度, 纬度) double lon (*plon); // 经度 double lat (*plat); // 纬度 double z 0.0; // 高程不需要可设为0 printf(转换前: 经度 %.4f, 纬度 %.4f\n, lon, lat); int ret 0; // 6. 执行坐标转换 // OCTTransform 会直接修改传入的数组 if (OCTTransform(hTransform, 1, lon, lat, z)) { printf(转换后: X (东向) %.2f, Y (北向) %.2f (Web Mercator 米)\n, lon, lat); *plon lon; *plat lat; } else { printf(坐标转换失败\n); ret -1; } // 7. 释放资源 OCTDestroyCoordinateTransformation(hTransform); OSRDestroySpatialReference(hSrcSRS); OSRDestroySpatialReference(hDstSRS); return ret; } double GetElevation(GDALDataset* poDS, double lon, double lat) { if (!poDS) return NAN; double adfGeoTransform[6]; if (poDS-GetGeoTransform(adfGeoTransform) CE_None) { printf(地理变换参数:\n); printf( 左上角 X: %f\n, adfGeoTransform[0]); printf( 像素宽度 (X方向分辨率): %f\n, adfGeoTransform[1]); printf( 行旋转系数: %f\n, adfGeoTransform[2]); printf( 左上角 Y: %f\n, adfGeoTransform[3]); printf( 列旋转系数: %f\n, adfGeoTransform[4]); printf( 像素高度 (Y方向分辨率): %f\n, adfGeoTransform[5]); } else { printf(获取地理变换参数失败\n); } double wcollon, wrowlat; wgs584_to_web(wcol, wrow, NULL); printf(wgs584_to_web:(%.4f, %.4f) - (%.4f, %.4f)\n, lon, lat, wcol, wrow); // transform to current map double map_col (wcol - adfGeoTransform[0]) / adfGeoTransform[1]; double map_row (wrow - adfGeoTransform[3]) / adfGeoTransform[5]; printf((%.4f, %.4f) - (%.4f, %.4f)\n, lon, lat, map_col, map_row); //point on map int x static_castint(round(map_col)); int y static_castint(round(map_row)); printf(x%d, y%d\n, x, y); int w poDS-GetRasterXSize(); int h poDS-GetRasterYSize(); printf(w%d, h%d\n, w, h); if (x 0 || x w || y 0 || y h) return NAN; GDALRasterBand* poBand poDS-GetRasterBand(1); if (!poBand) return NAN; double elev; CPLErr err poBand-RasterIO( GF_Read, x, y, 1, 1, elev, 1, 1, GDT_Float64, 0, 0, nullptr ); if (err ! CE_None) return NAN; return elev; } //调用 double alt GetElevation((GDALDataset*)hSrcDS, POINT_LONGITUDE, POINT_LATITUDE); if (isnan(alt)) printf(该坐标无有效海拔数据\n); else printf(经度%.4f 纬度%.4f 海拔%.2f m\n, POINT_LONGITUDE, POINT_LATITUDE, alt);