我們將在本章介紹以下案例:
· 創建頁面布局元素列表
· 為頁面布局元素賦唯一名稱
· 調用ListLayoutElements()函數限制返回的頁面布局元素
· 更新頁面布局元素屬性
· 獲取可用的印表機列表
· 調用PrintMap()函數列印地圖
· 將地圖導出為PDF文件
· 將地圖導出為圖片文件
· 調用PDFDocumentCreate()和PDFDocumentOpen()函數創建地圖冊
引言ArcGIS10推出的arcpy.mapping模塊提供了許多與自動化地圖生產相關的功能。我們可以為每一個元素賦唯一的元素名稱,這樣就可以在程序中訪問這些元素。名稱是在ArcMap中定義的。arcpy.mapping模塊提供了一個ListLayoutElements()函數來返回包含所有頁面布局元素的列表。在本案例中,你將學習如何使用ListLayoutElements()函數來生成頁面布局元素列表。
import arcpy.mappingas mapping
4.引用當前活動的地圖文檔(Crime_Ch5.mxd)並將該引用賦值給變量:mxd = mapping.MapDocument("CURRENT")
5.生成頁面布局元素列表,如果元素名稱屬性不為空的則將元素名稱輸出到屏幕上:for elin mapping.ListLayoutElements(mxd):
if el.name!= "":
print el.name
import arcpy.mappingas mapping
mxd = mapping.MapDocument("CURRENT")
for el in mapping.ListLayoutElements(mxd):
if el.name!= "":
print el.name
Crime_Inset
Alternating Scale Bar
Legend Test Performance
Crime Legend
North Arrow
Inset_Map
Test_Performance
Crime
How it works...ListLayoutElements()函數以多種頁面布局類的形式返回到頁面布局元素列表。元素可以是以下對象實例:GraphicElement,LegendElement,PictureElement,TextElement或者是MapSourroundElement。每一個元素都可以賦唯一名稱。不要求為每一個元素賦予名稱,不過這在通過腳本來訪問這些元素的時候就會很有用。在腳本中,我們在輸出元素名稱前先確認元素是否被賦了名稱。這樣處理的原因在於ArcMap並不要求頁面布局要素一定要賦一個名稱。為頁面布局元素賦予唯一名稱在ArcMap中給所有的頁面布局元素賦唯一名稱是一個良好的習慣。這在地理處理腳本需要對某一元素進行修改的時候就會很重要。比如,你可能需要更新公司logo的圖標。不需要人工來更新所有的地圖文檔文件,你只需要編寫一個地理處理腳本通過程序的方式讓所有地圖文檔文件中使用新的圖標。不過要實現這一想法,你就需要為頁面布局元素賦予唯一名稱。這樣你就可以訪問單個頁面布局元素了。Getting ready正如我前一個案例中提過到的,每個頁面布局元素隸屬於某種頁面元素類並且都可以賦一個名稱。元素名稱可以在Python腳本中用於引用某個特定元素。你可以在ArcMap中為每個頁面布局元素賦予唯一名稱。在本案例中,你會使用ArcMap來為頁面布局元素賦名稱。How to do it...按照以下步驟來學習如何在ArcMap中給頁面布局元素賦名稱:1.在ArcMap中打開C:\ArcpyBook\Ch5\Crime_Ch5.mxd文件。import arcpy.mappingas mapping
4.引用當前活動的地圖文檔(Crime_Ch5.mxd)並將該引用賦值給變量:mxd = mapping.MapDocument("CURRENT")
5.調用ListLayoutElements()函數,並限制僅返回元素名稱包含Crime文本的圖例元素:for elin mapping.ListLayoutElements(mxd,"LEGEND_ELEMENT","*Crime*"):
print el.name
2009 Crime Legend
How it works...ListLayoutElements()是一個非常靈活的函數,該函數最基本用法是用來返回地圖文檔頁面視圖中所有頁面布局元素的列表。不過該函數還提供了兩個可選參數用來篩選返回的列表內容。第一個是元素類型篩選器用來指定想要返回的頁面布局元素類型。你還是可以提供一個通配符來篩選返回的列表內容。兩個篩選器可以一起使用。比如,在本案例中我們指定僅返回元素名稱包含「Crime」的LEGEND_ELEMENT對象。函數返回了僅包含一個頁面布局元素的列表。ListLayoutElements()函數可使用以下元素類型篩選關鍵字參數:DATAFRAME_ELEMENT,GRAPHIC_ELEMENT,LEGEND_ELEMENT,MAPSURROUND_ELEMENT,PICTURE_ELEMENT,TEXT_ELEMENT更新頁面布局元素屬性每一個頁面布局元素的屬性都可以通過程序來修改。比如,LegendElement對象允許更改圖例在頁面中的位置,更改圖例標題以及獲取圖例項等屬性。Getting ready頁面布局元素的類型包括圖形,圖例,文本,地圖以及圖片等。每一個頁面布局元素都對應了arcpy.mapping包中的一個類。你可以利用這些類提供的不同屬性在程序中來更改元素。
DataFrame類提供了訪問地圖文檔中數據框屬性的功能。該對象可使用地圖單位也可以使用頁面布局單位。比如像位置和大小等這類的頁面布局屬性可以通過elementPositionX,elementPositionY,elementWidth,elementHeight屬性來設置。
GraphicElement類是一個更為通用的元素類型,像插入表,圖,輪廓線,標記,線以及多邊形等圖形都可以添加到頁面布局中。如果你想通過Python腳本來訪問每一個圖形元素的話,你需要為每一個圖形元素設置name屬性(其他的頁面布局元素同理)。
LegendElement提供調整圖例位置和修改圖例標題的功能,同時也提供訪問圖例項以及關聯的父數據框的功能。LegendElement對象僅與單個數據框有關聯。
MapsurroundElement包括指北針,圖示比例尺以及文本比例尺,與LegendElement一樣也是與單個數據框有關聯。該對象包含的屬性可以用於重新調整其在頁面布局中的位置。
PictureElement指頁面布局中的柵格或圖片。該對象最常用的屬性是獲取並設置數據源,當你需要在多個地圖文檔中更新某個圖片(比如說logo)的時候就會相當有幫助。比如,你可以編寫腳本遍歷所有的地圖文檔文件將當前的圖片替換為新的logo圖片。你還可以重新定位或縮放對象。
TextElement是指頁面布局中的文本信息,包括插入的文本,注釋,文本框以及標題等,但不包括圖例標題以及插入圖表中的文本。該對象提供的屬性可用於修改文本字符串內容,這在需要在頁面布局多個位置或多個地圖文檔中修改相同文本字符串的時候會極為有用。當然,該對象也支持重新定位文本的功能。
頁面布局中的返回的每一個元素都是某類元素對象的一個實例。在本案例中,我們將通過程序使用Legend對象中的title屬性來更改Crime圖例的標題並獲取圖例項所引用的圖層對象列表。
How to do it...按照以下步驟來學習如何更新某個頁面布局元素的屬性:
1.在ArcMap中打開C:\ArcpyBook\Ch5\Crime_Ch5.mxd文件。
2.打開Python窗口。
3.導入arcpy.mapping模塊:
import arcpy.mappingas mapping
4.引用當前活動的地圖文檔(Crime_Ch5.mxd)並將該引用賦值給變量:mxd = mapping.MapDocument("CURRENT")
5.調用ListLayoutElements()函數,並限制僅返回元素名稱包含Crime文本的圖例元素,並將返回結果賦給變量:elLeg = mapping.ListLayoutElements(mxd,"LEGEND_ELEMENT","*Crime*")[0]
elLeg.title= "Crimes by School District"
7.獲取圖例項中引用的圖層對象列表並列印圖層名稱:for itemin elLeg.listLegendItemLayers():
print item.name
import arcpy.mappingas mapping
mxd = mapping.MapDocument("CURRENT")
elLeg = mapping.ListLayoutElements(mxd,"LENEND_ELEMENT","*Crime*")[0]
elLeg.title= "Crimes by School District"
for item in elLeg.listLegendItemLayers():
print item.name
Burglaries in 2009
Crime Density by School District
import arcpy.mappingas mapping
4.引用當前活動的地圖文檔(Crime_Ch5.mxd)並將該引用賦值給變量:mxd = mapping.MapDocument("CURRENT")
5.調用ListPrinterNames()函數並列印每一個印表機的名稱:for printNamein mapping.ListPrinterNames():
print printName
6.運行腳本。輸出的結果依賴於你的計算機中可用的印表機列表。不過,輸出的結果應該類似於下面的情況:HP Photosmart D110 series
HP Deskjet 3050 J610 series(Network)
HP Deskjet 3050 J610 series(Copy1)
HP Deskjet 3050 J610 series
Dell 968 AIO Printer
How it works...ListPrinterNames()函數返回的列表中包含了當前所有可用的印表機。之後你可以調用PrintMap()函數將列印任務提交給計算機中的某一個印表機,這部分內容將會在下一個案例中介紹。調用PrintMap()函數列印地圖使用PrintMap()函數將地圖文檔布局發送給印表機很容易實現。默認情況下列印任務將會發送到隨地圖文檔保存的默認印表機,不過你可以指定列印任務要發送的印表機。Getting readyarcpy.mapping模塊提供的PrintMap()函數用於列印ArcMap中的地圖文檔布局或數據框。調用該函數之前,通常的步驟是先調用ListPrinterNames()函數。某個特定的印表機可通過迭代返回的印表機列表來查找並作為PrintMap()函數的輸入參數。
PrintMap()函數用於列印某特定數據框或地圖文檔布局。默認情況下,該函數會使用隨地圖文檔保存的默認印表機,如果地圖文檔中未提供默認印表機則使用系統默認印表機。正如之前所提到的,你還可以使用ListPrinterNames()函數獲取可用的印表機列表,然後選擇其中一個印表機作為PrintMap()函數的輸入參數。在本案例中,你將學習如何時候調用PrintMap()函數來列印地圖文檔頁面布局。
How to do it...按照以下步驟來學習如何調用PrintMap()函數列印ArcMap中的頁面視圖:1.在ArcMap中打開C:\ArcpyBook\Ch5\Crime_Ch5.mxd文件。import arcpy.mappingas mapping
4.引用當前活動的地圖文檔(Crime_Ch5.mxd)並將該引用賦值給變量:mxd = mapping.MapDocument("CURRENT")
5.如果找到Test_Performance數據框則列印該數據框:for dfin mapping.ListDataFrames(mxd):
if df.name== "Test_Performance":
mapping.PrintMap(mxd,"",df)
How it works...PrintMap()函數接受一個必選參數和幾個可選參數。必選參數是地圖文檔的引用。第一個可選參數是印表機名稱。在本案例中,我們沒有指定要使用的印表機。由於沒有指定印表機,函數將使用隨地圖文檔保存的印表機或在地圖文檔未提供印表機的情況下使用系統默認印表機。第二個可選參數是我們希望列印的數據框,在本案例中該參數是Test_Performance數據框。其他的可選參數是輸出的列印文件以及圖像質量,這些並未在案例中涉及。將地圖導出為PDF文件你可能只想將地圖或頁面視圖創建成可共享的PDF文件,而不是發送到印表機列印。Arcpy中的製圖模塊提供的ExportToPDF()函數可以完成此任務。Getting readyPDF是非常流行的跨平臺查看和列印的文件交換格式。arcpy的製圖模塊中的ExportToPDF()函數可將數據框或地圖頁面布局導出為PDF格式文件。默認情況下ExportToPDF()會導出地圖頁面布局,不過你可以傳遞一個可選參數來指定要導出的特定的數據框。在本案例中,你將學習如何將地圖頁面布局和數據框導出為PDF文件。How to do it...1.在ArcMap中打開C:\ArcpyBook\Ch5\Crime_Ch5.mxd文件。import arcpy.mappingas mapping
4.引用當前活動的地圖文檔(Crime_Ch5.mxd)並將該引用賦值給變量:mxd = mapping.MapDocument("CURRENT")
5.調用ExportToPDF()函數導出地圖頁面布局:mapping.ExportToPDF(mxd,r"C:\ArcpyBook\Ch5\Map_PageLayout.pdf")
6.運行腳本。
7.打開創建的Map_PageLayout.pdf文件,文件內容類似於下圖所示:
8.現在我們要列印地圖文檔中的一個指定的數據框。如下所示修改腳本:import arcpy.mappingas mapping
mxd = mapping.MapDocument("CURRENT")
for df in mapping.ListDataFrames(mxd):
if df.name== "Crime":
mapping.ExportToPDF(mxd,r"C:\ArcpyBook\Ch5\DataFrameCrime.pdf",df)
How it works...ExportToPDF()函數接受兩個必選參數,包括一個地圖文檔文件的引用參數以及輸出的PDF文件參數。我們編寫的第一個腳本中,函數接受了地圖文檔引用參數和輸出的PDF文件參數。我們並沒有傳遞用來指定輸出的數據框的可選參數,因此ExportToPDF()函數會輸出地圖頁面布局。該函數還接受許多可選參數,包括一個指定的數據框參數以及許多與輸出內容和輸出文件的質量有關的參數。我們編寫的第二個腳本就指定了要導出的數據框參數。你可以參考ArcGIS幫助頁面來獲取每一個可選參數的詳細信息。將地圖導出為圖片文件我們還可以使用arcpy.mapping模塊提供的眾多函數將地圖內容或頁面視圖導出為圖片文件。圖片導出函數會根據所要創建的圖片文件類型不同而在函數名稱有所區別,不過函數接受的參數幾乎沒什麼區別。Getting readyarcpy.mapping模塊除了提供了將數據框和地圖頁面布局導出為PDF文件的功能外,還提供了許多可用於將地圖內容導出為圖片文件的函數。支持導出的圖片格式包括AI,BMP,EMF,EPS,GIF,JPEG,SVG以及TIFF。每個函數接受的參數取決於所創建的圖片類型。這些函數中就包括ExportToJPEG(),ExportToGIF()以及ExportToBMP()等。在本案例中,你將學習如何將地圖導出為圖片文件。How to do it...按照以下步驟來學習如何將地圖文檔中的數據或頁面視圖導出為圖片文件:1.在ArcMap中打開C:\ArcpyBook\Ch5\Crime_Ch5.mxd文件。import arcpy.mappingas mapping
4.引用當前活動的地圖文檔(Crime_Ch5.mxd)並將該引用賦值給變量:mxd = mapping.MapDocument("CURRENT")
for dfin mapping.ListDataFrames(mxd):
if df.name== "Crime":
mapping.ExportToJPEG(mxd,r"C:\ArcpyBook\Ch5\DataFrameCrime.jpg",df)
6.運行腳本查看輸出結果。
7.現在我們使用一個可選參數來輸出一個帶有world文件(坐標文件)的影像文件。如下所示修改腳本:
import arcpy.mappingas mapping
mxd = mapping.MapDocument("CURRENT")
for df in mapping.ListDataFrames(mxd):
if df.name== "Crime":
mapping.ExportToJPEG(mxd,r"C:\ArcpyBook\Ch5\DataFrameCrime2.jpg",df,world_file=True)
8.運行腳本。我們會看到一個DataFrameCrime2.jpw新文件。用文本編輯器打開該文件,將看到如下內容:470.520239851286190
0.000000000000000
0.000000000000000
-496.256971063348490
1972178.761771137800000
13815440.387677660000000
How it works...你會注意到ExportToJPEG()函數與ExportToPDF()函數看起來很像。需要注意的一點是所有的導出函數在可選參數是有區別的。每一個ExportTo<Type>函數會根據創建的文件類型的不同而接受的參數也不同。調用PDFDocumentCreate()和PDFDocumentOpen()函數創建地圖冊對於GIS專業人員來講,創建地圖冊與他人共享是很普遍的事情。地圖冊可以簡單理解為針對某一特定區域的地圖集,通常還會包含一個索引圖。考慮到PDF作為常用的交換格式,地圖冊通常為PDF格式文件。Getting ready除了可將地圖導出為PDF文件,你還可以管理現有PDF文件或創建新的PDF文件。你可以合併頁面,設置文檔打開方式,添加文件附件以及創建或更改文檔安全性設置。PDFDocumentOpen()函數用於打開一個現有PDF文件來進行管理操作。PDFDocumentCreate()函數則會創建一個新的PDF文件。這些函數經常用來創建地圖冊,本案例中我們就學習如何創建地圖冊。How to do it...1.打開IDLE,創建一個新的腳本窗口。
2.導入arcpy.mapping和os模塊:
import arcpy.mappingas mapping
import os
3.設置要創建的地圖冊的路徑和文件名。如果該文件已存在則刪除:pdfPath = r"C:\ArcpyBook\Ch5\CrimeMapBook.pdf"
if os.path.exists(pdfPath):
os.remove(pdfPath)
pdfDoc = mapping.PDFDocumentCreate(pdfPath)
pdfDoc.appendPages(r"C:\ArcpyBook\Ch5\Map_PageLayout.pdf")
pdfDoc.appendPages(r"C:\ArcpyBook\CH5\Map_DataFrameCrime.pdf")
pdfDoc.saveAndClose()
import arcpy.mappingas mapping
import os
pdfPath= r"C:\ArcpyBook\Ch5\CrimeBook.pdf"
if os.path.exists(pdfPath):
os.remove(pdfPath)
pdfDoc = mapping.PDFDocumentCreate(pdfPath)
pdfDoc.appendPages(r"C:\ArcpyBook\Ch5\Map_PageLayout.pdf")
pdfDoc.appendPages(r"C:\ArcpyBook\Ch5\Map_DataFrameCrime.pdf")
pdfDoc.saveAndClose()
8.運行腳本。
9.查看新創建的地圖冊文件C:\ArcpyBook\Ch5\CrimeBook.pdf。該地圖冊會包含我們在前面的案例中生成兩個的PDF文件的內容。
How it works...PDFDocumentCreate()函數接受文件路徑和文件名參數創建一個新的PDF文件。該PDF文件在你向其中插入或添加其他PDF頁面或調用PDFDocument.saveAndClose()方法前並不會真在在磁碟中創建。appendPages()和insertPages()方法分別用於向PDF文件中增加頁面或插入頁面。