/// <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))); }
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)); }