OpenWebGlobe-開源三維GIS初體驗(附源碼和演示)

1.OpenWebGlobe簡介javascript

OpenWebGlobe是一個高性能的三維引擎。可應用於可視化仿真,遊戲,三維GIS,虛擬現實等領域。它使用純javascript編寫,能夠運行在任何支持HTML五、WebGL的瀏覽器上。使用OpenWebGlobe能夠快速構建一個屬於您本身的三維地球。國內的天地圖三維地球使用的就是該開源程序。天地圖三維地球地址爲http://map.tianditu.com/3d/index3d.htmlhtml

2.OpenWebGlobe的搭建環境java

(1)在Github上下載最新的開源庫,https://github.com/OpenWebGlobe/WebViewergit

(2)搭建WebViewergithub

     下載依賴兩個Google的庫,依次以下closure_libraryclosure-compiler,這個Closure工具使維護一具巨大的javascript代碼庫更容易。Closure本質上是擴展了javascript,並引入了其它語言的一些功能,好比 命名空間,類型檢查和數據隱藏。此外,它實現這些功能不是發生在運行時的。若是感興趣能夠研究一下。OpenWebGlobe就是基於Closure管理js文件的。這裏提供一個OpenWebGlobe編譯使用Closure文件地址爲:https://github.com/downloads/OpenWebGlobe/WebViewer/external.tar.gz,將文件解壓到該external下。如圖chrome

    下載Python2.7.x版本並安裝,修改scripts/setup.bat文件,將Python的路徑修改到與本地安裝路徑相同。如圖canvas

    下載Java JDK1.7.x版本並安裝,因爲編譯時須要調用jar命令,必須在Windows環境變量中指定JAVA_HOME,並在Path中輸入Java的bin路徑c#

    運行 scripts /compile.bat,建議修改該批處理文件,文本末尾加上 pause,這樣報錯能夠看到。若是有報錯信息,通常是你Python版本,必定是2.7,若是錯誤信息中有Java,保證你的JDK及環境變量和版本正確。跨域

   若是編譯正確,compiled 已經生成出了腳本庫,以下瀏覽器

3.第一個OpenWebGlobe例子

     感到不可理解的是官方給出的例子不能運行,OpenWebGlobe的官網可能在維護,他給的資源鏈接不上,最後參考了這篇博客http://blog.sina.com.cn/s/blog_4c8b1bdd01018dxi.html,搭建了基於天地圖的自定義圖層。以下

