Java环境下GDAL / OGR环境配置与入门

  • 0.概述
  • 1.环境配置
  • 1.1 开发环境下载
  • 1.2 环境变量配置
  • 1.3java工程配置
  • 1.3.1新建Java工程
  • 1.3.2添加GDAL的jar文件并构建
  • 1.3.3 添加一个dll文件到工程
  • 2.程序开发
  • 2.1 界面搭建
  • 2.2功能实现


0.概述

先放一个图标:

java gdal 解析dxf java gdal 解析_数据


在尝试在C#环境下使用OGR之后,由于可参考的代码太少,并且C#环境下没办法构建可视化界面,并且C#会乱码。所以转向Java平台了,用Java开打GDAL和OGR的人比较多,网上代码也多,相对来说效率就更高一些了。

刚接触的时候用的还是Eclipse,还没用过IDEA,所以这篇文章也是基于Eclipse的,但是实际上两者差不多。下面是程序运行的情况,本示例仅打开Shapefile文件,关于界面显示,用到了GeoTools,后面学了之后介绍。

java gdal 解析dxf java gdal 解析_java gdal 解析dxf_02

1.环境配置

关于环境配置网上的教程太多了,但是他们有一个共同的特点,就是过于条理性不足,并且对每一步的解释不够清晰,这篇文章我把步骤分为以下三个部分,希望能更容易被理解。
在进行下面的步骤之前,请确定自己已经配置了Java环境,并且Java的环境变量已经配置完毕。

1.1 开发环境下载

所需要下载的文件就只有一个,打开这个网站,找一个合适的版本下载即可 GDAL下载地址 ,我下载的是下图的版本,也可以选择其他版本,大差不差。

java gdal 解析dxf java gdal 解析_java_03


打开下载的压缩包,可以看到下面的文件

java gdal 解析dxf java gdal 解析_数据_04


打开bin目录,众所周知,bin下面就是关键的文件了,一会这个目录要加到环境变量里面

java gdal 解析dxf java gdal 解析_Java_05


打开gdal目录,这个时候就可以看到Java目录了,里面有两个文件,是用来配置Java工程的,1.3里面会用到

java gdal 解析dxf java gdal 解析_java gdal 解析dxf_06


java gdal 解析dxf java gdal 解析_java gdal 解析dxf_07


把这些文件解压到任意一个目录下面,之后就可以开始环境变量的配置了。

1.2 环境变量配置

网上关于环境配置的方法,大都是把刚下载文件里面的dll文件一股脑的放到Java目录下面,这样有个好处,就是十分方便,但是我感觉这样会一定程度的污染到Java环境,并且当自己不像再用GDAL的时候,想要把他的组件删掉,是一件很麻烦的事情。

从原理上面来说,直接把dll文件所在目录放到环境变量里面也是可以的,并且这个方法看起来更加符合逻辑。

因此具体做法是这样的

①右键桌面计算机,点击属性

java gdal 解析dxf java gdal 解析_java_08


②点击打开界面中右侧的高级系统设计

java gdal 解析dxf java gdal 解析_java_09


③点击环境变量按钮

java gdal 解析dxf java gdal 解析_Java_10


④找到path,点击编辑

java gdal 解析dxf java gdal 解析_java_11


⑤点击新建按钮,把刚才下载文件解压目录的对文件夹加载进去,实际上不需要把这五个都加进去,但是为了避免以后再加,这次就索性全部添加进去。

java gdal 解析dxf java gdal 解析_java gdal 解析dxf_12


⑥之后一路点确定,就完成环境变量配置了,下面创建一个Java工程,在Java里面进行一些配置。

1.3java工程配置

1.3.1新建Java工程

新建工程不多说了,直接New一个空的项目就行

java gdal 解析dxf java gdal 解析_Java_13

1.3.2添加GDAL的jar文件并构建

新建一个lib文件夹,然后把1.1里面最后一张图片的后缀为jar的文件放进去

java gdal 解析dxf java gdal 解析_java gdal 解析dxf_14

=>

java gdal 解析dxf java gdal 解析_环境配置_15


之后右键这个gdal.jar,点击Build Path,把它添加到没模型构建起里面。

java gdal 解析dxf java gdal 解析_环境配置_16

1.3.3 添加一个dll文件到工程

环境配置的最后一步,就是把gdalalljni.dll文件放到java的根目录下面,具体原理我也不知道,总之放就行了

java gdal 解析dxf java gdal 解析_环境配置_17

=>

java gdal 解析dxf java gdal 解析_环境配置_18


到这里环境变量配置工作就完成了,要使用GDAL,需要把组件在java文件开头引用一下

import org.gdal.ogr.*;
import org.gdal.gdal.*;

然后使用前把这两个东西注册一下

import org.gdal.ogr.*;
import org.gdal.gdal.*;

下面就可以开始使用了。

2.程序开发

2.1 界面搭建

java的swing界面虽然看起来美观度有些欠缺,但是用起来还是没什么问题的,下面搭建一个简单的界面,详细说明放在代码注释里面,界面上面的功能并没有全部实现,只需要关注打开Shapefile这一个功能即可:

