package com.sysu.admin.controller.analyse;

import com.sysu.admin.support.base.ServiceContext;
import com.sysu.admin.utils.shape.DataTypeConvert;
import com.sysu.admin.utils.shape.GeoServerCQLECQL;
import com.sysu.admin.utils.shape.postgis.PostGisUtil;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.operation.overlay.snap.SnapOverlayOp;
import org.opengis.feature.simple.SimpleFeature;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author shu hao
 * @description:
 * @date 2022/5/23 15:51
 */
@Service
public class CropAnalyseService extends ServiceContext implements AnalyseService{
    @Override
    public AnalyseTable analyse(String wkt) throws IOException, SQLException {
        DecimalFormat df = new DecimalFormat("######0.00");
        Geometry geometry = DataTypeConvert.wkt2Geometry(wkt);

        Double sumArea = DataTypeConvert.getArea(geometry);
        if(sumArea.intValue() > 1000000){
            throw new RuntimeException("耕地分析面积不能超过100万亩");
        }
        PostGisUtil postGisUtil = new PostGisUtil();
        postGisUtil.connPostGis();
        postGisUtil.openConnection();

        //查询出与测量面积相交的区域
        StringBuffer filter = new StringBuffer(500);
        filter.append(" FROM \"qingyuan_crop_2_cast\"  WHERE ST_Relate(geom,'")
                .append(wkt )
                .append("','T********') = true");
        System.out.println("长度："+filter.length());

        List<AnalyseRow> analyseResults = new ArrayList<>();
        SimpleFeatureTypeBuilder simpleFeatureTypeBuilder = new SimpleFeatureTypeBuilder();
        simpleFeatureTypeBuilder.add("objectid", Integer.class);
        simpleFeatureTypeBuilder.add("the_geom", MultiPolygon.class);
        simpleFeatureTypeBuilder.setName("temp");
        simpleFeatureTypeBuilder.setCRS(DefaultGeographicCRS.WGS84);
        SimpleFeatureBuilder simpleFeatureBuilder = new SimpleFeatureBuilder(simpleFeatureTypeBuilder.buildFeatureType());
        //耕地的数据
        List<SimpleFeature> cropFeatureList = null;
        GeometryCollection cropGeometry = null;
        {
            try {
                cropFeatureList = postGisUtil.queryMethod(filter.toString(), null, "qingyuan_crop_2_cast", true);
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                postGisUtil.closeConnection();
                postGisUtil.dispose();
            }
            List<Geometry> geometries = new ArrayList<>(cropFeatureList.size());

            //合并查询到的耕地
            for (SimpleFeature feature : cropFeatureList) {
                Geometry temp = (Geometry) feature.getDefaultGeometry();
                try {
                    temp = SnapOverlayOp.intersection(geometry, temp);
                }catch (TopologyException e){
                    temp = SnapOverlayOp.intersection(geometry, temp.intersection(temp));
                }
                if(temp == null)
                    continue;
                geometries.add(temp);
            }
            if(geometries.size() > 0) {
                GeometryFactory geometryFactory = new GeometryFactory();
                cropGeometry = new GeometryCollection(geometries.toArray(new Geometry[0]), geometryFactory);
                Map<String, Object> map = new HashMap();
                SimpleFeature simpleFeature = simpleFeatureBuilder.buildFeature("1", new Object[]{1});
                simpleFeature.setDefaultGeometry(cropGeometry);
                map.put("name", "耕地");
                map.put("objectid", 1);
                Double area = DataTypeConvert.getArea(cropGeometry);
                map.put("area", df.format(area));
                map.put("percent", df.format(area / sumArea * 100));
                String json = GeoServerCQLECQL.featureToGeoJson(simpleFeature);
                analyseResults.add(new AnalyseRow(json, map));
            }
        }
        //其他的数据
        Geometry ohterGeometry =  SnapOverlayOp.difference(geometry, cropGeometry);
        SimpleFeature simpleFeature = simpleFeatureBuilder.buildFeature("2", new Object[]{2});
        simpleFeature.setDefaultGeometry(ohterGeometry);
        Map<String, Object> map = new HashMap();
        map.put("name", "其他");
        map.put("objectid", 2);
        Double area = DataTypeConvert.getArea(ohterGeometry);
        map.put("area", df.format(area));
        map.put("percent", df.format(area / sumArea * 100));
        String json = GeoServerCQLECQL.featureToGeoJson(simpleFeature);
        analyseResults.add(new AnalyseRow(json, map));
        return new AnalyseTable(analyseResults, Double.parseDouble(df.format(sumArea)));
    }
}
