示例#1
0
        private static List <GeoCoordinate> ParseCoordinates(WellKnownTextTokenizer tokenizer)
        {
            var coordinates = new List <GeoCoordinate>();

            if (IsNumberNext(tokenizer) || (tokenizer.NextToken() == TokenType.LParen))
            {
                coordinates.Add(ParseCoordinate(tokenizer));
            }

            while (NextCloserOrComma(tokenizer) == TokenType.Comma)
            {
                var isOpenParen = false;

                if (IsNumberNext(tokenizer) || (isOpenParen = tokenizer.NextToken() == TokenType.LParen))
                {
                    coordinates.Add(ParseCoordinate(tokenizer));
                }

                if (isOpenParen)
                {
                    NextCloser(tokenizer);
                }
            }

            return(coordinates);
        }
示例#2
0
 private static void NextCloser(WellKnownTextTokenizer tokenizer)
 {
     if (tokenizer.NextToken() != TokenType.RParen)
     {
         throw new GeoWKTException(
                   $"Expected {(char)WellKnownTextTokenizer.RParen} " +
                   $"but found: {tokenizer.TokenString()}", tokenizer.LineNumber, tokenizer.Position);
     }
 }
示例#3
0
        private static MultiPointGeoShape ParseMultiPoint(WellKnownTextTokenizer tokenizer)
        {
            if (NextEmptyOrOpen(tokenizer) == TokenType.Word)
            {
                return(null);
            }

            var coordinates = ParseCoordinates(tokenizer);

            return(new MultiPointGeoShape(coordinates));
        }
示例#4
0
        private static PolygonGeoShape ParsePolygon(WellKnownTextTokenizer tokenizer)
        {
            if (NextEmptyOrOpen(tokenizer) == TokenType.Word)
            {
                return(null);
            }

            var coordinates = ParseCoordinateLists(tokenizer);

            return(new PolygonGeoShape(coordinates));
        }
示例#5
0
        private static LineStringGeoShape ParseLineString(WellKnownTextTokenizer tokenizer)
        {
            if (NextEmptyOrOpen(tokenizer) == TokenType.Word)
            {
                return(null);
            }

            var coordinates = ParseCoordinates(tokenizer);

            return(new LineStringGeoShape(coordinates));
        }
示例#6
0
        private static TokenType NextCloserOrComma(WellKnownTextTokenizer tokenizer)
        {
            var token = tokenizer.NextToken();

            if (token == TokenType.Comma || token == TokenType.RParen)
            {
                return(token);
            }

            throw new GeoWKTException(
                      $"Expected {(char)WellKnownTextTokenizer.Comma} or {(char)WellKnownTextTokenizer.RParen} " +
                      $"but found: {tokenizer.TokenString()}", tokenizer.LineNumber, tokenizer.Position);
        }
示例#7
0
        private static PointGeoShape ParsePoint(WellKnownTextTokenizer tokenizer)
        {
            if (NextEmptyOrOpen(tokenizer) == TokenType.Word)
            {
                return(null);
            }

            var point = new PointGeoShape(ParseCoordinate(tokenizer));

            NextCloser(tokenizer);

            return(point);
        }
示例#8
0
        private static TokenType NextEmptyOrOpen(WellKnownTextTokenizer tokenizer)
        {
            var token = tokenizer.NextToken();

            if (token == TokenType.LParen ||
                token == TokenType.Word && tokenizer.TokenValue.Equals(WellKnownTextTokenizer.Empty, StringComparison.OrdinalIgnoreCase))
            {
                return(token);
            }

            throw new GeoWKTException(
                      $"Expected {WellKnownTextTokenizer.Empty} or {(char)WellKnownTextTokenizer.LParen} " +
                      $"but found: {tokenizer.TokenString()}", tokenizer.LineNumber, tokenizer.Position);
        }
示例#9
0
        private static List <IEnumerable <GeoCoordinate> > ParseCoordinateLists(WellKnownTextTokenizer tokenizer)
        {
            var coordinates = new List <IEnumerable <GeoCoordinate> >();

            NextEmptyOrOpen(tokenizer);
            coordinates.Add(ParseCoordinates(tokenizer));

            while (NextCloserOrComma(tokenizer) == TokenType.Comma)
            {
                NextEmptyOrOpen(tokenizer);
                coordinates.Add(ParseCoordinates(tokenizer));
            }

            return(coordinates);
        }
