geojson文件太大了,java代码如何对geojson文件数据抽稀
GPT回答就算了,代码能不能运行难道不验证一下吗。。
package com.zimax.zplan.admin.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.vividsolutions.jts.geom.*;
import org.geotools.data.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class ShpToGeojson {
/**
* geojson转换为shp文件
*
* @param
* @param shpPath
* @return
*/
public Map geojson2Shape(String jsonPath, String shpPath) {
Map map = new HashMap();
GeometryJSON gjson = new GeometryJSON();
try {
// 读文件到Stringbuffer
StringBuffer sb = new StringBuffer();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(jsonPath));
String str;
while ((str = br.readLine()) != null) {// 逐行读取
sb.append(str + "\r\n");
}
br.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
JSONObject json = JSONObject.parseObject(sb.toString());
// JSONObject json = JSONObject.fromObject(sb.toString());
JSONArray features = (JSONArray) json.get("features");
JSONObject feature0 = JSONObject.parseObject(features.get(0).toString());
// 获取属性名称
Set properties = JSONObject.parseObject(feature0.getString("properties")).keySet();
String strType = ((JSONObject) feature0.get("geometry")).getString("type").toString();
Class<?> geoType = null;
switch (strType) {
case "Point":
geoType = Point.class;
break;
case "MultiPoint":
geoType = MultiPoint.class;
break;
case "LineString":
geoType = LineString.class;
break;
case "MultiLineString":
geoType = MultiLineString.class;
break;
case "Polygon":
geoType = Polygon.class;
break;
case "MultiPolygon":
geoType = MultiPolygon.class;
break;
}
// 创建shape文件对象
File file = new File(shpPath);
Map<String, Serializable> params = new HashMap<String, Serializable>();
params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
// 定义图形信息和属性信息
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
tb.setCRS(DefaultGeographicCRS.WGS84);
tb.setName("shapefile");
tb.add("the_geom", geoType);// 类型,Point/MultiPoint/LineString/MultiLineString/Polygon/MultiPolygon
Iterator propertiesIter = properties.iterator();
// 设置属性
while (propertiesIter.hasNext()) {
String str = propertiesIter.next().toString();
tb.add(str, String.class);// 此处设置为string,如需修改请自行改写代码
}
ds.createSchema(tb.buildFeatureType());
// 设置编码
Charset charset = Charset.forName("GBK");
ds.setCharset(charset);
// 设置Writer
FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.getTypeNames()[0],
Transaction.AUTO_COMMIT);
for (int i = 0, len = features.size(); i < len; i++) {
String strFeature = features.get(i).toString();
Reader reader = new StringReader(strFeature);
SimpleFeature feature = writer.next();
switch (strType) {
case "Point":
feature.setAttribute("the_geom", gjson.readPoint(reader));
break;
case "MultiPoint":
feature.setAttribute("the_geom", gjson.readMultiPoint(reader));
break;
case "LineString":
feature.setAttribute("the_geom", gjson.readLine(reader));
break;
case "MultiLineString":
feature.setAttribute("the_geom", gjson.readMultiLine(reader));
break;
case "Polygon":
feature.setAttribute("the_geom", gjson.readPolygon(reader));
break;
case "MultiPolygon":
feature.setAttribute("the_geom", gjson.readMultiPolygon(reader));
break;
}
Iterator propertiesset = properties.iterator();
while (propertiesset.hasNext()) {
String str = propertiesset.next().toString();
JSONObject featurei = JSONObject.parseObject(features.get(i).toString());
feature.setAttribute(str, JSONObject.parseObject(featurei.getString("properties")).get(str));
}
writer.write();
}
writer.close();
ds.dispose();
map.put("status", "success");
map.put("message", shpPath);
} catch (Exception e) {
map.put("status", "failure");
map.put("message", e.getMessage());
e.printStackTrace();
}
return map;
}
/**
* shp文件转换geojson数据
* @param shpPath
* @return
*/
public static Object shp2geojson(String shpPath)
{
Map map = new HashMap();
//新建json对象
FeatureJSON fjson = new FeatureJSON();
JSONObject geojsonObject=new JSONObject();
geojsonObject.put("type","FeatureCollection");
try{
//获取featurecollection
File file = new File(shpPath);
ShapefileDataStore shpDataStore = null;
shpDataStore = new ShapefileDataStore(file.toURL());
//设置编码
/* Charset charset = Charset.forName("GBK");
shpDataStore.setCharset(charset);*/
String typeName = shpDataStore.getTypeNames()[0];
SimpleFeatureSource featureSource = null;
featureSource = shpDataStore.getFeatureSource (typeName);
SimpleFeatureCollection result = featureSource.getFeatures();
SimpleFeatureIterator itertor = result.features();
JSONArray array = new JSONArray();
//遍历feature转为json对象
while (itertor.hasNext())
{
SimpleFeature feature = itertor.next();
StringWriter writer = new StringWriter();
fjson.writeFeature(feature, writer);
String temp=writer.toString();
Object geometry = JSONObject.parseObject(temp).getString("geometry");
byte[] b=temp.getBytes("iso8859-1");
temp=new String(b,"gbk");
JSONObject json = JSON.parseObject(temp);
array.add(geometry);
}
itertor.close();
return array;
// geojsonObject.put("features",array);
// itertor.close();
// long startTime=System.currentTimeMillis();
//将json字符串使用字符流写入文件
/* File outputfile=new File(jsonPath);
BufferedWriter bufferedWriter=new BufferedWriter(new FileWriter(outputfile));
bufferedWriter.write(JSON.toJSONString(geojsonObject));
bufferedWriter.flush();
bufferedWriter.close();*/
// File outputfile=new File(jsonPath);
// FileOutputStream fileOutputStream=new FileOutputStream(outputfile);
// OutputStreamWriter outputStreamWriter=new OutputStreamWriter(fileOutputStream,"utf-8");
// outputStreamWriter.write(JSON.toJSONString(geojsonObject));
// outputStreamWriter.flush();
// outputStreamWriter.close();
//将json字符串使用字节流写入文件
/* File outputfile=new File(jsonPath);
BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream(outputfile));
byte[] bytes= JSON.toJSONString(geojsonObject).getBytes("utf-8");
bufferedOutputStream.write(bytes);
//fileOutputStream.write(JSON.toJSONString(geojsonObject));
bufferedOutputStream.flush();
bufferedOutputStream.close();*/
// long endTime=System.currentTimeMillis();
// System.out.println("当前程序耗时:"+(endTime-startTime)+"ms");
}
catch(Exception e){
map.put("status", "failure");
map.put("message", e.getMessage());
e.printStackTrace();
}
//
return geojsonObject;
}
/**
* 工具类测试方法
*
* @param args
*/
public static void main(String[] args) {
ShpToGeojson shpToGeojson = new ShpToGeojson();
long start = System.currentTimeMillis();
// shape2Geojson
// String shpPath = "D:/geojsonTest/gaosu.shp";
// String jsonPath = "D:/geojsonTest/gaosu.geojson1";
// Map map = fileFormat.shape2Geojson(shpPath, jsonPath);
// geojson2Shape
String shpPath = "D:/矢量下载/123.shp";
String jsonPath = "D:/123.geojson";
Map map = shpToGeojson.geojson2Shape(jsonPath, shpPath);
System.out.println(shpPath +" "+ jsonPath + ",共耗时" + (System.currentTimeMillis() - start) + "ms");
}
}
我可以根据以下步骤使用Java代码对geojson文件进行抽稀:
导入所需依赖库,包括geojson-jackson、jts-core等,以便进行geojson文件的解析和处理。
使用java.io.File类读取待处理的geojson文件,并将其转化为FeatureCollection对象,如下所示:
File file = new File("path/to/geojson/file");
FeatureCollection features = (FeatureCollection) new ObjectMapper().readValue(file, GeoJson.class);
3.1 将FeatureCollection对象中的每一个Feature对象转换为JtsGeometry对象,例如将Polygon对象转换为MultiPolygon对象:
GeometryFactory geometryFactory = new GeometryFactory();
List<Geometry> geometries = new ArrayList<>();
for (Feature feature : features) {
JtsSpatialContext geoContext = JtsSpatialContext.GEO;
Geometry geometry = geoContext.read(feature.getGeometry().toString());
// 将Polygon转化为MultiPolygon
if (geometry instanceof Polygon) {
geometry = geometryFactory.createMultiPolygon(new Polygon[]{(Polygon) geometry});
}
geometries.add(geometry);
}
3.2 将JtsGeometry对象进行抽稀操作,这里使用DouglasPeuckerSimplifier对象来实现:
double distanceTolerance = 0.001; // 设置抽稀距离阈值
List<Geometry> simplified = new ArrayList<>();
for (Geometry geometry : geometries) {
Geometry simplifiedGeometry = DouglasPeuckerSimplifier.simplify(geometry, distanceTolerance);
simplified.add(simplifiedGeometry);
}
3.3 将抽稀后的JtsGeometry对象转换为Feature对象,并构建新的FeatureCollection对象:
FeatureCollection simplifiedFeatures = new FeatureCollection();
for (Geometry geometry : simplified) {
WKTWriter wktWriter = new WKTWriter();
Feature feature = new Feature();
feature.setGeometry(wktWriter.write(geometry));
simplifiedFeatures.add(feature);
}
String simplifiedGeoJson = new ObjectMapper().writeValueAsString(simplifiedFeatures);
File outFile = new File("path/to/output/file");
FileUtils.writeStringToFile(outFile, simplifiedGeoJson, StandardCharsets.UTF_8);
需要注意的是,抽稀距离阈值需要根据实际情况进行调整,以确保抽稀后的结果在视觉上仍然保持足够的精度。
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.FeatureSource;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureCollections;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.geojson.feature.FeatureJSON;
import org.opengis.feature.Feature;
import org.opengis.feature.GeometryAttribute;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public class GeoJsonSimplify {
public static void main(String[] args) throws Exception {
File file = new File("input.geojson");
// 读取geojson数据
Map<String, Object> map = new HashMap<>();
map.put("url", file.toURI().toURL());
DataStore dataStore = DataStoreFinder.getDataStore(map);
String typeName = dataStore.getTypeNames()[0];
FeatureSource<SimpleFeatureType, SimpleFeature> source =
dataStore.getFeatureSource(typeName);
FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures();
// 定义简化后的输出FeatureCollection
SimpleFeatureType schema = collection.getSchema();
FeatureCollection<SimpleFeatureType, SimpleFeature> simplifiedCollection =
FeatureCollections.newCollection();
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(schema);
FeatureIterator<SimpleFeature> featureItr = collection.features();
// 处理点、线、面特征
while (featureItr.hasNext()) {
SimpleFeature feature = featureItr.next();
GeometryAttribute geomAttr = feature.getDefaultGeometryProperty();
// 判断几何类型
if (geomAttr.getValue() instanceof Point) {
// 处理点特征
Point point = (Point) geomAttr.getValue();
Point simplifiedPoint = simplifyPoint(point);
featureBuilder.set(geomAttr.getName(), simplifiedPoint);
SimpleFeature simplifiedFeature = featureBuilder.buildFeature(null);
simplifiedCollection.add(simplifiedFeature);
} else if (geomAttr.getValue() instanceof LineString) {
// 处理线特征
LineString lineString = (LineString) geomAttr.getValue();
LineString simplifiedLineString = simplifyLineString(lineString);
featureBuilder.set(geomAttr.getName(), simplifiedLineString);
SimpleFeature simplifiedFeature = featureBuilder.buildFeature(null);
simplifiedCollection.add(simplifiedFeature);
} else if (geomAttr.getValue() instanceof Polygon) {
// 处理面特征
Polygon polygon = (Polygon) geomAttr.getValue();
Polygon simplifiedPolygon = simplifyPolygon(polygon);
featureBuilder.set(geomAttr.getName(), simplifiedPolygon);
SimpleFeature simplifiedFeature = featureBuilder.buildFeature(null);
simplifiedCollection.add(simplifiedFeature);
} else {
System.err.println("Unsupported geometry type: " +
geomAttr.getValue().getClass().getSimpleName());
}
}
// 输出简化后的结果
FeatureJSON io = new FeatureJSON();
io.writeFeatureCollection(simplifiedCollection, new File("output.geojson"));
}
private static Point simplifyPoint(Point point) {
// 对点特征不进行抽稀
return point;
}
private static LineString simplifyLineString(LineString lineString) {
// 使用Douglas-Peucker算法对线特征进行抽稀
double tolerance = 0.001;
GeometryFactory geometryFactory = new GeometryFactory();
Coordinate[] coords = lineString.getCoordinates();
// 将Coordinate数组转化为JTS的LineString对象
org.locationtech.jts.geom.Coordinate[] jtsCoords =
new org.locationtech.jts.geom.Coordinate[coords.length];
for (int i = 0; i < coords.length; i++) {
jtsCoords[i] = new org.locationtech.jts.geom.Coordinate(coords[i].x, coords[i].y);
}
org.locationtech.jts.geom.LineString jtsLine =
geometryFactory.createLineString(jtsCoords);
DouglasPeuckerSimplifier simplifier = new DouglasPeuckerSimplifier(jtsLine);
simplifier.setDistanceTolerance(tolerance);
org.locationtech.jts.geom.LineString simplifiedLine = (LineString) simplifier.getResultGeometry();
// 将简化后的JTS LineString对象转化为GeoTools LineString对象
Coordinate[] simplifiedCoords = new Coordinate[simplifiedLine.getNumPoints()];
for (int i = 0; i < simplifiedLine.getNumPoints(); i++) {
simplifiedCoords[i] = new Coordinate(simplifiedLine.getCoordinates()[i].getX(),
simplifiedLine.getCoordinates()[i].getY());
}
LineString simplifiedLineString =
new GeometryFactory().createLineString(simplifiedCoords);
return simplifiedLineString;
}
private static Polygon simplifyPolygon(Polygon polygon) {
// 使用Douglas-Peucker算法对面特征进行抽稀
double tolerance = 0.001;
GeometryFactory geometryFactory = new GeometryFactory();
Polygon jtsPolygon = (Polygon) polygon.getDefaultGeometry();
DouglasPeuckerSimplifier simplifier = new DouglasPeuckerSimplifier(jtsPolygon);
simplifier.setDistanceTolerance(tolerance);
org.locationtech.jts.geom.Polygon simplifiedPolygon =
(org.locationtech.jts.geom.Polygon) simplifier.getResultGeometry();
// 将简化后的JTS Polygon对象转化为GeoTools Polygon对象
LinearRing shell =
geometryFactory.createLinearRing(
simplifiedPolygon.getExteriorRing().getCoordinates());
LinearRing[] holes = new LinearRing[simplifiedPolygon.getNumInteriorRing()];
for (int i = 0; i < simplifiedPolygon.getNumInteriorRing(); i++) {
org.locationtech.jts.geom.LineString holeString =
simplifiedPolygon.getInteriorRingN(i);
Coordinate[] holeCoords = new Coordinate[holeString.getCoordinates().length];
for (int j = 0; j < holeString.getCoordinates().length; j++) {
holeCoords[j] = new Coordinate(
holeString.getCoordinates()[j].getX(),
holeString.getCoordinates()[j].getY());
}
holes[i] = geometryFactory.createLinearRing(holeCoords);
}
Polygon simplifiedPolygonGeom = geometryFactory.createPolygon(shell, holes);
// 创建GeoTools SimpleFeature对象
SimpleFeatureType type = polygon.getFeatureType();
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(type);
featureBuilder.set(type.getGeometryDescriptor().getLocalName(),
simplifiedPolygonGeom);
SimpleFeature simplifiedPolygonFeature =
featureBuilder.buildFeature(polygon.getID().toString());
return simplifiedPolygonFeature;
}
}