黃彥鋒,陳秀萍
(云南省測繪產(chǎn)品檢測站,云南 昆明 650034)
第三次全國國土調查(以下簡稱“三調”)是為了全面查清當前全國土地利用狀況,掌握真實準確的土地基礎數(shù)據(jù),健全土地調查、監(jiān)測和統(tǒng)計制度,強化土地資源信息社會化服務,滿足經(jīng)濟社會發(fā)展和國土資源管理工作需要?!叭{”縣級調查作業(yè)單位需要在短時間內完成外業(yè)調查、內業(yè)數(shù)據(jù)建庫、文檔編制等工作,成果需要經(jīng)過縣級、州市級、省級、國務院三調辦等各級檢查,其中縣級調查數(shù)據(jù)庫質量檢查是一項十分重要的工作?!叭{”數(shù)據(jù)庫是“三調”成果的核心載體與展示平臺,數(shù)據(jù)庫質量檢查合格是確保“三調”數(shù)據(jù)庫建設順利完成、數(shù)據(jù)準確匯總的前提,是保證“三調”數(shù)據(jù)庫質量合格的重要措施。
由于“三調”縣級調查工作量大,作業(yè)時間非常有限,留給各級檢查的時間更少,這就需要各級檢查能快速準確地將成果中存在的問題檢查出來??h級數(shù)據(jù)庫質檢必然離不開質檢軟件,如果質檢軟件僅僅按照技術標準對縣級數(shù)據(jù)庫進行全面檢查,不充分考慮運算速度的話,將會嚴重影響縣級“三調”工作推進。由于“三調”在縣級數(shù)據(jù)庫檢查方面設置的檢查環(huán)節(jié)較多,快速對數(shù)據(jù)庫進行質檢就顯得十分重要。
承擔“三調”工作的各單位使用的計算機幾乎都是多核CPU,更有甚者投入的圖形工作站是多CPU架構。如何充分利用計算機CPU多核的優(yōu)勢,發(fā)揮單臺計算機的計算潛能,是設計數(shù)據(jù)庫質檢軟件必須考慮的問題。本文以“屬性完全相同的圖斑空間位置不能相鄰”這一質檢規(guī)則的Python多線程檢查工具的實現(xiàn)為例,闡述并行處理在“三調”縣級數(shù)據(jù)庫質檢中的重要意義。
“三調”工作使用的主流縣級調查原始數(shù)據(jù)庫格式為ArcGIS GDB格式(File GDB 和Personal GDB),可使用C#、Java、C++、Python等編程語言進行ArcGIS二次開發(fā)。之所以采用Python,原因如下:
1)ArcGIS的安裝包中就已經(jīng)集成了Python和Python的NumPy、SciPy計算庫,安裝ArcGIS時將自動安裝Python,開發(fā)者無需進行復雜的安裝和配置,可快速將精力放在業(yè)務問題的解決上,而不用在編程語言自身特性上花費較多時間。
2)ArcGIS提供Python編程接口非常方便用戶使用,可大幅縮短開發(fā)周期。
3)Python語言數(shù)據(jù)處理的學習曲線相對其他語言較為平緩,開發(fā)者比較容易進入狀態(tài)。
為什么不選擇多線程,而選擇多進程這種較為耗費計算機資源的方式進行數(shù)據(jù)處理呢?原因如下:
1)ArcGIS支持的Python 語言是CPython實現(xiàn),對Python 虛擬機的訪問由GIL(Global Interpreter Lock,即全局解釋器鎖)來控制,保證在任意時刻,只有一個線程在解釋器中運行。
2)多線程Python處理ArcGIS數(shù)據(jù)時,在子線程讀取Polygon對象時,不能正常完成Polygon對象的初始化,進而導致數(shù)據(jù)處理異常。說明ArcGIS對Python多線程處理支持不是太好。
3)Python的標準庫multiprocessing提供的多進程并行數(shù)據(jù)處理方案能很好應用于ArcGIS數(shù)據(jù)處理,且技術復雜度不高。理論上,一臺計算機的所有CPU共有多少內核,計算時就可以開多少個進程,可充分利用CPU的多核計算優(yōu)勢。
圖1 多處理器系統(tǒng)Fig.1 Multiprocessor system
在“三調”工作中使用的圖形工作站一般包含2個相同的CPU,CPU之間可以相互交換數(shù)據(jù),共享內存,I/O設備、控制器及外部設備等所有硬件系統(tǒng)由操作系統(tǒng)控制管理,在CPU和軟件之間實現(xiàn)作業(yè)、任務、進程等的全面并行。多處理器系統(tǒng)見圖1。
在進行數(shù)據(jù)庫質量檢查時,既要充分利用CPU資源,也要考慮計算機用戶是否還需要利用本機同時進行其他業(yè)務工作。在執(zhí)行進程檢查軟件前,用戶可以根據(jù)計算機全部CPU內核數(shù)量、CPU主頻和檢查工作的計算量、等待質檢結果的時間等情況進行綜合考慮,指定質檢軟件在運行時使用的進程數(shù)。數(shù)據(jù)庫質檢并行數(shù)據(jù)處理流程如圖2所示。
圖2 數(shù)據(jù)處理流程Fig.2 Data processing flow
本文以地類圖斑層的檢查項“除面積字段、標識碼、圖斑編號外其它屬性完全相同的圖斑(道路、河流、溝渠除外)空間位置不能相鄰”為例,闡述使用Python多進程編程技術進行自動檢查的應用。
若程序代碼文件名為dltbpropertysame.py,則其主程序文件頭Python代碼如下:
主程序文件頭Python代碼
dltbpropertysame.py的文件頭
#-*- coding: UTF-8-*-
import os, sys, re, sqlite3
from time import time, sleep
import xlrd, xlsxwriter
from multiprocessing import Pool, Manager
from threading import Thread
from Queue import Queue
from arcpy import env
from arcpyimport MakeFeatureLayer_management as makeFLayer
from arcpy import PolygonNeighbors_analysis as polyNeighbors
from arcpy import GetCount_management as getCount
from arcpy import Delete_management as deleteLayer
from arcpy.da import SearchCursor as searchCursor
from arcpy import CreateFileGDB_management as createFileGDB
from arcpy import AddFieldDelimiters as addFieldDelimiters
為便于讀者理解數(shù)據(jù)處理流程,本文先對主方法進行講解。限于篇幅,本文略去詳細的實現(xiàn)代碼,僅對方法參數(shù)和功能進行描述。
程序主方法Python代碼
dltbpropertysame.py中的通用方法
def main(prjdir, dltb,cnum):
#主方法。檢查地類圖斑層屬性相同的多個圖斑空間不能相鄰
# (除BSM、TBBH、面積類等字段外,其余所有字段)
#prjdir質檢項目的目錄。絕對路徑
#dltb待檢測的地類圖斑數(shù)據(jù)層絕對路徑
#cnum數(shù)據(jù)處理的子進程數(shù)。即,需要使用幾個進程進行數(shù)據(jù)處理
#無返回值
tasks = createTask(dltb, prjdir) #創(chuàng)建任務列表
pool = Pool(processes=cnum)
mg = Manager()
oids = mg.list()#記錄相鄰圖斑屬性相同的記錄
msgs = mg.Queue()#記錄輸出消息
pover = mg.Value(‘H’, 0) #數(shù)據(jù)處理進程是否全部結束
for cs in tasks: #啟動所有子進程
cs.extend([oids, msgs])
pool.apply_async(chkDLTBlxx, args=cs)
print‘All tasks started.’
pool.close()
msgout = Thread(target=outMessage, args=(msgs, pover)) #創(chuàng)建消息輸出子進程
msgout.start() #消息輸出子進程負責統(tǒng)一輸出所有子進程的信息,避免消息顯示混亂。
pool.join()
pover.value = 1 #等于1表示所有數(shù)據(jù)處理子進程處理完畢。
msgout.join() #所有數(shù)據(jù)處理子進程處理完畢后,通知消息輸出子進程結束輸出。
outResult(dltb, outdir, oids) #匯總輸出各自進程的檢查結果
限于篇幅,本文僅對關鍵方法的輸入?yún)?shù)和功能進行描述。
dltbpropertysame.py中的核心方法
def createTask(dltb, prjdir):
#根據(jù)地類圖斑層不同地類和相鄰圖斑關鍵屬性項創(chuàng)建任務列表
#dltb地類圖斑數(shù)據(jù)層絕對路徑
#prjdir質檢項目路徑
#返回任務列表
return tasks
def chkDLTBlxx(inws, infcn, prjdir, outdir,lyr, dlbm, wc, sc, oids, msgs):
#地類圖斑層屬性相同的多個圖斑空間不能相鄰
#inws地類圖斑層所在的工作空間的絕對路徑
#infcn地類圖斑層基本名稱,不含路徑
#prjdir檢查項目目錄絕對路徑
#outdir檢查結果輸出目錄的絕對路徑
#outws檢查結果輸出的ArcGIS工作空間
#lyr數(shù)據(jù)篩選層名稱
#dlbm地類編碼
#wc ArcGIS數(shù)據(jù)篩選條件,即ArcGIS數(shù)據(jù)庫的SQL語句
#sc屬性相同的判別條件
#oids相鄰圖斑屬性相同的問題記錄列表。用于記錄問題圖斑的ObjectID
#msgs統(tǒng)一輸出消息的隊列
#1.根據(jù)數(shù)據(jù)篩選條件篩選創(chuàng)建數(shù)據(jù)層
makeFLayer(infcn, lyr, wc)#創(chuàng)建數(shù)據(jù)層
flds =[oidname,′BSM′,′DLBM′,′QSXZ′,′QSDWDM′,′ZLDWDM′,
′GDLX′,′GDPDJB′,′TBXHDM′,′ZZSXDM′,′XZDWKD′]
#2.進行圖斑相鄰的空間分析
polyNeighbors(lyr, outtn, flds,
″NO_AREA_OVERLAP″, ″NO_BOTH_SIDES″,
″.0001 Meters″,″METERS″,″SQUARE_METERS″)?。
#3.獲取相鄰圖斑屬性相同的圖斑ObjectID
with searchCursor(outtn,′*′, sc) as cursor:
for row in cursor:
oids.append([row[1], row[2], lyr, dlbm])
ss=fmt.format(oidname, row[1],row[2])
msgs.put(ss.encode(′GBK′))
def outResult(dltb, outdir, oids):
#輸出地類圖斑層屬性相同的多個圖斑空間不能相鄰的檢查結果
#dltb待檢測地類圖斑層的絕對路徑
#outdir檢查結果輸出目錄絕對路徑
#oids相鄰圖斑屬性相同的問題記錄列表
在雙路CPU圖形工作站上進行測試,CPU為Interl至強處理器 E5-2650 v4 @ 2.20GHz ,內存64GB,操作系統(tǒng)是Windows 7專業(yè)版64位。測試計算機的單CPU是12核24線程,故雙CPU為24核48線程,計算主要是由CPU的內核數(shù)決定,而Python主進程和消息處理進程各需要1個CPU內核,所以為了合理測試,最大數(shù)據(jù)處理子進程數(shù)量為22。使用某縣調查數(shù)據(jù)進行測試,該縣總面積約 4 234 km2,地類圖斑數(shù)有 166 823 個,自動檢查效率見表1、圖3。
表1 多進程自動檢查效率統(tǒng)計表
圖3 多進程自動檢查效率柱狀圖Fig.3 Multi-process automatic check efficiency bar chart
由表1、圖3可知,單進程數(shù)據(jù)處理效率最低,使用9個進程進行數(shù)據(jù)處理時效率最高。那為什么使用22個進程進行數(shù)據(jù)處理時效率不是最高的呢?經(jīng)初步分析,操作系統(tǒng)的各類服務、殺毒軟件、數(shù)據(jù)庫管理軟件等都需要計算資源,而過多的子進程,增加了系統(tǒng)調度和對共同資源訪問協(xié)同工作量,還增加了磁盤I/O的協(xié)同,故而數(shù)據(jù)處理子進程數(shù)量接近CPU總內核數(shù)一半時計算效率最高。
“三調”縣級數(shù)據(jù)庫質量檢查屬于地理信息數(shù)據(jù)庫的質檢,空間數(shù)據(jù)的空間分析計算密集度較高,很多時候分布式計算和服務器集群是一個較好的選擇。然而實際工作中很多場合不具備分布式計算和服務器集群所需的硬件環(huán)境。設計地理信息數(shù)據(jù)庫質檢軟件需要充分考慮和利用本機的計算能力。軟件設計得合理,可發(fā)揮多核CPU并行計算的能力,相比單進程數(shù)據(jù)處理,可大幅度提高計算效率,特別是遇到類似“三調”工期要求非常高的工作,并行數(shù)據(jù)處理可節(jié)約大量時間,可將地理信息專業(yè)技術人員的精力集中在業(yè)務上,提高成果質量。