本文介紹基於Python語言中ArcPy模塊,實現ArcMap自動批量出圖,並對地圖要素進行自定義批量設置的方法。 1 任務需求 首先,我們來明確一下本文所需實現的需求。 現有通過Python基於Excel數據加以反距離加權空間插值並掩膜圖層所繪製的北京市在2019年05月18日00時至23時(其中 ...
本文介紹基於Python語言中ArcPy模塊,實現ArcMap自動批量出圖,並對地圖要素進行自定義批量設置的方法。
1 任務需求
首先,我們來明確一下本文所需實現的需求。
現有通過Python基於Excel數據加以反距離加權空間插值並掩膜圖層所繪製的北京市在2019年05月18日00時至23時(其中不含19時)等23個逐小時PM2.5濃度插值數據柵格圖層,每小時一個圖層,因此共23個圖層;以當日10時為例,該時刻的柵格圖層如下所示。
我們希望做到的有兩點。首先,我們可以看到前述23個柵格圖層的符號系統都為灰度拉伸的狀態,因此希望按照一個給定的模板圖層文件m.lyr
,調整這23個柵格圖層的樣式(即拉伸的顏色),並分別以.lyr
格式導出這23個柵格圖層文件;且希望導出圖層文件的文件名包含具體的時刻。如下圖所示。
第二點希望做到的是,將每一個柵格圖層都設置為彩色後,添加圖名、指北針、比例尺等地圖要素,並導出為圖片格式。以當日10時、20時為例,我們所希望導出的圖片如下所示。
且希望導出圖片的文件名同樣包含具體的時刻。
2 代碼實現
瞭解了需求後,我們就基於Python中的ArcPy
模塊,進行詳細代碼的撰寫與介紹。
這裡需要說明的是:在編寫代碼的時候,為了方便執行,所以希望代碼後期可以在ArcMap中直接通過工具箱運行,即用到Python程式腳本新建工具箱與自定義工具的方法;因此,代碼中對於一些需要初始定義的變數,都用到了arcpy.GetParameterAsText()
函數。大家如果只是希望在IDLE中運行代碼,那麼直接對這些變數進行具體賦值即可。關於Python程式腳本新建工具箱與自定義工具,大家可以查看ArcMap將Python寫的代碼轉為工具箱與自定義工具詳細瞭解。
上面提到需要初始定義的變數一共有七個,其中arcpy.env.workspace
參數表示當前工作空間;mxd_file
參數表示後期批量出圖時,提供地圖要素參考信息的地圖文檔.mxd
文件;lyr_file
參數表示後期批量出圖時,提供地圖著色參考信息的模板圖層.lyr
文件;mask_path
參數表示前述插值柵格圖層所保存的路徑;new_lyr_path
參數表示插值柵格圖層經過樣式修改,並轉為圖層文件後的保存路徑;png_path
參數表示最終出圖結果的保存路徑;dpi
參數表示最終出圖結果的圖像解析度,單位為DPI(Dots per Inch)。
其中,上述第二個參數,即提供地圖要素參考信息的地圖文檔.mxd
文件需要由用戶自行創建,併在其中配置好圖名、圖例、指北針、比例尺等地圖要素的名稱、文本、位置、樣式等信息。或許這麼說有點不清楚,大家看下麵這幅圖就能比較容易明白了。
沒錯,這個提供地圖要素參考信息的地圖文檔.mxd
文件其實就是一個在Layout View中設置好各種地圖要素位置、大小、字體、顏色等的地圖文檔文件;它就相當於是一個模板,這個模板里各種地圖要素長什麼樣子,後期我們批量出圖結果圖的地圖要素就長什麼樣子。
此外,不知道為什麼,在我的ArcMap中似乎偶爾會出現無法有效執行lyr.visible=False
或arcpy.mapping.RemoveLayer(data_frame,new_lyr[0])
等代碼情況;因此若直接在上述地圖文檔文件中配置圖例,最終出圖結果有時會出現多個圖例堆疊,不能保證出圖結果百分之百完美。基於此,選擇將圖例格式元素(elm.name==”title”
)轉換為由一個圖片格式元素(elm.name==”pic”
)與兩個文本格式元素(elm.name==”text”
)組成的新元素,從而實現最終結果圖中圖例的繪製。
如果大家還是不明白,可以直接下載我的這一.mxd
文件;下載鏈接:https://pan.baidu.com/s/18l0l-kjPfdjV1UYcpkKg-w?pwd=fkxx 。
具體代碼如下。
# -*- coding: utf-8 -*-
# @author: ChuTianjia
import arcpy
arcpy.env.workspace=arcpy.GetParameterAsText(0)
mxd_file=arcpy.GetParameterAsText(1)
lyr_file=arcpy.GetParameterAsText(2)
mask_path=arcpy.GetParameterAsText(3)
new_lyr_path=arcpy.GetParameterAsText(4)
png_path=arcpy.GetParameterAsText(5)
dpi=arcpy.GetParameterAsText(6)
my_mxd=arcpy.mapping.MapDocument(mxd_file)
data_frame=arcpy.mapping.ListDataFrames(my_mxd)[0]
my_lyr=arcpy.mapping.Layer(lyr_file)
layer_list=arcpy.mapping.ListLayers(my_mxd)
my_mxd.activeView="PAGE_LAYOUT"
tif_file_list=arcpy.ListRasters("BJ_hour_*","TIF")
for raster in tif_file_list:
# Import the mask layer into ArcMap
raster_file=mask_path+"\\"+raster
arcpy.MakeRasterLayer_management(raster_file,raster.strip(".tif"))
# Modify the style of the mask layer according to the reference layer
arcpy.ApplySymbologyFromLayer_management(raster.strip(".tif"),lyr_file)
new_lyr_file=new_lyr_path+"\\"+raster.strip(".tif")+".lyr"
# Save and import the mask layer after modifying the style
arcpy.SaveToLayerFile_management(raster.strip(".tif"),new_lyr_file)
arcpy.AddMessage("{0} has been saved.".format(raster.strip(".tif")+".lyr"))
new_lyr=arcpy.mapping.Layer(new_lyr_file)
arcpy.mapping.AddLayer(data_frame,new_lyr,"TOP")
# Modify the image name
for element in arcpy.mapping.ListLayoutElements(my_mxd,"TEXT_ELEMENT"):
if element.name=="title":
element.text="Interpolation Map of PM2.5 Concentration\n at {0}:00 on May 18, 2019, Beijing".format(raster[8:10])
new_lyr.visible=True
# Modify the legend (see the program usage document for details)
max_pixel=arcpy.GetRasterProperties_management(new_lyr,"MAXIMUM").getOutput(0)[0:5]
min_pixel=arcpy.GetRasterProperties_management(new_lyr,"MINIMUM").getOutput(0)[0:5]
for element in arcpy.mapping.ListLayoutElements(my_mxd,"TEXT_ELEMENT"):
if element.name=="MAX":
element.text="{:0>5.2f}".format(float(max_pixel))
if element.name=="MIN":
element.text="{:0>5.2f}".format(float(min_pixel))
# Export to picture format
png_file=png_path+"\\"+raster.strip(".tif")+".png"
arcpy.mapping.ExportToPNG(my_mxd,png_file,resolution=dpi)
arcpy.AddMessage("{0} has been saved.".format(raster.strip(".tif")+".png"))
new_lyr.visible=False
arcpy.mapping.RemoveLayer(data_frame,new_lyr[0])
3 運行結果
執行上述代碼,具體得到的結果其實在本文開頭也就和大家講了,這裡就不再贅述。
不過還有一點,就是如果大家是在ArcMap中直接通過工具箱運行上述代碼,則可以看到代碼運行過程中出現的提示——程式運行過程中,對每一個時刻的PM2.5濃度數據分別完成圖層格式保存與圖片格式保存等2個操作後,均會輸出執行結果,方便用戶獲知程式的執行情況。
至此,大功告成。