/// <summary> /// Parses Multi Polygons /// </summary> /// <param name="inNode">The node containing Polygons</param> /// <param name="layer">The layer to add the resulting Polygons to</param> private void ParseMultiGeometry(XmlNode inNode, RIcons layer) { // Parse all Placemarks that have a name and Polygon XmlNodeList placemarkNodes = inNode.SelectNodes("Placemark[name and MultiGeometry]"); Random rand = new Random((int)DateTime.Now.Ticks); foreach(XmlNode placemarkNode in placemarkNodes) { XmlNode nameNode = placemarkNode.SelectSingleNode("name"); string name = nameNode.InnerText; // change this to something that unifies the geometry into a single object instead of a user-accessible list RIcons multiGeometryList = new RIcons(name); Style style = null; // get StyleUrl XmlNode styleUrlNode = placemarkNode.SelectSingleNode("styleUrl"); if(styleUrlNode != null) { string styleUrlKey = styleUrlNode.InnerText.Trim(); if(styleUrlKey.StartsWith("#")) styleUrlKey = styleUrlKey.Substring(1, styleUrlKey.Length - 1); style = (Style)iconStyles[styleUrlKey]; } else { XmlNode styleNode = placemarkNode.SelectSingleNode("Style"); if(styleNode != null) style = GetStyle( styleNode, new Style(), ""); } if(style == null) style = new Style(); if(style.LineStyle == null) style.LineStyle = new LineStyle(); if(style.PolyStyle == null) style.PolyStyle = new PolyStyle(); XmlNodeList lineStringNodes = placemarkNode.SelectNodes("MultiGeometry/LineString"); foreach(XmlNode lineStringNode in lineStringNodes) { bool extrude = false; XmlNode extrudeNode = lineStringNode.SelectSingleNode("extrude"); if (extrudeNode != null) extrude = Convert.ToBoolean(Convert.ToInt16(extrudeNode.InnerText)); XmlNode coordinateNode = lineStringNode.SelectSingleNode("coordinates"); Point3d[] points = ParseCoordinates(coordinateNode); XmlNode altitudeModeNode = lineStringNode.SelectSingleNode("altitudeMode"); AltitudeMode altitudeMode = GetAltitudeMode(altitudeModeNode); if(points != null && points.Length > 0) { LineFeature line = new LineFeature( name, m_world, points, System.Drawing.Color.FromArgb(style.LineStyle.Color.Color) ); line.AltitudeMode = altitudeMode; if(style.PolyStyle.Color != null) line.PolygonColor = System.Drawing.Color.FromArgb(style.PolyStyle.Color.Color); line.LineWidth = (float)style.LineStyle.Width.Value; line.Extrude = extrude; multiGeometryList.Add(line); } } XmlNodeList polygonNodes = placemarkNode.SelectNodes("MultiGeometry/Polygon"); foreach(XmlNode polygonNode in polygonNodes) { bool extrude = false; XmlNode extrudeNode = polygonNode.SelectSingleNode("extrude"); if (extrudeNode != null) extrude = Convert.ToBoolean(Convert.ToInt16(extrudeNode.InnerText)); XmlNode altitudeModeNode = polygonNode.SelectSingleNode("altitudeMode"); AltitudeMode altitudeMode = GetAltitudeMode(altitudeModeNode); LinearRing outerRing = null; LinearRing[] innerRings = null; // Parse Outer Ring XmlNode outerRingNode = polygonNode.SelectSingleNode("outerBoundaryIs/LinearRing/coordinates"); if (outerRingNode != null) { Point3d[] points = ParseCoordinates(outerRingNode); outerRing = new LinearRing(); outerRing.Points = points; } // Parse Inner Ring XmlNodeList innerRingNodes = polygonNode.SelectNodes("innerBoundaryIs"); if (innerRingNodes != null) { innerRings = new LinearRing[innerRingNodes.Count]; for(int i = 0; i < innerRingNodes.Count; i++) { Point3d[] points = ParseCoordinates(innerRingNodes[i]); innerRings[i] = new LinearRing(); innerRings[i].Points = points; } } if(outerRing != null) { PolygonFeature polygonFeature = new PolygonFeature( name, m_world, outerRing, innerRings, (style.PolyStyle.Color != null ? System.Drawing.Color.FromArgb(style.PolyStyle.Color.Color) : System.Drawing.Color.Yellow) ); polygonFeature.Extrude = extrude; polygonFeature.AltitudeMode = altitudeMode; polygonFeature.Outline = style.PolyStyle.Outline; if(style.LineStyle.Color != null) polygonFeature.OutlineColor = System.Drawing.Color.FromArgb(style.LineStyle.Color.Color); multiGeometryList.Add(polygonFeature); } } XmlNode visibilityNode = placemarkNode.SelectSingleNode("visibility"); if(visibilityNode != null) multiGeometryList.IsOn = (visibilityNode.InnerText == "1" ? true : false); layer.Add(multiGeometryList); } }
/// <summary> /// This Method parses screen overlays and adds to renderables /// using ScreenOverlay Object /// </summary> /// <param name="inNode">The node containing the Screen Overlay</param> /// <param name="layer">The layer to add the resulting Screen Overlay to</param> private void ParseScreenOverlays(XmlNode inNode, RIcons layer) { XmlNodeList screenOverlays = inNode.SelectNodes("ScreenOverlay"); if(screenOverlays!=null) { foreach(XmlNode screenOverlayNode in screenOverlays) { XmlNode nameNode = screenOverlayNode.SelectSingleNode("name"); String name = ""; if(nameNode != null) name = nameNode.InnerText; XmlNode uriNode = screenOverlayNode.SelectSingleNode("Icon/href"); String uri = "http://www.apogee.com.au/logo_topleft.gif"; if (uriNode != null) { uri = uriNode.InnerText; } float posX = 0; float posY = 0; ScreenUnits posXUnits = ScreenUnits.Pixels; ScreenUnits posYUnits = ScreenUnits.Pixels; XmlNode positionNode = screenOverlayNode.SelectSingleNode("screenXY"); if (positionNode != null) { if (positionNode.Attributes["x"] != null) { posX = float.Parse(positionNode.Attributes["x"].InnerText, CultureInfo.InvariantCulture); if (positionNode.Attributes["xunits"].InnerText.ToLower() == "fraction") { posXUnits = ScreenUnits.Fraction; } } if (positionNode.Attributes["y"] != null) { posY = float.Parse(positionNode.Attributes["y"].InnerText, CultureInfo.InvariantCulture); if (positionNode.Attributes["yunits"].InnerText.ToLower() == "fraction") { posYUnits = ScreenUnits.Fraction; } } } ScreenOverlay scoverlay = new ScreenOverlay(name, posX, posY, uri); scoverlay.PositionXUnits = posXUnits; scoverlay.PositionYUnits = posYUnits; scoverlay.ShowHeader = false; XmlNode sizeNode = screenOverlayNode.SelectSingleNode("size"); if (sizeNode != null) { if (sizeNode.Attributes["x"] != null) { scoverlay.Width = float.Parse(sizeNode.Attributes["x"].InnerText, CultureInfo.InvariantCulture); if(sizeNode.Attributes["xunits"].InnerText.ToLower() == "fraction") { scoverlay.SizeXUnits = ScreenUnits.Fraction; } } if (sizeNode.Attributes["y"] != null) { scoverlay.Height = float.Parse(sizeNode.Attributes["y"].InnerText, CultureInfo.InvariantCulture); if (sizeNode.Attributes["yunits"].InnerText.ToLower() == "fraction") { scoverlay.SizeYUnits = ScreenUnits.Fraction; } } } layer.Add(scoverlay); } } }
/// <summary> /// Parses LineStrings /// </summary> /// <param name="inNode">The node containing LineStrings</param> /// <param name="layer">The layer to add the resulting lines to</param> /// <param name="KmlPath">The path to the KML file that is being loaded</param> private void ParseLineStrings(XmlNode inNode, RIcons layer) { // Parse all Placemarks that have a name and LineString XmlNodeList lineStrings = inNode.SelectNodes("Placemark[name and LineString]"); foreach (XmlNode node in lineStrings) { // Extract the name from this node XmlNode nameNode = node.SelectSingleNode("name"); string name = nameNode.InnerText; Style style = null; // get StyleUrl XmlNode styleUrlNode = node.SelectSingleNode("styleUrl"); if(styleUrlNode != null) { string styleUrlKey = styleUrlNode.InnerText.Trim(); if(styleUrlKey.StartsWith("#")) styleUrlKey = styleUrlKey.Substring(1, styleUrlKey.Length - 1); style = (Style)iconStyles[styleUrlKey]; } else { XmlNode styleNode = node.SelectSingleNode("Style"); if(styleNode != null) style = GetStyle( styleNode, new Style(), ""); } if(style == null) style = new Style(); if(style.LineStyle == null) style.LineStyle = new LineStyle(); if(style.PolyStyle == null) style.PolyStyle = new PolyStyle(); // See if this LineString has to be extruded to the ground bool extrude = false; XmlNode extrudeNode = node.SelectSingleNode("LineString/extrude"); if (extrudeNode != null) extrude = Convert.ToBoolean(Convert.ToInt16(extrudeNode.InnerText)); //Parse Coordinates XmlNode outerRingNode = node.SelectSingleNode("LineString/coordinates"); if(outerRingNode != null) { // Parse the list of line coordinates Point3d[] points = ParseCoordinates(outerRingNode); LineFeature line = new LineFeature(name, m_world, points, System.Drawing.Color.FromArgb(style.LineStyle.Color.Color)); XmlNode altitudeModeNode = node.SelectSingleNode("LineString/altitudeMode"); line.AltitudeMode = GetAltitudeMode(altitudeModeNode); line.LineWidth = (float)style.LineStyle.Width.Value; if (extrude) { line.Extrude = true; if(style.PolyStyle.Color != null) { line.PolygonColor = System.Drawing.Color.FromArgb(style.PolyStyle.Color.Color); } } XmlNode visibilityNode = node.SelectSingleNode("visibility"); if(visibilityNode != null) line.IsOn = (visibilityNode.InnerText == "1" ? true : false); layer.Add(line); } } }
/// <summary> /// Parse Ground Overlays /// </summary> /// <param name="inNode">The node containing Ground Overlays</param> /// <param name="layer">The layer to add the resulting Ground Overlays to</param> private void ParseGroundOverlays(XmlNode inNode, RIcons layer) { // Parse all Placemarks that have a name and LineString XmlNodeList groundOverlays = inNode.SelectNodes("GroundOverlay[name and LatLonBox]"); foreach (XmlNode node in groundOverlays) { // Extract the name from this node XmlNode nameNode = node.SelectSingleNode("name"); string name = nameNode.InnerText; XmlNode latLonBoxNode = node.SelectSingleNode("LatLonBox"); //Parse Coordinates if(latLonBoxNode != null) { XmlNode northNode = latLonBoxNode.SelectSingleNode("north"); XmlNode southNode = latLonBoxNode.SelectSingleNode("south"); XmlNode westNode = latLonBoxNode.SelectSingleNode("west"); XmlNode eastNode = latLonBoxNode.SelectSingleNode("east"); double north = ConfigurationLoader.ParseDouble(northNode.InnerText); double south = ConfigurationLoader.ParseDouble(southNode.InnerText); double west = ConfigurationLoader.ParseDouble(westNode.InnerText); double east = ConfigurationLoader.ParseDouble(eastNode.InnerText); // Create GroundOverlay WorldWind.Renderable.ImageLayer imageLayer = new ImageLayer( name, ParentApplication.WorldWindow.CurrentWorld, 0, null, south, north, west, east, 1.0, ParentApplication.WorldWindow.CurrentWorld.TerrainAccessor ); imageLayer.DisableZBuffer = true; imageLayer.ImageUrl = node.SelectSingleNode("Icon/href").InnerText; XmlNode visibilityNode = node.SelectSingleNode("visibility"); if(visibilityNode != null) imageLayer.IsOn = (visibilityNode.InnerText == "1" ? true : false); layer.Add(imageLayer); } } }
/// <summary> /// Parse NetworkLinks /// </summary> /// <param name="inNode">The XmlNode to load NetworkLinks from</param> /// <param name="layer">The layer to add NetworkLinks to</param> private void ParseNetworkLinks(XmlNode inNode, RIcons layer) { // Find NetworkLinks, initialize them and download them for the first time XmlNodeList networklinks = inNode.SelectNodes("NetworkLink"); foreach (XmlNode node in networklinks) { try { // Find out the name for this NetworkLink string nlName = "NetworkLink"; XmlNode nameNode = node.SelectSingleNode("name"); if (nameNode != null) nlName = nameNode.InnerText; // See if a folder for this NetworkLink already exists RIcons folder = null; foreach (RenderableObject ro in layer.ChildObjects) { RIcons ricons = ro as RIcons; if ((ricons != null) && (ro.Name == nlName)) { folder = ricons; } } // Create a new folder if none is available if (folder == null) { folder = new RIcons(nlName); layer.Add(folder); } XmlNode visibilityNode = node.SelectSingleNode("visibility"); if(visibilityNode != null) folder.IsOn = (visibilityNode.InnerText == "1" ? true : false); // Find the URL to download the file from string loadFile = null; XmlNode hrefNode = node.SelectSingleNode("Url/href"); if ((hrefNode != null) && (hrefNode.InnerText.Length > 0)) loadFile = hrefNode.InnerText; // Give up if no URL can be found if (loadFile == null) continue; int tickSeconds = -1; int viewSeconds = -1; bool fired = false; if (node.SelectSingleNode("Url/refreshMode") != null) { if (node.SelectSingleNode("Url/refreshMode").InnerText == "onInterval") { string refreshText = node.SelectSingleNode("Url/refreshInterval").InnerText; tickSeconds = Convert.ToInt32(refreshText, CultureInfo.InvariantCulture); } if (node.SelectSingleNode("Url/refreshMode").InnerText == "once") { NetworkLink netLink = new NetworkLink(this, folder, loadFile, -1, -1); netLink.Fire(); netLink.Dispose(); fired = true; } } if ((node.SelectSingleNode("Url/viewRefreshMode") != null) && (node.SelectSingleNode("Url/viewRefreshMode").InnerText == "onStop")) { string refreshText = node.SelectSingleNode("Url/viewRefreshTime").InnerText; viewSeconds = Convert.ToInt32(refreshText, CultureInfo.InvariantCulture); } // Initialize the actual NetworkLink object to handle updates for us if (tickSeconds != -1 || viewSeconds != -1) { NetworkLink netLink = new NetworkLink(this, folder, loadFile, tickSeconds*1000, viewSeconds*1000); netLink.Fire(); networkLinks.Add(netLink); } else if(!fired) { NetworkLink netLink = new NetworkLink(this, folder, loadFile, -1, -1); netLink.Fire(); netLink.Dispose(); } } catch (Exception ex) { Log.Write(Log.Levels.Error, "KMLImporter: " + ex.ToString()); } } }
/// <summary> /// Locates Folders and parses them recursively /// </summary> /// <param name="inNode">The XmlNode to extract the Folders from</param> /// <param name="layer">The layer to add the folders to</param> /// <param name="KmlPath">The path to the KML file that is being loaded</param> private void ParseFolders(XmlNode inNode, RIcons layer, string KmlPath) { // Find Folders and initialize them recursively XmlNodeList folders = inNode.SelectNodes("Folder"); foreach (XmlNode node in folders) { try { // Find the name of the folder string foldername = "Folder"; XmlNode nameNode = node.SelectSingleNode("name"); if (nameNode != null) foldername = nameNode.InnerText; // See if the folder already exists RIcons folder = null; foreach (RenderableObject ro in layer.ChildObjects) { RIcons ricons = ro as RIcons; if ((ricons != null) && (ro.Name == foldername)) { folder = ricons; } } // Create a new folder if it doesn't exist yet if (folder == null) { folder = new RIcons(foldername); layer.Add(folder); } XmlNode visibilityNode = node.SelectSingleNode("visibility"); if(visibilityNode != null) layer.IsOn = (visibilityNode.InnerText == "1" ? true : false); // Parse placemarks into the folder ParseRenderables(node, folder, KmlPath); } catch (Exception ex) { Log.Write(Log.Levels.Error, "KMLImporter: " + ex.ToString()); } } }
/// <summary> /// Creates a scaled icon on the globe /// </summary> /// <param name="Name">The name of the item</param> /// <param name="Desc">The description</param> /// <param name="Lat">The latitude for the icon</param> /// <param name="Lon">The longitude for the icon</param> /// <param name="Alt">The altitude to draw the icon at</param> /// <param name="bitmapPath">The path to the bitmap to show</param> private void CreateIcon(RIcons layer, string Name, string Desc, string Uri, float Lat, float Lon, float Alt, Style style, bool bRotated, float rotation, bool bExtrude) { // Create the icon and set initial settings RIcon ic = new RIcon( Name, // name Lat, // latitude Lon, // longitude style.NormalIcon, // helper Alt); // altitude // Set optional icon settings if (Desc != null) ic.Description = Desc; if (Uri != null) ic.ClickableActionURL = Uri; if (bRotated) { ic.Rotation = Angle.FromDegrees(rotation); ic.IsRotated = true; } ic.m_drawGroundStick = bExtrude; if (style.NormalIcon != null && bitmapCache.Contains(style.NormalIcon)) { ic.Image = (Bitmap)bitmapCache[style.NormalIcon]; ic.Height = Double.IsNaN(style.NormalScale) ? IconSizeConstant : (int)(style.NormalScale * Math.Min(((Bitmap)bitmapCache[style.NormalIcon]).Height, IconSizeConstant)); ic.Width = Double.IsNaN(style.NormalScale) ? IconSizeConstant : (int)(style.NormalScale * Math.Min(((Bitmap)bitmapCache[style.NormalIcon]).Width, IconSizeConstant)); } // Add the icon to the layer layer.Add(ic); }
/// <summary> /// Parses Polygons /// </summary> /// <param name="inNode">The node containing Polygons</param> /// <param name="layer">The layer to add the resulting Polygons to</param> private void ParsePolygons(XmlNode inNode, RIcons layer) { // Parse all Placemarks that have a name and Polygon XmlNodeList polygons = inNode.SelectNodes("Placemark[name and Polygon]"); Random rand = new Random((int)DateTime.Now.Ticks); foreach (XmlNode node in polygons) { // Extract the name from this node XmlNode nameNode = node.SelectSingleNode("name"); string name = nameNode.InnerText; Style style = null; // get StyleUrl XmlNode styleUrlNode = node.SelectSingleNode("styleUrl"); if(styleUrlNode != null) { string styleUrlKey = styleUrlNode.InnerText.Trim(); if(styleUrlKey.StartsWith("#")) styleUrlKey = styleUrlKey.Substring(1, styleUrlKey.Length - 1); style = (Style)iconStyles[styleUrlKey]; } else { XmlNode styleNode = node.SelectSingleNode("Style"); if(styleNode != null) style = GetStyle( styleNode, new Style(), ""); } if(style == null) style = new Style(); if(style.LineStyle == null) style.LineStyle = new LineStyle(); if(style.PolyStyle == null) style.PolyStyle = new PolyStyle(); // See if this LineString has to be extruded to the ground bool extrude = false; XmlNode extrudeNode = node.SelectSingleNode("Polygon/extrude"); if (extrudeNode != null) extrude = Convert.ToBoolean(Convert.ToInt16(extrudeNode.InnerText)); XmlNode altitudeModeNode = node.SelectSingleNode("Polygon/altitudeMode"); AltitudeMode altitudeMode = GetAltitudeMode(altitudeModeNode); LinearRing outerRing = null; LinearRing[] innerRings = null; // Parse Outer Ring XmlNode outerRingNode = node.SelectSingleNode("Polygon/outerBoundaryIs/LinearRing/coordinates"); if (outerRingNode != null) { Point3d[] points = ParseCoordinates(outerRingNode); Console.WriteLine(points.Length); outerRing = new LinearRing(); outerRing.Points = points; } // Parse Inner Ring XmlNodeList innerRingNodes = node.SelectNodes("Polygon/innerBoundaryIs"); if (innerRingNodes != null) { innerRings = new LinearRing[innerRingNodes.Count]; for(int i = 0; i < innerRingNodes.Count; i++) { Point3d[] points = ParseCoordinates(innerRingNodes[i]); innerRings[i] = new LinearRing(); innerRings[i].Points = points; } } if(outerRing != null) { PolygonFeature polygonFeature = new PolygonFeature( name, m_world, outerRing, innerRings, System.Drawing.Color.FromArgb(style.PolyStyle.Color.Color)); polygonFeature.Extrude = extrude; polygonFeature.AltitudeMode = altitudeMode; polygonFeature.Outline = style.PolyStyle.Outline; if(style.LineStyle.Color != null) polygonFeature.OutlineColor = System.Drawing.Color.FromArgb(style.LineStyle.Color.Color); XmlNode visibilityNode = node.SelectSingleNode("visibility"); if(visibilityNode != null) polygonFeature.IsOn = (visibilityNode.InnerText == "1" ? true : false); layer.Add(polygonFeature); } } }