# -*- 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)