package cn.edu.whu.boot.common.utils.collection;

import cn.edu.whu.boot.collection.dto.GeometryType;
import cn.edu.whu.boot.common.domain.CommonConstant;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ArcGIS 的 shape 格式与标准 GeoJson 格式相互转换的工具类
 */
public class ShapeTypeUtil{

    /**
     * 将安卓端传来的 String Shape 转成标准的 GeoJson 的 GeometryString
     */
    public static String changeArcGISToGeometry(String arcGISString){
        GeometryType geometryType = new GeometryType();
        JSONObject shapeJson = JSON.parseObject(arcGISString);
        // 这里不能以shape字段以什么为开头来判断是点、线、面，应该获取shape里面的key关键字来进行判断
        if(shapeJson.containsKey(CommonConstant.X)){
            List<Double> coordinateList = new ArrayList<>();
            coordinateList.add(shapeJson.getDouble(CommonConstant.X));
            coordinateList.add(shapeJson.getDouble(CommonConstant.Y));
            geometryType.setType(CommonConstant.POINT);
            geometryType.setCoordinates(coordinateList);
        }
        else if(shapeJson.containsKey(CommonConstant.PATHS)){
            List<List<Double>> pathList = ((List<List<List<Double>>>) shapeJson.get(CommonConstant.PATHS)).get(0);
            geometryType.setType(CommonConstant.LINESTRING);
            geometryType.setCoordinates(pathList);
        }
        else if(shapeJson.containsKey(CommonConstant.RINGS)){
            List<List<List<Double>>> rinsList = (List<List<List<Double>>>) shapeJson.get(CommonConstant.RINGS);
            geometryType.setType(CommonConstant.POLYGON);
            geometryType.setCoordinates(rinsList);
        }
        else if(shapeJson.containsKey("xmin")){
            double xmin = shapeJson.getDouble("xmin");
            double xmax = shapeJson.getDouble("xmax");
            double ymin = shapeJson.getDouble("ymin");
            double ymax = shapeJson.getDouble("ymax");
            List<List<List<Double>>> coordinates = new ArrayList<>();
            List<List<Double>> firstRing = new ArrayList<>();

            List<Double> point = new ArrayList<>();
            point.add(xmin);
            point.add(ymin);
            firstRing.add(point);

            List<Double> point2 = new ArrayList<>();
            point2.add(xmin);
            point2.add(ymax);
            firstRing.add(point2);

            List<Double> point3 = new ArrayList<>();
            point3.add(xmax);
            point3.add(ymax);
            firstRing.add(point3);

            List<Double> point4 = new ArrayList<>();
            point4.add(xmax);
            point4.add(ymin);
            firstRing.add(point4);
            firstRing.add(point);

            coordinates.add(firstRing);
            geometryType.setType(CommonConstant.POLYGON);
            geometryType.setCoordinates(coordinates);
        }
        return JSON.toJSONString(geometryType, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 将标准的 GeoJson 的 GeometryString 转成 String Shape，以便返回给安卓端使用
     */
    public static String changeGeometryToArcGIS(String geometryString){
        GeometryType geometryType = JSON.toJavaObject(JSON.parseObject(geometryString), GeometryType.class);
        String type = geometryType.getType();
        Map<String, Object> result = new HashMap<>();
        switch(type){
            case CommonConstant.POINT:
                List<Double> coordinateList = (List<Double>) geometryType.getCoordinates();
                result.put(CommonConstant.X, coordinateList.get(0));
                result.put(CommonConstant.Y, coordinateList.get(1));
                break;
            case CommonConstant.LINESTRING:
                List<List<List<Double>>> pathList = new ArrayList<>();
                pathList.add((List<List<Double>>) geometryType.getCoordinates());
                result.put(CommonConstant.PATHS, pathList);
                break;
            case CommonConstant.MULTIPOLYGON:
                List<List<List<List<Double>>>> rinsList = (List<List<List<List<Double>>>>) geometryType.getCoordinates();
                result.put(CommonConstant.RINGS, rinsList.get(0));
                break;
            case CommonConstant.POLYGON:
                List<List<List<Double>>> rinsList2 = (List<List<List<Double>>>) geometryType.getCoordinates();
                result.put(CommonConstant.RINGS, rinsList2);
            default:
                break;
        }
        result.put(CommonConstant.SPATIAL_REFERENCE, CommonConstant.SPATIAL_REFERENCE_VALUE);
        return JSON.toJSONString(result);
    }
}
