java解析shp文件

    工作之余记录,没有美化好:
POM引入:


<!-- for geotools begin -->
    <!--处理空间数据-->
    <!-- geotools主要依赖 -->
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-metadata</artifactId>
        <version>27.2</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-referencing</artifactId>
        <version>27.2</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-epsg-wkt</artifactId>
        <version>27.2</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-shapefile</artifactId>
        <version>27.2</version>
    </dependency>

    <!--<dependency>-->
    <!--<groupId>org.geotools</groupId>-->
    <!--<artifactId>gt-data</artifactId>-->
    <!--<version>27.2</version>-->
    <!--</dependency>-->

    <!--<dependency>-->
    <!--<groupId>org.geotools</groupId>-->
    <!--<artifactId>gt-api</artifactId>-->
    <!--<version>27.2</version>-->
    <!--</dependency>-->
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-main</artifactId>
        <version>27.2</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-swing</artifactId>
        <version>27.2</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-jdbc</artifactId>
        <version>27.2</version>
    </dependency>
    <dependency>
        <groupId>org.geotools.jdbc</groupId>
        <artifactId>gt-jdbc-postgis</artifactId>
        <version>27.2</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-opengis</artifactId>
        <version>27.2</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-epsg-hsql</artifactId>
        <version>27.2</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-geojson</artifactId>
        <version>27.2</version>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-process-feature</artifactId>
        <version>27.2</version>
    </dependency>
    <dependency>
        <groupId>org.locationtech.jts</groupId>
        <artifactId>jts-core</artifactId>
        <version>1.18.2</version>
    </dependency>
    <!--for geotools end-->

    <!--读取geojson文件-->
    <dependency>
        <groupId>com.googlecode.json-simple</groupId>
        <artifactId>json-simple</artifactId>
        <version>1.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.wowtools</groupId>
        <artifactId>giscat-vector-pojo</artifactId>
        <version>1.1.1-STABLE</version>
    </dependency>
    <!--读取geojson文件end-->


</dependencies>

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/snapshot</url>
        <releases>
            <enabled>false</enabled>
        </releases>
    </repository>

    <!-- geotools的远程库 -->
    <repository>
        <id>osgeo</id>
        <name>OSGeo Release Repository</name>
        <url>https://repo.osgeo.org/repository/release/</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
        <releases>
            <enabled>true</enabled>
        </releases>
    </repository>
    <repository>
        <id>osgeo-snapshot</id>
        <name>OSGeo Snapshot Repository</name>
        <url>https://repo.osgeo.org/repository/snapshot/</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <releases>
            <enabled>false</enabled>
        </releases>
    </repository>
    <!-- geotools的远程库end -->
