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; }
public IOgcGeometry Read(string wkt) { if (wkt == null) throw new ArgumentNullException("wkt"); var tokens = new WktTokenQueue(_wktTokenizer.Tokenize(wkt)); return ParseGeometry(tokens); }
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); }
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); }
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); }
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 }; }
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); }
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); }
private LineString ParseLineString(WktTokenQueue tokens) { tokens.Dequeue("LINESTRING"); var dimensions = ParseDimensions(tokens); return ParseLineStringInner(tokens, dimensions); }
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); }
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); }
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); }
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]); }
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()); }
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; }
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()); }
private Polygon ParseTriangle(WktTokenQueue tokens) { tokens.Dequeue("TRIANGLE"); var dimensions = ParseDimensions(tokens); return ParsePolygonInner(tokens, dimensions); }
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); }
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; }