//创建一个类,继承JFrame,实现ActionListener接口
public class Plugin_PostGIS extends JFrame implements ActionListener{
	//注册一些公共组件,这其中包括了菜单栏按钮,表格,地图等等
	JMenuItem openshapefile;
	JMenuItem gdb;
	JMenuItem mdb;
	JMenuItem ConnectPostgres;
	JMenuItem discardPostgres;
	JMenuItem New;
	JMenuItem Delet;
	JMenuItem Import;
	JMenuItem Select;
	JMapPane mapPane;
	JTable table;
    MapLayerTable maptable;
    ArcDataToPostgre myArcDataToPostgre;
    Quickstart a;
    Postgis_OGR pPostgis_OGR;
    JComboBox filecombox = new JComboBox();
    JComboBox datacombox = new JComboBox();
    JButton jb2;
    JButton jb1;
    //注册GDAL
	public Plugin_PostGIS() {
		org.gdal.gdal.gdal.AllRegister();
		org.gdal.ogr.ogr.RegisterAll();
		// TODO Auto-generated method stub
		Init();
	}
	private static Map DBMAP = new HashMap<String, Object>() {
        {
            put("dbtype", "postgis");
            put("host", "localhost");
            put("port", 5432);
            put("schema", "public");
            put("database", "little_c_sharp");
            put("user", "postgres");
            put("passwd", "107530");

        }
    };
	public void Init() {
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		Dimension dm = Toolkit.getDefaultToolkit().getScreenSize();
		this.setBounds(dm.width/2-300, dm.height/2-300, 700, 700);
		this.setLayout(new BorderLayout());
		
		//菜单栏目
		JMenuBar menuBar = new JMenuBar();
		JMenu menufile = new JMenu("File");
		JMenu menudatabase = new JMenu("Database");
		openshapefile = new JMenuItem("打开OpenShapefile文件");
		gdb = new JMenuItem("打开gdb数据库");
		mdb = new JMenuItem("打开mdb数据库");
		

		ConnectPostgres = new JMenuItem("连接Postgres");
		discardPostgres = new JMenuItem("断开Postgres");
		New = new JMenuItem("新建数据表");
		Delet = new JMenuItem("删除数据表");
		Import = new JMenuItem("导入当前数据");
		Select = new JMenuItem("查询数据");
		
		openshapefile.addActionListener(this);
		Import.addActionListener(this);
		ConnectPostgres.addActionListener(this);
		discardPostgres.addActionListener(this);
			
		menuBar.add(menufile);
		menuBar.add(menudatabase);
		menufile.add(openshapefile);
		menufile.add(gdb);
		menufile.add(mdb);
		menudatabase.add(ConnectPostgres);
		menudatabase.add(discardPostgres);
		menudatabase.add(New);
		menudatabase.add(Delet);
		menudatabase.add(Import);
		menudatabase.add(Select);
		
		
		//地图容器

        mapPane = new JMapPane();
        mapPane.setBackground(Color.WHITE);
        mapPane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        
        //属性表
        table=new JTable();
        JScrollPane tablepanel=new JScrollPane(table);
        //maptable=new MapLayerTable(mapPane);
        //左侧容器
        
        
        
        
        JPanel leftJPanel=new JPanel();
        leftJPanel.setLayout(new BorderLayout());
        JPanel lefttopJPanel=new JPanel();
        JPanel leftbuttonJPanel=new JPanel();
        
        jb1=new JButton("显示");
        jb2=new JButton("读取");
        jb2.addActionListener(this);
        
        leftJPanel.add(lefttopJPanel,BorderLayout.NORTH);
        leftJPanel.add(leftbuttonJPanel,BorderLayout.SOUTH);
        
        lefttopJPanel.setLayout(new BorderLayout());
        leftbuttonJPanel.setLayout(new BorderLayout());
        
        lefttopJPanel.add(jb1,BorderLayout.CENTER);
        lefttopJPanel.add(filecombox,BorderLayout.NORTH);
        
        leftbuttonJPanel.add(jb2,BorderLayout.CENTER);
        leftbuttonJPanel.add(datacombox,BorderLayout.NORTH);
        
        
        
        
        JPanel top = new JPanel();
        top.setLayout(new BorderLayout());
        top.add(mapPane,BorderLayout.CENTER);
        top.add(leftJPanel,BorderLayout.WEST);
        
        SetComposeSize(dm,tablepanel,top,mapPane,leftJPanel,lefttopJPanel,leftbuttonJPanel);
        
        //添加控件到主界面
		this.setJMenuBar(menuBar);
		this.add(top,BorderLayout.CENTER);
		this.add(tablepanel,BorderLayout.SOUTH);
	}
	
