[WorldWind学习]14.ConfigurationLoader类

ConfigurationLoader主要负责WW中各个图层的加载。

首先看看安装目录Config文件夹下Earth.xml文件

View Code
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <World Name="Earth" EquatorialRadius="6378137.0" LayerDirectory="Earth" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="WorldXmlDescriptor.xsd">
 3     <TerrainAccessor Name="SRTM">
 4         <TerrainTileService>
 5             <ServerUrl>http://worldwind25.arc.nasa.gov/wwelevation/wwelevation.aspx</ServerUrl>
 6             <DataSetName>srtm30pluszip</DataSetName>
 7             <LevelZeroTileSizeDegrees>20.0</LevelZeroTileSizeDegrees>
 8             <NumberLevels>12</NumberLevels>
 9             <SamplesPerTile>150</SamplesPerTile>
10             <DataFormat>Int16</DataFormat>
11             <FileExtension>bil</FileExtension>
12             <CompressonType>zip</CompressonType>
13         </TerrainTileService>
14         <LatLonBoundingBox>
15             <North>
16                 <Value>90.0</Value>
17             </North>
18             <South>
19                 <Value>-90.0</Value>
20             </South>
21             <West>
22                 <Value>-180.0</Value>
23             </West>
24             <East>
25                 <Value>180.0</Value>
26             </East>
27         </LatLonBoundingBox>
28     </TerrainAccessor>
29 </World>

MainApplication构造函数中截取了如下代码:

 1 foreach (FileInfo worldXmlDescriptorFile in worldXmlDescriptorFiles)
 2                 {
 3                     try
 4                     {
 5                         Log.Write(Log.Levels.Debug+1, "CONF", "checking world " + worldXmlDescriptorFile.FullName + " ...");
 6                         World w = WorldWind.ConfigurationLoader.Load(worldXmlDescriptorFile.FullName, worldWindow.Cache);
 7                         if(!availableWorldList.Contains(w.Name))
 8                             this.availableWorldList.Add(w.Name, worldXmlDescriptorFile.FullName);
 9 
10                         w.Dispose();
11                         System.Windows.Forms.MenuItem mi = new System.Windows.Forms.MenuItem(w.Name, new System.EventHandler(OnWorldChange));
12                         menuItemFile.MenuItems.Add(worldIndex, mi);
13                         worldIndex++;
14                     }
15                     catch( Exception caught )
16                     {
17                         splashScreen.SetError( worldXmlDescriptorFile + ": " + caught.Message );
18                         Log.Write(caught);
19                     }
20                 }
21 
22                 Log.Write(Log.Levels.Debug, "CONF", "loading startup world...");
23                 OpenStartupWorld();

首先验证世界是否存在列表中,接着就释放了w。

