張凱旋, 鄒業(yè)斌, 劉曇曇, 馬文濤
(中國礦業(yè)大學(xué)(北京),北京 100083)
地理信息系統(tǒng)是一種采集、存儲、管理、分析、顯示與應(yīng)用地理信息的計(jì)算機(jī)系統(tǒng)[1],以數(shù)字化的形式反映地球空間現(xiàn)勢和變遷的各種空間數(shù)據(jù)并描述這些空間數(shù)據(jù)特征的屬性,以及使用模型化的方法來模擬地球空間對象的行為,在計(jì)算機(jī)軟、硬件的支持下,以特定的格式支持輸入/輸出、存貯、顯示以及進(jìn)行地理空間信息查詢、綜合分析、輔助決策,為人們提供處理地理信息最佳的方法和手段[2]。隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展,大數(shù)據(jù)和云計(jì)算等技術(shù)的興起,使WebGIS應(yīng)用得到了飛速的發(fā)展。利用Internet在Web上發(fā)布和出版地理信息,為用戶提供空間數(shù)據(jù)的瀏覽、查詢、制作專題圖和分析的功能,從而實(shí)現(xiàn)地理信息的共享,已經(jīng)成為GIS發(fā)展的必然趨勢[3]。在實(shí)際WebGIS開發(fā)中會需要上傳本地的ShapeFile文件并結(jié)合WebGIS系統(tǒng)進(jìn)行分析,Esri的服務(wù)非常昂貴,因此在小規(guī)模的GIS平臺搭建過程中可搭建本地后臺解析系統(tǒng)。本文詳細(xì)介紹了ShapeFile的文件結(jié)構(gòu),根據(jù)ShapeFile文件的結(jié)構(gòu),利用.NET技術(shù)進(jìn)行解析,并展示到Web前端。對各學(xué)者建設(shè)WebGIS平臺有所借鑒。
一個完整的ESRI的ShapeFile文件包括一個主文件*.shp,一個索引文件*.shx,和一個屬性文件*.dbf。主文件是一個直接存取,記錄長度文件,其中每個記錄描述一個由其頂點(diǎn)列表組成的ShapeFile。在索引文件中,每條記錄是在主文件中記錄對應(yīng)距離主文件頭部的偏移量。*.dbf中記錄的是對應(yīng)主文件中記錄的屬性記錄,每條主文件記錄對應(yīng)*.dbf中的一條屬性記錄。*.prj文件用于存儲坐標(biāo)系的信息;*.xml文件作為元數(shù)據(jù)文件,用于存儲ShapeFile的相關(guān)信息[4]。
主文件用來存儲地理要素的幾何圖形,一個.shp文件由文件頭和記錄實(shí)體兩部分組成[5]。主文件頭100字節(jié)長。表1描述了文件頭中數(shù)據(jù)的字節(jié)位置、值類型和字節(jié)順序。在表1中,位置是相對于文件頭的。文件頭的布局如表1所示。
表1 主文件頭結(jié)構(gòu)表Table 1 Structure table of main file header
.shx索引文件是存儲圖形要素與屬性信息索引的文件,主要起到定位的作用,其由文件頭和記錄兩部分組成,文件頭的內(nèi)容與主文件的基本一致[5]。每條記錄由8個字節(jié)組成,具體內(nèi)容如表2所示。其中,Offset可以理解為該條記錄在.shp文件中的偏移量,Content Length可以理解為該記錄的長度。
表2 索引文件記錄結(jié)構(gòu)表Table 2 Structure table of index file record
.dbf屬性表文件,是由頭記錄及數(shù)據(jù)記錄組成。頭記錄定義了該表的結(jié)構(gòu)并包含與表相關(guān)的其它信息,它主要對屬性文件作一些概括性描述,尤其是對屬性文件的記錄項(xiàng)信息進(jìn)行著重性說明,比如對每個記錄項(xiàng)的名稱、數(shù)據(jù)類型、精度、長度都作了詳細(xì)地介紹。
本地文件利用Ajax技術(shù)通過Post提交方式異步上傳給后臺服務(wù)端,后臺服務(wù)端通過HttpPostedFile接受前端傳遞過來的文件并且通過FileStream類讀取文件上傳到文件服務(wù)器[6]。然后調(diào)用WebService服務(wù)利用BinaryReader類以二進(jìn)制文件流的方式對ShapeFile進(jìn)行解析,以集合的方式返回解析后的數(shù)據(jù)。將集合數(shù)據(jù)轉(zhuǎn)換成JSON數(shù)據(jù)格式,利用ArcGIS for JavaScript庫類展示數(shù)據(jù),流程如圖1。
圖1 解析流程圖Fig.1 Analytical flow chart
HttpPostedFile postedFile =context.Request.Files[0]; //接收文件
postedFile.SaveAs(context.Request.MapPath(fullDir)); //保存文件
FileStream fo= new System.IO.FileStream
(context.Request.MapPath(shxpath),FileMode.Open,FileAccess.Read);
//文件流形式
以文件流的方式將前端Web Browser上傳的文件存儲到文件服務(wù)器,利用FileStream分別讀取.shp、.shx和.dbf文件,FileStream讀寫操作可以指定為同步或異步操作。同時支持對輸入輸出流進(jìn)行緩沖,提高性能。
[WebMethod]
public List
BinaryReader bi = new BinaryReader(shpfo); //讀取shp文件
BinaryReader br = new BinaryReader(fs); //讀取shx文件
for(int n = 0;n < RecorderNumber;n++) //文件解析過程
{ ……
double[] pointsx = new double[Numpoints];
double[]pointsy = new double[Numpoints]; //定義數(shù)組
for(int z = 0;z < Numpoints;z++) //for循環(huán)讀取
{ ……
pointtemp.X = br.ReadDouble();
pointtemp.Y = br.ReadDouble();
shpstr+= "["+ pointtemp.X+ ","+ pointtemp.Y+ "],";
}
list.Add(shpstr);//存入List集合
}
return list;
}
}
public List
{
BinaryReader br1 = new BinaryReader(dbfo); //讀取二進(jìn)制文件
…
DataRow dr = dt.NewRow();
tempBytes = br1.ReadBytes(fieldLength[j]);
Regex regex = new Regex("\s+");
tempStr = regex.Replace(tempStr,"");
dt.Rows[i][j] = """+ tempStr+ """;
dbfstr = Regex.Split(result,"},"); //將解析后的屬性信息,轉(zhuǎn)字符串?dāng)?shù)組
…
return list; //將字符串?dāng)?shù)組遍歷,添加到集合后返回
}
調(diào)用WebService服務(wù)對文件流通過BinaryReader類的ReadInt和ReadByte等方法,根據(jù)文件結(jié)構(gòu)以二進(jìn)制流的方式對ShapeFile文件的.shp、.dbf、.shx文件進(jìn)行解析,獲取點(diǎn)、線、面數(shù)據(jù)類型,以及點(diǎn)坐標(biāo)和屬性文件。最后將解析后的數(shù)據(jù)以List
圖2 坐標(biāo)List集合中每條數(shù)據(jù)格式圖Fig.2 Each data format chart in the coordinate List set
圖3 屬性List集合中每條數(shù)據(jù)格式圖Fig.3 Each data format graph in the attribute List collection
JSON是一種輕量級的數(shù)據(jù)交換格式[7],易于閱讀和編寫,同時也易于機(jī)器解析。每條JSON消息都是包含在大括號之內(nèi)的,鍵值對組合中的鍵名寫在前面并用雙引號包含,鍵和值使用冒號分隔,冒號后面緊接著值,如:“key”:“value”;數(shù)組是用方括號包含起來的,如:[“zhou”,“zhang”]。相較于xml,JSON在傳輸?shù)倪^程中采用了壓縮技術(shù),傳輸?shù)倪^程中更加節(jié)省寬帶而且傳輸更加高效。當(dāng)大量的坐標(biāo)信息以及屬性信息傳遞給前端瀏覽器的時候?yàn)榱瞬灰馂g覽器卡頓,用戶等待時間過長,所以后臺需要將list集合進(jìn)行遍歷,然后將字符串拼接成JSON格式的字符串再傳遞給前端。
以線的ShapeFile文件的解析為例。根據(jù)ArcGIS for JavaScript庫類提供的線的數(shù)據(jù)格式,將數(shù)據(jù)拼接成如下格式:
var myLine =[{ attributes:{“TNODE”:”7”,”LPOLY”:”2”},geometry:{"paths":[[[-91.40625,6.328125],[6.328125,19.3359375]]],
"spatialReference":{"wkid":4326}},
"symbol":{"color":[0,0,0,255],"width":1,"type":"esriSLS","style":"esriSLSSolid"}}];
核心代碼如下:
if(Convert.ToInt32(type)==3)
{
bdfstring1 = "{"+ ""attributes""+ ":"+bdfstring[i].ToString()+ "},"+ shapetype; //通過for循環(huán),添加屬性信息
…
dbfstr = "["+ str.Remove(0,1)+ "]],"+ ""spatialReference""+ ":"+ "{"+ ""wkid""+ ":"+ 4326+ " }"+ "},"+ ""type""+ ":"+3+"},"; //通過for循環(huán),添加坐標(biāo)系信息
}
傳遞給前端的JSON字符串格式如圖4。
ArcGIS for JavaScript庫類是ESRI根據(jù)JavaScript技術(shù)實(shí)現(xiàn)的一組腳本,可以將ArcGIS Server提供的地圖資源和其它資源(ArcGIS Online)嵌入到Web應(yīng)用中。有豐富的網(wǎng)絡(luò)資源、基于功能強(qiáng)大的Dojo JavaScript工具包、開發(fā)和部署都是完全免費(fèi)的等優(yōu)點(diǎn)。
前臺通過調(diào)用ArcGIS for JavaScript的GraphicLayer、Graphic和Geometry等接口對后臺還回的JSON數(shù)據(jù)進(jìn)行解析。創(chuàng)建一個新的圖層,然后根據(jù)ArcGIS for JavaScript 框架提供的Graphic類new Graphic(geometry?,symbol?,attributes?,infoTemplate?)將解析后的數(shù)據(jù)傳遞給瀏覽器渲染展示。通過InfoTemplate類new InfoTemplate(JSON)將屬性信息展示出來。
圖5 中國省級行政區(qū)界線讀取Fig.5 Reading of China’s provincial administrative boundaries
圖6 中國省級行政區(qū)界線面讀取Fig.6 Reading the boundary surface of provincial administrative regions in China
圖4 傳遞給前端的JSON字符串格式Fig.4 JSON string format passed to the front end
//設(shè)置線的顏色寬度
var myLine = {"symbol":{ "color":[0,0,0,255],"width":2,"type":"esriSLS","style":"esriSLSSolid" }};
//設(shè)置屬性窗口
var infoTemplate = new mapAPI.InfoTemplate("Attributes",JSON.parse(attri));
//創(chuàng)建一個新的圖層
var countyLayer = new map.GraphicsLayer();
//將圖層添加到地圖上
countyLayer.add(gra);
map.addLayer(countyLayer);
本文采用中國省級行政區(qū)界.shp矢量地圖數(shù)據(jù),用來驗(yàn)證編寫的系統(tǒng)讀寫ShapeFile 圖形文件的功能。采用谷歌瀏覽器,利用VS 2012,在.NET 4.5的環(huán)境下完成。Esri提供的底圖是WGS 84坐標(biāo)系。
(1) 讀取中國省級行政區(qū)界.shp,如圖5所示。
(2) 讀取中國省級行政區(qū)界.shp面信息,以及屬性信息,如圖6所示。
(3) 中國省級行政區(qū)界屬性信息的讀取展示,如圖7所示。
本文首先介紹了Shapefile圖形文件的基本結(jié)構(gòu),根據(jù)ShapeFile文件的結(jié)構(gòu)在.NET環(huán)境下利用 Microsoft Visual Studio2012平臺開發(fā)了可以展示ShapeFile圖形及其屬性信息的WebGIS系統(tǒng),加深了對網(wǎng)絡(luò)傳輸、JSON字符串、以二進(jìn)制文件流的方式解析文件、WebGIS系統(tǒng)開發(fā)以及ShapeFile文件結(jié)構(gòu)等的理解,對后期各學(xué)者建設(shè)WebGIS平臺提供借鑒。
圖7 中國省級行政區(qū)界屬性信息顯示Fig.7 Attribute information display of provincial administrative boundaries in China