package com.sysu.admin.utils.shape;

import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sysu.admin.utils.shape.vo.Param;
import com.sysu.admin.utils.shape.vo.ParamType;
import com.sysu.admin.utils.shape.vo.*;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.geotools.data.*;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.store.ContentFeatureCollection;
import org.geotools.data.store.ContentFeatureSource;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.jdbc.JDBCDataStore;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.locationtech.jts.geom.*;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.FactoryException;


public class FileFormat {




	/**
	 * geojson转换为shp文件
	 * @param jsonPath
	 * @param shpPath
	 * @return
	 */
	public static Map geojson2Shape(String jsonPath, String shpPath){
		Map map = new HashMap();
		GeometryJSON gjson = new GeometryJSON();
		try{
			String strJson = CommonMethod.getFileContent(jsonPath);
			JSONObject json = JSON.parseObject(strJson);
			JSONArray features = (JSONArray) json.get("features");
			JSONObject feature0 = JSON.parseObject(features.get(0).toString());
			System.out.println(feature0.toString());
			String strType = ((JSONObject)feature0.get("geometry")).getString("type").toString();

			Class<?> geoType = null;
			switch(strType){
				case "Point":
					geoType = Point.class;
				case "MultiPoint":
					geoType = MultiPoint.class;
				case "LineString":
					geoType = LineString.class;
				case "MultiLineString":
					geoType = MultiLineString.class;
				case "Polygon":
					geoType = Polygon.class;
				case "MultiPolygon":
					geoType = MultiPolygon.class;
			}
			//创建shape文件对象
			File file = new File(shpPath);
			Map<String, Serializable> params = new HashMap<String, Serializable>();
			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");
			tb.add("the_geom", geoType);
			tb.add("POIID", Long.class);
			ds.createSchema(tb.buildFeatureType());
			//设置编码
			Charset charset = Charset.forName("GBK");
			ds.setCharset(charset);
			//设置Writer
			FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.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();
				feature.setAttribute("the_geom",GeoCastUtil.readGeometry(reader, strType, gjson));
				feature.setAttribute("POIID",i);
				writer.write();
			}
			writer.close();
			ds.dispose();
			map.put("status", "success");
			map.put("message", shpPath);
		}
		catch(Exception e){
			map.put("status", "failure");
			map.put("message", e.getMessage());
			e.printStackTrace();
		}
		return map;
	}

	public static void toShp(List<Geometry> geometryList, String shpPath, ParamType[] paramTypes, List<Param> params) throws IOException {
		GeometryJSON fjson = new GeometryJSON();
		File file = new File(shpPath);
		Map<String, Serializable> map = new HashMap<String, Serializable>();
		map.put( ShapefileDataStoreFactory.URLP.key, file.toURI().toURL() );
		ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory().createNewDataStore(map);
		//定义图形信息和属性信息
		SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
		//设置坐标系
		//创建
		try {
			tb.setCRS(CRS.decode("EPSG:4326"));
		} catch (FactoryException e) {
			e.printStackTrace();
		}
		tb.setName("shapefile");
		tb.add("the_geom", MultiPolygon.class);
		for(ParamType paramType : paramTypes){
			tb.add(paramType.getName(), paramType.getType());
		}
		ds.createSchema(tb.buildFeatureType());
		//设置编码
		ds.setCharset(Charset.forName("GBK"));
		//设置Writer
		FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriterAppend(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);

		for(int i=0,len=geometryList.size();i<len;i++){
			Geometry geometry = geometryList.get(i);
			SimpleFeature feature = writer.next();
			feature.setAttribute("the_geom", GeoSwapXYUtil.swap(fjson, geometry));
			Param param = params.get(i);
			for(int j = 0;j < param.getNames().length;j++){
				feature.setAttribute(param.getNames()[j], param.getValues()[j]);
			}
			writer.write();
		}
		writer.close();
		ds.dispose();
	}

	public static void toShpPostGis(List<Geometry> geometryList, JDBCDataStore ds, ParamType[] paramTypes, List<Param> params) throws IOException {
		GeometryJSON fjson = new GeometryJSON();
		String typeName = "shapefile";

		if(!ds.hasSchema(typeName)) {
			//定义图形信息和属性信息
			SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
			//设置坐标系
			//创建
			tb.setCRS(DefaultGeographicCRS.WGS84);
			tb.setName(typeName);
			tb.add("the_geom", GeometryCollection.class);
			for (ParamType paramType : paramTypes) {
				tb.add(paramType.getName(), paramType.getType());
			}
			ds.createSchema(tb.buildFeatureType());
		}
		FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriterAppend(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);

		for(int i=0,len=geometryList.size();i<len;i++){
			Geometry geometry = geometryList.get(i);
			SimpleFeature feature = writer.next();
			feature.setAttribute("the_geom", GeoCastUtil.castGeometryCollection(fjson, geometry));
			Param param = params.get(i);
			for (int j = 0; j < param.getNames().length; j++) {
				feature.setAttribute(param.getNames()[j], param.getValues()[j]);
			}
			writer.write();
		}
		writer.close();
		ds.dispose();
	}


	/**
	 * shp转换为Geojson
	 * @param shpPath
	 * @return
	 */
	public static Map shape2Geojson(String shpPath, String jsonPath){
		Map map = new HashMap();
		FeatureJSON fjson = new FeatureJSON();
		try{
			StringBuffer sb = new StringBuffer();
			sb.append("{\"type\": \"FeatureCollection\",\"features\": ");
			File file = new File(shpPath);
			ShapefileDataStore shpDataStore = new ShapefileDataStore(file.toURL());
			FeatureIterator<SimpleFeature> itertor = getFeatures(shpDataStore);
			JSONArray array = new JSONArray();
			while (itertor.hasNext())
			{
				SimpleFeature feature = itertor.next();
				StringWriter writer = new StringWriter();
				fjson.writeFeature(feature, writer);
				JSONObject json = JSON.parseObject(writer.toString());
				array.add(json);
			}
			itertor.close();
			sb.append(array.toString());
			sb.append("}");
			//写入文件
			CommonMethod.append2File(jsonPath, sb.toString(), false);

			map.put("status", "success");
			map.put("message", sb.toString());
		}
		catch(Exception e){
			map.put("status", "failure");
			map.put("message", e.getMessage());
			e.printStackTrace();

		}
		return map;
	}

	public static FeatureIterator<SimpleFeature> getFeatures(ShapefileDataStore shpDataStore) throws IOException {
		//设置编码
		Charset charset = Charset.forName("GBK");
		shpDataStore.setCharset(charset);
		String typeName = shpDataStore.getTypeNames()[0];
		ContentFeatureSource featureSource = null;
		featureSource =  shpDataStore.getFeatureSource (typeName);
		ContentFeatureCollection result = featureSource.getFeatures();
		FeatureIterator<SimpleFeature> itertor = result.features();
		return itertor;
	}


	/**
	 * shp转换为Geojson
	 * @param shpPath
	 * @return
	 */
	public Map shape2GeoJsonList(String shpPath, String jsonPathDir, String numberPropertyName){
		Map map = new HashMap();
		FeatureJSON fjson = new FeatureJSON();
		try{
			File file = new File(shpPath);
			ShapefileDataStore shpDataStore = new ShapefileDataStore(file.toURL());
			FeatureIterator<SimpleFeature> itertor = getFeatures(shpDataStore);
			while (itertor.hasNext())
			{
				StringBuffer sb = new StringBuffer();
				sb.append("{\"type\": \"FeatureCollection\",\"features\": [");
				SimpleFeature feature = itertor.next();
				StringWriter writer = new StringWriter();
				fjson.writeFeature(feature, writer);
				JSONObject json = JSON.parseObject(writer.toString());
				sb.append(json.toJSONString());
				sb.append("]}");
				//写入文件
				String path = jsonPathDir + "\\" + getPinyin(file.getName().substring(0, 2)) + "_" + feature.getProperty(numberPropertyName).getValue()  + ".geojson";
				CommonMethod.append2File(path, sb.toString(), false);
			}
			itertor.close();


			map.put("status", "success");
		}
		catch(Exception e){
			map.put("status", "failure");
			e.printStackTrace();

		}
		return map;
	}



	/**
	 * @param china (字符串 汉字)
	 * @return 汉字转拼音 其它字符不变
	 */
	public static String getPinyin(String china){
		HanyuPinyinOutputFormat formart = new HanyuPinyinOutputFormat();
		formart.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		formart.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		formart.setVCharType(HanyuPinyinVCharType.WITH_V);
		char[] arrays = china.trim().toCharArray();
		String result = "";
		try {
			for (int i=0;i<arrays.length;i++) {
				char ti = arrays[i];
				if(Character.toString(ti).matches("[\\u4e00-\\u9fa5]")){ //匹配是否是中文
					String[] temp = PinyinHelper.toHanyuPinyinStringArray(ti,formart);
					result += temp[0];
				}else{
					result += ti;
				}
			}
		} catch (BadHanyuPinyinOutputFormatCombination e) {
			e.printStackTrace();
		}

		return result;
	}
	/**
	 * 工具类测试方法
	 * @param args
	 */
	public static void main(String[] args){
		no3();
	}


	public static void no3(){
		String shpPath = "C:\\Users\\Administrator\\Desktop\\改建\\";
		geojson2Shape(shpPath + "districts.geojson",shpPath + "districts.shp");
	}

	public static void no2(){
		geojson2Shape("E:\\zcjy\\intersections.geojson",
				"E:\\zcjy\\intersections.shp");
//		shape2Geojson("E:\\zcjy\\intersections.shp","E:\\zcjy\\intersections.geojson");
	}

	public static void no1(){
		FileFormat fileFormat = new FileFormat();
		long start = System.currentTimeMillis();
		String shpPath = "E:\\zcjy\\bhjc\\清远裸露山体\\采矿权数据.shp";
		String jsonPath = "E:\\zcjy\\workspace2\\change_det\\src\\main\\webapp\\geojson";
		fileFormat.shape2GeoJsonList(shpPath, jsonPath,"OBJECTID");

		shpPath = "E:\\zcjy\\bhjc\\清远裸露山体\\英德最终裸露山体地块8.11new.shp";
		fileFormat.shape2GeoJsonList(shpPath, jsonPath,"地块编号");

		shpPath = "E:\\zcjy\\bhjc\\清远裸露山体\\阳山最终裸露山体地块8.11new.shp";
		fileFormat.shape2GeoJsonList(shpPath, jsonPath,"地块编号");

		shpPath = "E:\\zcjy\\bhjc\\清远裸露山体\\清新最终裸露山体地块8.11new.shp";
		fileFormat.shape2GeoJsonList(shpPath, jsonPath,"地块编号");

		shpPath = "E:\\zcjy\\bhjc\\清远裸露山体\\清城最终裸露山体地块8.11new.shp";
		fileFormat.shape2GeoJsonList(shpPath, jsonPath,"地块编号");

		shpPath = "E:\\zcjy\\bhjc\\清远裸露山体\\连州最终裸露山体地块8.11new.shp";
		fileFormat.shape2GeoJsonList(shpPath, jsonPath,"地块编号");

		shpPath = "E:\\zcjy\\bhjc\\清远裸露山体\\连山最终裸露山体地块8.11new.shp";
		fileFormat.shape2GeoJsonList(shpPath, jsonPath,"地块编号");

		shpPath = "E:\\zcjy\\bhjc\\清远裸露山体\\连南最终裸露山体地块8.11new.shp";
		fileFormat.shape2GeoJsonList(shpPath, jsonPath,"地块编号");

		shpPath = "E:\\zcjy\\bhjc\\清远裸露山体\\佛冈最终裸露山体地块8.11new.shp";
		fileFormat.shape2GeoJsonList(shpPath, jsonPath,"地块编号");

		System.out.println(jsonPath+",共耗时"+(System.currentTimeMillis() - start)+"ms");
	}


}