一種基于SVG的Google用戶地圖文本標注方法
【專利摘要】本發(fā)明公開了一種基于SVG的Google用戶地圖文本標注方法,它將帶有路徑文本的svg對象加入Google地圖的自定義疊加層,并且在繪制此疊加層時,調(diào)用getProjection()方法獲取當前地圖投影;將經(jīng)緯度表示的標注路徑轉(zhuǎn)換為當前投影下的像素路徑;計算像素路徑長度,并與標注文本長度比較,如果太短,則不顯示svg對象;確定標注文本在像素路徑的起點位置,以確保文本處于路徑中部;按文本長度確定標注文本實際占據(jù)的像素路徑;比較確定標注文本像素路徑的最小坐標值,并將其作為svg對象的左上角坐標;計算標注文本相對svg左上角的像素路徑;將坐標串表示的文本像素路徑轉(zhuǎn)換為svg中path元素的路徑表示形式,并替換其d屬性。本發(fā)明解決文本標注問題,為Google用戶地圖文本標注找到一條新的途徑。
【專利說明】—種基于SVG的Google用戶地圖文本標注方法
【技術(shù)領(lǐng)域】
[0001]本發(fā)明屬于計算機【技術(shù)領(lǐng)域】,涉及一種基于SVG的Google用戶地圖文本標注方法。
【背景技術(shù)】
[0002]地圖上沒有文字是很難理解的,每個地圖元素都需要文字注解。傳統(tǒng)GIS (Geographic Information System,地理信息系統(tǒng))軟件,如 ArcGIS、Maplnfo 等本身具有豐富的文本標注自動生成功能,在二次開發(fā)建立應(yīng)用系統(tǒng)時無需考慮標注問題。但近年來隨著Google地圖的廣泛應(yīng)用,越來越多的用戶希望將應(yīng)用建立在Google地圖上。GoogleMaps API V3是建立Google地圖應(yīng)用系統(tǒng)的基本工具,提供了諸多地圖繪制功能,但缺少相應(yīng)的文本標注功能。
[0003]針對標注問題,Google提供了幾種解決方案,即利用Marker符號(默認或自定義符號)、彈出式Info window窗口和自定義疊加層。前兩種方案根本無法產(chǎn)生類似Google基礎(chǔ)地圖那樣的標注效果。相比之下,自定義疊加層具有較大靈活性,且Google在其實用程序庫(Google Maps Utility Library)中提供了 MapLabel類以方便用戶在地圖上繪制文本。
[0004]MapLabel 是對 Overlay View 類的擴展。而 Overlay View 是 Google Maps APIV3的一個基類,它只為用戶提供在創(chuàng)建疊加層時必須實現(xiàn)的若干方法,在用戶的自定義疊加層中具體添加什么內(nèi)容由用戶自己決定。MapLabel是將繪有文本的HTML5Canvas元素加入疊加層,并放置在地圖指定位置,從而形成對此處地圖元素的標注。
[0005]但HTML5Canvas元素在文本繪制方面有很大的局限性,只能在水平方向自左向右繪制。所以,MapLabel可基本滿足場點標注的需要。如果要文字傾斜、旋轉(zhuǎn),或沿道路、河流、各種管線等線狀或帶狀地圖元素標繪文字,MapLabel就無能為力了。
【發(fā)明內(nèi)容】
[0006]本發(fā)明的目的在于克服上述現(xiàn)有技術(shù)缺陷,提供一種基于SVG的Google用戶地圖文本標注方法,解決文本標注問題,為Google用戶地圖文本標注找到一條新的途徑。其具體技術(shù)方案為:
[0007]一種基于SVG的Google用戶地圖文本標注方法,包括以下步驟:
[0008]首先將含有路徑本本的svg元素作為JavaScript對象加入自定義疊加層的地圖窗格中;然后在繪制此疊加層的過程中執(zhí)行以下步驟:
[0009](I)調(diào)用Overlay View類的getPro jection O方法獲取當前地圖投影;
[0010](2)將經(jīng)緯度表示的標注路徑轉(zhuǎn)換為當前投影下的像素路徑;
[0011](3)計算像素路徑長度,并與標注文本長度比較,如果太短,則不顯示svg對象;
[0012](4)確定標注文本在像素路徑的起點位置,以使文本居于路徑中部;
[0013](5)按文本長度確定標注文本實際占據(jù)的像素路徑;[0014](6)比較確定標注文本像素路徑的最小坐標值,并將其作為svg對象的左上角坐標;
[0015](7)將步驟(5)得到的標注文本像素路徑轉(zhuǎn)換為相對svg左上角的像素路徑;
[0016](8)將步驟(7)得到的坐標串表示的文本像素路徑轉(zhuǎn)換為svg中文本路徑path元素的路徑表示形式,并替換其d屬性。
[0017]進一步優(yōu)選,每個待標注地圖元素均需建立一個或多個文本標注對象,并利用數(shù)組進行管理,以適應(yīng)地圖元素長度的不同和變化。
[0018]除了按文本長度控制標注的顯示,還可以通過地圖縮放級別控制標注的顯示。
[0019]當標注對象注銷時,Google Maps API調(diào)用onRemove O方法從地圖上移除svg對象。利用對象方法setMap (null)和setMap (map)可從地圖上隱去或復(fù)顯文本標注。
[0020]與現(xiàn)有技術(shù)相比,本發(fā)明的有益效果為:本發(fā)明將HTML5SVG與Google Maps APIV3 的 Overlay View 類結(jié)合,建立一個 JavaScript 類 SVGMapLabel,用于在 Google 地圖生成文本標注。SVGMapLabel可以為Google地圖上的點、線、區(qū)域?qū)ο蠼⑽谋緲俗ⅲ捎糜诮换ナ綐俗?,也可與KML圖層結(jié)合,對KML圖層中的地圖要素進行自動標注,其標注效果類似于Google基礎(chǔ)地圖,完全可以取代MapLabel。在建立基于Google地圖的WebGIS時,SVGMapLabel類可用于用戶地圖的內(nèi)文本標注。
【專利附圖】
【附圖說明】
[0021]圖1是在獨立Web頁面上用svg沿路徑繪制文本;
[0022]圖2是道路中線KML文檔結(jié)構(gòu);
[0023]圖3是道路標注,其中圖3a為1: 2000通路圖,圖3b為1: 5000道路圖。【具體實施方式】
[0024]下面結(jié)合附圖和具體實例對本發(fā)明的技術(shù)方案做進一步詳細說明。
[0025]I基于SVG的地圖標注類SVGMapLabel
[0026]1.1SVG Text
[0027]SVG是Scalable Vector Graphics (可伸縮矢量圖形)的縮寫,是HTML5內(nèi)含的XML風格的圖形標記語言。與HTML5Canvas使用API的繪圖方式不同,HTML5SVG利用一系列專有標記描述Web頁面圖形。在文本繪制方面,它利用text元素及其眾多樣式屬性控制文本繪制,如圖1上部所示的文檔片段。這段文檔的作用就是沿路徑繪制文本,經(jīng)瀏覽器(需支持HTML5)渲染后產(chǎn)生圖1下部的輸出。
[0028]瀏覽器在渲染svg時,把svg元素輸出為頁面上的一個圖塊,其屬性(x,y)指其左上角相對頁面左上角的位置(以像素計)。text屬性(X,y)指文本相對svg左上角的位置。text屬性style指文本自身樣式屬性。其中g(shù)lyph-orientation-horizontal指字形相對自身水平基線的方位,其值為O或270。O表示正常輸出(圖1左下圖),270表示每個字繞字形左下角順時針旋轉(zhuǎn)270° (圖1右下圖)。text子元素textPath指明文字按指定路徑輸出,其屬性href的值”#MyPath”是事先定義的路徑path的惟一標識id值。路徑path在text之前的defs元素中定義。如果text內(nèi)只是文本元素,沒有textPath元素,輸出路徑默認為水平線。[0029]路徑path是通過屬性d來描述的。d=〃 M12,12L40,40L100,80"表示在svg圖塊中將光標移至點(12,12)位置,然后向點(40,40)畫線,再向點(100,80)畫線。這是一條折線,將作為文字基線,但是并不顯示在頁面上。在svg中也可以繪制更復(fù)雜的曲線作為文字基線。
[0030]HTML5SVG雖然符合W3CXML規(guī)則,但其子元素的名稱必須處于指定的命名空間,即xmlns = ”http://www.w3.0rg/2000/svg”,而鏈接屬性(如href)的名稱必須處于另一個命名空間,即 xmlns:xlink = " htt://www.w3.0rg/1999/xlink"。否則,瀏覽器無法識別,也就得不到期望的輸出。
[0031 ] 有關(guān)SVG更詳細的說明,參見SVG規(guī)范。
[0032]很顯然,這樣一種文字輸出方式與期望的Google地圖標注方式是一致的。那么將它引入Google地圖生成文本標注,就值得深入研究。
[0033]1.2基于SVG的地圖標注類SVGMapLabel
[0034]Google提供的地圖標注類MapLabel是將HTML5Canvas元素加入自定義疊加層而形成的,這與Google地圖建立在HTML5Canvas上的總體思路是一致的?,F(xiàn)在要用上述svg文檔片段替換MapLabel中的Canvas元素,需要建立一個新的JavaScript類,名曰SVGMapLabel,以描述在Google地圖上如何用svg建立文本標注。
[0035]按照Google地圖自定義疊加層的創(chuàng)建要求,SVGMapLabel類由構(gòu)造函數(shù)和三個原型方法onAdd()、draw O、onRemove O組成,并且需要將SVGMapLabel原型設(shè)為google.maps.0verlayView的新實例,以繼承OverlayView類。SVGMapLabel類的定義如下:
[0036]function SVGMapLabel (options) {/* 對象構(gòu)造函數(shù) */}
[0037]SVGMapLabel.prototype = new google, maps.0verlayView ;/* 子類化 */
[0038]SVGMapLabe1.prototype.0nAdd = function () {/* 添加 svg 兀素 */}
[0039]SVGMapLabe1.prototype, draw = funetion () {/* 動態(tài)計算文本路徑及 svg 位置*/}
[0040]SVGMapLabe1.prototype.0nRemove = function () {/* 注銷時,刪除 svg 兀素 */}
[0041]構(gòu)造函數(shù)SVGMapLabel (options)的作用為創(chuàng)建疊加層對象,并將外部數(shù)據(jù)轉(zhuǎn)換為對象屬性,以利于對象的其他方法共享。外部數(shù)據(jù)包括標注文本的字體參數(shù)、標注路徑的經(jīng)緯度數(shù)據(jù)及其惟一性標識等。
[0042]當疊加層對象完成首次實例化并處于準備顯示的狀態(tài)時,Google Maps API就會調(diào)用疊加層對象的onAdd O方法將其添加到Google地圖,也就是把1.1節(jié)所示的svg樹作為一個DOM節(jié)點添加到Google地圖窗格對象MapPanes中。svg代碼的添加有兩種方式:一種是將1.1節(jié)的svg文檔整塊加入到窗格層Pane節(jié)點上;另一種是按節(jié)點對象逐級加入。前者無法進行節(jié)點控制,后者可以控制各級節(jié)點的屬性。因為Google地圖隨縮放等級而變化,疊加在它上面的svg圖塊的位置及標注路徑也是動態(tài)變化的,這種變化需要后續(xù)計算才能確定,因此只能采用后一種方式。窗格對象MapPanes有多個窗格層Pane,且有特定的疊置順序,文本標注最好放在最上層MapPanes.f 1atPane。
[0043]完成上述疊加層初始化之后,每當需要在地圖上繪制疊加層時(包括首次添加疊加層時),Google MapsAPI都會調(diào)用draw O方法。在此方法中,使用基類方法getPro jection O檢素疊加層的MapCanvasPro jection對象以得到當前地圖的投影,并據(jù)此重新確定文本標注路徑及所在SVg圖塊的位置。按照習(xí)慣,標注文本應(yīng)始終處于路徑中間部位,且當路徑長度小于某個像素值時不再顯示。具體處理過程如下:
[0044](I)調(diào)用getPro jection O方法獲取當前地圖投影;
[0045](2)指經(jīng)緯度表示的標注路徑轉(zhuǎn)換為當前投影下的像素路徑;
[0046](3)計算像素路徑長度,并與標注文本長度比較。如果太短,則不顯示svg對象。
[0047](4)確定標注文本在像素路徑的起點位置;
[0048](5)按文本長度確定標注文本實際占據(jù)的像素路徑;
[0049](6)比較確定標注文本像素路徑的最小(X,y)像素值,并將其作為svg對象的左上角坐標;
[0050](7)計算標注文本相對svg左上角的像素路徑;
[0051](8)將坐標串表示的文本像素路徑轉(zhuǎn)換為svg中path元素的路徑表示形式,并修改其d屬性。
[0052]除了按文本長度控制標注的顯示,還可以通過地圖縮放級別控制標注的顯示與否。
[0053]SVGMapLabel對象注銷時,Google Maps API調(diào)用onRemove O方法從地圖上移除svg對象。利用對象方法setMap (null)和setMap (map)可從地圖上隱去或復(fù)顯文本標注。
[0054]每個待標注地圖元素均需建立一個或多個文本標注對象,并利用數(shù)組進行管理。
[0055]2應(yīng)用及效果
[0056]SVGMapLabel類是在客戶端進行文本標注的一種方法,可以用于交互標注,也可以與Google地圖上的KML圖層結(jié)合起來,利用KML文檔提供的屬性數(shù)據(jù)對KML圖層中的地圖元素進行自動標注。這里以道路標注為例,說明對KML圖層自動標注的過程。
[0057]道路設(shè)有三個圖層:路面、邊線及中線。標注信息來自中線的KML文檔,其基本結(jié)構(gòu)如圖2所示。每條道路的標注文本取自文檔〈Placemark〉的〈name〉元素值,標注路徑的經(jīng)諱度坐標取自〈Placemark〉的〈coordinates〉元素值。
[0058]實際標注時需要解決兩個問題,
[0059](I)客戶端如何獲取KML文檔;
[0060](2)對于較長道路,能否增加標注個數(shù)。
[0061]利用jQuery函數(shù)$.get O可以方便地讀取服務(wù)器端KML文檔,而利用jQuery函數(shù)$.xml2json(kml)可以將獲得的KML文檔進一步轉(zhuǎn)換為JSON格式以方便讀取其中的數(shù)據(jù)。
[0062]一條道路在不同的縮放級別下,其地圖長度(以像素計)是不同的。若要求標注間隔固定,道路地圖長度增加時,標注的個數(shù)也應(yīng)該增加;反之,則減少,從而使標注個數(shù)適應(yīng)道路長度的變化。實現(xiàn)這種動態(tài)標注的方法如下:
[0063](I)按縮放級別(或比例尺)估算出道路在地圖上的長度(像素);
[0064](2)按固定像素值(如3OO像素)的基本長度將通路等分成若干段;
[0065](3)計算出每段道路的經(jīng)緯度路徑;
[0066](4)應(yīng)用SVGMapLabel為每段道路建立文本標注對象,并設(shè)置其對應(yīng)的縮放級別。
[0067]據(jù)此方法,每條道路Road有多個標注對象label,分別對應(yīng)于地圖map的不同縮放級別zoom和道路的不同路段Pathseg,每個路段還必須賦予惟一標識pathID。下面是利用SVGMapLabel類創(chuàng)建一個標注對象并存入道路標注數(shù)組Label Road的JavaScript代碼:[0068]
【權(quán)利要求】
1.一種基于SVG的Google用戶地圖文本標注方法,其特征在于,將帶有路徑文本的svg對象加入Google地圖的自定義疊加層,并且在繪制此疊加層時,包括以下步驟: (1)調(diào)用OverlayView類的getProiection O方法獲取當前地圖投影; (2)將經(jīng)緯度表示的標注路徑轉(zhuǎn)換為當前投影下的像素路徑; (3)計算像素路徑長度,并與標注文本長度比較,如果太短,則不顯示svg對象; (4)確定標注文本在像素路徑的起點位置,以確保文本處于路徑中部; (5)按文本長度確定標注文本實際占據(jù)的像素路徑; (6)比較確定標注文本像素路徑的最小坐標值,并將其作為svg對象的左上角坐標; (7)計算標注文本相對svg左上角的像素路徑; (8)將坐標串表示的文本像素路徑轉(zhuǎn)換為svg中path元素的路徑表示形式,并替換其d屬性。
2.根據(jù)權(quán)利要求1所述的基于SVG的Google用戶地圖文本標注方法,其特征在于,每個待標注地圖元素均需建立一個或多個文本標注對象,并利用數(shù)組進行管理。
【文檔編號】G06F17/30GK103970859SQ201410191069
【公開日】2014年8月6日 申請日期:2014年4月29日 優(yōu)先權(quán)日:2014年4月29日
【發(fā)明者】楊立法 申請人:楊立法