java 使用GeoTools工具 geojson 与shp 相互转换

记录使用geotools工具,实现shp和geojson数据互转

java 使用GeoTools工具 geojson 与shp 相互转换_第1张图片 

 爬坑:不使用依赖:vividsolutions ,因为 1.8 与 geotools 20以后版本jts 不一致,会报错。


    com.vividsolutions
    jts
    1.8
    pom

----------------------------------------------------------开启编码-------------------------------------------------------

1. 引起pom依赖jar


    
        org.geotools
        gt-shapefile
        20.3
    
    
        org.geotools
        gt-api
        20.3
    
    
        org.geotools
        gt-geojson
        20.3
    
    
        org.geotools
        gt-geometry
        20.3
    
    
        org.geotools
        gt-jts-wrapper
        20.3
    
    
        org.geotools
        gt-main
        20.3
    
    
        org.geotools
        gt-epsg-hsql
        20.3
    
    
        org.geotools
        gt-opengis
        20.3
    
    
        org.geotools
        gt-data
        20.3
    
    
        org.geotools
        gt-referencing
        20.3
    
    
        com.alibaba
        fastjson
        1.2.83
    




    
        
            org.apache.maven.plugins
            maven-compiler-plugin
            3.0
            
                1.8
                1.8
                true
            
        
    

2. 上代码,自动识别坐标系,默认为84坐标

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.geotools.referencing.CRS;
import org.locationtech.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 org.opengis.referencing.crs.CoordinateReferenceSystem;

import java.io.*;
import java.nio.charset.Charset;
import java.util.*;

/**
 * @author qiaobing1226
 * @since 2022/10/28 上午10:52
 * 参考:https://blog.csdn.net/qiaobing1226/article/details/127612665
 */
public class Shp2GeojsonUtils {
    private static final String POINT = "Point";
    private static final String MULTIPOINT = "MultiPoint";
    private static final String LINESTRING = "LineString";
    private static final String MULTILINESTRING = "MultiLineString";
    private static final String POLYGON = "Polygon";
    private static final String MULTIPOLYGON = "MultiPolygon";
    private static final String THE_GEOM = "the_geom";
    private static final String PROPERTIES = "properties";
    private static final String GEOMETRY = "geometry";
    private static final String GBK = "GBK";

