# -*- 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.oracle import Oracle reload(sys) sys.setdefaultencoding('utf-8') class Fzxz: def __init__(self, data): self.bsm = data self.db = Oracle(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,a.SJY,a.YDXZ_BSM,a.FWLX,a.XZFW,a.YDMJBEGIN,a.YDMJEND,a.KDDK,a.ZDPD,b.SJYMC,b.DMZD,b.MCZD,b.FZBS,c.MC,b.XZQDMZD,b.XZQMCZD FROM KJGH.T_FZSS_FZXZ a INNER JOIN KJGH.T_FZSS_FZXZ_SJY b ON a.SJY = b.BSM LEFT JOIN KJGH.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,A.RWBSM,A.YZBSM,A.YXYZMC,A.YZTJ,A.YXZ,B.SJLX,B.SJY,B.GLTJ,B.FXJG_C,B.FXJG_N FROM KJGH.T_FZSS_FZXZ_XZYZ A LEFT JOIN KJGH.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("SDE.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("SDE") 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 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 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)