/// <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> /// 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> /// Parses Placemarks /// </summary> /// <param name="inNode">The node containing Placemarks</param> /// <param name="layer">The layer to add the resulting icons or folders to</param> /// <param name="KmlPath">The path to the KML file that is being loaded</param> private void ParsePlacemarks(XmlNode inNode, RIcons layer, string KmlPath) { foreach (WorldWind.Renderable.RenderableObject ro in layer.ChildObjects) { RIcon ricon = ro as RIcon; if (ricon != null) ricon.HasBeenUpdated = false; } // Parse all Placemarks that have a name and location XmlNodeList placemarks = inNode.SelectNodes("Placemark[name and Point]"); foreach (XmlNode node in placemarks) { try { string name = node.SelectSingleNode("name").InnerText; RIcon update = null; // Extract the location string for this Placemark node and split it up string loc = node.SelectSingleNode("Point/coordinates").InnerText.Trim(); LLA lla = ParseCoordinate(loc); string desc = null; string uri = null; // Extract a description and make sure it's not too long XmlNode xnode = node.SelectSingleNode("description"); if (xnode != null) { string descRaw = xnode.InnerText; uri = SearchUri(descRaw); // Ashish Datta - commented so that the HTML stays in the description property. desc = descRaw; if (desc.Length > 505) desc = desc.Substring(0, 500) + "..."; } float rotation = 0; bool bRotated = false; string rotRaw = null; // Locate a node containing rotation XmlNode rotNode1 = node.SelectSingleNode("Point/rotation"); if (rotNode1 != null) rotRaw = rotNode1.InnerText; else { XmlNode rotNode2 = node.SelectSingleNode("IconStyle/heading"); if (rotNode2 != null) rotRaw = rotNode2.InnerText; else { XmlNode rotNode3 = node.SelectSingleNode("Style/IconStyle/heading"); if (rotNode3 != null) rotRaw = rotNode3.InnerText; } } // If rotation was found parse it if (rotRaw != null) { rotation = Convert.ToSingle(rotRaw, CultureInfo.InvariantCulture); bRotated = true; } // Find a style for this icon Style style = LocateStyle(node, KmlPath); // Check if this icon has to be extruded bool bExtrude = false; XmlNode extrudeNode = node.SelectSingleNode("Point/extrude"); if (extrudeNode != null) { if (extrudeNode.InnerText == "1") bExtrude = true; } // See if this icon already exists, and store it if it does foreach (WorldWind.Renderable.RenderableObject ro in layer.ChildObjects) { RIcon ricon = ro as RIcon; if (ricon != null) { if ((ro.Name == name) && ((style == null) || ((ricon.NormalIcon == style.NormalIcon) && (!ricon.HasBeenUpdated)))) { update = ricon; update.HasBeenUpdated = true; break; } } } // If a previous icons has been found update it's location if (update != null) { update.IsRotated = bRotated; if (bRotated) { update.Rotation = Angle.FromDegrees(rotation); } if (style != null) { update.Height = Double.IsNaN(style.NormalScale) ? IconSizeConstant : (int)(style.NormalScale * Math.Min(((Bitmap)bitmapCache[style.NormalIcon]).Height, IconSizeConstant)); update.Width = Double.IsNaN(style.NormalScale) ? IconSizeConstant : (int)(style.NormalScale * Math.Min(((Bitmap)bitmapCache[style.NormalIcon]).Width, IconSizeConstant)); update.Description = desc; update.SetPosition(lla.lat, lla.lon, lla.alt); } } else { // Create the icon with either the generated bitmap or the default dot if (style != null) { CreateIcon(layer, name, desc, uri, lla.lat, lla.lon, lla.alt, style, bRotated, rotation, bExtrude); } else { // Use the default 'tack' icon if no style was found string pal3Path = Path.Combine(KmlDirectory, "icons/palette-3.png"); if (File.Exists(pal3Path)) { if (!bitmapCache.Contains(pal3Path)) bitmapCache.Add(pal3Path, (Bitmap)Bitmap.FromFile(pal3Path)); Style pinStyle = new Style(GetSubImage(new Style(pal3Path), 448, 64, 64, 64)); CreateIcon(layer, name, desc, uri, lla.lat, lla.lon, lla.alt, pinStyle, bRotated, rotation, bExtrude); } } } } catch (Exception ex) { Log.Write(Log.Levels.Error, "KMLImporter: " + ex.ToString()); } } // Cleanup icons that have not been updated RemoveUnusedIcons(layer); }
/// <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> /// Extracts a rectangular selection from a given style /// </summary> /// <param name="filename">The file to extract the SubBitmap from</param> /// <param name="x">x</param> /// <param name="y">y</param> /// <param name="w">width</param> /// <param name="h">height</param> /// <returns>The generated bitmap</returns> private string GetSubImage(Style style, int x, int y, int w, int h) { // Try using a cached version string key = style.NormalIcon+ "|" +x.ToString("D5", CultureInfo.InvariantCulture) +y.ToString("D5", CultureInfo.InvariantCulture) +w.ToString("D5", CultureInfo.InvariantCulture) +h.ToString("D5", CultureInfo.InvariantCulture); if (bitmapCache.ContainsKey(key)) return key; // Create a new bitmap to draw into Bitmap outImage = new Bitmap(w, h); Graphics graphics = Graphics.FromImage(outImage); // Draw a region into the newly created bitmap RectangleF destinationRect = new RectangleF(0, 0, w, h); if (style.NormalIcon != null && bitmapCache.Contains(style.NormalIcon)) { System.Drawing.Bitmap bit = ((Bitmap)bitmapCache[style.NormalIcon]); RectangleF sourceRect = new RectangleF(x, bit.Height - y - h, w, h); graphics.DrawImage((Bitmap)bitmapCache[style.NormalIcon], destinationRect, sourceRect, GraphicsUnit.Pixel); graphics.Flush(); // Cache the generated bitmap bitmapCache.Add(key, outImage); return key; } else { return null; } }
/// <summary> /// Modifies a style with Style tags loaded from an XmlNode /// </summary> /// <param name="style">The XmlNode containing override information</param> /// <param name="oldStyle">The style to override</param> /// <param name="KmlPath">The path to the KML file that is being loaded</param> /// <returns>The style with overridden values</returns> private Style GetStyle(XmlNode style, Style oldStyle, string KmlPath) { try { Style overStyle = oldStyle; bool bPalette = false; // Determine the scale, if any, for this style XmlNode scaleNode = style.SelectSingleNode("IconStyle/scale"); if (scaleNode != null) overStyle.NormalScale = Convert.ToDouble(scaleNode.InnerText, CultureInfo.InvariantCulture); // Search for style tags in location 1 XmlNode hrefNode = style.SelectSingleNode("IconStyle/Icon/href"); if (hrefNode != null) { string filename = hrefNode.InnerText; if (filename.StartsWith("root://")) // Use palette bitmap { filename = Path.Combine(KmlDirectory, filename.Remove(0, 7)); if (File.Exists(filename)) { bPalette = true; overStyle.NormalIcon = GetDiskImage(filename); } } else if (filename.StartsWith("http://")) // Use bitmap from the internet { overStyle.NormalIcon = GetWebImage(filename); } else if (File.Exists(Path.Combine(Path.GetDirectoryName(KmlPath), filename))) // Use a file from disk { overStyle.NormalIcon = GetDiskImage(Path.Combine(Path.GetDirectoryName(KmlPath), filename)); } else if (File.Exists(Path.Combine(KmlDirectory, filename))) // Use a file from disk { overStyle.NormalIcon = GetDiskImage(Path.Combine(KmlDirectory, filename)); } } // See if we need to cut this style to a substyle XmlNode wNode = style.SelectSingleNode("IconStyle/Icon/w"); XmlNode hNode = style.SelectSingleNode("IconStyle/Icon/h"); if (wNode != null && hNode != null) { int w = Convert.ToInt32(wNode.InnerText, CultureInfo.InvariantCulture); int h = Convert.ToInt32(hNode.InnerText, CultureInfo.InvariantCulture); int x = 0, y = 0; XmlNode xNode = style.SelectSingleNode("IconStyle/Icon/x"); if (xNode != null) x = Convert.ToInt32(xNode.InnerText, CultureInfo.InvariantCulture); XmlNode yNode = style.SelectSingleNode("IconStyle/Icon/y"); if (yNode != null) y = Convert.ToInt32(yNode.InnerText, CultureInfo.InvariantCulture); if (bPalette) overStyle.NormalIcon = GetSubImage(overStyle, x*2, y*2, w*2, h*2); else overStyle.NormalIcon = GetSubImage(overStyle, x, y, w, h); } // Search for style tags in a possible secondary location XmlNode iconNode = style.SelectSingleNode("icon"); if (iconNode != null) { string filename = iconNode.InnerText; if (!filename.StartsWith("http://")) return null; overStyle.NormalIcon = GetWebImage(filename); } XmlNode balloonStyleNode = style.SelectSingleNode("BalloonStyle"); if(balloonStyleNode != null) { BalloonStyle balloonStyle = new BalloonStyle(); XmlNode balloonTextNode = balloonStyleNode.SelectSingleNode("text"); if(balloonTextNode != null) { TextElement textElement = new TextElement(); textElement.Text = balloonTextNode.InnerText; XmlNode textNodeColor = balloonTextNode.SelectSingleNode("textColor"); if(textNodeColor != null) textElement.TextColor = new ColorElement(ParseColor(textNodeColor.InnerText)); balloonStyle.Text = textElement; } XmlNode balloonTextColorNode = balloonStyleNode.SelectSingleNode("textColor"); if(balloonTextColorNode != null) balloonStyle.TextColor = new ColorElement(ParseColor(balloonTextColorNode.InnerText)); XmlNode balloonColorNode = balloonStyleNode.SelectSingleNode("color"); if(balloonColorNode != null) balloonStyle.Color = new ColorElement(ParseColor(balloonColorNode.InnerText)); overStyle.BalloonStyle = balloonStyle; } XmlNode iconStyleNode = style.SelectSingleNode("IconStyle"); if(iconStyleNode != null) { XmlNode iconElementNode = iconStyleNode.SelectSingleNode("Icon"); IconElement iconElement = new IconElement(); if(iconElementNode != null) { XmlNode iconElementHrefNode = iconElementNode.SelectSingleNode("href"); if (iconElementHrefNode != null) { string filename = iconElementHrefNode.InnerText; if (filename.StartsWith("root://")) // Use palette bitmap { filename = Path.Combine(KmlDirectory, filename.Remove(0, 7)); if (File.Exists(filename)) { bPalette = true; iconElement.href = GetDiskImage(filename); } } else if (filename.StartsWith("http://")) // Use bitmap from the internet { iconElement.href = GetWebImage(filename); } else if (File.Exists(Path.Combine(Path.GetDirectoryName(KmlPath), filename))) // Use a file from disk { iconElement.href = GetDiskImage(Path.Combine(Path.GetDirectoryName(KmlPath), filename)); } else if (File.Exists(Path.Combine(KmlDirectory, filename))) // Use a file from disk { iconElement.href = GetDiskImage(Path.Combine(KmlDirectory, filename)); } } // See if we need to cut this style to a substyle XmlNode iconElementWNode = iconElementNode.SelectSingleNode("w"); XmlNode iconElementHNode = iconElementNode.SelectSingleNode("h"); if (iconElementWNode != null && iconElementHNode != null) { int w = Convert.ToInt32(wNode.InnerText, CultureInfo.InvariantCulture); int h = Convert.ToInt32(hNode.InnerText, CultureInfo.InvariantCulture); int x = 0, y = 0; XmlNode xNode = iconElementNode.SelectSingleNode("x"); if (xNode != null) x = Convert.ToInt32(xNode.InnerText, CultureInfo.InvariantCulture); XmlNode yNode = iconElementNode.SelectSingleNode("y"); if (yNode != null) y = Convert.ToInt32(yNode.InnerText, CultureInfo.InvariantCulture); if (bPalette) iconElement.href = GetSubImage(overStyle, x*2, y*2, w*2, h*2); else iconElement.href = GetSubImage(overStyle, x, y, w, h); } IconStyle iconStyle = new IconStyle(iconElement); XmlNode iconStyleColorNode = iconStyleNode.SelectSingleNode("color"); if(iconStyleColorNode != null) iconStyle.Color = new ColorElement(ParseColor(iconStyleColorNode.InnerText)); XmlNode iconStyleColorModeNode = iconStyleNode.SelectSingleNode("colorMode"); if(iconStyleColorModeNode != null) { iconStyle.ColorMode = (iconStyleColorModeNode.InnerText.ToLower() == "random" ? ColorMode.Random : ColorMode.Normal); } XmlNode iconStyleHeadingNode = iconStyleNode.SelectSingleNode("heading"); if(iconStyleHeadingNode != null) iconStyle.Heading = new DecimalElement(double.Parse(iconStyleHeadingNode.InnerText, CultureInfo.InvariantCulture)); XmlNode iconStyleScaleNode = iconStyleNode.SelectSingleNode("scale"); if(iconStyleScaleNode != null) iconStyle.Scale = new DecimalElement(double.Parse(iconStyleScaleNode.InnerText, CultureInfo.InvariantCulture)); overStyle.IconStyle = iconStyle; } } XmlNode labelStyleNode = style.SelectSingleNode("LabelStyle"); if(labelStyleNode != null) { LabelStyle labelStyle = new LabelStyle(); XmlNode labelColorNode = labelStyleNode.SelectSingleNode("color"); if(labelColorNode != null) labelStyle.Color = new ColorElement(ParseColor(labelColorNode.InnerText)); XmlNode labelColorModeNode = labelStyleNode.SelectSingleNode("colorMode"); if(labelColorModeNode != null) labelStyle.ColorMode = (labelColorModeNode.InnerText.ToLower() == "random" ? ColorMode.Random : ColorMode.Normal); XmlNode labelScaleNode = labelStyleNode.SelectSingleNode("scale"); if(labelScaleNode != null) labelStyle.Scale = new DecimalElement(double.Parse(labelScaleNode.InnerText, CultureInfo.InvariantCulture)); overStyle.LabelStyle = labelStyle; } XmlNode lineStyleNode = style.SelectSingleNode("LineStyle"); if(lineStyleNode != null) { LineStyle lineStyle = new LineStyle(); XmlNode lineColorNode = lineStyleNode.SelectSingleNode("color"); if(lineColorNode != null) lineStyle.Color = new ColorElement(ParseColor(lineColorNode.InnerText)); XmlNode lineColorModeNode = lineStyleNode.SelectSingleNode("colorMode"); if(lineColorModeNode != null) lineStyle.ColorMode = (lineColorModeNode.InnerText.ToLower() == "random" ? ColorMode.Random : ColorMode.Normal); XmlNode lineWidthNode = lineStyleNode.SelectSingleNode("width"); if(lineWidthNode != null) lineStyle.Width = new DecimalElement(double.Parse(lineWidthNode.InnerText, CultureInfo.InvariantCulture)); overStyle.LineStyle = lineStyle; } XmlNode polyStyleNode = style.SelectSingleNode("PolyStyle"); if(polyStyleNode != null) { PolyStyle polyStyle = new PolyStyle(); XmlNode polyColorNode = polyStyleNode.SelectSingleNode("color"); if(polyColorNode != null) polyStyle.Color = new ColorElement(ParseColor(polyColorNode.InnerText)); XmlNode polyColorModeNode = polyStyleNode.SelectSingleNode("colorMode"); if(polyColorModeNode != null) polyStyle.ColorMode = (polyColorModeNode.InnerText.ToLower() == "random" ? ColorMode.Random : ColorMode.Normal); XmlNode polyFillNode = polyStyleNode.SelectSingleNode("fill"); if(polyFillNode != null) polyStyle.Fill = (polyFillNode.InnerText == "1" ? true : false); XmlNode polyOutlineNode = polyStyleNode.SelectSingleNode("outline"); if(polyOutlineNode != null) polyStyle.Outline = (polyOutlineNode.InnerText == "1" ? true : false); overStyle.PolyStyle = polyStyle; } return overStyle; } catch (System.Net.WebException ex) { Log.Write(Log.Levels.Error, "KMLImporter: " + ex.ToString()); } return null; }
/// <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); } } }