Example #1
0
        private Coordinate ParseCoordinate(WktTokenQueue tokens, WktDimensions dimensions)
        {
            var token = tokens.Dequeue(WktTokenType.Number);
            var x = double.Parse(token.Value, CultureInfo.InvariantCulture);

            token = tokens.Dequeue(WktTokenType.Number);
            var y = double.Parse(token.Value, CultureInfo.InvariantCulture);

            var z = double.NaN;
            var m = double.NaN;

            var optional = ParseOptionalOrdinates(tokens);

            if (optional.Count > 0)
            {
                if (dimensions == WktDimensions.XYM)
                {
                    m = optional[0];
                }
                else
                {
                    z = optional[0];
                    if (optional.Count > 1)
                        m = optional[1];
                }
            }

            if (!double.IsNaN(z) && !double.IsNaN(m))
                return new CoordinateZM(y, x, z, m);
            if (!double.IsNaN(z))
                return new CoordinateZ(y, x, z);
            if (!double.IsNaN(m))
                return new CoordinateM(y, x, m);
            return new Coordinate(y, x);
        }
        private object ParseGeometry(WktTokenQueue tokens)
        {
            if (tokens.Count == 0)
                return null;

            var token = tokens.Peek();

            if (token.Type == WktTokenType.String)
            {
                var value = token.Value.ToUpperInvariant();
                if (value == "POINT")
                    return ParsePoint(tokens);
                if (value == "LINESTRING")
                    return ParseLineString(tokens);
                if (value == "LINEARRING")
                    return ParseLinearRing(tokens);
                if (value == "POLYGON")
                    return ParsePolygon(tokens);
                if (value == "TRIANGLE")
                    return ParseTriangle(tokens);
                if (value == "MULTIPOINT")
                    return ParseMultiPoint(tokens);
                if (value == "MULTILINESTRING")
                    return ParseMultiLineString(tokens);
                if (value == "MULTIPOLYGON")
                    return ParseMultiPolygon(tokens);
                if (value == "GEOMETRYCOLLECTION")
                    return ParseGeometryCollection(tokens);
            }
            throw new SerializationException("WKT type '" + token.Value + "' not supported.");
        }
        public WktTokenQueue Tokenize(TextReader reader)
        {
            var queue = new WktTokenQueue();
            var builder = new StringBuilder();

            var nextCh = reader.Peek();
            while (nextCh != -1)
            {
                var ch = (char)reader.Read();
                var type = GetTokenType(ch);

                nextCh = reader.Peek();
                var nextType = WktTokenType.None;
                if (nextCh != -1)
                    nextType = GetTokenType((char)nextCh);

                if (type != WktTokenType.Whitespace)
                {
                    builder.Append(ch);
                    if (type != nextType ||
                        type == WktTokenType.Comma ||
                        type == WktTokenType.LeftParenthesis ||
                        type == WktTokenType.RightParenthesis)
                    {
                        if (type != WktTokenType.Whitespace)
                            queue.Enqueue(new WktToken(type, builder.ToString()));
                        builder.Remove(0, builder.Length);
                    }
                }
            }
            return queue;
        }
Example #4
0
        public IOgcGeometry Read(string wkt)
        {
            if (wkt == null)
                throw new ArgumentNullException("wkt");

            var tokens = new WktTokenQueue(_wktTokenizer.Tokenize(wkt));
            return ParseGeometry(tokens);
        }
Example #5
0
        public IOgcGeometry Read(Stream stream)
        {
            if (stream == null)
                throw new ArgumentNullException("stream");

            using (var reader = new StreamReader(stream))
            {
                var tokens = new WktTokenQueue(_wktTokenizer.Tokenize(reader));
                return ParseGeometry(tokens);
            }
        }
        private object ParsePoint(WktTokenQueue tokens)
        {
            tokens.Dequeue("POINT");
            var dimensions = ParseDimensions(tokens);

            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
				return _shapeConverter.ToPoint(null);
            }

            tokens.Dequeue(WktTokenType.LeftParenthesis);
            var coordinate = ParseCoordinate(tokens, dimensions);
            tokens.Dequeue(WktTokenType.RightParenthesis);
			return _shapeConverter.ToPoint(coordinate);
        }
