# coding=utf-8
#author:        4N
#createtime:    2022/3/8
#email:         nheweijun@sina.com


from osgeo import ogr
from osgeo.ogr import *
import math
import os
import copy
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"

from test.zonghe.ShapeData import ShapeData
from test.zonghe.ConcaveHull import concaveHull
import numpy as np

class Zonghe:

    data:ShapeData
    area_threshold = 100.0
    buffer_threshold = 100.0
    distance_buffer_threshold = 2.114691025217302e-04

    def __init__(self,data):
        self.data = data


    def creat_point(self,tuple):
        p: Geometry = ogr.Geometry(ogr.wkbPoint)
        p.AddPoint(tuple[0], tuple[1])
        return p



    def merge2(self,p1,p2):

        polygons = []
        points = []

        for p in [p1,p2]:

            if p.GetGeometryCount() == 1:
                polygon_line: Geometry = ogr.ForceToLineString(p)
            # 有孔Polygon
            else:
                polygon_line: Geometry = ogr.ForceToLineString(p.GetGeometryRef(0))

            points.extend(polygon_line.GetPoints()[:-1])

        multipoint: Geometry = ogr.Geometry(ogr.wkbMultiPoint)


        for p in  points:
            poi = ogr.Geometry(ogr.wkbPoint)
            poi.AddPoint(p[0],p[1])
            multipoint.AddGeometry(poi)

        delauney: Geometry = multipoint.DelaunayTriangulation()
        merge_polygon = None

        for p in delauney:

            p_c = p.Centroid()

            # print("\"" + p_c.ExportToWkt() + "\",")
            if p1.Contains(p) or p2.Contains(p):
                continue
            print("\"" + p.ExportToWkt() + "\",")


        return polygons


    def merge(self,p1,p2):



        if p1.GetGeometryCount() == 1:
            polygon_line1: Geometry = ogr.ForceToLineString(p1)
        # 有孔Polygon
        else:
            polygon_line1: Geometry = ogr.ForceToLineString(p1.GetGeometryRef(0))


        p1_points =   polygon_line1.GetPoints()[:-1]

        if p2.GetGeometryCount() == 1:
            polygon_line2: Geometry = ogr.ForceToLineString(p2)
        # 有孔Polygon
        else:
            polygon_line2: Geometry = ogr.ForceToLineString(p2.GetGeometryRef(0))

        p2_points = polygon_line2.GetPoints()[:-1]


        multipoint: Geometry = ogr.Geometry(ogr.wkbMultiPoint)




        for p in p1_points:

            p_t = False
            for pp in p2_points:
                line = ogr.Geometry(ogr.wkbLineString)
                line.AddPoint(p[0], p[1])
                line.AddPoint(pp[0], pp[1])

                ggg:Geometry = line.Intersection(p1)


                if ggg.GetGeometryType() in [1,-2147483647,3001]:
                    p_t = True
                    break
            if p_t:
                pppp = ogr.Geometry(ogr.wkbPoint)
                pppp.AddPoint(p[0],p[1])

                multipoint.AddGeometry(pppp)

        for p in p2_points:

            p_t = False
            for pp in p1_points:
                line = ogr.Geometry(ogr.wkbLineString)
                line.AddPoint(p[0], p[1])
                line.AddPoint(pp[0], pp[1])

                ggg:Geometry = line.Intersection(p2)


                if ggg.GetGeometryType() in [1,-2147483647,3001]:
                    p_t = True
                    break
            if p_t:
                pppp = ogr.Geometry(ogr.wkbPoint)
                pppp.AddPoint(p[0],p[1])
                multipoint.AddGeometry(pppp)


        delauney: Geometry = multipoint.DelaunayTriangulation()
        merge_polygon = None

        for p in delauney:

            print("\"" + p.ExportToWkt() + "\",")



        return None

    def merge3(self,polygons):

        multi_poly = ogr.Geometry(ogr.wkbMultiPolygon)

        points = []
        for poly in polygons:
            multi_poly.AddGeometry(poly)
            if poly.GetGeometryCount() == 1:
                poly_line: Geometry = ogr.ForceToLineString(poly)
            # 有孔Polygon
            else:
                poly_line: Geometry = ogr.ForceToLineString(poly.GetGeometryRef(0))

            points.extend(poly_line.GetPoints()[:-1])


        points = np.array([[p[0],p[1]] for p in points])

        merge_p_line = concaveHull(points, 3)

        ring = ogr.Geometry(ogr.wkbLinearRing)

        merge_p = ogr.Geometry(ogr.wkbPolygon)


        for l in merge_p_line:
            ring.AddPoint(l[0], l[1])

        ring.AddPoint(merge_p_line[0][0], merge_p_line[0][1])

        merge_p.AddGeometry(ring)


        # for p in polygons:
        #
        #     merge_p = merge_p.Union(p)
        #
        #
        #
        # print(merge_p)

        return [merge_p.ExportToWkt()]




    def merge4(self,p1,p2):

        polygons = []
        points = []

        mp: Geometry = ogr.Geometry(ogr.wkbMultiPolygon)
        mp.AddGeometry(p1)
        mp.AddGeometry(p2)


        delauney: Geometry = mp.DelaunayTriangulation(bOnlyEdges=True)
        merge_polygon = None

        for p in delauney:

            p_c = p.Centroid()

            # print("\"" + p_c.ExportToWkt() + "\",")
            # if p1.Contains(p) or p2.Contains(p):
            #     continue
            print("\"" + p.ExportToWkt() + "\",")


        return polygons

    def merge5(self,p1:Geometry,p2):



        ext = p1.GetEnvelope()

        tor = min(ext[1]-ext[0],ext[3]-ext[2])

        pp = p1.Simplify(tor/20)

        pp2 = p2.Simplify(tor / 20)

        return [pp.ExportToWkt(),pp2.ExportToWkt() ]


    def process(self):
        polygons = self.data.get_polygons()

        return self.merge3(polygons)


if __name__ == '__main__':


    # print(sd.get_polygons()[0])
    # sd.close()

    # create = True
    # create = False
    #
    # if create:
    #
    #     sd = ShapeData(r"J:\Data\制图综合\me.shp")
    #
    #     ext =  sd.layer.GetExtent()
    #     threshold = (ext[1]-ext[0])/20
    #     print(threshold)
    #
    #
    #     zh = Zonghe(sd)
    #     zh.process()
    # else:
    #     wkts = ["POLYGON ((113.371086251 22.5101043861001,113.371311338 22.5099257505,113.371611445 22.5098560668001,113.371450698 22.5095291511,113.370775465 22.5096884259,113.371086251 22.5101043861001))"
    #             ]
    #     result = r"J:\Data\制图综合\mes.shp"
    #     ShapeData.create_shp_fromwkts(result,"zh",wkts)
    #


    sd = ShapeData(r"J:\Data\制图综合\concave.shp")

    ext =  sd.layer.GetExtent()
    threshold = (ext[1]-ext[0])/20
    print(threshold)


    zh = Zonghe(sd)
    wkts = zh.process()


    result = r"J:\Data\制图综合\concave_merge.shp"
    ShapeData.create_shp_fromwkts(result,"zh",wkts)