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大学的时候学过,之后就没写过了,这里基本上全是抄的,哈哈哈哈,抄得不好见谅!忘记抄的谁的了,就不注明了。

  • 相关阅读:
    sqlserver2000及以上版本导出数据到mysql里的详细图解
    JDBC和ODBC的区别何在?什么是ODBC?
    mysql ODBC 在64位下提示找不到odbc驱动问题
    Microsoft sqlserver2000如何导入.mdf格式的数据库文件
    使用navicat 链接sql server 出现08001错误
    sql语句如何转成hql语句?
    显示所有SAP图标的ABAP代码
    SMW0上传EXCEL模板时报错无分配给对象***的MIME类型
    显示小闹钟的函数
    便携计算器
  • 原文地址:https://www.cnblogs.com/webgis-ling/p/15095192.html
Copyright © 2011-2022 走看看