zoukankan      html  css  js  c++  java
  • Java调用开源GDAL解析dxf成shp,再调用开源GeoTools解析shp文件

    • 需求

        最近项目要做国产化,有一个导入CAD的功能需要修改。要换成开源的或者国产的技术去解析CAD。DWG格式的,懂的都懂,开源的不可能解析,国产收费的那些CAD公司,个人认为也是买的AutoCAD的接口解析的。所以我们只能改成解析CAD的另一种文件格式:DXF文件。

    • 方案

        解析dxf用开源的GDAL,调用GDAL驱动把dxf转成shp文件,然后再用开源的GeoTools去解析shp文件。

        GDAL的依赖下载地址:https://www.gisinternals.com/release.php

        调用GDAL动态链接库:

          windows系统:

            (1)第一种简单粗暴的方式就是把gdal包bin目录下所有的dll文件和bingdaljava下的dll文件丢到你的JDK的bin目录下,对应的jar包也许在ingdaljava目录下。

            (2)第二种是自己新建一个文件夹把需要的dll文件全放在一起,然后自己配环境变量(总之让系统能找到你的库就行了)。

          Linux和docker镜像:

             在Linux上,gdal官网上没有编译好的包,要自己去下gdal的源码包,然后自己编译,后面会生成.so文件和jar包,和windows一样可以配置环境变量或者把so文件丢到jdk的bin目录下。

             docker镜像,可以去dockerhub(https://hub.docker.com/r/osgeo/gdal/tags?page=1&ordering=last_updated)下载镜像,然后镜像里边会有相应的jar包和so文件(一般比较大的镜像才会有),可以直接拿里边的jar包和so文件来用。或者直接在镜像里部署应用也可以。docker镜像的jar包和so文件不知道在linux上能不能用,按道理应该可以吧,这个没试过。但是docker镜像上的好像有系统的区别?(还有好多疑问啊,后面遇到了再验证吧)。

          注意:jar包和so文件是一一对应的,就是镜像里的jar包和你自己编译生成的so文件不能配合使用,但是windows上调用dll动态链接库,用到的jar包却不讲究,不管是docker还是linux上的jar包都可以用(至少我在项目中测试是这样的,我也不知道为啥)

        GeoTools包下载地址(也可以用maven):https://sourceforge.net/projects/geotools/files/

    • 代码

      

    DXF转SHP代码片段:
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.nio.charset.Charset;
    import java.util.*;
    
    import org.geotools.data.shapefile.ShapefileDataStore;
    import org.opengis.feature.Property;
    import org.opengis.feature.simple.SimpleFeature;
    import org.opengis.feature.simple.SimpleFeatureType;
    import org.geotools.data.FeatureSource;
    import org.geotools.feature.FeatureCollection;
    import org.geotools.feature.FeatureIterator;
    
    import org.gdal.gdal.gdal;
    import org.gdal.ogr.DataSource;
    import org.gdal.ogr.Driver;
    import org.gdal.ogr.Layer;
    import org.gdal.ogr.ogr;
    
    public String getDxfData() throws Exception{
                
                //dxf文件路径
                String filePath ="C:\WorkSpace\rect_field_demo.dxf";
                // 注册所有的驱动
                ogr.RegisterAll();
                gdal.SetConfigOption("DXF_ENCODING","UTF-8");
                gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","YES");//支持中文路径
                gdal.SetConfigOption("SHAPE_ENCODING","CP936");//属性表字段支持中文
                DataSource ds = ogr.Open(filePath,1);
                if (ds == null)
                {
                    System.out.println("打开文件失败!" );
                    return null;
                }
                System.out.println("打开文件成功!" );
                Layer oLayer = ds.GetLayerByIndex(0);
                if(oLayer == null){
                    System.out.println("获取失败");
                    return null;
                }
                oLayer.ResetReading();
                Driver dv = ogr.GetDriverByName("ESRI Shapefile"); //调用驱动转shp
                String extfile = "C:\WorkSpace\rect_field_demo.shp";
                DataSource dataSource = dv.CopyDataSource(ds, extfile);//创建shp文件并写入内容
                dataSource.delete();    //释放与数据源对象关联的本机资源并关闭文件(这句非常重要,如果没有关闭文件,那么下面的解析shp就解析不了)
                String geometry = getShpData("C:\WorkSpace\rect_field_demo.shp",coordInfo);
    
                return geometry;
    
            }
    解析shp文件public static String getShpData(String filePath) throws Exception {
            File file = new File(filePath);
            long fileSize = file.length();
            List<Map<String,Object>> list = new ArrayList<Map<String, Object>>();
            ShapefileDataStore shpDataStore = new ShapefileDataStore(file.toURL());
            shpDataStore.setStringCharset(Charset.forName("GBK"));
            String typeName = shpDataStore.getTypeNames()[0];
            FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = null;
            featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>)shpDataStore.getFeatureSource(typeName);//这里我看了很多人的博客都没有指定类(FeatureSource<SimpleFeatureType, SimpleFeature>),难道不会报错吗,反正我的会
            FeatureCollection<SimpleFeatureType, SimpleFeature> result = featureSource.getFeatures();
    
            FeatureIterator<SimpleFeature> itertor = result.features();
            while (itertor.hasNext())
            {
                Map<String,Object> data  = new HashMap<String, Object>();
                SimpleFeature feature = itertor.next();
                Collection<Property> p = feature.getProperties();
                Iterator<Property> it = p.iterator();
                while(it.hasNext()) {
                    Property pro = it.next();
                    String field = pro.getName().toString();
                    String value = pro.getValue().toString();
                    field = field.equals("the_geom")?"wkt":field;
                    data.put(field, value);
                }
                list.add(data);
            }
            JSONArray jsonarray = JSONArray.fromObject(list);
            return jsonarray.toString();
        }

    ps:Java大学的时候学过,之后就没写过了,这里基本上全是抄的,哈哈哈哈,抄得不好见谅!忘记抄的谁的了,就不注明了。

  • 相关阅读:
    用wamp配置的环境,想用CMD连接mysql怎么连
    Mysql删除表
    MySQL创建表
    Leetcode 130. Surrounded Regions
    Leetcode 111. Minimum Depth of Binary Tree
    Leetcode 110. Balanced Binary Tree
    Leetcode 98. Validate Binary Search Tree
    Leetcode 99. Recover Binary Search Tree
    Leetcode 108. Convert Sorted Array to Binary Search Tree
    Leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal
  • 原文地址:https://www.cnblogs.com/webgis-ling/p/15095192.html
Copyright © 2011-2022 走看看