Пример #1
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));
        }
Пример #2
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);
        }
Пример #3
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));
        }
Пример #4
0
        private Polygon ParseTriangle(WktTokenQueue tokens)
        {
            tokens.Dequeue("TRIANGLE");
            var dimensions = ParseDimensions(tokens);

            return(ParsePolygonInner(tokens, dimensions));
        }
Пример #5
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));
        }
Пример #6
0
        private Polygon ParsePolygon(WktTokenQueue tokens)
        {
            tokens.Dequeue("POLYGON");
            var dimensions = ParseDimensions(tokens);

            return(ParsePolygonInner(tokens, dimensions));
        }
Пример #7
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);
        }
Пример #8
0
        private LineString ParseLineString(WktTokenQueue tokens)
        {
            tokens.Dequeue("LINESTRING");
            var dimensions = ParseDimensions(tokens);

            return(ParseLineStringInner(tokens, dimensions));
        }
Пример #9
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));
        }
Пример #10
0
        public IOgcGeometry Read(string wkt)
        {
            if (wkt == null)
            {
                throw new ArgumentNullException("wkt");
            }

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

            return(ParseGeometry(tokens));
        }
Пример #11
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));
            }
        }
Пример #12
0
        private IOgcGeometry 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.");
        }
Пример #13
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);
        }
Пример #14
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))));
        }
Пример #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));
        }
Пример #16
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));
        }
Пример #17
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));
        }
Пример #18
0
        public WktTokenQueue Tokenize(TextReader reader)
        {
            var queue   = new WktTokenQueue();
            var builder = new StringBuilder();

            WktTokenType?lastType = null;

            var nextCh = reader.Peek();

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

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

                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);
                    }
                }

                lastType = type;
            }
            return(queue);
        }
Пример #19
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));
        }
Пример #20
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));
        }
Пример #21
0
        private LineString ParseLineStringInner(WktTokenQueue tokens, WktDimensions dimensions)
        {
            var coords = ParseCoordinateSequence(tokens, dimensions);

            return(coords == null ? LineString.Empty : new LineString(coords));
        }