Skip to content

Commit 98d0671

Browse files
Implement IntersectsBbox to translate PostGIS && operator (#3484)
Closes #3485
1 parent bd07c34 commit 98d0671

4 files changed

Lines changed: 39 additions & 1 deletion

File tree

src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteDbFunctionsExtensions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ namespace Microsoft.EntityFrameworkCore;
77
/// </summary>
88
public static class NpgsqlNetTopologySuiteDbFunctionsExtensions
99
{
10+
/// <summary>
11+
/// Checks whether the 2D bounding boxes of two geometries intersect.
12+
/// Translates to the PostGIS <c>&amp;&amp;</c> operator.
13+
/// </summary>
14+
public static bool IntersectsBbox(this DbFunctions _, Geometry geometry, Geometry anotherGeometry)
15+
=> throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(IntersectsBbox)));
16+
1017
/// <summary>
1118
/// Returns a new geometry with its coordinates transformed to a different spatial reference system.
1219
/// Translates to <c>ST_Transform(geometry, srid)</c>.

src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ var t when typeof(Geometry).IsAssignableFrom(t) && instance is not null
122122
method.ReturnType,
123123
arguments[1].TypeMapping),
124124

125+
nameof(NpgsqlNetTopologySuiteDbFunctionsExtensions.IntersectsBbox) => _sqlExpressionFactory.MakePostgresBinary(
126+
PgExpressionType.Overlaps,
127+
arguments[1],
128+
arguments[2]),
129+
125130
nameof(NpgsqlNetTopologySuiteDbFunctionsExtensions.DistanceKnn) => _sqlExpressionFactory.MakePostgresBinary(
126131
PgExpressionType.Distance,
127132
arguments[1],

test/EFCore.PG.FunctionalTests/Migrations/MigrationsInfrastructureNpgsqlTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,4 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
220220
=> optionsBuilder.UseNpgsql(TestEnvironment.DefaultConnection);
221221

222222
public DbSet<Blog> Blogs { get; set; }
223-
}
223+
}

test/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,32 @@ public override async Task Intersection(bool async)
363363
""");
364364
}
365365

366+
[ConditionalTheory]
367+
[MemberData(nameof(IsAsyncData))]
368+
public async Task IntersectsBbox(bool async)
369+
{
370+
var polygon = Fixture.GeometryFactory.CreatePolygon([new Coordinate(0, 0), new Coordinate(1, 0), new Coordinate(0, 1), new Coordinate(0, 0)]);
371+
372+
await AssertQuery(
373+
async,
374+
ss => ss.Set<PolygonEntity>().Select(e => new { e.Id, IntersectsBbox = (bool?)EF.Functions.IntersectsBbox(e.Polygon, polygon) }),
375+
ss => ss.Set<PolygonEntity>().Select(e => new { e.Id, IntersectsBbox = (e.Polygon == null ? (bool?)null : e.Polygon.EnvelopeInternal.Intersects(polygon.EnvelopeInternal)) }),
376+
elementSorter: e => e.Id,
377+
elementAsserter: (e, a) =>
378+
{
379+
Assert.Equal(e.Id, a.Id);
380+
Assert.Equal(e.IntersectsBbox, a.IntersectsBbox);
381+
});
382+
383+
AssertSql(
384+
"""
385+
@polygon='POLYGON ((0 0, 1 0, 0 1, 0 0))' (DbType = Object)
386+
387+
SELECT p."Id", p."Polygon" && @polygon AS "IntersectsBbox"
388+
FROM "PolygonEntity" AS p
389+
""");
390+
}
391+
366392
public override async Task Intersects(bool async)
367393
{
368394
await base.Intersects(async);

0 commit comments

Comments
 (0)