赞
踩
基于前一篇文章GeoServer系列-通过mongodb发布geojson数据,业务上可将常见的地理文件统一为geojson保存到mongodb,方便统一维护和发布geoserver,这一篇将列举SHP、GDB、CAD、KML格式转geojson。
C:\Users\CDLX>gdalinfo.exe --version
GDAL 3.3.0, released 2021/04/26
<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>
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();
}
}
}
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;
}
因为转换过程较为复杂,可查看同系列下另一篇文章(ಥ _ ಥ)
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;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。