利用Arcpy和Geopandas进行多规比对

在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)
土地利用建设图
规划冲突调整图
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,104评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,816评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,697评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,836评论 1 298
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,851评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,441评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,992评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,899评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,457评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,529评论 3 341
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,664评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,346评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,025评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,511评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,611评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,081评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,675评论 2 359

推荐阅读更多精彩内容

  • 我国现行规划体系存在经济社会发展规划和空间规划两大序列,规划类型很多(据不完全统计,具有法定依据的各类规划至少有8...
    ZzxX_b8f7阅读 1,237评论 0 5
  • 婺源,古徽州一府六县之一。地处江西省东北部,赣浙皖三省交汇处。 婺源——中国最美的乡村。一生痴绝处,无梦到徽州。来...
    林可非非非阅读 6,567评论 2 2
  • 夜莺2517阅读 127,728评论 1 9
  • 版本:ios 1.2.1 亮点: 1.app角标可以实时更新天气温度或选择空气质量,建议处女座就不要选了,不然老想...
    我就是沉沉阅读 6,904评论 1 6
  • 我是一名过去式的高三狗,很可悲,在这三年里我没有恋爱,看着同龄的小伙伴们一对儿一对儿的,我的心不好受。怎么说呢,高...
    小娘纸阅读 3,392评论 4 7