Reads a stream of Well Known Text (wkt) string and returns a stream of tokens.
Inheritance: StreamTokenizer
Ejemplo n.º 1
0
        /// <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 Point ReadPointText(WktStreamTokenizer tokenizer)
        {
            var p         = new Point();
            var nextToken = GetNextEmptyOrOpener(tokenizer);

            if (nextToken == "EMPTY")
            {
                return(p);
            }
            p.X = GetNextNumber(tokenizer);
            p.Y = GetNextNumber(tokenizer);
            GetNextCloser(tokenizer);
            return(p);
        }
Ejemplo n.º 2
0
        /// <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 MultiPoint ReadMultiPointText(WktStreamTokenizer tokenizer)
        {
            var mp        = new MultiPoint();
            var nextToken = GetNextEmptyOrOpener(tokenizer);

            if (nextToken == "EMPTY")
            {
                return(mp);
            }
            mp.Points.Add(new Point(GetNextNumber(tokenizer), GetNextNumber(tokenizer)));
            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                mp.Points.Add(new Point(GetNextNumber(tokenizer), GetNextNumber(tokenizer)));
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return(mp);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///     Creates a <see cref="GeometryCollection" /> 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 GeometryCollection Text.
        /// </param>
        /// <returns>
        ///     A <see cref="GeometryCollection" /> specified by the next token in the stream.
        /// </returns>
        private static GeometryCollection ReadGeometryCollectionText(WktStreamTokenizer tokenizer)
        {
            var geometries = new GeometryCollection();
            var nextToken  = GetNextEmptyOrOpener(tokenizer);

            if (nextToken.Equals("EMPTY"))
            {
                return(geometries);
            }
            geometries.Collection.Add(ReadGeometryTaggedText(tokenizer));
            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken.Equals(","))
            {
                geometries.Collection.Add(ReadGeometryTaggedText(tokenizer));
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return(geometries);
        }
Ejemplo n.º 4
0
        /// <summary>
        ///     Creates a <see cref="MultiLineString" /> 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="MultiLineString" /> specified by the next token in the stream</returns>
        private static MultiLineString ReadMultiLineStringText(WktStreamTokenizer tokenizer)
        {
            var lines     = new MultiLineString();
            var nextToken = GetNextEmptyOrOpener(tokenizer);

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

            lines.LineStrings.Add(ReadLineStringText(tokenizer));
            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                lines.LineStrings.Add(ReadLineStringText(tokenizer));
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return(lines);
        }
Ejemplo n.º 5
0
        /// <summary>
        ///     Creates a Geometry 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;Geometry Tagged Text&gt;.
        /// </param>
        /// <returns>Returns a Geometry specified by the next token in the stream.</returns>
        /// <remarks>
        ///     Exception is thrown if the coordinates used to create a Polygon
        ///     shell and holes do not form closed linestrings, or if an unexpected
        ///     token is encountered.
        /// </remarks>
        private static Geometry ReadGeometryTaggedText(WktStreamTokenizer tokenizer)
        {
            tokenizer.NextToken();
            var      type = tokenizer.GetStringValue().ToUpper();
            Geometry geometry;

            switch (type)
            {
            case "POINT":
                geometry = ReadPointText(tokenizer);
                break;

            case "LINESTRING":
                geometry = ReadLineStringText(tokenizer);
                break;

            case "MULTIPOINT":
                geometry = ReadMultiPointText(tokenizer);
                break;

            case "MULTILINESTRING":
                geometry = ReadMultiLineStringText(tokenizer);
                break;

            case "POLYGON":
                geometry = ReadPolygonText(tokenizer);
                break;

            case "MULTIPOLYGON":
                geometry = ReadMultiPolygonText(tokenizer);
                break;

            case "GEOMETRYCOLLECTION":
                geometry = ReadGeometryCollectionText(tokenizer);
                break;

            default:
                throw new Exception(string.Format(CultureInfo.InvariantCulture,
                                                  "Geometrytype '{0}' is not supported.",
                                                  type));
            }
            return(geometry);
        }
Ejemplo n.º 6
0
        /// <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>
        /// <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)
        {
            var pol       = new Polygon();
            var nextToken = GetNextEmptyOrOpener(tokenizer);

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

            pol.ExteriorRing = new LinearRing(GetCoordinates(tokenizer));
            nextToken        = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                //Add holes
                pol.InteriorRings.Add(new LinearRing(GetCoordinates(tokenizer)));
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return(pol);
        }
Ejemplo n.º 7
0
        /// <summary>
        ///     Creates a <see cref="MultiPolygon" /> 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 MultiPolygon.
        /// </param>
        /// <returns>
        ///     a <code>MultiPolygon</code> specified by the next token in the
        ///     stream, or if if the coordinates used to create the <see cref="Polygon" />
        ///     shells and holes do not form closed linestrings.
        /// </returns>
        private static MultiPolygon ReadMultiPolygonText(WktStreamTokenizer tokenizer)
        {
            var polygons  = new MultiPolygon();
            var nextToken = GetNextEmptyOrOpener(tokenizer);

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

            var polygon = ReadPolygonText(tokenizer);

            polygons.Polygons.Add(polygon);
            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                polygon = ReadPolygonText(tokenizer);
                polygons.Polygons.Add(polygon);
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return(polygons);
        }
Ejemplo n.º 8
0
 /// <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());
 }
