zoukankan      html  css  js  c++  java
  • 如何将Excel表批量赋值到ArcGIS属性表

    情景再现

    现需要将Excel表信息批量赋值(不是挂接)到Shp文件的属性表,两张表的字段、记录数一模一样,至于为什么会出现这样的问题,咱也不敢问,只有想个法子把它搞定!

    原始的Excel信息表共57列,总共3万多条记录,包含了正确的记录数据,如下:

    目标的ArcGIS属性表也是57列(不是Table表,是要素类的属性表),记录中的信息不正确,如下:

    好在它们的FID字段可以一一对应,现在需要根据Excel属性表把ArcGIS属性表填充正确。

    常规思路

    最容易想到的方法是,用属性表连接Excel表,然后利用字段计算器,分别进行计算。

    由于记录有3万多条,平均一个字段计算要8分钟,这也得花一天时间啊,如果没有其实方法,且不用管"白猫""黑猫",能解决就行。

    编程思维

    从上面的方法,我们会很快发现一个问题:50多个字段的计算都是重复一个步骤,在某个字段上右键,点击"字段计算器"弹出窗口,选择相应的字段,点击确定。这个过程简单而无味,是否有让电脑自动重复这个操作,解放我们的双手?答案是肯定的,通过简单的编程来实现重复的操作,对于本场景最佳编程方式是使用强大的Python脚本。对于新手来说也莫怕,编程并不可怕,可怕的是你遇到这种问题不会编程。下面来试一下:

    简单解释一下:

    第一步,导入arcpy,这是ESRI给我造好的"轮子",引入它后可以做所有地理处理的功能;

    第二步,直接调用字段计算的方法,方法名称是:arcpy.CalculateField_management,其后面的括号带四个参数,分别是计算的图层名称(即表名称)、计算的字段(即在哪个字段上右键调出字段计算器)、计算表达式(就是选择的赋值字段)、Python版本(固定值);

    第三步,回车执行,糟糕,报错了。不要紧,仔细分析一下,看是语法问题,还是数据问题,重写一句再执行就对了。

    有了成功的开始,是不是增加信心。我们不可能手动输入50多句话,也很难写的,得再想个法子来解放双手(再次编程思维)。强大的Excel上场了:用公式写好一行,直接向下拖动(或双击右下角),呵呵,这个我最擅长了。

    将这些正确语法的Python语句放在窗口中执行,连续两次回车才是执行哦!

    接下来就慢慢等,虽然不需要反复操作,但时间也要花很久。

    收工。

    ---------回--------家---------吃---------饭--------

    Too young to simple!第二行就报错了

    怎么办?有三种方案:

    方案一:辞职转行了,处理数据真是心累!

    方案二:把问题返回给用户,让他们改好带拿过来!(你以为他们会听你的吗?你以为他们能准备无误地改得好吗?)

    方案三:百度、谷歌,查一下原因,写一个能容错的脚本,学习一下ArcPy处理地理数据。

    编程能力

    接下来,才是展示真正的技术的时候了。在连接好Excel表后,不使用字段计算器工具和脚本,而且是通过遍历的方式赋值。

    连接可保证行数相同。

    连接后将数据导出后,将

    下面这段代码主要考虑三个问题:

    (1)同名字赋值,如将Name_1的值赋给Name;

    (2)缺失字段不赋值,如果不存在Name_1字段,则Name的值不重处理;

    (3)忽略值与类型逻辑不一致的情况,如Count字段的值不能为空,默认为0,而Count_1的值为NULL.

    代码如下,不过多解释,因为这不是本文重点。

    import arcpy,os
    
    input_table=arcpy.GetParameterAsText(0)
    
    input_result=arcpy.GetCount_management(input_table)
    input_count= int(input_result.getOutput(0))
    arcpy.AddMessage("input count:"+ str(input_count))
    oidFieldName=arcpy.Describe(input_table).OIDFieldName
    allfields = arcpy.ListFields(input_table) 
    lstFields=[]
    for field in allfields:
        lstFields.append(field.name)
    arcpy.AddMessage(lstFields)
    
    # foreach all row and all field
    cursor = arcpy.UpdateCursor(input_table)
    for row in cursor:
        fields = arcpy.ListFields(input_table)
        oid=int(row.getValue(oidFieldName))
        if oid>1:
            arcpy.AddMessage(oid)   
        for field in fields:
            if field.required or field.name[-2:]=='_1':
                print('')
            else:
                targetField=field.name+'_1'
                if targetField in lstFields:
                    newValue=row.getValue(targetField)
                    try:
                        row.setValue(field.name,newValue)
                        #arcpy.AddMessage(field.name+":"+ str(newValue))
                    except:
                        #arcpy.AddMessage(field.name+":except....")
                        pass
                else:
                    print('')
                    #arcpy.AddMessage(targetField+":is not exist")
        cursor.updateRow(row)
    

      

    慢慢等结果了:

    小结

    1、要学会有编程(或程序)的思维去解决问题,提高工作效率;

    2、编程解决问题是一种能力,是慢慢学习积累的过程,没有一本速成的书;

    3、实际生产过程中的数据往往不是理想的,有各种各样的"陷阱"。

    补充:

    个别网友认为我小题大作了,由于原始数据不传于上传,所以我也不再反驳:

  • 相关阅读:
    小程序_递归求年纪
    小程序_递归求阶层
    把字符串复制到剪贴板
    主流的三种RF方案及其优缺点比较
    CC1100E的ESD指标?
    delphi怎样打开一个文本文件
    CC1100模块 250K的速率的问题
    delphi 中显示access数据库表怎么实现
    delphi与Access数据库连接的步骤
    数据库基本语句
  • 原文地址:https://www.cnblogs.com/liweis/p/11518998.html
Copyright © 2011-2022 走看看