Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <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);
        }