Java使用geotools将Geometry转换为kml

最近有个需求,要求将地图要素导出成kml文件,略作研究再次整理下步骤,作为备忘。

1、引入依赖包pom.xml

14.1        
		
			org.geotools
			gt-shapefile
			${geotools.version}
		

		
			org.geotools
			gt-api
			${geotools.version}
		

		
			org.geotools
			gt-opengis
			${geotools.version}
		

		
			org.geotools
			gt-data
			${geotools.version}
		

		
			org.geotools
			gt-main
			${geotools.version}
		

		
			org.geotools
			gt-referencing
			13.2
		

		
			org.geotools
			gt-metadata
			${geotools.version}
		
		
			org.geotools.xsd
			gt-xsd-kml
			${geotools.version}
		
		
			org.geotools.xsd
			gt-xsd-core
			${geotools.version}
		
		
			com.vividsolutions
			jts
			1.13
		

 

2、导出步骤

import com.vividsolutions.jts.geom.*;
import org.geotools.data.DataUtilities;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.kml.v22.KML;
import org.geotools.kml.v22.KMLConfiguration;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.xml.Encoder;
import org.opengis.feature.simple.SimpleFeature;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

public class KmlUtil {

    
    /**
     * 生成wml文件
     * @param wmlPath wml文件路径(包含文件名称) 如:D:\data\tmp\ceshi.kml
     * @param type 图幅元素类型
     * @param geometries 图幅集合
     * @throws Exception
     */
    public static void write2Wml(String wmlPath, String type, List geometries) throws Exception {
        FileOutputStream fos = new FileOutputStream(wmlPath,true);
        String str = write2WmlStr(type, geometries);
        //true表示在文件末尾追加
        fos.write(str.getBytes());
        fos.close();
    }

    /**
     * 生成wml文件
     * @param wmlPath wml文件路径(包含文件名称) 如:D:\data\tmp\ceshi.kml
     * @param type 图幅元素类型
     * @param geoKey data中图幅的key
     * @param attrKeys 属性key集合
     * @param geomList 图幅和属性集合
     * @throws Exception
     */
    public static void write2Wml(String wmlPath, String type, String geoKey, List attrKeys, List> geomList) throws Exception {
        FileOutputStream fos = new FileOutputStream(wmlPath,true);
        String str = write2WmlStr(type, geoKey, attrKeys, geomList);
        //true表示在文件末尾追加
        fos.write(str.getBytes());
        fos.close();
    }

    /**
     * 生成wml格式的字符串
     * @param type 图幅元素类型
     * @param geometrys 图幅集合
     * @return 字符串
     * @throws Exception
     */
    public static String write2WmlStr(String type, List geometrys) throws Exception {
        ByteArrayOutputStream os = write2WmlStream(type, geometrys);
        String out = os.toString().replaceAll("kml:", "");
        return out;
    }

    /**
     * 生成wml格式的字符串
     * @param type 图幅元素类型
     * @param geoKey data中图幅的key
     * @param attrKeys 属性key集合
     * @param geomList 图幅和属性集合
     * @return 字符串
     * @throws Exception
     */
    public static String write2WmlStr(String type, String geoKey, List attrKeys, List> geomList) throws Exception {
        ByteArrayOutputStream os = write2WmlStream(type, geoKey, attrKeys, geomList);
        String out = os.toString().replaceAll("kml:", "");
        return out;
    }

    /**
     * 生成wml格式的字节流
     * @param type 图幅元素类型
     * @param geometrys 图幅元素集合
     * @return 字节流
     * @throws Exception
     */
    public static ByteArrayOutputStream write2WmlStream(String type, List geometrys) throws Exception {
        SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
        tb.setCRS(DefaultGeographicCRS.WGS84);
        tb.setName("kmlfile");
        if ("Polygon".equals(type)) {
            tb.add("the_geom", Polygon.class);
        } else if ("MultiPolygon".equals(type)) {
            tb.add("the_geom", MultiPolygon.class);
        } else if ("Point".equals(type)) {
            tb.add("the_geom", Point.class);
        } else if ("MultiPoint".equals(type)) {
            tb.add("the_geom", MultiPoint.class);
        } else if ("LineString".equals(type)) {
            tb.add("the_geom", LineString.class);
        } else if ("MultiLineString".equals(type)) {
            tb.add("the_geom", MultiLineString.class);
        } else {
            throw new Exception("Geometry中没有该类型:" + type);
        }
        List features = new ArrayList<>();
        for (Geometry geometry : geometrys) {

            SimpleFeatureBuilder sfb = new SimpleFeatureBuilder(tb.buildFeatureType());
            sfb.add(geometry);
            //构建要素
            SimpleFeature feature = sfb.buildFeature(null);

            features.add(feature);
        }

        SimpleFeatureCollection fc = DataUtilities.collection(features);
        Encoder encoder = new Encoder(new KMLConfiguration());
        //设置编码
        Charset charset = Charset.forName("utf-8");
        encoder.setEncoding(charset);
        encoder.setIndenting(true);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        encoder.encode(fc, KML.kml, os);
        return os;
    }