Example #7
0
        private CoordinateSequence ParseCoordinateSequence(WktTokenQueue tokens, WktDimensions dimensions)
        {
            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
                return null;
            }

            tokens.Dequeue(WktTokenType.LeftParenthesis);

            var coordinates = new List<Coordinate> { ParseCoordinate(tokens, dimensions) };
            while (tokens.NextTokenIs(WktTokenType.Comma))
            {
                tokens.Dequeue();
                coordinates.Add(ParseCoordinate(tokens, dimensions));
            }

            tokens.Dequeue(WktTokenType.RightParenthesis);

            return new CoordinateSequence(coordinates);
        }
Example #8
0
        private Point ParseMultiPointCoordinate(WktTokenQueue tokens, WktDimensions dimensions)
        {
            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
                return Point.Empty;
            }

            var parenthesis = false;

            if (tokens.NextTokenIs(WktTokenType.LeftParenthesis))
            {
                tokens.Dequeue(WktTokenType.LeftParenthesis);
                parenthesis = true;
            }
            var coordinate = ParseCoordinate(tokens, dimensions);
            if (parenthesis && tokens.NextTokenIs(WktTokenType.RightParenthesis))
                tokens.Dequeue(WktTokenType.RightParenthesis);
            return new Point(coordinate);
        }
Example #9
0
        private MultiPolygon ParseMultiPolygon(WktTokenQueue tokens)
        {
            tokens.Dequeue("MULTIPOLYGON");
            var dimensions = ParseDimensions(tokens);

            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
                return MultiPolygon.Empty;
            }

            tokens.Dequeue(WktTokenType.LeftParenthesis);
            var polygons = new List<Polygon> { ParsePolygonInner(tokens, dimensions) };
            while (tokens.NextTokenIs(WktTokenType.Comma))
            {
                tokens.Dequeue();
                polygons.Add(ParsePolygonInner(tokens, dimensions));
            }
            tokens.Dequeue(WktTokenType.RightParenthesis);

            return new MultiPolygon(polygons);
        }
        private CoordinateInfo ParseCoordinate(WktTokenQueue tokens, Dimensions dimensions)
        {
            var token = tokens.Dequeue(WktTokenType.Number);
            var x = double.Parse(token.Value, CultureInfo.InvariantCulture);

            token = tokens.Dequeue(WktTokenType.Number);
            var y = double.Parse(token.Value, CultureInfo.InvariantCulture);

            var z = double.NaN;
            var m = double.NaN;

            var optional = ParseOptionalOrdinates(tokens);

            if (optional.Count > 0)
            {
                if (dimensions.HasFlag(Dimensions.M) && !dimensions.HasFlag(Dimensions.Z))
                {
                    m = optional[0];
                }
                else
                {
                    z = optional[0];
                    if (optional.Count > 1)
                        m = optional[1];
                }
            }

            if (!double.IsNaN(z) && !double.IsNaN(m))
                return new CoordinateInfo { X = x, Y = y, Z = z, M = m };
            if (!double.IsNaN(z))
                return new CoordinateInfo { X = x, Y = y, Z = z };
            if (!double.IsNaN(m))
                return new CoordinateInfo { X = x, Y = y, M = m };
            return new CoordinateInfo { X = x, Y = y };
        }
Example #11
0
        private MultiPoint ParseMultiPoint(WktTokenQueue tokens)
        {
            tokens.Dequeue("MULTIPOINT");
            var dimensions = ParseDimensions(tokens);

            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
                return MultiPoint.Empty;
            }

            tokens.Dequeue(WktTokenType.LeftParenthesis);

            var points = new List<Point> { ParseMultiPointCoordinate(tokens, dimensions) };
            while (tokens.NextTokenIs(WktTokenType.Comma))
            {
                tokens.Dequeue();
                points.Add(ParseMultiPointCoordinate(tokens, dimensions));
            }

            tokens.Dequeue(WktTokenType.RightParenthesis);

            return new MultiPoint(points);
        }
Example #12
0
        private Polygon ParsePolygonInner(WktTokenQueue tokens, WktDimensions dimensions)
        {
            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
                return Polygon.Empty;
            }

            tokens.Dequeue(WktTokenType.LeftParenthesis);
            var linestrings = ParseLineStrings(tokens, dimensions);
            tokens.Dequeue(WktTokenType.RightParenthesis);
            return new Polygon(new LinearRing(linestrings.First().Coordinates), linestrings.Skip(1).Select(x => new LinearRing(x.Coordinates)));
        }
        private object ParseMultiLineString(WktTokenQueue tokens)
        {
            tokens.Dequeue("multilinestring");
            var dimensions = ParseDimensions(tokens);

            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
                return _shapeConverter.ToMultiLineString(new CoordinateInfo[0][]);
            }

            var lineStrings = ParseLineStrings(tokens, dimensions);

            return _shapeConverter.ToMultiLineString(lineStrings);
        }