	public void SetComposeSize(Dimension dm,JScrollPane jp,JPanel t,JMapPane jm,JPanel l,JPanel lt,JPanel jb) {
		jp.setSize(dm.width,(int)(dm.height*0.3));
		t.setSize(dm.width,(int)(dm.height*0.7));
		Dimension dtd=l.getSize();
		
		jm.setSize((int)(dtd.width*0.8),(int)(dtd.height));
        l.setSize((int)(dtd.width*0.2),(int)(dtd.height));
        Dimension ld=l.getSize();
        lt.setSize(ld.width,(int)(ld.height*0.5));
        jb.setSize(ld.width,(int)(ld.height*0.5));
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if(e.getSource()==openshapefile) {
			JFileChooser chooser=new JFileChooser();
			int returnvalue =chooser.showOpenDialog(this);
			if(returnvalue==JFileChooser.APPROVE_OPTION) {
				//File f = chooser.getSelectedFile();
				File f = new File("E:/CodeStudy/CsharpConPG/SHp/四省.shp");
				if(a==null) {
					a = new Quickstart();
				}
				String[] columnameStrings = a.openfileCol(f.getAbsolutePath());
		        String[][] data = a.openfile(f.getAbsolutePath());
		        
		        DefaultTableModel model;
		        model = new DefaultTableModel(data, columnameStrings);
		        table.setModel(model);
		        
				this.mapPane.setMapContent(a.getMapContent(f));
			}
		}
		else if(e.getSource()==ConnectPostgres) {
			if(a==null) {
				a = new Quickstart();
			}
			pPostgis_OGR=new Postgis_OGR("PG:dbname=little_c_sharp host=localhost port=5432 user=postgres password=107530");
			myArcDataToPostgre = new ArcDataToPostgre(this.DBMAP);
			List<String> names = pPostgis_OGR.getLayerNames();
			for (int i = 0; i < names.size(); i++) {
				this.datacombox.addItem(names.get(i));
			}
		}
		else if(e.getSource()==Import) {
			myArcDataToPostgre.importGdbToDatabaseSingal(a.currentDataSource.GetLayer(0), null);
		}
		else if(e.getSource()==discardPostgres) {
			myArcDataToPostgre.disconnectdatabase();
		}
		else if(e.getSource()==jb2) {
			Layer nowLayer = pPostgis_OGR.getLayerByname(datacombox.getSelectedItem().toString());
			String filepathString = pPostgis_OGR.LayerToGeoJson(nowLayer);
			File geojsonFile = new File(filepathString);
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			String[] columnameStrings = a.openfileCol(nowLayer);
	        String[][] data = a.openfile(nowLayer);
	        
	        DefaultTableModel model;
	        model = new DefaultTableModel(data, columnameStrings);
	        table.setModel(model);
	        this.mapPane.setMapContent(a.getMapContent(geojsonFile));
	        
			//this.mapPane.setMapContent(a.getMapContent(f));
		}
	}
	
}

2.2功能实现

下面是两个方法,主要是获取属性表的表头和数据,表头用一个数组表示,数据用一个二维数组表示,代码解释放在注释里面,这些数据主要用来创建DefaultTableModel用来作为JTable的数据源。

//这个函数用来获取表头
    public static String[] openfileCol(String filename) {
    //打开shapefile
		DataSource ds = ogr.Open(filename,1);
		currentDataSource=ds;
		for (int i=0;i< ds.GetLayerCount(); i++)
        {
            org.gdal.ogr.Layer layer = ds.GetLayerByIndex(i);
            //获取表头信息
            FeatureDefn pFeatureDefn = layer.GetLayerDefn();
    		String[] outst = new String[pFeatureDefn.GetFieldCount()];
    		//遍历表头,存储到outst里面用于返回
            for (int j = 0; j < pFeatureDefn.GetFieldCount(); j++)
            {
                FieldDefn fie = pFeatureDefn.GetFieldDefn(j);
                outst[j]=fie.GetName();
                //MessageBox.Show(pFeatureDefn.GetFieldDefn(j).GetNameRef().ToString());
                //MessageBox.Show(pFeatureDefn.GetFieldDefn(j).GetTypeName().ToString());
            }
    		return outst;
        }
		return null;
    }
//这个函数用来获取属性表里面的数据,输入shapefile文件名,返回存储了数据的二维数组
	public static String[][] openfile(String filename) {
		DataSource ds = ogr.Open(filename,1);
		currentDataSource=ds;
		String outst = "";
		for (int i=0;i< ds.GetLayerCount(); i++)
        {
            org.gdal.ogr.Layer layer = ds.GetLayerByIndex(i);
            FeatureDefn pFeatureDefn = layer.GetLayerDefn();
            String[][] dataut =new String[(int)layer.GetFeatureCount()][pFeatureDefn.GetFieldCount()];
            for (int j = 0; j < layer.GetFeatureCount(1); j++)
            {
            	//获取一个要素
                Feature feature = layer.GetFeature(j);
                //遍历各个要素的属性,存储到数组里面
                for(int k=0;k< pFeatureDefn.GetFieldCount(); k++)
                {
                	dataut[j][k] = feature.GetFieldAsString(k);
                }
                outst+="\n";
            }
            return dataut;
        }
		return null;
	}