/// <summary>
        ///     Creates a Point using the next token in the stream.
        /// </summary>
        /// <param name="tokenizer">
        ///     Tokenizer over a stream of text in Well-known Text
        ///     format. The next tokens must form a &lt;Point Text&gt;.
        /// </param>
        /// <returns>
        ///     Returns a Point specified by the next token in
        ///     the stream.
        /// </returns>
        /// <remarks>
        ///     ParseException is thrown if an unexpected token is encountered.
        /// </remarks>
        private static MapPoint ReadPointText(WktStreamTokenizer tokenizer)
        {
            var nextToken = GetNextEmptyOrOpener(tokenizer);

            if (nextToken == "EMPTY")
            {
                throw new Exception("Empty Point");
            }

            var p = new MapPoint(GetNextNumber(tokenizer), GetNextNumber(tokenizer));

            GetNextCloser(tokenizer);
            return(p);
        }
        /// <summary>
        ///     Creates a <see cref="Polyline" /> using the next token in the stream.
        /// </summary>
        /// <param name="tokenizer">
        ///     tokenizer over a stream of text in Well-known Text format. The next tokens must form a
        ///     MultiLineString Text
        /// </param>
        /// <returns>a <see cref="Polyline" /> specified by the next token in the stream</returns>
        private static Polyline ReadMultiLineStringText(WktStreamTokenizer tokenizer)
        {
            var nextToken = GetNextEmptyOrOpener(tokenizer);

            if (nextToken == "EMPTY")
            {
                throw new Exception("Empty Multiline");
            }

            var lines = new PolylineBuilder(GetCoordinates(tokenizer));

            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                lines.AddPart(GetCoordinates(tokenizer));
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return(lines.ToGeometry());
        }
        /// <summary>
        ///     Creates a Polygon using the next token in the stream.
        /// </summary>
        /// <param name="tokenizer">
        ///     Tokenizer over a stream of text in Well-known Text
        ///     format. The next tokens must form a &lt;Polygon Text&gt;.
        /// </param>
        /// <param name="exteriorRingCcw"></param>
        /// <param name="exteriorRingCcwSpecified"></param>
        /// <returns>
        ///     Returns a Polygon specified by the next token
        ///     in the stream
        /// </returns>
        /// <remarks>
        ///     ParseException is thown if the coordinates used to create the Polygon
        ///     shell and holes do not form closed linestrings, or if an unexpected
        ///     token is encountered.
        /// </remarks>
        private static Polygon ReadPolygonText(WktStreamTokenizer tokenizer, bool exteriorRingCcw = false,
                                               bool exteriorRingCcwSpecified = false)
        {
            var nextToken = GetNextEmptyOrOpener(tokenizer);

            if (nextToken == "EMPTY")
            {
                throw new Exception("Empty Polygon");
            }

            var exteriorRing = GetCoordinates(tokenizer);


            IEnumerable <MapPoint> firstRing;

            // Exterior ring.  Force it to be CW/CCW to match the first exterior ring of the multipolygon, if it is part of a multipolygon
            if (exteriorRingCcwSpecified)
            {
                firstRing = Algorithms.IsCcw(exteriorRing) != exteriorRingCcw?Reverse(exteriorRing) : exteriorRing;
            }
            else
            {
                firstRing = exteriorRing;
            }

            var polygonBuilder = new PolygonBuilder(firstRing);

            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                //Add holes
                var interiorRing  = GetCoordinates(tokenizer);
                var correctedRing = interiorRing;
                // Make sure interior rings go in the opposite direction of the exterior rings
                if (Algorithms.IsCcw(interiorRing) == exteriorRingCcw)
                {
                    correctedRing = Reverse(interiorRing);
                }
                polygonBuilder.AddPart(correctedRing); //interior rings
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return(polygonBuilder.ToGeometry());
        }
        /// <summary>
        ///     Returns the next array of Coordinates in the stream.
        /// </summary>
        /// <param name="tokenizer">
        ///     Tokenizer over a stream of text in Well-known Text format.  The
        ///     next element returned by the stream should be "(" (the beginning of "(x1 y1, x2 y2, ..., xn yn)" or
        ///     "EMPTY".
        /// </param>
        /// <returns>
        ///     The next array of Coordinates in the stream, or an empty array of "EMPTY" is the
        ///     next element returned by the stream.
        /// </returns>
        private static IEnumerable <MapPoint> GetCoordinates(WktStreamTokenizer tokenizer)
        {
            var coordinates = new PointCollection();
            var nextToken   = GetNextEmptyOrOpener(tokenizer);

            if (nextToken == "EMPTY")
            {
                return(coordinates);
            }

            var externalCoordinate = new MapPoint(GetNextNumber(tokenizer), GetNextNumber(tokenizer));

            coordinates.Add(externalCoordinate);
            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                var internalCoordinate = new MapPoint(GetNextNumber(tokenizer), GetNextNumber(tokenizer));
                coordinates.Add(internalCoordinate);
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return(coordinates);
        }
 /// <summary>
 ///     Returns the next number in the stream.
 /// </summary>
 /// <param name="tokenizer">
 ///     Tokenizer over a stream of text in Well-known text format.  The next token
 ///     must be a number.
 /// </param>
 /// <returns>Returns the next number in the stream.</returns>
 /// <remarks>
 ///     ParseException is thrown if the next token is not a number.
 /// </remarks>
 private static double GetNextNumber(WktStreamTokenizer tokenizer)
 {
     tokenizer.NextToken();
     return(tokenizer.GetNumericValue());
 }
 /// <summary>
 ///     Creates a LineString using the next token in the stream.
 /// </summary>
 /// <param name="tokenizer">
 ///     Tokenizer over a stream of text in Well-known Text format.  The next
 ///     tokens must form a LineString Text.
 /// </param>
 /// <returns>Returns a LineString specified by the next token in the stream.</returns>
 /// <remarks>
 ///     ParseException is thrown if an unexpected token is encountered.
 /// </remarks>
 private static Polyline ReadLineStringText(WktStreamTokenizer tokenizer)
 {
     return(new Polyline(GetCoordinates(tokenizer)));
 }
Exemplo n.º 7
0
        /// <summary>
        ///     Converts a Well-known Text representation to a <see cref="Geometry" />.
        /// </summary>
        /// <param name="reader">
        ///     A Reader which will return a Geometry Tagged Text
        ///     string (see the OpenGIS Simple Features Specification)
        /// </param>
        /// <returns>
        ///     Returns a <see cref="Geometry" /> read from StreamReader.
        ///     An exception will be thrown if there is a parsing problem.
        /// </returns>
        public static Geometry GeometryFromWkt(TextReader reader)
        {
            var tokenizer = new WktStreamTokenizer(reader);

            return(ArcGISRuntimeWKT.GeometryFromWkt.ReadGeometryTaggedText(tokenizer));
        }