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);
        }
 internal 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);
     }
 }
 private static void NextComma(WellKnownTextTokenizer tokenizer)
 {
     if (tokenizer.NextToken() != TokenType.Comma)
     {
         throw new GeoWKTException(
                   $"Expected {(char)WellKnownTextTokenizer.Comma} but found: {tokenizer.TokenString()}",
                   tokenizer.LineNumber,
                   tokenizer.Position);
     }
 }
        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);
        }
        internal 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);
        }
        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);
        }
        internal static double NextNumber(WellKnownTextTokenizer tokenizer)
        {
            if (tokenizer.NextToken() == TokenType.Word)
            {
                if (string.Equals(tokenizer.TokenValue, WellKnownTextTokenizer.NaN, StringComparison.OrdinalIgnoreCase))
                {
                    return(double.NaN);
                }

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

            throw new GeoWKTException(
                      $"Expected number but found: {tokenizer.TokenString()}", tokenizer.LineNumber, tokenizer.Position);
        }
        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 = GeoFormat.WellKnownText;
                return(point);

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

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

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

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

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

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

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

            default:
                throw new GeoWKTException($"Unknown geometry type: {type}");
            }
        }
예제 #9
0
        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
                    });
            }
            }
        }