java代码如何对geojson文件数据抽稀

geojson文件太大了,java代码如何对geojson文件数据抽稀

GPT回答就算了,代码能不能运行难道不验证一下吗。。

  • 这篇文章讲的很详细,请看:java根据一个完整的geojson文件,根据图层名称导出单个图层的geojson文件
  • 除此之外, 这篇博客: java实现geojson格式数据与shp文件相互转换中的 java实现geojson格式数据与shp文件相互转换 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 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");
        }
    }
    
  • 以下回答由chatgpt基于相关博客总结生成:

    我可以根据以下步骤使用Java代码对geojson文件进行抽稀:

    1. 导入所需依赖库,包括geojson-jackson、jts-core等,以便进行geojson文件的解析和处理。

    2. 使用java.io.File类读取待处理的geojson文件,并将其转化为FeatureCollection对象,如下所示:

    File file = new File("path/to/geojson/file");
    FeatureCollection features = (FeatureCollection) new ObjectMapper().readValue(file, GeoJson.class);
    
    1. 对FeatureCollection对象进行抽稀操作,可以使用jts-simplify库和jts-geojson库来实现。具体步骤如下:

    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);
    }
    
    1. 将抽稀后的FeatureCollection对象转换为geojson格式的字符串,并写入到新的文件中:
    String simplifiedGeoJson = new ObjectMapper().writeValueAsString(simplifiedFeatures);
    File outFile = new File("path/to/output/file");
    FileUtils.writeStringToFile(outFile, simplifiedGeoJson, StandardCharsets.UTF_8);
    

    需要注意的是,抽稀距离阈值需要根据实际情况进行调整,以确保抽稀后的结果在视觉上仍然保持足够的精度。

该回答引用ChatGPT
抽稀是指在保留数据主要特征的前提下,舍弃一部分数据来减少数据量,提高效率。

对于geojson格式数据,可以使用Java中的GeoTools库来进行抽稀处理。GeoTools提供了多种几何操作函数,包括点、线、面等几何要素的抽稀函数。

具体实现步骤如下:
1. 使用GeoTools库读取geojson文件,将其转化为FeatureCollection类型的要素集合对象。
2. 针对文件中的点、线、面要素进行抽稀处理,可以使用Douglas-Peucker算法或Ramer-Douglas-Peucker算法来实现。
3. 将抽稀处理后的FeatureCollection对象重新保存为geojson格式的文件。

以下是一个简单的Java代码示例:


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;
}
}


以上代码简单使用了GeoTools库,对于点、线、面三类几何要素都进行了抽稀处理,可以根据实际情况对抽稀算法进行调整。