package com.sysu.admin.utils.shape;

import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.WKTReader2;
import org.geotools.geometry.jts.WKTWriter2;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.io.ParseException;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;

import java.io.IOException;
import java.io.StringReader;
import java.math.BigDecimal;
import java.text.DecimalFormat;

public class GeoCastUtil {
    public static GeometryJSON gjson = new GeometryJSON(20);
    private static WKTWriter2 wKTWriter2 = new WKTWriter2();
    private static WKTReader2 wktReader2 = new WKTReader2();

    public static String geomToWkt(Geometry geometry){
        return wKTWriter2.write(geometry);
    }

    public static Geometry wktToGeom(String wkt){
        try {
            return wktReader2.read(wkt);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static GeometryCollection castGeometryCollection2(GeometryJSON fjson, GeometryCollection geometryCollection) throws IOException {
        if (geometryCollection.getGeometryType().equals("GeometryCollection")) {
            return geometryCollection;
        }
        String[] geometriesJsonArray = new String[geometryCollection.getNumGeometries()];
        int length = 0;
        for(int i=0; i< geometryCollection.getNumGeometries(); i++){
            Geometry geometry = geometryCollection.getGeometryN(i);
            geometriesJsonArray[i] = fjson.toString(geometry);
            length += geometriesJsonArray[i].length();
        }
        StringBuffer result = new StringBuffer(length + 100);
        result.append("{\"type\": \"GeometryCollection\",\"geometries\": [");
        result.append(geometriesJsonArray[0]);
        for(int i=1;i< geometriesJsonArray.length;i++){
            result.append(",").append(geometriesJsonArray[i]);
        }
        result.append("]}");
        return fjson.readGeometryCollection(new StringReader(result.toString()));
    }

    public static GeometryCollection castGeometryCollection(GeometryJSON fjson, Geometry geometry) throws IOException {
        if (geometry.getGeometryType().equals("GeometryCollection")) {
            return (GeometryCollection)geometry;
        }
        if (geometry instanceof GeometryCollection) {
            return castGeometryCollection2(fjson, (GeometryCollection)geometry);
        }
        String geometryJson = fjson.toString(geometry);
        StringBuffer result = new StringBuffer(geometryJson.length() + 100);
        result.append("{\"type\": \"GeometryCollection\",\"geometries\": [");
        result.append(geometryJson);
        result.append("]}");
        return fjson.readGeometryCollection(new StringReader(result.toString()));
    }

    public static Geometry readGeometry(Object input, String type, GeometryJSON gjson) throws IOException {
        switch(type){
            case "Point":
                return gjson.readPoint(input);
            case "MultiPoint":
                return gjson.readMultiPoint(input);
            case "LineString":
                return gjson.readLine(input);
            case "MultiLineString":
                return gjson.readMultiLine(input);
            case "Polygon":
                return gjson.readPolygon(input);
            case "MultiPolygon":
                return gjson.readMultiPolygon(input);
        }
        return null;
    }



    public static Double[] lonlatToMactor(Double[] point){
        CoordinateReferenceSystem crsTarget = null;
        // 投影转换
        MathTransform transform = null;
        try {
            crsTarget = CRS.decode("EPSG:3857");
            transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, crsTarget);
        } catch (FactoryException e) {
            e.printStackTrace();
        }
        Coordinate sourcePoint = new Coordinate(point[0],point[1]);
        Coordinate targetPoint = new Coordinate();
        try {
            JTS.transform(sourcePoint, targetPoint, transform);
        } catch (TransformException e) {
            e.printStackTrace();
        }
        return new Double[]{targetPoint.getX(), targetPoint.getY()};
    }

    public static Double[] mactorToLonlat(Double[] point){
        CoordinateReferenceSystem srcTarget = null;
        // 投影转换
        MathTransform transform = null;
        try {
            srcTarget = CRS.decode("EPSG:3857");
            transform = CRS.findMathTransform(srcTarget, DefaultGeographicCRS.WGS84);
        } catch (FactoryException e) {
            e.printStackTrace();
        }
        Coordinate sourcePoint = new Coordinate(point[0],point[1]);
        Coordinate targetPoint = new Coordinate();
        try {
            JTS.transform(sourcePoint, targetPoint, transform);
        } catch (TransformException e) {
            e.printStackTrace();
        }
        return new Double[]{targetPoint.getX(),targetPoint.getY()};
    }

//    public static double toFlex(double d){
//        BigDecimal bd = new BigDecimal(d);
//        String s = bd.toPlainString();
//        int index = s.indexOf(".");
//        String last = s.substring(index + 1);
//        if(last.length() > 4){
//            last = last.substring(0,4);
//        }
//        return Double.parseDouble(s.substring(0,index + 1) + last);
//    }

    public static void main(String[] args) {
        Double[] res = lonlatToMactor(new Double[]{113.348406,23.166332});
        System.out.println(res[0] + " " + res[1] );
    }


}
