地圖的開發研究--基於openlayers+geoserver+tomcat的離線地圖--postgis空間數據庫

此節主要介紹以下內容:    

       1、安裝配置postgresqlpostgis,升級postgresql爲空間數據庫,導入.shp格式的地圖,轉化爲空間數據

2深入研究geoserver的用法和功能,實現其連接postgis空間數據庫,發佈地圖

3完成geoserver的發佈數據庫的地圖,並使用Udig修改地圖樣式

4學習geoserverWFS服務,實現按照過濾條件高亮查詢的圖層。 


1.....前期準備工作:

   前周主要學習的都是geoserver調用的本地.shp格式的地圖數據,其實geoserver的數據源可以有很多種,如下所示:


     可見,geoserver可以讀取很多的數據源,經過內部機制處理,發佈爲一個地圖圖層,本週學習的是以PostGis Database空間數據庫作爲數據源,前期使用uboss平臺的時候,框架組曾經使用過postgresql數據庫,只知道其優勢就是可以存儲地圖數據,具體沒有研究過,所以本週進行了相應的學習和配置。


關於PostgreSQL

   通過上網查閱資料可以發現,PostgreSQL(以下簡稱PG數據庫) 是一個自由的對象-關係數據庫服務器(數據庫管理系統),除了作爲普通關係數據庫所具有的的特徵外,我看到其最吸引的優勢是其數據類型,包括:任意精度的數值無限制長度文本幾何圖元IP地址IPv6地址無類域間路由地址塊,MAC地址數組…………此外,用戶可以創建自定義數據類型,通常通過PostgreSQLGiST機制,它們也能被很好得索引,比如PostGIS地理信息系統的數據類型 同時也要指出的是,PostgreSQL 對接口的支持也是非常豐富的,幾乎支持所有類型的數據庫客戶端接口。這一點也可以說是 PostgreSQL 一大優點。

  

