[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         }

 

 

你可能感兴趣的:(configuration)