示例#10
0
        private static GeoCoordinate ParseCoordinate(WellKnownTextTokenizer tokenizer)
        {
            var    lon = NextNumber(tokenizer);
            var    lat = NextNumber(tokenizer);
            double?z   = null;

            if (IsNumberNext(tokenizer))
            {
                z = NextNumber(tokenizer);
            }

            return(z == null
                                ? new GeoCoordinate(lat, lon)
                                : new GeoCoordinate(lat, lon, z.Value));
        }
示例#11
0
        private static MultiPolygonGeoShape ParseMultiPolygon(WellKnownTextTokenizer tokenizer)
        {
            if (NextEmptyOrOpen(tokenizer) == TokenType.Word)
            {
                return(null);
            }

            var coordinates = new List <IEnumerable <IEnumerable <GeoCoordinate> > >
            {
                ParseCoordinateLists(tokenizer)
            };

            while (NextCloserOrComma(tokenizer) == TokenType.Comma)
            {
                coordinates.Add(ParseCoordinateLists(tokenizer));
            }

            return(new MultiPolygonGeoShape(coordinates));
        }
        public static CartesianPoint FromWellKnownText(string wkt)
        {
            using var tokenizer = new WellKnownTextTokenizer(new StringReader(wkt));
            var token = tokenizer.NextToken();

            if (token != TokenType.Word)
            {
                throw new GeoWKTException(
                          $"Expected word but found {tokenizer.TokenString()}", tokenizer.LineNumber, tokenizer.Position);
            }

            var type = tokenizer.TokenValue.ToUpperInvariant();

            if (type != GeoShapeType.Point)
            {
                throw new GeoWKTException(
                          $"Expected {GeoShapeType.Point} but found {type}", tokenizer.LineNumber, tokenizer.Position);
            }

            if (GeoWKTReader.NextEmptyOrOpen(tokenizer) == TokenType.Word)
            {
                return(null);
            }

            var x = Convert.ToSingle(GeoWKTReader.NextNumber(tokenizer));
            var y = Convert.ToSingle(GeoWKTReader.NextNumber(tokenizer));

            // ignore any z value for now
            if (GeoWKTReader.IsNumberNext(tokenizer))
            {
                GeoWKTReader.NextNumber(tokenizer);
            }

            var point = new CartesianPoint(x, y)
            {
                Format = ShapeFormat.WellKnownText
            };

            GeoWKTReader.NextCloser(tokenizer);

            return(point);
        }
示例#13
0
        private static EnvelopeGeoShape ParseBoundingBox(WellKnownTextTokenizer tokenizer)
        {
            if (NextEmptyOrOpen(tokenizer) == TokenType.Word)
            {
                return(null);
            }

            var minLon = NextNumber(tokenizer);

            NextComma(tokenizer);
            var maxLon = NextNumber(tokenizer);

            NextComma(tokenizer);
            var maxLat = NextNumber(tokenizer);

            NextComma(tokenizer);
            var minLat = NextNumber(tokenizer);

            NextCloser(tokenizer);
            return(new EnvelopeGeoShape(new [] { new GeoCoordinate(maxLat, minLon), new GeoCoordinate(minLat, maxLon) }));
        }
示例#14
0
        private static double NextNumber(WellKnownTextTokenizer tokenizer)
        {
            if (tokenizer.NextToken() == TokenType.Number)
            {
                if (string.Equals(tokenizer.TokenValue, WellKnownTextTokenizer.NaN, StringComparison.OrdinalIgnoreCase))
                {
                    return(double.NaN);
                }

                if (double.TryParse(
                        tokenizer.TokenValue,
                        NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign,
                        CultureInfo.InvariantCulture, out var d))
                {
                    return(d);
                }
            }

            throw new GeoWKTException(
                      $"Expected number but found: {tokenizer.TokenString()}", tokenizer.LineNumber, tokenizer.Position);
        }
