/// <summary> /// This method visits a KML Polygon element /// </summary> /// <param name="elem">KML Polygon element to be visited</param> protected void VisitPolygon(XmlElement elem) { if (elem == null) { return; } #region Extract Outer Border XmlElement outerBoundaryIs = GetFirstChild(elem, "outerBoundaryIs"); if (outerBoundaryIs == null) { return; } XmlElement outerLinearRing = GetFirstChild(outerBoundaryIs, "LinearRing"); if (outerLinearRing == null) { return; } int numOfGeographiesBefore = this.Geographies.Count; VisitLinearRing(outerLinearRing); int numOfGeographiesAfter = this.Geographies.Count; // Extracts the outer ring if (numOfGeographiesAfter == numOfGeographiesBefore) { throw new KMLException("Outer ring not found!"); } int index = this.Geographies.Count - 1; Geography g = this.Geographies[index]; this.m_Geographies.RemoveAt(index); LinearRing outerRing = g as LinearRing; if (outerRing == null) { throw new KMLException("Outer ring not created!"); } Polygon polygon = new Polygon(); bool isValidPolygon = true; #region Check outer ring orientation. Outer boundary should be oriented counter-clockwise if (!outerRing.IsValid) { // Checks if just the ring's orientation is wrong outerRing.SwitchOrientation(); if (!outerRing.IsValid) { isValidPolygon = false; outerRing.SwitchOrientation(); } } #endregion polygon.OuterRing = outerRing; #endregion #region Extract Inner Borders XmlNodeList innerBoundaryIsLst = elem.GetElementsByTagName("innerBoundaryIs"); if (innerBoundaryIsLst != null) { foreach (XmlNode innerBorderNode in innerBoundaryIsLst) { XmlElement innerBoundaryIs = innerBorderNode as XmlElement; if (innerBoundaryIs == null) { continue; } XmlElement innerLinearRing = GetFirstChild(innerBoundaryIs, "LinearRing"); if (innerLinearRing == null) { continue; } numOfGeographiesBefore = this.Geographies.Count; VisitLinearRing(innerLinearRing); numOfGeographiesAfter = this.Geographies.Count; // Extracts the inner ring if (numOfGeographiesBefore == numOfGeographiesAfter) { throw new KMLException("Inner ring not found!"); } index = this.Geographies.Count - 1; g = this.Geographies[index]; this.m_Geographies.RemoveAt(index); LinearRing innerRing = g as LinearRing; if (innerRing == null) { throw new KMLException("Inner ring not created!"); } #region Check the ring's orientation. Inner rings should be clockwise oriented if (isValidPolygon) { if (innerRing.IsValid) { // The inner rings should be in the opposite direction from the outer ring innerRing.SwitchOrientation(); } } #endregion polygon.InnerRing.Add(innerRing); } } #endregion // Extracts the other non-geographic data VisitGeography(elem, polygon); #region Extract altitude mode int?altitudeModeCode = GetAltitudeModeCode(elem); if (altitudeModeCode.HasValue) { // Updates all the points on the outer bound if (polygon.OuterRing != null) { foreach (Point p in polygon.OuterRing.Points) { p.Measure = altitudeModeCode; } } // Update all the points on all the inner bounds if (polygon.InnerRing != null) { foreach (LinearRing r in polygon.InnerRing) { if (r.Points == null) { return; } foreach (Point p1 in r.Points) { p1.Measure = altitudeModeCode; } } } } #endregion #region Handles tesselate flag if (polygon.Tesselate) { if (polygon.OuterRing != null) { polygon.OuterRing.StoreTesselateFlag(); } if (polygon.InnerRing != null) { foreach (LinearRing r in polygon.InnerRing) { r.StoreTesselateFlag(); } } } #endregion // Sets the geography instance context polygon.Context = (elem.ParentNode != null) ? elem.ParentNode.OuterXml : elem.OuterXml; m_Geographies.Add(polygon); }
/// <summary> /// This method visits a KML LineString element /// </summary> /// <param name="elem">KML line string element to be visited</param> /// <param name="isLineRing">True if the line is the ring</param> protected void VisitLineString( XmlElement elem, bool isLineRing) { if (elem == null) { return; } XmlNode coordinates = GetFirstChild(elem, "coordinates"); if (coordinates == null || !coordinates.HasChildNodes) { return; } XmlNode txt = coordinates.ChildNodes[0]; string allCoordinates = txt.InnerText; IList <Point> points = ParseCoordinates(allCoordinates); if (points == null || points.Count == 0) { return; } LineString ls = null; if (isLineRing) { ls = new LinearRing(); } else { ls = new LineString(); } ls.Points.AddRange(points); int?altitudeModeCode = GetAltitudeModeCode(elem); foreach (Point p in ls.Points) { p.Measure = altitudeModeCode; } // Extract other non-geographic data VisitGeography(elem, ls); #region Handle tesselate flag ls.StoreTesselateFlag(); #endregion // Sets the geography instance context ls.Context = (elem.ParentNode != null) ? elem.ParentNode.OuterXml : elem.OuterXml; m_Geographies.Add(ls); }