import org.geotools.data.DefaultTransaction;
import org.geotools.data.FeatureSource;
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.data.simple.SimpleFeatureStore;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.filter.text.cql2.CQL;
import org.geotools.geojson.GeoJSON;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.util.factory.GeoTools;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.MalformedURLException;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.*;
@Component
public class GeoToolsMethod {
    //使用openGIS FilterFactory2
    private static org.opengis.filter.FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints());
    //读取shp
    public FeatureSource<SimpleFeatureType, SimpleFeature> ReadShpFile(String filePath) throws Exception{
        File dir = new File(filePath);
        File[] subFiles = dir.listFiles();
        if (null!=subFiles){
            for (File subFile : subFiles) {
                if (subFile.getName().endsWith(".shp")) {
                    filePath = subFile.getPath();break;
                }
            }
        }
        File shpFile = new File(filePath);
        //源shape文件
        //ShapefileDataStore shpDataStore = (ShapefileDataStore) new ShapefileDataStoreFactory().createDataStore(subFile.toURI().toURL());
        ShapefileDataStore shpDataStore = new ShapefileDataStore(shpFile.toURI().toURL());
        shpDataStore.setCharset(Charset.forName("UTF-8"));
        FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = shpDataStore.getFeatureSource();
        return featureSource;
    }
    //读取geojson
    public FeatureCollection ReadGeojsonFile(String pathfile) throws Exception{
        FeatureCollection featureCollection = null;
                //创建一个JSONParser对象
        JSONParser jsonParser = new JSONParser();
        //解析JSON文件的内容
        try {
            //String pathfile = getClass().getClassLoader().getResource("csdata").getPath()+"/csfeature.geojson";
            //先用json.simple读取geojson文件
//            org.json.simple.JSONObject obj = (org.json.simple.JSONObject) jsonParser.parse(new FileReader("D:/hjyTest/JAVA/demo_gdal2/target/classes/csdata/csfeature.geojson"));
            JSONObject obj = (JSONObject) jsonParser.parse(new FileReader(pathfile));
            //JSONObject obj = (JSONObject) jsonParser.parse(new FileReader("E:\\河南省乡镇点\\FieldPolygon.geojson"));
            //删除除features以外其它对象,方便下面所需的geojson字符串
//            obj.remove("type");
//            obj.remove("name");
//            obj.remove("crs");
            //获取features对象json字符串
            String strGeoJson =obj.toString();
            System.out.println(strGeoJson);


            // 指定GeometryJSON构造器,15位小数
            FeatureJSON fjson_15 = new FeatureJSON(new GeometryJSON(15));
            // fjson_15已经保留15位
            fjson_15.setEncodeFeatureCollectionCRS(true);
            fjson_15.setEncodeNullValues(true);

            featureCollection = fjson_15.readFeatureCollection(strGeoJson);
            fjson_15.writeFeatureCollection(featureCollection,System.out);  // 控制台输出和原始geojson一致



//            OutputStream ostream = new ByteArrayOutputStream();
//            GeoJSON.write(featureCollection, ostream);
//            // 输出:{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[116.1983,39.7832],[116.0445,39.2323],[116.8959,39.3831],[116.8698,39.9182],[116.1983,39.7832]]]},"properties":{"area":3865207830},"id":"polygon.1"}]}
//            System.out.println(ostream);

//            //获取数据
//            FeatureIterator<SimpleFeature> iterator = featureCollection.features();
//            while(iterator.hasNext()) {
//                SimpleFeature feature = iterator.next();
//                try{
//                    org.locationtech.jts.geom.Geometry geom1 = (org.locationtech.jts.geom.Geometry) feature.getDefaultGeometry();
//                    System.out.println(geom1.getCoordinate());
//                }catch (Exception e){
//
//                }
//
//
//                feature.getName();
//                Iterator<Property> it = feature.getProperties().iterator();
//                LinkedHashMap<String, Object> data = new LinkedHashMap<>();
//                String geometry = "";
//                while (it.hasNext()) {
//                    Property pro = it.next();
//                    if (pro.getValue() instanceof  org.locationtech.jts.geom.Point) {//点
//                        geometry = "'" + ((org.locationtech.jts.geom.Point) pro.getValue()).toString() + "'";
//                        data.put("geom", geometry);
//                    } else if (pro.getValue() instanceof org.locationtech.jts.geom.Polygon) {//面
//                        geometry = "'" + ((org.locationtech.jts.geom.Polygon) pro.getValue()).toString() + "'";
//                        data.put("geom", geometry);
//                    } else if (pro.getValue() instanceof org.locationtech.jts.geom.MultiPolygon) {//多面
//                        geometry = "'" + ((org.locationtech.jts.geom.MultiPolygon) pro.getValue()).toString() + "'";
//                        data.put("geom", geometry);
//                    } else if (pro.getValue() instanceof org.locationtech.jts.geom.LineString) {//线
//                        geometry = "'" + ((org.locationtech.jts.geom.LineString) pro.getValue()).toString() + "'";
//                        data.put("geom", geometry);
//                    } else {
//                        data.put(pro.getName().toString(), pro.getValue());
//                    }
//                }
//                System.out.println(data);
//            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return featureCollection;
    }
    //方法一:
    //返回其属性值
    public List<LinkedHashMap<String,Object>> getAttirbutes(String srs, FeatureCollection col){
        //srs="EPSG:4326"
        List<LinkedHashMap<String,Object>> listMap = new ArrayList<>();
        FeatureIterator<SimpleFeature> iterator = col.features();
            while(iterator.hasNext()) {
                SimpleFeature feature = iterator.next();
                //获取属性
                Iterator<Property> it = feature.getProperties().iterator();
                LinkedHashMap<String, Object> data = new LinkedHashMap<>();
                String geometry = "";
                while (it.hasNext()) {
                    Property pro = it.next();
                    if (pro.getValue() instanceof Point) {//点
                        geometry = "'"  +((Point) pro.getValue()).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1);
                        data.put("geom",geometry);
                    } else if (pro.getValue() instanceof Polygon) {//面
                        geometry = "'"+((Polygon) pro.getValue()).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1);
                        data.put("geom",geometry);
                    } else if (pro.getValue() instanceof MultiPolygon) {//多面
                        geometry = "'"+((MultiPolygon) pro.getValue()).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1);
                        data.put("geom",geometry);
                    } else if (pro.getValue() instanceof LineString) {//线
                        geometry = "'" +((LineString) pro.getValue()).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1);
                        data.put("geom",geometry);
                    } else {
                        if(pro.getValue() instanceof Date){
                            Date myDate = (Date)pro.getValue();
                            SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            String strDate3 = sdf3.format(myDate);
                            data.put(pro.getName().toString(),strDate3);
                        }else{
                            data.put(pro.getName().toString(),pro.getValue());
                        }
                    }
                }
                //System.out.println(data);
                listMap.add(data);
            }
            return listMap;
    }
    //方法二:
    //返回属性值
    public List<LinkedHashMap<String,Object>> getAttirbutes2(String srs, FeatureCollection col){
        //srs="EPSG:4326"
        List<LinkedHashMap<String,Object>> listMap = new ArrayList<>();
        //另外一种循环start
        SimpleFeatureCollection sfc = (SimpleFeatureCollection)col;
        // 获取当前矢量数据有哪些属性字段值
        List<AttributeDescriptor> attributes = sfc.getSchema().getAttributeDescriptors();
        // 拿到迭代器
        SimpleFeatureIterator simpleFeatureIterator = sfc.features();
        // 遍历每一个要素
        while(simpleFeatureIterator.hasNext()) {
            SimpleFeature simpleFeature = simpleFeatureIterator.next();
            LinkedHashMap<String, Object> data = new LinkedHashMap<>();
            // java8新特性流api
            attributes.stream().forEach((a) -> {
                Object tempobj = simpleFeature.getAttribute(a.getLocalName());
                // 依次读取这个shape中每一个属性值,当然这个属性值,可以处理其它业务
                if(a.getLocalName().indexOf("geom")>=0){
                    String geometry = "";
                    if (tempobj instanceof Point) {//点
                        geometry = "'"  +((Point) tempobj).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1);
                        data.put("geom",geometry);
                    } else if (tempobj instanceof Polygon) {//面
                        geometry = "'"+((Polygon) tempobj).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1);
                        data.put("geom",geometry);
                    } else if (tempobj instanceof MultiPolygon) {//多面
                        geometry = "'"+((MultiPolygon) tempobj).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1);
                        data.put("geom",geometry);
                    } else if (tempobj instanceof LineString) {//线
                        geometry = "'" +((LineString) tempobj).toString()+ "'"+","+srs.substring(srs.indexOf(":")+1);
                        data.put("geom",geometry);
                    }
                }else{
                    if(tempobj instanceof Date){
                        Date myDate = (Date)tempobj;
                        SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        String strDate3 = sdf3.format(myDate);
                        data.put(a.getLocalName(),strDate3);
                    }else{
                        data.put(a.getLocalName(),tempobj);
                    }
//                    System.out.println(a.getLocalName() + ":" + simpleFeature.getAttribute(a.getLocalName()));
                }
            });
            listMap.add(data);
        }
        return listMap;
    }
    //查询 CQL
    public Filter ReturnFilter(String sql)throws Exception{
        String wkt = "POLYGON ((113.17574362102584 23.135924459989738, 113.07445367113468 22.981863911800943, 113.3121749821035 22.932375044753726, 113.3907263718155 23.073180341529934, 113.17574362102584 23.135924459989738))";
        Filter filter = null;
        // 相交
        filter =  CQL.toFilter( "OBJECTID = 5 or INTERSECTS(the_geom," + wkt + ")");
        if(sql!=null || sql!=""){
            filter = CQL.toFilter(sql);
        }
        // 在10公里以内
        //  Filter filter =  CQL.toFilter( "DWITHIN(the_geom," + wkt + ", 10, kilometers)");
        return filter;
    }
    //查询 使用openGIS FilterFactory2
    public Filter ReturnFilter2(){
        Filter filter = ff.greaterOrEqual(ff.property("OBJECTID"), ff.literal(5));
        return filter;
    }

    public static SimpleFeatureType createType(Class<?> c, String layerName) {
        SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
        builder.setCRS(DefaultGeographicCRS.WGS84);
        builder.add("FID",String.class);
        builder.add("the_geom", c);
        // 设置了图层的名字
        builder.setName(layerName);
        SimpleFeatureType simpleFeatureType = builder.buildFeatureType();
        return simpleFeatureType;
    }
  //生成shp
    public static void createShp(String shpPath, SimpleFeatureCollection collection) throws IOException {
        File shpFile = new File(shpPath);
        ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
        SimpleFeatureType simpleFeatureType = collection.getSchema();
        // 创造shpstore需要的参数
        Map<String, Serializable> params = new HashMap<>();
        params.put("url", shpFile.toURI().toURL());
        params.put("create spatial index", Boolean.TRUE);
        ShapefileDataStore newDataStore =
                (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
        newDataStore.createSchema(simpleFeatureType);
        Transaction transaction = new DefaultTransaction("create");
        String typeName = newDataStore.getTypeNames()[0];
        SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);
        SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
        featureStore.setTransaction(transaction);
        featureStore.addFeatures(collection);
        featureStore.setTransaction(transaction);
        transaction.commit();
        transaction.close();
    }
