使用GeoTools解析shp文件内容

前言

记录一下工作中使用GeoTools解析shp过程。

默认上传shp文件为zip格式文件,shp压缩包内容如下图

image

代码流程

1.解压zip文件

// 解压缩zip包
File shpFile = ShpParseUtil.unShapeZip(file.getInputStream(), tempDir);

2.解析shp文件内容

parseShapeFile(shpFile);
public static void parseShapeFile(File file) throws Exception {
        Map<String, Object> map = new HashMap<>(1);
        map.put("url", file.toURI().toURL());
        DataStore dataStore = DataStoreFinder.getDataStore(map);
        //字符转码,防止中文乱码
        ShapefileDataStore shpStore = (ShapefileDataStore) dataStore;
//        shpStore.setCharset(StandardCharsets.UTF_8);
        shpStore.setCharset(Charset.forName("GBK"));

        SimpleFeatureSource source = shpStore.getFeatureSource();
        SimpleFeatureType schema = source.getSchema();
        Query query = new Query(schema.getTypeName());
        FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures(query);
        //获取shp文件内容
        try (FeatureIterator<SimpleFeature> features = collection.features()) {
            while (features.hasNext()) {
                SimpleFeature feature = features.next();
                String name = feature.getName().toString();
                System.out.println("名称:" + name);

                //获取坐标系
                CoordinateReferenceSystem coordinateReferenceSystem = feature.getFeatureType().getCoordinateReferenceSystem();
                if (coordinateReferenceSystem != null) {
                    ReferenceIdentifier referenceIdentifier = coordinateReferenceSystem.getCoordinateSystem().getName();
                    String code = referenceIdentifier.getCode();
                    System.out.println("坐标系:" + code);
                }
                //获取shp文件的属性信息
//                List<Object> attributes = feature.getAttributes();
                String geomType = feature.getFeatureType().getDescriptor("the_geom").getType().getName().toString();
                System.out.println("属性值数量:" + feature.getValue().size());
                Map<String, Object> propertoryMap = feature.getValue().stream()
                        .filter(property -> !"the_geom".equals(property.getName().toString()))
                        .collect(Collectors.toMap(property -> property.getName().toString(), Property::getValue));
                for (Property property : feature.getValue()) {
                    String propertyName = property.getName().toString();
                    String typeName = property.getType().getName().toString();
                    System.out.println("属性名:" + propertyName + "类型:" + typeName + " 属性值:" + property.getValue());
                }
                Geometry geom = (Geometry) feature.getAttribute("the_geom");
                String geometryType = geom.getGeometryType();
				// 封装为geojson格式
                String geoJson = convertToJson(geom,propertoryMap);
            }
        }
    }

工具类

public class ShpParseUtil {


    /**
     * 解压shapefile压缩包
     */
    public static File unShapeZip(InputStream inputStream,File tempDir){
        // 解压shp文件
        File unzipFiles = ZipUtil.unzip(inputStream, tempDir, null);
        Optional<File> optional = ListUtil.toList(unzipFiles.listFiles())
                .stream()
                .filter(file1 -> file1.getName().endsWith(".shp"))
                .findAny();
        if (!optional.isPresent()) {
            throw new JeecgBootException("不存在解压后shp文件");
        }
        return optional.get();
    }

    /**
     * 格式化矢量数据为json格式
     * @param the_geom
     * @return
     */
    public static String convertToJson(Geometry the_geom, Map<String, Object> propertoryMap){
        String geomType = the_geom.getGeometryType();
        // 解析组装坐标Json数组
        JSONArray geoJsonArray = getCoordinates(the_geom);

        // 构建 GeoJSON 对象
        JSONObject geoJsonFeature = new JSONObject();
        geoJsonFeature.put("type", "Feature");
        JSONObject geometry = new JSONObject();
        geometry.put("type", geomType);
        geometry.put("coordinates", geoJsonArray);
        geoJsonFeature.put("geometry", geometry);

        // 添加属性
        geoJsonFeature.put("properties", propertoryMap);

        // 返回 GeoJSON 结果
        JSONObject geoJson = new JSONObject();
        geoJson.put("type", "FeatureCollection");
        geoJson.put("features", new JSONArray().fluentAdd(geoJsonFeature));
        return geoJson.toString();
    }

    /**
     *  解析不同类型坐标返回JSON数组
     */
    private static JSONArray getCoordinates(Geometry geometry) {
        if (geometry instanceof Point) {
            Point point = (Point) geometry;
            JSONArray geoJsonPoints = new JSONArray();
            geoJsonPoints.add(point.getX());
            geoJsonPoints.add(point.getY());
            return geoJsonPoints;
        } else if (geometry instanceof LineString) {
            LineString lineString = (LineString) geometry;
            org.locationtech.jts.geom.Coordinate[] coordinates = lineString.getCoordinates();
            JSONArray geoJsonLineString = new JSONArray();
            for (Coordinate coordinate : coordinates) {
                geoJsonLineString.add(coordinate.getX());
                geoJsonLineString.add(coordinate.getY());
            }
            return geoJsonLineString;
        } else if (geometry instanceof Polygon) {
            Polygon polygon = (Polygon) geometry;
            return getPolygonCoordinates(polygon);
        } else if (geometry instanceof MultiPoint) {
            MultiPoint multiPoint = (MultiPoint) geometry;
            JSONArray coords = new JSONArray();
            for (int i = 0; i < multiPoint.getNumGeometries(); i++) {
                Point point = (Point) multiPoint.getGeometryN(i);
                coords.add(new JSONArray().fluentAdd(point.getX()).fluentAdd(point.getY()));
            }
            return coords;
        } else if (geometry instanceof MultiLineString) {
            MultiLineString multiLineString = (MultiLineString) geometry;
            JSONArray coords = new JSONArray();
            for (int i = 0; i < multiLineString.getNumGeometries(); i++) {
                coords.add(getCoordinates(multiLineString.getGeometryN(i)));
            }
            return coords;
        } else if (geometry instanceof MultiPolygon) {
            MultiPolygon multiPolygon = (MultiPolygon) geometry;
            JSONArray coords = new JSONArray();
            for (int i = 0; i < multiPolygon.getNumGeometries(); i++) {
                coords.add(getPolygonCoordinates((Polygon) multiPolygon.getGeometryN(i)));
            }
            return coords;
        } else {
            return null;
        }
    }

    // 解析获取多边形的坐标数组
    private static JSONArray getPolygonCoordinates(Polygon polygon) {
        JSONArray coords = new JSONArray();
        // 多边形外环
        JSONArray exteriorRing = new JSONArray();
        for (int i = 0; i < polygon.getExteriorRing().getNumPoints(); i++) {
            exteriorRing.fluentAdd(new JSONArray().fluentAdd(polygon.getExteriorRing().getCoordinateN(i).x)
                    .fluentAdd(polygon.getExteriorRing().getCoordinateN(i).y));
        }
        coords.add(exteriorRing);
        // 多边形内环
        for (int i = 0; i < polygon.getNumInteriorRing(); i++) {
            JSONArray interiorRing = new JSONArray();
            for (int j = 0; j < polygon.getInteriorRingN(i).getNumPoints(); j++) {
                interiorRing.fluentAdd(new JSONArray().fluentAdd(polygon.getInteriorRingN(i).getCoordinateN(j).x)
                        .fluentAdd(polygon.getInteriorRingN(i).getCoordinateN(j).y));
            }
            coords.add(interiorRing);
        }
        return coords;
    }
}
posted @ 2024-09-09 11:08  香酥豆腐皮  阅读(157)  评论(0编辑  收藏  举报
正在加载今日诗词....