之前的一篇博客是关于载入粗三维模型的,见http://blog.csdn.net/giser_whu/article/details/43452703,这个地方还存在着不能载入纹理的问题,一直没呢解决。那么WW怎样载入经常使用的三维模型格式(3ds、obj、skp)呢。通过一番搜索,了解到WW能够载入collada的dae格式的三维模型。而且还能够载入kml\kmz文件。那么WW载入三维模型的方法就出来了:首先将其它格式三维模型转换为kmz或kml文件,再载入。这里我是从su的三维模型库中下载的skp文件,在su中能够直接转换为kmz文件,通过測试,这种方法是可行的。先来看下效果图:

1.效果图

第一幅是德国标志性建筑——柏林奥林匹克体育场。能够看到效果还是能够的,只是没有使用lod技术,一旦模型数量增多,会卡顿。
第二幅是也是德国地标性建筑——柏林电视塔。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ2lzZXJfd2h1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

第三幅是3D City DB上的德国柏林一些collada三维模型,须要的能够去下载做下測试

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ2lzZXJfd2h1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

2.实现方法

开头已经明白了WW载入三维模型的路线。WW又提供了载入kml/kmz文件的demo(KMLViewer),所以要实现这个是非常easy的了。仅仅需依据自己的须要修改原demo。整合到自己的project下就可以,这里我修改原demo,编写了SmartScopeKMLViewer,方法參见之前的博客。所用到的数据,整理完上传到CSDN资源,须要的能够去下载。下载地址:http://download.csdn.net/detail/liushuo_whu/8512739

3.源码

