今天和大家分享shp数据的读取入库。
程序代码使用IDEA编写,使用mybatis、gdal,数据库是postgresql,安装postGIS扩展。废话不多说,从controller层开始上代码。
@PostMapping("add")
public ReturnModel add(){
// shp文件地址。处理过程中没有做坐标转换,这里的shp数据的坐标系采用WGS84,对应的EPSG代码为4326
String shpPath = "E:\data_cd\build\build4326.shp";
// 返回给前端的模型
ReturnModel returnModel = new ReturnModel();
// 处理程序。这里仅为示例,采用同步的形式
// 一般数据处理是一个耗时操作,建议处理为异步的形式
shpService.shpHandler(returnModel, shpPath);
returnModel.setCode(1);
returnModel.setMessage("添加成功");
return returnModel;
}
service实现类
@Override
public void shpHandler(ReturnModel returnModel, String path) {
ogr.RegisterAll();
// 支持中文路径
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
// 属性表字段支持中文
gdal.SetConfigOption("SHAPE_ENCODING", "CP936");
// 打开shp文件是一个datasource对象
Driver shpDriver = ogr.GetDriverByName("ESRI Shapefile");
String info = "shp文件处理中";
if (shpDriver == null) {
info = "ESRI Shapefile 驱动不可用";
log.error(info);
returnModel.setCode(-1);
returnModel.setMessage(info);
return;
}
DataSource ds = shpDriver.Open(path);
if (ds == null) {
info = "文件打开失败";
log.error(info);
returnModel.setCode(-1);
returnModel.setMessage(info);
return;
}
Layer layer = ds.GetLayer(0);
if (layer == null) {
info = "打开图层失败";
log.error(info);
returnModel.setCode(-1);
returnModel.setMessage(info);
return;
}
// 要素数量
long count = layer.GetFeatureCount();
if (count == 0) {
info = "该文件内无数据";
log.error(info);
returnModel.setCode(-1);
returnModel.setMessage(info);
return;
}
// 获取图形和属性信息。构建入库的list
List featureList = getFeatureList(layer);
// 批量入库
shpMapper.insertFeatureList(featureList);
}
读取数据的具体实现
private List getFeatureList(Layer layer) {
// 图层id
String setid = UUID.randomUUID().toString();
long count = layer.GetFeatureCount();
String name = layer.GetName();
// 坐标系
SpatialReference spatialRef = layer.GetSpatialRef();
List featureModelList = new ArrayList<>();
for (int i = 0; i < count; i++) {
FeatureModel featureModel = new FeatureModel();
// 设置图层uuid
featureModel.setSetid(setid);
// 设置要素uuid
featureModel.setUuid(UUID.randomUUID().toString());
// 设置坐标系
featureModel.setCoordinateSystem(spatialRef.toString());
// 图形feature
Feature feature = layer.GetFeature(i);
Geometry geometry = feature.GetGeometryRef();
// WKT形式的图形字符串
String geometryWkt = geometry.ExportToWkt();
featureModel.setGeometryWKT(geometryWkt);
// 属性字段
FeatureDefn featureDefn = layer.GetLayerDefn();
int fieldCount = feature.GetFieldCount();
Map fieldMap = new HashMap<>();
for (int j = 0; j < fieldCount; j++) {
FieldDefn fieldDefn = featureDefn.GetFieldDefn(j);
int type = fieldDefn.GetFieldType();
// 字段类型
String fieldTypeName = fieldDefn.GetFieldTypeName(type);
// 属性名称
String fieldName = fieldDefn.GetName();
// 属性值
String value = feature.GetFieldAsString(j);
fieldMap.put(fieldName, value);
}
JSONObject fieldJson = new JSONObject(fieldMap);
// 属性信息存为json格式
featureModel.setFieldInfo(fieldJson.toString());
featureModelList.add(featureModel);
}
return featureModelList;
}
mapper层
@Mapper
@Repository
public interface ShpMapper {
int insertFeatureList(@Param("featureList") List featureModelList);
}
mapper.xml
insert into feature_build (uuid, setid, geometry, info, "system") values
(#{item.uuid}, #{item.setid}, ST_GeomFromText(#{item.geometryWKT}, 4326), #{item.fieldInfo},
#{item.coordinateSystem})
本文涉及到的两个model
@Data
public class ReturnModel {
// -1处理失败;0 处理中;1处理成功
private int code;
// 返回数据
private Object data;
// 返回的提示信息
private String message;
}
@Data
public class FeatureModel {
// 图形的唯一uuid
private String uuid;
// 标识每一个shp文件
private String setid;
// 坐标系
private String coordinateSystem;
// 属性信息
private String fieldInfo;
// 图形WKT串
private String geometryWKT;
}
入库结果
点击图中的眼睛按钮,可以查看图形。如果这里的图形结果不对,请查看数据的坐标系,和入库时(mapper.xml)指定的坐标系是否一致。
留言与评论(共有 0 条评论) “” |