当前位置:   article > 正文

GeoServer系列-多种文件转geojson_geoserver 发布geojson

geoserver 发布geojson

前言

基于前一篇文章GeoServer系列-通过mongodb发布geojson数据,业务上可将常见的地理文件统一为geojson保存到mongodb,方便统一维护和发布geoserver,这一篇将列举SHP、GDB、CAD、KML格式转geojson。

1,必要的依赖

  • 文件转换和解析用到了gdal,需要先下载并配置环境变量(我用的3.3),安装后可使用以下命令查看版本
C:\Users\CDLX>gdalinfo.exe --version
GDAL 3.3.0, released 2021/04/26
  • 1
  • 2
  • pom引入
    <dependencies>
        <dependency>
            <groupId>org.gdal</groupId>
            <artifactId>gdal</artifactId>
            <version>3.2.0</version>
        </dependency>
    </dependencies>
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.8.7</version>
    </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2,SHP文件转GEOJSON

shp文件一般以压缩包上传,解析时.shp文件必须与其他文件在放一起不能单独拿一个.shp文件就开始转换

    /**
     * shp压缩包转geojson
     * @param fileName
     * @param userId
     * @param fileMd5
     * @return 成功返回geojson全路径,失败返回失败描述
     */
    @Override
    public String shpToGeojson(String fileName, String userId, String fileMd5) {
        //从临时目录获取shp压缩包
        String filePath = fileDirectory + "/" + fileMd5 + userId + "/" + fileName;
        //1解压shp文件
        try {
            //shp解压目录
            File descDirFile = new File(fileDirectory + "/" + fileMd5 + userId + "/shp");
            if (descDirFile.exists()) {
                descDirFile.delete();
                descDirFile.mkdir();
            }
            ZipFile zipFile = new ZipFile(filePath, Charset.forName("GBK"));
            ZipUtil.unzip(zipFile, descDirFile);
            //2遍历解压目录找到shp文件(针对用户压缩名包与shp文件名不一致的情况)
            String shpFilePath = "";
            for (String shpfile : descDirFile.list()) {
                if (shpfile.endsWith("shp")) {
                    shpFilePath = descDirFile + "/" + shpfile;
                }
            }
            //2shp文件转geojson
            String geojsonFileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".geojson";
            String geojsonPath = fileDirectory + "/" + fileMd5 + userId + "/" + geojsonFileName;
            log.info("开始转换shp文件{}", shpFilePath);
            boolean res = toGeojson(shpFilePath, geojsonPath);
            if (res) {
                return geojsonPath;
            } else {
                return "shp转geojson失败";
            }
        } catch (Exception e) {
            log.error("shp转geojson失败:{},", filePath, e.toString());
            return "shp转geojson失败";
        }
    }
    
    /**
     * shp文件转geojson
     *
     * @param shpPath     shp文件全路径
     * @param geojsonPath 输出geojson全路径
     */
    public boolean toGeojson(String shpPath, String geojsonPath) {
        //注册所有的驱动
        ogr.RegisterAll();
        //为了支持中文路径,请添加下面这句代码
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
        //为了使属性表字段支持中文,请添加下面这句
        gdal.SetConfigOption("SHAPE_ENCODING", "");

        DataSource shpData = null;
        DataSource geojsonData = null;
        Driver driver = null;

        try {
            // 打开shp文件
            shpData = ogr.GetDriverByName("ESRI Shapefile").Open(shpPath);

            // 获取shp文件第一个图层
            Layer layer = shpData.GetLayerByIndex(0);

            // 获取geojson数据源
            driver = ogr.GetDriverByName("GeoJSON");
            geojsonData = driver.CreateDataSource(geojsonPath);
            //指定 2000坐标系
            SpatialReference epsg2000 = new SpatialReference("");
            epsg2000.ImportFromEPSG(4490);
            // 创建geojson的图层
            Layer newLayer = geojsonData.CreateLayer(layer.GetName(), epsg2000, ogr.wkbUnknown, null);
            for (int i = 0; i < layer.GetLayerDefn().GetFieldCount(); i++) {
                newLayer.CreateField(layer.GetLayerDefn().GetFieldDefn(i));
            }
            // 复制shp文件的图层到geojson图层
            layer.ResetReading();
            org.gdal.ogr.Feature feature;
            while ((feature = layer.GetNextFeature()) != null) {
                //获取空间属性
                Geometry geometry = feature.GetGeometryRef();
                //转换坐标系
                geometry.TransformTo(epsg2000);
                geometry.SwapXY();
                geometry.CloseRings();
                //传给新建的矢量图层
                Feature dstFeature = feature.Clone();
                dstFeature.SetGeometry(geometry);
                newLayer.CreateFeature(dstFeature);
            }
            return true;
        } catch (Exception e) {
            log.error("shp文件转geojson失败", e);
            return false;
        } finally {
            // 关闭数据源和驱动
            if (shpData != null) {
                shpData.delete();
            }
            if (geojsonData != null) {
                geojsonData.delete();
            }
            if (driver != null) {
                ogr.GetDriverByName("ESRI Shapefile").delete();
                ogr.GetDriverByName("GeoJSON").delete();
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113

3,GDB文件转GEOJSON

gdb文件与shp文件类似,都是压缩包上传且文件不能单独存放

    /**
     * GDB压缩包转geojson
     * @param fileName gdb文件名  xxxx.gdb.zip
     * @param fileMd5  文件md5值 123434
     * @return 成功返回null ,失败返回错误描述
     */
    @Override
    public String gdbToGeojson(String fileName, String userId, String fileMd5) {
        //1解压gdb压缩包到 D:\\ITS\\temp\\文件md5\\userId\\xxx.gdb目录下 (gdb解压目录必须是xxx.gdb,否则ogr.Open(gdbPath)始终为null)
        DataSource ds = null;
        DataSource outputDS = null;
        try {
            String name = fileName.substring(0, fileName.lastIndexOf("."));
            //D:\\ITS\\sharding\\文件md5\\xxx.gdb
            String gdbPath = fileDirectory + "/" + fileMd5 + userId + "/" + name;
            File descDirFile = new File(gdbPath);
            if (descDirFile.exists()) {
                descDirFile.delete();
                descDirFile.mkdir();
            }
            File zipFile = new File(fileDirectory + "/" + fileMd5 + userId + "/" + fileName);
            ZipUtil.unzip(zipFile, descDirFile);
            //判断压缩包下是否还有文件夹
            if (descDirFile.list().length == 1) {
                gdbPath = descDirFile + "/" + descDirFile.list()[0];
            }
            // 注册驱动程序
            ogr.RegisterAll();
            // 打开 GDB 文件
            ds = ogr.Open(gdbPath, false);
            // 获取第一个图层
            Layer layer = ds.GetLayer(0);
            // 创建 GeoJSON 文件并添加图层 D:\ITS\sharding\文件md5\xxx.gdb.geojson
            String geojsonFile = fileDirectory + "/" + fileMd5 + userId + "/" + name + ".geojson";
            Driver driver = ogr.GetDriverByName("GeoJSON");
            outputDS = driver.CreateDataSource(geojsonFile);
            //指定 2000坐标系
            SpatialReference epsg2000 = new SpatialReference("");
            epsg2000.ImportFromEPSG(4490);
            Layer outputLayer = outputDS.CreateLayer("layer", epsg2000, ogrConstants.wkbUnknown);
            // 遍历每个要素
            Feature feature = null;
            while ((feature = layer.GetNextFeature()) != null) {
                // 获取几何图形
                Geometry geometry = feature.GetGeometryRef();
                if (geometry != null) {
                    // 解决自相交问题
                    geometry = geometry.Buffer(0.0);
                    //转换坐标系
                    geometry.TransformTo(epsg2000);
                    geometry.SwapXY();
                    geometry.CloseRings();
                    // 将几何图形添加到输出图层
                    Feature outputFeature = feature.Clone();
                    outputFeature.SetGeometry(geometry);
                    outputLayer.CreateFeature(outputFeature);
                    outputFeature.delete();
                }
                feature.delete();
            }
        } catch (UtilException e) {
            log.error("gdb转geojson失败", e);
            return "gdb转geojson失败";
        } finally {
            // 释放资源
            if (outputDS != null) {
                outputDS.delete();
            }
            if (ds != null) {
                ds.delete();
            }
        }
        return null;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74

4,CAD文件转GEOJSON

因为转换过程较为复杂,可查看同系列下另一篇文章(ಥ _ ಥ)

5,KML文件转GEOJSON

    public String kmlToGeojson(String fileName,String userId, String fileMd5) {
        String kmlpath = fileDirectory + "/" + fileMd5 + userId + "/" + fileName;
        String geojsonpath = fileDirectory + "/" + fileMd5 + userId + "/" + fileName.replace("kml", "geojson");

        // 打开KML数据源
        ogr.RegisterAll();
        DataSource kmlDataSource = ogr.Open(kmlpath);

        // 获取GeoJSON驱动程序
        Driver geoJSONDriver = ogr.GetDriverByName("GeoJSON");

        // 创建输出数据源
        DataSource geoJSONDataSource = geoJSONDriver.CreateDataSource(geojsonpath);

        // 获取KML数据源的第一个图层
        org.gdal.ogr.Layer kmlLayer = kmlDataSource.GetLayer(0);

        // 将KML图层复制到GeoJSON数据源中
        geoJSONDataSource.CopyLayer(kmlLayer, "converted_layer", null);

        // 释放资源
        geoJSONDataSource.delete();
        kmlDataSource.delete();

        // 输出转换成功信息
        log.info("KML to GeoJSON conversion successful! {}", kmlpath);
        return null;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/878669
推荐阅读
  

闽ICP备14008679号