/// <summary> /// Parses a coordinate. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <param name="is3D">bool value indicating whether coordinate being parsed had z-coordinate.</param> /// <param name="isMeasured">bool value indicating whether coordinate beeing parsed has m-value.</param> /// <returns>A coordinate specified by tokens.</returns> /// <remarks><![CDATA[<x> <y> {<z>} {<m>}]]></remarks> private static Coordinate ParseCoordinate(WktTokensBuffer tokens, bool is3D, bool isMeasured) { WktToken t = WktReader.Expect(TokenType.NUMBER, tokens); double x = double.Parse(t.Value, _invarianCulture); WktReader.Expect(TokenType.WHITESPACE, tokens); t = WktReader.Expect(TokenType.NUMBER, tokens); double y = double.Parse(t.Value, _invarianCulture); double z = double.NaN; double m = double.NaN; if (is3D) { WktReader.Expect(TokenType.WHITESPACE, tokens); t = WktReader.Expect(TokenType.NUMBER, tokens); z = double.Parse(t.Value, _invarianCulture); } if (isMeasured) { WktReader.Expect(TokenType.WHITESPACE, tokens); t = WktReader.Expect(TokenType.NUMBER, tokens); m = double.Parse(t.Value, _invarianCulture); } return(new Coordinate(x, y, z, m)); }
/// <summary> /// Retrieves the next token from the tokens and checks if it has expected type. /// </summary> /// <param name="type">Expected type of token.</param> /// <param name="tokens">The list of tokens.</param> /// <returns>The head of the tokens queue.</returns> private static WktToken Expect(TokenType type, WktTokensBuffer tokens) { bool ignoreWhitespace = type != TokenType.WHITESPACE; WktToken t = tokens.GetToken(ignoreWhitespace); if (t.Type != type) { string expected = string.Empty; switch (type) { case TokenType.WHITESPACE: expected = " "; break; case TokenType.LEFT_PARENTHESIS: expected = "("; break; case TokenType.RIGHT_PARENTHESIS: expected = ")"; break; case TokenType.STRING: expected = "STRING"; break; case TokenType.NUMBER: expected = "NUMBER"; break; } throw new WktParseException(string.Format("Expected '{0}' but encountered '{1}'", expected, t.Value)); } return(t); }
/// <summary> /// Parses a GeometryCollection text. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <param name="is3D">bool value indicating whether GeometryCollection being parsed has z-coordinate.</param> /// <param name="isMeasured">bool value indicating whether GeometryCollection being parsed has m-value.</param> /// <returns>A GeometryCollection specified by tokens.</returns> /// <remarks><![CDATA[<GeometryCollection text> ::= <empty set> | <left paren> <geometry tagged text> {<comma> <geometry tagged text>}* <right paren>]]></remarks> private static GeometryCollection <Geometry> ParseGeometryCollectionText(WktTokensBuffer tokens, bool is3D, bool isMeasured) { WktToken t = tokens.Peek(true); if (t.Type == TokenType.STRING && t.Value.ToUpperInvariant() == "EMPTY") { tokens.GetToken(true); return(new GeometryCollection <Geometry>()); } WktReader.Expect(TokenType.LEFT_PARENTHESIS, tokens); GeometryCollection <Geometry> result = new GeometryCollection <Geometry>(); result.Geometries.Add(WktReader.ParseGeometryTaggedText(tokens)); t = tokens.Peek(true); while (t.Type == TokenType.COMMA) { tokens.GetToken(true); result.Geometries.Add(WktReader.ParseGeometryTaggedText(tokens)); t = tokens.Peek(true); } WktReader.Expect(TokenType.RIGHT_PARENTHESIS, tokens); return(result); }
/// <summary> /// Initializes a new instance of the WktReader class that reads data from specific stream. /// </summary> /// <param name="input">The stream to read data from.</param> public WktReader(Stream input) { if (input == null) { throw new ArgumentNullException("input", "Input stream cannot be null"); } _inputReader = new StreamReader(input); _tokens = new WktTokensBuffer(WktTokenizer.Tokenize(_inputReader)); }
/// <summary> /// Retrieves the next token from tokens and checks if it is TokenType.STRING and if it has correct value. /// </summary> /// <param name="value">Expected string value of the token.</param> /// <param name="tokens">The list of tokens.</param> /// <returns>The head of the tokens queue.</returns> /// <remarks>String comparsion is not case-sensitive.</remarks> private static WktToken Expect(string value, WktTokensBuffer tokens) { WktToken t = tokens.GetToken(true); if (t.Type != TokenType.STRING || string.Equals(value, t.Value, StringComparison.InvariantCultureIgnoreCase) == false) { throw new WktParseException(string.Format("Expected '{0}' but encountered '{1}", value, t.Value)); } return(t); }
/// <summary> /// Parses a multipolygon text. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <param name="is3D">bool value indicating whether multipolygon being parsed has z-coordinate.</param> /// <param name="isMeasured">bool value indicating whether multipolygon being parsed has m-value.</param> /// <returns>A multipolygon specified by tokens.</returns> /// <remarks><![CDATA[<multipolygon text> ::= <empty set> | <left paren> <polygon text> {<comma> <polygon text>}* <right paren>]]></remarks> private static MultiPolygon ParseMultiPolygonText(WktTokensBuffer tokens, bool is3D, bool isMeasured) { WktToken t = tokens.Peek(true); if (t.Type == TokenType.STRING && t.Value.ToUpperInvariant() == "EMPTY") { tokens.GetToken(true); return(new MultiPolygon()); } WktReader.Expect(TokenType.LEFT_PARENTHESIS, tokens); MultiPolygon result = new MultiPolygon(WktReader.ParsePolygons(tokens, is3D, isMeasured)); WktReader.Expect(TokenType.RIGHT_PARENTHESIS, tokens); return(result); }
/// <summary> /// Parses series of polygons. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <param name="is3D">bool value indicating whether polygon being parsed has z-coordinate.</param> /// <param name="isMeasured">bool value indicating whether polygon being parsed has m-value.</param> /// <returns>A list of polygons specified by tokens.</returns> private static IEnumerable <Polygon> ParsePolygons(WktTokensBuffer tokens, bool is3D, bool isMeasured) { List <Polygon> polygons = new List <Polygon>(); polygons.Add(WktReader.ParsePolygonText(tokens, is3D, isMeasured)); WktToken t = tokens.Peek(true); while (t.Type == TokenType.COMMA) { tokens.GetToken(true); polygons.Add(WktReader.ParsePolygonText(tokens, is3D, isMeasured)); t = tokens.Peek(true); } return(polygons); }
/// <summary> /// Parses multiple Points separated by comma. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <param name="is3D">bool value indicating whether point being parsed had z-coordinate.</param> /// <param name="isMeasured">bool value indicating whether point being parsed has m-value.</param> /// <returns>A list of point specified by tokens.</returns> private static List <Point> ParsePoints(WktTokensBuffer tokens, bool is3D, bool isMeasured) { List <Point> points = new List <Point>(); points.Add(WktReader.ParsePointText(tokens, is3D, isMeasured)); WktToken t = tokens.Peek(true); while (t.Type == TokenType.COMMA) { tokens.GetToken(true); points.Add(WktReader.ParsePointText(tokens, is3D, isMeasured)); t = tokens.Peek(true); } return(points); }
/// <summary> /// Parses multiple LineStrings separated by comma. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <param name="is3D">bool value indicating whether linestring being parsed had z-coordinate.</param> /// <param name="isMeasured">bool value indicating whether linestring being parsed has m-value.</param> /// <returns>A list of linestrings specified by tokens.</returns> private static List <LineString> ParseLineStrings(WktTokensBuffer tokens, bool is3D, bool isMeasured) { List <LineString> linestrigns = new List <LineString>(); linestrigns.Add(WktReader.ParseLineStringText(tokens, is3D, isMeasured)); WktToken t = tokens.Peek(true); while (t.Type == TokenType.COMMA) { tokens.GetToken(true); linestrigns.Add(WktReader.ParseLineStringText(tokens, is3D, isMeasured)); t = tokens.Peek(true); } return(linestrigns); }
/// <summary> /// Parses a linestring text. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <param name="is3D">bool value indicating whether linestring being parsed has z-coordinate.</param> /// <param name="isMeasured">bool value indicating whether linestring being parsed has m-value.</param> /// <returns>A linestring specified by tokens.</returns> /// <remarks><![CDATA[<empty set> | <left paren> <point> {<comma> <point>}* <right paren>]]></remarks> private static LineString ParseLineStringText(WktTokensBuffer tokens, bool is3D, bool isMeasured) { WktToken t = tokens.Peek(true); if (t.Type == TokenType.STRING && t.Value.ToUpperInvariant() == "EMPTY") { tokens.GetToken(true); return(new LineString()); } WktReader.Expect(TokenType.LEFT_PARENTHESIS, tokens); IEnumerable <Coordinate> coords = WktReader.ParseCoordinates(tokens, is3D, isMeasured); WktReader.Expect(TokenType.RIGHT_PARENTHESIS, tokens); return(new LineString(coords)); }
/// <summary> /// Parses a multipolyugon tagged text. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <returns>A multipolygon specified by tokens.</returns> /// <remarks><![CDATA[<multipolygon tagged text> ::= multipolygon {z}{m} <multipolygon text>]]></remarks> private static MultiPolygon ParseMultiPolygonTaggedText(WktTokensBuffer tokens) { WktReader.Expect("multipolygon", tokens); WktReader.Expect(TokenType.WHITESPACE, tokens); bool is3D = false; bool isMeasured = false; WktToken t = tokens.Peek(true); if (WktReader.TryParseDimensions(t, out is3D, out isMeasured)) { tokens.GetToken(true); WktReader.Expect(TokenType.WHITESPACE, tokens); } return(WktReader.ParseMultiPolygonText(tokens, is3D, isMeasured)); }
/// <summary> /// Parses a linestring tagged text. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <returns>A linestring specified by tokens.</returns> /// <remarks><![CDATA[<linestring tagged text> ::= linestring {z}{m} <linestring text>]]></remarks> private static LineString ParseLineStringTaggedText(WktTokensBuffer tokens) { WktReader.Expect("linestring", tokens); WktReader.Expect(TokenType.WHITESPACE, tokens); bool is3D = false; bool isMeasured = false; WktToken t = tokens.Peek(true); if (WktReader.TryParseDimensions(t, out is3D, out isMeasured)) { tokens.GetToken(true); WktReader.Expect(TokenType.WHITESPACE, tokens); } return(WktReader.ParseLineStringText(tokens, is3D, isMeasured)); }
/// <summary> /// Parses a series of coordinate. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <param name="is3D">bool value indicating whether coordinate being parsed had z-coordinate.</param> /// <param name="isMeasured">bool value indicating whether coordinate beeing parsed has m-value.</param> /// <returns>A list of coordinates specified by tokens.</returns> private static IEnumerable <Coordinate> ParseCoordinates(WktTokensBuffer tokens, bool is3D, bool isMeasured) { List <Coordinate> coordinates = new List <Coordinate>(); coordinates.Add(WktReader.ParseCoordinate(tokens, is3D, isMeasured)); WktToken t = tokens.Peek(true); while (t.Type == TokenType.COMMA) { tokens.GetToken(true); WktReader.Expect(TokenType.WHITESPACE, tokens); coordinates.Add(WktReader.ParseCoordinate(tokens, is3D, isMeasured)); t = tokens.Peek(true); } return(coordinates); }
/// <summary> /// Parses a geometry tagged text. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <returns>A geometry specified by tokens.</returns> private static Geometry ParseGeometryTaggedText(WktTokensBuffer tokens) { WktToken t = tokens.Peek(true); if (t.Type == TokenType.STRING) { if (t.Value.ToUpperInvariant() == "POINT") { return(WktReader.ParsePointTaggedText(tokens)); } else if (t.Value.ToUpperInvariant() == "LINESTRING") { return(WktReader.ParseLineStringTaggedText(tokens)); } else if (t.Value.ToUpperInvariant() == "POLYGON") { return(WktReader.ParsePolygonTaggedText(tokens)); } else if (t.Value.ToUpperInvariant() == "MULTIPOINT") { return(WktReader.ParseMultiPointTaggedText(tokens)); } else if (t.Value.ToUpperInvariant() == "MULTILINESTRING") { return(WktReader.ParseMultiLineStringTaggedText(tokens)); } else if (t.Value.ToUpperInvariant() == "MULTIPOLYGON") { return(WktReader.ParseMultiPolygonTaggedText(tokens)); } else if (t.Value.ToUpperInvariant() == "GEOMETRYCOLLECTION") { return(WktReader.ParseGeometryCollectionTaggedText(tokens)); } } if (t.Type == TokenType.END_OF_DATA) { return(null); } throw new WktParseException(string.Format("Invalid geometry type '{0}'", t.Value)); }
/// <summary> /// Parses a polygon text. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <param name="is3D">bool value indicating whether polygon being parsed has z-coordinate.</param> /// <param name="isMeasured">bool value indicating whether polygon being parsed has m-value.</param> /// <returns>A polygon specified by tokens.</returns> /// <remarks><![CDATA[<empty set> | <left paren> <linestring text> {<comma> <linestring text>}* <right paren>]]></remarks> private static Polygon ParsePolygonText(WktTokensBuffer tokens, bool is3D, bool isMeasured) { WktToken t = tokens.Peek(true); if (t.Type == TokenType.STRING && t.Value.ToUpperInvariant() == "EMPTY") { tokens.GetToken(true); return(new Polygon()); } WktReader.Expect(TokenType.LEFT_PARENTHESIS, tokens); IEnumerable <LineString> linestrings = WktReader.ParseLineStrings(tokens, is3D, isMeasured); Polygon result = new Polygon(linestrings.First().Coordinates); foreach (var inner in linestrings.Skip(1)) { result.InteriorRings.Add(inner.Coordinates); } WktReader.Expect(TokenType.RIGHT_PARENTHESIS, tokens); return(result); }
/// <summary> /// Initializes a new instance of the WktReader class that reads data from specific file. /// </summary> /// <param name="path">Path to the file to read data from.</param> public WktReader(string path) { _inputFileStream = new FileStream(path, FileMode.Open, FileAccess.Read); _inputReader = new StreamReader(_inputFileStream); _tokens = new WktTokensBuffer(WktTokenizer.Tokenize(_inputReader)); }
/// <summary> /// Parses a Geometry from WKT string. /// </summary> /// <param name="wkt">The string with WKT representation of a Geometry.</param> /// <returns>The parsed Geometry.</returns> public static Geometry Parse(string wkt) { WktTokensBuffer tokens = new WktTokensBuffer(WktTokenizer.Tokenize(wkt)); return(WktReader.ParseGeometryTaggedText(tokens)); }
/// <summary> /// Parses a multipolyugon tagged text. /// </summary> /// <param name="tokens">The list of tokens.</param> /// <returns>A GeometryCollection specified by tokens.</returns> /// <remarks><![CDATA[<GeometryCollection tagged text> ::= GeometryCollection {z}{m} <GeometryCollection text>]]></remarks> private static GeometryCollection <Geometry> ParseGeometryCollectionTaggedText(WktTokensBuffer tokens) { WktReader.Expect("geometrycollection", tokens); WktReader.Expect(TokenType.WHITESPACE, tokens); bool is3D = false; bool isMeasured = false; WktToken t = tokens.Peek(true); if (WktReader.TryParseDimensions(t, out is3D, out isMeasured)) { tokens.GetToken(true); WktReader.Expect(TokenType.WHITESPACE, tokens); } return(WktReader.ParseGeometryCollectionText(tokens, is3D, isMeasured)); }