World Wind Java開發之八——載入本地快取檔案構建大範圍三維場景
阿新 • • 發佈:2019-02-09
/** * @Copyright 2014-2020 @奔跑的雞絲 **/ package edu.whu.vge.util; import edu.whu.vge.util.JavaCheckBoxTree.CheckBoxTreeNode; import gov.nasa.worldwind.Factory; import gov.nasa.worldwind.WorldWind; import gov.nasa.worldwind.avlist.AVKey; import gov.nasa.worldwind.avlist.AVList; import gov.nasa.worldwind.avlist.AVListImpl; import gov.nasa.worldwind.awt.WorldWindowGLCanvas; import gov.nasa.worldwind.cache.FileStore; import gov.nasa.worldwind.exception.WWRuntimeException; import gov.nasa.worldwind.geom.Sector; import gov.nasa.worldwind.globes.Earth; import gov.nasa.worldwind.globes.ElevationModel; import gov.nasa.worldwind.layers.Layer; import gov.nasa.worldwind.terrain.CompoundElevationModel; import gov.nasa.worldwind.util.DataConfigurationFilter; import gov.nasa.worldwind.util.DataConfigurationUtils; import gov.nasa.worldwind.util.Logging; import gov.nasa.worldwind.util.WWIO; import gov.nasa.worldwind.util.WWXML; import java.awt.Component; import java.io.File; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.tree.DefaultMutableTreeNode; import javax.xml.xpath.XPath; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * @專案名稱:GF_ZHJCYPG * @類名稱:LoadCacheData * @類描述: 載入快取資料 * @建立人:奔跑的雞絲 * @建立時間:2014-12-19 下午4:30:49 * @修改備註: * @版本: */ public class LoadCacheData { private static WorldWindowGLCanvas worldWindowGLCanvas; private static JTree layerJTree; /** * * 建立一個新的例項 LoadCacheData. * * @param worWindowGLCanvas */ public LoadCacheData(WorldWindowGLCanvas worWindowGLCanvas, JTree jTree) { LoadCacheData.setWorldWindowGLCanvas(worWindowGLCanvas); LoadCacheData.setLayerJTree(jTree); } /** * * @方法名稱: loadPreviouslyInstalledData ; * @方法描述: 載入已有的快取檔案 ; * @引數 : * @返回型別: void ; * @建立人:奔跑的雞絲 ; * @建立時間:2014-12-19 下午7:06:09; * @throws */ public void loadPreviouslyInstalledData() { Thread thread = new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub loadInstalledDataFromFileStore(WorldWind.getDataFileStore()); } }); thread.start(); } /** * * @方法名稱: loadInstalledDataFromFileStore ; * @方法描述: TODO ; * @引數 :@param fileStore * @返回型別: void ; * @建立人:奔跑的雞絲 ; * @建立時間:2014-12-19 下午7:06:42; * @throws */ protected void loadInstalledDataFromFileStore(FileStore fileStore) { // 便利已有的快取檔案 for (File file : fileStore.getLocations()) { // 檔案存在並且是快取檔案目錄 if (file.exists() && fileStore.isInstallLocation(file.getPath())) { System.out.println(file.getPath()); loadInstalledDataFromDirectory(file); } } } /** * * @方法名稱: loadInstalledDataFromDirectory ; * @方法描述: 從檔案目錄載入快取資料 ; * @引數 :@param dir * @返回型別: void ; * @建立人:奔跑的雞絲 ; * @建立時間:2014-12-19 下午7:43:36; * @throws */ private void loadInstalledDataFromDirectory(File dir) { /** * 獲取快取檔案xml配置檔案的在快取檔案目錄的相對目錄,如Landsat\Landsat.xml */ String[] names = WWIO.listDescendantFilenames(dir, new DataConfigurationFilter(), false); if (names == null || names.length == 0) return; for (String filename : names) { Document doc = null; try { // 根據快取檔案XML描述檔案建立Document物件 File dataConfigFile = new File(dir, filename); doc = WWXML.openDocument(dataConfigFile); doc = DataConfigurationUtils.convertToStandardDataConfigDocument(doc); } catch (WWRuntimeException e) { e.printStackTrace(); } if (doc == null) continue; // 由於資料配置檔案來自於已有的檔案,因此不能保證它是由當前版本WW's Installer // 產生的。可能是由之前版本或其他應用程式產生的,因此要為可能缺失的引數設定備用值(這些引數需要用來構建圖層或高程模擬) AVList params = new AVListImpl(); setFallbackParams(doc, filename, params); // 新增資料 addInstalledData(doc, params); } } /** * * @方法名稱: setFallbackParams ; * @方法描述: 設定備用引數值 ; * @引數 :@param dataConfig :資料配置XML檔案 * @引數 :@param filename :檔名 * @引數 :@param params :引數列表 * @返回型別: void ; * @建立人:奔跑的雞絲 ; * @建立時間:2014-12-20 下午12:21:03; * @throws */ private void setFallbackParams(Document dataConfig, String filename, AVList params) { XPath xpath = WWXML.makeXPath(); Element domElement = dataConfig.getDocumentElement(); // If the data configuration document doesn't define a cache name, then // compute one using the file's path // relative to its file cache directory. String s = WWXML.getText(domElement, "DataCacheName", xpath); if (s == null || s.length() == 0) DataConfigurationUtils.getDataConfigCacheName(filename, params); // If the data configuration document doesn't define the data's extreme // elevations, provide default values using // the minimum and maximum elevations of Earth. String type = DataConfigurationUtils.getDataConfigType(domElement); if (type.equalsIgnoreCase("ElevationModel")) { if (WWXML.getDouble(domElement, "ExtremeElevations/@min", xpath) == null) params.setValue(AVKey.ELEVATION_MIN, Earth.ELEVATION_MIN); if (WWXML.getDouble(domElement, "ExtremeElevations/@max", xpath) == null) params.setValue(AVKey.ELEVATION_MAX, Earth.ELEVATION_MAX); } } /** * * @方法名稱: addInstalledData ; * @方法描述: 新增快取資料 ; * @引數 :@param dataConfig * @引數 :@param params * @返回型別: void ; * @建立人:奔跑的雞絲 ; * @建立時間:2014-12-20 下午12:22:29; * @throws */ private void addInstalledData(final Document dataConfig, final AVList params) { if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(new Runnable() { public void run() { addInstalledData(dataConfig, params); } }); } else { addInstalledCacheData(dataConfig.getDocumentElement(), params); } } /** * * @方法名稱: addInstalledCacheData ; * @方法描述: 新增已有快取資料 ; * @引數 :@param domElement :資料XML描述檔案 * @引數 :@param params :引數列表 * @返回型別: void ; * @建立人:奔跑的雞絲 ; * @建立時間:2014-12-19 下午8:02:21; * @throws */ public void addInstalledCacheData(final Element domElement, final AVList params) { if (domElement == null) { String message = Logging.getMessage("nullValue.DocumentIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } String description = getDescription(domElement); // 圖層名稱 Sector sector = getSector(domElement); // 圖層範圍 System.out.println(description); System.out.println(sector); addToWorldWindow(domElement, params); } /** * * @方法名稱: addToWorldWindow ; * @方法描述: 將快取檔案加入WW ; * @引數 :@param domElement * @引數 :@param params * @返回型別: void ; * @建立人:奔跑的雞絲 ; * @建立時間:2014-12-19 下午4:44:08; * @throws */ private void addToWorldWindow(Element domElement, AVList params) { String type = DataConfigurationUtils.getDataConfigType(domElement); if (type == null) return; if (type.equalsIgnoreCase("Layer")) { addLayerToWorldWindow(domElement, params); } else if (type.equalsIgnoreCase("ElevationModel")) { addElevationModelToWorldWindow(domElement, params); } } /** * * @方法名稱: addLayerToWorldWindow ; * @方法描述: 向WW中新增圖層 ; * @引數 :@param domElement * @引數 :@param params * @返回型別: void ; * @建立人:奔跑的雞絲 ; * @建立時間:2014-12-19 下午4:45:06; * @throws */ private void addLayerToWorldWindow(Element domElement, AVList params) { Layer layer = null; try { // Factory建立的圖層預設是不可見的 Factory factory = (Factory) WorldWind.createConfigurationComponent(AVKey.LAYER_FACTORY); layer = (Layer) factory.createFromConfigSource(domElement, params); } catch (Exception e) { String message = Logging.getMessage( "generic.CreationFromConfigurationFailed", DataConfigurationUtils.getDataConfigDisplayName(domElement)); Logging.logger().log(java.util.logging.Level.SEVERE, message, e); } if (layer == null) return; layer.setEnabled(true); // 設定圖層可見 // 新增至WW if (!getWorldWindowGLCanvas().getModel().getLayers().contains(layer)) { getWorldWindowGLCanvas().getModel().getLayers().add(layer); // System.out.println(pLayerTree.getModel().getRoot().toString()); Object rootObject = layerJTree.getModel().getRoot(); if (!layerJTree.getModel().isLeaf(rootObject)) { int count = layerJTree.getModel().getChildCount(rootObject); for (int i = 0; i < count; i++) { String childNodeNameString = layerJTree.getModel().getChild( rootObject, i).toString(); if (childNodeNameString.equals("影像圖層")) { ((DefaultMutableTreeNode) layerJTree.getModel().getChild( rootObject, i)).add(new CheckBoxTreeNode( layer.getName())); layerJTree.updateUI(); } } } } } /** * * @方法名稱: addElevationModelToWorldWindow ; * @方法描述: 新增高程圖層 ; * @引數 :@param domElement * @引數 :@param params * @返回型別: void ; * @建立人:奔跑的雞絲 ; * @建立時間:2014-12-19 下午4:51:37; * @throws */ private void addElevationModelToWorldWindow(Element domElement, AVList params) { ElevationModel em = null; try { Factory factory = (Factory) WorldWind.createConfigurationComponent(AVKey.ELEVATION_MODEL_FACTORY); em = (ElevationModel) factory.createFromConfigSource(domElement, params); } catch (Exception e) { String message = Logging.getMessage( "generic.CreationFromConfigurationFailed", DataConfigurationUtils.getDataConfigDisplayName(domElement)); Logging.logger().log(java.util.logging.Level.SEVERE, message, e); } if (em == null) return; ElevationModel defaultElevationModel = getWorldWindowGLCanvas().getModel().getGlobe().getElevationModel(); if (defaultElevationModel instanceof CompoundElevationModel) { if (!((CompoundElevationModel) defaultElevationModel).containsElevationModel(em)) ((CompoundElevationModel) defaultElevationModel).addElevationModel(em); } else { CompoundElevationModel cm = new CompoundElevationModel(); cm.addElevationModel(defaultElevationModel); cm.addElevationModel(em); getWorldWindowGLCanvas().getModel().getGlobe().setElevationModel(cm); } } /** * 獲取快取檔案型別 獲取快取配置檔案描述:是Layer或者是Elevation * * @方法名稱: getDescription ; * @方法描述: TODO ; * @引數 :@param domElement * @引數 :@return * @返回型別: String ; * @建立人:奔跑的雞絲 ; * @建立時間:2014-12-19 下午4:53:26; * @throws */ private String getDescription(Element domElement) { String displayName = DataConfigurationUtils.getDataConfigDisplayName(domElement); String type = DataConfigurationUtils.getDataConfigType(domElement); StringBuilder sb = new StringBuilder(displayName); if (type.equalsIgnoreCase("Layer")) { sb.append(" (Layer)"); } else if (type.equalsIgnoreCase("ElevationModel")) { sb.append(" (Elevations)"); } return sb.toString(); } /** * 獲取圖層範圍 * * @方法名稱: getSector ; * @方法描述: TODO ; * @引數 :@param domElement * @引數 :@return * @返回型別: Sector ; * @建立人:奔跑的雞絲 ; * @建立時間:2014-12-19 下午4:54:17; * @throws */ protected static Sector getSector(Element domElement) { return WWXML.getSector(domElement, "Sector", null); } public static WorldWindowGLCanvas getWorldWindowGLCanvas() { return worldWindowGLCanvas; } public static void setWorldWindowGLCanvas( WorldWindowGLCanvas worldWindowGLCanvas) { LoadCacheData.worldWindowGLCanvas = worldWindowGLCanvas; } public JTree getLayerJTree() { return layerJTree; } public static void setLayerJTree(JTree layerJTree) { LoadCacheData.layerJTree = layerJTree; } }