影像数据有多种数据处理,上一篇写的影像切割,这里我又写了影像的合并,两个影像数据, 由于分辨率不同,折腾了大半天,调整为相同分辨率后,进行的数据合并(暂时只支持两个数据的合并,批量合并以后再考虑)。我的测试数据是一个县区数据,所以影像边界有无数据块,这里我做了处理,合并数据左边无数据块就不会压盖在源影像上了。还有我这是测试代码, 所以七参数的设置你们要自己弄清楚。
package GDALExample.TIFRead;
import java.io.File;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.Driver;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;
/**
* 影像合并
*/
public class TifMerge {
static int bandNum = -1;
static String fileName_tif = "D:\\DATA\\new.tif";
static int rCount = -1;
static String strTIFPath = "D:\\DATA\\clip";
static int dataType = -1;
static int TIFWidth = 1000;
static int TIFHeight = 1000;
static double[][] geoTransform = null;
public static void main(String[] args) {
if (gdal.GetDriverCount() < 1)
gdal.AllRegister();
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); // 支持中文路径
String outPath = "D:\\temptemp\\clip";
File f8 = new File(strTIFPath);
File[] ff = f8.listFiles();
double[] dCoor = getLeftTopCoor(ff);
// MergeTIF(outPath, ff, dCoor, TIFWidth, TIFHeight);
MergeTIFNew(outPath, ff, dCoor, TIFWidth, TIFHeight);
}
// 获取左上角坐标点,以及计算合并后影像的长与宽
private static double[] getLeftTopCoor(File[] ff) {
double[] dCoorLeftTop = new double[] { -99999, -999999 };
double[] dCoorRightButton = new double[] { -99999, -999999 };
geoTransform = new double[2][4];
int[][] TIFRange = new int[2][2];
int iLength = 0;
for (int i = 0; i < ff.length; i++) {
if (!ff[i].getPath().toLowerCase().endsWith(".tif"))
continue;
// 宽、高、波段数
Dataset dsTIF = gdal.Open(ff[i].getPath(), gdalconstConstants.GA_ReadOnly);
// 从波段中获取影像的数据类型,gdal中波段索引从1开始
dataType = dsTIF.GetRasterBand(1).GetRasterDataType();
TIFRange[iLength][0] = dsTIF.getRasterXSize();
TIFRange[iLength][1] = dsTIF.getRasterYSize();
System.out.println(ff[i].getPath());
// 六参数信息
geoTransform[iLength] = dsTIF.GetGeoTransform();
if (dCoorLeftTop[0] == -99999) {
dCoorLeftTop[0] = geoTransform[iLength][0];
dCoorLeftTop[1] = geoTransform[iLength][3];
dCoorRightButton[0] = geoTransform[iLength][0] + dsTIF.getRasterXSize() * geoTransform[iLength][1];
dCoorRightButton[1] = geoTransform[iLength][3] + dsTIF.getRasterYSize() * geoTransform[iLength][5];
} else {
if (dCoorLeftTop[0] > geoTransform[iLength][0])
dCoorLeftTop[0] = geoTransform[iLength][0];
if (dCoorLeftTop[1] < geoTransform[iLength][3])
dCoorLeftTop[1] = geoTransform[iLength][3];
if (dCoorRightButton[0] < geoTransform[iLength][0] + dsTIF.getRasterXSize() * geoTransform[iLength][1])
dCoorRightButton[0] = geoTransform[iLength][0] + dsTIF.getRasterXSize() * geoTransform[iLength][1];
if (dCoorRightButton[1] > geoTransform[iLength][3] + dsTIF.getRasterYSize() * geoTransform[iLength][5])
dCoorRightButton[1] = geoTransform[iLength][3] + dsTIF.getRasterYSize() * geoTransform[iLength][5];
}
iLength++;
dsTIF.delete();
}
// TIFWidth = (int) ((dCoorLeftTop[0] - dCoorRightButton[0]) /
// geoTransform[0][5]);
// TIFHeight = (int) ((dCoorRightButton[1] - dCoorLeftTop[1]) /
// geoTransform[0][5]);
TIFWidth = (int) ((geoTransform[1][0] - geoTransform[0][0]) * (geoTransform[1][1] / geoTransform[0][1])
+ TIFRange[0][0]);
TIFHeight = (int) (-(geoTransform[1][3] - geoTransform[0][3]) * (geoTransform[1][5] / geoTransform[0][5])
+ TIFRange[1][0]);
return dCoorLeftTop;
}
//同分辨率数据的合并
public static void MergeTIF(String outPath, File[] ff, double[] startCoor, int clipWidth, int clipHeight) {
Driver driver = gdal.GetDriverByName("GTIFF");
Dataset outputDs = null;
Dataset dsSourceTIF = null;
double[] SourceTransform = null;
for (int n = 0; n < ff.length; n++) {
if (!ff[n].getPath().toLowerCase().endsWith(".tif"))
continue;
dsSourceTIF = gdal.Open(ff[n].getPath(), gdalconstConstants.GA_ReadOnly);
double[] ObjGeoTransform = dsSourceTIF.GetGeoTransform();
rCount = dsSourceTIF.getRasterCount();
// 从波段中获取影像的数据类型,gdal中波段索引从1开始
dataType = dsSourceTIF.GetRasterBand(1).GetRasterDataType();
double dCurrYcoor = ObjGeoTransform[3];
// 六参数信息
if (SourceTransform == null) {
outputDs = driver.Create(fileName_tif, clipWidth, clipHeight, rCount, dataType);
dataType = dsSourceTIF.GetRasterBand(1).GetRasterDataType();
SourceTransform = dsSourceTIF.GetGeoTransform();
SourceTransform[0] = startCoor[0];
SourceTransform[3] = startCoor[1];
outputDs.SetGeoTransform(SourceTransform);
outputDs.SetProjection(dsSourceTIF.GetProjection());
}
// 按band读取
byte[] cache = new byte[dsSourceTIF.getRasterYSize() * rCount];
int[] bands = new int[] { 1, 2, 3 };
int iSourceX = dsSourceTIF.getRasterXSize();
int iSourceY = dsSourceTIF.getRasterYSize();
int iWriteX = (int) ((SourceTransform[0] - ObjGeoTransform[0]) / SourceTransform[5]);
int iWriteY = (int) ((SourceTransform[3] - ObjGeoTransform[3]) / SourceTransform[1]);
for (int i = 0; i < dsSourceTIF.getRasterYSize(); i++) {
dsSourceTIF.ReadRaster(0, i, iSourceX, 1, iSourceY, 1, dataType, cache, bands);
outputDs.WriteRaster(iWriteX, iWriteY + i, iSourceX, 1, iSourceY, 1, dataType, cache, bands);
}
outputDs.FlushCache();
System.out.println(ff[n].getPath());
}
outputDs.delete();
// 释放资源
dsSourceTIF.delete();
}
/**
* 重采样,设置影像缩放
* 2500*2500 转换为 5000*5000
*
* @param outPath
* @param ff
* @param startCoor
* @param clipWidth
* @param clipHeight
*/
public static void ResampleTIF(String outPath, File[] ff, double[] startCoor, int clipWidth, int clipHeight) {
Driver driver = gdal.GetDriverByName("GTIFF");
Dataset dsSourceTIF = null;
String[] ppszOptions = null;
// ppszOptions = new String[] { "BIGTIFF", "IF_NEEDED" }; // 配置图像信息
dsSourceTIF = gdal.Open("D:\\temptemp\\clip\\4401162012ikdom24.TIF", gdalconstConstants.GA_ReadOnly);
if (dsSourceTIF == null) {
System.out.println("Can't Open Image!");
System.exit(0);
}
int imgWidth = dsSourceTIF.GetRasterXSize(); // 图像宽度
int imgHeight = dsSourceTIF.GetRasterYSize(); // 图像高度
int bandNum = dsSourceTIF.GetRasterCount(); // 波段数
int depth = gdal.GetDataTypeSize(dsSourceTIF.GetRasterBand(1).GetRasterDataType()) / 8; // 图像深度
int bufWidth = dsSourceTIF.GetRasterXSize();
int bufHeight = dsSourceTIF.GetRasterYSize();
Dataset dst = driver.Create(fileName_tif, 5000, 5000, bandNum, 1, ppszOptions);
if (dst == null) {
System.out.println("Can't Write Image!");
return;
}
dst.SetGeoTransform(dsSourceTIF.GetGeoTransform());
// 申请buf
int imgBufNum = bufWidth * bufHeight * bandNum * depth;
int imgBufOffset = bufWidth * (bufHeight - 1) * bandNum * depth;
byte[] imgBuf = new byte[imgBufNum];
int[] iBand = new int[] { 1, 2, 3 };
// 读取
dsSourceTIF.ReadRaster(0, 0, imgWidth, imgHeight, imgWidth, imgHeight, gdalconstConstants.GDT_Byte, imgBuf,
iBand);
// 写入
dst.WriteRaster(0, 0, imgWidth * 2, imgHeight * 2, imgWidth, imgHeight, gdalconstConstants.GDT_Byte, imgBuf,
iBand);
dsSourceTIF.delete();
dst.delete();
}
/**
* 不同分辨率影像合并
*
* @param outPath
* @param ff
* @param startCoor
* @param clipWidth
* @param clipHeight
*/
public static void MergeTIFNew(String outPath, File[] ff, double[] startCoor, int clipWidth, int clipHeight) {
Driver driver = gdal.GetDriverByName("GTIFF");
Dataset outputDs = null;
Dataset dsSourceTIF = null;
double[] SourceTransform = null;
for (int n = 0; n < ff.length; n++) {
if (!ff[n].getPath().toLowerCase().endsWith(".tif"))
continue;
dsSourceTIF = gdal.Open(ff[n].getPath(), gdalconstConstants.GA_ReadOnly);
double[] ObjGeoTransform = dsSourceTIF.GetGeoTransform();
rCount = dsSourceTIF.getRasterCount();
// 从波段中获取影像的数据类型,gdal中波段索引从1开始
dataType = dsSourceTIF.GetRasterBand(1).GetRasterDataType();
double dCurrYcoor = ObjGeoTransform[3];
// 六参数信息
if (SourceTransform == null) {
outputDs = driver.Create(fileName_tif, clipWidth, clipHeight, rCount, dataType);
dataType = dsSourceTIF.GetRasterBand(1).GetRasterDataType();
SourceTransform = dsSourceTIF.GetGeoTransform();
SourceTransform[0] = startCoor[0];
SourceTransform[3] = startCoor[1];
outputDs.SetGeoTransform(SourceTransform);
outputDs.SetProjection(dsSourceTIF.GetProjection());
}
// 按band读取
byte[] cache = new byte[dsSourceTIF.getRasterYSize() * rCount];
int[] bands = new int[] { 1, 2, 3 };
int iSourceX = dsSourceTIF.getRasterXSize();
int iSourceY = dsSourceTIF.getRasterYSize();
int iWriteX = (int) ((SourceTransform[0] - ObjGeoTransform[0]) / SourceTransform[5]);
int iWriteY = (int) ((SourceTransform[3] - ObjGeoTransform[3]) / SourceTransform[1]);
for (int i = 0; i < dsSourceTIF.getRasterYSize(); i++) {
dsSourceTIF.ReadRaster(0, i, iSourceX, 1, iSourceY, 1, dataType, cache, bands);
int sNoData = 0;
for (sNoData = 0; sNoData < cache.length; sNoData++) {
if (cache[sNoData] == 0)
sNoData++;
else
break;
}
dsSourceTIF.ReadRaster(0 + sNoData, i, iSourceX - sNoData, 1, iSourceY, 1, dataType, cache, bands);
outputDs.WriteRaster(iWriteX + sNoData, iWriteY + i, iSourceX - sNoData, 1, iSourceY, 1, dataType, cache, bands);
}
outputDs.FlushCache();
// 释放资源
dsSourceTIF.delete();
System.out.println(ff[n].getPath());
}
outputDs.delete();
}
}