第二章 使用ArcPy編寫腳本 ||| 第四章 查找和修復數據源
我們將在本章介紹以下案例:
- 引用當前地圖文檔
- 引用磁盤上的地圖文檔
- 訪問數據框
- 獲取地圖文檔中的圖層列表
- 限制圖層列表內容
- 更改地圖顯示范圍
- 獲取表數據列表
- 向地圖文檔中添加圖層
- 向地圖文檔中插入圖層
- 更新圖層符號系統
- 更新圖層屬性
引言
ArcPy制圖模塊是ArcGIS 10新增加的功能模塊,該模塊提供了相當贊的自動化制圖功能,包括管理地圖文檔和圖層文件以及數據。制圖模塊提供了自動化地圖輸出和打印功能,可用于創建PDF地圖冊和發布ArcGIS Server地圖服務。制圖模塊對于那些需要完成的許多日常地處理任務的GIS人員是很有用的。
在本章中,你將了解如何使用ArcPy制圖模塊來管理地圖文檔和圖層文件。你會了解如何從地圖文檔文件中增加和刪除圖層和表,如何向數據框中插入圖層,如何在地圖文檔內移動圖層。最后你還會學習如何更新圖層屬性和符號化系統。
引用當前地圖文檔
當通過ArcGIS Python窗口或者自定義工具中執行地理處理腳本的時候,你通常需要獲取當前加載到ArcMap中的地圖文檔的引用地址。在腳本中這通常是對地圖文檔中的圖層和表執行地理操作前的第一步。在本案例中,你將會學習如何在Python地理處理腳本中引用當前地圖文檔。
Getting ready
對一個地圖文檔文件執行任何操作前,你首先需要在Python腳本中獲得該地圖文檔的引用地址。這一操作可通過調用arcpy.mapping
模塊中的MapDocument()
函數來實現。你可以引用當前活動的地圖文檔文件,也可以引用磁盤中的地圖文檔文件。你只要將關鍵字CURRENT
作為MapDocument()
函數的參數即可引用當前活動的地圖文檔,即當前ArcMap中打開的地圖文檔。下面的示例代碼中展示了如何獲取當前活動地圖文檔的引用:
mxd = arcpy.mapping.MapDocument("CURRENT")
當通過ArcGIS Python窗口或者自定義工具中執行地處理腳本的時候,你可以只使用
CURRENT
關鍵字。如果想在IDLE或者其他開發環境下運行腳本,使用CURRENT
關鍵字則不能訪問當前加載到ArcMap中的地圖文檔文件。CURRENT
關鍵字大小寫不敏感,你也可以寫作current
。
如果要引用本地磁盤或遠程磁盤上的地圖文檔的話,你只要將地圖文檔路徑和文件名作為MapDocument()
函數的參數即可。比如,你想要引用c:\data
文件夾下的crime.mxd
地圖文檔文件就可以使用下面的代碼:
arcpy.mapping.MapDocument("c:/data/crime.mxd")
How to do it...
按照以下步驟來學習如何獲取ArcMap中當前活動的地圖文檔:
1.使用ArcMap打開c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.點擊ArcMap主工具欄上的Python窗口按鈕。
3.在Python窗口中導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
4.上一步中的代碼下敲入以下代碼來引用當前活動的地圖文檔(Crime_Ch3.mxd
)并將該引用賦值給變量:
mxd = mapping.MapDocument("CURRENT")
5.獲取地圖文檔的標題并將結果輸出到shell窗口中。代碼執行時print
語句會將地圖文檔的標題打印到屏幕:
print mxd.title
6.為地圖文檔設置一個新的標題:
mxd.title = "Copy of Crime Project"
7.使用saveACopy()
方法保存一個地圖文檔文件的備份:
mxd.saveACopy("c:/ArcpyBook/Ch3/crime_copy.mxd")
8.運行腳本。
9.在ArcMap中打開剛才創建的crime_copy.mxd
文件,選擇文件(File)|地圖文檔屬性(Map Document Properties)來查看地圖文檔的新標題。
How it works...
MapDocument
類中的構造函數會創建該類的一個實例。在面向對象編程中,一個實例(instance)也就是通常說的一個對象(object)。MapDocument
的構造函數中的參數可以是CURRENT
關鍵字也可以是本地或者遠程磁盤上的地圖文檔文件的路徑。構造函數創建了一個對象并賦值給變量mxd
。你可以使用點標注符來獲取對象的屬性和方法。在本案例中,我們使用MapDocument.title
屬性設置并輸出地圖文檔的標題,同時我們也使用MapDocument.saveACopy()
方法保存了一個新的地圖文檔文件。
引用磁盤上的地圖文檔
除了能夠引用ArcMap中當前活動的地圖文檔文件,你還可以使用MapDocument()
函數來獲取保存在本地磁盤或遠程磁盤中的地圖文檔文件。在本案例中,你將會學習如何獲取這些地圖文檔。
Getting Ready
正如之前所述,你可以引用計算機中或在共享服務器上的地圖文檔文件。只要在MapDocument()
中提供文件的路徑就可以實現。由于該操作可以不通過ArcGIS Python窗口或自定義腳本工具來運行,因此這是獲取地圖文檔引用的更為靈活的方式。
How to do it...
按照以下步驟來學習如何訪問本地或遠程磁盤上保存的地圖文檔:
1.通過開始菜單|所有程序|ArcGIS|Python2.7|IDLE打開IDLE開發環境。
2.在IDLE窗口中選擇New|New Window創建一個新的IDLE腳本窗口。
3.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
4.引用在上一個案例中創建的crime_copy.mxd
地圖文檔:
mxd=mapping.MapDocument("c:/ArcpyBook/Ch3/crime_copy.mxd")
5.打印地圖文檔的標題:
print mxd.title
6.運行腳本可以看到如下結果顯示:
Copy of Crime Project
How it works...
本案例同前一案例唯一的區別在于我們提供了本地或遠程磁盤上的地圖文檔文件的引用地址而不是使用CURRENT
關鍵字。這也是我們推薦的引用地圖文檔文件的方式,除非你確定地理處理腳本將在ArcGIS中的Python窗口或是自定義腳本工具中執行。
訪問數據框
ArcMap的內容列表(table of content)由一個或多個數據框(data frame)組成。每一個數據框均可包含圖層和表。數據框還可以用來篩選像ListLayers()
這樣的列表函數返回的列表內容。比如說DataFrame
對象可以作為輸入參數用來限制ListLayers()
函數僅返回位于某一特定的數據框中的圖層數據。你還可以使DataFrame
對象來設置或獲取當前地圖的地理范圍,這在創建地圖冊的時候非常有用。在本案例中你將學習如何在Python腳本中訪問數據框。
Getting Ready
ListDataFrames()
會返回一個包含DataFrame
對象的列表。每一個數據框均可包含圖層和表,同時也可以作為參數用來限制ListLayers()
函數和ListTableViews()
函數返回的列表內容。
How to do it...
按照以下步驟來學習如何獲取一個地圖文檔中的數據框列表:
1.在ArcMap中打開c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.點擊ArcMap主工具欄上的Python窗口按鈕。
3.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
4.引用當前活動的地圖文檔(Crime_Ch3.mxd
)并將該引用賦值給變量:
mxd = mapping.MapDocument("CURRENT")
5.調用ListDataFrames()
函數并將地圖文檔的引用地址參數以及通配符參數傳遞給該函數,其中通配符用來查找以字母C開頭的數據框:
frames = mapping.ListDataFrames(mxd,"C*")
6.使用for
循環語句打印輸出返回的每一個數據框的名稱:
for df in frames:
print df.name
7.運行腳本將看到如下的結果的顯示:
Crime
Crime_Inset
How it works...
ListDataFrames()
函數會返回一個包含ArcMap內容列表中所有數據框的列表。跟其他的列表一樣,你可以使用for
循環語句來迭代遍歷列表中的內容。在for
循環中,每一個數據框會動態地賦值給df
變量并將數據框的名稱打印輸出到屏幕上。
獲取地圖文檔中的圖層列表
地理處理腳本中通常開始的幾個步驟中就需要獲取地圖文檔中的圖層列表。一旦獲取了圖層列表,腳本可能就要循環遍歷每一個圖層執行一些處理操作。制圖模塊中的ListLayers()
函數提供了獲取圖層列表的功能。在本案例中,你就會學習如何獲取包含在地圖文檔中的圖層列表。
Getting Ready
arcpy.mapping
模塊包含了多個列表函數用來返回圖層列表,數據框列表,損壞數據源列表,表單視圖列表以及頁面元素列表。這些列表函數通常是多步驟處理中的第一步,多步驟處理腳本中往往需要獲取一個或多個列表元素來執行下一步的處理。每一個列表函數都會返回一個Python列表,你已經在前面的內容了解到列表是保存信息一種非常高效的數據結構。
列表函數通常是多步驟處理中的一部分,而在這些處理過程中創建列表僅僅只是開始。在腳本中,后續的處理步驟會迭代列表中一個或多個元素。比如你可能先獲取一個地圖文檔中的圖層列表,之后遍歷所有圖層來查找一個指定的圖層名稱,隨后會進行下一步的處理過程。
在本案例中,你將學習如何獲取地圖文檔文件中的圖層列表。
How to do it...
按照以下步驟來學習如何獲取地圖文檔文件中的圖層列表:
1.在ArcMap中打開c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.點擊ArcMap主工具欄上的Python窗口按鈕。
3.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
4.引用當前活動的地圖文檔(Crime_Ch3.mxd
)并將該引用賦值給變量:
mxd = mapping.MapDocument("CURRENT")
5.調用ListLayers()
函數并將地圖文檔的引用地址參數傳遞給該函數:
layers = mapping.ListLayers(mxd)
6.使用for
循環語句打印輸出地圖文檔中每一個圖層的名稱:
for lyr in layers:
print lyr.name
7.運行腳本將看到如下結果顯示:
Burglaries in 2009
Crime Density by School District
Bexar County Boundary
Test Performance by School District
Bexar County Boundary
Bexar County Boundary
Texas Counties
School_Districts
Crime Surface
Bexar County Boundary
How it works...
ListLayers()
函數返回地圖文檔中,或指定的數據框中或圖層文件中的圖層列表。在本案例中我們將當前的地圖文檔的引用傳遞給ListLayers()
函數,該函數將獲取地圖文檔中的圖層列表。返回的結果被保存在變量layers
中,該變量是一個包含了一個或多個Layer
對象的Python列表,可使用for
循環語句進行迭代遍歷。
There's more...
ListLayers()
函數只是arcpy.mapping
模塊提供的眾多列表函數中的一個。每一個列表函數返回一個包含某類型數據的Python列表。其他列表函數中包括返回Table
對象的ListTableViews()
函數,返回DataFrame
對象的ListDataFrames()
函數以及返回地圖文檔中書簽列表的ListBookmarks()
函數。本書后面的章節中會介紹其他大部分內容。
限制圖層列表內容
在上一個案例中,你學習了如何使用ListLayers()
函數獲取圖層列表。有時候你不需要地圖文檔中的所有圖層,而只需要這些圖層中的一部分。ListLayers()
函數允許限制生成的圖層列表內容。在本案例中,你將學習如何使用通配符和指定的數據框來限制返回的圖層。
Getting Ready
默認情況下,如果你只傳遞一個地圖文檔或圖層文件的引用參數,ListLayers()
函數會返回包含所有圖層的列表。不過你可以在函數中使用可選的通配符參數或者傳遞指定的數據框的引用參數來限制返回的圖層列表內容。
如果你處理的對象為圖層文件(.lyr),那么就不能使用數據框參數來限制返回結果。因為圖層文件不支持數據框。
在本案例中,你將學習如何使用通配符和數據框參數來限制ListLayers()
函數返回的圖層列表內容。
How to do it...
按照以下步驟來學習如何限制返回的地圖文檔中的圖層列表內容:
1.在ArcMap中打開c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.點擊ArcMap主工具欄上的Python窗口按鈕。
3.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
4.引用當前活動的地圖文檔(Crime_Ch3.mxd
)并將該引用賦值給變量:
mxd = mapping.MapDocument("CURRENT")
5.獲取地圖文檔中的數據框列表并查找一個名稱Crime
的數據框。注意文本字符串一定要包含在單引號或者雙引號之內:
for df in mapping.ListDataFrames(mxd):
if (df.name == 'Crime'):
6.調用ListLayers()
函數并將地圖文檔的引用參數,用于限制查找范圍的通配符參數以及數據框參數傳遞給該函數,其中數據框參數在本案例中位上一步指定的數據框。ListLayers()
函數一定要在上一步的if
語句的縮進范圍內:
layers = mapping.ListLayers(mxd,'Burg*',df)
7.使用for
循環語句打印輸出返回的每一個圖層名稱:
for layer in layers:
print layer.name
8.完整代碼如下:
import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
for df in mapping.ListDataFrames(mxd):
if (df.name == 'Crime'):
layers = mapping.ListLayers(mxd,'Burg*',df)
for layer in layers:
print layer.name
9.運行腳本將看到如下結果顯示:
Burglaries in 2009
How it works...
你在前面的案例中了解到ListDataFrames()
函數是arcpy.mapping
提供的一個列表函數。該函數返回一個包含地圖文檔中所有的數據框的列表。之后我們循環遍歷返回的數據框列表來查找名稱為Crime
的數據框。如果找到了符合條件的數據框,我們就可以調用ListLayers()
函數,同時使用一個通配符"Burg*"作為該函數的第二個參數以及Crime
數據框的引用參數。其中通配符(*
)匹配任何數量的字符。
在本案例中,我們查找Crime
數據框中所有以Burg
開頭的圖層。任何滿足條件的圖層會顯示到屏幕中。值得注意的是,我們在本案例中只是打印輸出了圖層名稱,然而在大多數情況下你需要調用其他工具或其他函數來執行其他地理處理任務。
更改地圖顯示范圍
在很多情況下,比如當你進行自動化制圖過程中需要創建許多不同范圍或要素地圖的時候,就會需要更改地圖的顯示范圍。利用arcpy
,你就可以通過多種方式來更改地圖顯示范圍。在本案例中,我們將學習如何使用條件查詢表達式來更改地圖顯示范圍。
Getting Ready
你可以使用DataFrame
類中的extent
屬性來設置地理范圍。它通常與
Layer.definitionQuery
屬性一起使用,其中的definitionQuery
屬性來定義一個圖層的查詢條件。在本案例中,你會學習如何使用這些對象和屬性來更改地圖顯示范圍。
How to do it...
按照以下步驟來學習如何更改圖層的地圖顯示范圍:
1.在ArcMap中打開c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.點擊ArcMap主工具欄上的Python窗口按鈕。
3.導入arcpy.mapping模塊:
import arcpy.mapping as mapping
4.引用當前活動的地圖文檔(Crime_Ch3.mxd
)并將該引用賦值給變量:
mxd = mapping.MapDocument("CURRENT")
5.創建for
循環語句來循環遍歷地圖文檔中的所有數據框:
for df in mapping.ListDataFrames(mxd):
6.找到名稱為Crime
的數據框并指定一個圖層來應用自定義查詢條件語句:
if (df.name == 'Crime'):
layers = mapping.ListLayers(mxd,'Crime Density by School District',df)
7.創建for
循環語句來循環遍歷返回的圖層。在for
循環語句中,我們還創建一個自定義查詢語句并設置數據框新的顯示范圍:
for layer in layers:
query = '"NAME" = \'Lackland ISD\''
layer.definitionQuery = query
df.exent = layer.getExtent()
8.完整代碼如下:
import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
for df in mapping.ListDataFrames(mxd):
if (df.name == 'Crime'):
layers = mapping.ListLayers(mxd,'Crime Density by School District',df)
for layer in layers:
query = '"NAME" = \'Lackland ISD\''
layer.definitionQuery = query
df.extent = layer.getExtent()
9.保存并運行腳本。數據視圖(data view)中顯示的范圍更新至滿足查詢條件的要素的范圍,如下圖所示:
How it works...
在本案例中,我們針對圖層使用定義表達式更新了地圖顯示范圍。在臨近腳本結束位置,創建了一個新的變量query
來保存定義表達式。定義表達式來查找名稱為Lackland ISD
的學區。該查詢字符串賦值給definitionQuery
屬性。最后df.extent
屬性設置為layer.getExtent()
值。
獲取表數據列表
arcpy.mapping
模塊還提供了一個ListTableViews()
函數用于返回地圖文檔中表數據列表。在本案例中,你會學習如何使用ListTableViews()
函數來創建表數據列表。
Getting Ready
arcpy.mapping
模塊除了提供能夠返回地圖文檔或數據框中圖層列表的函數之外,還提供了一個ListTableViews()
函數來生成表數據列表。
ListTableViews()
函數只處理包含表數據的地圖文檔文件和數據框。圖層文件(.lyr)中不能包含表數據。
How to do it...
按照以下步驟來學習如何獲取地圖文檔中的表數據列表:
1.在ArcMap中打開c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.點擊ArcMap主工具欄上的Python窗口按鈕。
3.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
4.引用當前活動的地圖文檔(Crime_Ch3.mxd
)并將該引用賦值給變量:
mxd = mapping.MapDocument("CURRENT")
5.獲取地圖文檔中的表數據列表:
for tableview in mapping.ListTableViews(mxd):
print tableview.name
6.運行腳本將看到如下結果顯示:
Crime2009Table
How it works...
ListTableViews()
函數非常類似于arcpy.mapping
模塊提供的其他列表函數。正如ListLayers()
案例中一樣,ListTableViews()
函數也接受一個地圖文檔引用參數(不能引用圖層文件)以及可選的通配符參數和數據框參數。該函數返回的表數據列表可使用for
循環進行迭代。
向地圖文檔中添加圖層
很多情況下,你需要向地圖文檔文件中添加一個圖層。制圖模塊中的AddLayer()
函數提供該功能。在本案例中,你將學習如何使用AddLayer()
函數向地圖文檔中添加圖層。
Getting Ready
arcpy.mapping
模塊提供了向現有地圖文檔文件中添加圖層或圖層組的功能。你可以利用ArcMap的“自動排列”(auto-arrange)功能,該功能會自動安排數據框中的圖層位置。這與通過ArcMap中的添加數據(Add Data)按鈕的功能一樣,數據框中的圖層位置基于幾何類型和圖層權重規則來確定。
不能向圖層文件中(
.lyr
)添加圖層
向地圖文檔中添加圖層時,該圖層必須引用已有的圖層文件中的圖層,可以是同一地圖文檔或同一數據框中的圖層,也可以是同一地圖文檔不同數據框中的圖層或者完全不同的地圖文檔中的圖層。圖層可以是地圖文檔中的圖層也可以是.lyr
文件中的圖層。如果想向一個地圖文檔中添加圖層,你必須首先創建一個Layer
類的實例之后再調用AddLayer()
函數,并將圖層要放置的數據框引用參數和位置規則參數傳遞給該函數。
How to do it...
按照以下步驟來學習如何向地圖文檔中添加圖層:
1.在ArcMap中打開c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.點擊ArcMap主工具欄上的Python窗口按鈕。
3.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
4.引用當前活動的地圖文檔(Crime_Ch3.mxd
)并將該引用賦值給變量:
mxd = mapping.MapDocument("CURRENT")
5.獲取Crime
數據框的引用,該數據框是ListDataFrames()
函數返回的數據框列表中的第一個元素。語句最后的[0]
指定ListDataFrames()
返回的數據框列表的第一個元素。列表是從零值開始索引,因為我們使用索引值0
來訪問第一個元素。
df = mapping.ListDataFrames(mxd)[0]
6.通過引用一個.lyr
文件來創建一個Layer
對象。
layer = mapping.Layer(r"c:\ArcpyBook\data\School_Districts.lyr")
7.向數據框中添加圖層:
mapping.AddLayer(df,layer,"AUTO_ARRANGE")
8.運行腳本。School_Districts.lyr
文件就添加到數據框中,如下圖所示:
How it works...
在開始的兩行中,我們導入了arcpy.mapping
模塊并獲取了當前活動的地圖文檔的引用。接下來我們創建了一個新的變量df
用來保存Crime
數據框的引用地址。該引用地址通過ListDataFrames()
函數來獲取。之后我們使用列表索引值來訪問返回的數據框列表中的第一個元素即Crime
數據框。通過一個School_Districts.lyr
的圖層文件,我們創建了一個變量名為layer
的Layer
對象實例。最后我們調用了AddLayer()
函數,并將圖層要放置的數據框引用參數以及用來指定AUTO_ARRANGE位置參數傳遞給該函數。除了自動排列之外,我們還可以使用BOOTOM
或TOP
關鍵字參數來指定將圖層放置在數據框的底層或者頂層位置。
There's more...
arcpy.mapping
模塊除了提供了向地圖文檔中添加圖層的功能,還提供了一個
AddLayerToGroup()
函數,該函數可用于向圖層組中添加圖層。圖層可以添加到圖層組中的頂層或頂層位置,也可以使用自動排列來放置圖層。你還可以向一個空的圖層組中添加圖層。不過跟其他常規的圖層對象一樣,圖層組不能添加到圖層文件中。
向地圖文檔中插入圖層
AddLayer()
函數可用來向地圖文檔中添加圖層,添加進來的圖層在數據框中的位置可以根據ArcMap提供的自動排列的位置,也可以是數據框中的頂層或底層位置。不過,該函數并沒有提供將圖層插入到數據框中的指定位置的控制機制。對于這樣情況,你可以使用InsertLayer()
函數來實現。在本案例中,你將學習如何將圖層添加到數據框中的指定位置。
Getting Ready
AddLayer()
函數只是簡單地將圖層添加到一個數據框或者圖層組中,要么利用自動排列來放置圖層要么將圖層放置在數據框或圖層組的頂部或末端特定位。InsertLayer()
函數允許將新添加到數據框或圖層組中的圖層放置在更為精準的位置。該函數使用一個參考圖層來指定一個位置,可以在代碼中指明圖層是插入到該參考位置的前面還是后面。由于InsertLayer()
函數需要使用一個參考圖層,因此你不能在空的數據框下使用該函數。
下圖可以說明InsertLayer()
的工作模式,圖中的District_Crime_Join
圖層是參考圖層,School_Districts
是要添加進來的圖層。調用InsertLayer()
可以將School_Districts
圖層放置到參數圖層的前面或者后面。
How to do it...
按照以下步驟來學習如何調用InsertLayer()
函數向數據框中插入圖層:
1.在ArcMap中打開c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.點擊ArcMap主工具欄上的Python窗口按鈕。
3.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
4.引用當前活動的地圖文檔(Crime_Ch3.mxd
)并將該引用賦值給變量:
mxd = mapping.MapDocument("CURRENT")
5.獲取Crime
數據框的引用:
df = mapping.ListDataFrames(mxd,"Crime")[0]
6.定義一個參考圖層:
refLayer = mapping.ListLayers(mxd,"Burglaries*",df)[0]
7.定義一個要插入的圖層:
insertLayer=mapping.Layer(r"c:\ArcpyBook\data\CityOfSanAntonio.gdb\Crimes2009")
8.向數據框中插入圖層:
mapping.InsertLayer(df,refLayer,insertLayer,"BEFORE")
9.運行腳本。如下圖所示Crimes2009
要素類添加到數據框中:
How it works...
導入arcpy.mapping
模塊并獲取當前地圖文檔文件和Crime
數據框的引用之后,之后我們定義了一個參考圖層。在本案例中,我們調用ListLayers()
函數以及“Burglaries*”
通配符參數和Crime
數據框參數來限制返回的數據列表中只有一個元素。該元素即Burglaries in 2009
圖層。我們使用索引值0
來訪問返回的列表中的Burglaries in 2009
圖層并賦值給一個Layer
對象變量。接下來,我們定義一個插入圖層,該圖層是一個新的Layer
對象,該圖層對象引用了CityOfSanAntonio
地理數據庫中的Crimes2009
要素類。最后,我們調用了InsertLayer()
函數并將數據框,參考圖層,插入圖層以及插入位置關鍵字參數傳遞給該函數。結果如下圖所示:
There's more...
你還可以重新調整已經在數據框或圖層組中的圖層的位置。MoveLayer()
函數提供了這樣的功能。圖層的移動必須是在同一個數據框中進行。你不能將圖層從一個數據框移動到另一個數據框中。跟InsertLayer()
一樣,MoveLayer()
也使用一個參考圖層來定義調整圖層的位置。
更新圖層符號系統
也許有時候,你需要更改地圖文檔中某個圖層的符號系統。該操作可以使用
UpdateLayer()
函數來完成,該函數用來更改圖層的符號系統以及圖層的其他屬性。在本案例中,你將會使用UpdateLayer()
函數來更新圖層的符號系統。
Getting ready
arcpy.mapping
模塊中的UpdateLayer()
函數可以在腳本中用來更新圖層的符號系統。舉個例子,如下圖示你可能想通過腳本將圖層的符號系統系統由漸變色更改為漸變符號。UpdateLayer()
函數還可以用于更新其他的圖層屬性,其默認功能是更新符號系統屬性。由于UpadateLayer()
是一個功能強大的函數,可以修改符號系統和其他屬性,因此你需要理解多個輸入參數的意義。
How to do it...
按照以下步驟來學習如何調用UpdateLayer()
函數來更新圖層的符號系統:
1.在ArcMap中打開c:\ArcpyBook\Ch3\Crime_Ch3.mxd
文件。
2.點擊ArcMap主工具欄上的Python窗口按鈕。
3.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
4.引用當前活動的地圖文檔(Crime_Ch3.mxd
)并將該引用賦值給變量:
mxd = mapping.MapDocument("CURRENT")
5.獲取Crime
數據框的引用:
df = mapping.ListDataFrames(mxd,"Crime")[0]
6.定義將要更新的圖層:
updateLayer = mapping.ListLayer(mxd,"Crime Density by School District",df)[0]
7.定義用于更新符號系統的圖層:
sourceLayer =mapping.Layer(r"C:\ArcpyBook\data\CrimeDensityGradSym.lyr")
8.調用UpdateLayer()
函數更新符號系統:
mapping.UpdateLayer(df,updateLayer,sourceLayer,True)
9.運行腳本。如下圖所示,Crime Density by School District
圖層會使用漸變符號來替代漸變色。
How it works...
在本案例中,我們使用UpdateLayer()
函數更新了圖層的符號系統。我們并沒有更改其他屬性,不過我們將在下一個案例中會涉及更改其他屬性的內容。UpdateLayer()
函數需要以下幾個參數,包括更新圖層所在的數據框,更新圖層以及參考源圖層,其中參考源圖層的符號系統將會應用到更新圖層中。在我們的代碼中,updataLayer
變量引用了要進行符號系統更新的圖層Crime Density by School District。參考源圖層是一個圖層文件(CrimeDensityGradSym.lyr
),該圖層中的漸變符號系統將會應用到更新圖層中。
如果要更新一個圖層的符號系統,你必須首先保證更新圖層和參考源圖層具有相同的幾何類型(點,線或面)。考慮到渲染器的因素,你還需要核實更新圖層和源圖層的屬性定義是否一致。比如,漸變色符號系統和漸變符號系統都是基于一個特定的屬性字段。在本案例中,兩個圖層都是多邊形且都包含一個犯罪案發密度信息的CrimeDens
字段。
一旦獲取更新圖層和源圖層后,我們就可以調用UpdateLayer()
函數并將數據框參數以及兩個圖層參數和第四個參數傳遞給該函數,其中第四個參數用來指明我們只更新符號系統屬性。我們將第四個參數設置為True
,即說明我們只要求更新符號系統而不更新其他屬性。
mapping.UpdateLayer(df,updateLayer,sourceLayer,True)
There's more...
UpdateLayer()
還可以刪除圖層并在該位置添加一個新圖層。刪除的圖層和添加的圖層是完全無關的,因此當重新定義圖層符號系統時也就不需要保證兩個圖層具有相同的幾何類型以及相同的屬性字段。圖層的這種轉換實際上相當于把先調用RemoveLayer()
函數再調用AddLayer()
函數的兩個操作合并為一個操作來執行。要使用此功能,你必須將symbology_only
參數設置為False
。
更新圖層屬性
在前一個案例中,你學習了如何更新一個圖層的符號系統。正如我前面提到的,UpdateLayer()
函數還可以用來更新圖層的其他屬性,比如字段別名,定義查詢及其他屬性。在本案例中,你將使用UpdateLayer()
函數來更改圖層的多個屬性。
Getting ready
你還可以使用UpdateLayer()
函數來更新一部分圖層屬性。調用UpdateLayer()
函數可以更新包括像字段別名,選擇符號,定義查詢,標注字段及其他一些特定的圖層屬性。同一個圖層出現在多個地圖文檔中是常見的情況,在這種情況下要對所有地圖文檔中該圖層的某一屬性進行變更。如果要完成這一任務,你需要在ArcMap中修改該圖層的屬性后保存為一個圖層文件。該圖層文件會作為參考源圖層來更新其他需要更新圖層的屬性。在本案例中,你將會使用ArcMap來修改一個圖層的屬性,之后保存為圖層文件(.lyr
),然后編寫Python腳本調用UpdateLayer()
函數來應用到其他圖層中。
How to do it...
按照以下步驟來學習如何使用UpdateLayer()
來更改圖層屬性:
1.在ArcMap中打開c:\Arcpybook\Ch3\Crime_Ch3.mxd
。在本案例中,我們將處理Burglaries in 2009要素類,如下圖所示:
2.雙擊Crime數據框下的Burglaries in 2009要素彈出圖層屬性對話框(Layer Properties)(如下圖所示)。每一個選項卡中的屬性都可以設置:
3.點擊常規(General)選項卡,將圖層名稱(Layer Name)中信息按照下圖修改:
4.點擊定義查詢(Definition Query)選項卡,按照下圖定義查詢條件語句。你可以使用查詢構造器(Query Builder)來定義查詢語句也可以直接輸入條件語句:
5.如下圖所示將OFFDESC
字段別名修改為Offense Description
。
6.點擊圖層屬性對話框(Layer Properties)中的字段(Field)選項卡,按照下圖所示將勾選的字段設為可見。
7.點擊OK按鈕,關閉圖層屬性對話框(Layer Properties)。
8.右鍵單擊Burlaries-No Forced Entry圖層選擇另存為圖層文件(Save as Layer File)。
9.將文件保存為c:\Arcpybook\data\BurglariesNoForcedEntry.lyr
。
10.右鍵單擊Burlaries-No Forced Entry圖層選擇移除(Remove)。
11.使用添加數據(Add Data)按鈕,添加CityOfSanAntonio
地理數據庫中的Crime2009要素類數據。如下圖所示,該要素類添加到數據框中:
12.打開ArcMap中的Python窗口。
13.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
14.引用當前活動的地圖文檔(Crime_Ch3.mxd
)并將該引用賦值給變量:
mxd = mapping.MapDocument("CURRENT")
15.獲取Crime
數據框的引用:
df = mapping.ListDataFrames(mxd,"Crime")[0]
16.定義要更新屬性圖層:
updateLayer = mapping.ListLayer(mxd,"Crime2009",df)[0]
17.定義用于更新屬性的圖層:
sourceLayer=mapping.Layer(r"c:\Arcpybook\data\BurglariesNoForcedEntry.lyr")
18.調用UpdateLayer()
函數來更新屬性:
mapping.UpdateLayer(df,updateLayer,sourceLayer,False)
19.運行腳本。
20.如下圖所示,Crime2009圖層屬性會更新為BurglariesNoForcedEntry.lyr
文件中的屬性。我們可以看到圖層的定義查詢條件也已經應用。你還可以打開圖層屬性對話框(Layer Properties)來查看已經應用到Crime2009圖層中的屬性更新: