示例#1
0
 /// <summary>
 ///     Returns the mimimum spherical distance between Point or MultiPoint arguments on a sphere in meters,
 ///     by using the specified algorithm.
 ///     It is assumed that `g1` and `g2` are associated with an SRID of `4326`.
 /// </summary>
 /// <param name="_">The DbFunctions instance.</param>
 /// <param name="g1">First geometry argument.</param>
 /// <param name="g2">Second geometry argument.</param>
 /// <param name="algorithm">The algorithm to use. Must be directly supplied as a constant.</param>
 /// <returns>Distance betweeen g1 and g2.</returns>
 public static double SpatialDistanceSphere(
     [CanBeNull] this DbFunctions _,
     Geometry g1,
     Geometry g2,
     SpatialDistanceAlgorithm algorithm)
 {
     throw new InvalidOperationException(MySqlStrings.FunctionOnClient(nameof(SpatialDistanceSphere)));
 }
示例#2
0
        public static SqlExpression GetStDistanceSphereFunctionCall(
            SqlExpression left,
            SqlExpression right,
            SpatialDistanceAlgorithm algorithm,
            Type resultType,
            RelationalTypeMapping resultTypeMapping,
            MySqlSqlExpressionFactory sqlExpressionFactory,
            IMySqlOptions options)
        {
            if (options.ServerVersion.Supports.SpatialDistanceSphereFunction)
            {
                if (algorithm == SpatialDistanceAlgorithm.Native)
                {
                    // Returns null for empty geometry arguments.
                    return(sqlExpressionFactory.NullableFunction(
                               "ST_Distance_Sphere",
                               new[] { left, right },
                               resultType,
                               resultTypeMapping,
                               false));
                }

                if (algorithm == SpatialDistanceAlgorithm.Andoyer &&
                    options.ServerVersion.Supports.SpatialDistanceFunctionImplementsAndoyer)
                {
                    // The `ST_Distance()` in MySQL already uses the Andoyer algorithm, when SRID 4326 is associated
                    // with the geometry.
                    // CHECK: It might be faster to just run the custom implementation, if `ST_SRID()` does not support
                    //        a second parameter yet (see SetSrid()).
                    return(sqlExpressionFactory.Case(
                               new[]
                    {
                        new CaseWhenClause(
                            sqlExpressionFactory.Equal(
                                sqlExpressionFactory.NullableFunction(
                                    "ST_SRID",
                                    new[] { left },
                                    typeof(int)),
                                sqlExpressionFactory.Constant(4326)),
                            GetStDistanceFunctionCall(
                                left,
                                right,
                                resultType,
                                resultTypeMapping,
                                sqlExpressionFactory))
                    },
                               GetStDistanceFunctionCall(
                                   SetSrid(left, 4326, sqlExpressionFactory, options),
                                   SetSrid(right, 4326, sqlExpressionFactory, options),
                                   resultType,
                                   resultTypeMapping,
                                   sqlExpressionFactory)));
                }

                if (algorithm == SpatialDistanceAlgorithm.Haversine)
                {
                    // The Haversine algorithm assumes planar coordinates.
                    return(sqlExpressionFactory.Case(
                               new[]
                    {
                        new CaseWhenClause(
                            sqlExpressionFactory.Equal(
                                sqlExpressionFactory.NullableFunction(
                                    "ST_SRID",
                                    new[] { left },
                                    typeof(int)),
                                sqlExpressionFactory.Constant(0)),
                            GetHaversineDistance(
                                left,
                                right,
                                resultType,
                                sqlExpressionFactory))
                    },
                               GetHaversineDistance(
                                   SetSrid(left, 0, sqlExpressionFactory, options),
                                   SetSrid(right, 0, sqlExpressionFactory, options),
                                   resultType,
                                   sqlExpressionFactory)));
                }
            }

            if (algorithm == SpatialDistanceAlgorithm.Haversine)
            {
                return(GetHaversineDistance(left, right, resultType, sqlExpressionFactory));
            }

            return(GetAndoyerDistance(left, right, resultType, sqlExpressionFactory));
        }