    /**
     * geoJson转换为shp文件
     *
     * @param jsonPath
     * @param shpPath
     * @return
     */
    public static Map geoJson2Shape(String jsonPath, String shpPath) {
        Map map = new HashMap<>();
        GeometryJSON geoJson = new GeometryJSON();
        try {
            JSONObject json = readGeoJsonFile(jsonPath);
            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");
            String strCrs = json.getJSONObject("crs").getJSONObject(PROPERTIES).getString("name");
            CoordinateReferenceSystem crs = CRS.decode(strCrs);
            ShapefileDataStore shapefileDataStore = dataStore(properties, strType, shpPath, crs);
            if (shapefileDataStore == null) {
                return map;
            }
            // 设置Writer
            FeatureWriter writer = shapefileDataStore.getFeatureWriter(shapefileDataStore.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, geoJson.readPoint(reader));
                        break;
                    case MULTIPOINT:
                        feature.setAttribute(THE_GEOM, geoJson.readMultiPoint(reader));
                        break;
                    case LINESTRING:
                        feature.setAttribute(THE_GEOM, geoJson.readLine(reader));
                        break;
                    case MULTILINESTRING:
                        feature.setAttribute(THE_GEOM, geoJson.readMultiLine(reader));
                        break;
                    case POLYGON:
                        feature.setAttribute(THE_GEOM, geoJson.readPolygon(reader));
                        break;
                    case MULTIPOLYGON:
                        feature.setAttribute(THE_GEOM, geoJson.readMultiPolygon(reader));
                        break;
                }
                Iterator iterator = properties.iterator();
                while (iterator.hasNext()) {
                    String str = iterator.next().toString();
                    JSONObject element = JSONObject.parseObject(features.get(i).toString());
                    feature.setAttribute(str, JSONObject.parseObject(element.getString(PROPERTIES)).get(str));
                }
                writer.write();
            }
            writer.close();
            shapefileDataStore.dispose();
            map.put("status", 200);
            map.put("message", "shp转换success");
        } catch (Exception e) {
            map.put("status", 400);
            map.put("message", e.getMessage());
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 读取geojosn文件
     *
     * @param jsonPath
     * @return
     */
    private static JSONObject readGeoJsonFile(String jsonPath) {
        // 读文件到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) {
            if (br != null) {
                try {
                    br.close();
                } catch (Exception exception) {
                    exception.printStackTrace();
                }
            }
            e.printStackTrace();
        }
        return JSONObject.parseObject(sb.toString());
    }

    /**
     * 设置shp文件属性
     *
     * @param properties
     * @param strType
     * @param shpPath
     * @return
     */
    private static ShapefileDataStore dataStore(Set properties, String strType, String shpPath, CoordinateReferenceSystem crs) {
        try {
            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 params = new HashMap();
            params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
            ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
            // 定义图形信息和属性信息
            SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
            //默认84坐标
            tb.setCRS(crs == null ? DefaultGeographicCRS.WGS84 : crs);
            tb.setName("shapefile");
            // 类型,Point/MultiPoint/LineString/MultiLineString/Polygon/MultiPolygon
            tb.add("the_geom", geoType);
            Iterator propertiesIter = properties.iterator();
            // 设置属性
            while (propertiesIter.hasNext()) {
                String str = propertiesIter.next().toString();
                // 此处设置为string
                tb.add(str, String.class);
            }
            ds.createSchema(tb.buildFeatureType());
            // 设置编码
            Charset charset = Charset.forName(GBK);
            ds.setCharset(charset);
            return ds;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;

    }

    /**
     * shp文件转换geojson数据
     *
     * @param shpPath
     * @return
     */
    public static Map shp2Geojson(String shpPath, String jsonPath) {
        Map map = new HashMap();
        //新建json对象

        JSONObject geojsonObject = new JSONObject();
        geojsonObject.put("type", "FeatureCollection");
        try {
            JSONArray array = new JSONArray();
            String fileName = readShpContent(shpPath, array);
            geojsonObject.put("features", array);
            geojsonObject.put("name", fileName);
            String crs = getCoordinateSystemWKT(shpPath);
            //GEOGCS表示这个是地址坐标系,PROJCS则表示是平面投影坐标系
            JSONObject crsJson = new JSONObject();
            JSONObject proJson = new JSONObject();
            crsJson.put("type", "name");
            if (crs.startsWith("PROJCS")) {
                proJson.put("name", "urn:ogc:def:crs:EPSG::3857");
                crsJson.put("properties", proJson);
            } else {
                proJson.put("name", "urn:ogc:def:crs:OGC:1.3:CRS84");
                crsJson.put("properties", proJson);
            }
            geojsonObject.put("crs", crsJson);

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

    private static String readShpContent(String shpPath, JSONArray array) {
        String fileName = "";
        try {
            FeatureJSON fjson = new FeatureJSON();
            //获取featurecollection
            File file = new File(shpPath);
            ShapefileDataStore shpDataStore = null;
            shpDataStore = new ShapefileDataStore(file.toURL());
            //设置编码
/*            Charset charset = Charset.forName("GBK");
            shpDataStore.setCharset(charset);*/
            fileName = shpDataStore.getTypeNames()[0];
            SimpleFeatureSource featureSource = null;
            featureSource = shpDataStore.getFeatureSource(fileName);
            SimpleFeatureCollection result = featureSource.getFeatures();
            SimpleFeatureIterator itertor = result.features();

            //遍历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(json);
            }
            itertor.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileName;
    }

    /**
     * 获取Shape文件的坐标系信息,GEOGCS表示这个是地址坐标系,PROJCS则表示是平面投影坐标系
     *
     * @shpPath
     */
    public static String getCoordinateSystemWKT(String shpPath) {
        ShapefileDataStoreFactory factory = new ShapefileDataStoreFactory();
        ShapefileDataStore dataStore = null;
        try {
            dataStore = (ShapefileDataStore) factory.createDataStore(new File(shpPath).toURI().toURL());
            return dataStore.getSchema().getCoordinateReferenceSystem().toWKT();
        } catch (UnsupportedOperationException | IOException e) {
            e.printStackTrace();
        } finally {
            dataStore.dispose();
        }
        return "";
    }

    /**
     * 工具类测试方法
     *
     * @param args
     */
    public static void main(String[] args) throws Exception {
        Shp2GeojsonUtils shpToGeojson = new Shp2GeojsonUtils();
//        // shape2Geojson
        String shpPath = "/Users/ecarx/Desktop/geojson/上下高架mct/123/AD_Road.shp";
        String jsonPath = "/Users/ecarx/Desktop/geojson/AD_Road.geojson";
        Map map = shpToGeojson.shp2Geojson(shpPath, jsonPath);

        // geojson2Shape
//        String shpPath = "/Users/ecarx/Desktop/geojson/上下高架mct/123/AD_Road.shp";
//        String jsonPath = "/Users/ecarx/Desktop/geojson/上下高架mct/AD_Road.geojson";
//        Map map = shpToGeojson.geoJson2Shape(jsonPath, shpPath);
//        System.out.println(map.toString());
    }
}

你可能感兴趣的:(gis,java,开发语言)