/*
Copyright (C) 2001, 2010 United States Government
as represented by the Administrator of the
National Aeronautics and Space Administration.
All Rights Reserved.
*/ package gov.nasa.worldwindx.examples.kml; import gov.nasa.worldwind.WorldWind;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.awt.WorldWindowGLCanvas;
import gov.nasa.worldwind.layers.RenderableLayer;
import gov.nasa.worldwind.ogc.kml.KMLAbstractFeature;
import gov.nasa.worldwind.ogc.kml.KMLRoot;
import gov.nasa.worldwind.ogc.kml.impl.KMLController;
import gov.nasa.worldwind.render.Offset;
import gov.nasa.worldwind.retrieve.RetrievalService;
import gov.nasa.worldwind.util.WWIO;
import gov.nasa.worldwind.util.WWUtil;
import gov.nasa.worldwind.util.layertree.KMLLayerTreeNode;
import gov.nasa.worldwind.util.layertree.KMLNetworkLinkTreeNode;
import gov.nasa.worldwind.util.layertree.LayerTree;
import gov.nasa.worldwindx.examples.util.BalloonController;
import gov.nasa.worldwindx.examples.util.HotSpotController; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.net.URL; import javax.swing.SwingUtilities;
import javax.xml.stream.XMLStreamException; /**
* 导入KML或KMZ文件,以图层形式查看。KML或KMZ文件的内容显示为一个要素树。在要素树上点击KML要素能够查看该要素
* 。在球上点击要素能够弹出要素的描写叙述信息框
*/
public class SmartScopeKMLViewer
{
public static class KMLUtil
{
protected LayerTree layerTree; // 图层树
protected RenderableLayer hiddenLayer; // 渲染图层(图层树) protected HotSpotController hotSpotController; // 热点controller
protected KMLApplicationController kmlAppController; // KMLcontroller
protected BalloonController balloonController; // BalloonController
protected WorldWindowGLCanvas wwd; // ww public KMLUtil(WorldWindowGLCanvas worldWindowGLCanvas)
{
this.wwd = worldWindowGLCanvas;
// 初始化图层树
this.layerTree = new LayerTree(new Offset(20d, 160d, AVKey.PIXELS,
AVKey.INSET_PIXELS));
// this.layerTree.getModel().refresh(this.wwd.getModel().getLayers()); // 图层树渲染图层
this.hiddenLayer = new RenderableLayer();
this.hiddenLayer.addRenderable(this.layerTree);
this.wwd.getModel().getLayers().add(this.hiddenLayer); // 注冊图层选择和气球热点选择事件监听
this.hotSpotController = new HotSpotController(this.wwd);
// 注冊kml事件监听
this.kmlAppController = new KMLApplicationController(this.wwd); this.balloonController = new BalloonController(this.wwd)
{
@Override
protected void addDocumentLayer(KMLRoot document)
{
addKMLLayer(document);
}
}; // 关联kml管理器和balloon管理器
this.kmlAppController.setBalloonController(balloonController); // Set up to receive SSLHandshakeExceptions that occur during
// resource retrieval.
WorldWind.getRetrievalService().setSSLExceptionListener(
new RetrievalService.SSLExceptionListener()
{
public void onException(Throwable e, String path)
{
System.out.println(path);
System.out.println(e);
}
});
} /**
*
* @方法名称: addKMLLayer 。
* @方法描写叙述: 加入KML图层: 。
* @參数 :@param kmlRoot
* @返回类型: void ;
* @创建人:bluce ;
* @创建时间:2015年3月17日 下午7:54:40。
* @throws
*/
protected void addKMLLayer(KMLRoot kmlRoot)
{
// Create a KMLController to adapt the KMLRoot to the World Wind
KMLController kmlController = new KMLController(kmlRoot); // 加入kml图层
RenderableLayer layer = new RenderableLayer();
layer.setName((String) kmlRoot.getField(AVKey.DISPLAY_NAME));
layer.addRenderable(kmlController);
this.wwd.getModel().getLayers().add(layer); // 加入kml图层树节点
KMLLayerTreeNode layerNode = new KMLLayerTreeNode(layer, kmlRoot);
this.layerTree.getModel().addLayer(layerNode);
this.layerTree.makeVisible(layerNode.getPath());
layerNode.expandOpenContainers(this.layerTree); // Listens to refresh property change events from KML network link
// nodes. Upon receiving such an event this
// expands any tree paths that represent open KML containers. When a
// KML network link refreshes, its tree
// node replaces its children with new nodes created from the
// refreshed content, then sends a refresh
// property change event through the layer tree. By expanding open
// containers after a network link refresh,
// we ensure that the network link tree view appearance is
// consistent with the KML specification.
layerNode.addPropertyChangeListener(
AVKey.RETRIEVAL_STATE_SUCCESSFUL,
new PropertyChangeListener()
{
public void propertyChange(
final PropertyChangeEvent event)
{
if (event.getSource() instanceof KMLNetworkLinkTreeNode)
{
// Manipulate the tree on the EDT.
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
((KMLNetworkLinkTreeNode) event
.getSource())
.expandOpenContainers(layerTree);
wwd.redraw();
}
});
}
}
});
}
} /**
*
* @项目名称:worldwind-1.5.0
* @类名称:WorkerThread
* @类描写叙述:载入KML文件线程类
* @创建人:bluce 
* @创建时间:2015年3月17日 下午7:58:38
* @改动备注:
* @版本号:
*/
public static class WorkerThread extends Thread
{
/**
* 待载入kml文件,在构造函数中初始化
*/
protected Object kmlSource;
/**
* kmlapp
*/
protected KMLUtil KMLUtil; public WorkerThread(Object kmlSource, KMLUtil KMLUtil)
{
this.kmlSource = kmlSource;
this.KMLUtil = KMLUtil;
} /**
* Loads this worker thread's KML source into a new
* <code>{@link gov.nasa.worldwind.ogc.kml.KMLRoot}</code>, then adds
* the new <code>KMLRoot</code> to this worker thread's
* <code>AppFrame</code>. The <code>KMLRoot</code>'s
* <code>AVKey.DISPLAY_NAME</code> field contains a display name created
* from either the KML source or the KML root feature name.
* <p/>
* If loading the KML source fails, this prints the exception and its
* stack trace to the standard error stream, but otherwise does nothing.
*/
public void run()
{
try
{
KMLRoot kmlRoot = this.parse();
// 设置文档的显示名称
kmlRoot.setField(AVKey.DISPLAY_NAME,
formName(this.kmlSource, kmlRoot)); // 启动一个任务进程载入解析的kml文件
final KMLRoot finalKMLRoot = kmlRoot;
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
KMLUtil.addKMLLayer(finalKMLRoot);
}
});
}
catch (Exception e)
{
e.printStackTrace();
}
} /**
*
* @方法名称: parse 。
* @方法描写叙述: 解析KML文档 。
* @參数 :@return 返回KMLRoot
* @參数 :@throws IOException:文档不可读
* @參数 :@throws XMLStreamException :文档解析出现错误
* @返回类型: KMLRoot 。
* @创建人:bluce  ;
* @创建时间:2015年3月17日 下午8:02:59;
* @throws
*/
protected KMLRoot parse() throws IOException, XMLStreamException
{
// KMLRoot.createAndParse will attempt to parse the document using a
// namespace aware parser, but if that
// fails due to a parsing error it will try again using a namespace
// unaware parser. Note that this second
// step may require the document to be read from the network again
// if the kmlSource is a stream.
return KMLRoot.createAndParse(this.kmlSource);
}
} protected static String formName(Object kmlSource, KMLRoot kmlRoot)
{
KMLAbstractFeature rootFeature = kmlRoot.getFeature(); if (rootFeature != null && !WWUtil.isEmpty(rootFeature.getName()))
return rootFeature.getName(); if (kmlSource instanceof File)
return ((File) kmlSource).getName(); if (kmlSource instanceof URL)
return ((URL) kmlSource).getPath(); if (kmlSource instanceof String
&& WWIO.makeURL((String) kmlSource) != null)
return WWIO.makeURL((String) kmlSource).getPath(); return "KML Layer";
} }

