Ejemplo n.º 1
0
        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()));
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        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()));
        }
Ejemplo n.º 4
0
        private object ParseTriangle(WktTokenQueue tokens)
        {
            tokens.Dequeue("TRIANGLE");
            var dimensions = ParseDimensions(tokens);

            return(ParsePolygonInner(tokens, dimensions));
        }
Ejemplo n.º 5
0
        private CoordinateInfo[] ParseCoordinateSequence(WktTokenQueue tokens, Dimensions dimensions)
        {
            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();

                return(new CoordinateInfo[0]);
            }

            tokens.Dequeue(WktTokenType.LeftParenthesis);

            var coordinates = new List <CoordinateInfo> {
                ParseCoordinate(tokens, dimensions)
            };

            while (tokens.NextTokenIs(WktTokenType.Comma))
            {
                tokens.Dequeue();
                coordinates.Add(ParseCoordinate(tokens, dimensions));
            }

            tokens.Dequeue(WktTokenType.RightParenthesis);

            return(coordinates.ToArray());
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        private object ParsePolygon(WktTokenQueue tokens)
        {
            tokens.Dequeue("POLYGON");
            var dimensions = ParseDimensions(tokens);

            return(ParsePolygonInner(tokens, dimensions));
        }
Ejemplo n.º 8
0
        private object ParseLineString(WktTokenQueue tokens)
        {
            tokens.Dequeue("LINESTRING");
            var dimensions = ParseDimensions(tokens);

            return(ParseLineStringInner(tokens, dimensions));
        }
Ejemplo n.º 9
0
        private object ParseLinearRing(WktTokenQueue tokens)
        {
            tokens.Dequeue("LINEARRING");
            var dimensions = ParseDimensions(tokens);
            var coords     = ParseCoordinateSequence(tokens, dimensions);

            return(_shapeConverter.ToLinearRing(coords ?? new CoordinateInfo[0]));
        }
Ejemplo n.º 10
0
        public object Read(string wkt)
        {
            if (wkt == null)
            {
                throw new ArgumentNullException("wkt");
            }

            var tokens = new WktTokenQueue(_wktTokenizer.Tokenize(wkt));

            return(ParseGeometry(tokens));
        }
Ejemplo n.º 11
0
        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
            });
        }
Ejemplo n.º 12
0
        private object ParsePolygonInner(WktTokenQueue tokens, Dimensions dimensions)
        {
            if (tokens.NextTokenIs("EMPTY"))
            {
                tokens.Dequeue();
                return(_shapeConverter.FromPolygon(new CoordinateInfo[0][][]));
            }

            var linestrings = ParseLineStrings(tokens, dimensions);

            return(_shapeConverter.ToPolygon(linestrings));
        }
Ejemplo n.º 13
0
        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.");
        }
Ejemplo n.º 14
0
        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));
        }
Ejemplo n.º 15
0
        private CoordinateInfo[][] ParseLineStrings(WktTokenQueue tokens, Dimensions dimensions)
        {
            tokens.Dequeue(WktTokenType.LeftParenthesis);
            var lineStrings = new List <CoordinateInfo[]> {
                ParseCoordinateSequence(tokens, dimensions)
            };

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

            tokens.Dequeue(WktTokenType.RightParenthesis);
            return(lineStrings.ToArray());
        }
Ejemplo n.º 16
0
        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));
        }
Ejemplo n.º 17
0
        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);
        }
Ejemplo n.º 18
0
        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);
        }
Ejemplo n.º 19
0
        private object ParseLineStringInner(WktTokenQueue tokens, Dimensions dimensions)
        {
            var coords = ParseCoordinateSequence(tokens, dimensions);

            return(_shapeConverter.ToLineString(coords ?? new CoordinateInfo[0]));
        }