JAVA新实战5:Java用GDAL开发地图瓦片拼接带坐标信息的tiff文件

 1、前言       

        前两天写了个地图瓦片采集及拼接工具,在导入到geoserver使用时发生了以下错误,查找原因后发现是未在拼接的图片文件中加入坐标信息,研究了一下,发现使用GDAL可以生成带坐标信息的tiff文件,于是进行尝试JAVA项目中引入GDAL库并进行使用。

        无坐标信息的文件导入geoserver时的报错信息如下:

  • Could not list layers for this store, an error occurred retrieving them: Failed to create reader from file:workspaces/jilin/tile-merge/z1.tiff and hints Hints: REPOSITORY = org.geoserver.catalog.CatalogRepository@25e71a88 EXECUTOR_SERVICE = java.util.concurrent.ThreadPoolExecutor@32768ba7[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0] System defaults: FORCE_AXIS_ORDER_HONORING = http FILTER_FACTORY = FilterFactoryImpl LENIENT_DATUM_SHIFT = true FORCE_LONGITUDE_FIRST_AXIS_ORDER = true GRID_COVERAGE_FACTORY = GridCoverageFactory TILE_ENCODING = null LOCAL_DATE_TIME_HANDLING = true COMPARISON_TOLERANCE = 1.0E-8 STYLE_FACTORY = StyleFactoryImpl FEATURE_FACTORY = org.geotools.feature.LenientFeatureFactoryImpl@1716c774

本文所用开发环境如下:

操作系统:windows 11

Java JDK:OpenJDK21

构建工具:Gradle 8.4

开发工具:VsCode - Visual Studio Code 1.84.1

关键组件库:gdal 3.7.2    http://www.gisinternals.com/release.php 

2、下载引入GDAL库设置环境变量

        GDAL是使用C++编写的程序库,GDAL使用SWIG生成了用于在C#、Java、Python等语言中使用GDAL的接口文件,在JAVA项目中正常引用GDAL是关键的一步。

        到GDAL官网下载,并安装GDAL,有多种方式,我这里选择其中一种:

        从 http://www.gisinternals.com/release.php 下载 GDAL 核心文件包 release-1930-x64-gdal-3-7-2-mapserver-8-0-1.zip ,解压到 D:\gdal 。

        设置一系列环境变量:

添加新环境变量:
GDAL_DATA:D:\gdal\bin\gdal-data
GDAL_DRIVER_PATH:D:\gdal\bin\gdal\plugins
PROJ_LIB:D:\gdal\bin\proj9\share


现有PATH变量中添加:
D:\gdal\bin
D:\gdal\bin\gdal-data
D:\gdal\bin\gdal\java
D:\gdal\bin\gdal\apps
D:\gdal\bin\gdal\plugins-external
D:\gdal\bin\gdal\plugins-optional


  

3、将GDAL库引入JAVA项目工程

        在java项目创建lib\gdal目录,将相关.dll文件和D:\gdal\bin\gdal\java\gdal-3.7.2.jar文件复制到该目录下。

        在java项目build.gradle的dependencies代码块中增加:implementation(files("lib/gdal/gdal-3.7.2.jar")),如下图:

4、用GDAL库将坐标加入瓦片拼接图

        在java运行程序代码中引入gdal类库,如下:

        调用gdal为拼接后的图片写入经纬度信息,具体代码如下:


	/**
	 * 为拼接图增加坐标信息,生成tiff文件
	 * 
	 * @param mergeFileName 瓦片拼接图路径
	 * @param tiffFilename  生成tiff文件路径
	 */
	public static void geotiff(String mergeFileName, String tiffFilename) {

		System.out.println("生成tifff增加坐标信息。。。");

		// 注册
		gdal.AllRegister();
		/*
		 * 定义空间参考,由于WGS84是世界上比较知名的大地坐标系统,所以可以使用SetWellKnownGeogCS定义,从而简化代码。
		 * 如果要定义其他空间参考系,可以调用ImportFromEPSG方法实现,前提是该空间参考系在EPSG编码中
		 * 如果不在EPSG编码中的自定义空间参考系,可以使用wkt字符串描述空间参考系,然后调用dataset.SetProjection()来定义投影
		 */
		SpatialReference spatialReference = new SpatialReference();
		spatialReference.SetWellKnownGeogCS("WGS84");

		// 定义仿射转换参数(从设置的开始点经纬度获取)
		double[] gt = { startLon, 0.1, 0.0, startLat, 0.0, -0.1 };

		// 建立源图片数据集
		// System.out.println(mergeFileName);
		Dataset dataSoure = gdal.Open(mergeFileName, 0); // 可写状态
		int xSize = dataSoure.getRasterXSize();
		int ySize = dataSoure.getRasterYSize();

		System.out.println("X " + xSize);
		System.out.println("Y " + ySize);

		// 获取图片大小

		// // 获取驱动
		Driver driver = gdal.GetDriverByName("GTiff");
		// Dataset dataset = driver.Create(tiffFilename, xSize, ySize);
		// 获取数据集,一般来说需要指定数据类型,默认为Byte - 8位3无符号整型
		driver.CreateCopy(tiffFilename, dataSoure);

		// 获取新生成的tiff
		Dataset dataset = gdal.Open(tiffFilename, 1);
		// 配置信息含坐标存入dataset中
		dataset.SetGeoTransform(gt);
		dataset.SetSpatialRef(spatialReference);

		// 将缓存数据写入磁盘
		dataset.FlushCache();
		// 释放资源
		dataset.delete();
	}

        瓦片拼接生成结果如下:

5、GeoServer中应用时不再报错

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值