# -*- coding: utf-8 -*-
import os
import sys
import log
import uuid
import appconfig
import arcpy
import datetime
import time
import utils
from arcpy import env
from db.postgresql import Postgresql

import importlib, sys

importlib.reload(sys)


class Fzxz:
    def __init__(self, data):
        self.bsm = data
        self.db = Postgresql(appconfig.DB_CONN)
        log.info(data)
        self.fxlog(self.bsm, "info", "开始进行选址分析")
        # 读任务
        self.task()
        # 选址GDB
        self.root = os.path.dirname(os.path.abspath(__file__))
        path = os.path.join(self.root, "out")
        self.tbxPath = os.path.abspath(os.path.join(self.root, "../tbxs"))
        if not os.path.exists(path):
            os.makedirs(path)
        self.outGdb = os.path.join(path, "{0}.gdb".format(data))
        arcpy.Delete_management(self.outGdb)
        arcpy.CreateFileGDB_management(path, "{0}.gdb".format(data))

        # 输出文件夹里面已经有内容的，就覆盖掉
        env.overwriteOutput = True
        # 设置工作空间
        env.workspace = appconfig.SDE["KJGH"]

    def task(self):
        '''加载数据-任务、因子'''
        sql = "SELECT a.BSM as \"BSM\",a.SJY as \"SJY\",a.YDXZ_BSM as \"YDXZ_BSM\",a.FWLX as \"FWLX\",a.XZFW as \"XZFW\",a.YDMJBEGIN as \"YDMJBEGIN\",a.YDMJEND as \"YDMJEND\",a.KDDK as \"KDDK\",a.ZDPD as \"ZDPD\",b.SJYMC as \"SJYMC\",b.DMZD as \"DMZD\",b.MCZD as \"MCZD\",b.FZBS as \"FZBS\",c.MC as \"MC\",b.XZQDMZD as \"XZQDMZD\",b.XZQMCZD as \"XZQMCZD\" FROM onemap.T_FZSS_FZXZ a INNER JOIN onemap.T_FZSS_FZXZ_SJY b ON a.SJY = b.BSM LEFT JOIN onemap.T_FZSS_FZXZ_DICT c ON b.FZBS = C.FZBS AND a.YDXZ_BSM = c.DM  where a.BSM='{0}'".format(
            self.bsm)
        tasks = self.db.query(sql)
        if len(tasks) == 0:
            self.fxlog(self.bsm, "error", "任务标识错误[{0}]".format(self.bsm))
            raise Exception("任务标识错误[{0}]".format(self.bsm))

        self.task = tasks[0]
        sql = "SELECT A.BSM as \"BSM\",A.RWBSM as \"RWBSM\",A.YZBSM as \"YZBSM\",A.YXYZMC as \"YXYZMC\",A.YZTJ as \"YZTJ\",A.YXZ as \"YXZ\",B.SJLX as \"SJLX\",B.SJY as \"SJY\",B.GLTJ as \"GLTJ\",B.FXJG_C as \"FXJG_C\",B.FXJG_N as \"FXJG_N\" FROM onemap.T_FZSS_FZXZ_XZYZ A LEFT JOIN onemap.T_FZSS_FZXZ_YZ B ON A.YZBSM = B.BSM WHERE A.RWBSM = '{0}'".format(
            self.bsm)
        self.xzyz = self.db.query(sql)

        yznames = ""
        for yz in self.xzyz:
            yznames = yznames + yz['YXYZMC'] + "、"
        logs = "选址参数：数据源={0}，用地性质={1}，用地面积={2}-{3}，影响因子={4}"
        logs = logs.format(self.task["SJYMC"],
                           self.task["MC"],
                           self.task["YDMJBEGIN"],
                           self.task["YDMJEND"],
                           yznames[:-1])
        self.fxlog(self.bsm, "info", logs)

    def run(self):
        # 1.范围导入
        # 设置工作空间
        self.xzfw = r"{0}\XZFW".format(self.outGdb)
        # 范围
        if self.task["FWLX"] == 0:
            arcpy.Select_analysis("KJGH.XZQXZ", self.xzfw, "XZQDM = '{0}'".format(self.task["XZFW"]))
            arcpy.AddField_management(self.xzfw, "RWBSM", "TEXT")
            with arcpy.da.UpdateCursor(self.xzfw, "RWBSM") as cursor:
                for row in cursor:
                    row[0] = self.bsm
                    cursor.updateRow(row)
        else:
            where = '"rwbsm"=\'{0}\''.format(self.bsm);
            arcpy.Select_analysis("KJGH.T_FZSS_FXRW_GIS", self.xzfw, where)
        self.fxlog(self.bsm, "info", "载入选址范围完成")

        # 2.相交数据源
        # env.workspace = appconfig.getSDE(self.task['SJY'])
        env.workspace = appconfig.getSDE("KJGH")
        self.sjy = r"{0}\SJY".format(self.outGdb)
        arcpy.Intersect_analysis([self.task['SJY'], self.xzfw], self.sjy)
        arcpy.ImportToolbox(os.path.join(self.tbxPath, "xzydyh.tbx"), "xzydyh")
        arcpy.fzxz_xzydyh(self.sjy)
        self.fxlog(self.bsm, "info", "相交裁剪数据源" + self.task['SJYMC'])

        # 3.条件过滤
        if self.task['YDXZ_BSM'] != '' and self.task['YDXZ_BSM'] != None:
            where = '"{0}" LIKE \'{1}%\''.format(self.task['DMZD'], self.task['YDXZ_BSM'])
            tjgl = r"{0}\TJGL".format(self.outGdb)
            arcpy.Select_analysis(self.sjy, tjgl, where)
            self.sjy = tjgl

        # 4.因子
        for yz in self.xzyz:
            sjlx = yz['SJLX'].lower()
            if sjlx == 'sde':
                self.yzfx(yz)
                self.fxlog(self.bsm, "info", "{0}因子影响分析完成".format(yz['YXYZMC']))
            # elif sjlx == 'geoserver':
            #   self.geoserver(yz)
            # elif sjlx == 'arcgisserver':
            #   self.arcgisserver(yz)
            else:
                self.fxlog(self.bsm, "error", "影响因子数据源错误[{0}]".format(yz['YXYZMC']))
                raise Exception("影响因子数据源错误[{0}]".format(yz['YXYZMC']))

        # 5.面积
        log.info("面积")
        mjField = "TBMJ"
        arcpy.AddField_management(self.sjy, mjField, "DOUBLE")
        arcpy.CalculateField_management(self.sjy, mjField, "!shape.area@SQUAREMETERS!", "PYTHON_9.3")
        mjWhere = ""
        bBegin = self.task['YDMJBEGIN'] != "" and self.task['YDMJBEGIN'] != None
        bEnd = self.task['YDMJEND'] != "" and self.task['YDMJEND'] != None

        # TODO 面积筛选字段配置 之前版本是MJ现替换成了mjField 计算后的面积
        if bBegin and bEnd:
            mjWhere = "TBMJ >= {0} and TBMJ <= {1} ".format(self.task['YDMJBEGIN'], self.task['YDMJEND'])
        elif bBegin:
            mjWhere = "TBMJ >= {0}".format(self.task['YDMJBEGIN'])
        elif bEnd:
            mjWhere = "TBMJ <= {0}".format(self.task['YDMJEND'])

        if mjWhere != "":
            out = r"{0}\YZ_MJ".format(self.outGdb)
            arcpy.Select_analysis(self.sjy, out, mjWhere)
            self.sjy = out
        self.fxlog(self.bsm, "info", "用地面积分析完成")

        # 6.入结果库
        attrs = ["objectid", "objectid_1", "shape", "shape_length", "shape_area", "rwbsm", "tbmj",
                 self.task['DMZD'].lower(), self.task['MCZD'].lower(), self.task['XZQDMZD'].lower(),
                 self.task['XZQMCZD'].lower()]
        # RWBSM\DLB\DLBM\DLMC\TBMJ\CJSJ\YXFW   == rwbsm
        fields = arcpy.ListFields(self.sjy)
        for field in fields:
            if field.name.lower() not in attrs:
                arcpy.DeleteField_management(self.sjy, field.name)

        # 添加字段
        arcpy.AddField_management(self.sjy, "BSM", "TEXT")
        arcpy.AddField_management(self.sjy, "TBXL", "SHORT")
        arcpy.AddField_management(self.sjy, "DLB", "TEXT")
        arcpy.AddField_management(self.sjy, "DLBM", "TEXT")
        arcpy.AddField_management(self.sjy, "DLMC", "TEXT")
        arcpy.AddField_management(self.sjy, "XZQDM", "TEXT")
        arcpy.AddField_management(self.sjy, "XZQMC", "TEXT")
        arcpy.AddField_management(self.sjy, "CJSJ", "DATE")
        arcpy.AddField_management(self.sjy, "YXFA", "SHORT")
        # 结果入库-判读可能没有数据
        ufields = ["BSM", "TBXL", "DLB", "DLBM", "DLMC", "XZQDM", "XZQMC", "CJSJ", "YXFA",
                   self.task['DMZD'].lower(), self.task['MCZD'].lower(), self.task['XZQDMZD'].lower(),
                   self.task['XZQMCZD'].lower()]
        bsmlist = []
        tbxl = 0
        with arcpy.da.UpdateCursor(self.sjy, ufields, sql_clause=(None, 'ORDER BY TBMJ DESC')) as cursor:
            for row in cursor:
                tbxl = tbxl + 1
                guid = ''.join(str(uuid.uuid1()).split('-'))
                bsmlist.append(guid)
                row[0] = guid
                row[1] = tbxl
                row[2] = self.task["SJY"]
                row[3] = row[9]
                row[4] = row[10]
                row[5] = row[11]
                row[6] = row[12]
                row[7] = datetime.datetime.now()
                row[8] = 0
                cursor.updateRow(row)
        arcpy.Append_management([self.sjy], "KJGH.T_FZSS_FZXZ_JG_GIS", "NO_TEST")

        # 7.统计分析
        self.tjfx = r"{0}\YZ_TJFX".format(self.outGdb)
        tbxl = 0
        for bsm in bsmlist:
            arcpy.Delete_management(self.tjfx)
            arcpy.Select_analysis(self.sjy, self.tjfx, '"BSM"=\'{0}\''.format(bsm))
            tbxl = tbxl + 1
            for yz in self.xzyz:
                sjlx = yz['SJLX'].lower()
                if yz['YZTJ'] == 'F':
                    self.yzjg_FX(bsm, yz)
                else:
                    self.yzjg_TJ(bsm, yz)
            self.fxlog(self.bsm, "info", "图斑{0}统计分析完成".format(str(tbxl)))
        time.sleep(1)
        self.fxlog(self.bsm, "info", "选址完成")
        print("####OK####")

    def test(self):
        self.xzfw = r'E:\99project\P008KJGH\SVN\trunk\SoureCode\2.Api\QM.KJGH.Com\QM.GisPython\fzxz\out\072f6ecbb54a4d5abd68b7ea06421202.gdb\XZFW'
        self.sjy = r'E:\99project\P008KJGH\SVN\trunk\SoureCode\2.Api\QM.KJGH.Com\QM.GisPython\fzxz\out\072f6ecbb54a4d5abd68b7ea06421202.gdb\YZ_MJ'
        bsmlist = [
            "a393c0c004af11ec9e3b4074e0062853",
            "a393c0c104af11ecb1f04074e0062853",
            "a393e7cf04af11ecadf14074e0062853",
            "a393e7d004af11ec9db94074e0062853",
            "a393e7d104af11eca8ab4074e0062853",
            "a393e7d204af11ec96104074e0062853"
        ]
        # 统计分析
        self.tjfx = r"{0}\YZ_TJFX".format(self.outGdb)
        for bsm in bsmlist:
            arcpy.Delete_management(self.tjfx)
            arcpy.Select_analysis(self.sjy, self.tjfx, '"BSM"=\'{0}\''.format(bsm))
            for yz in self.xzyz:
                sjlx = yz['SJLX'].lower()
                if yz['YZTJ'] == 'F':
                    self.yzjg_FX(bsm, yz)
                else:
                    self.yzjg_TJ(bsm, yz)

    # 4.因子筛选
    def yzfx(self, data):
        yztj = data['YZTJ']  # 条件
        yzsjy = data['SJY']  # 数据
        # 条件过滤
        if data['GLTJ'] != "" and data['GLTJ'] != None:
            out = r"{0}\YZGL_{1}".format(self.outGdb, data['YZBSM'])
            arcpy.Select_analysis(yzsjy, out, data['GLTJ'])
            yzsjy = out

        out = r"{0}\YZ_{1}_{2}".format(self.outGdb, yztj, data['YZBSM'])
        xyz = data.get('YXZ')
        if yztj == 'C':  # 包含
            if xyz != '' and xyz != None:  # 距离
                arcpy.Near_analysis(self.sjy, yzsjy, "{0} Meters".format(xyz), method='GEODESIC')
                arcpy.Select_analysis(self.sjy, out, " NEAR_DIST > -1 ")
            else:
                arcpy.Clip_analysis(self.sjy, yzsjy, out)
            self.sjy = out
        elif yztj == 'N':  # 不包含
            if xyz != '' and xyz != None:
                arcpy.Near_analysis(self.sjy, yzsjy, "{0} Meters".format(xyz), method='GEODESIC')
                arcpy.Select_analysis(self.sjy, out, " NEAR_DIST = -1 ")
            else:
                clip = r"{0}\YZ_{1}0_{2}".format(self.outGdb, yztj, data['YZBSM'])
                arcpy.Clip_analysis(yzsjy, self.xzfw, clip)
                arcpy.SymDiff_analysis(self.sjy, clip, out)
            self.sjy = out

    # 6.因子结果-分析
    def yzjg_FX(self, bsm, yz):
        '''分析'''
        out = r"{0}\YZ_{1}_{2}".format(self.outGdb, yz['YZTJ'], yz['YZBSM'])
        arcpy.Clip_analysis(yz["SJY"], self.tjfx, out)
        mjField = "TBMJ"
        arcpy.AddField_management(out, mjField, "DOUBLE")
        arcpy.CalculateField_management(out, mjField, "!shape.area@SQUAREMETERS!", "PYTHON_9.3")
        mj = 0;
        jgstr = ""
        with arcpy.da.SearchCursor(out, ['TBMJ']) as cursor:
            for row in cursor:
                mj = mj + row[0]
        # if mj == 0:
        #    jgstr = "地块未压占" + yz['YXYZMC']
        # else:
        #    jgstr = round(mj)
        self.jgrk(bsm, yz, round(mj))

    # 6.因子结果-统计
    def yzjg_TJ(self, bsm, yz):
        '''统计'''
        # self.tjfx
        jgstr = yz['FXJG_' + yz['YZTJ']]
        keys = utils.regDkh(jgstr)
        if len(keys) == 0:
            self.jgrk(bsm, yz, jgstr)
        else:
            self.yztjjl = r"{0}\YZGL_{1}".format(self.outGdb, yz['YZBSM'])
            arcpy.Near_analysis(self.yztjjl, self.tjfx, method='GEODESIC')
            where = "NEAR_DIST <= {0}".format(yz['YXZ'])
            if yz['YZTJ'] == 'N':
                where = "NEAR_DIST > {0}".format(yz['YXZ'])

            for key in keys:
                if key == 'YXZ':
                    jgstr = jgstr.replace("{YXZ}", yz['YXZ'])
                elif key == 'COUNT':
                    jgstr = jgstr.replace("{COUNT}", self.yzjg_TJ_COUNT(yz, where))
                elif key == 'DIST':
                    jgstr = jgstr.replace("{DIST}", self.yzjg_TJ_DIST(yz, where))
                elif key.startswith('YZ.'):
                    jgstr = jgstr.replace("{" + key + "}", self.yzjg_TJ_YZ(yz, where, key))
                elif key.startswith('[') and key.endswith(']'):
                    jgstr = jgstr.replace("{" + key + "}", self.yzjg_TJ_YZS(yz, where, key))
            self.jgrk(bsm, yz, jgstr)

    def yzjg_TJ_COUNT(self, yz, where):
        count = 0;
        with arcpy.da.SearchCursor(self.yztjjl, ["NEAR_DIST"], where) as cursor:
            for row in cursor:
                count = count + 1
        return str(count)

    def yzjg_TJ_DIST(self, yz, where):
        dist = 0;
        with arcpy.da.SearchCursor(self.yztjjl, ["NEAR_DIST"], where,
                                   sql_clause=(None, 'ORDER BY NEAR_DIST')) as cursor:
            for row in cursor:
                dist = row[0]
                break
        return str(round(dist))

    def yzjg_TJ_YZ(self, yz, where, key):
        val = "";
        key = key.replace("YZ.", "")
        with arcpy.da.SearchCursor(self.yztjjl, [key], where, sql_clause=(None, 'ORDER BY NEAR_DIST')) as cursor:
            for row in cursor:
                val = row[0]
                break
        return val

    def yzjg_TJ_YZS(self, yz, where, key):
        val = "";
        key = key.replace("YZ.", "").replace("[", "").replace("]", "")
        with arcpy.da.SearchCursor(self.yztjjl, [key], where, sql_clause=(None, 'ORDER BY NEAR_DIST')) as cursor:
            for row in cursor:
                val = val + row[0] + "、"
        return val[:-1]

    def jgrk(self, bsm, yz, jg):
        sql = "INSERT  INTO onemap.T_FZSS_FZXZ_JGYZ(BSM,JBBSM,YZBSM,YXYZMC,YZTJ,YXZ,FXJG) VALUES ('{0}','{1}','{2}','{3}','{4}','{5}','{6}')";
        sql = sql.format(
            ''.join(str(uuid.uuid1()).split('-'))
            , bsm
            , yz['BSM']
            , yz['YXYZMC']
            , yz['YZTJ']
            , yz['YXZ'] if yz['YXZ'] != None else ''
            , jg
        )
        self.db.insert(sql)

    def fxlog(self, bsm, rzlx, msg):
        sql = "INSERT INTO onemap.T_FZSS_FXRWRZ(RWLX,RWBSM,RZLX,FXJG,RZSJ,RZLR,BSM) VALUES ('{0}','{1}','{2}','{3}',to_date('{4}','yyyy-mm-dd hh24:mi:ss'),'{5}','{6}')";
        sql = sql.format(
            '辅助选址'
            , bsm
            , rzlx
            , ''
            , utils.getNowTimeStr("%Y-%m-%d %H:%M:%S")
            , msg
            , ''.join(str(uuid.uuid1()).split('-'))
        )
        self.db.insert(sql)
