石全悅
(安徽省第一測繪院, 安徽合肥 230031)
使用地圖模板瀏覽或處理地理信息數(shù)據(jù),省去了重新配圖的時(shí)間,但是常常無差別的符號(hào)化設(shè)置形成一種錯(cuò)誤的作業(yè)方法或思維習(xí)慣:流動(dòng)水面和靜止水面被錯(cuò)誤地設(shè)置為相同的藍(lán)色。隨時(shí)隨地設(shè)置地理要素的符號(hào),甚至一鍵實(shí)現(xiàn)符號(hào)與屬性匹配,是地圖用戶的需求。
屬性值自動(dòng)匹配符號(hào)庫中的符號(hào),可以節(jié)約大量的配圖時(shí)間,也可以據(jù)此發(fā)現(xiàn)數(shù)據(jù)中的問題。要實(shí)現(xiàn)此功能,需要:有精心設(shè)計(jì)的符號(hào)庫[1],符號(hào)美觀,名稱與屬性項(xiàng)強(qiáng)關(guān)聯(lián);通過關(guān)聯(lián)或增加屬性字段的方式,確保某屬性項(xiàng)的值與符號(hào)庫中的符號(hào)名完全一致。
符號(hào)是數(shù)據(jù)的圖形顯示。數(shù)據(jù)是千差萬別的,但都有其國標(biāo)代碼GB,每一代碼都要有專門的符號(hào),需要多少種符號(hào)[2],都可以通過統(tǒng)計(jì)得到。統(tǒng)計(jì)方法如下:
def statistics_fd(fcsfilefolder,fieldname):
arcpy.env.workspace=fcsfilefolder
fcs=arcpy.ListFeatureClasses()
gblist=[]
for fc in fcs:
fieldList=[]
fields=arcpy.ListFields(fc)
for field in fields:
fieldList.append(field.name)
if fieldname in fieldList:
for row in arcpy.da.SearchCursor(fc,["SHAPE@",fieldname]):
if fc+" "+str(row[1])not in gblist:
gblist.append(fc+" "+str(row[1]))
else:
pass
return gblist
函數(shù)的返回值就是所要的統(tǒng)計(jì)結(jié)果,安徽不到600個(gè)地形要素國標(biāo)分類碼,制作符號(hào)庫的工作不是從0開始,利用已有的符號(hào),嚴(yán)格定義其名稱如“810301稻田”。
圖1中,符號(hào)的Value值,是國標(biāo)碼與中文名稱的組合,這樣有利于使用。但規(guī)范的數(shù)據(jù)是不含此類組合值的,這種橋梁作用的字段需要搭建——通過新建字段并賦值的方式或建立與設(shè)計(jì)的表連接的方式。新建字段方法,將會(huì)破壞原數(shù)據(jù)的屬性結(jié)構(gòu),不可取;建立表連接方法是理想的選擇。不需手動(dòng)建立表連接,使用如下的語句,這種連接只瞬間存在,應(yīng)在地圖文檔打開時(shí),運(yùn)行如下語句,并保存地圖文檔,才能存儲(chǔ)這種關(guān)聯(lián)關(guān)系。這樣的好處是不改變原數(shù)據(jù),僅在地圖文檔中添加關(guān)聯(lián)關(guān)系。
biao=r"XXXXXSheet1$"
fc=r"XXXXVEGA"
AddJoin(fc,"GB",biao,"GB")
表中有GB字段和GBNAME組合字段,要素含有GB字段,以GB為橋構(gòu)建要素與表的連接,再用GBNAME值匹配符號(hào)庫中的符號(hào)。僅打開地圖文檔,才出現(xiàn)這種連接,也才時(shí)時(shí)保持屬性與符號(hào)的匹配。移除關(guān)聯(lián),符號(hào)化效果消失。
圖1 用屬性值匹配符號(hào)庫中的符號(hào)Figure 1.Match symbols in the symbol library with attribute values
圖2 是檢查員的特色用圖設(shè)置:①夸大道路端點(diǎn)目的是為檢查員掌握道路的相交打斷情況;②道路相交打斷錯(cuò)誤;③河流中心線,箭頭表示流向;④水田符號(hào)及品字排列形式。不同的使用者需求有差異[3],符號(hào)化應(yīng)有不同的版本:普通用戶使用國標(biāo)版,特殊用戶使用符號(hào)化版。
圖2 數(shù)據(jù)、符號(hào)、遙感影像Figure 2.Data,symbols and remote sensing images
字體文件“Public_V2.0.ttf”及符號(hào)庫“YWSymbol.style”,是地圖文檔符號(hào)化不可缺少的文件,連同存放它們的路徑要記錄到地圖文檔的description屬性內(nèi)。
mxd=arcpy.mapping.MapDocument("CURRENT")
mxd.description="E:Symbol_FontPublic_V2.0.ttfE:Symbol_FontYWSymbol.style"
可以手動(dòng)拷貝,最好使用上述語句。以后使用者遇到一些問題,也容易找到答案。使用方法是,將Public_V2.0.ttf復(fù)制到Windows下font內(nèi),YWSymbol.style拷貝到用戶方便的地方,再將軟件的符號(hào)庫路徑指向此處;更安全的策略是,將原設(shè)備的字體文件拷貝到他處,地圖任務(wù)結(jié)束后,還原以前的設(shè)置。這些動(dòng)作可以通過創(chuàng)建相應(yīng)的工具來實(shí)現(xiàn)。
如果不采用自動(dòng)生成地圖文檔方法,日常需要這樣處理:將地圖文檔*.mxd指向的數(shù)據(jù)源改名,打開文檔時(shí),路徑不正確,不顯示數(shù)據(jù)及符號(hào),需重新定位數(shù)據(jù)的路徑,修改顯示范圍,另存地圖文檔,這樣生成的地圖文檔基本可以使用,有時(shí)也會(huì)遇到較難解決的問題:比如若干個(gè)數(shù)據(jù)源,不能一次解決,需要多次修改數(shù)據(jù)源的路徑,投影參數(shù)與數(shù)據(jù)源的揭示參數(shù)不一致,需要判斷投影帶的中央經(jīng)線重新設(shè)置投影參數(shù)。
自動(dòng)生成地圖文檔,也會(huì)遇到這些問題,只不過是通過程序的方式來解決,重要的是也可以解決空圖層數(shù)據(jù)的加載問題,因?yàn)榭請D層總會(huì)破壞整圖顯示的愿望。
自動(dòng)生成地圖文檔的思路是:準(zhǔn)備字體、符號(hào)庫文件,使用自動(dòng)匹配等方法創(chuàng)建通用的地圖文檔,設(shè)計(jì)好圖層組、圖層,圖層與數(shù)據(jù)層按同名方式命名。mxd模板的路徑、mxd模板的名稱、數(shù)據(jù)源文件的路徑、新層文件的路徑、新mxd的名稱均按編程要求存放,shp、mdb、gdb格式的數(shù)據(jù)源方法幾乎相同:導(dǎo)入地圖文檔文件、導(dǎo)入數(shù)據(jù)源中非空數(shù)據(jù)對應(yīng)的圖層組和圖層,計(jì)算數(shù)據(jù)源中數(shù)據(jù)的范圍,得到整個(gè)地圖的范圍值,并計(jì)算對應(yīng)投影參數(shù)獲取對應(yīng)的引用文件,指定圖層的數(shù)據(jù)源。
def create_mxd(self,template,templatefolder,sour-cefolder,newmxdlyrfolder):
L0=int(gkp.L2L0(L,3)[0])##計(jì)算投影帶的中央經(jīng)線
MapDocument(os.path.join(templatefolder,"%s.mxd"%L0))
df=arcpy.mapping.ListDataFrames(mxd,"Layers")[0]
df.extent=newExtent
result=GetCount_management(fc)
count=int(result.getOutput(0))
GroupLayer=ListLayers(mxd,"%s"%fc[:3],df)[0]
addLayer=Layer(fc)
AddLayerToGroup(df,targetGroupLayer,addLayer,"AUTO_ARRANGE")
replaceDataSource(os.path.join(mdb_folder,mdbname),"ACCESS_WORKSPACE")
findAndReplaceWorkspacePaths(template,os.path.join(mdbfolder,mdbname))
mxd.saveACopy(os.path.join(newmxdlyrfolder,"%s.mxd"%newtuming))
新生成的地圖文檔、數(shù)據(jù)源和工作空間,都經(jīng)過程序的設(shè)置,確保用戶打開文件時(shí)圖形顯示正常、工作空間正常。
屬性能自動(dòng)匹配符號(hào)、自動(dòng)生成地圖文檔,制作應(yīng)急圖就有了基礎(chǔ)。比如這次新冠疫情,美國的數(shù)據(jù),每日都在更新,可以制作即時(shí)更新的疫情圖。因?yàn)槲覈臄?shù)據(jù)涉及地圖審查的原因,會(huì)給出版帶來額外的工作,所以才使用美國的數(shù)據(jù)。基本步驟是:準(zhǔn)備基礎(chǔ)地圖要素?cái)?shù)據(jù),制作地圖文檔,抓取網(wǎng)頁數(shù)據(jù),寫數(shù)據(jù)到電子表格,關(guān)聯(lián)表。
基 礎(chǔ) 數(shù) 據(jù) 包 括 :states、usabln、neighcountry、landbnds、us_lakes、intrstat、counties、cities、us_rivers。應(yīng)急內(nèi)容主要涉及states屬性數(shù)據(jù)。
選擇可靠的網(wǎng)址
https://news.ifeng.com/c/special/7uLyp1412jw?code=USA&needpage=1&webkit=1
本文沒有使用因發(fā)布疫情數(shù)據(jù)又火了一把的約翰斯·霍普金斯大學(xué)的數(shù)據(jù),而是鳳凰網(wǎng)的數(shù)據(jù)。主要語句如下:
wangzhi="https://news.ifeng.com/c/special/7uLyp 1412jw?code=USA&needpage=1&webkit=1"
response=urllib.request.urlopen(wangzhi)
txtfile=response.read().decode("utf-8")
可以將數(shù)據(jù)寫入磁盤,也可以直接分析挖掘。數(shù)據(jù)格式如下:
str1={"siwang":"5426","sys_ ":"2020-03-05 10:49:03","name3":"新澤西州","zhongzheng_xianyou":"","quezhen_xianyou":"","quezhen_add":"待公布","quezhen":"100025","id":"","name2":"美國","name1":"國外","quezhen_jingwaishuru":"","yisi":"","sys_orderBy":"","quezhen_wzz":"","zhiyu":"","sys_publisher":"王寧1"}
使用正則表達(dá)式提取數(shù)據(jù):matchObj=re.match('''{"siwang": (.*?), "sys_publishDateTime": (.*?),"name3":(.*?),"zhongzheng_xianyou":(.*?),"quezhen_xianyou":(.*?),"quezhen_add":(.*?),"quezhen":(.*?),"id":(.*?),"name2":(.*?),"name1":(.*?),"quezhen_jingwaishuru":(.*?),"yisi":(.*?),"sys_orderBy":(.*?),"quezhen_wzz":(.*?),"zhiyu":(.*?),"sys_publisher":(.*?)}''',str1,re.M|re.I)
所有的(.*?)均代表一個(gè)變量,共有16組數(shù)據(jù):
siwang=matchObj.group(1),,,
sys_publisher=matchObj.group(16)
圖3 快速符號(hào)化生成的2020年04月23日美國疫情圖Figure 3.A rapidly symbolized map of the epidemic outbreak in the United States on April 23,2020
將獲取的數(shù)據(jù)寫入電子表格,再將表格與屬性連接,橋字段為州名稱,屬性變化后符號(hào)化立即生效,就得到剛剛從網(wǎng)上爬取數(shù)據(jù)的疫情圖(圖3)。作者無意于趕潮,重點(diǎn)在于說明,通過屬性與符號(hào)匹配技術(shù)、地圖文檔自動(dòng)生成方法,可以與公布的數(shù)據(jù)同步生成應(yīng)急圖。
屬性與符號(hào)自動(dòng)匹配實(shí)現(xiàn)地圖符號(hào)化,為使用者節(jié)約了大量的時(shí)間。有差別的符號(hào)設(shè)置,使得在生產(chǎn)階段嚴(yán)把質(zhì)量關(guān)成為可能[4]。自動(dòng)地圖文檔生成的功能,為第三方使用者帶來便利。獲取網(wǎng)絡(luò)數(shù)據(jù)、使用地圖快速符號(hào)理論,可以同步更新移動(dòng)端地圖顯示。