GDAL的Java配置,Java使用GDAL,Eclipse,JDK1.8
发布日期:2021-05-08 03:35:22 浏览次数:21 分类:精选文章

本文共 4821 字,大约阅读时间需要 16 分钟。

GDAL介绍:

GDAL(Geospatial Data Abstraction Library)是一个开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式。它还有一系列命令行工具来进行数据转换和处理。

GDAL使用C++开发,因此要在Java环境下使用GDAL库,要用JNI(Java跨平台调用的一种方式)的方法调用dll库。所以,我们可以下载GDAL的源码,依照官网教程,通过Visual Studio编译出可用dll。但是最简单的做法就是使用已经编译生成好的符合JNI标准的动态dll库和jar包了,推荐这个网址:,下载合适的文件。

    例如我下载的是release-1800-x64-gdal-2-2-3-mapserver-7-0-7,里面包含了编译好的GDAL以及jar包。

    下面以Eclipse的配置为例,示范如何在Java环境中调用GDAL库(此时假设所有GDAL的dll都已经编译好,或是从上面写的网址下载下来了):

1.将下载下来的压缩包解压至合适位置,内容列表如下:

2. 打开Eclipse,新建一个普通的java工程。

3.将下载下来的压缩包bin/gdal/java目录下的gdal.jar、gdalconstjni.dll、gdaljni.dll、ogrjni.dll、osrjni.dll文件拷贝到刚才新建的java工程目录下,如下图,和src目录同级。

https://img-blog.csdn.net/20180522191047718

 

4.右键gdal.jar,在弹出的菜单中选择Build Path -> Add to Build Path,将gdal.jar引入到工程环境中

https://img-blog.csdn.net/20180522191324917

    这时候写代码,Eclipse编译不会有错误,但是运行程序时会报错,于是还要进行下一步:

 

5.将下载下来的压缩包bin目录下的所有dll文件(这些文件是GDAL相关的dll文件,是GDAL_Java的dll需要调用的)拷贝至正确的位置,有很多地方可选:

1)java工程目录下(我用的是这种方法,让dll文件跟着项目一块)。

2){JAVA_HOME}jre/bin,也可以采用这种做法,将这些dll拷贝至jdk安装目录下的jre下的bin目录下。

https://img-blog.csdn.net/20180522191918654

            3)网上有人说拷贝至{windir}system32目录下,此方法没有检验过

 

6. 新建一个HelloGDAL类来执行转换,代码如下:

