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
}