Ejemplo n.º 9
0
        /// <summary>
        ///     Converts a Well-known Text representation to a <see cref="Mapsui.Geometries.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="Mapsui.Geometries.Geometry" /> read from StreamReader.
        ///     An exception will be thrown if there is a parsing problem.
        /// </returns>
        public static Geometry Parse(TextReader reader)
        {
            var tokenizer = new WktStreamTokenizer(reader);

            return(ReadGeometryTaggedText(tokenizer));
        }
Ejemplo n.º 10
0
        /// <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>
        /// <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)
        {
            var pol = new Polygon();
            var nextToken = GetNextEmptyOrOpener(tokenizer);
            if (nextToken == "EMPTY")
                return pol;

            pol.ExteriorRing = new LinearRing(GetCoordinates(tokenizer));
            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                //Add holes
                pol.InteriorRings.Add(new LinearRing(GetCoordinates(tokenizer)));
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return pol;
        }
Ejemplo n.º 11
0
 /// <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();
 }
Ejemplo n.º 12
0
        /// <summary>
        ///     Returns the next ")" in the stream.
        /// </summary>
        /// <param name="tokenizer">
        ///     Tokenizer over a stream of text in Well-known Text
        ///     format. The next token must be ")".
        /// </param>
        /// <returns>Returns the next ")" in the stream.</returns>
        /// <remarks>
        ///     ParseException is thrown if the next token is not ")".
        /// </remarks>
        private static void GetNextCloser(WktStreamTokenizer tokenizer)
        {
            var nextWord = GetNextWord(tokenizer);
            if (nextWord == ")")
                return;

            throw new Exception("Expected ')' but encountered '" + nextWord + "'");
        }
Ejemplo n.º 13
0
 /// <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 LineString ReadLineStringText(WktStreamTokenizer tokenizer)
 {
     return(new LineString(GetCoordinates(tokenizer)));
 }
Ejemplo n.º 14
0
        /// <summary>
        ///     Creates a <see cref="MultiLineString" /> 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="MultiLineString" /> specified by the next token in the stream</returns>
        private static MultiLineString ReadMultiLineStringText(WktStreamTokenizer tokenizer)
        {
            var lines = new MultiLineString();
            var nextToken = GetNextEmptyOrOpener(tokenizer);
            if (nextToken == "EMPTY")
                return lines;

            lines.LineStrings.Add(ReadLineStringText(tokenizer));
            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                lines.LineStrings.Add(ReadLineStringText(tokenizer));
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return lines;
        }
Ejemplo n.º 15
0
 /// <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 LineString ReadLineStringText(WktStreamTokenizer tokenizer)
 {
     return new LineString(GetCoordinates(tokenizer));
 }
