package com.sysu.admin.utils.shape;

import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.sysu.admin.utils.shape.vo.Param;
import com.sysu.admin.utils.shape.vo.ParamType;
import org.apache.commons.lang3.StringUtils;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.FeatureSource;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.filter.text.cql2.CQL;
import org.geotools.filter.text.cql2.CQLException;
import org.geotools.geojson.feature.FeatureJSON;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.operation.overlay.snap.SnapOverlayOp;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.Filter;

/**
 * 采用geotools中公共查询语言
 * 过滤条件如下
 *
 * 例如：
 *    PERSONS > 15000000
 *    PERSONS BETWEEN 1000000 AND 3000000
 *    STATE_NAME LIKE 'N%'
 *    STATE_NAME = 'California'
 *    MALE > FEMALE
 *    UNEMPLOY / (EMPLOYED + UNEMPLOY) > 0.07
 *     IN ('states.1', 'states.12'):
 *   STATE_NAME IN ('New York', 'California', 'Montana', 'Texas'):
 *  带函数的使用：
 *     strToLowerCase(STATE_NAME) like ‘%m%’
 *
 * @Title:
 * @Description: 实现TODO
 * @Copyright:Copyright (c) 2011
 * @Company:
 * @Date:2012-9-10
 * @author  longgangbai
 * @version 1.0
 */
public class GeoServerCQLECQL {
    /**
     * 查询元素
     * @param filterStr
     * @param layerName
     * @return
     */
    public static ArrayList<SimpleFeature> queryMethod(String url, String filterStr, String layerName) throws IOException {

        Map<String, String> connectionParameters = new HashMap<String, String>();
        connectionParameters.put("WFSDataStoreFactory:GET_CAPABILITIES_URL",   url.toLowerCase());
        // Step 2 - connection
        DataStore data = DataStoreFinder.getDataStore(connectionParameters);
        FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = data.getFeatureSource(layerName);
        ArrayList<SimpleFeature> featureList = new ArrayList<SimpleFeature>();
        FeatureCollection<SimpleFeatureType, SimpleFeature> result = null;
        if (featureSource == null)
            return featureList;
        try {
            if(StringUtils.isEmpty(filterStr)){
                result = featureSource.getFeatures();
            }else {
                Filter filter = CQL.toFilter(filterStr); // filterStr形式 如  name='武汉大学' or code like 'tt123%'
                result = featureSource.getFeatures(filter);
            }

//            ReferencedEnvelope bounds = new ReferencedEnvelope();
            FeatureIterator<SimpleFeature> iterator = result.features();
            while (iterator.hasNext()) {
                SimpleFeature feature = iterator.next();
//                bounds.include(feature.getBounds());
                featureList.add(feature);
            }
//            System.out.println("Calculated Bounds:" + bounds);
            iterator.close();
            return featureList;
        } catch (CQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
        }
        return null;
    }



    public static String featureToGeoJson(SimpleFeature simpleFeature){
        FeatureJSON fjson = new FeatureJSON();
        SimpleFeature feature = simpleFeature;
        StringWriter writer = new StringWriter();
        try {
            fjson.writeFeature(feature, writer);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return writer.toString();
    }

    public static String coordinate2WktPolygon(Coordinate[] s){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("POLYGON ((");
        stringBuffer.append(s[0].getX()).append(" ").append(s[0].getY());

        double preX=s[0].getX(), preY=s[0].getY();
        for(int i=1;i<s.length;i++){
            if(Double.compare(preX, s[i].getX()) == 0 && Double.compare(preY, s[i].getY()) == 0){
                continue;
            }

            stringBuffer.append(",").append(s[i].getX()).append(" ").append(s[i].getY());
            preX = s[i].getX();
            preY = s[i].getY();
        }
        stringBuffer.append("))");
        return stringBuffer.toString();
    }




    public static void main(String[] args) throws IOException {





//        FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
//        //边框查询
//        double[] b= {114.25438, 30.57838, 114.27532, 30.59795};
//        BBOX bbox = ff.bbox("the_geom",b[1],b[0],b[3],b[2],"EPSG:4326");
        String url = "http://localhost:8080/geoserver/wuhan/wfs";

        //多边形相交查询
        //查询顶点
        ArrayList<SimpleFeature> list = queryMethod(url,"","wuhan:test3");
//        for(SimpleFeature s : list){
//            System.out.println(s.getProperties("locname").iterator().next().getValue());
//        }

        Geometry geometry = (Geometry) list.get(0).getDefaultGeometry();
        String POLYGON = coordinate2WktPolygon(geometry.getCoordinates());

        StringBuffer filter = new StringBuffer(POLYGON.length() + 30);
        filter.append("RELATE(the_geom,").append(POLYGON).append(",T********)");
        System.out.println(filter.toString());
        list = queryMethod(url, filter.toString(),
                "wuhan:whxzqh");
        //交叉数组
        ArrayList<Geometry> intersections = new ArrayList<>(list.size());
        List<Param> paramList = new ArrayList<>();
        String[] names = {"locname","area"};//属性名
        Class[] types = {String.class, Double.class};//属性类型
        for(SimpleFeature s : list){
            System.out.println(featureToGeoJson(s));
            Object locname = s.getProperties("locname").iterator().next().getValue();
            System.out.println(locname);
            Geometry intersection =  SnapOverlayOp.intersection(geometry.intersection(geometry),(Geometry)s.getDefaultGeometry());
            if(!intersection.isEmpty()) {
                intersections.add(intersection);
                Object[] vals = {locname, intersection.getArea()};
                paramList.add(new Param(names,vals));
            }
        }
        ParamType[] paramTypes = ParamType.build(names,types);
        FileFormat.toShp(intersections,"E:\\zcjy\\intersections.shp", paramTypes, paramList);


    }
}