例如:第一章 arcpy2.7自动化出图
在使用ArcGIS与arcpy进行制图或进行数据处理时,需要先对数据库、数据框、图层、mxd文档有一个大概的了解,因此本文主要包括基础知识和arcpy制图实践两部分
一个制图文件中可以包含多各数据框,常见就是在已有制图区域中添加一个数据框作为鸟瞰图来显示地图区位
总结1:分别遍历数据框或图层,可以分别得到一个数据框列表和图层列表(某一数据框中的图层列表);因此数据框与图层的排列是有先后顺序的。了解这些便于后续使用代码进行操作。
目前arcgis\arcpy不支持符号系统的修改,如栅格的拉伸;仅支持使用已知图层的符号系统进行替换更新,这便于处理矢量数据可视化,不利于栅格数据的可视化
代码如下(示例):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
代码如下(初始化工作空间):
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
import arcpy
import os
from arcpy.sa import *
class InitPath(object):
"""初始化工作空间,创建gdb数据库(如果没有的话)"""
"""__new__和__init__相配合才是python中真正的类构造器
先执行__new__控制生成一个新实例的过程
__init__初始化新实例的过程,添加各种属性"""
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
# if not cls._instance:
# 生成实例cls
cls._instance = object.__new__(cls)
return cls._instance
def __init__(self, GDBDir = "",name = "Base"):
"""_________create folder_________"""
scratch_path = GDBDir # <<注释1>>
try:
if not os.path.isdir(scratch_path):
os.makedirs(scratch_path)
except:
scratch_path = GDBDir # <<注释2>>
if not os.path.isdir(scratch_path):
os.makedirs(scratch_path)
"""_________create folder_________"""
# make gdb,用于存储矢量栅格数据,以及中间生成变量
scratch_gdb = os.path.join(scratch_path, "{}.gdb".format(name))
if not arcpy.Exists(scratch_gdb):
arcpy.CreateFileGDB_management(scratch_path, "{}".format(name))
arcpy.env.workspace = scratch_path
arcpy.env.overwriteOutput = True
self.scratch_path = scratch_path
self.scratch_gdb = scratch_gdb
"""
:param1 GDBdir数据库路径
:param2 name数据库名称
"""
# 1.初始化环境
folder_path, gdb_path = InitPath(GDBdir, name)
arcpy.env.workspace = gdb_path # <<注释3:用于设置默认工作空间>>
arcpy.env.overwriteOutput = False # <<注释4:输出的结果会覆盖旧的数据>>
Data_class = "COD"
# 2.加载模板
mxd_dir =r"E:\user\Reclass.mxd"
mxd0 = arcpy.mapping.MapDocument(mxd_dir)
# 打印数据框
frames = arcpy.mapping.ListDataFrames(mxd0, "*")[0]
# 3.读取底图影像
# 4.读取数据影像,裁剪,并将其转换为栅格文件
img_dir = r"E:\user\LJHinversion\XX.tif"
waterShp = r"E:\user\Watershp\XX.shp"
color = r"E:\user\XX.clr"#重分类颜色映射表
#这里进行了掩膜操作,函数返回一个图层对象,但该对象不能直接进行插入图层操作,需要先另存图层,再后面再执行像mxd添加图层的操作
outExtractByMask = ExtractByMask(img_dir, waterShp)
if os.path.exists(r"E:\user\Reclass{}{}potency.tif".format(Data_class,"Clip")):
#这里先保存一下裁剪后的栅格文件
#删除已存在的数据,arcgis对已存在的数据进行修改,这算是一种保护机制吧
os.remove(r"E:\user\Reclass{}{}potency.tif")
outExtractByMask.save(r"E:\Reclass{}{}potency.tif".format(Data_class,"Clip"))
#重新读取该文件
reclassdir = r"E:\user\Reclass{}{}potency.tif".format(Data_class)
#这里设置一些必要的参数
# 影像数据源:"imgsource";影像获取日期:"imgdate";打印分辨率:"print_res"
img_info = {"imgsource":"高分","imgdate":"2023","print_res":800}
E2C= {"DO":"溶解氧", "CODMn":"高锰酸盐","BOD":"五日生华需氧量","COD":"化学需氧量","NH3N":"氨氮","TP":"总磷","TN":"总氮"}
#这里用于重分类范围值
remapdic = {"DO": [[0, 2, 6], [2, 3, 5], [3, 5, 4], [5, 6, 3], [6, 7.5, 2], [7.5, 100, 1]],
"COD": [[0, 15, 1], [15, 15, 2], [15, 20, 3], [20, 30, 4], [30, 40, 5], [40, 100, 6]],
"TP":[[0, 0.02, 1], [0.02, 0.1, 2], [0.1, 0.2, 3], [0.2, 0.3, 4], [0.3, 0.4, 5],[0.4, 100, 6]],
}
# 根据数据索引->分类映射表
remap = remapdic[Data_class]
# Check out the ArcGIS Spatial Analyst extension license
arcpy.CheckOutExtension("Spatial")
# Execute Reclassify
outReclassify = Reclassify(outExtractByMask, "Value", RemapRange(remap), "NODATA")
# Save the output
if os.path.exists(reclassdir):
os.remove(reclassdir)
outReclassify.save(reclassdir)
# 颜色映射
Reclass_temp = arcpy.AddColormap_management(outReclassify, "#",color)
# 创建图层并添加到地图中
Reclass_lyr = arcpy.MakeRasterLayer_management(Reclass_temp, "Reclasss{}layer".format(Data_class), "#", waterShp)
# Execute SaveToLayerFile
if os.path.exists(r"E:\user\Reclass{}layer.lyr".format(Data_class)):
os.remove(r"E:\user\Reclass{}layer.lyr".format(Data_class))
arcpy.SaveToLayerFile_management("Reclasss{}layer".format(Data_class), r"E:\user\Reclass{}layer.lyr".format(Data_class), "ABSOLUTE")
# 向地图中添加图层
# 设置最上面的图层作为参考图层
refLayer = arcpy.mapping.ListLayers(mxd0)[0]
# 加载图层文件
insertLayer = arcpy.mapping.Layer(r"E:\user\Reclass{}layer.lyr".format(Data_class))
# 添加图层
arcpy.mapping.InsertLayer(frames, refLayer, insertLayer, "BEFORE")
frames.extent = insertLayer.getSelectedExtent()
elTxt = arcpy.mapping.ListLayoutElements(mxd0, "TEXT_ELEMENT", "*")
#在这里我们将一些图例等采用图片的方式进行修饰,
#可以通过替换文件来时相对对应的修改,通过设置每个插入对象属性的alph/name来进行索引替换。
for item in elTxt:
if item.name == "data":
item.text = "{}".format(img_info["imgsource"])
if item.name == "date":
item.text = "影像日期:{}".format(img_info["imgdate"])
if item.name == "idname":
item.text = "水质指标:{}".format(E2C[Data_class])
elPic = arcpy.mapping.ListLayoutElements(mxd0, "PICTURE_ELEMENT", "*")
for item in elPic:
if item.name != Data_class:
item.sourceImage = PicClass[Data_class]
item.elementHeight = 0.9944
item.elementPositionX = 6.5865
item.elementPositionY = 0.3385
item.elementWidth = 7.8269
# 9.另存制图文件
arcpy.mapping.ExportToJPEG(mxd0, r"E:\user\Reclass{}layer.jpg".format(Data_class),resolution = img_info["print_res"])
mxd0.saveACopy(r"E:\user\{}.mxd".format(Data_class))
代码的整体思路如下:
1、设置工作空间
2、读取数据,并设置必要的图幅属性信息
3、执行裁剪、重分类操作,并保存数据和图层文件
4、向mxd中添加图层文件
5、图幅要素更新(文字、图片等)
6、打印文件、保存mxd
arcpy制图中栅格数据无法进行拉伸操作,据说arcgispro可以进行相关设置,但笔者在进行测试时,效果并不理想,可操作的空间有限,还有待进一步尝试。arcpy进行矢量数据与重分类数据可视化制图还是够用的,通过定义颜色表或使用已有的图层符号进行更新完全可以实现灵活的操作。