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
  • 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>

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();
            }
        }
    }

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;
    }

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;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

占星安啦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值