package com.persagy.server.util

import cn.hutool.core.collection.CollUtil
import com.fasterxml.jackson.databind.node.ObjectNode
import com.persagy.server.datacenter.models.entities.assistant.PointPosition
import org.geotools.geometry.jts.JTSFactoryFinder
import org.locationtech.jts.geom.Coordinate
import org.locationtech.jts.geom.LinearRing
import org.locationtech.jts.geom.Point
import org.locationtech.jts.geom.Polygon

/**
 * @ClassName GeoToolsUtil
 * @Description: 点面包含关系分析
 * @Author linhuili
 * @Date 2021/9/3 20:31
 * @Version V1.0
 */
object GeoToolsUtil {
    /**
     * 创建点
     * @param pointLocal
     */
    private fun createPoint(pointLocal: ObjectNode): Point {
        var x = 0.0
        var y = 0.0
        val z = 0.0
        if (pointLocal["X"] != null) {
            x = pointLocal["X"].asDouble()
        }
        if (pointLocal["Y"] != null) {
            y = pointLocal["Y"].asDouble()
        }
        val geometryFactory = JTSFactoryFinder.getGeometryFactory()
        val coord = Coordinate(x, y, z)
        return geometryFactory.createPoint(coord)
    }

    /**
     * 创建面
     * @param outLines
     */
    private fun createPolygon(outLines: ArrayList<ArrayList<PointPosition>>?): Polygon {
        val pointPositions = outLines?.get(0)
        val geometryFactory = JTSFactoryFinder.getGeometryFactory()
        val objects: MutableList<Coordinate> = ArrayList()
        for (outLine in pointPositions!!) {
            var x = 0.0
            if(outLine.x != null){
                x = outLine.x!!
            }
            var y = 0.0
            if(outLine.y != null){
                y = outLine.y!!
            }

            var z = 0.0
            if(outLine.z!= null){
                z = outLine.z!!
            }
            val coordinate = Coordinate(x, y, z)
            objects.add(coordinate)


        }
        //注意数据的闭合
        val coordinates = objects.toTypedArray()
        val ring = geometryFactory.createLinearRing(coordinates)
        val holes: Array<LinearRing>? = null
        return geometryFactory.createPolygon(ring, holes)
    }

    /**
     * 点面包含关系判断
     * 用途：判断一个面是否包含一个点，即一个点是否在一个面内
     * @param pointLocal 坐标点
     * @param outLines 轮廓线
     * @return
     */
    fun isPointInPoly(pointLocal: ObjectNode?, outLines: ArrayList<ArrayList<PointPosition>>?): Boolean {
        if (null == pointLocal || CollUtil.isEmpty(outLines)) {
            return false
        }
        //创建点
        val point = createPoint(pointLocal)
        //创建面
        val polygon = createPolygon(outLines)
        //判断点面包含关系
        return polygon.contains(point)
    }

}