package com.ysq.gdal;import org.gdal.gdal.Band;import org.gdal.gdal.Dataset;import org.gdal.gdal.Driver;import org.gdal.gdal.gdal;import org.gdal.gdalconst.gdalconstConstants;import org.gdal.ogr.DataSource;//import org.gdal.ogr.Driver;import org.gdal.ogr.ogr;public class HelloGDAL {		public static void main(String[] args) {         //此处换成自己文件的位置的路径		//readGDAL("E:\\xxxxxxx.tif");		getElevationFromTif("E:\\xxxxxxx.tif");	}	/**	 * 读取tif文件的相关信息	 * @param fileName	 */	public static void readGDAL(String fileName) {		gdal.AllRegister();		//读取影像数据		Dataset dataset = gdal.Open(fileName,gdalconstConstants.GA_ReadOnly);		if(dataset == null){			System.err.println("GDALOpen failed - "+gdal.GetLastErrorNo());			System.err.println(gdal.GetLastErrorMsg());			System.exit(1);		}				Driver driver = dataset.GetDriver();		System.out.println("Driver:"+driver.getShortName()+"/"+driver.getLongName());				//读取影像信息		int xSize = dataset.getRasterXSize();		int ySize = dataset.getRasterYSize();		int bandCount = dataset.GetRasterCount();		System.out.println("size is "+xSize+","+ySize+",光带数:"+bandCount);				Band band = dataset.GetRasterBand(1);		int type = band.GetRasterDataType();		//type为1,代表的是Eight bit unsigned integer		System.out.println(type);				dataset.delete();		gdal.GDALDestroyDriverManager();	}		/**	 * shp转换geojson	 * @param shpFileName	 * @param geojsonFileName	 */	public static void shpToGeojson(String shpFileName,String geojsonFileName) {		// 注册所有的驱动		ogr.RegisterAll();	    // 为了支持中文路径,请添加下面这句代码  	    gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","YES");        // 为了使属性表字段支持中文,请添加下面这句          gdal.SetConfigOption("SHAPE_ENCODING","");        //shp文件所在的位置        //String strVectorFile = "D:\\sichuan\\sichuanPointALL.shp";        //打开数据        DataSource ds = ogr.Open(shpFileName,0);        if (ds == null)	    {        	System.out.println("打开文件失败!" );			return;        }		System.out.println("打开文件成功!" );		org.gdal.ogr.Driver dv = ogr.GetDriverByName("GeoJSON");		if (dv == null)		{			System.out.println("打开驱动失败!" );			return;		}		System.out.println("打开驱动成功!" );		//输出geojson的位置及文件名		//String geojsonFileName = "D:\\data\\sichuan.geojson";		dv.CopyDataSource(ds, geojsonFileName);		System.out.println("转换成功!");	}	/**	 * 获取每个点的高程值	 * @param fileName_tif	 */	public static void getElevationFromTif(String fileName_tif) {		gdal.AllRegister();		Dataset hDataset = gdal.Open(fileName_tif, gdalconstConstants.GA_ReadOnly);		if (hDataset == null)		{			System.err.println("GDALOpen failed - " + gdal.GetLastErrorNo());			System.err.println(gdal.GetLastErrorMsg()); 			System.exit(1);		} 		Driver hDriver = hDataset.GetDriver();		System.out.println("Driver: " + hDriver.getShortName() + "/" + hDriver.getLongName());		int iXSize = hDataset.getRasterXSize();		int iYSize = hDataset.getRasterYSize();		System.out.println("Size is " + iXSize + ", " + iYSize); 		Band band = hDataset.GetRasterBand(1);		//这里是DEM数据,所以声明一个int数组来存储,如果是其他数据类型,声明相应的类型即可		int buf[] = new int[iXSize];					for(int i=0; i<50/*iYSize*/; i++)		{			band.ReadRaster(0, i, iXSize, 1, buf);	//读取一行数据						// 下面是输出像元值,为了方便,我只输出了左上角 10×10的范围内的数据			for(int j=0; j<50/*iXSize*/; j++){				System.out.print(buf[j] + ", ");			}							System.out.println("\n");		}		hDataset.delete();				// 可选		gdal.GDALDestroyDriverManager();	}}

 

执行结果示例:

PS:运行java工程时可能的报错:

    1. 工程中只引用了gdal.jar包,没有任何gdal_java的dll

Native library load failed.

java.lang.UnsatisfiedLinkError: no gdaljni in java.library.path

Exception in thread "main" java.lang.UnsatisfiedLinkError: org.gdal.gdal.gdalJNI.AllRegister()V

       at org.gdal.gdal.gdalJNI.AllRegister(Native Method)

       at org.gdal.gdal.gdal.AllRegister(gdal.java:519)

       at com.ysq.gdal.HelloGDAL.getElevationFromTif(HelloGDAL.java:91)

       at com.ysq.gdal.HelloGDAL.main(HelloGDAL.java:17)

    2. 有引用了gdal.jar包 ,也将releasegdal_java的dll文件拷贝到正确位置,但是缺少GDAL本身的dll(即release-1800-gdal/bin下的众多dll文件)

上一篇:Win10 JDK配置环境变量以及为什么需要配置每部分的原因
下一篇:几个流行的WEB UI开源框架,备份下

发表评论

最新留言

不错!
[***.144.177.141]2025年04月17日 13时36分26秒