gdal影像数据合并

gdal影像数据合并

影像数据有多种数据处理,上一篇写的影像切割,这里我又写了影像的合并,两个影像数据, 由于分辨率不同,折腾了大半天,调整为相同分辨率后,进行的数据合并(暂时只支持两个数据的合并,批量合并以后再考虑)。我的测试数据是一个县区数据,所以影像边界有无数据块,这里我做了处理,合并数据左边无数据块就不会压盖在源影像上了。还有我这是测试代码, 所以七参数的设置你们要自己弄清楚。

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();
	}
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值