OpenStartupWorld()方法体最后调用了OpenWorld( curWorldFile );

  1 /// <summary>
  2         /// Loads a new planet
  3         /// </summary>
  4         private void OpenWorld(string worldXmlFile)
  5         {
  6             
  7             if(this.worldWindow.CurrentWorld != null)
  8             {
  9                 try
 10                 {
 11                     this.worldWindow.ResetToolbar();
 12                 }
 13                 catch
 14                 {}
 15 
 16                 try
 17                 {
 18                     foreach(PluginInfo p in this.compiler.Plugins)
 19                     {
 20                         try
 21                         {
 22                             if(p.Plugin.IsLoaded)
 23                                 p.Plugin.Unload();
 24                         }
 25                         catch
 26                         {}
 27                     }
 28                 }
 29                 catch
 30                 {}
 31                 
 32                 try
 33                 {
 34                     this.worldWindow.CurrentWorld.Dispose();
 35                 }
 36                 catch
 37                 {}
 38                 
 39             }
 40 
 41 
 42             if(this.gotoDialog != null)
 43             {
 44                 this.gotoDialog.Dispose();
 45                 this.gotoDialog = null;
 46             }
 47 
 48             if(this.rapidFireModisManager != null)
 49             {
 50                 this.rapidFireModisManager.Dispose();
 51                 this.rapidFireModisManager = null;
 52             }
 53 
 54             if(this.animatedEarthMananger != null)
 55             {
 56                 this.animatedEarthMananger.Dispose();
 57                 this.animatedEarthMananger = null;
 58             }
 59 
 60             if(this.wmsBrowser != null)
 61             {
 62                 this.wmsBrowser.Dispose();
 63                 this.wmsBrowser = null;
 64             }
 65 
 66             //currentWorld = world;
 67 
 68         //    TerrainAccessor terrainAccessor = null;
 69         //    if(worldDescriptor.HasTerrainAccessor())
 70         //        terrainAccessor = this.getTerrainAccessorFromXML(worldDescriptor.TerrainAccessor);
 71 
 72             worldWindow.CurrentWorld = WorldWind.ConfigurationLoader.Load(worldXmlFile, worldWindow.Cache);
 73 
 74 
 75         /*    if(this.currentWorld.HasLayerDirectory())
 76             {
 77                 string dirPath = worldDescriptor.LayerDirectory.Value;
 78                 if(!Path.IsPathRooted(dirPath))
 79                     if (worldDescriptor.LayerDirectory.Value.IndexOf("//") < 0) // ?
 80                         dirPath = Path.Combine(  Settings.ConfigPath, dirPath );
 81 
 82                 ArrayList nodes = new ArrayList();
 83                 foreach (string layerSetFile in Directory.GetFiles( dirPath, "*.xml" ))
 84                 {
 85                     try
 86                     {
 87                         
 88                         LayerSet.LayerSetDoc curLayerSetDoc = new LayerSet.LayerSetDoc();
 89                         LayerSet.Type_LayerSet curLayerSet = new LayerSet.Type_LayerSet(curLayerSetDoc.Load(layerSetFile));
 90 
 91                         RenderableObject wwroi = getRenderableObjectListFromLayerSet(this.worldWindow.CurrentWorld, curLayerSet, layerSetFile);
 92                         world.RenderableObjects.Add( wwroi );
 93                     }
 94                     catch (Exception caught)
 95                     {
 96                         // Altova throws System.Exception
 97                         splashScreen.SetError(
 98                             String.Format(CultureInfo.CurrentCulture, "The file '{0}' is invalid: {1}",
 99                             Path.GetFileName(layerSetFile), caught.Message) );
100                     }
101                 }
102 
103                 this.layerTreeNodes = (TreeNode[])nodes.ToArray(typeof(TreeNode));
104             }
105 */
106             
107             this.splashScreen.SetText("Initializing menus...");
108                 
109             InitializePluginCompiler();
110 
111             foreach(RenderableObject worldRootObject in this.worldWindow.CurrentWorld.RenderableObjects.ChildObjects)
112             {
113                 this.AddLayerMenuButtons(this.worldWindow, worldRootObject);
114             }
115 
116             this.AddInternalPluginMenuButtons();
117 
118             this.menuItemModisHotSpots.Enabled = worldWindow.CurrentWorld.IsEarth;
119             this.menuItemAnimatedEarth.Enabled = worldWindow.CurrentWorld.IsEarth;
120         
121 
122         }

worldWindow.CurrentWorld = WorldWind.ConfigurationLoader.Load(worldXmlFile, worldWindow.Cache);
真正加载世界。

