java 调用gdal读取gdb数据

说点废话:越来越觉得自己渺小,以前只在前端用些turf做过简单的空间分析了解ogc,后来慢慢接触到geotools,再后来发现geotools也有不顶用的时候,直到又发现了gdal,感觉打开了新世界的大门。

配置GDAL调用环境

GDAL开源读取arcgis数据(shape,ged,mdb等)的方案,由C++编写,Java可以调用

1.下载GDAL

//下载地址,不会*的话下载很慢
https://www.gisinternals.com/

//懒得下可以用我下好的
链接: https://pan.baidu.com/s/1sjLHrxBKpubO6Uwfvkj6qw 提取码: uijm 复制这段内容后打开百度网盘手机App,操作更方便哦

2.下载下来获取到文件并解压,并配置java调用环境变量

让java能调用dll文件

将解压目录下bin目录下的dll文件全部复制到java安装路径的bin目录下:C:\Program Files\Java\jdk1.8.0_171\bin

java 调用gdal读取gdb数据

并将bin/gdal/java下的dll调用文件同样复制到jdk环境下C:\Program Files\Java\jdk1.8.0_171\bin

java 调用gdal读取gdb数据

配置环境变量

java 调用gdal读取gdb数据

3.maven配置调用的jar

新建lib目录并将\bin\gdal\java\gdal.jar放到里面

java 调用gdal读取gdb数据

配置jar地址


		<dependency>
			<groupId>org.gdal</groupId>
			<artifactId>gdal</artifactId>
			<version>1.0</version>
			<scope>system</scope>
			<systemPath>${project.basedir}/lib/gdal.jar</systemPath>
		</dependency>

spring boot配置引入外部jar包打包(请注意我这里的spring boot是打包成war)

   <plugin>
           <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
               <webResources>
                  <resource>
                     <directory>lib</directory>
                     <targetPath>WEB-INF/lib/</targetPath>
                     <includes>
                        <include>**/gdal.jar</include>
                     </includes>
                  </resource>
               </webResources>
            </configuration>
         </plugin>

 

至此我们的环境设置已经完成了。


java 调用gdal

package com.ruoyi;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.ReUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.ruoyi.common.utils.JdbcUtils;
import com.ruoyi.common.utils.UnitConverionUtils;
import com.ruoyi.project.zrzy.domain.CityCode;
import com.ruoyi.project.zrzy.service.IVitUplodFileService;
import org.gdal.gdal.gdal;
import org.gdal.ogr.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Auther: jhwang
 * @Date: 2021/4/27 09:23
 * @Description:
 */
@RunWith(SpringRunner.class)   //这两个注解是为了让测试类能拥有同等的spring boot上下文环境
@SpringBootTest
public class GDBread2 {