Ejemplo n.º 16
0
 /// <summary>
 ///     Creates a Geometry 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;Geometry Tagged Text&gt;.
 /// </param>
 /// <returns>Returns a Geometry specified by the next token in the stream.</returns>
 /// <remarks>
 ///     Exception is thrown if the coordinates used to create a Polygon
 ///     shell and holes do not form closed linestrings, or if an unexpected
 ///     token is encountered.
 /// </remarks>
 private static Geometry ReadGeometryTaggedText(WktStreamTokenizer tokenizer)
 {
     tokenizer.NextToken();
     var type = tokenizer.GetStringValue().ToUpper();
     Geometry geometry;
     switch (type)
     {
         case "POINT":
             geometry = ReadPointText(tokenizer);
             break;
         case "LINESTRING":
             geometry = ReadLineStringText(tokenizer);
             break;
         case "MULTIPOINT":
             geometry = ReadMultiPointText(tokenizer);
             break;
         case "MULTILINESTRING":
             geometry = ReadMultiLineStringText(tokenizer);
             break;
         case "POLYGON":
             geometry = ReadPolygonText(tokenizer);
             break;
         case "MULTIPOLYGON":
             geometry = ReadMultiPolygonText(tokenizer);
             break;
         case "GEOMETRYCOLLECTION":
             geometry = ReadGeometryCollectionText(tokenizer);
             break;
         default:
             throw new Exception(string.Format(CultureInfo.InvariantCulture,
                 "Geometrytype '{0}' is not supported.",
                 type));
     }
     return geometry;
 }
Ejemplo n.º 17
0
 /// <summary>
 ///     Creates a <see cref="GeometryCollection" /> 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 GeometryCollection Text.
 /// </param>
 /// <returns>
 ///     A <see cref="GeometryCollection" /> specified by the next token in the stream.
 /// </returns>
 private static GeometryCollection ReadGeometryCollectionText(WktStreamTokenizer tokenizer)
 {
     var geometries = new GeometryCollection();
     var nextToken = GetNextEmptyOrOpener(tokenizer);
     if (nextToken.Equals("EMPTY"))
         return geometries;
     geometries.Collection.Add(ReadGeometryTaggedText(tokenizer));
     nextToken = GetNextCloserOrComma(tokenizer);
     while (nextToken.Equals(","))
     {
         geometries.Collection.Add(ReadGeometryTaggedText(tokenizer));
         nextToken = GetNextCloserOrComma(tokenizer);
     }
     return geometries;
 }
Ejemplo n.º 18
0
        /// <summary>
        ///     Returns the next word in the stream as uppercase text.
        /// </summary>
        /// <param name="tokenizer">
        ///     Tokenizer over a stream of text in Well-known Text
        ///     format. The next token must be a word.
        /// </param>
        /// <returns>Returns the next word in the stream as uppercase text.</returns>
        /// <remarks>
        ///     Exception is thrown if the next token is not a word.
        /// </remarks>
        private static string GetNextWord(WktStreamTokenizer tokenizer)
        {
            var type = tokenizer.NextToken();
            var token = tokenizer.GetStringValue();
            if (type == TokenType.Number)
                throw new Exception("Expected a number but got " + token);
            if (type == TokenType.Word)
                return token.ToUpper();
            if (token == "(")
                return "(";
            if (token == ")")
                return ")";
            if (token == ",")
                return ",";

            throw new Exception("Not a valid symbol in WKT format.");
        }
Ejemplo n.º 19
0
        /// <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 Collection<Point> GetCoordinates(WktStreamTokenizer tokenizer)
        {
            var coordinates = new Collection<Point>();
            var nextToken = GetNextEmptyOrOpener(tokenizer);
            if (nextToken == "EMPTY") return coordinates;

            var externalCoordinate = new Point {X = GetNextNumber(tokenizer), Y = GetNextNumber(tokenizer)};
            coordinates.Add(externalCoordinate);
            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                var internalCoordinate = new Point {X = GetNextNumber(tokenizer), Y = GetNextNumber(tokenizer)};
                coordinates.Add(internalCoordinate);
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return coordinates;
        }