ConfigurationLoader的改造和使用方法:

 1 public static World Load(string filename, Cache cache)
 2         {
 3             Log.Write(Log.Levels.Debug, "CONF", "Loading " + filename);
 4 
 5             // get the World Wind Settings through reflection to avoid changing the signature of Load().
 6             Assembly a = Assembly.GetEntryAssembly();
 7             Type appType = a.GetType("WorldWind.MainApplication");
 8             System.Reflection.FieldInfo finfo = appType.GetField("Settings", BindingFlags.Static | BindingFlags.Public | BindingFlags.GetField);
 9             WorldWindSettings settings = finfo.GetValue(null) as WorldWindSettings;
10 
11             XmlReaderSettings readerSettings = new XmlReaderSettings();
12 
13             if (settings.ValidateXML)
14             {
15                 Log.Write(Log.Levels.Debug, "CONF", "validating " + filename + " against WorldXmlDescriptor.xsd and LayerSet.xsd");
16                 readerSettings.ValidationType = ValidationType.Schema;
17                 /* load the schema to validate against instead of hoping for an inline schema reference */
18                 XmlSchemaSet schemas = new XmlSchemaSet();
19                 schemas.Add(null, settings.ConfigPath + "/WorldXmlDescriptor.xsd");
20                 schemas.Add(null, settings.ConfigPath + "/Earth/LayerSet.xsd");
21 
22 
23                 readerSettings.Schemas = schemas;
24                 readerSettings.ValidationEventHandler += new ValidationEventHandler(XMLValidationCallback);
25                 readerSettings.ValidationFlags |= System.Xml.Schema.XmlSchemaValidationFlags.ReportValidationWarnings;
26             }
27             else
28             {
29                 Log.Write(Log.Levels.Debug, "CONF", "loading " + filename + " without validation");
30                 readerSettings.ValidationType = ValidationType.None;
31             }
32 
33             try
34             {
35                 XmlReader docReader = XmlReader.Create(filename, readerSettings);
36                 XPathDocument docNav = new XPathDocument(docReader);
37                 XPathNavigator nav = docNav.CreateNavigator();
38 
39                 XPathNodeIterator worldIter = nav.Select("/World[@Name]");
40                 if (worldIter.Count > 0)
41                 {
42                     worldIter.MoveNext();
43                     string worldName = worldIter.Current.GetAttribute("Name", "");
44                     double equatorialRadius = ParseDouble(worldIter.Current.GetAttribute("EquatorialRadius", ""));
45                     string layerDirectory = worldIter.Current.GetAttribute("LayerDirectory", "");
46 
47                     if (layerDirectory.IndexOf(":") < 0)
48                     {
49                         layerDirectory = Path.Combine(Path.GetDirectoryName(filename), layerDirectory);
50                     }
51 
52                     TerrainAccessor[] terrainAccessor = getTerrainAccessorsFromXPathNodeIterator(worldIter.Current.Select("TerrainAccessor"),
53                         System.IO.Path.Combine(cache.CacheDirectory, worldName));
54 
55                     World newWorld = new World(
56                         worldName,
57                         new Microsoft.DirectX.Vector3(0, 0, 0),
58                         new Microsoft.DirectX.Quaternion(0, 0, 0, 0),
59                         equatorialRadius,
60                         cache.CacheDirectory,
61                         (terrainAccessor != null ? terrainAccessor[0] : null)//TODO: Oops, World should be able to handle an array of terrainAccessors
62                         );
63 
64                     //调用getRenderablesFromLayerDirectory()方法.
65                     newWorld.RenderableObjects = getRenderablesFromLayerDirectory(layerDirectory, newWorld, cache);
66 
67                     return newWorld;
68                 }
69             }
70             catch (XmlSchemaException ex)
71             {
72                 Log.Write(Log.Levels.Error, "CONF", "Exception caught during XML parsing: " + ex.Message);
73                 Log.Write(Log.Levels.Error, "CONF", "File " + filename + " was not read successfully.");
74                 // TODO: should pop up a message box or something.
75                 return null;
76             }
77 
78             return null;
79         }

getRenderablesFromLayerDirectory()方法: 

 1 private static RenderableObjectList getRenderablesFromLayerDirectory(string layerDirectory, World parentWorld, Cache cache)
 2         {
 3             RenderableObjectList renderableCollection = new RenderableObjectList(parentWorld.Name);
 4 
 5             DirectoryInfo layerDir = new DirectoryInfo(layerDirectory);
 6             if(!layerDir.Exists)
 7             {
 8                 return renderableCollection;
 9             }
10             //从layerDirectory文件夹中读取所有的xml文件,并从xml文件中读取图层信息
11             foreach(FileInfo layerFile in layerDir.GetFiles("*.xml"))
12             {
13                 //调用getRenderableFromLayerFile()方法,从中读取RenderableObjectList 对象。
14                 RenderableObjectList currentRenderable = getRenderableFromLayerFile(layerFile.FullName, parentWorld, cache);
15                 if(currentRenderable != null)
16                 {
17                     renderableCollection.Add(currentRenderable);
18                 }
19             }
20             //返回RenderableObjectList对象
21             return renderableCollection;
22         }

 

 

posted @ 2013-05-02 11:44  太一吾鱼水  阅读(397)  评论(0编辑  收藏  举报