package utils;
import cn.hutool.core.io.FileUtil;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.FeatureSource;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.PropertyType;
import org.opengis.filter.Filter;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.Charset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @Created by junlong.hou
* @Date 2023/4/12
* @Description TODO
*/
public class GeoToolsUtils {
/**
* 读取Shapefiles文件表内容和对应表数据
*
* @param SHPFile Shapefiles文件
* @return Map<( entity / datas ), List ( 对应map数据 )>
*/
public static Map<String, List> readSHP(File SHPFile) throws Exception {
// 一个数据存储实现,允许从Shapefiles读取和写入
ShapefileDataStore shpDataStore = null;
shpDataStore = new ShapefileDataStore(SHPFile.toURI().toURL());
shpDataStore.setCharset(Charset.forName("UTF-8"));
// 获取这个数据存储保存的类型名称数组
// getTypeNames:获取所有地理图层
String typeName = shpDataStore.getTypeNames()[0];
// 通过此接口可以引用单个shapefile、数据库表等。与数据存储进行比较和约束
FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = null;
featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) shpDataStore.getFeatureSource(typeName);
// 一个用于处理FeatureCollection的实用工具类。提供一个获取FeatureCollection实例的机制
FeatureCollection<SimpleFeatureType, SimpleFeature> result = featureSource.getFeatures();
FeatureIterator<SimpleFeature> iterator = result.features();
// 迭代
int stop = 0;
Map<String, List> map = new HashMap<>();
List<Map> entity = new ArrayList<>();
List<Map> datas = new ArrayList<>();
while (iterator.hasNext()) {
SimpleFeature feature = iterator.next();
Collection<Property> p = feature.getProperties();
Iterator<Property> it = p.iterator();
// 构建实体
// 特征里面的属性再迭代,属性里面有字段
String name;
Map<String, Object> data = new HashMap<>();
while (it.hasNext()) {
Property pro = it.next();
name = pro.getName().toString();
if (stop == 0) {
Map<String, Object> et = new HashMap<>();
PropertyType propertyType = pro.getType();
Class cls = propertyType.getBinding();
String className = cls.getName();
String tName = className.substring(className.lastIndexOf(".") + 1);
Filter filter = propertyType.getRestrictions().isEmpty() ? null : propertyType.getRestrictions().get(0);
String typeLength = filter != null ? filter.toString() : "0";
Pattern pattern = Pattern.compile("[^0-9]");
Matcher matcher = pattern.matcher(typeLength);
String tLength = matcher.replaceAll("").trim();
et.put("name", name);
et.put("type", tName);
et.put("length", tLength);
entity.add(et);
}
data.put(name, pro.getValue().toString());
} // end 里层while
datas.add(data);
stop++;
} // end 最外层 while
map.put("entity", entity);
map.put("datas", datas);
iterator.close();
return map;
}
/**
* 读取Shapefiles文件表内容不包含内容数据
*
* @param SHPFile Shapefiles文件
* @return List<( Map ), List ( 对应map数据 )>
*/
public static List readSHPNoData(File SHPFile) throws Exception {
// 一个数据存储实现,允许从Shapefiles读取和写入
ShapefileDataStore shpDataStore = null;
shpDataStore = new ShapefileDataStore(SHPFile.toURI().toURL());
shpDataStore.setCharset(Charset.forName("UTF-8"));
// 获取这个数据存储保存的类型名称数组
// getTypeNames:获取所有地理图层
String typeName = shpDataStore.getTypeNames()[0];
// 通过此接口可以引用单个shapefile、数据库表等。与数据存储进行比较和约束
FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = null;
featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) shpDataStore.getFeatureSource(typeName);
// 一个用于处理FeatureCollection的实用工具类。提供一个获取FeatureCollection实例的机制
FeatureCollection<SimpleFeatureType, SimpleFeature> result = featureSource.getFeatures();
FeatureIterator<SimpleFeature> iterator = result.features();
// 迭代
int stop = 0;
List<Map> entity = new ArrayList<>();
while (iterator.hasNext()) {
SimpleFeature feature = iterator.next();
Collection<Property> p = feature.getProperties();
Iterator<Property> it = p.iterator();
// 构建实体
// 特征里面的属性再迭代,属性里面有字段
String name;
Map<String, Object> data = new HashMap<>();
while (it.hasNext()) {
Property pro = it.next();
name = pro.getName().toString();
if (stop == 0) {
Map<String, Object> et = new HashMap<>();
PropertyType propertyType = pro.getType();
Class cls = propertyType.getBinding();
String className = cls.getName();
String tName = className.substring(className.lastIndexOf(".") + 1);
Filter filter = propertyType.getRestrictions().isEmpty() ? null : propertyType.getRestrictions().get(0);
String typeLength = filter != null ? filter.toString() : "0";
Pattern pattern = Pattern.compile("[^0-9]");
Matcher matcher = pattern.matcher(typeLength);
String tLength = matcher.replaceAll("").trim();
et.put("name", name);
et.put("type", tName);
et.put("length", tLength);
entity.add(et);
}
data.put(name, pro.getValue().toString());
} // end 里层while
stop++;
} // end 最外层 while
iterator.close();
return entity;
}
/**
* 描述:把shp的边界线转换为geojson
*
* @param file
* @return File
*/
public static void shpTranGeoJsonFile(File file, File tarFile) throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
map.put("url", file.toURI().toURL());// 必须是URL类型
DataStore dataStore = DataStoreFinder.getDataStore(map);
//字符转码,防止中文乱码
((ShapefileDataStore) dataStore).setCharset(Charset.forName("utf8"));
String typeName = dataStore.getTypeNames()[0];
FeatureSource<SimpleFeatureType, SimpleFeature> source = dataStore.getFeatureSource(typeName);
FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures();
FeatureIterator<SimpleFeature> features = collection.features();
// 根据几何图形创建要素列表
List<SimpleFeature> featureList = new ArrayList<>();
SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
typeBuilder.setName("GeometryFeature");
typeBuilder.add("geometry", Geometry.class);
// 创建要素类型
SimpleFeatureType featureType = typeBuilder.buildFeatureType();
while (features.hasNext()) {
// 迭代提取属性
SimpleFeature feature = features.next();
CoordinateReferenceSystem sourceCRS = feature.getFeatureType().getCoordinateReferenceSystem();
CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326", true);
MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
Geometry sourceGeo = geometryFactory.createGeometry((Geometry) feature.getDefaultGeometry());
Geometry targetGeo = JTS.transform(sourceGeo, transform);
// 设置保留8位小数,否则GeometryJSON默认保留4位小数
// GeometryJSON geometryJson = new GeometryJSON(8);
// geometryJson.write(targetGeo, new FileOutputStream(FileUtil.touch(tarFile)));
// 创建要素生成器
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
// 设置几何体属性
featureBuilder.set("geometry", targetGeo);
// 构建功能
SimpleFeature featureSave = featureBuilder.buildFeature(null);
// 将功能添加到列表,多个才用遍历的添加
featureList.add(featureSave);
}
// 从要素列表创建要素集合
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection =
new ListFeatureCollection(featureType, featureList);
FeatureJSON io = new FeatureJSON();
io.writeFeatureCollection(featureCollection, new FileOutputStream(FileUtil.touch(tarFile)));
}
/**
* 描述:把shp的边界线转换为geojson
*
* @param file
* @return File
*/
public static void shpTranGeoJsonFileTwo(File file, File tarFile) throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
map.put("url", file.toURI().toURL());// 必须是URL类型
DataStore dataStore = DataStoreFinder.getDataStore(map);
//字符转码,防止中文乱码
((ShapefileDataStore) dataStore).setCharset(Charset.forName("utf8"));
String typeName = dataStore.getTypeNames()[0];
FeatureSource<SimpleFeatureType, SimpleFeature> source = dataStore.getFeatureSource(typeName);
FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures();
FeatureIterator<SimpleFeature> features = collection.features();
while (features.hasNext()) {
// 迭代提取属性
SimpleFeature feature = features.next();
CoordinateReferenceSystem sourceCRS = feature.getFeatureType().getCoordinateReferenceSystem();
CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326", true);
MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
Geometry sourceGeo = geometryFactory.createGeometry((Geometry) feature.getDefaultGeometry());
Geometry targetGeo = JTS.transform(sourceGeo, transform);
SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
typeBuilder.setName("GeometryFeature");
typeBuilder.add("geometry", Geometry.class);
// Create a feature type
SimpleFeatureType featureType = typeBuilder.buildFeatureType();
// Create a feature builder
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
// Create a list of features from the geometries
List<SimpleFeature> features1 = new ArrayList<>();
// Set the geometry attribute
featureBuilder.set("geometry", targetGeo);
// Build the feature
SimpleFeature feature1 = featureBuilder.buildFeature(null);
// Add the feature to the list
features1.add(feature1);
// Create a feature collection from the list of features
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection =
new ListFeatureCollection(featureType, feature1);
FeatureJSON io = new FeatureJSON();
io.writeFeatureCollection(featureCollection, new FileOutputStream(FileUtil.touch(tarFile)));
// geometryJson.write(targetGeo, new FileOutputStream(FileUtil.touch(tarFile)));
}
}
/*
*/
/**
* 描述:把shp的边界线转换为geojson
*
* @param file
* @return File
*//*
public static void shpTranGeoJsonFile(File file, File tarFile) throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
map.put("url", file.toURI().toURL());// 必须是URL类型
DataStore dataStore = DataStoreFinder.getDataStore(map);
//字符转码,防止中文乱码
((ShapefileDataStore) dataStore).setCharset(Charset.forName("utf8"));
String typeName = dataStore.getTypeNames()[0];
FeatureSource<SimpleFeatureType, SimpleFeature> source = dataStore.getFeatureSource(typeName);
FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures();
FeatureIterator<SimpleFeature> features = collection.features();
while (features.hasNext()) {
// 迭代提取属性
SimpleFeature feature = features.next();
CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326");
GeometryJSON gjson = new GeometryJSON();
FeatureJSON jSON = new FeatureJSON(gjson);
jSON.setFeatureType(feature.getFeatureType());
jSON.writeFeatureCollection(collection, tarFile);
jSON.writeCRS(targetCRS, FileUtil.touch(tarFile));
}
}
*/
}
读取shp文件边界为geojson,包含坐标转换
于 2023-05-30 15:15:04 首次发布