1.OpenWebGlobe简介
OpenWebGlobe是一个高性能的三维引擎。可应用于可视化仿真,游戏,三维GIS,虚拟现实等领域。它使用纯javascript编写,可以运行在任何支持HTML5、WebGL的浏览器上。使用OpenWebGlobe可以快速构建一个属于您自己的三维地球。国内的天地图三维地球使用的就是该开源程序。天地图三维地球地址为http://map.tianditu.com/3d/index3d.html。
2.OpenWebGlobe的搭建环境
(1)在Github上下载最新的开源库,https://github.com/OpenWebGlobe/WebViewer
(2)搭建WebViewer
下载依赖两个Google的库,依次如下closure_library和closure-compiler,这个Closure工具使维护一具巨大的javascript代码库更容易。Closure本质上是扩展了javascript,并引入了其它语言的一些功能,比如 命名空间,类型检查和数据隐藏。此外,它实现这些功能不是发生在运行时的。如果感兴趣可以研究一下。OpenWebGlobe就是基于Closure管理js文件的。这里提供一个OpenWebGlobe编译使用Closure文件地址为:https://github.com/downloads/OpenWebGlobe/WebViewer/external.tar.gz,将文件解压到该external下。如图
下载Python2.7.x版本并安装,修改scripts/setup.bat文件,将Python的路径修改到与本地安装路径相同。如图
下载Java JDK1.7.x版本并安装,由于编译时需要调用jar命令,必须在Windows环境变量中指定JAVA_HOME,并在Path中输入Java的bin路径
运行 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;
}
//------------------------------------------------------------------------------