Java---GDAL的使用

    xiaoxiao2021-03-25  75

    最近工作比较忙,博客就落下了,批评一下自己的,还是要每天坚持。

    最近在处理一些地图数据,格式主要是mif、tab为主。mif格式就是用文本去记录的,比较方便去解析和读取。tab格式是Mapinfo的默认格式,我没在网上找到这个格式的说明文件。于是就去找了一些开源的包来读取。

    GDAL除了能对接mif格式外,还可以读取shp、tab、sqlite、oracle等等,我通过程序看了下,一共支持73种格式的驱动。

    使用的时候需要注意下,自己的系统是32位,还是64位,去下载相应的gdal版本。

    我简单介绍下步骤

    1.下载自己适合gdal版本

    http://download.gisinternals.com/release.php

    我是64位的,用的这个

    下载解压后是这样的:

    2.创建环境变量

    在环境变量,系统变量中,增加一个GDAL_JAVA和GDAL32_DLL,变量值根据自己的存放路径来填写

    变量名:GDAL_JAVA

    变量值:E:\myenv\gdal64\release-1800-x64-dev\release-1800-x64\bin\gdal\java

    变量名:GDAL32_DLL

    变量值:E:\myenv\gdal64\release-1800-x64-dev\release-1800-x64\bin

    在系统变量中增加path变量,如果之前已经存在了,就在这个变量的值后面追加即可。

    变量名:path

    变量值:;%GDAL32_DLL%;%GDAL32_JAVA%;

    比如变量值是有Java的

    %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;

    添加后,就是

    %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;%GDAL32_DLL%;%GDAL32_JAVA%;

    此步骤完成后需要重启计算机

    3.在你自己使用的ide中新建一个工程,把release-1800-x64-dev\release-1800-x64\bin\gdal\java目录下的4个dll文件

    把E:\myenv\gdal64\release-1800-x64-dev\release-1800-x64\bin\gdal\java下面的gdal.jar文件引入到你的libraries中。比如我用的idea

    4.到此环境已经全部搭建好了,可以开始写代码了。

    我们写一个demo来测试一下

    package com.navinfo.dcs; import org.gdal.gdal.gdal; import org.gdal.ogr.*; import java.io.*; public class Demo { public static void main(String[] args) throws IOException { //指定文件的名字和路径 String strVectorFile ="D:\\testShap06.tab";// 注册所有的驱动 ogr.RegisterAll();//这个可以看到支持哪些格式的驱动,不用的时候可以注释掉 /* int count =ogr.GetDriverCount(); for(int i=0;i<count;i++){ System.out.println(ogr.GetDriver(i).GetName()); } */ // 为了支持中文路径,请添加下面这句代码 //gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","YES"); // 为了使属性表字段支持中文,请添加下面这句 gdal.SetConfigOption("SHAPE_ENCODING","CP936");/*就这个中文设置,我怎么都没搞好,一直都是乱码,有知道的同学教教我*///创建数据,这里以创建ESRI的shp文件为例 //String strDriverName = "ESRI Shapefile";//shp文件 String strDriverName = "Mapinfo file";//tab文件 //创建一个文件,根据strDriverName扩展名自动判断是创建mif文件或tab文件 org.gdal.ogr.Driver oDriver =ogr.GetDriverByName(strDriverName);if (oDriver == null) { System.out.println(strVectorFile+ " 驱动不可用!\n"); return; }// 创建数据源 DataSource oDS = oDriver.CreateDataSource(strVectorFile,null); if (oDS == null) { System.out.println("创建矢量文件【"+ strVectorFile +"】失败!\n" ); return; }// 创建图层,创建一个多边形图层,这里没有指定空间参考,如果需要的话,需要在这里进行指定//如果是mif或者tab,其实是可以多元素混合存放的,shp每个图层只能存放点线面中的一种。//所以tab创建图层的时候,选择什么都不影响后面的操作和存储结果 Layer oLayer =oDS.CreateLayer("TestPolygon", null, ogr.wkbPolygon, null); if (oLayer == null) { System.out.println("图层创建失败!\n"); return; }// 下面创建属性表 // 先创建一个叫FieldID的整型属性 FieldDefn oFieldID = new FieldDefn("FieldID", ogr.OFTInteger); oLayer.CreateField(oFieldID, 1); // 再创建一个叫FeatureName的字符型属性,字符长度为50 FieldDefn oFieldName = new FieldDefn("FieldName", ogr.OFTString); oFieldName.SetWidth(100); oLayer.CreateField(oFieldName, 1); FeatureDefn oDefn =oLayer.GetLayerDefn();// 创建三角形要素 //使用wkb方式创建几何对象 Feature oFeatureTriangle = new Feature(oDefn); oFeatureTriangle.SetField(0, 0); oFeatureTriangle.SetField(1, "三角形"); Geometry geomTriangle =Geometry.CreateFromWkt("POLYGON ((0 0,20 0,10 15,0 0))"); oFeatureTriangle.SetGeometry(geomTriangle); oLayer.CreateFeature(oFeatureTriangle); // 创建矩形要素 Feature oFeatureRectangle = new Feature(oDefn); oFeatureRectangle.SetField(0, 1); oFeatureRectangle.SetField(1, "四边形"); Geometry geomRectangle =Geometry.CreateFromWkt("POLYGON ((30 0,60 0,60 30,30 30,30 0))"); oFeatureRectangle.SetGeometry(geomRectangle); oLayer.CreateFeature(oFeatureRectangle); // 创建五角形要素 Feature oFeaturePentagon = new Feature(oDefn); oFeaturePentagon.SetField(0, 2); oFeaturePentagon.SetField(1, "五角星"); Geometry geomPentagon =Geometry.CreateFromWkt("POLYGON ((70 0,85 0,90 15,80 30,65 15,70 0))"); oFeaturePentagon.SetGeometry(geomPentagon); oLayer.CreateFeature(oFeaturePentagon); //创建line对象,因为只有一条line,所以只创建一个对象就够了 Feature oFeatureLine = new Feature(oDefn); oFeatureLine.SetField(0, 1); oFeatureLine.SetField(1, "trajectory1"); String shape = "LINESTRING(";File f = new File("c:/a.txt"); BufferedReader reader = new BufferedReader(new FileReader(f)); String strline = ""; while ((strline=reader.readLine())!=null){ String[] strs = strline.split(","); String x= strs[0]; String y= strs[1]; shape = shape +x+" "+y+","; } shape = shape.substring(0,shape.length()-1)+")"; Geometry geomLine =Geometry.CreateFromWkt(shape); oFeatureLine.SetGeometry(geomLine); oLayer.CreateFeature(oFeatureLine);//写入文件 oLayer.SyncToDisk(); oDS.SyncToDisk(); System.out.println("\n数据集创建完成!\n"); } } 这里比网上的攻略,多了一个根据txt输入来创建line对象,txt输入的格式内容为

    所有的代码全部完成,可以执行了。就是乱码问题还没解决,如果有同学知道怎么处理,请教教我,谢谢!

    转载请注明原文地址: https://ju.6miu.com/read-37657.html

    最新回复(0)