Ejemplo n.º 20
0
 /// <summary>
 ///     Returns the next ")" or "," in the stream.
 /// </summary>
 /// <param name="tokenizer">
 ///     tokenizer over a stream of text in Well-known Text
 ///     format. The next token must be ")" or ",".
 /// </param>
 /// <returns>Returns the next ")" or "," in the stream.</returns>
 /// <remarks>
 ///     ParseException is thrown if the next token is not ")" or ",".
 /// </remarks>
 private static string GetNextCloserOrComma(WktStreamTokenizer tokenizer)
 {
     tokenizer.NextToken();
     var nextWord = tokenizer.GetStringValue();
     if ((nextWord == ",") || (nextWord == ")"))
         return nextWord;
     throw new Exception("Expected ')' or ',' but encountered '" + nextWord + "'");
 }
Ejemplo n.º 21
0
 /// <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 Point ReadPointText(WktStreamTokenizer tokenizer)
 {
     var p = new Point();
     var nextToken = GetNextEmptyOrOpener(tokenizer);
     if (nextToken == "EMPTY")
         return p;
     p.X = GetNextNumber(tokenizer);
     p.Y = GetNextNumber(tokenizer);
     GetNextCloser(tokenizer);
     return p;
 }
Ejemplo n.º 22
0
 /// <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 MultiPoint ReadMultiPointText(WktStreamTokenizer tokenizer)
 {
     var mp = new MultiPoint();
     var nextToken = GetNextEmptyOrOpener(tokenizer);
     if (nextToken == "EMPTY")
         return mp;
     mp.Points.Add(new Point(GetNextNumber(tokenizer), GetNextNumber(tokenizer)));
     nextToken = GetNextCloserOrComma(tokenizer);
     while (nextToken == ",")
     {
         mp.Points.Add(new Point(GetNextNumber(tokenizer), GetNextNumber(tokenizer)));
         nextToken = GetNextCloserOrComma(tokenizer);
     }
     return mp;
 }
Ejemplo n.º 23
0
        /// <summary>
        ///     Returns the next "EMPTY" or "(" in the stream as uppercase text.
        /// </summary>
        /// <param name="tokenizer">
        ///     Tokenizer over a stream of text in Well-known Text
        ///     format. The next token must be "EMPTY" or "(".
        /// </param>
        /// <returns>
        ///     the next "EMPTY" or "(" in the stream as uppercase
        ///     text.
        /// </returns>
        /// <remarks>
        ///     ParseException is thrown if the next token is not "EMPTY" or "(".
        /// </remarks>
        private static string GetNextEmptyOrOpener(WktStreamTokenizer tokenizer)
        {
            tokenizer.NextToken();
            var nextWord = tokenizer.GetStringValue();
            if ((nextWord == "EMPTY") || (nextWord == "("))
                return nextWord;

            throw new Exception("Expected 'EMPTY' or '(' but encountered '" + nextWord + "'");
        }
Ejemplo n.º 24
0
        /// <summary>
        ///     Creates a <see cref="MultiPolygon" /> 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 MultiPolygon.
        /// </param>
        /// <returns>
        ///     a <code>MultiPolygon</code> specified by the next token in the
        ///     stream, or if if the coordinates used to create the <see cref="Polygon" />
        ///     shells and holes do not form closed linestrings.
        /// </returns>
        private static MultiPolygon ReadMultiPolygonText(WktStreamTokenizer tokenizer)
        {
            var polygons = new MultiPolygon();
            var nextToken = GetNextEmptyOrOpener(tokenizer);
            if (nextToken == "EMPTY")
                return polygons;

            var polygon = ReadPolygonText(tokenizer);
            polygons.Polygons.Add(polygon);
            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                polygon = ReadPolygonText(tokenizer);
                polygons.Polygons.Add(polygon);
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            return polygons;
        }
Ejemplo n.º 25
0
        /// <summary>
        ///     Converts a Well-known Text representation to a <see cref="Mapsui.Geometries.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="Mapsui.Geometries.Geometry" /> read from StreamReader.
        ///     An exception will be thrown if there is a parsing problem.
        /// </returns>
        public static Geometry Parse(TextReader reader)
        {
            var tokenizer = new WktStreamTokenizer(reader);

            return ReadGeometryTaggedText(tokenizer);
        }