示例#15
0
        private static GeometryCollection ParseGeometryCollection(WellKnownTextTokenizer tokenizer)
        {
            if (NextEmptyOrOpen(tokenizer) == TokenType.Word)
            {
                return(null);
            }

            var geometries = new List <IGeoShape>
            {
                Read(tokenizer, GeoShapeType.GeometryCollection)
            };

            while (NextCloserOrComma(tokenizer) == TokenType.Comma)
            {
                geometries.Add(Read(tokenizer, null));
            }

            return(new GeometryCollection {
                Geometries = geometries
            });
        }
        public GeoLocation Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
        {
            switch (reader.GetCurrentJsonToken())
            {
            case JsonToken.Null:
                reader.ReadNext();
                return(null);

            case JsonToken.String:
                var wkt = reader.ReadString();
                using (var tokenizer = new WellKnownTextTokenizer(new StringReader(wkt)))
                {
                    var token = tokenizer.NextToken();
                    if (token != TokenType.Word)
                    {
                        throw new GeoWKTException(
                                  $"Expected word but found {tokenizer.TokenString()}", tokenizer.LineNumber, tokenizer.Position);
                    }

                    var type = tokenizer.TokenValue.ToUpperInvariant();
                    if (type != GeoShapeType.Point)
                    {
                        throw new GeoWKTException(
                                  $"Expected {GeoShapeType.Point} but found {type}", tokenizer.LineNumber, tokenizer.Position);
                    }

                    if (GeoWKTReader.NextEmptyOrOpen(tokenizer) == TokenType.Word)
                    {
                        return(null);
                    }

                    var lon = GeoWKTReader.NextNumber(tokenizer);
                    var lat = GeoWKTReader.NextNumber(tokenizer);
                    return(new GeoLocation(lat, lon)
                    {
                        Format = GeoFormat.WellKnownText
                    });
                }

            default:
            {
                var    count = 0;
                double lat   = 0;
                double lon   = 0;
                while (reader.ReadIsInObject(ref count))
                {
                    var propertyName = reader.ReadPropertyNameSegmentRaw();
                    if (Fields.TryGetValue(propertyName, out var value))
                    {
                        switch (value)
                        {
                        case 0:
                            lat = reader.ReadDouble();
                            break;

                        case 1:
                            lon = reader.ReadDouble();
                            break;
                        }
                    }
                    else
                    {
                        reader.ReadNextBlock();
                    }
                }

                return(new GeoLocation(lat, lon)
                    {
                        Format = GeoFormat.GeoJson
                    });
            }
            }
        }
示例#17
0
 /// <summary>
 /// Reads Well-Known Text (WKT) into a new instance of <see cref="IGeoShape"/>
 /// </summary>
 public static IGeoShape Read(string wellKnownText)
 {
     using (var tokenizer = new WellKnownTextTokenizer(new StringReader(wellKnownText)))
         return(Read(tokenizer, null));
 }
示例#18
0
        private static bool IsNumberNext(WellKnownTextTokenizer tokenizer)
        {
            var token = tokenizer.PeekToken();

            return(token == TokenType.Number);
        }
示例#19
0
        private static IGeoShape Read(WellKnownTextTokenizer tokenizer, string shapeType)
        {
            var token = tokenizer.NextToken();

            if (token != TokenType.Word)
            {
                throw new GeoWKTException(
                          $"Expected word but found {tokenizer.TokenString()}", tokenizer.LineNumber, tokenizer.Position);
            }

            var type = tokenizer.TokenValue.ToUpperInvariant();

            if (shapeType != null && shapeType != GeoShapeType.GeometryCollection && type != shapeType)
            {
                throw new GeoWKTException($"Expected geometry type {shapeType} but found {type}");
            }

            switch (type)
            {
            case GeoShapeType.Point:
                var point = ParsePoint(tokenizer);
                point.Format = GeoShapeFormat.WellKnownText;
                return(point);

            case GeoShapeType.MultiPoint:
                var multiPoint = ParseMultiPoint(tokenizer);
                multiPoint.Format = GeoShapeFormat.WellKnownText;
                return(multiPoint);

            case GeoShapeType.LineString:
                var lineString = ParseLineString(tokenizer);
                lineString.Format = GeoShapeFormat.WellKnownText;
                return(lineString);

            case GeoShapeType.MultiLineString:
                var multiLineString = ParseMultiLineString(tokenizer);
                multiLineString.Format = GeoShapeFormat.WellKnownText;
                return(multiLineString);

            case GeoShapeType.Polygon:
                var polygon = ParsePolygon(tokenizer);
                polygon.Format = GeoShapeFormat.WellKnownText;
                return(polygon);

            case GeoShapeType.MultiPolygon:
                var multiPolygon = ParseMultiPolygon(tokenizer);
                multiPolygon.Format = GeoShapeFormat.WellKnownText;
                return(multiPolygon);

            case GeoShapeType.BoundingBox:
                var envelope = ParseBoundingBox(tokenizer);
                envelope.Format = GeoShapeFormat.WellKnownText;
                return(envelope);

            case GeoShapeType.GeometryCollection:
                var geometryCollection = ParseGeometryCollection(tokenizer);
                geometryCollection.Format = GeoShapeFormat.WellKnownText;
                return(geometryCollection);

            default:
                throw new GeoWKTException($"Unknown geometry type: {type}");
            }
        }
        internal static bool IsNumberNext(WellKnownTextTokenizer tokenizer)
        {
            var token = tokenizer.PeekToken();

            return(token == TokenType.Word);
        }