From 5da4a58fd551e74eceec662343631174d3e8c818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Harrtell?= Date: Sat, 1 Mar 2025 14:47:48 +0100 Subject: [PATCH 1/2] Attempt to implement IntersectsBbox --- ...qlNetTopologySuiteDbFunctionsExtensions.cs | 6 ++++++ ...TopologySuiteMethodCallTranslatorPlugin.cs | 5 +++++ .../Query/SpatialQueryNpgsqlGeometryTest.cs | 21 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteDbFunctionsExtensions.cs b/src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteDbFunctionsExtensions.cs index 4dabe27a1f..c462aedd81 100644 --- a/src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteDbFunctionsExtensions.cs +++ b/src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteDbFunctionsExtensions.cs @@ -7,6 +7,12 @@ namespace Microsoft.EntityFrameworkCore; /// public static class NpgsqlNetTopologySuiteDbFunctionsExtensions { + /// + /// + /// + public static bool IntersectsBbox(this DbFunctions _, Geometry geometry, Geometry anotherGeometry) + => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(IntersectsBbox))); + /// /// Returns a new geometry with its coordinates transformed to a different spatial reference system. /// Translates to ST_Transform(geometry, srid). diff --git a/src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs b/src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs index 8965897196..05624ac730 100644 --- a/src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs +++ b/src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs @@ -104,6 +104,11 @@ public NpgsqlGeometryMethodTranslator( method.ReturnType, arguments[1].TypeMapping), + nameof(NpgsqlNetTopologySuiteDbFunctionsExtensions.IntersectsBbox) => _sqlExpressionFactory.MakePostgresBinary( + PgExpressionType.Overlaps, + arguments[1], + arguments[2]), + nameof(NpgsqlNetTopologySuiteDbFunctionsExtensions.DistanceKnn) => _sqlExpressionFactory.MakePostgresBinary( PgExpressionType.Distance, arguments[1], diff --git a/test/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs b/test/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs index 6bf97811be..ba8c6ee7b0 100644 --- a/test/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs @@ -362,6 +362,27 @@ public override async Task Intersection(bool async) """); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public async Task IntersectsBbox(bool async) + { + var polygon = Fixture.GeometryFactory.CreatePolygon([new Coordinate(0, 0), new Coordinate(1, 0), new Coordinate(0, 1), new Coordinate(0, 0)]); + + await AssertQuery( + async, + ss => ss.Set().Select(e => new { e.Id, IntersectsBbox = (bool?)EF.Functions.IntersectsBbox(e.Polygon, polygon) }), + ss => ss.Set().Select(e => new { e.Id, IntersectsBbox = (e.Polygon == null ? (bool?)false : EF.Functions.IntersectsBbox(e.Polygon, polygon)) }), + x => x.Id); + + AssertSql( + """ +@__Polygon_0='POLYGON ((0 0, 1 0, 1 1, 0 0))' (DbType = Object) + +SELECT l."Id", l."Polygon" && @__Polygon_0 AS "IntersectsBbox" +FROM "PolygonEntity" AS l +"""); + } + public override async Task Intersects(bool async) { await base.Intersects(async); From c4c729c2ee8815f63cbe7309a79e98abc2132cca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Harrtell?= Date: Sat, 1 Mar 2025 16:27:02 +0100 Subject: [PATCH 2/2] Fix test --- .../Query/SpatialQueryNpgsqlGeometryTest.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs b/test/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs index ba8c6ee7b0..e0dcd8c57a 100644 --- a/test/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs @@ -371,15 +371,20 @@ public async Task IntersectsBbox(bool async) await AssertQuery( async, ss => ss.Set().Select(e => new { e.Id, IntersectsBbox = (bool?)EF.Functions.IntersectsBbox(e.Polygon, polygon) }), - ss => ss.Set().Select(e => new { e.Id, IntersectsBbox = (e.Polygon == null ? (bool?)false : EF.Functions.IntersectsBbox(e.Polygon, polygon)) }), - x => x.Id); + ss => ss.Set().Select(e => new { e.Id, IntersectsBbox = (e.Polygon == null ? (bool?)null : e.Polygon.EnvelopeInternal.Intersects(polygon.EnvelopeInternal)) }), + elementSorter: e => e.Id, + elementAsserter: (e, a) => + { + Assert.Equal(e.Id, a.Id); + Assert.Equal(e.IntersectsBbox, a.IntersectsBbox); + }); AssertSql( """ -@__Polygon_0='POLYGON ((0 0, 1 0, 1 1, 0 0))' (DbType = Object) +@__polygon_1='POLYGON ((0 0, 1 0, 0 1, 0 0))' (DbType = Object) -SELECT l."Id", l."Polygon" && @__Polygon_0 AS "IntersectsBbox" -FROM "PolygonEntity" AS l +SELECT p."Id", p."Polygon" && @__polygon_1 AS "IntersectsBbox" +FROM "PolygonEntity" AS p """); }