World Wind Java开发之十五——载入三维模型的更多相关文章

  1. World Wind Java开发之十五——加载三维模型(转)

    之前的一篇博客是关于加载粗三维模型的,见http://blog.csdn.net/giser_whu/article/details/43452703,这个地方还存在着不能加载纹理的问题,一直没呢解决 ...

  2. World Wind Java开发之十四——添加WMS地图服务资源(转)

    数据是GIS的核心,没有数据一切无从谈起,Internet上有很多在线WMS地图服务资源,我们可以好好利用这些数据资源,比如天地图.必应地图.NASA.OGC数据服务等等. 在我们国家常用的还是天地图 ...

  3. World Wind Java开发之十——AnalyticSurface栅格渲染(转)

    http://blog.csdn.net/giser_whu/article/details/43017881 1.AnalyticSurfaceDemo ArcGIS下对栅格的各种分级渲染效果是非常 ...

  4. Java开发学习(十五)----AOP入门案例及其工作流程解析

    一.AOP简介 1.1 什么是AOP AOP(Aspect Oriented Programming)面向切面编程,一种编程范式,指导开发者如何组织程序结构. OOP(Object Oriented ...

  5. World Wind Java开发之十二——加载粗制三维模型(ExtrudedPolygon)(转)

    ww可以根据DLG图批量生成假三维模型,这对于小区等特征相似的建筑物模型的构建是非常有用的.下面来看如何一步步实现假三维模型的加载: 1.Shp文件的制作 首先在arcmap下数字化几个建筑物,并新建 ...

  6. “全栈2019”Java多线程第二十五章:生产者与消费者线程详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  7. “全栈2019”Java多线程第十五章:当后台线程遇到finally

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  8. “全栈2019”Java异常第十五章:异常链详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  9. “全栈2019”Java第八十五章:实现接口中的嵌套接口

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

随机推荐

  1. wed网页开发面试笔试必备小知识

    HTML中行内元素与块级元素的区别: 在标准文档流里面,块级元素具有以下特点: ①总是在新行上开始,占据一整行: ②高度,行高以及外边距和内边距都可控制: ③宽带始终是与浏览器宽度一样,与内容无关: ...

  2. 转载——CLR标量函数、表值函数和聚合函数(UDA)

    本节主要介绍使用CLR创建标量函数,表值函数和聚合函数. 所谓标量函数指的就是此函数只返回一个值.表值函数返回值是一个表.聚合函数是在select语句中使用的,用来聚合一个结果集,类似于Sum()或是 ...

  3. 指针 v.s. 引用

    对C++的指针总觉得和引用差不多,其实还是挺有差别的. 程序 先看一个小程序: ; int& ra = a; int* pa = &ra; printf("&a = ...

  4. UVA10090 数论基础 exgcd

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  5. C#使用itextsharp生成PDF文件

    项目需求需要生成一个PDF文档,使用的是VS2010,ASP.NET. 网络上多次搜索没有自己想要的,于是硬着头皮到itextpdf官网看英文文档,按时完成任务,以实用为主,共享一下: 使用HTML文 ...

  6. 用PHP删除文件操作unlink

    使用unlink要注意的是$filename的值,要用的是本地绝对地址.比如"c:\aaa\a.jpg",不能用相对地址比如:"../aa.jpg",那么如果在 ...

  7. 子类重载父类的方法“parent:方法名”

    在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法 ...

  8. 文成小盆友python-num5 -装饰器回顾,模块,字符串格式化

    一.装饰器回顾与补充 单层装饰器: 如上篇文章所讲单层装饰器指一个函数用一个装饰器来装饰,即在函数执行前或者执行后用于添加相应的操作(如判断某个条件是否满足). 具体请见如下: 单层装饰器 双层装饰器 ...

  9. pcduino连接OTG登录远程桌面

    由于没有HDMI的显示屏,为了方便起见,使用了pcduino的OTG来连接到虚拟桌面,可是发现连接上虚拟桌面后,电脑的外网就断了.下面这个方法让你既可以连接到pcduino,又可以让电脑能上外网. 打 ...

  10. [工具]web开发时自动刷新网页:liveReload

    传统网页开发流程:用sublime text写好代码,运行,发现问题,再回到sublime text修改,运行…如此往复,十分繁琐.今天看到有人(<LiveReload>讓Sublime ...