關於PostGIS

     在PostgreSQL中已經定義了一些基本的集合實體類型,這些類型包括:點(POINT)、線(LINE)、線段(LSEG)、方形(BOX)、多邊形(POLYGON)和圓(CIRCLE;另外,PostgreSQL定義了一系列的函數和操作符來實現幾何類型的操作和運算;同時,PostgreSQL引入空間數據索引R-tree

     儘管在PostgreSQL提供了上述幾項支持空間數據的特性,但其提供的空間特性很難達到GIS的要求,主要表現在:缺乏複雜的空間類型;沒有提供空間分析;沒有提供投影變換功能。PostGIS是對象關係型數據庫系統PostgreSQL的一個擴展,PostGIS提供如下空間信息服務功能:空間對象、空間索引、空間操作函數和空間操作符。同時,PostGIS遵循OpenGIS的規範。PostGIS還提供以下功能:數據庫座標變換,球體長度運算,三維的幾何類型,空間聚集函數,柵格數據類型。(如果要深層次的研究可以參考:http://www.opengeo.cn/dz/forum.php?mod=viewthread&tid=71&reltid=49&pre_thread_id=0&pre_pos=7&ext=CB)


 關於安裝配置:

     PostgreSQL的安裝和普通的數據庫安裝差別不大,端口,用戶名,密碼等等,其中需要注意的是選擇數據庫存儲區域的運行時語言環境(字符編碼格式)。在選擇語言環境時,若選擇"default locale"會導致安裝不正確;同時,PostgreSQL 不支持 GBK 和 GB18030 作爲字符集,如果選擇其它四個中文字符集:中文繁體 香港(Chinese[Traditional], Hong Kong S.A.R.)、中文簡體 新加坡(Chinese[Simplified], Singapore)、中文繁體 臺灣(Chinese[Traditional], Taiwan)和中文繁體 澳門(Chinese[Traditional], Marco S.A.R.),會導致查詢結果和排序效果不正確。建議選擇"C",即不使用區域。安裝完成後使用

進行管理;


   升級PostgreSQL爲postgis空間數據庫,此處需要注意的是版本的要對應,開始升級的時候版本不一致,導致安裝失敗,無法建立空間數據庫。我安裝的PostgreSQL是9.3的所以官網下載了相應的升級插件,如下:


  升級後PostgreSQL插件裏面會出現PostGIS Shapfile and DBF loader ,說明已經產生了一個postgis空間數據庫根據名字就可以知道,可以導入.shp格式的地圖,不過需要注意的是,導入的時候如果地圖數據含有中文數據,一定要在options的字符集設置爲GBK,否則導入失敗。導入成功後,就會發現空間數據庫下產生地圖的數據表:



   其實看到這裏的時候,我才明白當初在geoserver導入本地地圖的時候,曾經看到過這些字段名,可以說明geoserver和此時的導入的解析結果是一致的,導入是成功的。




2.....geoserver以PostGIS作爲數據源

上面已經前期工作準備就緒,現在就可以連接PostGIS,以剛纔導入的數據作爲數據源,形成圖層。

  在選擇的工作區下,添加數據存儲,進行如下配置,


   提交無誤後,會自動跳到圖層管理頁面,因爲數據庫中存在三個空間數據表,點擊發布,進行圖層配置(上週已描述)之後就可以通過圖層預覽功能看到相應的圖層:



   看到這個地圖,可以說明geoserverpostgresql數據庫可以正常連接,同時經過測試發現,修改postgresql空間數據庫的表記錄時,相應的圖層的數據也會改變,這就爲我們今後通過修改數據庫的信息從而發佈新的圖層提供了極大的便利,我們可以像以前關係數據庫的操作一樣操作地圖。


3.....使用Udig修改圖層的樣式:

uDig是一個 open source (EPL and BSD桌面應用程序框架,構建在Eclipse RCPGeoTools(一個開源的Java GIS工具包)上的桌面GIS(地理信息系統是一款開源桌面GIS軟件,基於JavaEclipse平臺,可以進行shp格式地圖文件的編輯和查看;是一個開源空間數據查看器/編輯器,對OpenGIS標準,關於互聯網GIS、網絡地圖服務器和網絡功能服務器有特別的加強。通過此軟件可以創建本地地圖,可以連接geoserver的地圖,可以連接數據庫的地圖圖層…………


  此處我主要使用的是通過geoserverWMS服務和Udig進行連接,在Udig內查看相應工作區的圖層,這次我學習的是發佈的全國地圖的樣式修改,右擊圖層,改變樣式選項,可以看到如下圖的編輯,Label選項的內容又見到了上述熟悉的幾個字段,這裏我顯示的是名字(如北京市,遼寧省等地名),另外需要注意的是如果有中文顯示,字體選項的腳本語言要是中文GB2312



在相應的設置完成後,點擊XML,複製其中的內容或者導出樣式文件,這裏我選擇的是複製,然後到geoserver配置界面新建樣式,將樣式內容粘貼到配置框,如下:


然後到剛纔在Udig打開的圖層配置界面,選中此圖層樣式,前後對比效果如下:




3.....使用geoserverWFS服務,按照過濾條件高亮查詢的圖層

  利用Geoserver可以把數據作爲 maps/images來 發佈(利用WMS來實現),上次已經使用實現過,也可以直接發佈實際的數據(利用WFS來實現),所以這次學習使用了這個服務來實現,同時也提供了修改,刪除和新增的功能(利用WFS-T)

   Wfs服務包含getFeature操作,用來檢索要素信息,支持返回gml格式的地理要素表達。根據getFeature提供的參數FILTER,我們就可以實現條件查詢。

   Filter是一種基於XML的並且符合OGC規範的語言。SLD用它來實現複雜的Rule選擇。WFS在所有需要定位操作對象的地方都會使用Filter。Filter的作用是構建一個表達式,返回值就是Feature的集合,換句話說Filter就如他的名字一般爲我們從一個集合中過濾出一個滿足我們要求的子集。而過濾的方法就是Filter定義的操作符。Filter定義了三種操作符:地理操作符(Spatial operators),比較操作符(Comparison operators)和邏輯操作符(Logical operators)。

   所以就通過自定義XML語句作爲查詢條件:

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. XML = '<?xml version="1.1.0" encoding="UTF-8"?>' ;  
  2.         XML = '<wfs:GetFeature service="WFS" version="1.0.0" outputFormat="GML2"' ;  
  3.         XML += '  xmlns:topp="http://www.openplans.org/topp"' ;  
  4.         XML += '  xmlns:wfs="http://www.opengis.net/wfs"' ;  
  5.         XML += '  xmlns:ogc="http://www.opengis.net/ogc"' ;  
  6.         XML += '  xmlns:gml="http://www.opengis.net/gml"';  
  7.         XML += '  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';  
  8.         XML += '  xsi:schemaLocation="http://www.opengis.net/wfs';  
  9.         XML+= ' http://schemas.opengis.net/wfs/1.1.0/WFS-basic.xsd">';          
  10.         //上面是查詢用的gml的前綴  
  11.         XML += '<wfs:Query typeName="mytest:bou2_4p">';  
  12.         XML += '<wfs:PropertyName>mytest:NAME</wfs:PropertyName>';  
  13.         XML += '<wfs:PropertyName>mytest:the_geom</wfs:PropertyName>';    
  14.         XML += '<ogc:Filter>' ;  
  15.         XML += '<ogc:Intersects>' ;  
  16.         XML += '<ogc:PropertyName>mytest:the_geom</ogc:PropertyName>' ;  
  17.         XML += ' <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">';  
  18. // 查詢條件 北京地界BBOX範圍  
  19.   XML += '<gml:coordinates>116.817265,40.5296504</gml:coordinates>' ;  
  20.         XML += '</gml:Point>' ;  
  21.         XML += '</ogc:Intersects>' ;  
  22.         XML += '</ogc:Filter>';  
  23.         XML += '</wfs:Query>' ;  
  24.         XML += '</wfs:GetFeature>';  

調用WFS服務:

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. var request = OpenLayers.Request.POST({  
  2.                  url: "http://localhost:8080/geoserver/wfs?",  
  3.                  data: xmlPara,  
  4.                  callback: onComplete  
  5.              });     


然後通過Vector臨時圖層(自己這樣理解的)添加查詢的地理要素,浮在原地圖圖層上面:

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. var temVectorLayer=new OpenLayers.Layer.Vector("Vector Layer");  
  2.  var polygon = feature.geometry.components[0].clone();  
  3.  var vec = new OpenLayers.Feature.Vector(polygon);  
  4.  temVectorLayer.addFeatures([vec]);  

  

效果圖:



總結:

   這一週主要是對geoserver的再研究,發現它的功能還是很多的,爲了學習其功能和用法,學習的東西很多,如空間數據庫的安裝配置,如Udig軟件的使用,拓寬了自己的知識面,由於geoserver符合OPG規範,所以今後學習其他的地圖服務器的時候會容易點。在實現過程中遇到很多問題,不過還是很好的解決了,例如加載wfs的寫法後,發現怎麼加載都沒反應,後來在IE中調試發現,報“拒絕訪問”的錯誤,百度後得知存在跨域問題。先要改變全局變量OpenLayers.ProxyHost的值,設置成服務器的地址,url則爲提供數據的地址,它和服務器不在同一個域中,這實際上是利用服務器進行了中轉,因爲服務器去跨域取數據要靈活的多。具體要修改的就是修改OpenLayers\examples\proxy.cgi配置文件,

添加geoserver服務器的地址,問題就解決了,最終實現了WFS服務。

  

 

遺留問題:

 1.樣式使用問題:geoserver直接加載本地.shp格式的地圖發佈的圖層使用樣式沒有問題,但是連接postgis數據庫的地圖使用樣式時,地圖都無法發佈使用,網上查了原因,說是因爲地圖中含有中文數據(我使用的是上述的北京地圖,含有地名等中文),要修改樣式xmlencoding=GBK可是修改之後還是不行,現在問題還沒解決。

 2.關於使用WFS實現過濾條件查詢:上述使用的是自己寫的XML,但是後來網上說OpenLayers已經寫好了Filter過濾條件和轉成xml的類,這樣Filter標籤裏的內容不用逐個編寫了,以後的章節將會對此進行講解

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. function conformationFilter(geo) {  
  2. var filter_1_0 = new OpenLayers.Format.Filter.v1_0_0();  
  3. //也可以使用1.1版本構造過濾條件  
  4.     //var filter_1_1 = new OpenLayers.Filter({ version: "1.1.0" });  
  5.     var xml = new OpenLayers.Format.XML(); //構造xml格式的文件  
  6.     var filter = new OpenLayers.Filter.Logical({//邏輯操作符  
  7.         type: OpenLayers.Filter.Logical.AND, //並且更改爲或者  
  8.         filters: [  
  9.         new OpenLayers.Filter.Spatial({  
  10.             type: OpenLayers.Filter.Spatial.INTERSECTS, //INTERSECTS, //相交OK  
  11.             value: geo,  
  12.             projection: "EPSG:4326"  
  13.         }),  
  14.  //構造指定格式的xml  
  15.     return result = xml.write(filter_1_0.write(filter));  


3.其實這段時間做的GIS地圖都很簡單,因爲圖層很少,所以放大或者縮小地圖的時候加載速度問題不是很明顯,目前對於此方法的解決方法很普遍流行的是地圖瓦片的技術,和geoserver結合使用的就是geowebcachegeowebcache就相當於是openlayergeoserver之間的中介,首先,geowebcache會根據你的配置信息,把相應的地圖圖層切好圖,存放在磁盤中,然後在使用openlayer加載地圖服務的時候,把地圖服務的地址指向geowebcachegeowebcache接收到這些請求後,會根據請求的位置和比例尺在切片目錄中找到對應的瓦片,然後返回給你,省去了動態生成地圖的過程,速度大幅度提高,而且由於請求的圖片資源是事先生成好的,瀏覽器加載這些圖片之後,下一次再去請求同樣的圖片,就會從瀏覽器的緩存中拉去,速度進一步提高!

轉自:http://blog.csdn.net/songjian1314/article/details/17263865
發佈了14 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章