郭啟倩,武曉紅,李盛樂
(1.中國地震局 地震研究所, 湖北 武漢 430071;2.西安測繪總站, 陜西 西安 710054)
瓦片式震中分布圖生成及局部自動更新
郭啟倩1,武曉紅2,李盛樂1
(1.中國地震局 地震研究所, 湖北 武漢 430071;2.西安測繪總站, 陜西 西安 710054)
針對目前在線震中分布圖存在的問題,提出瓦片式地震震中分布圖。使用ArcGIS Engine開發(fā)瓦片切圖工具及局部瓦片自動更新程序,結(jié)合Google Maps實(shí)現(xiàn)瓦片式震中分布圖的展示。基于Web GIS的瓦片式震中分布圖在顯示歷史地震和最新地震方面較以往在線震中分布圖有很大改善,瓦片局部自動更新程序也克服了瓦片式地圖本身更新速度慢的缺陷。
瓦片;震中分布圖;局部自動更新; ArcGIS Engine ;Google Maps
目前地震系統(tǒng)可用于在線瀏覽的震中分布圖主要有2類:第1類是在地震信息門戶網(wǎng)站直接訪問靜態(tài)震中分布圖,該靜態(tài)圖件是由應(yīng)急人員人工或通過程序生成的,這種方式增加了應(yīng)急時(shí)期的響應(yīng)時(shí)間,且靜態(tài)圖件的比例尺難以滿足公眾需求。第2類是基于Web GIS的地震震中分布圖[1],是目前使用最廣泛的在線震中分布圖形式。該方法是通過Internet上主流的網(wǎng)絡(luò)地圖,如Google Maps、百度地圖、MapABC等公布的基于Web的API接口,在地圖上添加覆蓋類標(biāo)注顯示地震震中地點(diǎn)。這種方式優(yōu)點(diǎn)在于其信息更新迅速、訪問速度快[2],在顯示少量地震,如最近一段時(shí)期的地震信息時(shí)效果顯著,但在顯示大量地震,如歷史地震信息時(shí),會造成網(wǎng)絡(luò)響應(yīng)速度慢,甚至出現(xiàn)頁面崩潰情況。本文提出基于Web GIS的瓦片式地震震中分布圖,在顯示歷史地震和最新地震方面較以往在線震中分布圖有很大改善,并利用局部瓦片自動更新程序在震后快速更新地圖數(shù)據(jù),縮短應(yīng)急響應(yīng)時(shí)間。
Web GIS是Internet技術(shù)應(yīng)用于GIS開發(fā)的產(chǎn)物。利用Internet在Web上發(fā)布和出版空間數(shù)據(jù),為用戶提供空間數(shù)據(jù)瀏覽、查詢和分析的功能,已經(jīng)成為GIS發(fā)展的必然趨勢。傳統(tǒng)的Web GIS服務(wù)根據(jù)用戶請求參數(shù)實(shí)時(shí)渲染地圖數(shù)據(jù)再返回給客戶端,由于GIS數(shù)據(jù)通常是海量的,用戶對每次請求的等待時(shí)間較長,數(shù)據(jù)傳輸與瀏覽速度較慢,成了Web GIS應(yīng)用推廣的瓶頸。Google Maps將Ajax技術(shù)引入Web GIS[3],打破了傳統(tǒng)Web GIS根據(jù)用戶請求來實(shí)時(shí)渲染數(shù)據(jù)的服務(wù)模式,采用了地圖緩存,即瓦片技術(shù)提高訪問速度,減緩服務(wù)器壓力。
地圖瓦片技術(shù)是將地圖和影像采用特定的預(yù)切割方式進(jìn)行切片,按一定規(guī)則存儲在服務(wù)器上,客戶端異步加載當(dāng)前屏幕可視區(qū)域的瓦片數(shù)據(jù)。瓦片式地圖采用金字塔模型結(jié)構(gòu)(如圖1)。這是一種多分辨率的層次模型,每一層對應(yīng)一個(gè)地圖級別,從瓦片金字塔的底層到頂層,地圖級別及分辨率越來越低,但表示的地理范圍不變。當(dāng)用戶提出數(shù)據(jù)請求時(shí),服務(wù)器根據(jù)當(dāng)前的地圖級別,只返回屏幕區(qū)域?qū)?yīng)的瓦片到客戶端并緩存,有效避免了一次性請求所有數(shù)據(jù)導(dǎo)致的服務(wù)器壓力及帶寬浪費(fèi),提高了Web瀏覽器的地圖訪問能力。目前,越來越多的地圖服務(wù)網(wǎng)站(如Google Maps、百度地圖、MapABC、Microsoft Live Map等)都采用了這種技術(shù)來提高地圖訪問的速度。
圖 1 瓦片金字塔結(jié)構(gòu)
地圖瓦片技術(shù)讓W(xué)eb GIS系統(tǒng)的性能得到極大改善。然而,地圖生成瓦片以后,只是以圖片的形式存在,地理空間數(shù)據(jù)發(fā)生變化后只有等待后臺管理員重建地圖緩存才能在客戶端得到反映,而重建地圖瓦片通常需要幾h甚至更長的時(shí)間。實(shí)際上,地理空間數(shù)據(jù)變更通常只是局部區(qū)域變更,無需對整個(gè)地圖文檔重建瓦片,若能夠在后臺自動獲取更新的地理空間數(shù)據(jù),編輯地圖文檔,并輸出局部區(qū)域地圖瓦片替換舊的瓦片文件,在很大程度上減少耗時(shí),克服瓦片式地圖本身更新速度慢的缺陷。
將地圖瓦片技術(shù)運(yùn)用于震中分布圖中,可以彌補(bǔ)目前在線震中分布圖存在的不足。
1)瓦片式地圖利用Ajax實(shí)現(xiàn)數(shù)據(jù)的按需獲取、異步加載,根據(jù)地震目錄資料制作歷史地震震中分布地圖,預(yù)處理為地圖瓦片作為專題底圖,用戶在地震速報(bào)頁面查看最近地震的同時(shí)可加載該地區(qū)歷史地震震中分布瓦片,無論震例多少,用戶一次瀏覽只需加載當(dāng)前屏幕范圍的地圖瓦片,且瀏覽過的瓦片緩存到客戶端,無需重復(fù)請求數(shù)據(jù),大大提高了網(wǎng)頁訪問速度,減小服務(wù)器壓力。
2)瓦片式震中分布圖便于和目前互聯(lián)網(wǎng)主流的地圖服務(wù)結(jié)合,利用API接口將震中分布專題底圖與Google Maps、百度地圖等疊加,還可利用API實(shí)現(xiàn)簡單的查詢、測距等功能,取得較好的應(yīng)用效果。
3)地震分層逐級顯示,地圖級別越高,顯示震級越低,震例越多。
4)瓦片式震中分布圖分級縮放顯示,彌補(bǔ)了靜態(tài)震中分布圖比例尺無法滿足用戶需求的不足。
5)局部自動更新代替瓦片金字塔重建,改善了瓦片式地圖本身存在的更新困難的問題。
瓦片切圖工具是基于Visual Studio2010平臺和ArcGIS Engine 10.0,利用C#語言編程實(shí)現(xiàn)的。ArcGIS Engine是ESRI公司發(fā)布的用于構(gòu)建定制應(yīng)用的嵌入式GIS組件庫。ArcGIS Engine包括構(gòu)建ArcGIS產(chǎn)品的所有核心組件,提供COM、.NET和C++的應(yīng)用程序編程接口(API)。利用ArcGIS Engine提供的編程接口,可以方便地設(shè)計(jì)GIS程序,操作ArcMap地圖文檔。
3.1 切圖算法流程
切圖數(shù)據(jù)源采用ArcMap地圖文檔(.mxd格式)。首先確定將要進(jìn)行瓦片切圖的地圖的初始地理坐標(biāo)范圍,該范圍可自定義,也可利用IEnvelope接口的QueryCoords方法輸出。然后選取坐標(biāo)范圍起始點(diǎn),根據(jù)切片級別確定比例尺,由比例尺(dMapScale)、瓦 片 尺 寸(dImageWidth、dImageHeight) 及 跨度(detaX、detaY)循環(huán)計(jì)算每個(gè)瓦片的地理范圍(dTempXMin、dTempXMax、dTempYMax、dTempYMin);最后利用IExport接口輸出瓦片。瓦片切圖算法流程如圖2所示。
圖 2 切圖算法流程圖
程序?qū)Ω鱾€(gè)級別切割完成的瓦片按照瓦片切割等級、相應(yīng)等級的切圖列數(shù)、相應(yīng)列下的切圖行數(shù)進(jìn)行分級組織存儲,便于客戶端對瓦片庫進(jìn)行索引和查找。本文采用Google Maps瓦片組織方式存儲地圖瓦片。Google Maps所使用的地圖投影被稱作Web Mercator,它與常規(guī)墨卡托投影的主要區(qū)別就是把地球模擬為球體而非橢球體。程序中起始瓦片所對應(yīng)的列、行號,即在瓦片坐標(biāo)系下的X坐標(biāo)、Y坐標(biāo),分別根據(jù)切圖范圍最小經(jīng)度值、最大緯度值轉(zhuǎn)換而來,結(jié)合墨卡托投影函數(shù)將經(jīng)度、緯度值轉(zhuǎn)換為瓦片X、Y坐標(biāo),轉(zhuǎn)換算法如下:
//經(jīng)度轉(zhuǎn)換瓦片X坐標(biāo)
int getXFromLongitude(double lon,int level)
{
return (int)((lon+180)/360)*Math.Pow(2, level);
}
//緯度轉(zhuǎn)換瓦片Y坐標(biāo)
int getYFromLatitude(double lat,int level)
{
double sinLat = Math.sin(Math.PI * lat/180);
double y=0.5 - Math.Log((1+sinLat)/(1-sinLat))/ (4*Math.PI);
return(int)(y*Math.Pow(2, level))
}
切圖算法根據(jù)圖幅范圍自適應(yīng)每一地圖級別對應(yīng)的瓦片數(shù),整體執(zhí)行效率較高,瓦片約以20張/s 的速度輸出。
3.2 切圖工具開發(fā)
切圖工具程序?qū)崿F(xiàn)主要利用ArcGIS Engine中的IExport、IActive View、IEnvelope等接口進(jìn)行地圖瓦片的生成,根據(jù)切圖等級和切割的行列數(shù)不斷調(diào)整地圖的可視范圍,然后將當(dāng)前地圖范圍的顯示內(nèi)容導(dǎo)出為預(yù)定義格式的圖片,并按照瓦片庫的目錄組織結(jié)構(gòu)進(jìn)行存儲[4,5]。工具界面如圖3所示。
圖 3 切圖工具界面圖
瓦片導(dǎo)出函數(shù)如下:
private void exportToImage(IActiveView pActiveView, string sImagePath, IEnvelope pEnvelope, int right, int bottom)
{
IExportPNG pExpng = new ExportPNGClass(); IExport export = pExpng as IExport;
IEnvelope envelope = new EnvelopeClass();
ITrackCancel cancel = new CancelTrackerClass(); tagRECT grect; grect.left = 0; grect.top = 0;
grect.right = right;
grect.bottom = bottom;
int num = Convert.ToInt32(export.Resolution); envelope.PutCoords((double)grect.left, (double)grect. bottom, (double)grect.right, (double)grect.top);
export.ExportFileName = sImagePath;
export.PixelBounds = envelope;
pActiveView.Output(export.StartExporting(), num, ref grect, pEnvelope, cancel);
export.FinishExporting();
}
如前所述,瓦片式地圖是金字塔形分級存儲的圖片格式數(shù)據(jù),當(dāng)?shù)乩硪匕l(fā)生變化后需要重建瓦片金字塔,這一過程將耗費(fèi)很長時(shí)間。瓦片局部自動更新旨在用更新變化區(qū)域瓦片數(shù)據(jù)的方法替代整體瓦片金字塔重建,更新過程只需要幾s。這一改進(jìn)大大縮短了瓦片數(shù)據(jù)更新、準(zhǔn)備時(shí)間,對于及時(shí)更新震中分布圖優(yōu)勢顯著。
瓦片地圖局部自動更新程序分為更新地圖文檔和替換瓦片2個(gè)部分。更新地圖文檔,即根據(jù)需要更新的地圖要素?cái)?shù)據(jù)通過后臺程序修改.mxd文檔。當(dāng)?shù)貓D文檔更新以后,首先要獲取更新后的地圖要素對應(yīng)的坐標(biāo)范圍,然后根據(jù)這個(gè)坐標(biāo)范圍計(jì)算該范圍內(nèi)對應(yīng)地圖瓦片的行列號,接著在后臺重新生成這個(gè)范圍內(nèi)的地圖瓦片,最后以新生成的瓦片替換舊的瓦片,最終實(shí)現(xiàn)圖形與數(shù)據(jù)更新的同步[6]。
當(dāng)點(diǎn)要素發(fā)生變化時(shí),根據(jù)點(diǎn)要素在地圖投影坐標(biāo)系下的坐標(biāo)值計(jì)算該點(diǎn)在不同地圖級別下所在瓦片的行列號(X、Y),生成對應(yīng)地圖級別的瓦片。線要素、面要素發(fā)生變化,根據(jù)變化要素的最小外包矩形計(jì)算該要素地理范圍所在瓦片的行列號序列,生成對應(yīng)地圖級別的瓦片集合。下面以更新一個(gè)震中點(diǎn)pGeom要素為例,說明瓦片式震中分布圖局部自動更新流程。
4.1 更新地圖文檔
更新地圖文檔是獲取指定地圖文檔的當(dāng)前圖層,對當(dāng)前圖層添加新的地理要素,保存修改后的.mxd文檔作為瓦片數(shù)據(jù)新的地圖數(shù)據(jù)源。主要利用IFeatureClass、IFeature等接口向指定圖層添加新的地圖要素,關(guān)鍵代碼如下:
IFeatureLayer pFeatureLayer = (IFeatureLayer)m_ pCurrentLayer;
IFeatureClass pFeatureClass = pFeatureLayer. FeatureClass;
//開始創(chuàng)建地理要素
IFeature pFeature = pFeatureClass.CreateFeature(); //定義要素類型
pFeature.Shape = pGeom;
//要素賦字段值
int fi eldindex = pFeature.Fields.FindField("字段名"); pFeature.set_Value(f i eldindex, "字段值"); //保存地理要素pFeature.Store();
由于地震目錄采用經(jīng)緯度記錄震中位置,點(diǎn)pGeom要素的坐標(biāo)值是經(jīng)過轉(zhuǎn)換處理的投影坐標(biāo)系下的坐標(biāo)值。
4.2 替換瓦片
1)將經(jīng)緯度值轉(zhuǎn)換為對應(yīng)地圖級別下的地圖瓦片坐標(biāo)X、Y,轉(zhuǎn)換算法見§3.1。
2)根據(jù)瓦片號計(jì)算瓦片地理范圍。
double dTempXMin = dTileOriginX + dImageWidth * (detaX - 1);
double dTempXMax = dTileOriginX + dImageWidth * detaX;
double dTempYMax = dTileOriginY - dImageHeight * detaY;
double dTempYMin = dTileOriginY - dImageHeight * (detaY - 1);
IEnvelope envelope = new EnvelopeClass();
envelope.PutCoords(dTempXMin, dTempYMin, dTempXMax, dTempYMax);
pActiveView.Extent = envelope;
其中,dTileOriginX、dTileOriginY分別是該mxd文檔的X最小值和Y最大值,dImageWidth、dImageHeight代表瓦片的地理跨度值,detaX、detaY分別是瓦片號X、Y與該mxd文檔最小瓦片號OriginX、OriginY的差值。
3)輸出瓦片替換舊瓦片。
string sImagePath = sFolderDir + "\" + X+ "\" + Y +".PNG";
exportToImage(pActiveView, sImagePath, envelope, 256,256)。
本文基于Google Maps提供的JavaScript API接口對Google Maps進(jìn)行二次開發(fā)[7]。對于歷史地震信息,采用疊加瓦片式震中分布圖的方式分震級縮放顯示,地圖級別越高,能夠顯示的震級越小,震例越多;對于最近一段時(shí)間發(fā)生的地震事件A,采用疊加覆蓋類標(biāo)注的方式動態(tài)閃爍顯示。當(dāng)新增地震事件B時(shí),后臺程序自動將地震事件A寫入.mxd地圖文檔,并更新對應(yīng)的各級地圖瓦片,地震事件B閃爍標(biāo)注。
5.1 疊加震中分布圖瓦片
1)切圖數(shù)據(jù)源準(zhǔn)備。按照逐級顯示地震的原則,在ArcMap中完成震中分布圖制圖,地圖投影方式采用與Google Maps一致的Web Mercator投影。
2)地圖瓦片制作。使用瓦片切圖工具制作地圖瓦片,不同級別的地圖瓦片選擇顯示對應(yīng)震級范圍的地圖數(shù)據(jù)源,如2級地圖顯示7級以上地震,10級地圖顯示3級以上地震。
3)地圖瓦片疊加。Google Maps API為基本類型google.maps.Map提供了overlayMapTypes屬性疊加自定義瓦片地圖,關(guān)鍵腳本如下:
//疊加自定義瓦片
map.overlayMapTypes.insertAt(0, new OverLayer (new google.maps.Size(256, 256)));
//瓦片的tileSize、getTile屬性
function OverLayer(tileSize) {}
OverLayer.prototype.tileSize = new google.maps. Size(256, 256);
OverLayer.prototype.getTile = function (coord, zoom, ownerDocument)
{
var overlay = ownerDocument.createElement ('overlay');
overlay.style.width = this.tileSize.width + 'px';
overlay.style.height = this.tileSize.height + 'px';
var strURL = "EQMs7/";
strURL += zoom + "/" + coord.x + "/" + coord.y + ".PNG";
overlay.style.backgroundImage = 'url(' + strURL + ')';
return overlay;
}
其中coord.x、coord.y分別是Google Maps定義的瓦片坐標(biāo)系中的瓦片坐標(biāo)值X、Y,§4.2中程序生成的瓦片存儲路徑為zoom/ coord.x/coord.y,與strURL對應(yīng)。圖4為7級地圖疊加Ms5以上地震的震中分布圖瓦片。
圖 4 瓦片式震中分布圖
5.2 標(biāo)注最新地震事件
對于最新地震事件,采用Google Maps API提供的覆蓋類型google.maps.Marker動態(tài)閃爍顯示,并添加信息窗。圖5所示為在6級地理底圖上顯示全球5級以上地震震中分布圖,閃爍標(biāo)注湖北巴東5.1級地震。
圖 5 標(biāo)注最新地震
瓦片式地震震中分布圖結(jié)合主流的Web GIS服務(wù)平臺,彌補(bǔ)了傳統(tǒng)在線震中分布圖的不足,并改進(jìn)瓦片數(shù)據(jù)更新方法,進(jìn)一步優(yōu)化了應(yīng)用效果。功能方面,主要優(yōu)勢在于將歷史地震震中分布圖作為專題底圖,以瓦片形式分級分層顯示,地圖級別越高,能夠顯示的地震級數(shù)越小,震例越多;同時(shí)利用Google Maps API提供的Marker覆蓋類顯示最新地震震情信息,實(shí)現(xiàn)歷史地震和最新地震同時(shí)顯示,效果較好。技術(shù)方面,采用局部瓦片自動更新的方法替代瓦片金字塔重建,在區(qū)域地理空間數(shù)據(jù)發(fā)生變化后(例如在震中分布圖上新增震中點(diǎn)),僅需要更新每個(gè)瓦片級別對應(yīng)該區(qū)域的瓦片數(shù)據(jù),最大程度地縮短了地圖瓦片的更新時(shí)間。
[1] 董星宏,賈寧.基于Web GIS的地震震中分布圖實(shí)現(xiàn)方式探討[J].高原地震,2011,23(1):63-64
[2] 吳阿丹,李勝樂.生成GoogleMap地震震中分布圖的一種方法[J].地震地磁觀測與研究,2012,33(2):120-123
[3] 吳云超,王汶,牛錚,等.Ajax在WebGIS中的應(yīng)用[J].地理與地理信息科學(xué),2007,23(2):43-46
[4] 寇曼曼,王勤忠,譚同德.Google map數(shù)字柵格地圖算法及應(yīng)用[J].計(jì)算機(jī)技術(shù)與發(fā)展,2012,22(4):204-206
[5] 王小軍,劉璐.基于ArcGIS Engine進(jìn)行瓦片式切圖的技術(shù)研究[J].測繪與空間地理信息,2010,33(4):49-54
[6] 郭明武,彭青山,李黎.ArcGIS Server中地圖瓦片實(shí)時(shí)在線局部更新方法研究[J].測繪通報(bào),2012(2):35-38
[7] Google. Google Maps JavaScript API V3[EB/OL].https:// developers.google.com/maps/documentation/javascript/ maptypes?hl=zh-CN#TileCoordinates,2014-05-21
P208
B
1672-4623(2015)01-0115-04
10.3969/j.issn.1672-4623.2015.01.038
郭啟倩,碩士,主要研究方向?yàn)榈卣鹋c地理信息系統(tǒng)。
2014-05-21。
項(xiàng)目來源:“十二五”國家科技支撐計(jì)劃資助項(xiàng)目(2012BAK19B02-05)。