package org.springblade.common.utils;
|
|
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.text.CharSequenceUtil;
|
import com.alibaba.fastjson.JSONObject;
|
import org.geotools.data.*;
|
import org.geotools.data.shapefile.ShapefileDataStore;
|
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
|
import org.geotools.feature.FeatureCollection;
|
import org.geotools.feature.FeatureIterator;
|
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
|
import org.geotools.geojson.feature.FeatureJSON;
|
import org.geotools.referencing.CRS;
|
import org.locationtech.jts.geom.*;
|
import org.locationtech.jts.io.ParseException;
|
import org.locationtech.jts.io.WKTReader;
|
import org.opengis.feature.GeometryAttribute;
|
import org.opengis.feature.simple.SimpleFeature;
|
import org.opengis.feature.simple.SimpleFeatureType;
|
import org.opengis.filter.Filter;
|
import org.opengis.referencing.FactoryException;
|
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
import org.springblade.core.log.exception.ServiceException;
|
|
import java.io.File;
|
import java.io.IOException;
|
import java.io.Serializable;
|
import java.io.StringWriter;
|
import java.nio.charset.StandardCharsets;
|
import java.util.*;
|
|
public class ShapeFileUtil {
|
|
/**
|
* 导出shp文件
|
*
|
* @param dataPropertiesList 属性列表{属性名:属性值}
|
* @param fileName 导出shp文件名
|
* @param geomType geometry类型
|
* @param saveFolder 导出位置
|
*/
|
public static void exportShp(List<Map<String, Object>> dataPropertiesList,
|
String fileName,
|
String geomType,
|
String saveFolder) {
|
String path = saveFolder + "/" + fileName;
|
//创建保存shp文件夹
|
File dir = new File(path);
|
if (!dir.exists()) {
|
FileUtil.mkdir(dir);
|
}
|
//shp文件路径
|
String shpFileName = fileName + ".shp";
|
String fileUrl = path+ "/" + shpFileName;
|
File file = new File(fileUrl);
|
|
FeatureWriter<SimpleFeatureType, SimpleFeature> writer = null;
|
ShapefileDataStore ds = null;
|
try {
|
Map<String, Serializable> params = new HashMap<>();
|
params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
|
ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
|
|
//定义图形信息和属性信息
|
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
|
//设置坐标系
|
CoordinateReferenceSystem crs84 = CRS.decode("EPSG:4326", true);
|
tb.setCRS(crs84);
|
//设置文件名
|
tb.setName(fileName);
|
|
//定义导出shp文件地块属性名称
|
String geomProperty = "the_geom";
|
String idProperty = "ID";
|
String nameProperty = "name";
|
String firmIdProperty = "firmId";
|
String firmNameProperty = "firmName";
|
|
//设置图形类型
|
if ("Polygon".equals(geomType)) {
|
tb.add(geomProperty, Polygon.class);
|
} else if ("MultiPolygon".equals(geomType)) {
|
tb.add(geomProperty, MultiPolygon.class);
|
} else if ("Point".equals(geomType)) {
|
tb.add(geomProperty, Point.class);
|
} else if ("MultiPoint".equals(geomType)) {
|
tb.add(geomProperty, MultiPoint.class);
|
} else if ("LineString".equals(geomType)) {
|
tb.add(geomProperty, LineString.class);
|
} else if ("MultiLineString".equals(geomType)) {
|
tb.add(geomProperty, MultiLineString.class);
|
} else {
|
throw new ServiceException("Geometry中没有该类型:" + geomType);
|
}
|
//设置对应属性类型
|
tb.add(idProperty, String.class);
|
tb.add(nameProperty, String.class);
|
tb.add(firmIdProperty, String.class);
|
tb.add(firmNameProperty, String.class);
|
|
//设置默认geometry
|
tb.setDefaultGeometry(geomProperty);
|
//创建
|
ds.createSchema(tb.buildFeatureType());
|
ds.setCharset(StandardCharsets.UTF_8);
|
|
//设置Writer
|
writer = ds.getFeatureWriter(ds.getTypeNames()[0],
|
Transaction.AUTO_COMMIT);
|
SimpleFeature feature;
|
for (Map<String, Object> map : dataPropertiesList) {
|
feature = writer.next();
|
//属性赋值 geometry要赋值wkt格式的
|
if (map.containsKey("geometry")) {
|
feature.setAttribute(geomProperty, new WKTReader().read((MapUtil.getStr(map, "geometry"))));
|
}
|
feature.setAttribute(idProperty, MapUtil.getStr(map, idProperty));
|
feature.setAttribute(nameProperty, MapUtil.getStr(map, nameProperty));
|
feature.setAttribute(firmIdProperty, MapUtil.getStr(map, firmIdProperty));
|
feature.setAttribute(firmNameProperty, MapUtil.getStr(map, firmNameProperty));
|
// String description = MapUtil.getStr(map, "描述");
|
// if (CharSequenceUtil.isNotBlank(description)) {
|
// feature.setAttribute(descriptionProperty, description);
|
// }
|
}
|
writer.write();
|
} catch (IOException | FactoryException | ParseException e) {
|
e.printStackTrace();
|
} finally {
|
//关闭相关流
|
try {
|
if (writer != null) {
|
writer.close();
|
}
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
if (ds != null) {
|
ds.dispose();
|
}
|
}
|
}
|
|
/**
|
* 导出shp文件
|
*
|
* @param map 属性列表{属性名:属性值}
|
* @param fileName 导出shp文件名
|
* @param geomType geometry类型
|
* @param saveFolder 导出位置
|
*/
|
public static void exportShp(Map<String, Object> map,
|
String fileName,
|
String geomType,
|
String saveFolder) {
|
String path = saveFolder + "/" + fileName;
|
//创建保存shp文件夹
|
File dir = new File(path);
|
if (!dir.exists()) {
|
FileUtil.mkdir(dir);
|
}
|
//shp文件路径
|
String shpFileName = fileName + ".shp";
|
String fileUrl = path+ "/" + shpFileName;
|
File file = new File(fileUrl);
|
|
FeatureWriter<SimpleFeatureType, SimpleFeature> writer = null;
|
ShapefileDataStore ds = null;
|
try {
|
Map<String, Serializable> params = new HashMap<>();
|
params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
|
ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
|
|
//定义图形信息和属性信息
|
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
|
//设置坐标系
|
CoordinateReferenceSystem crs84 = CRS.decode("EPSG:4326", true);
|
tb.setCRS(crs84);
|
//设置文件名
|
tb.setName(fileName);
|
|
//定义导出shp文件地块属性名称
|
String geomProperty = "the_geom";
|
String idProperty = "ID";
|
String nameProperty = "name";
|
|
//设置图形类型
|
if ("Polygon".equals(geomType)) {
|
tb.add(geomProperty, Polygon.class);
|
} else if ("MultiPolygon".equals(geomType)) {
|
tb.add(geomProperty, MultiPolygon.class);
|
} else if ("Point".equals(geomType)) {
|
tb.add(geomProperty, Point.class);
|
} else if ("MultiPoint".equals(geomType)) {
|
tb.add(geomProperty, MultiPoint.class);
|
} else if ("LineString".equals(geomType)) {
|
tb.add(geomProperty, LineString.class);
|
} else if ("MultiLineString".equals(geomType)) {
|
tb.add(geomProperty, MultiLineString.class);
|
} else {
|
throw new ServiceException("Geometry中没有该类型:" + geomType);
|
}
|
//设置对应属性类型
|
tb.add(idProperty, String.class);
|
tb.add(nameProperty, String.class);
|
|
//设置默认geometry
|
tb.setDefaultGeometry(geomProperty);
|
//创建
|
ds.createSchema(tb.buildFeatureType());
|
ds.setCharset(StandardCharsets.UTF_8);
|
|
//设置Writer
|
writer = ds.getFeatureWriter(ds.getTypeNames()[0],
|
Transaction.AUTO_COMMIT);
|
SimpleFeature feature;
|
feature = writer.next();
|
//属性赋值 geometry要赋值wkt格式的
|
feature.setAttribute(geomProperty, new WKTReader().read((MapUtil.getStr(map, "geometry"))));
|
feature.setAttribute(idProperty, MapUtil.getStr(map, idProperty));
|
feature.setAttribute(nameProperty, MapUtil.getStr(map, nameProperty));
|
writer.write();
|
} catch (IOException | FactoryException | ParseException e) {
|
e.printStackTrace();
|
} finally {
|
//关闭相关流
|
try {
|
if (writer != null) {
|
writer.close();
|
}
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
if (ds != null) {
|
ds.dispose();
|
}
|
}
|
}
|
|
/**
|
* 将文件解压
|
* @param zipFile
|
* @return
|
* @throws IOException
|
*/
|
public static FeatureCollection getFeatureCollectionByShpFile(File zipFile) throws IOException {
|
try {
|
String tempDir = FileUtil.getTmpDirPath();
|
File shapeDir = new File(tempDir + File.separator + new Date().getTime());
|
shapeDir.mkdir();
|
List<String> files = ZipUtil.unZipFiles(zipFile, shapeDir.getPath() + File.separator);
|
String shapFileName = "";
|
for (String fileName : files) {
|
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
|
if ("shp".equals(suffix)) {
|
shapFileName = fileName;
|
}
|
}
|
File shapeFile = new File(shapFileName);
|
Map<String, Object> shapeFileParams = new HashMap();
|
shapeFileParams.put("url", shapeFile.toURI().toURL());
|
// 设置编码
|
shapeFileParams.put("charset", "utf-8");
|
DataStore dataStore = DataStoreFinder.getDataStore(shapeFileParams);
|
if (dataStore == null) {
|
throw new RuntimeException("couldn't load the damn data store: " + shapeFileParams);
|
}
|
String typeName = dataStore.getTypeNames()[0];
|
FeatureSource<SimpleFeatureType, SimpleFeature> source = dataStore.getFeatureSource(typeName);
|
Filter filter = Filter.INCLUDE;
|
FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures(filter);
|
return collection;
|
} catch (Exception e) {
|
throw e;
|
}
|
}
|
|
/**
|
* 解析shp文件返回数据
|
* @param zipFile:
|
* @return JSONObject
|
* @description 通过shp压缩文件,将其转换为GeoJson格式
|
*/
|
//将解压后的文件转换成GeoJson格式
|
public static List<Map<String,Object>> shpToGeoJson(File zipFile) throws IOException{
|
List<Map<String,Object>> dtoList = new ArrayList<>();
|
try {
|
FeatureJSON featureJSON = new FeatureJSON();
|
JSONObject geoJsonObject = new JSONObject();
|
geoJsonObject.put("type", "FeatureCollection");
|
// 解压zip文件,获取FeatureCollection
|
FeatureCollection collection = getFeatureCollectionByShpFile(zipFile);
|
// 获取迭代对象
|
FeatureIterator iterator = collection.features();
|
// 遍历feature转为json对象
|
while (iterator.hasNext()) {
|
Map<String,Object> shpDTO = new HashMap<>();
|
SimpleFeature feature = (SimpleFeature) iterator.next();
|
StringWriter writer = new StringWriter();
|
featureJSON.writeFeature(feature, writer);
|
String temp = writer.toString();
|
JSONObject json = JSONObject.parseObject(temp);
|
Object value = feature.getDefaultGeometryProperty().getValue();
|
try {
|
// 空间坐标
|
shpDTO.put("geometry",value);
|
// 空间类型
|
if (json.getJSONObject("geometry").get("type") != null) {
|
shpDTO.put("type",json.getJSONObject("geometry").getString("type"));
|
}
|
// 名称
|
if (json.getJSONObject("properties").get("Name")!= null) {
|
shpDTO.put("name",json.getJSONObject("properties").getString("Name"));
|
}
|
if (json.getJSONObject("properties").get("TYPE")!= null) {
|
shpDTO.put("name",json.getJSONObject("properties").getString("TYPE"));
|
}
|
// 所属公司名称
|
if (json.getJSONObject("properties").get("name_1")!= null) {
|
shpDTO.put("firmName",json.getJSONObject("properties").getString("name_1"));
|
}
|
if (json.getJSONObject("properties").get("QYMC")!= null) {
|
shpDTO.put("firmName",json.getJSONObject("properties").getString("QYMC"));
|
}
|
dtoList.add(shpDTO);
|
} catch (NumberFormatException e) {
|
System.err.println("处理单个特征时发生错误:" + e.getMessage());
|
} catch (Exception e) {
|
System.err.println("处理单个特征时发生错误:" + e.getMessage());
|
}
|
}
|
iterator.close();
|
} catch (IOException e) {
|
System.err.println("读取或解析文件时发生错误:" + e.getMessage());
|
throw e;
|
}
|
return dtoList;
|
}
|
|
|
public static void main(String[] args) throws IOException, ParseException {
|
// File file = new File("F:\\test4jdata\\shp\\import\\zrq.zip");
|
File file = new File("F:\\test4jdata\\shp\\zip\\test.zip");
|
List<Map<String, Object>> list = shpToGeoJson(file);
|
System.out.println("list = " + list);
|
|
// 导出shp 文件
|
// List<Map<String,Object>> propertyList = new ArrayList<>();
|
// for (int i = 0; i < 3; i++) {
|
// Map<String,Object> map = new HashMap<>();
|
// map.put("ID", i);
|
// map.put("名称", "test" + i);
|
// map.put("描述", "测试shp导出" + i);
|
// map.put("geometry", "MULTILINESTRING ((114.0888763800001 22.549298400000055, 114.0897166200001 22.54931240800005, 114.09006708000004 22.549318250000056, 114.09104754000009 22.549328150000065))");
|
// propertyList.add(map);
|
// }
|
// String exportPath = "F:\\test4jdata\\shp\\export\\";
|
// exportShp(propertyList, "test", "MultiLineString",exportPath);
|
// // 打包成 zip 包,然后导出
|
// String zipPath = "F:\\test4jdata\\shp\\zip\\test.zip";
|
// boolean folder = ZipUtil.zipFolder(exportPath, zipPath);
|
// 打包成功后导出
|
|
}
|
|
public static double[] getLongitudeLatitude(Geometry wktPoint) throws ParseException {
|
Geometry geometry = wktPoint;
|
if (geometry instanceof Point) {
|
Point point = (Point) geometry;
|
double longitude = point.getX();
|
double latitude = point.getY();
|
return new double[]{longitude, latitude};
|
} else {
|
throw new IllegalArgumentException("The geometry is not a point.");
|
}
|
}
|
}
|