You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

400 lines
9.4 KiB
C++

2 years ago
#include "stdafx.h"
#include <opencv2\opencv.hpp>
using namespace cv;
#include "GeoTIFFEdit.h"
// tif ͼ<><CDBC>
#include <ogr_srs_api.h>
#include <ogr_spatialref.h>
#include <gdal.h>
#include <gdal_priv.h>
// <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3>
#include "SysGeoCorrect.h"
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E9B1A8><EFBFBD><EFBFBD>Ϊtiff<66>ļ<EFBFBD>
bool SaveQBDataToGeoTIFF(QBStru *qbData, string savePath)
{
try
{
if (qbData == NULL || savePath == "")
{
return false;
}
// ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>֤
if (qbData->image.bValid == false)
{
return false;
}
else
{
if ( false == SaveImgStruToGeoTIFF(&qbData->image.geoImg, savePath))
{
if (true == SysGeoCorrectImg(qbData, false)) // <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3>
{
return SaveImgStruToGeoTIFF(&qbData->image.geoImg, savePath);
}
else
{
return false;
}
}
}
}
catch(cv::Exception &e)
{
string str = e.msg;
return false;
}
catch(...)
{
return false;
}
return true;
}
//<2F><><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>GeoTiff<66><66>ʽ<EFBFBD><CABD>
//<2F><><EFBFBD>룺 1. qbData ͨ<><CDA8>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>ݽṹ<DDBD><E1B9B9>
// 2. savePath Tiff<66>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1. <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>true<75><65>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>false
bool SaveImgStruToGeoTIFF(const ImgStru *Img, string savePath)
{
try
{
if (Img == NULL || savePath == "")
{
return false;
}
// <20>ж<EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>
string postfix = savePath.substr(savePath.rfind('.') + 1, savePath.length());
if ("tif" != postfix)
{
return false;
}
// ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>֤
if (Img->ImgWidth <= 0 ||
Img->ImgHeight <= 0 ||
Img->bitcount <= 0 ||
Img->buff == NULL)
{
return false;
}
// <20><>γ<EFBFBD>ȱ߽<C8B1><DFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>֤
double NorthLat = Img->BoundingBox.NorthLat;
double SouthLat = Img->BoundingBox.SouthLat;
double WestLon = Img->BoundingBox.WestLon;
double EastLon = Img->BoundingBox.EastLon;
// γ<><CEB3><EFBFBD><EFBFBD>֤
if (NorthLat > 90 || NorthLat < -90 ||
SouthLat > 90 || SouthLat < -90 ||
NorthLat - SouthLat <= 0)
{
return false;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
if (WestLon > 180 || WestLon < -180 ||
EastLon > 180 || EastLon < -180 ||
EastLon - WestLon <= 0)
{
return false;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int ImgWidth = Img->ImgWidth;
int ImgHeight = Img->ImgHeight;
int Imgchannels = Img->bitcount / 8;
if (Img->bitcount != 8 && Img->bitcount != 24)
{
return false;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱͼ<CAB1><CDBC>
cv::Mat geoImg;
if (Img->bitcount == 8)
{
geoImg = cv::Mat(ImgHeight, ImgWidth, CV_8UC1);
}
else
{
geoImg = cv::Mat(ImgHeight, ImgWidth, CV_8UC3);
}
// <20><><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD>ֱ<EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD>
if (geoImg.empty() == true)
{
return false;
}
else
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int lineByte = ImgWidth * Img->bitcount / 8;
unsigned int imgBufSize = static_cast<unsigned int>(ImgHeight * lineByte);
memcpy(geoImg.data, Img->buff, imgBufSize);
}
// <20><>γ<EFBFBD><CEB3> <20>ֱ<EFBFBD><D6B1><EFBFBD>
double Lon_resolution = (EastLon - WestLon) / ImgWidth;
double Lat_resolution = (SouthLat - NorthLat) / ImgHeight;
// ע<><D7A2>
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD>
GDALDataset* poDstDS = NULL;
char** papszOptions = NULL;
string fomat;
fomat = "GTiff";
GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName( fomat.c_str());
double adfGeoTransform[6];
adfGeoTransform[0] = WestLon; /* top left x */
adfGeoTransform[1] = Lon_resolution;/* w-e pixel resolution */
adfGeoTransform[2] = 0; /* rotation, 0 if image is "north up" */
adfGeoTransform[3] = NorthLat; /* top left y */
adfGeoTransform[4] = 0; /* rotation, 0 if image is "north up" */
adfGeoTransform[5] = Lat_resolution;/* n-s pixel resolution */
if (Imgchannels == 1)
{
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
poDstDS = poDriver->Create( savePath.c_str(), ImgWidth, ImgHeight, 1, GDT_Byte, papszOptions );
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
poDstDS->SetGeoTransform( adfGeoTransform );
OGRSpatialReference oSRS;
char* pszWKT = NULL;
oSRS.SetWellKnownGeogCS( "WGS84" );
oSRS.exportToWkt( &pszWKT );
poDstDS->SetProjection( pszWKT );
//ң<>е<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GDALRasterBand *poBand = poDstDS->GetRasterBand( 1 );
//<2F>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>tiff<66>ļ<EFBFBD>
poBand->RasterIO( GF_Write, 0, 0, ImgWidth, ImgHeight, geoImg.data, ImgWidth, ImgHeight, GDT_Byte, 0, 0 );
GDALFlushCache( poDstDS );
GDALClose( poDstDS );
GetGDALDriverManager()->DeregisterDriver(poDriver);
GDALDestroyDriverManager();
poDstDS = NULL;
poDriver = NULL;
}
else
{
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
poDstDS = poDriver->Create( savePath.c_str(), ImgWidth, ImgHeight, 3, GDT_Byte, papszOptions );
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
poDstDS->SetGeoTransform( adfGeoTransform );
OGRSpatialReference oSRS;
char* pszWKT = NULL;
oSRS.SetWellKnownGeogCS( "WGS84" );
oSRS.exportToWkt( &pszWKT );
poDstDS->SetProjection( pszWKT );
//ң<>е<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GDALRasterBand *poBand1 = poDstDS->GetRasterBand( 1 );
GDALRasterBand *poBand2 = poDstDS->GetRasterBand( 2 );
GDALRasterBand *poBand3 = poDstDS->GetRasterBand( 3 );
std::vector<cv::Mat> planes;
cv::split(geoImg, planes);
//<2F>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>tiff<66>ļ<EFBFBD>
poBand1->RasterIO( GF_Write, 0, 0, ImgWidth, ImgHeight, planes[2].data, ImgWidth, ImgHeight, GDT_Byte, 0, 0 );
poBand2->RasterIO( GF_Write, 0, 0, ImgWidth, ImgHeight, planes[1].data, ImgWidth, ImgHeight, GDT_Byte, 0, 0 );
poBand3->RasterIO( GF_Write, 0, 0, ImgWidth, ImgHeight, planes[0].data, ImgWidth, ImgHeight, GDT_Byte, 0, 0 );
GDALFlushCache( poDstDS );
GDALClose( poDstDS );
GetGDALDriverManager()->DeregisterDriver(poDriver);
GDALDestroyDriverManager();
poDstDS = NULL;
poDriver = NULL;
}
return true;
}
catch(cv::Exception &e)
{
string str = e.msg;
return false;
}
catch(...)
{
return false;
}
}
//<2F><><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>GeoTiff<66><66>ʽ<EFBFBD><CABD>
//<2F><><EFBFBD>룺 1. Img OpenCVͼ<56><CDBC>
// 2. LBbox <20><>γ<EFBFBD>ȱ߽<C8B1>
// 3. savePath Tiff<66>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1. <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>true<75><65>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>false
bool SaveImgStruToGeoTIFF(cv::Mat& img, GeoBoundingBox& LBbox, string savePath)
{
try
{
// ͼ<><CDBC><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>֤
if (img.empty() == true || savePath == "")
{
return false;
}
if (img.type() != CV_8UC1 && img.type() != CV_8UC3)
{
return false;
}
// <20><>γ<EFBFBD>ȱ߽<C8B1><DFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>֤
double NorthLat = LBbox.NorthLat;
double SouthLat = LBbox.SouthLat;
double WestLon = LBbox.WestLon;
double EastLon = LBbox.EastLon;
// γ<><CEB3><EFBFBD><EFBFBD>֤
if (NorthLat > 90 || NorthLat < -90 ||
SouthLat > 90 || SouthLat < -90 ||
NorthLat - SouthLat <= 0)
{
return false;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
if (WestLon > 180 || WestLon < -180 ||
EastLon > 180 || EastLon < -180 ||
EastLon - WestLon <= 0)
{
return false;
}
// <20><>γ<EFBFBD><CEB3> <20>ֱ<EFBFBD><D6B1><EFBFBD>
double Lon_resolution = (EastLon - WestLon) / img.cols;
double Lat_resolution = (SouthLat - NorthLat) / img.rows;
// <20>ж<EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>
if ("tif" != savePath.substr(savePath.find_first_of('.'), savePath.length()))
{
return false;
}
// ע<><D7A2>
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD>
GDALDataset* poDstDS = NULL;
char** papszOptions = NULL;
string fomat;
fomat = "GTiff";
GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName( fomat.c_str());
double adfGeoTransform[6];
adfGeoTransform[0] = WestLon; /* top left x */
adfGeoTransform[1] = Lon_resolution;/* w-e pixel resolution */
adfGeoTransform[2] = 0; /* rotation, 0 if image is "north up" */
adfGeoTransform[3] = NorthLat; /* top left y */
adfGeoTransform[4] = 0; /* rotation, 0 if image is "north up" */
adfGeoTransform[5] = Lat_resolution;/* n-s pixel resolution */
if (img.type() == 0)
{
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
poDstDS = poDriver->Create( savePath.c_str(), img.cols, img.rows, 1, GDT_Byte, papszOptions );
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
poDstDS->SetGeoTransform( adfGeoTransform );
OGRSpatialReference oSRS;
char* pszWKT = NULL;
oSRS.SetWellKnownGeogCS( "WGS84" );
oSRS.exportToWkt( &pszWKT );
poDstDS->SetProjection( pszWKT );
//ң<>е<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GDALRasterBand *poBand = poDstDS->GetRasterBand( 1 );
//<2F>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>tiff<66>ļ<EFBFBD>
poBand->RasterIO( GF_Write, 0, 0, img.cols, img.rows, img.data, img.cols, img.rows, GDT_Byte, 0, 0 );
GDALFlushCache( poDstDS );
GDALClose( poDstDS );
GetGDALDriverManager()->DeregisterDriver(poDriver);
GDALDestroyDriverManager();
poDstDS = NULL;
poDriver = NULL;
}
else
{
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
poDstDS = poDriver->Create( savePath.c_str(), img.cols, img.rows, 3, GDT_Byte, papszOptions );
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
poDstDS->SetGeoTransform( adfGeoTransform );
OGRSpatialReference oSRS;
char* pszWKT = NULL;
oSRS.SetWellKnownGeogCS( "WGS84" );
oSRS.exportToWkt( &pszWKT );
poDstDS->SetProjection( pszWKT );
//ң<>е<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GDALRasterBand *poBand1 = poDstDS->GetRasterBand( 1 );
GDALRasterBand *poBand2 = poDstDS->GetRasterBand( 2 );
GDALRasterBand *poBand3 = poDstDS->GetRasterBand( 3 );
std::vector<cv::Mat> planes;
cv::split(img, planes);
//<2F>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>tiff<66>ļ<EFBFBD>
poBand1->RasterIO( GF_Write, 0, 0, img.cols, img.rows, planes[2].data, img.cols, img.rows, GDT_Byte, 0, 0 );
poBand2->RasterIO( GF_Write, 0, 0, img.cols, img.rows, planes[1].data, img.cols, img.rows, GDT_Byte, 0, 0 );
poBand3->RasterIO( GF_Write, 0, 0, img.cols, img.rows, planes[0].data, img.cols, img.rows, GDT_Byte, 0, 0 );
GDALFlushCache( poDstDS );
GDALClose( poDstDS );
GetGDALDriverManager()->DeregisterDriver(poDriver);
GDALDestroyDriverManager();
poDstDS = NULL;
poDriver = NULL;
}
return true;
}
catch(cv::Exception &e)
{
string str = e.msg;
return false;
}
catch(...)
{
return false;
}
}