• World Wind Java开发之十五——载入三维模型


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

    1.效果图

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


    第二幅是也是德国地标性建筑——柏林电视塔。


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

    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";
    	}
    
    }
    




  • 相关阅读:
    Web端导出CSV
    dojo/dom-style样式操作学习笔记
    dojo/dom源码学习
    上层建筑——DOM元素的特性与属性(dojo/dom-prop)
    上层建筑——DOM元素的特性与属性(dojo/dom-attr)
    返本求源——DOM元素的特性与属性
    DOM扩展札记
    以代码爱好者角度来看AMD与CMD
    dojo事件驱动编程之事件绑定
    通过Web.config中的configSections配置自己系统的全局常量
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5181981.html
Copyright © 2020-2023  润新知