考慮將shp格式的地圖數(shù)據(jù)發(fā)布到webgis上去的想法有一段時間了,正好有空閑時間便忙碌開來,沒想到期間遇到了諸多的問題
1.開發(fā)工具:
Geoserver,Openlayer,Ext-js,Postgres/Postgis,Python2.6,PIL,TileCache
2.地圖數(shù)據(jù)
我的地圖數(shù)據(jù)是08年的全國地圖,按每個省市分隔開來,每個省市又分了若干個圖層文件,格式是mapinfo的Tab,容量10G
由于沒有全國大比例圖,在偶然的一個機會從網(wǎng)上下載到一份C/S的監(jiān)控系統(tǒng),沒想到安裝目錄內(nèi)就有一份全國圖,就是比例不高。
3.處理過程
1.Tab轉(zhuǎn)換成shp: Ogr工具可以完成這兩種格式的轉(zhuǎn)換,編寫python腳本可以輕易處理完
在轉(zhuǎn)換數(shù)據(jù)之前需要提醒的是,發(fā)現(xiàn)在處理多邊形圖層時,這個多邊形圖層并不是簡單的多邊形,也就是那種mapinfo允許存在polygon和pline的圖層,這將導(dǎo)致之后的導(dǎo)入空間數(shù)據(jù)庫的失敗,因為postgis要求每個圖層數(shù)據(jù)類型必須是一致的,不能存在多種類型,所以編寫mapbasic腳本,將這些pline對象從這多邊形圖層中剔去即可。
2.數(shù)據(jù)校驗: 這個過程非常重要,任何提供的的矢量數(shù)據(jù)都有可能存在錯誤數(shù)據(jù),所以第一步必須要修復(fù)這些可能存在的錯誤,工具就是ArcGis,使用其工具對每個省市的每個圖層文件進行修復(fù)。
3.導(dǎo)入空間數(shù)據(jù)庫: 編寫腳本,將shp數(shù)據(jù)轉(zhuǎn)成sql文件,此時必須注意空間數(shù)據(jù)庫的字符編碼與sql數(shù)據(jù)字符編碼要吻合或者能夠自動轉(zhuǎn)換。pg2sq由于轉(zhuǎn)換成sql時,由于shp數(shù)據(jù)中某些圖層表存儲的字符編碼不統(tǒng)一導(dǎo)致產(chǎn)生的非法的sql數(shù)據(jù),所以必須對這些數(shù)據(jù)進行修正,并采用ultraedit將數(shù)據(jù)進行轉(zhuǎn)碼成數(shù)據(jù)的字符集類型,我使用的是utf-8.
4.數(shù)據(jù)分離: 由于提供的全國地理數(shù)據(jù)是沒有根據(jù)應(yīng)用來分層的,所有的道路都合在同一個叫road的圖層內(nèi),然后通過屬性來區(qū)分道路的級別,由于我們在控制顯示道路時是需要分層分級別的,所以必須將這些數(shù)據(jù)要分離成不同的道路圖層,道路共10級別(0-9),編寫腳本將每個省市的道路切割成road_?10級道路層(select into即可搞定)。
同樣,除了道路之外還有其他的比如河流,POI對象等都需要進行分割到不同圖層以便更精確的現(xiàn)實控制。
5.配置Geoserver: 數(shù)據(jù)都有了,接下來就是配置繪制引擎了。Geoserver提供WFS,WMS服務(wù),性能一般,由于是java開發(fā)的。不管3721,配置了最新的I5主機,將java虛擬機的內(nèi)存設(shè)置的最大,將postgis的數(shù)據(jù)庫內(nèi)存也足夠調(diào)大。手工添加了1,2個圖層到geoserver,preview一下,ok!
接下來編寫控制這些圖層的SLD了,這些花了好些時間學(xué)習(xí)和開發(fā)(學(xué)習(xí)sld對我以前開發(fā)嵌入式地圖引擎風(fēng)格配置也是一種幫助,之后的嵌入式地圖引擎也全部使用sld進行配置了!)
由于全國數(shù)據(jù)分31個省市,每個省市都配置了21個圖層,所以要人工11加到geoserver還真是很大的問題,不過沒關(guān)系,有python在手,然后對geoserver的配置文件研究了一把便寫了腳本將幾百個圖層全加了進去,然后將這些圖層按省市進行分組,再次Preview,ok!
6.Cache Tile生成: 使用過GeoWebCache,發(fā)現(xiàn)很多地方實在不好理解,幸好找到了TileCache,代碼也容易修改,研讀了TileCache代碼之后修改了N處地方,把效率提高了10倍以上。現(xiàn)在的問題在于Tilecache實現(xiàn)了Disk Cache,Memory Cache,但就是沒有DB cache,每個tile將創(chuàng)建一個文件,如果這些文件很小,有的甚至才幾十字節(jié)也要浪費一個文件塊空間,效率不高,如果采用db的話空間就能節(jié)省很多,等以后有了時間自己編寫一個后端為postgres的Tile Cache吧。
Tile Cache生成有些問題要注意:
1. 空白tile: 由于我設(shè)置的繪制設(shè)置的BBox非常大,所以在繪制的時候有些空白區(qū)域也將提交給geoserver進行處理,這樣浪費了處理時間,同時這些產(chǎn)生的小規(guī)格圖塊大大占據(jù)了磁盤空間,所以修改的代碼將不存儲這些空白tile,僅僅存儲這些tile的文件名稱,而不保存內(nèi)容
2. tilecache的Resolutions,ZoomLevels,BBox和Openlayers的屬性必須一樣,否則Opnelayers無法顯示正確的tile
3. tile相交檢測: 同樣是空白區(qū)域的繪制,如果每次都提交給geoserver的話,geoserver將根據(jù)配置的layer去相交并繪制一次,這就完全沒有必要的,我的解決方式就是提前將31個省市產(chǎn)生他們的MBR,然后再tile進行提交給geoserver之前,將請求的tile的bbox與這些省市的mbr進行相交測試,只有相交的圖層才送入geoserver繪制
4. 大網(wǎng)格繪制: 每次以256×256的規(guī)格給geoserver繪制全國圖的話效率實在太低,之后修改成2048×2048規(guī)格,整體的繪制效率上升了n倍,繪制完了之后采用split_tile.py將這些大塊切割成256規(guī)格的小塊,必須注意產(chǎn)生的序號
寫得好累
1.開發(fā)工具:
Geoserver,Openlayer,Ext-js,Postgres/Postgis,Python2.6,PIL,TileCache
2.地圖數(shù)據(jù)
我的地圖數(shù)據(jù)是08年的全國地圖,按每個省市分隔開來,每個省市又分了若干個圖層文件,格式是mapinfo的Tab,容量10G
由于沒有全國大比例圖,在偶然的一個機會從網(wǎng)上下載到一份C/S的監(jiān)控系統(tǒng),沒想到安裝目錄內(nèi)就有一份全國圖,就是比例不高。
3.處理過程
1.Tab轉(zhuǎn)換成shp: Ogr工具可以完成這兩種格式的轉(zhuǎn)換,編寫python腳本可以輕易處理完
在轉(zhuǎn)換數(shù)據(jù)之前需要提醒的是,發(fā)現(xiàn)在處理多邊形圖層時,這個多邊形圖層并不是簡單的多邊形,也就是那種mapinfo允許存在polygon和pline的圖層,這將導(dǎo)致之后的導(dǎo)入空間數(shù)據(jù)庫的失敗,因為postgis要求每個圖層數(shù)據(jù)類型必須是一致的,不能存在多種類型,所以編寫mapbasic腳本,將這些pline對象從這多邊形圖層中剔去即可。
2.數(shù)據(jù)校驗: 這個過程非常重要,任何提供的的矢量數(shù)據(jù)都有可能存在錯誤數(shù)據(jù),所以第一步必須要修復(fù)這些可能存在的錯誤,工具就是ArcGis,使用其工具對每個省市的每個圖層文件進行修復(fù)。
3.導(dǎo)入空間數(shù)據(jù)庫: 編寫腳本,將shp數(shù)據(jù)轉(zhuǎn)成sql文件,此時必須注意空間數(shù)據(jù)庫的字符編碼與sql數(shù)據(jù)字符編碼要吻合或者能夠自動轉(zhuǎn)換。pg2sq由于轉(zhuǎn)換成sql時,由于shp數(shù)據(jù)中某些圖層表存儲的字符編碼不統(tǒng)一導(dǎo)致產(chǎn)生的非法的sql數(shù)據(jù),所以必須對這些數(shù)據(jù)進行修正,并采用ultraedit將數(shù)據(jù)進行轉(zhuǎn)碼成數(shù)據(jù)的字符集類型,我使用的是utf-8.
4.數(shù)據(jù)分離: 由于提供的全國地理數(shù)據(jù)是沒有根據(jù)應(yīng)用來分層的,所有的道路都合在同一個叫road的圖層內(nèi),然后通過屬性來區(qū)分道路的級別,由于我們在控制顯示道路時是需要分層分級別的,所以必須將這些數(shù)據(jù)要分離成不同的道路圖層,道路共10級別(0-9),編寫腳本將每個省市的道路切割成road_?10級道路層(select into即可搞定)。
同樣,除了道路之外還有其他的比如河流,POI對象等都需要進行分割到不同圖層以便更精確的現(xiàn)實控制。
5.配置Geoserver: 數(shù)據(jù)都有了,接下來就是配置繪制引擎了。Geoserver提供WFS,WMS服務(wù),性能一般,由于是java開發(fā)的。不管3721,配置了最新的I5主機,將java虛擬機的內(nèi)存設(shè)置的最大,將postgis的數(shù)據(jù)庫內(nèi)存也足夠調(diào)大。手工添加了1,2個圖層到geoserver,preview一下,ok!
接下來編寫控制這些圖層的SLD了,這些花了好些時間學(xué)習(xí)和開發(fā)(學(xué)習(xí)sld對我以前開發(fā)嵌入式地圖引擎風(fēng)格配置也是一種幫助,之后的嵌入式地圖引擎也全部使用sld進行配置了!)
由于全國數(shù)據(jù)分31個省市,每個省市都配置了21個圖層,所以要人工11加到geoserver還真是很大的問題,不過沒關(guān)系,有python在手,然后對geoserver的配置文件研究了一把便寫了腳本將幾百個圖層全加了進去,然后將這些圖層按省市進行分組,再次Preview,ok!
6.Cache Tile生成: 使用過GeoWebCache,發(fā)現(xiàn)很多地方實在不好理解,幸好找到了TileCache,代碼也容易修改,研讀了TileCache代碼之后修改了N處地方,把效率提高了10倍以上。現(xiàn)在的問題在于Tilecache實現(xiàn)了Disk Cache,Memory Cache,但就是沒有DB cache,每個tile將創(chuàng)建一個文件,如果這些文件很小,有的甚至才幾十字節(jié)也要浪費一個文件塊空間,效率不高,如果采用db的話空間就能節(jié)省很多,等以后有了時間自己編寫一個后端為postgres的Tile Cache吧。
Tile Cache生成有些問題要注意:
1. 空白tile: 由于我設(shè)置的繪制設(shè)置的BBox非常大,所以在繪制的時候有些空白區(qū)域也將提交給geoserver進行處理,這樣浪費了處理時間,同時這些產(chǎn)生的小規(guī)格圖塊大大占據(jù)了磁盤空間,所以修改的代碼將不存儲這些空白tile,僅僅存儲這些tile的文件名稱,而不保存內(nèi)容
2. tilecache的Resolutions,ZoomLevels,BBox和Openlayers的屬性必須一樣,否則Opnelayers無法顯示正確的tile
3. tile相交檢測: 同樣是空白區(qū)域的繪制,如果每次都提交給geoserver的話,geoserver將根據(jù)配置的layer去相交并繪制一次,這就完全沒有必要的,我的解決方式就是提前將31個省市產(chǎn)生他們的MBR,然后再tile進行提交給geoserver之前,將請求的tile的bbox與這些省市的mbr進行相交測試,只有相交的圖層才送入geoserver繪制
4. 大網(wǎng)格繪制: 每次以256×256的規(guī)格給geoserver繪制全國圖的話效率實在太低,之后修改成2048×2048規(guī)格,整體的繪制效率上升了n倍,繪制完了之后采用split_tile.py將這些大塊切割成256規(guī)格的小塊,必須注意產(chǎn)生的序號
寫得好累