使用geotools解析shape文件工具

2 篇文章 0 订阅
1 篇文章 0 订阅

解析shape文件转换为geojson,支持坐标系转换工具

package com.sboot.test;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import org.geotools.data.FeatureSource;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.geojson.GeoJSON;
import org.geotools.geojson.GeoJSONUtil;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.json.simple.JSONStreamAware;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.geometry.BoundingBox;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;

import java.io.*;
import java.nio.charset.Charset;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static org.geotools.geojson.GeoJSONUtil.*;

public class GeoShapeFileUtil {

    public static void readShapeFile(File shpFile) {
        try {
            FeatureSource featuresource = getFeatureSource(shpFile);
            //读取要素
            SimpleFeatureCollection simpleFeatureCollection = (SimpleFeatureCollection) featuresource.getFeatures();
            //获取当前矢量数据有哪些属性字段值
            List<AttributeDescriptor> attributes = simpleFeatureCollection.getSchema().getAttributeDescriptors();
            SimpleFeatureIterator simpleFeatureIterator = simpleFeatureCollection.features();
            //
            while (simpleFeatureIterator.hasNext()) {
                SimpleFeature simpleFeature = simpleFeatureIterator.next();
                attributes.stream().forEach((a) -> {
                    //读取属性值,业务处理,存储
                    System.out.println(simpleFeature.getAttribute(a.getLocalName()));
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            //关闭资源
            simpleFeatureIterator.close();
        }

    }

    private static FeatureSource getFeatureSource(File shpFile) throws Exception {
        ShapefileDataStore shapefileDataStore = new ShapefileDataStore(shpFile.toURI().toURL());
        String charset = getShapeFileCharsetName(shpFile.getAbsolutePath().replace(".shp", ".cpg"));
        System.out.println("文件:" + shpFile.getName() + ",编码格式:" + charset);
        shapefileDataStore.setCharset(Charset.forName(charset));
        return shapefileDataStore.getFeatureSource(shapefileDataStore.getTypeNames()[0]);
    }

    /**
     * shapeFile转Geojson文件
     *
     * @param shpFile
     * @param outFile
     */
    public static void shapeFileToGeoJson(File shpFile, File outFile) {
        try {
            FeatureSource featuresource = getFeatureSource(shpFile);
            //读取要素
            SimpleFeatureCollection simpleFeatureCollection = (SimpleFeatureCollection) featuresource.getFeatures();
            System.out.println(simpleFeatureCollection.getSchema().getCoordinateReferenceSystem());
            GeoJSON.write(simpleFeatureCollection, outFile);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * shapeFile转Geojson文件
     *
     * @param shpFile    shape文件
     * @param outFile    输出geojson文件
     * @param outSrsCode 输出坐标系
     */
    public static void shapeFileToGeoJson(File shpFile, File outFile, String outSrsCode) {
        try {
            FeatureSource featuresource = getFeatureSource(shpFile);
            //读取shpa坐标系
            CoordinateReferenceSystem shapeCRS = featuresource.getSchema().getCoordinateReferenceSystem();
            //输出目标坐标系
            CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:" + outSrsCode, true);
            //投影转换系统
            MathTransform transform = CRS.findMathTransform(shapeCRS, targetCRS, true);
            //读取要素
            SimpleFeatureCollection simpleFeatureCollection = (SimpleFeatureCollection) featuresource.getFeatures();
            //FeatureJSON
            writeFeatureCollection(simpleFeatureCollection, outFile, targetCRS, transform);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void writeFeatureCollection(SimpleFeatureCollection collection, File outFile, CoordinateReferenceSystem crs, MathTransform transform) throws IOException {

        LinkedHashMap obj = new LinkedHashMap();
        obj.put("type", "FeatureCollection");

        if (collection.getSchema().getGeometryDescriptor() != null) {
            final ReferencedEnvelope bounds = collection.getBounds();

//            if (bounds != null) {
//                obj.put("bbox", new JSONStreamAware() {
//                    public void writeJSONString(Writer out) throws IOException {
//                        JSONArray.writeJSONString(Arrays.asList(bounds.getMinX(),
//                                bounds.getMinY(), bounds.getMaxX(), bounds.getMaxY()), out);
//                    }
//                });
//            }

            if (crs != null) {
                obj.put("crs", createCRS(crs));
            }
        }

        obj.put("features", new FeatureCollectionEncoder(collection, new GeometryJSON(8), transform));
        GeoJSONUtil.encode(obj, outFile);
    }

    private static Map<String, Object> createCRS(CoordinateReferenceSystem crs) throws IOException {
        Map<String, Object> obj = new LinkedHashMap<String, Object>();
        obj.put("type", "name");

        Map<String, Object> props = new LinkedHashMap<String, Object>();
        if (crs == null) {
            props.put("name", "EPSG:4326");
        } else {
            try {
                String identifier = CRS.lookupIdentifier(crs, true);
                props.put("name", identifier);
            } catch (FactoryException e) {
                throw (IOException) new IOException("Error looking up crs identifier").initCause(e);
            }
        }
        obj.put("properties", props);
        return obj;
    }

    static class FeatureCollectionEncoder implements JSONStreamAware {

        FeatureCollection features;
        GeometryJSON gjson;
        MathTransform transform;

        public FeatureCollectionEncoder(FeatureCollection features, GeometryJSON gjson, MathTransform transform) {
            this.features = features;
            this.gjson = gjson;
            this.transform = transform;
        }

        public void writeJSONString(Writer out) throws IOException {
            out.write("[");
            FeatureIterator i = features.features();
            try {
                if (i.hasNext()) {
                    SimpleFeature f = (SimpleFeature) i.next();
                    out.write(toJSONString(f));

                    while (i.hasNext()) {
                        out.write(",");
                        f = (SimpleFeature) i.next();
                        out.write(toJSONString(f));
                    }
                }
            } catch (TransformException e) {
                throw new RuntimeException(e);
            } finally {
                if (i != null) {
                    i.close();
                }
            }
            out.write("]");
            out.flush();
        }

        public String toJSONString(SimpleFeature feature) throws TransformException {
            SimpleFeatureType featureType = feature.getType();
            StringBuilder sb = new StringBuilder();
            sb.append("{");

            //type
            entry("type", "Feature", sb);
            sb.append(",");


            //geometry
            if (feature.getDefaultGeometry() != null) {
                Object geometry = feature.getDefaultGeometry();
                if (transform != null) {
                    geometry = JTS.transform((Geometry) feature.getDefaultGeometry(), transform);
                }
                string("geometry", sb).append(":")
                        .append(gjson.toString((Geometry) geometry));
                sb.append(",");
            }

            //properties
            int gindex = featureType.getGeometryDescriptor() != null ?
                    featureType.indexOf(featureType.getGeometryDescriptor().getLocalName()) :
                    -1;

            string("properties", sb).append(":").append("{");
            boolean attributesWritten = false;
            for (int i = 0; i < featureType.getAttributeCount(); i++) {
                AttributeDescriptor ad = featureType.getDescriptor(i);

                // skip the default geometry, it's already encoded
                if (i == gindex) {
                    continue;
                }

                Object value = feature.getAttribute(i);

                if (value == null) {
                    //skip
                    continue;
                }

                attributesWritten = true;

                // handle special types separately, everything else as a string or literal
                if (value instanceof Envelope) {
                    array(ad.getLocalName(), gjson.toString((Envelope) value), sb);
                } else if (value instanceof BoundingBox) {
                    array(ad.getLocalName(), gjson.toString((BoundingBox) value), sb);
                } else if (value instanceof Geometry) {
                    string(ad.getLocalName(), sb).append(":")
                            .append(gjson.toString((Geometry) value));
                } else {
                    entry(ad.getLocalName(), value, sb);
                }
                sb.append(",");
            }

            if (attributesWritten) {
                sb.setLength(sb.length() - 1);
            }
            sb.append("},");

            //id
            entry("id", feature.getID(), sb);

            sb.append("}");
            return sb.toString();
        }
    }

    /**
     * @param path cpg文件路径
     * @return
     * @throws Exception
     */
    private static String getShapeFileCharsetName(String path) throws Exception {
        File pFile = new File(path);
        if (pFile.exists() && !pFile.isFile()) {
            return "GBK";
        }
        File file = new File(path);
        String encode = "GBK";
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            // 一次读入一行,直到读入null为文件结束
            while ((tempString = reader.readLine()) != null) {
                // 显示行号
                if ("UTF-8".equals(tempString.toUpperCase())) {
                    encode = "UTF-8";
                    break;
                }
                break;
            }
            reader.close();
        } catch (IOException e) {
//            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }
        return encode;
    }
}

测试用例代码

package com.sboot.test;

import org.junit.Test;

import java.io.File;
import java.io.IOException;

public class GeoShapeFileTest {

    @Test
    public void shapeFileToGeoJsonTest() throws IOException {
        String dir = "C:\\Users\\admin\\Desktop\\split\\split";
        String outDir = "C:\\Users\\admin\\Desktop\\split";
        File dirFile = new File(dir);
        File[] files = dirFile.listFiles(f -> f.getName().endsWith(".shp"));
        for (File shapeFile : files) {
            String shapeName = shapeFile.getName();
            System.out.println(shapeName);
            File geoJsonFile = new File(outDir, shapeName + ".json");
            geoJsonFile.createNewFile();
            GeoShapeFileUtil.shapeFileToGeoJson(shapeFile, geoJsonFile, "4490");
        }

    }

    @Test
    public void readShapefileTest() {
        String shapeFileName = "C:\\Users\\admin\\Desktop\\test.shp";
        GeoShapeFileUtil.readShapeFile(new File(shapeFileName));
    }
}

引入geotools相关jar包

<dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>17.1</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-api</artifactId>
            <version>17.1</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-data</artifactId>
            <version>17.1</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>17.1</version>
        </dependency>
        <!-- 坐标系转换 -->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-epsg-hsql</artifactId>
            <version>17.1</version>
        </dependency>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值