Example #14
0
 private LineString ParseLineString(WktTokenQueue tokens)
 {
     tokens.Dequeue("LINESTRING");
     var dimensions = ParseDimensions(tokens);
     return ParseLineStringInner(tokens, dimensions);
 }
Example #15
0
        private Point ParsePoint(WktTokenQueue tokens)
        {
            tokens.Dequeue("POINT");
            var dimensions = ParseDimensions(tokens);

            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
                return Point.Empty;
            }

            tokens.Dequeue(WktTokenType.LeftParenthesis);
            var coordinate = ParseCoordinate(tokens, dimensions);
            tokens.Dequeue(WktTokenType.RightParenthesis);
            return new Point(coordinate);
        }
Example #16
0
        private GeometryCollection ParseGeometryCollection(WktTokenQueue tokens)
        {
            tokens.Dequeue("GEOMETRYCOLLECTION");

            ParseDimensions(tokens);

            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
                return GeometryCollection.Empty;
            }

            tokens.Dequeue(WktTokenType.LeftParenthesis);

            var geometries = new List<IGeometry>();
            geometries.Add(ParseGeometry(tokens));

            while (tokens.NextTokenIs(WktTokenType.Comma))
            {
                tokens.Dequeue();
                geometries.Add(ParseGeometry(tokens));
            }

            tokens.Dequeue(WktTokenType.RightParenthesis);

            return new GeometryCollection(geometries);
        }
Example #17
0
 private LineString ParseLinearRing(WktTokenQueue tokens)
 {
     tokens.Dequeue("LINEARRING");
     var dimensions = ParseDimensions(tokens);
     var coords = ParseCoordinateSequence(tokens, dimensions);
     return coords == null ? LinearRing.Empty : new LinearRing(coords);
 }
Example #18
0
 private WktDimensions ParseDimensions(WktTokenQueue tokens)
 {
     var token = tokens.Peek();
     if (token.Type == WktTokenType.String)
     {
         var value = token.Value.ToUpperInvariant();
         if (value == "Z")
         {
             tokens.Dequeue();
             return WktDimensions.XYZ;
         }
         if (value == "M")
         {
             tokens.Dequeue();
             return WktDimensions.XYM;
         }
         if (value == "ZM")
         {
             tokens.Dequeue();
             return WktDimensions.XYZM;
         }
     }
     return WktDimensions.XY;
 }
 private object ParseLinearRing(WktTokenQueue tokens)
 {
     tokens.Dequeue("LINEARRING");
     var dimensions = ParseDimensions(tokens);
     var coords = ParseCoordinateSequence(tokens, dimensions);
     return _shapeConverter.ToLinearRing(coords ?? new CoordinateInfo[0]);
 }
 private object ParseLineStringInner(WktTokenQueue tokens, Dimensions dimensions)
 {
     var coords = ParseCoordinateSequence(tokens, dimensions);
     return _shapeConverter.ToLineString(coords ?? new CoordinateInfo[0]);
 }
