第三章 管理地圖文檔和圖層 ||| 第五章 自動化地圖生產和打印
我們將在本章介紹以下案例:
- 查找地圖文檔和圖層文件中損壞的數據源
- 調用MapDocument.findAndReplaceWorkspacePaths()方法修復損壞的數據源
- 調用MapDocument.replaceWorkspaces()方法修復損壞的數據源
- 調用replaceDataSource()方法修復單個圖層和表
- 查找文件夾中所有地圖文檔中損壞的數據源
引言
GIS數據的移動,格式轉換以及刪除等操作是很普遍的情況。這些操作過程會導致許多地圖文檔或圖層文件中數據源損壞。這些受損的數據源修復之后才能正常使用,如果涉及到大量的地圖文檔,修復數據源將會是一個巨大的工程。你可以使用arcpy.mapping
模塊來自動化完成損壞數據源的查找和修復工作,而且不用打開受影響的地圖文檔。使用ListBrokenDataSources()
函數來查找損壞的數據源是一個簡單的處理過程,該函數返回一個包含地圖文檔或者圖層文件中所有損壞的數據源列表。在腳本中通常會先調用ListBrokenDataSources()
函數,之后迭代返回的列表數據并修復數據源。修復損壞的數據源的工作既可以針對單獨的數據圖層也可以針對一個工作空間內的所有圖層。
查找地圖文檔和圖層文件中損壞的數據源
數據源損壞是地圖文檔中常見問題。你可以使用arcpy.mapping
模塊來查找已經移動或刪除或轉換格式的數據源。
Getting ready
在ArcMap中,數據源損壞的圖層會在圖層名稱前面用紅色感嘆號來標識(如下圖所示)。arcpy.mapping
模塊中的ListBrokenDataSources()
函數會返回地圖文檔或圖層文件中受損的圖層對象列表:
How to do it...
按照以下步驟來學習如何查找地圖文檔文件中的損壞的數據源:
1.在ArcMap中打開C:\ArcpyBook\Ch4\Crime_BrokenDataLinks.mxd
。
你會看到該文檔中的所有圖層的數據源都已經損壞。在本案例中,地圖文檔中的數據移動到了其他文件夾中,數據刪除或者轉換為其他格式的話,你也會看到相同的提示符號。比如說,數據從個人地理數據庫中遷移到文件地理數據庫:
2.關閉ArcMap。
3.打開IDLE,創建一個新的腳本窗口。
4.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
5.引用Crime_BrokenDataLinks.mxd
地圖文檔:
mxd=mapping.MapDocument(r"c:\ArcpyBook\Ch4\Crime_BrokenDataLinks.mxd")
6.獲取損壞數據源列表:
lstBrokenDS = mapping.ListBrokenDataSources(mxd)
7.迭代列表并打印圖層名稱:
for layer in lstBrokenDS:
print layer.name
運行結果如下:
District_Crime_Join
Bexar_County_Boundary
District_Crime_Join
Bexar_County_Boundary
Bexar_County_Boundary
Texas_Counties_LowRes
School_Districts
Crime_surf
Bexar_County_Boundary
Crime2009Table
8.腳本保存為c:\ArcpyBook\Ch4
文件夾下的FindFixBrokenData.py
。
How it works...
ListBrokenDataSources()
函數返回一個損壞數據源的圖層列表。我們可以使用for
循環語句迭代列表內容并對每個圖層執行操作。在本案例中,我們只是簡單地顯示圖層名稱來說明函數返回的數據情況。在下一個案例中,我們將編寫腳本來修復這些損壞的數據源。
There's more...
ListBrokenDataSources()
函數不僅可以返回地圖文檔中損壞的數據源圖層列表,還可以查找圖層文件(.lyr
)中損壞的數據源。只要簡單地將圖層文件的路徑參數傳遞給該函數就可以查看該圖層文件中是否存在損壞的數據源。需要說明一點的是打包好的地圖文檔或圖層文件不需要這些函數來查找損壞的數據源,這是因為不同于圖層文件,這類文件和數據是綁定在一起的。
調用MapDocument.findAndReplaceWorkspacePaths()方法修復損壞的數據源
MapDocument.findAndReplaceWorkspacePaths()
方法用于在地圖文檔中進行全局查找并替換所有圖層和表的工作空間路徑。你還可以一次替換多個工作空間類型的路徑。
Getting ready
我們在學習修復數據集的方法前需要先介紹幾個概念。你會發現涉及到修復損壞數據源的方法的時候,這些術語會經常提起,因此你需要理解在這些概念的含義。工作空間(workspace)可以簡單地理解為數據的容器。它可以是一個文件夾(針對shapefile文件來說),個人地理數據庫,文件地理數據庫或是ArcSDE連接。工作空間路徑(workspace path)是工作空間的系統路徑。對于地理空間數據庫來說,工作空間路徑是包含地理數據庫的名稱在內的。數據集(dataset)則可以簡單地理解為工作空間內的要素類或是表,而數據源(data source)則是工作空間和數據集的組合。不要混淆數據集和要素數據集兩個概念,前者只是針對數據來說的一個籠統的概念,而后者則是地理數據庫中的一個對象,作為要素類或其他數據集的容器。
arcpy.mapping
中有三個與修復受損數據源相關的類,分別是MapDocument
類,Layer
類以及TableView
類。每一個類中包含的方法都可以用于修復數據源。在本案例中,我們將看一下如何使用MapDocument
類中的findAndReplaceWorkspacePaths()
方法對地圖文檔中的圖層和表執行全局的查找和替換操作。
How to do it...
按照以下步驟來學習如何使用findAndReplaceWorkspacePaths()
方法來修復地圖文檔中的圖層和表:
1.在ArcMap中打開C:\ArcpyBook\Ch4\Crime_BrokenDataLinks.mxd
。
2.右鍵單擊任意圖層選擇屬性(Properties)。
3.點擊源(Source)選項卡,你會注意到該圖層引用的位置為
C:\ArcpyBook\Ch4\Data\OldData\CityOfSanAntonio.gdb
。文件地理數據庫位置已經不存在了;數據已經移至C:\ArcpyBook\data
文件夾中了。
4.打開IDLE,創建一個新的腳本窗口。
5.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
6.引用Crime_BrokenDataLinks.mxd
地圖文件文件:
mxd=mapping.MapDocument(r"c:\ArcpyBook\Ch4\Crime_BrokenDataLinks.mxd")
7.使用findAndReplaceWorkspacePaths()
方法來修復該地圖文檔中所有數據源的路徑:
mxd.findAndReplaceWorkspacePaths(r"C:\ArcpyBook\Ch4\OldData\CityOfSanAntonio.gdb",r"C:\ArcpyBook\data\CityOfSanAntonio.gdb")
8.保存為一個新的mxd
文件:
mxd.saveACopy(r"C:\ArcpyBook\Ch4\Crime_DataLinksFixed.mxd")
9.腳本保存為C:\ArcpyBook\Ch4\MapDocumentFindReplace.py
。
10.運行腳本。
11.在ArcMap中打開C:\ArcpyBook\Ch4\Crime_DataLinksFixed.mxd
文件。如下圖所示,所有的數據源已經修復完成:
How it work...
MapDocument.findAndReplaceWorkspacePaths()
方法用于在地圖文檔中進行全局查找并替換所有圖層和表的工作空間路徑。你還可以一次替換多個工作空間類型的路徑。
There's more...
Layer
類和TableView
類同樣可以使用findAndReplaceWorkspacePaths()
方法來執行相同的操作。對于Layer
和TableView
對象來講,該方法用于修復地圖文檔文件中的單個損壞的數據源而不進行全局查找和替換。
使用MapDocument.replaceWorkspaces()方法修復損壞的數據源
在GIS操作課程中,數據從一種工作空間類型遷移到其他類型是相當普遍的操作。比如,許多組織機構會將數據從舊的個人地理數據庫中遷移到新的文件地理數據庫甚至是企業級的ArcSDE地理數據庫中。你可以使用MapDocument.replaceWorkspaces()
方法來自動化完成數據集更新至不同工作空間類型中的工作。
Getting ready
MapDocument.replaceWorkspaces()
方法與MapDocument.findAndReplaceWorkspacePaths()
方法類類似,不過前者允許更改工作空間類型。比如,你可以從一個文件地理數據庫中轉為個人地理數據庫。不過一次操作只能針對一個工作空間。在本案例中,我們將使用MapDocument.replaceWorkspaces()
方法將數據源從文件地理數據庫轉至個人地理數據庫。
How to do it...
按照以下步驟來學習如何使用MapDocument.replaceWorkspaces()
來修復損壞的數據源:
1.在ArcMap中打開C:\ArcpyBook\Ch4\Crime_DataLinksFixed.mxd
。
2.如下圖所示,注意到所有的圖層和表位于一個叫CityOfSanAntonio.gdb
的文件地理數據庫中:
3.打開IDLE,創建一個新的腳本窗口。
4.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
5.引用Crime_BrokenLinksFixed.mxd
文件:
mxd=mapping.MapDocument(r"C:\ArcpyBook\Ch4\Crime_DataLinksFixed.mxd")
6.調用replaceWorkspaces()
方法,并將新舊地理數據庫類型關鍵字參數傳遞給該方法:
mxd.repalceWorkspaces(r"C:\ArcpyBook\data\CityOfSanAntonio.gbd","FILEGDB_WORKSPACE",r"C:\ArcpyBook\new_data\CityOfSanAntonio_Personal.mdb","ACCESS_WORKSPACE")
7.保存為一個新的mxd
文件:
mxd.saveACopy(r:"C:\ArcpyBook\Ch4\Crime_DataLinksUpdated.mxd")
8.腳本保存為C:\ArcpyBook\Ch4\MapDocumentReplaceWorkspace.py
。
9.運行腳本。
10.在ArcMap中打開C:\ArcpyBook\Ch4\Crime_DataLinksUpdated.mxd
文件。如下圖所示,所有的數據源已經位于個人地理數據庫中(擴展名為.mdb
):
How it work...
MapDocument.replaceWorkspaces()
方法接受的參數中包括新舊工作空間的路徑以及工作空間類型。工作空間路徑不言而喻,工作空間類型方面還是很有必要多闡述一下。工作空間類型是以字符串關鍵字(string keyword)的形式傳遞給方法。在本案例中,舊的工作空間類型為文件地理數據庫因此使用了關鍵字FILEGDB_WORKSPACE
。新的工作空間類型的關鍵字為ACCESS_WORKSPACE
來表示個人地理數據庫。個人地理數據庫是存儲在Mircrosoft的ACCESS文件中。還有一些不同的工作空間類型可以存儲GIS數據。你要確保提供的工作空間類型與你的數據集相匹配。下面列出了一些可用的工作空間類型(許多人仍然會使用shapefile文件,這類文件的工作空間類型為SHAPEFILE_WORKSPACE
):
-
ACCESS_WORKSPACE
:個人地理數據庫或Access工作空間 -
ARCINFO_WORKSPACE
:Arcinfo coverage工作空間 -
CAD_WORKSPACE
:CAD文件工作空間 -
EXCEL_WORKSPACE
:Excel文件工作空間 -
FILEGDB_WORKSPACE
:文件地理數據庫工作空間 -
NONE
:用于忽略該參數 -
OLEDB_WORKSPACE
:OLE數據庫工作空間 -
PCCOVERAGE_WORKSPACE
:PC ARC/INFO Coverage工作空間 -
RASTER_WORKSPACE
:柵格工作空間 -
SDE_WORKSPACE
:SDE地理數據庫工作空間 -
SHAPEFILE_WORKSPACE
:shapefile文件工作空間 -
TEXT_WORKSPACE
:文本文件工作空間 -
TIN_WORKSPACE
:TIN工作空間 -
VPF_WORKSPACE
:VPF工作空間
調用replaceDataSource()方法修復單個圖層和表
本章前面幾個案例介紹了針對MapDocument
對象中用來修復數據鏈接的幾種方法。Layer
對象和TableView
對象同樣包含可用于修復數據鏈接的方法,不過這些方法只針對單個對象而不能作用于地圖文檔中的所有數據集。
Getting ready
Layer
類和TableView
類都有一個replaceDataSource()
方法。該方法針對單個圖層或表來更改工作空間路徑,工作空間類型以及數據集名稱。在本案例中,你將編寫腳本來更改某個圖層的工作空間路徑和類型。replaceDataSource()
方法適用于Layer
類和TableView
類。對于圖層而言,既可以是地圖文檔中的圖層也可以是圖層文件中的圖層。由于表不能包含在圖層文件中,對表來講只能是地圖文檔中的表。
How to do it...
按照以下步驟來學習如何使用replaceDataSource()
方法來修復地圖文檔中單個Layer
對象和TableView
對象:
1.在ArcMap中打開C:\ArcpyBook\Ch4\Crime_DataLinksLayer.mxd
文件。Crime數據框中包含一個Burglary的圖層,該圖層數據是位于CityOfSanAntonio
文件地理數據庫中的一個要素類。你要用一個包含相同數據的shapefile文件來替換該要素類:
2.打開IDLE,創建一個新的腳本窗口。
3.導入arcpy.mapping
模塊:
import arcpy.mapping as mapping
4.引用Crime_DataLinksLayer.mxd
文件:
mxd=mapping.MapDocument(r"C:\ArcpyBook\Ch4\Crime_DataLinksLayer.mxd")
5.獲取Crime
數據框引用:
df = mapping.ListDataFrames(mxd,"Crime")[0]
6.查找Burglary
圖層并保存在一個變量中:
lyr = mapping.ListLayers(mxd,"Burglary",df)[0]
7.針對獲取的Layer
對象調用replaceDataSource()
方法,并將shapefile文件的引用路徑參數,shapefile工作空間類型的關鍵字參數以及shapefile文件名稱傳遞給該方法:
lyr.replaceDataSource(r:"C:\ArcpyBook\data","SHAPEFILE_WORKSPACE","Burglaries_2009")
8.保存為一個新的地圖文檔文件:
mxd.saveACopy(r"C:\ArcpyBook\Ch4\Crime_DataLinksNewLayer.mxd")
9.腳本保存為C:\ArcpyBook\Ch4\LayerReplaceDataSource.py
。
10.運行腳本。
11.在ArcMap中打開C:\ArcpyBook\Ch4\Crime_DataLinksNewLayer.mxd
文件。如下圖所示,你會看到Burglary圖層已經引用了新的工作空間:
12.右鍵單擊Burglary圖層選擇屬性(Properties)
13.點擊源(Source)選項卡查看新的工作空間,工作空間類型和數據集名稱:
How it work...
replaceDataSource()
方法接受兩個必選參數和兩個可選參數。前兩個參數定義用于要替換圖層的工作空間路徑和類型。第三個參數dataset_name
是一個可選參數,該參數定義了用于替換的圖層的數據集名稱。該名稱要求完全匹配。比如,在本案例中,我們Burglaries_2009
傳遞給dataset_name
參數,這個shapefile文件的名稱將作為替換圖層。如果該參數沒有提供,那么arcpy
將會嘗試查找與當前圖層數據集名稱相同的數據來進行替換。最后一個可選參數是validate
。默認情況下,該參數值為true
。當validate
為true
時,只有當workspace_path
值是一個有效工作空間才會進行更新操作。如果validate
為false
,不管workspace_path
是否是一個有效的工作空間,該方法都會進行工作空間的更新操作。這將會導致損壞的數據源的情況出現,不過這在需要事先創建或修改一個為尚未存在的數據做準備的地圖文檔時會很有用。
There's more...
Layer
類和TableView
類還包含一個findAndReplaceWorkspacePath()
方法,該方法與MapDocument.findAndReplaceWorkspacePaths()
非常相似。兩者唯一的區別在于前者只針對單個Layer
或TableView
對象,而不是遍歷整個地圖文檔或圖層文件。
查找文件夾中所有地圖文檔文件中損壞的數據源
數據從一個工作空間遷移到另一個工作空間或是從某個工作空間類型遷移到其他工作空間類型中,這在許多機構部門是很普遍的事情。該情況發生時,所有地圖文檔或圖層文件引用的這些數據源都會中斷受損。如果是人工來查找每一個數據源,這會是一項巨大的工程。幸運的是,你可以創建一個地理處理腳本來查找一個或多個文件夾中所有損壞的數據源。
Getting ready
在本案例中,你將學習如何遍歷搜索文件夾來查找在文件夾中的地圖文檔文件中所有損壞的數據源,并將這些圖層的名稱寫入到文件中。
How to do it...
按照以下步驟來學習如何查找文件夾中所有地圖文檔文件中損壞的數據源:
1.打開IDLE,創建一個新的腳本窗口。
2.導入arcpy
和os
包:
import arcpy.mapping as mapping,os
3.定義一個開始搜索的系統路徑。在本案例中,我們會從C盤根目錄開始搜索,之后遍歷搜索C盤下面所有的目錄。你也可以定義一個更為明確的路徑:
path = "C:"
4.打開一個文件用來寫入損壞的數據圖層的名稱:
f = open('BrokenDataLinks.txt','w')
5.使用os.walk()
方法以及for
循環語句來遍歷目錄樹:
for root,dirs,files in os.walk(path):
6.在for
循環語句中創建一個二級for
循環語句來遍歷所有返回的文件。對于每一個文件,調用os.path.splitext()
方法來獲取文件的文件名和擴展名:
for filename in files:
basename,extension = os.path.splitext(filename)
7.查看文件擴展名來查看是否為地圖文檔文件。如果是的話,首先獲取該地圖文檔文件的完整路徑,之后使用該路徑創建一個新的地圖文檔對象實例并將地圖文檔名寫入文件中,最后循環遍歷每一個損壞的數據源并寫入文件中:
if extension = ".mxd":
fullpath = os.path.join(root,filename)
mxd = mapping.MapDoucment(fullpath)
f.write("MXD:" + filename + "\n")
brknList = mapping.ListBrokenDataSources(mxd)
for brknItem in brknList:
f.write("\t" +brknItem.name + "\n")
8.關閉文件:
f.close()
9.完整代碼如下所示:
import arcpy.mapping as mapping,os
path = r"C:"
f = open("BrokenDataLinks.txt","w")
for root,dirs,files in os.walk(path):
for filename in files:
basename,extension = os.path.splitext(filename)
if extension = ".mxd":
fullpath = os.path.join(root,filename)
mxd = mapping.MapDocument(fullpath)
f.write("MXD:" + filename + "\n")
brknList = mapping.ListBrokenDataSources(mxd)
for brknItem in brknList:
f.write("\t" + brknItem.name + "\n")
f.close()
10.運行腳本。
11.打開生成的文本文件查看結果。你的結果會由于定義的path
變量中的路徑不同而有區別。下圖為我的結果:
How it work...
腳本中使用了Python的os
包以及arcpy.mapping
模塊中的方法。os.walk()
方法會從你定義的C盤目錄作為根目錄開始遍歷目錄樹,并返回每次遍歷目錄的路徑,目錄列表和文件列表。其中根目錄可以是任意目錄。os.walk()
方法返回一個包含根目錄路徑,目錄列表和文件列表的三個元素的元組。之后我們循環遍歷文件列表并調用os.path.splitext()
方法將每一個文件分離成文件名和擴展名。其中擴展名用來查看是否匹配地圖文檔文件的擴展名.mxd
字符串。判定為地圖文檔的文件的文件名會寫入到一個文本文件中去,同時創建了一個新的地圖文檔對象實例。最后,我們調用ListBrokenDataSources()
函數生成地圖文檔中損壞的數據源列表,同時這些損壞的數據源的圖層名稱也被寫入到文本文件中。