    /**
     * 生成wml格式的字节流
     * @param type 图幅元素类型
     * @param geoKey data中图幅的key
     * @param attrKeys 属性key集合
     * @param geomList 图幅和属性集合
     * @return 字节流
     * @throws Exception
     */
    public static ByteArrayOutputStream write2WmlStream(String type, String geoKey, List attrKeys, List> geomList) throws Exception {
        SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
        tb.setCRS(DefaultGeographicCRS.WGS84);
        tb.setName("kmlfile");
        if ("Polygon".equals(type)) {
            tb.add("the_geom", Polygon.class);
        } else if ("MultiPolygon".equals(type)) {
            tb.add("the_geom", MultiPolygon.class);
        } else if ("Point".equals(type)) {
            tb.add("the_geom", Point.class);
        } else if ("MultiPoint".equals(type)) {
            tb.add("the_geom", MultiPoint.class);
        } else if ("LineString".equals(type)) {
            tb.add("the_geom", LineString.class);
        } else if ("MultiLineString".equals(type)) {
            tb.add("the_geom", MultiLineString.class);
        } else {
            throw new Exception("Geometry中没有该类型:" + type);
        }
             
        //设置用户属性参数
        for (String key : attrKeys) {
            tb.add(key, String.class);
        }

        List features = new ArrayList<>();
        for (Map obj : geomList) {
            Object geoObj = obj.get(geoKey);
            if (geoObj instanceof Geometry) {
                Geometry geometry = (Geometry) geoObj;
                SimpleFeatureBuilder sfb = new SimpleFeatureBuilder(tb.buildFeatureType());
                sfb.add(geometry);
                //构建要素
                SimpleFeature feature = sfb.buildFeature(null);

                for (String key : obj.keySet()) {
                    if (!key.equals(geoKey)) {
                        feature.setAttribute(key, obj.get(key).toString());
                    }
                }
                features.add(feature);
            } else {
                throw new Exception("图幅元素集合中为geoKey:" + geoKey + "的图幅元素类型必须是Geometry");
            }
        }

        SimpleFeatureCollection fc = DataUtilities.collection(features);
        Encoder encoder = new Encoder(new KMLConfiguration());
        //设置编码
        Charset charset = Charset.forName("utf-8");
        encoder.setEncoding(charset);
        encoder.setIndenting(true);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        encoder.encode(fc, KML.kml, os);
        return os;
    }

}

3、测试

public class TestMain {

    public static void main(String[] args) throws Exception {
        List 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 geometryList = new ArrayList<>();
        for (String str : list) {
            WKTReader reader = new WKTReader();
            geometryList.add(reader.read(wkt));
        }
        List attrKeys = new ArrayList<>();
        attrKeys.add("ceshi1");
        attrKeys.add("ceshi2");
        attrKeys.add("ceshi3");

        int i = 1;
        List> geomList = new ArrayList<>();
        for (String str : list) {
            Map map = new HashMap<>();
            map.put("geoKey", WKTUtil.wktToGeom(str));
            map.put("ceshi1", "测试" + i++);
            map.put("ceshi2", "测试" + i++);
            map.put("ceshi3", "测试" + i++);
            geomList.add(map);
        }

        String path1 = "D:\\data\\tmp\\测试1.kml";
        String path2 = "D:\\data\\tmp\\测试2.kml";
        KmlUtil.write2Wml(path1, "Polygon", geometryList);
        KmlUtil.write2Wml(path2, "Polygon", "geoKey", attrKeys, geomList)
        //System.out.println(str);
    }
}

4、测试结果(测试1.kml和测试2.kml)

// 测试1.kml ************************************

  
    
      
        
          
            113.38185597038,34.54828048706 113.38224220848,34.548355588913 113.38249970055,34.548108825684 113.38237095451,34.54787279129 113.38208127594,34.547786960602 113.38185597038,34.54828048706
          
        
      
    
    
      
        
          
            116.21278950384274,39.90557982319698 116.21177234433465,39.90610963061354 116.21106912279264,39.90264172209895 116.21399502548638,39.902612822554126 116.21629305278306,39.905011479365406 116.21278950384274,39.90557982319698
          
        
      
    
  



// 测试2.kml ************************************

  
    
      
        
          测试4
        
        
          测试5
        
        
          测试6
        
      
      
        
          
            113.38185597038,34.54828048706 113.38224220848,34.548355588913 113.38249970055,34.548108825684 113.38237095451,34.54787279129 113.38208127594,34.547786960602 113.38185597038,34.54828048706
          
        
      
    
    
      
        
          测试1
        
        
          测试2
        
        
          测试3
        
      
      
        
          
            116.21278950384274,39.90557982319698 116.21177234433465,39.90610963061354 116.21106912279264,39.90264172209895 116.21399502548638,39.902612822554126 116.21629305278306,39.905011479365406 116.21278950384274,39.90557982319698
          
        
      
    
  


参考博文:

        GeoJSON to KML conversion: https://gis.stackexchange.com/questions/310989/geojson-to-kml-conversion

你可能感兴趣的:(GIS开发)