コード例 #1
0
        public static string EncodePolygon(GeoLinearRing linearRing)
        {
            Argument.AssertNotNull(linearRing, nameof(linearRing));

            StringBuilder odata = new("geography'POLYGON((");

            bool first = true;

            foreach (GeoPosition position in linearRing.Coordinates)
            {
                if (!first)
                {
                    odata.Append(',');
                }
                else
                {
                    first = false;
                }

                odata.Append(JsonSerialization.Double(position.Longitude, CultureInfo.InvariantCulture))
                .Append(' ')
                .Append(JsonSerialization.Double(position.Latitude, CultureInfo.InvariantCulture));
            }

            return(odata
                   .Append("))'")
                   .ToString());
        }
コード例 #2
0
        /// <summary>
        /// Encodes the longitude and latitude of points or positions for use in OData filters.
        /// </summary>
        /// <param name="longitude">The longitude to encode, which may also be known as Y.</param>
        /// <param name="latitude">The latitude to encode, which may also be known as X.</param>
        /// <returns>The OData filter-encoded POINT string.</returns>
        public static string EncodePoint(double longitude, double latitude)
        {
            const int maxLength =
                19 +       // "geography'POINT( )'".Length
                2 *        // Lat and Long each have:
                (15 +      //     Maximum precision for a double (without G17)
                 1 +       //     Optional decimal point
                 1);       //     Optional negative sign

            return(new StringBuilder(maxLength)
                   .Append("geography'POINT(")
                   .Append(JsonSerialization.Double(longitude, CultureInfo.InvariantCulture))
                   .Append(" ")
                   .Append(JsonSerialization.Double(latitude, CultureInfo.InvariantCulture))
                   .Append(")'")
                   .ToString());
        }
コード例 #3
0
        /// <summary>
        /// Convert a <see cref="GeometryPosition"/> to an OData value.
        /// </summary>
        /// <param name="position">The position.</param>
        /// <returns>The OData representation of the position.</returns>
        private static string EncodeGeometry(GeometryPosition position)
        {
            const int maxLength =
                19 +       // "geography'POINT( )'".Length
                2 *        // Lat and Long each have:
                (15 +      //     Maximum precision for a double (without G17)
                 1 +       //     Optional decimal point
                 1);       //     Optional negative sign
            StringBuilder odata = new StringBuilder(maxLength);

            odata.Append("geography'POINT(");
            odata.Append(JsonSerialization.Double(position.Longitude, CultureInfo.InvariantCulture));
            odata.Append(" ");
            odata.Append(JsonSerialization.Double(position.Latitude, CultureInfo.InvariantCulture));
            odata.Append(")'");
            return(odata.ToString());
        }
コード例 #4
0
        /// <summary>
        /// Encodes a polygon for use in OData filters.
        /// </summary>
        /// <param name="line">The <see cref="GeographyLineStringProxy"/> to encode.</param>
        /// <returns>The OData filter-encoded POLYGON string.</returns>
        /// <exception cref="ArgumentException">The <paramref name="line"/> has fewer than 4 points, or the first and last points do not match.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="line"/> or <see cref="GeographyLineStringProxy.Points"/> is null.</exception>
        public static string EncodePolygon(GeographyLineStringProxy line)
        {
            Argument.AssertNotNull(line, nameof(line));
            Argument.AssertNotNull(line.Points, $"{nameof(line)}.{nameof(line.Points)}");

            if (line.Points.Count < 4)
            {
#pragma warning disable CA2208 // Instantiate argument exceptions correctly
                throw new ArgumentException(
                          $"A GeographyLineString must have at least four Points to form a searchable polygon.",
                          $"{nameof(line)}.{nameof(line.Points)}");
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
            }
            else if (line.Points[0] != line.Points[line.Points.Count - 1])
            {
#pragma warning disable CA2208 // Instantiate argument exceptions correctly
                throw new ArgumentException(
                          $"A GeographyLineString must have matching first and last Points to form a searchable polygon.",
                          $"{nameof(line)}.{nameof(line.Points)}");
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
            }

            StringBuilder odata = new StringBuilder("geography'POLYGON((");

            bool first = true;
            foreach (GeographyPointProxy position in line.Points)
            {
                if (!first)
                {
                    odata.Append(',');
                }
                else
                {
                    first = false;
                }

                odata.Append(JsonSerialization.Double(position.Longitude, CultureInfo.InvariantCulture))
                .Append(' ')
                .Append(JsonSerialization.Double(position.Latitude, CultureInfo.InvariantCulture));
            }

            return(odata
                   .Append("))'")
                   .ToString());
        }
コード例 #5
0
        // Support for both Azure.Core.GeoJson and Microsoft.Spatial encoding are duplicated
        // below to avoid extraneous allocations for adapters and to consolidate them to a single
        // source file for easier maintenance.

