# -*- coding: utf-8 -*- import os import sys import json import log import appconfig import arcpy import utils from arcpy import env from db.oracle import Oracle reload(sys) sys.setdefaultencoding('utf-8') class Xmydsyx: def __init__(self, data): self.bsm = data self.db = Oracle(appconfig.DB_CONN) self.outputname = "XMYDSYX" + data log.info(data) # 根据BSM获取任务信息 self.task() # 临时工作空间 self.root = os.path.dirname(os.path.abspath(__file__)) path = os.path.join(self.root, "out") if not os.path.exists(path): os.makedirs(path) # 创建输出GDB,如果已存在则删除后新建 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): # 根据BSM获取任务信息 sql = "select t.id,m.fxtable,y.name,y.sjlx from t_fxpj_xmyd_rz t left join t_fxpj_ctfx_main m on m.id = t.rwbsm left join t_fxpj_ctfx_yz y on y.id = t.yzbsm where t.rwbsm = '{0}'".format( self.bsm) tasks = self.db.query(sql) if len(tasks) == 0: raise Exception("任务标识错误[{0}]".format(self.bsm)) self.tasks = tasks def run(self): try: self.fxjgtable = "result_" + self.bsm # 记录任务开始时间 self.rwkssj = utils.getNowTimeStr("%Y-%m-%d %H:%M:%S") mjField = "TBMJ" syxField = "SYX" markField = "SW_XZQH" # 配置以哪个适宜性为主 firstStyle = "0" fxtable = "" # 记录主任务开始时间并写入表 # 遍历分析因子 进行叠加分析 for curtask in self.tasks: curkssj = utils.getNowTimeStr("%Y-%m-%d %H:%M:%S") try: fxtable = curtask["FXTABLE"] # 创建当前分析因子叠加结果表 curtablename = curtask["SJLX"] curt = r"{0}\{1}".format(self.outGdb, curtablename) # 使用要素识别,用影响因子切分项目范围 arcpy.Identity_analysis(fxtable, "SDE." + curtask["SJLX"], curt, "ALL", 0) # 计算面积 arcpy.AddField_management(curt, mjField, "DOUBLE") arcpy.CalculateField_management(curt, mjField, "!shape.area@SQUAREMETERS!", "PYTHON_9.3") # 增加适宜性字段 arcpy.AddField_management(curt, syxField, "TEXT") # 遍历数据 设置markField不为空则表示压覆,反之则不压覆,并计算各类面积统计 syArea = 0 # 适宜面积统计 bsyArea = 0 # 不适宜面积统计 totalArea = 0 with arcpy.da.UpdateCursor(curt, [markField, syxField, mjField]) as cursor: for row in cursor: if row[0] != None and row[0] != "": row[1] = "0" bsyArea = bsyArea + row[2] else: row[1] = "1" syArea = syArea + row[2] totalArea = totalArea + row[2] cursor.updateRow(row) # 组装返回结果 self.updateFxyzzt(curtask["ID"], "2", curkssj, curtablename, self.arrangeFxjg(syArea, bsyArea, totalArea)) except arcpy.ExecuteError: log.error(arcpy.GetMessages()) self.updateFxyzzt(curtask["ID"], "3", curkssj, curtablename, arcpy.GetMessages()) except: msg = str(sys.exc_info()).decode('string-escape') log.error(msg) self.updateFxyzzt(curtask["ID"], "3", curkssj, curtablename, msg) # 遍历分析因子 将权重高的数据类型统一提取到临时表 templist = [] for curtask in self.tasks: curtablename = curtask["SJLX"] curt = r"{0}\{1}".format(self.outGdb, curtablename) tempt = r"{0}\{1}".format(self.outGdb, "temp" + curtablename) templist.append(tempt) arcpy.Select_analysis(curt, tempt, "" + syxField + " = '" + firstStyle + "'") # 将权重数据提取到一张临时表进行要素图斑范围合并 merget = "{0}\{1}".format(self.outGdb, "merge_" + firstStyle) # 定义合并字段 # fldmap = arcpy.FieldMap() # for cur in templist: # fldmap.addInputField(cur, markField) # fldmap_outField = fldmap.outputField # fldmap_outField.name = markField # fldmap.outputField = fldmap_outField # fieldmappings = arcpy.FieldMappings() # for cur in templist: # fieldmappings.addTable(cur) # fieldmappings.addFieldMap(fldmap) arcpy.Merge_management(templist, merget) mergelast = r"{0}\{1}".format(self.outGdb, "mergelast_" + firstStyle) arcpy.Dissolve_management(merget, mergelast) arcpy.AddField_management(mergelast, markField, "TEXT") arcpy.CalculateField_management(mergelast, markField, "'1'", "PYTHON_9.3") # 使用要素识别,用影响因子切分项目范围 fxjgtable = r"{0}\{1}".format(self.outGdb, self.fxjgtable) arcpy.Identity_analysis(fxtable, mergelast, fxjgtable, "ALL", 0) # 计算面积 arcpy.AddField_management(fxjgtable, mjField, "DOUBLE") arcpy.CalculateField_management(fxjgtable, mjField, "!shape.area@SQUAREMETERS!", "PYTHON_9.3") # 增加适宜性字段 arcpy.AddField_management(fxjgtable, syxField, "TEXT") # 遍历数据 设置markField不为空则表示压覆,反之则不压覆,并计算各类面积统计 syArea = 0 # 适宜面积统计 bsyArea = 0 # 不适宜面积统计 totalArea = 0 with arcpy.da.UpdateCursor(fxjgtable, [markField, syxField, mjField]) as cursor: for row in cursor: if row[0] != None and row[0] != "": row[1] = "0" bsyArea = bsyArea + row[2] else: row[1] = "1" syArea = syArea + row[2] totalArea = totalArea + row[2] cursor.updateRow(row) # 组装返回结果 self.updateFxzt(self.bsm, "2", self.arrangeFxjg(syArea, bsyArea, totalArea)) log.info("####OK####") print("####OK####") except arcpy.ExecuteError: print("####ERROR####" + arcpy.GetMessages()) log.error(arcpy.GetMessages()) self.updateFxzt(self.bsm, "3", arcpy.GetMessages()) except: msg = str(sys.exc_info()).decode('string-escape') print("####ERROR####" + msg) log.error(msg) self.updateFxzt(self.bsm, "3", msg) # 整理统计数据 def arrangeFxjg(self, syArea, bsyArea, totalArea): obj = { "sy": { "area": "%.2f" % syArea, "proportion": "" + "%.2f" % (syArea / totalArea * 100) + "%" }, "bsy": { "area": "%.2f" % bsyArea, "proportion": "" + "%.2f" % (bsyArea / totalArea * 100) + "%" } } return json.dumps(obj) # 更新分析因子任务状态 def updateFxyzzt(self, bsm, fxzt, rwkssj, outputname, msg): # 记录任务结束时间 rwjssj = utils.getNowTimeStr("%Y-%m-%d %H:%M:%S") sql = "update t_fxpj_xmyd_rz t set rwzt = '{0}',rwkssj = to_date('{1}','yyyy-mm-dd hh24:mi:ss') , rwjssj = to_date('{2}','yyyy-mm-dd hh24:mi:ss') ,statist = '{3}',fxjgtable = '{4}',workspace = '{5}' where t.id = '{6}'" sql = sql.format( fxzt , rwkssj , rwjssj , msg , outputname , self.outGdb , bsm) self.db.insert(sql) # 更新冲突分析任务状态 def updateFxzt(self, bsm, fxzt, msg): # 记录任务结束时间 self.rwjssj = utils.getNowTimeStr("%Y-%m-%d %H:%M:%S") sql = "update t_fxpj_ctfx_main t set rwzt = '{0}',rwkssj = to_date('{1}','yyyy-mm-dd hh24:mi:ss') , rwjssj = to_date('{2}','yyyy-mm-dd hh24:mi:ss') ,fxjg = '{3}',fxjgtable = '{4}',workspace = '{5}' where t.id = '{6}'" sql = sql.format( fxzt , self.rwkssj , self.rwjssj , msg , self.fxjgtable , self.outGdb , bsm) self.db.insert(sql)