Java使用geotools将Geometry(地图要素)导出为shp文件

        做图形方面的功能,往往会遇到将地图要素导出成shap文件的需求,现整理记录一下方便后期直接使用。

1、需要用到的依赖

        <geotools.version>20.5</geotools.version>
        <!--jts版本跟geotools相匹配,20.x后的需要1.16版本-->
        <jts.version>1.16.1</jts.version>

        <!-- geotools start -->
        <dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-main</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-referencing</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-api</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-opengis</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-metadata</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-geometry</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-coverage</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-cql</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-data</artifactId>
			<version>${geotools.version}</version>
		</dependency>
        <dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-epsg-wkt</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-jdbc</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools.jdbc</groupId>
			<artifactId>gt-jdbc-postgis</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-shapefile</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-geojson</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>com.googlecode.json-simple</groupId>
			<artifactId>json-simple</artifactId>
			<version>1.1.1</version>
		</dependency>
		<dependency>
			<groupId>org.geotools</groupId>
			<artifactId>gt-swing</artifactId>
			<version>${geotools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.locationtech.jts</groupId>
			<artifactId>jts-core</artifactId>
			<version>1.16.1</version>
		</dependency>
		 <!-- geotools end -->

2、工具类

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

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.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiLineString;
import org.locationtech.jts.geom.MultiPoint;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
 
public class ShapeUtil {
 
    /**
     * 生成shape文件
     *
     * @param shpPath 生成shape文件路径(包含文件名称)
     * @param encode  编码
     * @param geoType 图幅类型,Point和Rolygon
     * @param geoms   图幅集合
     */
    public static void write2Shape(String shpPath, String encode, String geoType, List<Geometry> geoms) {
        try {
            //创建shape文件对象
            File file = new File(shpPath);
            Map<String, Serializable> params = new HashMap<>();
            params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
            ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(params);
            //定义图形信息和属性信息
            SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
            /**
             *  //方式一
             *	CRS.decode("EPSG:4326");
             *  //方式二
             *	DefaultGeographicCRS.WGS84;
             *
             *  EPSG:4490为大地坐标系_国家2000大地坐标系CGCS2000
             *  EPSG:4326支持一种默认的定义方式, 坐标系WGS84
             */
            tb.setCRS(CRS.decode("EPSG:4490"));
            
            tb.setName("shapefile");
 
            if ("Polygon".equals(geoType) || "polygon".equals(geoType)) {
                tb.add("the_geom", Polygon.class);
            } else if ("MultiPolygon".equals(geoType)) {
                tb.add("the_geom", MultiPolygon.class);
            } else if ("Point".equals(geoType) || "point".equals(geoType)) {
                tb.add("the_geom", Point.class);
            } else if ("MultiPoint".equals(geoType)) {
                tb.add("the_geom", MultiPoint.class);
            } else if ("LineString".equals(geoType)) {
                tb.add("the_geom", LineString.class);
            } else if ("MultiLineString".equals(geoType) || "Polyline".equals(geoType) || "polyline".equals(geoType)) {
                tb.add("the_geom", MultiLineString.class);
            } else {
                throw new Exception("Geometry中没有该类型:" + geoType);
            }
 
            ds.createSchema(tb.buildFeatureType());
            //设置编码
            Charset charset = Charset.forName(encode);
            ds.setCharset(charset);
            //设置Writer
            FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);
            for (Geometry geom : geoms) {
                //String type = geom.getGeometryType();
 
                //写下一条
                SimpleFeature feature = writer.next();
 
                feature.setAttribute("the_geom", geom);
            }
            writer.write();
            writer.close();
            ds.dispose();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 生成shape文件
     *
     * @param shpPath  生成shape文件路径(包含文件名称)
     * @param encode   编码
     * @param geoType  图幅类型,Point和Rolygon
     * @param shpKey   data中图幅的key
     * @param attrKeys 属性key集合
     * @param data     图幅和属性集合
     */
    public static void write2Shape(String shpPath, String encode, String geoType, String shpKey, List<String> attrKeys, List<Map<String, Object>> data) {
        try {
            if (data == null || data.size() == 0) {
                return;
            }
            //创建shape文件对象
            File file = new File(shpPath);
            Map<String, Serializable> params = new HashMap<>();
            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");
 
            if ("Polygon".equals(geoType)) {
                tb.add("the_geom", Polygon.class);
            } else if ("MultiPolygon".equals(geoType)) {
                tb.add("the_geom", MultiPolygon.class);
            } else if ("Point".equals(geoType)) {
                tb.add("the_geom", Point.class);
            } else if ("MultiPoint".equals(geoType)) {
                tb.add("the_geom", MultiPoint.class);
            } else if ("LineString".equals(geoType)) {
                tb.add("the_geom", LineString.class);
            } else if ("MultiLineString".equals(geoType)) {
                tb.add("the_geom", MultiLineString.class);
            } else {
                throw new Exception("Geometry中没有该类型:" + geoType);
            }
 
            for (String field : attrKeys) {
                tb.add(field.toUpperCase(), String.class);
            }
 
            ds.createSchema(tb.buildFeatureType());
            //设置编码
            Charset charset = Charset.forName(encode);
            ds.setCharset(charset);
            //设置Writer
            FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);
            //写入文件信息
            for (int i = 0; i < data.size(); i++) {
                SimpleFeature feature = writer.next();
                Map<String, Object> row = data.get(i);
                Geometry geom = (Geometry) row.get(shpKey);
                feature.setAttribute("the_geom", geom);
                for (String key : row.keySet()) {
                    if (!key.equals(shpKey)) {
                        if (row.get(key) != null) {
                            feature.setAttribute(key.toUpperCase(), row.get(key).toString());
                        } else {
                            feature.setAttribute(key.toUpperCase(), "");
                        }
                    }
                }
            }
            writer.write();
            writer.close();
            ds.dispose();
 
            //添加到压缩文件
            //zipShapeFile(shpPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
 
    /**
     * 压缩shape文件
     *
     * @param shpPath shape文件路径(包含shape文件名称)
     */
    public static void zipShapeFile(String shpPath) {
        try {
            File shpFile = new File(shpPath);
            String shpRoot = shpFile.getParentFile().getPath();
            String shpName = shpFile.getName().substring(0, shpFile.getName().lastIndexOf("."));
 
            String zipPath = shpRoot + File.separator + shpName + ".zip";
            File zipFile = new File(zipPath);
            InputStream input = null;
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
            // zip的名称为
            zipOut.setComment(shpName);
            String[] shpFiles = new String[]{
                    shpRoot + File.separator + shpName + ".dbf",
                    shpRoot + File.separator + shpName + ".prj",
                    shpRoot + File.separator + shpName + ".shp",
                    shpRoot + File.separator + shpName + ".shx",
                    shpRoot + File.separator + shpName + ".fix"
            };
 
            for (int i = 0; i < shpFiles.length; i++) {
                File file = new File(shpFiles[i]);
                input = new FileInputStream(file);
                zipOut.putNextEntry(new ZipEntry(file.getName()));
                int temp = 0;
                while ((temp = input.read()) != -1) {
                    zipOut.write(temp);
                }
                input.close();
            }
            zipOut.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.io.WKTReader;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

public class GeometryUtil {
	
	/**
     * geometry转geojson
     * @param geometry
     * @return JSONObject
     * @throws IOException
     */
    public static JSONObject toGeoJson(Geometry geometry) {
        try {
            StringWriter sw = new StringWriter();
            // 设置保留6位小数,否则GeometryJSON默认保留4位小数
            GeometryJSON geometryJson = new GeometryJSON(6);
            geometryJson.write(geometry, sw);
            JSONObject geoJson = JSONObject.parseObject(sw.toString());
            sw.close();
            return geoJson;
        }catch(IOException ex){
            ex.printStackTrace();
            return null;
        }
    }
    
    /**
     * geojson转geometry
     * @param geojson
     * @return Geometry
     */
    public static Geometry toGeometry(JSONObject geojson){
        Geometry geometry = null;
        try {
            GeometryJSON geometryJson = new GeometryJSON(6);
            String jsonStr = JSONObject.toJSONString(geojson);
            StringReader sr = new StringReader(jsonStr);
            geometry = geometryJson.read(sr);
            sr.close();
            return geometry;
        }catch(IOException ex){
            ex.printStackTrace();
            return null;
        }
    }
	
    /**
     * 字符串转对象
     * @param wktGeometry
     * @return Geometry
     */
    public static Geometry toGeometry(String wktGeometry){
        try {
            GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
            WKTReader reader = new WKTReader(geometryFactory);
            Geometry geometry = reader.read(wktGeometry);
            return geometry;
        }catch (Exception ex){
            ex.printStackTrace();
            return null;
        }
    }
    
    public static List<String> arrayListToWktPoint(JSONArray points){
        List<String> strings = new ArrayList<>();
        for (int i=0;i<points.size();i++){
            String result = points.getString(i);
            result = result.substring(0,result.lastIndexOf(",")-1);
            result =  "MULTIPOINT"+result.replace("[","(").replace(","," ")+")";
            strings.add(result);
        }
        return strings;
    }

    public static List<String> arrayListToWktLine(JSONArray lines){
        List<String> strings = new ArrayList<>();
        for (int i=0;i<lines.size();i++){
            String result = lines.getString(i);
            result =  "MULTILINESTRING"+result.replace(","," ").replace(" 0.0] [",",").replace(" 0.0]","]").replace("[","(").replace("]",")");
            strings.add(result);
        }
        return strings;
    }

    public static String shapeToWktPolygon(JSONObject shape){
        String geom = "";
        JSONArray coordinates = shape.getJSONObject("geometry").getJSONArray("coordinates");
        for (int i=0;i<coordinates.size();i++){
            JSONArray zbc = coordinates.getJSONArray(i).getJSONArray(0);
            String zbcstr = "";
            for (int j=0;j<zbc.size();j++){
                JSONArray xy = zbc.getJSONArray(j);
                for (int k=0;k<xy.size();k++){
                    if (k==0){
                        zbcstr += xy.getString(k)+" ";
                    }else if (k==1){
                        zbcstr += xy.getString(k)+",";
                    }
                }
            }
            geom ="MULTIPOLYGON((("+zbcstr.substring(0,zbcstr.lastIndexOf(","))+")))";
        }
        return geom;
    }

	 public static String geomToWkt(Geometry geometry) {
	       String wkt = null;
	       WKTWriter writer = new WKTWriter();
	       wkt = writer.write(geometry);
	       return wkt;
	 }

	 public static Geometry wktToGeom(String wkt) throws ParseException {
	       Geometry geometry = null;
	       WKTReader reader = new WKTReader();
	       geometry = reader.read(wkt);
	       return geometry;
	 }


}
//测试
   public static void main(String[] args) throws Exception {
       
       List<String> list = new ArrayList<>();

       //list.add("POLYGON ((116.21278950384274 39.90557982319698, 116.21177234433465 39.90610963061354, 116.21106912279264 39.90264172209895, 116.21399502548638 39.902612822554126, 116.21629305278306 39.905011479365406, 116.21278950384274 39.90557982319698))");
       //list.add("POLYGON((113.38185597038 34.54828048706,113.38224220848 34.548355588913,113.38249970055 34.548108825684,113.38237095451 34.54787279129,113.38208127594 34.547786960602,113.38185597038 34.54828048706))");
       
       list.add("[116.28338813781738,39.82858807695661,0.0]");
       
       
       List<Geometry> geometryList = new ArrayList<>();
       for (String str : list) {
           Geometry geom = GeometryUtil.wktToGeom(str);
           geometryList.add(geom);
       }
       
       String url = "D:\\attachment\\ZBDC\\ceshi88889999.shp";
       File file = new File(url);
       if (!file.getParentFile().exists()) {
    	   file.getParentFile().mkdirs();
       }
       
       ShapeUtil.write2Shape(url, "utf-8", "Point", geometryList);
       ShapeUtil.zipShapeFile(url);

   }

3、测试结果

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值