#if EXPERIMENTAL_SPATIAL
        /// <summary>
        /// Encodes a polygon for use in OData filters.
        /// </summary>
        /// <param name="line">The <see cref="GeoLine"/> to encode.</param>
        /// <returns>The OData filter-encoded POLYGON string.</returns>
        /// <exception cref="ArgumentException">The <paramref name="line"/> has fewer than 4 points, or the first and last points do not match.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="line"/> or <see cref="GeoLine.Positions"/> is null.</exception>
        public static string EncodePolygon(GeoLine line)
        {
            Argument.AssertNotNull(line, nameof(line));
            Argument.AssertNotNull(line.Positions, $"{nameof(line)}.{nameof(line.Positions)}");

            if (line.Positions.Count < 4)
            {
                throw new ArgumentException(
                          $"A {nameof(GeoLine)} must have at least four {nameof(GeoLine.Positions)} to form a searchable polygon.",
                          $"{nameof(line)}.{nameof(line.Positions)}");
            }
            else if (line.Positions[0] != line.Positions[line.Positions.Count - 1])
            {
                throw new ArgumentException(
                          $"A {nameof(GeoLine)} must have matching first and last {nameof(GeoLine.Positions)} to form a searchable polygon.",
                          $"{nameof(line)}.{nameof(line.Positions)}");
            }

            StringBuilder odata = new StringBuilder("geography'POLYGON((");

            bool first = true;

            foreach (GeoPosition position in line.Positions)
            {
                if (!first)
                {
                    odata.Append(",");
                }
                else
                {
                    first = false;
                }

                odata.Append(JsonSerialization.Double(position.Longitude, CultureInfo.InvariantCulture))
                .Append(" ")
                .Append(JsonSerialization.Double(position.Latitude, CultureInfo.InvariantCulture));
            }

            return(odata
                   .Append("))'")
                   .ToString());
        }
コード例 #6
0
        /// <summary>
        /// Convert a <see cref="LineGeometry"/> forming a polygon to an OData
        /// value.  A LineGeometry must have at least four
        /// <see cref="LineGeometry.Positions"/> and the first and last must
        /// match to form a searchable polygon.
        /// </summary>
        /// <param name="line">The line forming a polygon.</param>
        /// <returns>The OData representation of the line.</returns>
        private static string EncodeGeometry(LineGeometry line)
        {
            Argument.AssertNotNull(line, nameof(line));
            Argument.AssertNotNull(line.Positions, $"{nameof(line)}.{nameof(line.Positions)}");
            if (line.Positions.Count < 4)
            {
                throw new ArgumentException(
                          $"A {nameof(LineGeometry)} must have at least four {nameof(LineGeometry.Positions)} to form a searchable polygon.",
                          $"{nameof(line)}.{nameof(line.Positions)}");
            }
            else if (line.Positions[0] != line.Positions[line.Positions.Count - 1])
            {
                throw new ArgumentException(
                          $"A {nameof(LineGeometry)} must have matching first and last {nameof(LineGeometry.Positions)} to form a searchable polygon.",
                          $"{nameof(line)}.{nameof(line.Positions)}");
            }

            Argument.AssertInRange(line.Positions?.Count ?? 0, 4, int.MaxValue, $"{nameof(line)}.{nameof(line.Positions)}");

            StringBuilder odata = new StringBuilder();

            odata.Append("geography'POLYGON((");
            bool first = true;

            foreach (GeometryPosition position in line.Positions)
            {
                if (!first)
                {
                    odata.Append(",");
                }
                first = false;
                odata.Append(JsonSerialization.Double(position.Longitude, CultureInfo.InvariantCulture));
                odata.Append(" ");
                odata.Append(JsonSerialization.Double(position.Latitude, CultureInfo.InvariantCulture));
            }
            odata.Append("))'");
            return(odata.ToString());
        }
コード例 #7
0
        /// <summary>
        /// Create an OData filter expression from an interpolated string.  The
        /// interpolated values will be quoted and escaped as necessary.
        /// </summary>
        /// <param name="filter">An interpolated filter string.</param>
        /// <param name="formatProvider">
        /// Format provider used to convert values to strings.
        /// <see cref="CultureInfo.InvariantCulture"/> is used as a default.
        /// </param>
        /// <returns>A valid OData filter expression.</returns>
        public static string Create(FormattableString filter, IFormatProvider formatProvider)
        {
            if (filter == null)
            {
                return(null);
            }
            formatProvider ??= CultureInfo.InvariantCulture;

            string[] args = new string[filter.ArgumentCount];
            for (int i = 0; i < filter.ArgumentCount; i++)
            {
                args[i] = filter.GetArgument(i) switch
                {
                    // Null
                    null => "null",

                    // Boolean
                    bool x => x.ToString(formatProvider).ToLowerInvariant(),

                    // Numeric
                    sbyte x => x.ToString(formatProvider),
                    byte x => x.ToString(formatProvider),
                    short x => x.ToString(formatProvider),
                    ushort x => x.ToString(formatProvider),
                    int x => x.ToString(formatProvider),
                    uint x => x.ToString(formatProvider),
                    long x => x.ToString(formatProvider),
                    ulong x => x.ToString(formatProvider),
                    decimal x => x.ToString(formatProvider),

                    // Floating point
                    float x => JsonSerialization.Float(x, formatProvider),
                    double x => JsonSerialization.Double(x, formatProvider),

                    // Dates as 8601 with a time zone
                    DateTimeOffset x => JsonSerialization.Date(x, formatProvider),
                    DateTime x => JsonSerialization.Date(x, formatProvider),

#if EXPERIMENTAL_SPATIAL
                    // Points
                    GeometryPosition x => EncodeGeometry(x),
                    PointGeometry x => EncodeGeometry(x),

                    // Polygons
                    LineGeometry x => EncodeGeometry(x),
                    PolygonGeometry x => EncodeGeometry(x),
#endif

                    // Text
                    string x => Quote(x),
                    char x => Quote(x.ToString(formatProvider)),
                    StringBuilder x => Quote(x.ToString()),

                    // Everything else
                    object x => throw new ArgumentException(
                              $"Unable to convert argument {i} from type {x.GetType()} to an OData literal.")
                };
            }
            string text = string.Format(formatProvider, filter.Format, args);
            return(text);
        }