/  //这里也是读取shp
    public static SimpleFeatureCollection readFeatureCollection(String shpPath) {
        SimpleFeatureCollection featureCollection = null;
        File shpFile = new File(shpPath);
        try {
            ShapefileDataStore shapefileDataStore = new ShapefileDataStore(shpFile.toURI().toURL());
            // 设置编码,防止属性的中文字符出现乱码
            shapefileDataStore.setCharset(Charset.forName("UTF-8"));
            // 这个typeNamae不传递,默认是文件名称
            FeatureSource featuresource = shapefileDataStore.getFeatureSource(shapefileDataStore.getTypeNames()[0]);
            featureCollection = (SimpleFeatureCollection) featuresource.getFeatures();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return featureCollection;
    }

}

@Autowired
    GeoToolsMethod geoToolsMethod;

//测试geoTools封装好的方法
    @Test
    public void Test_geoToolsMethod() throws Exception{
        //测试读取shp
        FeatureSource<SimpleFeatureType, SimpleFeature> featureSource=geoToolsMethod.ReadShpFile("D:\\ceshi\\dwq0606");
        String srs = CRS.lookupIdentifier(featureSource.getSchema().getCoordinateReferenceSystem(),true);  // 获取EPSG
        System.out.println(srs);
        FeatureCollection collection = featureSource.getFeatures();
        long startTime = System.currentTimeMillis();
        //测试获取getAttributes
        List<LinkedHashMap<String,Object>> listAttr = geoToolsMethod.getAttirbutes(srs,collection);
        long endTime = System.currentTimeMillis();
        System.out.println("运行时长:"+(endTime-startTime)+"ms"); //1128ms
        startTime = System.currentTimeMillis();
        //测试获取getAttributes2
        List<LinkedHashMap<String,Object>> listAttr2 = geoToolsMethod.getAttirbutes2(srs,collection);
        endTime = System.currentTimeMillis();
        System.out.println("运行时长:"+(endTime-startTime)+"ms"); //980ms 1015
        //System.out.println(listAttr);
    }