(1)修改全局入口source/core/globerenderer.js 裏頭部須要添加你建立的自定義圖層,咱們在末尾加載了一個叫owg.hhyImageLayer的自定義圖層(就像c#中的引用同樣,這就是谷歌Closure實現的)以下

goog.provide('owg.GlobeRenderer');
goog.require('goog.debug.Logger');
goog.require('owg.Texture');
goog.require('owg.GlobeCache');
goog.require('owg.MercatorQuadtree');
goog.require('owg.OSMImageLayer');
goog.require('owg.ViewFrustum');
goog.require('owg.i3dImageLayer');
goog.require('owg.owgImageLayer');
goog.require('owg.i3dElevationLayer');
goog.require('owg.owgElevationLayer');
goog.require('owg.GoogleImageLayer');
goog.require('owg.OYMImageLayer');
goog.require('owg.TMSImageLayer');
goog.require('owg.WMSImageLayer');
goog.require('owg.WMTSImageLayer');
goog.require('owg.owgGeometryLayer');
goog.require('owg.owgPointCloudLayer');
goog.require('owg.hhyImageLayer');

 

(2)同時繼續在該文件件中添加本身自定義圖層類型的邏輯處理

      // OpenStreetMap tile layout
      else if (options["service"] == "osm")
      {
         if (goog.isDef(options["url"]) && options["url"].length>0)
         {
            var imgLayer = new OSMImageLayer();
            if (goog.isDef(options["minlod"]))
            {
               imgLayer.userminlod = options["minlod"];
            }
            if (goog.isDef(options["maxlod"]))
            {
               imgLayer.usermaxlod = options["maxlod"];
            }
            imgLayer.Setup(options["url"]);
            index = this.imagelayerlist.length;
            this.imagelayerlist.push(imgLayer);
            this._UpdateLayers();
         }
      }
      //自定義邏輯處理 ,只須要寫下面這段便可
      else if (options["service"] == "hhy") {
            if (goog.isDef(options["url"]) && options["url"].length > 0) {
                var imgLayer = new hhyImageLayer();
                if (goog.isDef(options["minlod"])) {
                    imgLayer.userminlod = options["minlod"];
                }
                if (goog.isDef(options["maxlod"])) {
                    imgLayer.usermaxlod = options["maxlod"];
                }
                imgLayer.Setup(options["url"], options["layer"], options["getTile"]);
                index = this.imagelayerlist.length;
                this.imagelayerlist.push(imgLayer);
                this._UpdateLayers();
          }
      }

在該代碼中將自定義須要用到的參數採用options傳進去,例如此處,我添加一個getTile做爲靈活的圖層路徑返回處理。就是經過經緯度獲取地圖切片。

(3)在source/core/layer添加自定義圖層類imagelayer_hhy.js,在該js中作圖層控制。隨便複製一個原有的圖層,在原有的imagelayer圖層上修改一下,添加getTile處理方法以下

goog.provide('owg.hhyImageLayer');

goog.require('owg.GlobeUtils');
goog.require('owg.ImageLayer');
goog.require('owg.MercatorQuadtree');
goog.require('owg.Texture');

//------------------------------------------------------------------------------
function hhyImageLayer()
{
   this.servers = null;
   this.layer = null;
   this.quadtree = new MercatorQuadtree();
   this.curserver = 0;
 
   //---------------------------------------------------------------------------
   this.Ready = function()
   {
      return true;
   }
   //---------------------------------------------------------------------------
   this.Failed = function()
   {
      return false;
   }
   //---------------------------------------------------------------------------
   this.RequestTile = function (engine, quadcode, layer, cbfReady, cbfFailed, caller) {
       var coords = new Array(4);
       var res = {};
       this.quadtree.QuadKeyToTileCoord(quadcode, res);

       var sFilename = '';
       if (this.getTile) {
           sFilename = this.getTile(res.x, res.y, res.lod, layer);
       } else {

           sFilename = this.servers[this.curserver] + "?T=" +
                      this.layer + "&L=" +
                      res.lod + "&X=" +
                      res.x + "&Y=" +
                      res.y;
       }

       var ImageTexture = new Texture(engine);
       ImageTexture.quadcode = quadcode;   // store quadcode in texture object
       ImageTexture.layer = layer;
       ImageTexture.cbfReady = cbfReady;   // store the ready callback in texture object
       ImageTexture.cbfFailed = cbfFailed; // store the failure callback in texture object
       ImageTexture.caller = caller;
       ImageTexture.loadTexture(sFilename, _cbhhyTileReady, _cbhhyTileFailed, true);


       this.curserver++;
       if (this.curserver >= this.servers.length) {
           this.curserver = 0;
       }

   };
   //---------------------------------------------------------------------------
   this.GetMinLod = function()
   {
      return 0;
   }
  
   //---------------------------------------------------------------------------
   this.GetMaxLod = function()
   {
      return 18;
   }
  
   //---------------------------------------------------------------------------
   this.Contains = function(quadcode)
   {
      if (quadcode.length<19)
      {
         return true;
      } 
      return false;
   }
   //---------------------------------------------------------------------------

   this.Setup = function (serverlist, layer, gettilefn) {
       // Please respect: http://wiki.openstreetmap.org/wiki/Tile_Usage_Policy

       // serverlist:
       //   ["http://a.tile.openstreetmap.org", "http://b.tile.openstreetmap.org", "http://c.tile.openstreetmap.org" ]
       //   or your own tileserver(s).
       //

       this.servers = serverlist;
       this.layer = layer;

       //獲取瓦片路徑的方法
       this.getTile = gettilefn;

   }
}

hhyImageLayer.prototype = new ImageLayer();

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
function _cbhhyTileReady(imgTex)
{
   imgTex.cbfReady(imgTex.quadcode, imgTex, imgTex.layer);
   imgTex.cbfReady = null;
   imgTex.cbfFailed = null;
   imgTex.quadcode = null;
   imgTex.caller = null;
   imgTex.layer = null;
}
//--------------------------自定義獲取切片的方法----------------------------------------------------
function _cbhhyTileFailed(imgTex)
{
   imgTex.cbfFailed(imgTex.quadcode, imgTex.caller, imgTex.layer);
   imgTex.cbfReady = null;
   imgTex.cbfFailed = null;
   imgTex.quadcode = null;
   imgTex.caller = null;
   imgTex.layer = null;
}
//------------------------------------------------------------------------------
View Code

(4)調用圖層編寫第一個demo,要將整個文件部署到本地服務器上(我是發佈到IIS上的),由於有些資源會出現訪問權限問題。

這裏咱們調用一下天地圖的三維地圖影像服務。所有代碼以下

<!DOCTYPE html>
<html lang="en">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1">

<script type="text/javascript" src="../../../external/closure-library/closure/goog/base.js"></script>
<script type="text/javascript" src="../../../compiled/deps.js"></script>
<script type="text/javascript">goog.require('owg.OpenWebGlobe');</script>

<script type="text/javascript">

//------------------------------------------------------------------------------
// called every frame:
function OnRender(context)
{
   ogSetTextColor(context, 0,1,0);
   ogDrawText(context, "www.cnblogs.com/ATtuing", 0, 20);
}
//------------------------------------------------------------------------------

function OnMouseDown(context, button, mx, my)
{
   var scene = ogGetScene(context);
    var world = ogGetWorld(scene);
   
    var result = ogPickGlobe(scene, mx, my);
    /*if (result[0])
    {
        alert("hit: "+ result[1]+ ", " + result[2] + ", " + result[3]);
    }*/
}

function main()
{
    // (1) Specify where artwork is located.
    // This must be a directory and end with "/". It is recommended
    // to have it relative to this html (to prevent cross origin issues).
    ogSetArtworkDirectory("../../../art/");
   
   // (2) create an OpenWebGlobe context using canvas
   // first parameter is canvas-id and second is "fullscreen"
   var ctx = ogCreateContextFromCanvas("canvas", true);
  
   // (3) Create a virtual globe
   var globe = ogCreateGlobe(ctx);
  
   // (4) Add image and an elevation layers
var tdtlayer = {
      url: ['http://t7.tianditu.cn/DataServer'],
      layer: 'img_w',
      service: 'hhy',
      getTile: function (x, y, z) {
          return 'http://t0.tianditu.cn/DataServer?T=img_w&X=' + x + '&y=' + y + '&L=' + z;
      }
  };
ogAddImageLayer(globe, tdtlayer);
   
    //------------ Create a POI with default style -----------------------------------
    var scene = ogGetScene(ctx);
   
    var PoiDefinition =
    {
        text         :     "Hello World! 世界你好",
        position :  [7.66, 46.13, 6000],
        size         :     50
    };
   
    var poi = ogCreatePOI(scene, PoiDefinition);
    //---------------------------------------------------------------------------

   // (5) Set the "Render-Callback" function.
   // The callback function will be called everytime a frame is drawn.
   ogSetRenderFunction(ctx, OnRender);
    ogSetMouseDownFunction(ctx, OnMouseDown);
  
   // (6) Set the background color
   ogSetBackgroundColor(ctx, 0.2,0.2,0.7,1);

}
//------------------------------------------------------------------------------
  
</script>

</head>
<body onload="main()" style="padding:0px; margin:0px; overflow:hidden;">
   <canvas id="canvas"></canvas>         
</body>
</html>
View Code

它添加有平移、縮放,以及視角切換,效果以下:

                                                                      全圖

                                                                     贛州斜視

                                                                    故宮

                                                                   人民大會堂 斜視

4.總結

這個OpenWebGlobe是咱們老師讓我研究一下的,在研究過程當中也發現文檔過於少,例子打不開的問題,但總的來講OpenWebGlobe是一個很是不錯的開源GIS三維js庫,之後有時間的話我會多研究一下的。有興趣的能夠查看我附上源碼,直接部署個人源碼就能夠省去第二步的OpenWebGlobe的搭建環境。

期待您的關注…………

源碼地址:http://pan.baidu.com/s/1nu7nSI9

在線演示地址:http://sharegis.cn/WebViewer-master/WebViewer-master/source/demos/01_HelloWorld/demo.html(由於跨域顯示有點問題,本地部署的話沒問題)。

做者:ATtuing

出處:http://www.cnblogs.com/ATtuing

本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接。

相關文章
相關標籤/搜索