mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-26 00:02:08 -05:00
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@3286 c8812cc2-4d05-0410-92ff-de0c093fc19c
117 lines
3.9 KiB
C++
117 lines
3.9 KiB
C++
#include <cmath>
|
|
#include <iostream>
|
|
|
|
#include <cpl_conv.h>
|
|
#include <cpl_string.h>
|
|
#include <gdal.h>
|
|
#include <gdal_priv.h>
|
|
#include <gdalwarper.h>
|
|
#include <gdal_frmts.h>
|
|
|
|
#include "qgsimagewarper.h"
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
void QgsImageWarper::warp(const QString& input, const QString& output,
|
|
double& xOffset, double& yOffset,
|
|
ResamplingMethod resampling, bool useZeroAsTrans) {
|
|
// Open input file
|
|
GDALAllRegister();
|
|
GDALDataset* hSrcDS = static_cast<GDALDataset*>(GDALOpen((const char*)input,
|
|
GA_ReadOnly));
|
|
// Setup warp options.
|
|
GDALWarpOptions *psWarpOptions = GDALCreateWarpOptions();
|
|
psWarpOptions->hSrcDS = hSrcDS;
|
|
psWarpOptions->nBandCount = hSrcDS->GetRasterCount();
|
|
psWarpOptions->panSrcBands =
|
|
(int *) CPLMalloc(sizeof(int) * psWarpOptions->nBandCount);
|
|
psWarpOptions->panDstBands =
|
|
(int *) CPLMalloc(sizeof(int) * psWarpOptions->nBandCount);
|
|
for (int i = 0; i < psWarpOptions->nBandCount; ++i) {
|
|
psWarpOptions->panSrcBands[i] = i + 1;
|
|
psWarpOptions->panDstBands[i] = i + 1;
|
|
}
|
|
psWarpOptions->pfnProgress = GDALTermProgress;
|
|
psWarpOptions->pfnTransformer = &QgsImageWarper::transform;
|
|
psWarpOptions->eResampleAlg = GDALResampleAlg(resampling);
|
|
|
|
// check the bounds for the warped raster
|
|
// order: upper right, lower right, lower left (y points down)
|
|
double x[] = { hSrcDS->GetRasterXSize(), hSrcDS->GetRasterXSize(), 0 };
|
|
double y[] = { 0, hSrcDS->GetRasterYSize(), hSrcDS->GetRasterYSize() };
|
|
int s[] = { 0, 0, 0 };
|
|
TransformParameters tParam = { mAngle, 0, 0 };
|
|
transform(&tParam, FALSE, 3, x, y, NULL, s);
|
|
double minX = 0, minY = 0, maxX = 0, maxY = 0;
|
|
for (int i = 0; i < 3; ++i) {
|
|
minX = minX < x[i] ? minX : x[i];
|
|
minY = minY < y[i] ? minY : y[i];
|
|
maxX = maxX > x[i] ? maxX : x[i];
|
|
maxY = maxY > y[i] ? maxY : y[i];
|
|
}
|
|
int newXSize = int(maxX - minX) + 1;
|
|
int newYSize = int(maxY - minY) + 1;
|
|
xOffset = -minX;
|
|
yOffset = -minY;
|
|
tParam.x0 = xOffset;
|
|
tParam.y0 = yOffset;
|
|
psWarpOptions->pTransformerArg = &tParam;
|
|
|
|
// create the output file
|
|
GDALDriver* driver = static_cast<GDALDriver*>(GDALGetDriverByName("GTiff"));
|
|
char **papszOptions = NULL;
|
|
papszOptions = CSLSetNameValue(papszOptions, "INIT_DEST", "NO_DATA");
|
|
GDALDataset* hDstDS =
|
|
driver->Create((const char*)output, newXSize, newYSize,
|
|
hSrcDS->GetRasterCount(),
|
|
hSrcDS->GetRasterBand(1)->GetRasterDataType(),
|
|
papszOptions);
|
|
for (int i = 0; i < hSrcDS->GetRasterCount(); ++i) {
|
|
GDALColorTable* cTable = hSrcDS->GetRasterBand(i+1)->GetColorTable();
|
|
if (cTable)
|
|
hDstDS->GetRasterBand(i+1)->SetColorTable(cTable);
|
|
double noData = hSrcDS->GetRasterBand(i+1)->GetNoDataValue();
|
|
if (noData != -1e10)
|
|
hDstDS->GetRasterBand(i+1)->SetNoDataValue(noData);
|
|
else if (useZeroAsTrans) {
|
|
std::cerr<<"***** Source raster has no NODATA value, using 0"<<std::endl;
|
|
hDstDS->GetRasterBand(i+1)->SetNoDataValue(0);
|
|
}
|
|
}
|
|
|
|
psWarpOptions->hDstDS = hDstDS;
|
|
|
|
// Initialize and execute the warp operation.
|
|
GDALWarpOperation oOperation;
|
|
oOperation.Initialize(psWarpOptions);
|
|
oOperation.ChunkAndWarpImage(0, 0, GDALGetRasterXSize(hDstDS),
|
|
GDALGetRasterYSize(hDstDS));
|
|
|
|
GDALDestroyWarpOptions(psWarpOptions);
|
|
delete hSrcDS;
|
|
delete hDstDS;
|
|
}
|
|
|
|
|
|
int QgsImageWarper::transform(void *pTransformerArg, int bDstToSrc,
|
|
int nPointCount, double *x, double *y,
|
|
double *z, int *panSuccess) {
|
|
TransformParameters* t = static_cast<TransformParameters*>(pTransformerArg);
|
|
double a = cos(t->angle), b = sin(t->angle), x0 = t->x0, y0 = t->y0;
|
|
for (int i = 0; i < nPointCount; ++i) {
|
|
double xT = x[i], yT = y[i];
|
|
if (bDstToSrc == FALSE) {
|
|
x[i] = x0 + a * xT - b * yT;
|
|
y[i] = y0 + b * xT + a * yT;
|
|
}
|
|
else {
|
|
x[i] = (a * (xT - x0) + b * (yT - y0)) * 1 / (pow(a, 2) + pow(b, 2));
|
|
y[i] = (-b* (xT - x0) + a * (yT - y0)) * 1 / (pow(a, 2) + pow(b, 2));
|
|
}
|
|
panSuccess[i] = TRUE;
|
|
}
|
|
return TRUE;
|
|
}
|