Example #21
0
        private List<double> ParseOptionalOrdinates(WktTokenQueue tokens)
        {
            var attempt = true;
            var doubles = new List<double>();

            while (attempt)
            {
                if (tokens.NextTokenIs(WktTokenType.Number))
                {
                    var token = tokens.Dequeue(WktTokenType.Number);
                    doubles.Add(double.Parse(token.Value, CultureInfo.InvariantCulture));
                }
                else if (tokens.NextTokenIs(double.NaN.ToString(CultureInfo.InvariantCulture)))
                {
                    //TODO: Review this
                    tokens.Dequeue(WktTokenType.String);
                    doubles.Add(double.NaN);
                }
                else
                {
                    attempt = false;
                }
            }
            return doubles;
        }
        private CoordinateInfo ParseMultiPointCoordinate(WktTokenQueue tokens, Dimensions dimensions)
        {
            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
                return null;
            }

            var parenthesis = false;

            if (tokens.NextTokenIs(WktTokenType.LeftParenthesis))
            {
                tokens.Dequeue(WktTokenType.LeftParenthesis);
                parenthesis = true;
            }
            var coordinate = ParseCoordinate(tokens, dimensions);
            if (parenthesis && tokens.NextTokenIs(WktTokenType.RightParenthesis))
                tokens.Dequeue(WktTokenType.RightParenthesis);
			return coordinate;
        }
        private object ParseMultiPolygon(WktTokenQueue tokens)
        {
            tokens.Dequeue("MULTIPOLYGON");
            var dimensions = ParseDimensions(tokens);

            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
                return _shapeConverter.ToMultiPolygon(new CoordinateInfo[0][][]);
            }

            tokens.Dequeue(WktTokenType.LeftParenthesis);
			var polygons = new List<CoordinateInfo[][]> { ParseLineStrings(tokens, dimensions) };
            while (tokens.NextTokenIs(WktTokenType.Comma))
            {
                tokens.Dequeue();
				polygons.Add(ParseLineStrings(tokens, dimensions));
            }
            tokens.Dequeue(WktTokenType.RightParenthesis);

			return _shapeConverter.ToMultiPolygon(polygons.ToArray());
        }
Example #24
0
        private List<LineString> ParseLineStrings(WktTokenQueue tokens, WktDimensions dimensions)
        {
            var lineStrings = new List<LineString> { ParseLineStringInner(tokens, dimensions) };

            while (tokens.NextTokenIs(WktTokenType.Comma))
            {
                tokens.Dequeue();
                lineStrings.Add(ParseLineStringInner(tokens, dimensions));
            }

            return lineStrings;
        }
Example #25
0
 private Polygon ParsePolygon(WktTokenQueue tokens)
 {
     tokens.Dequeue("POLYGON");
     var dimensions = ParseDimensions(tokens);
     return ParsePolygonInner(tokens, dimensions);
 }
        private object ParseGeometryCollection(WktTokenQueue tokens)
        {
            tokens.Dequeue("GEOMETRYCOLLECTION");

            ParseDimensions(tokens);

            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
				return _shapeConverter.ToGeometryCollection(new object[0]);
            }

            tokens.Dequeue(WktTokenType.LeftParenthesis);

            var geometries = new List<object>();
            geometries.Add(ParseGeometry(tokens));

            while (tokens.NextTokenIs(WktTokenType.Comma))
            {
                tokens.Dequeue();
                geometries.Add(ParseGeometry(tokens));
            }

            tokens.Dequeue(WktTokenType.RightParenthesis);

            return _shapeConverter.ToGeometryCollection(geometries.ToArray());
        }
Example #27
0
 private Polygon ParseTriangle(WktTokenQueue tokens)
 {
     tokens.Dequeue("TRIANGLE");
     var dimensions = ParseDimensions(tokens);
     return ParsePolygonInner(tokens, dimensions);
 }
Example #28
0
        private MultiLineString ParseMultiLineString(WktTokenQueue tokens)
        {
            tokens.Dequeue("multilinestring");
            var dimensions = ParseDimensions(tokens);

            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
                return MultiLineString.Empty;
            }

            tokens.Dequeue(WktTokenType.LeftParenthesis);
            var lineStrings = ParseLineStrings(tokens, dimensions);
            tokens.Dequeue(WktTokenType.RightParenthesis);

            return new MultiLineString(lineStrings);
        }
Example #29
0
 private LineString ParseLineStringInner(WktTokenQueue tokens, WktDimensions dimensions)
 {
     var coords = ParseCoordinateSequence(tokens, dimensions);
     return coords == null ? LineString.Empty : new LineString(coords);
 }
 private Dimensions ParseDimensions(WktTokenQueue tokens)
 {
     var result = Dimensions.XY;
     var token = tokens.Peek();
     if (token.Type == WktTokenType.String)
     {
         var value = token.Value.ToUpperInvariant();
         if (value == "Z")
         {
             tokens.Dequeue();
             result |= Dimensions.Z;
         }
         if (value == "M")
         {
             tokens.Dequeue();
             result |= Dimensions.M;
         }
         if (value == "ZM")
         {
             tokens.Dequeue();
             result |= Dimensions.Z;
             result |= Dimensions.M;
         }
     }
     return result;
 }