/** * @file RasterProjectBase.cpp * @brief None * @author 陈增辉 (3045316072@qq.com) * @version 2.5.0 * @date 24-6-4 * @copyright Copyright (c) Since 2024 中科卫星应用研究院 All rights reserved. */ #include #include "RasterToolBase.h" #include "gdal_priv.h" #include "ogr_spatialref.h" #include "cpl_conv.h" // for CPLMalloc() #include #include #include namespace RasterToolBase { long getProjectEPSGCodeByLon_Lat(double lon, double lat, ProjectStripDelta stripState) { long EPSGCode = 0; switch(stripState) { case ProjectStripDelta::Strip_3: { break; }; case ProjectStripDelta::Strip_6: { break; } default: { EPSGCode = -1; break; } } qDebug() << QString(" EPSG code : %1").arg(EPSGCode); return EPSGCode; } long getProjectEPSGCodeByLon_Lat_inStrip3(double lon, double lat) { // EPSG 4534 ~ 4554 3 度带 // 首先判断是否是在 中国带宽范围 // 中心经度范围 :75E ~ 135E 实际范围 73.5E ~ 136.5E, // 纬度范围 3N ~ 54N,放宽到 0N~ 60N if(73.5 <= lon && lon <= 136.5 && 0 <= lat && lat <= 60) { // 中国境内 long code = trunc((lon - 73.5) / 3) + 4534; return code; } else { // 非中国境内 使用 高斯克吕格 bool isSouth = lat < 0; // 简单判断南北半球,这里仅为示例,实际应用可能需要更细致的逻辑 long prefix = isSouth ? 327000 : 326000; // std::string prefix = isSouth ? "327" : "326"; lon = fmod(lon + 360.0, 360.0); long zone = std::floor((lon + 180.0) / 3.0); prefix = prefix + zone; return prefix; } return 0; } long getProjectEPSGCodeByLon_Lat_inStrip6(double lon, double lat) { // EPSG 4502 ~ 4512 6度带 // 首先判断是否是在 中国带宽范围 // 中心经度范围 :75E ~ 135E 实际范围 72.0E ~ 138E, // 纬度范围 3N ~ 54N,放宽到 0N~ 60N if(73.5 <= lon && lon <= 136.5 && 0 <= lat && lat <= 60) { // 中国境内 long code = trunc((lon - 72.0) / 6) + 4502; return code; } else { // 非中国境内 使用 UTM// 确定带号,6度带从1开始到60,每6度一个带 int zone = static_cast((lon + 180.0) / 6.0) + 1; bool isSouth = lon < 0; // 判断是否在南半球 long epsgCodeBase = isSouth ? 32700 : 32600; // 计算EPSG代码 long prefix = static_cast(epsgCodeBase + zone); return prefix; } return 0; } QString GetProjectionNameFromEPSG(long epsgCode) { qDebug() << "============= GetProjectionNameFromEPSG ======================"; OGRSpatialReference oSRS; // 设置EPSG代码 if(oSRS.importFromEPSG(epsgCode) != OGRERR_NONE) { qDebug() << "epsgcode not recognition"; return ""; } // 获取并输出坐标系的描述(名称) const char* pszName = oSRS.GetAttrValue("GEOGCS"); if(pszName) { qDebug() << "Coordinate system name for EPSG " + QString::number(epsgCode) << " is: " + QString::fromStdString(pszName); return QString::fromStdString(pszName); } else { qDebug() << "Unable to retrieve the name for EPSG " + QString::number(epsgCode); return ""; } // char* wkt = NULL; // // 转换为WKT格式 // oSRS.exportToWkt(&wkt); // // qDebug() << wkt; // // // 从WKT中解析投影名称,这里简化处理,实际可能需要更复杂的逻辑来准确提取名称 // std::string wktStr(wkt); // long start = wktStr.find("PROJCS[\"") + 8; // 找到"PROJCS["后的第一个双引号位置 // // 从start位置开始找下一个双引号,这之间的内容即为投影名称 // int end = wktStr.find('\"', start); // QString projName = QString::fromStdString(wktStr.substr(start, end - start)); // // // 释放WKT字符串内存 // CPLFree(wkt); // return projName; } long GetEPSGFromRasterFile(QString filepath) { qDebug() << "============= GetEPSGFromRasterFile ======================"; // QTextCodec* codec = QTextCodec::codecForLocale(); // 获取系统默认编码的文本编解码器 // QByteArray byteArray = codec->fromUnicode(filepath); // 将QString转换为QByteArray //,这个应该会自动释放 const char* charArray = byteArray.constData(); // // 获取QByteArray的const char*指针 { if(QFile(filepath).exists()){ qDebug() << "info: the image found.\n"; }else{ return -1; } GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // 注册GDAL驱动 // std::cout<GetProjectionRef(); qDebug() << QString::fromUtf8(pszProjection); // 创建SpatialReference对象 OGRSpatialReference oSRS; if(oSRS.importFromWkt((char**)&pszProjection) != OGRERR_NONE) { qDebug() << ("Error: Unable to import projection information.\n"); GDALClose(poDataset); return -1; } long epsgCode = atoi(oSRS.GetAuthorityCode(nullptr)); // 获取EPSG代码 if(epsgCode != 0) { GDALClose(poDataset); qDebug() << QString("file %1 :epsg Code %2").arg(filepath).arg(epsgCode); return epsgCode; } else { qDebug() << "EPSG code could not be determined from the spatial reference."; GDALClose(poDataset); return -1; } } } std::shared_ptr GetCenterPointInRaster(QString filepath) { qDebug() << "============= GetCenterPointInRaster ======================"; // QTextCodec* codec = QTextCodec::codecForLocale(); // 获取系统默认编码的文本编解码器 // QByteArray byteArray = codec->fromUnicode(filepath); // 将QString转换为QByteArray //,这个应该会自动释放 const char* charArray = byteArray.constData(); // // 获取QByteArray的const char*指针 GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // std::cout<GetGeoTransform(adfGeoTransform) != CE_None) { qDebug() << "Failed to get GeoTransform"; return nullptr; } double dfWidth = poDataset->GetRasterXSize(); double dfHeight = poDataset->GetRasterYSize(); // 计算中心点坐标(像素坐标) double dfCenterX = adfGeoTransform[0] + dfWidth * adfGeoTransform[1] / 2.0 + dfHeight * adfGeoTransform[2] / 2.0; double dfCenterY = adfGeoTransform[3] + dfWidth * adfGeoTransform[4] / 2.0 + dfHeight * adfGeoTransform[5] / 2.0; OGRSpatialReference oSRS; oSRS.importFromWkt(poDataset->GetProjectionRef()); if(oSRS.IsGeographic()) { qDebug() << "Center coords (already in geographic): (" + QString::number(dfCenterX) + ", " + QString::number(dfCenterY) + ")"; flag = true; x = dfCenterX; y = dfCenterY; } else { // 如果不是地理坐标系,转换到WGS84 OGRSpatialReference oSRS_WGS84; oSRS_WGS84.SetWellKnownGeogCS("WGS84"); OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation(&oSRS, &oSRS_WGS84); if(poCT == nullptr) { qDebug() << "Failed to create coordinate transformation"; return nullptr; } // double dfLon, dfLat; if(poCT->Transform(1, &dfCenterX, &dfCenterY)) { qDebug() << "Center coords (transformed to WGS84): (" + QString::number(dfCenterX) + ", " + QString::number(dfCenterY) << ")"; flag = true; x = dfCenterX; y = dfCenterY; } else { qDebug() << "Transformation failed."; } OGRCoordinateTransformation::DestroyCT(poCT); } } if(nullptr==poDataset||NULL==poDataset){}else{ GDALClose(poDataset); } if(flag) { std::shared_ptr RasterCenterPoint = std::make_shared(); RasterCenterPoint->x = x; RasterCenterPoint->y = y; RasterCenterPoint->z = 0; return RasterCenterPoint; } else { return nullptr; } } CoordinateSystemType getCoordinateSystemTypeByEPSGCode(long epsg_code) { OGRSpatialReference oSRS; if(oSRS.importFromEPSG(epsg_code) == OGRERR_NONE) { if(oSRS.IsGeographic()) { return CoordinateSystemType::GeoCoordinateSystem; } else if(oSRS.IsProjected()) { return CoordinateSystemType::ProjectCoordinateSystem; } } else { return CoordinateSystemType::UNKNOW; } } } // namespace RasterToolBase