# -*- coding: utf-8 -*- import struct import decimal import itertools import arcpy import math import sys import datetime import cx_Oracle import json import os import time import uuid import logging from arcpy import env from arcpy.sa import * #参数:文件路径,字段序列,字段类型序列,数据记录序列 def dbfwriter(f, fieldnames, fieldspecs, records): """ Return a string suitable for writing directly to a binary dbf file. File f should be open for writing in a binary mode. Fieldnames should be no longer than ten characters and not include x00. Fieldspecs are in the form (type, size, deci) where type is one of: C for ascii character data M for ascii character memo data (real memo fields not supported) D for datetime objects N for ints or decimal objects L for logical values 'T', 'F', or '?' size is the field width deci is the number of decimal places in the provided decimal object Records can be an iterable over the records (sequences of field values). """ # header info ver = 3 now = datetime.datetime.now() yr, mon, day = now.year - 1900, now.month, now.day numrec = len(records) numfields = len(fieldspecs) lenheader = numfields * 32 + 33 lenrecord = sum(field[1] for field in fieldspecs) + 1 hdr = struct.pack('<BBBBLHH20x', ver, yr, mon, day, numrec, lenheader, lenrecord) f.write(hdr) # field specs for name, (typ, size, deci) in itertools.izip(fieldnames, fieldspecs): name = name.ljust(11, 'x00') fld = struct.pack('<11sc4xBB14x', name, typ, size, deci) f.write(fld) # terminator f.write(' ') # records for record in records: f.write(' ') # deletion flag for (typ, size, deci), value in itertools.izip(fieldspecs, record): if typ == "N": value = str(value).rjust(size, ' ') elif typ == 'D': value = value.strftime('%Y%m%d') elif typ == 'L': value = str(value)[0].upper() else: value = str(value)[:size].ljust(size, ' ') assert len(value) == size f.write(value) # End of file f.write('x1A') ##################################################################### LOG_FILENAME="E:updatelog.txt"; t = datetime.datetime.now(); logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG); logging.debug(str(t)+"闪电数据处理开始:"); #修改默认系统编码格式,让系统支持中文 reload(sys); #print sys.getdefaultencoding(); sys.setdefaultencoding('utf8'); env.workspace = r"e:update"; logging.debug("1、从数据库查询数据,然后保存到dbtable.dbf中(计算值工具不能用于python编辑)"); cnxn = cx_Oracle.connect('ycybyj/ycybyj@127.0.0.1:1521/orcl'); cursor0 = cnxn.cursor(); #查询出字段用ID,SHI1,XIAN1 分析完后字段用SHI,XIAN,SHENG querySql="select ID,LONGITUDE,LATITUDE,SHI SHI1,XIAN XIAN1 from lightning where sheng is not null and rownum<=100"; cursor0.execute(querySql); records=[]; for item in cursor0: records.append(item); #生成dbtable之前,需要先把现有的dbtable.dbf删除 filename ='e:/update/shp/dbtable.dbf' if arcpy.Exists(filename): try: arcpy.Delete_management(filename, "") except: arcpy.AddError("无法删除dbtable.dbf:" + filename) f = open(filename, 'wb+') fieldnames=['ID','LONGITUDE','LATITUDE','SHI1','XIAN1']; fieldspecs=[('N',10,0),('N',10,4),('N',10,4),('C',50,0),('C',50,0)]; dbfwriter(f, fieldnames, fieldspecs, records) f.close() logging.debug("2、利用XY事件图层工具,把数据库表转换成要素类"); arcpy.MakeXYEventLayer_management(filename, "LONGITUDE", "LATITUDE", "out_layer"); nums=arcpy.GetCount_management("out_Layer"); logging.debug("2.1、 该次处理的数据行数是:"+str(nums)); logging.debug("3、利用空间链接工具,获取到闪电的行政区"); joinfc=r"e:updateshpxian.shp"; outfc=r"e:updateshpout.shp"; #生成out.shp之前,需要先把现有的out.shp删除 if arcpy.Exists(outfc): try: arcpy.Delete_management(outfc, "") except: arcpy.AddError("无法删除out.shp:" + outfc) arcpy.SpatialJoin_analysis("out_layer", joinfc, outfc); logging.debug("4、将结果shp里的信息更新到数据库,唯一标识用ID"); cursor = cnxn.cursor(); cursor1 = arcpy.SearchCursor(outfc) for row in cursor1: ids=row.getValue("ID"); ids=int(ids); xian=row.getValue("XIAN"); shi=row.getValue("SHI"); sheng=row.getValue("SHENG"); if sheng==' ': sheng='非安徽省'; updatesql="update lightning set sheng='"+sheng+"', xian='"+xian+"',shi='"+shi+"' where id="+str(ids); cursor.execute(updatesql); cnxn.commit(); #删除不在行政区边界内的闪电点位 delSql="delete from lightning where sheng='非安徽省'"; cursor.execute(updatesql); cnxn.commit(); #关闭系统资源 cursor0.close; cursor.close; cnxn.close; tt = datetime.datetime.now(); logging.debug(str(tt)+"闪电数据处理结束.");