美文网首页gis
利用Arcpy和Geopandas进行多规比对

利用Arcpy和Geopandas进行多规比对

作者: 任源_c4d5 | 来源:发表于2021-01-31 04:12 被阅读0次

    在ArcGIS中可以很容易进行土规和城规的比对,这里,利用Arcpy和Geopandas来进行多规比对。

    土规 城规
    # encoding: utf-8
    # @Author : hanqi
    

    数据预处理

    导入相关模块

    ## 导入相关模块
    import arcpy
    from arcpy import env
    import numpy as np
    import pandas as pd
    import geopandas as gpd
    import matplotlib.pyplot as plt
    

    防止乱码

    plt.rcParams['font.family'] = ['sans-serif']
    plt.rcParams['font.sans-serif'] = ['SimHei']#替换sans-serif字体为黑体
    plt.rcParams['axes.unicode_minus'] = False   # 解决坐标轴负数的负号显示问题
    

    设置arcpy工作环境和路径

    env.workspace = r"F:\ArcGIS\多规对比"
    path = "F:\ArcGIS\多规对比\图斑对比.gdb"
    tg_path = "F:\ArcGIS\多规对比\图斑对比.gdb\土规用地"
    cg_path = "F:\ArcGIS\多规对比\图斑对比.gdb\城规用地"
    

    土规和城规用地分类

    读取数据

    land = gpd.GeoDataFrame.from_file(path,layer='土规用地')
    city = gpd.GeoDataFrame.from_file(path,layer='城规用地')
    
    land.head()
    city.head()
    
    处理后的数据

    arcpy数据处理

    ## 删除字段
    ## 因为我做过一遍,所以先删除
    arcpy.DeleteField_management(tg_path, "tg_yongdi")
    arcpy.DeleteField_management(cg_path, "cg_yongdi")
    
    
    ## 添加字段
    fieldName1 = "tg_yongdi"
    fieldLength = 30
     
    # Execute AddField twice for two new fields
    arcpy.AddField_management(tg_path, fieldName1, "TEXT", field_length=fieldLength)
    
    fieldName2 = "cg_yongdi"
    fieldLength = 30
    
    arcpy.AddField_management(cg_path, fieldName2, "TEXT", field_length=fieldLength)
    
    ## 字段计算器
    ## 城规字段计算器
    ## 只有一个水域不是建设用地
    
    # Set local variables
    inTable = cg_path
    fieldName = "cg_yongdi"
    expression = "getClass((!cg_fenlei!))"
    codeblock = """
    def getClass(cg_fenlei):
        if cg_fenlei in "E11":
            return "城规_非建设用地"
        
        else:
            return "城规_建设用地"   """
            
    # Execute CalculateField 
    arcpy.CalculateField_management(inTable, fieldName, expression, "PYTHON_9.3", codeblock)
    
    ## 土规字段计算器
    
    # Set local variables
    inTable = tg_path
    fieldName = "tg_yongdi"
    expression = "getClass((!Layer!))"
    codeblock = """
    def getClass(Layer):
        if Layer in ("TG-一般农田", "TG-基本农田", "TG-林地", "TG-水系", "TG-林地"):
            return "土规_非建设用地"
            
        if Layer is None:
            return None
        
        else:
            return "土规_建设用地"   """
    
    
    # Execute CalculateField 
    arcpy.CalculateField_management(inTable, fieldName, expression, "PYTHON_9.3", codeblock)
    

    结果就是上图,土规和城规的用地分为两类了,这里不做演示。

    多规比对

    ## 联合工具
    
    inFeatures = [cg_path, tg_path]
    outFeatures = outFeatures = path + "\\多规比对"
    
    arcpy.Union_analysis (inFeatures, outFeatures, "ALL")
    
    dg_path = "F:\ArcGIS\多归对比\图斑对比.gdb\多规比对"
    dg = gpd.GeoDataFrame.from_file(path, layer="多规比对")
    dg.head()
    
    联合结果
    # Set local variables
    ## 多规字段计算器
    inTable = dg_path
    fieldName = "cg_yongdi"
    expression = "getClass3((!cg_yongdi!))"
    codeblock = """
    def getClass3(cg_yongdi):
        if cg_yongdi is None:
            return "城规_非建设用地"
        else:
            return cg_yongdi
    """
     
    # Execute CalculateField 
    arcpy.CalculateField_management(inTable, fieldName, expression, "PYTHON_9.3", codeblock)
    
    ## 删除字段
    
    arcpy.DeleteField_management(dg_path, ["FID_城规用地","Layer","cg_fenlei","FID_土规用地"])
    
    ## 添加合并字段
    
    fieldName3 = "dg_hebing"
    fieldLength = 30
     
    # Execute AddField twice for two new fields
    arcpy.AddField_management(dg_path, fieldName3, "TEXT", field_length=fieldLength)
    
    ## 城规字段合并
    # Set local variables
    inTable = dg_path
    fieldName = "dg_hebing"
    expression = "!tg_yongdi!+'_'+!cg_yongdi!"
    # Execute CalculateField 
    arcpy.CalculateField_management(inTable, fieldName, expression, "PYTHON_9.3")
    
    
    dg = gpd.GeoDataFrame.from_file(path, layer="多规比对")
    dg_path = path+'\\多规比对'
    dg
    
    多归处理后结果

    冲突对比

    ## 添加索引
    rec = 0
    inTable = dg_path
    fieldName = "Identify"
    expression = "autoIncrement()"
    codeblock = """
    def autoIncrement():
        global rec
        pStart = 1
        pInterval = 1
        if (rec == 0):
            rec = pStart
         
        else:
            rec = rec + pInterval
        return rec """
     
    # Execute AddField
    arcpy.AddField_management(inTable, fieldName, "LONG")
     
    # Execute CalculateField 
    arcpy.CalculateField_management(inTable, fieldName, expression, "PYTHON_9.3", codeblock)
    
    dg = gpd.GeoDataFrame.from_file(path, layer="多规比对")
    dg.head()
    
    索引
    ## 按属性分割
    
    
    # Set local variables
    in_feature_class = dg_path
    target_workspace = path
    fields = ['dg_hebing']
    arcpy.SplitByAttributes_analysis(in_feature_class, target_workspace, fields)
    
    cgfjs_tgjs = gpd.GeoDataFrame.from_file(path, layer="土规_非建设用地_城规_建设用地")
    cgfjs_tgjs.plot()
    
    土规_非建设用地_城规_建设用地
    cgjs_tgfjs = gpd.GeoDataFrame.from_file(path, layer="土规_建设用地_城规_非建设用地")
    cgjs_tgfjs.plot()
    
    土规_建设用地_城规_非建设用地

    区划调整

    土规非建设用地_城规建设用地调整

    ## 定义路径
    tgfjs_cgjs_path = path+"\\土规_非建设用地_城规_建设用地"
    
    # Set local variables
    ## 土地面积大于10000依城规
    
    inTable = tgfjs_cgjs_path
    fieldName = "gz_1"
    expression = "getClass((!Shape_Area!))"
    codeblock = """
    def getClass(Shape_Area):
        if Shape_Area>10000:
            return "依城规用地"
            
        else:
            return "依土规用地"   """
    
    
    # Execute CalculateField 
    arcpy.CalculateField_management(inTable, fieldName, expression, "PYTHON_9.3", codeblock)
    
    
    土规_非建设用地_城规_建设用地属性表
    土规_非建设用地_城规_建设用地

    土规建设用地_城规非建设用地调整

    ## 限制1000以内不隐藏
    pd.set_option('max_columns',1000)
    pd.set_option('max_row',1000)
    
    tgjs_cgfjs_path = path+"\\土规_建设用地_城规_非建设用地"
    tgjs_cgfjs = gpd.GeoDataFrame.from_file(path, layer="土规_建设用地_城规_非建设用地")
    tgjs_cgfjs.sort_values('Shape_Area',ascending=False)  ##观察面积
    
    土规建设_城规非建设属性表
    # Set local variables
    ## 土地面积大于10000以土规
    
    inTable = tgjs_cgfjs
    fieldName = "gz_2"
    expression = "getClass5((!Shape_Area!))"
    codeblock = """
    def getClass5(Shape_Area):
        if Shape_Area>10000:
            return "依土规用地"
    
        
        else:
            return "依城规用地"   """
    
    
    # Execute CalculateField 
    arcpy.CalculateField_management(inTable, fieldName, expression, "PYTHON_9.3",   codeblock)
    
    tgjs_cgfjs = gpd.GeoDataFrame.from_file(path, layer="土规_建设用地_城规_非建设用地")
    tgjs_cgfjs.plot(column='gz_2',legend=True)
    
    土规建设城规非建设

    数据连接

    
    layerName = dg_path
    joinTable = cgjs_tgfjs_path
    joinField = "Identify"
    
    
    # Join the feature layer to a table
    arcpy.AddJoin_management(layerName, joinField, joinTable, joinField)
    
    
    
    layerName = '多规比对_Layer1'
    joinTable = cgfjs_tgjs_path
    joinField = "Identify"
    
    
    # Join the feature layer to a table
    arcpy.AddJoin_management(layerName, joinField, joinTable, joinField)
    
    
    ## 导出数据
    # 输入
    in_features = ['多规比对_Layer1']
    # 输出
    out_location = path
     
    # 执行 FeatureClassToGeodatabase
    arcpy.FeatureClassToGeodatabase_conversion(in_features, out_location)
    
    
    dg_3 = gpd.GeoDataFrame.from_file(path, layer="多规比对_Layer3")
    dg_3.head()
    
    数据连接
    ## 重命名
    
    # Set local variables
    in_data =  "多规比对_Layer1"
    out_data = "多规比对_最终"
    
    # Execute Rename
    arcpy.Rename_management(in_data, out_data)
    
    # Set local variables
    
    inTable = path+"\\多规对比_最终"
    fieldName = "gz_all"
    expression = "getClass5(!土规_非建设用地_城规_建设用地_gz_1! , !土规_建设用地_城规_非建设用地_gz_2!)"  ## 不能用别名
    codeblock = """
    def getClass6(gz_1,gz_2):
        if gz_1 is not None:
            return gz_1
            
        if gz_2 is not None:
            return gz_2
             
        else:
            return "无冲突"   """
    
    arcpy.AddField_management(inTable, fieldName, "TEXT", 30)
    
    # Execute CalculateField 
    arcpy.CalculateField_management(inTable, fieldName, expression, "PYTHON_9.3", codeblock)
    
    dg_zz = gpd.GeoDataFrame.from_file(path, layer="多规比对_最终")
    dg_zz.plot(column='gz_all',legend=True)
    
    冲突比对

    用地判定

    就是根据冲突比对来返回想对呀的地块用地,这里我用字段计算pyhton做不出来,用vb可以,但是可以用pandas来处理。
    vb脚本

    if [gz_all] = "依土规用地" then
        value = [多规比对_tg_yongdi]
    
    if [gz_all] = "依成规用地" then
        value = [多规比对_cg_yongdi]
    
    if [gz_all] = "无冲突" then
        value = [多规比对_cg_yongdi]
    end if
    
    value
    

    pandas

    ## 最终用地
    for i in dg_zz.index:
            if dg_zz.at[i,'gz_all']=="无冲突":
                dg_zz["最终用地"].at[i] = dg_zz["多规比对_tg_yongdi"].at[i]
            if dg_zz.at[i,'gz_all'] == "依城规用地":
                dg_zz["最终用地"].at[i] = dg_zz["多规比对_cg_yongdi"].at[i]
            else:
                dg_zz["最终用地"].at[i] = dg_zz["多规比对_tg_yongdi"].at[i]
    dg_zz.head()      
    
    ## 分列
    dg_zz["用地"] = dg_zz['最终用地'].str.split('_',expand=True)[1]
    dg_zz.head()
    
    #dg_zz["用地"] = s.split('_')[1]
    

    结果,这里我进行过很多次计算了


    用地结果
    ## 写入excel文件
    
    dg_zz.to_excel("成果.xlsx",index=None,encoding="utf8")
    

    然后连接回shp文件就行了,有些ArcGIS不支持xlsx,保存的时候可以注意点,我的可以

    字段计算器分列

    ## 分割字段
    
    # Set local variables
    
    inTable = path + "\\多规比对_最终"
    fieldName = "yongdi"
    expression = "getClass6(!zz_yongdi!)"  ## 不能用别名
    codeblock = """
    def getClass6(zz_yongdi):
        value = zz_yongdi.split('_')[1]
            
        return value   """
    
    arcpy.AddField_management(inTable, fieldName, "TEXT", 30)
    # Execute CalculateField 
    arcpy.CalculateField_management(inTable, fieldName, expression, "PYTHON_9.3", codeblock)
    
    dg_zz = gpd.GeoDataFrame.from_file(path, layer="多规比对_最终")
    dg_zz.plot(column='zz_yongdi',legend=True)
    
    最终用地比对

    成果出图

    fig, ax = plt.subplots(figsize=(10, 10))
    ax = dg_zz.plot(ax=ax,column='yongdi',cmap='Set1',legend=True,legend_kwds={
                                                         'loc': 'lower left',
                                                         'title': '图例',
                                                         'shadow': True})
    plt.suptitle('土地利用建设分布图', fontsize=24) # 添加最高级别标题
    plt.tight_layout(pad=4.5) # 调整不同标题之间间距
    plt.grid(True, alpha=0.3)
    
    fig.savefig('土地利用建设分布图.png', dpi=300)
    
    fig, ax = plt.subplots(figsize=(10, 10))
    ax = dg_zz.plot(ax=ax,column='gz_all',cmap='tab10',legend=True,legend_kwds={
                                                         'loc': 'lower left',
                                                         'title': '图例',
                                                         'shadow': True})
    plt.suptitle('规划冲突调整图', fontsize=24) # 添加最高级别标题
    plt.tight_layout(pad=4.5) # 调整不同标题之间间距
    plt.grid(True, alpha=0.3)
    
    fig.savefig('规划冲突调整图.png', dpi=300)
    
    土地利用建设图 规划冲突调整图

    相关文章

      网友评论

        本文标题:利用Arcpy和Geopandas进行多规比对

        本文链接:https://www.haomeiwen.com/subject/joeltltx.html