//做geometry 的计算距离,取交集、合并几何、difference
    @Test
    public void GeometryOperate() throws Exception{
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory( null );
        //创建一条线
        List<Coordinate> points1 = new ArrayList<Coordinate>();
        points1.add(new Coordinate(0,0));
        points1.add(new Coordinate(1,3));
        points1.add(new Coordinate(2,3));
        Coordinate[] coords  = (Coordinate[]) points1.toArray(new Coordinate[points1.size()]);
        LineString line1 = geometryFactory.createLineString(coords);
        //创建第二条线
        List<Coordinate> points2 = new ArrayList<Coordinate>();
        points2.add(new Coordinate(3,0));
        points2.add(new Coordinate(3,3));
        points2.add(new Coordinate(5,6));
        Coordinate[] coords2  = (Coordinate[]) points2.toArray(new Coordinate[points2.size()]);
        LineString line2 = geometryFactory.createLineString(coords2);
//        返回(A)与(B)中距离最近的两个点的距离
        System.out.println(line1.distance(line2));//out 1.0
//        两个几何对象的交集
        System.out.println(line1.intersection(line2));//out GEOMETRYCOLLECTION EMPTY
//        几何对象合并
        Geometry lineunion = line1.union(line2);
        System.out.println(lineunion); //out MULTILINESTRING ((0 0, 1 3, 2 3), (3 0, 3 3, 5 6))
        //在A几何对象中有的,但是B几何对象中没有
        System.out.println(line1.difference(line2));//out LINESTRING (0 0, 1 3, 2 3)
        System.out.println(lineunion.difference(line2));//out LINESTRING (0 0, 1 3, 2 3)
        //交集
        System.out.println(lineunion.intersection(line2));//out MULTILINESTRING ((3 0, 3 3), (3 3, 5 6))

        WKTReader reader = new WKTReader(geometryFactory);
        Polygon geometry1 = (Polygon) reader.read("POLYGON((0 0, 2 0 ,2 2, 0 2,0 0))");
        Polygon geometry2 = (Polygon) reader.read("POLYGON((0 0, 4 0 , 4 1, 0 1, 0 0))");
        OverlayOp op = new OverlayOp(geometry1,geometry2);
        Geometry g =op.getResultGeometry(OverlayOp.INTERSECTION);//POLYGON ((2 0, 0 0, 0 1, 2 1, 2 0))
        //Geometry g2 = op.getResultGeometry(OverlayOp.UNION);
        //Geometry g3 = op.getResultGeometry(OverlayOp.DIFFERENCE);
        //Geometry g4 = op.getResultGeometry(OverlayOp.SYMDIFFERENCE);
        //PlanarGraph p = op.getGraph(); //图<v,e

        //LineMerger 线路合并,线路之间不能有交点,并且只在线路末尾有公共交点
        // lineMerger 和union区别,union可以在两条相交的线中生成交点(noded)
        WKTReader wktReader = new WKTReader();
        LineMerger lineMerger = new LineMerger();
        List<Geometry> list = new ArrayList<Geometry>();
        list.add(wktReader.read("LINESTRING (3 3,2 2,0 0)"));
        list.add(wktReader.read("LINESTRING (3 3,6 6,0 10)"));
        list.add(wktReader.read("LINESTRING (0 10,3 1,10 1)"));
        lineMerger.add(list);
        Collection<Geometry> mergerLineStrings = lineMerger.getMergedLineStrings();
        for (Geometry tempg : mergerLineStrings) {
            System.out.println(tempg.toText()); //LINESTRING (0 0, 2 2, 3 3, 6 6, 0 10, 3 1, 10 1)
        }

    }

  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值