    static {
        gdal.AllRegister();//设置gdal环境
    }

  

//    /**
//     * 从GDB中读取行政区划数据并返回
//     * 读不出来,连表查询有问题
//     * @return
//     */
//    public void selectGDBCity(String year){
//        JdbcTemplate xzqh = JdbcUtils.getJdbcTemplate("xzqh");
//        List<CityCode> query = xzqh.query(getCitySql(year),
//                (rs, rowNum) -> {
//                    CityCode cityCode = new CityCode();
//                    cityCode.setPac(rs.getString("pac"));
//                    return cityCode;
//                }
//        );
//        Console.log();
//        File[] ls = FileUtil.ls(cityFileFolder);
//        Map map = new HashMap<>();
//        Driver driver = ogr.GetDriverByName("OpenFileGDB"); //设置驱动
//        for (int i = 0; i < ls.length; i++) {
//            String filePath = ls[i].getPath();
//            String year = ReUtil.get("\\d+", ls[i].getName(), 0);
//            List<CityCode> list = new ArrayList<>();
//            DataSource dataSource = driver.Open(filePath, 0);
//            Layer querylayer = dataSource.ExecuteSQL("select DISTINCT f.pac as pac ,f.SHAPE_Area as area ,m.name as name ,m.gb as gb,m.level from (select t.pac,sum(t.SHAPE_Area) as SHAPE_Area  from (select name,gb,pac,SHAPE_Area from v_boua2 UNION select name,gb,pac,SHAPE_Area from v_boua4 UNION select name,gb,pac,SHAPE_Area from v_boua5 UNION select name,gb,pac,SHAPE_Area from v_boua6 order by gb) t group by t.pac) f left join (select name,gb,pac,SHAPE_Area,'0' as level from v_boua2 UNION select name,gb,pac,SHAPE_Area,'1' as level from v_boua4 UNION select name,gb,pac,SHAPE_Area,'2' as level from v_boua5 UNION select name,gb,pac,SHAPE_Area,'3' as level from v_boua6 ) m on m.pac  = f.pac order by f.pac");
//
//            //测试是否支持统计查询(测试完全支持统计查询)
//            //Layer querylayer = dataSource.ExecuteSQL("select sum(SHAPE_Area) as s from v_boua5");
//            //好像是不支持关联查询,有点狗了
//
//            do {//获取图层下的要素
//                Feature feature = querylayer.GetNextFeature();
//                if (null == feature) {break;}
//                CityCode cityCode = new CityCode();
//                cityCode.setPac(feature.GetFieldAsString("pac"));
//                cityCode.setArea(new BigDecimal(feature.GetFieldAsString("SHAPE_Area")));
//                cityCode.setGb(feature.GetFieldAsString("gb"));
//                cityCode.setName(feature.GetFieldAsString("name"));
//                list.add(cityCode);
//            } while (true);
//            map.put(year,list);
//        }
//        Console.log(map);
//    }

 
    private static Object getProperty(Feature feature, int index) {
        int type = feature.GetFieldType(index);
        GDBread2.PropertyGetter propertyGetter;
        if (type < 0 || type >= propertyGetters.length) {
            propertyGetter = stringPropertyGetter;
        } else {
            propertyGetter = propertyGetters[type];
        }
        try {
            return propertyGetter.get(feature, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 属性获取器
     */
    @FunctionalInterface
    private interface PropertyGetter {
        Object get(Feature feature, int index);
    }

    private static final GDBread2.PropertyGetter stringPropertyGetter = (feature, index) -> feature.GetFieldAsString(index);

    /**
     * feature.GetFieldType(index)得到一个属性类型的int值,该值对应具体类型
     */
    private static final GDBread2.PropertyGetter[] propertyGetters = new GDBread2.PropertyGetter[]{
            (feature, index) -> feature.GetFieldAsInteger(index),//0	Integer
            (feature, index) -> feature.GetFieldAsIntegerList(index),//1	IntegerList
            (feature, index) -> feature.GetFieldAsDouble(index),//2	Real
            (feature, index) -> feature.GetFieldAsDoubleList(index),//3	RealList
            stringPropertyGetter,//4	String
            (feature, index) -> feature.GetFieldAsStringList(index),//5	StringList
            stringPropertyGetter,//6	(unknown)
            stringPropertyGetter,//7	(unknown)
            (feature, index) -> feature.GetFieldAsBinary(index),//8	Binary
            (feature, index) -> {
                int[] pnYear = new int[1];
                int[] pnMonth = new int[1];
                int[] pnDay = new int[1];
                int[] pnHour = new int[1];
                int[] pnMinute = new int[1];
                float[] pfSecond = new float[1];
                int[] pnTZFlag = new int[1];
                feature.GetFieldAsDateTime(index, pnYear, pnMonth, pnDay, pnHour, pnMinute, pfSecond, pnTZFlag);
                java.sql.Date date = java.sql.Date.valueOf(LocalDate.of(pnYear[0], pnMonth[0], pnDay[0]));
                return date;
            },//9	Date
            (feature, index) -> {
                int[] pnYear = new int[1];
                int[] pnMonth = new int[1];
                int[] pnDay = new int[1];
                int[] pnHour = new int[1];
                int[] pnMinute = new int[1];
                float[] pfSecond = new float[1];
                int[] pnTZFlag = new int[1];
                feature.GetFieldAsDateTime(index, pnYear, pnMonth, pnDay, pnHour, pnMinute, pfSecond, pnTZFlag);
                float fSecond = pfSecond[0];
                int s = (int) fSecond;
                int ns = (int) (1000000000 * fSecond - s);
                Time time = Time.valueOf(LocalTime.of(pnHour[0], pnMinute[0], s, ns));
                return time;
            },// 10	Time
            (feature, index) -> {
                int[] pnYear = new int[1];
                int[] pnMonth = new int[1];
                int[] pnDay = new int[1];
                int[] pnHour = new int[1];
                int[] pnMinute = new int[1];
                float[] pfSecond = new float[1];
                int[] pnTZFlag = new int[1];
                feature.GetFieldAsDateTime(index, pnYear, pnMonth, pnDay, pnHour, pnMinute, pfSecond, pnTZFlag);
                float fSecond = pfSecond[0];
                int s = (int) fSecond;
                int ns = (int) (1000000000 * fSecond - s);
                LocalDateTime localDateTime = LocalDateTime.of(
                        LocalDate.of(pnYear[0], pnMonth[0], pnDay[0]),
                        LocalTime.of(pnHour[0], pnMinute[0], s, ns)
                );
                Timestamp timestamp = Timestamp.valueOf(localDateTime);
                return timestamp;
            },//11	DateTime
            (feature, index) -> feature.GetFieldAsInteger64(index),//12	Integer64
            (feature, index) -> feature.GetFieldAsIntegerList(index),//13 Integer64List
            //>=14	(unknown)
    };

  

    /**
     * 不存在则级联创建文件
     * @param path
     */
    private static void CreateFile(String path){
        File testFile = new File(path);
        String parent = testFile.getParent();
        if(!new File(parent).exists()){
            new File(parent).mkdirs();
        }
        if (!testFile.exists()) {
            try {
                testFile.createNewFile();// 能创建多级目录
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

 

上一篇:单片机程序中,Modbus功能码的回调函数如何编写--FreeModbus从站设计(10)


下一篇:Modbus,看这个就行了