Skip to content

Commit 2922b63

Browse files
feat(#305, #432): add support for PostGIS functions for topological and distance relationships (#434)
1 parent 522e653 commit 2922b63

File tree

68 files changed

+2586
-24
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+2586
-24
lines changed

docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md

Lines changed: 76 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
- **Arrays/JSON**: Use `CONTAINS`, `IS_CONTAINED_BY`, `OVERLAPS` for array and JSON operations
1717
- **Spatial**: Use `SPATIAL_CONTAINS`, `SPATIAL_CONTAINED_BY` for explicit spatial bounding box operations
1818
- **Text**: Use `REGEXP`, `IREGEXP` for pattern matching
19-
- **Boolean operators**: All spatial operators return boolean values and **shall be used with `= TRUE` or `= FALSE` in DQL**
19+
- **Boolean operators**: All spatial operators return boolean values and **should be used with `= TRUE` or `= FALSE` in DQL**
2020

2121
## General Operators
2222

@@ -60,22 +60,22 @@
6060

6161
### Bounding Box Operators
6262

63-
These operators work with geometry and geography bounding boxes. All return boolean values and **shall be used with `= TRUE` or `= FALSE` in DQL**.
63+
These operators work with geometry and geography bounding boxes. All return boolean values and **should be used with `= TRUE` or `= FALSE` in DQL**.
6464

6565
| PostgreSQL operator | Register for DQL as | Description | Implemented by |
6666
|---|---|---|---|
67-
| &< | OVERLAPS_LEFT | Returns TRUE if A's bounding box overlaps or is to the left of B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\OverlapsLeft` |
68-
| &> | OVERLAPS_RIGHT | Returns TRUE if A's bounding box overlaps or is to the right of B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\OverlapsRight` |
69-
| << | STRICTLY_LEFT | Returns TRUE if A's bounding box is strictly to the left of B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StrictlyLeft` |
70-
| >> | STRICTLY_RIGHT | Returns TRUE if A's bounding box is strictly to the right of B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StrictlyRight` |
71-
| @ | SPATIAL_CONTAINED_BY | Returns TRUE if A's bounding box is contained by B's (**spatial version**) | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\SpatialContainedBy` |
72-
| ~ | SPATIAL_CONTAINS | Returns TRUE if A's bounding box contains B's (**spatial version**) | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\SpatialContains` |
73-
| ~= | SPATIAL_SAME | Returns TRUE if A's bounding box is the same as B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\SpatialSame` |
74-
| \|&> | OVERLAPS_ABOVE | Returns TRUE if A's bounding box overlaps or is above B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\OverlapsAbove` |
75-
| \|>> | STRICTLY_ABOVE | Returns TRUE if A's bounding box is strictly above B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StrictlyAbove` |
76-
| &<\| | OVERLAPS_BELOW | Returns TRUE if A's bounding box overlaps or is below B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\OverlapsBelow` |
77-
| <<\| | STRICTLY_BELOW | Returns TRUE if A's bounding box is strictly below B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StrictlyBelow` |
78-
| &&& | ND_OVERLAPS | Returns TRUE if A's n-D bounding box intersects B's n-D bounding box | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\NDimensionalOverlaps` |
67+
| &< | OVERLAPS_LEFT | Returns TRUE if A's bounding box overlaps or is to the left of B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\OverlapsLeft` |
68+
| &> | OVERLAPS_RIGHT | Returns TRUE if A's bounding box overlaps or is to the right of B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\OverlapsRight` |
69+
| << | STRICTLY_LEFT | Returns TRUE if A's bounding box is strictly to the left of B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\StrictlyLeft` |
70+
| >> | STRICTLY_RIGHT | Returns TRUE if A's bounding box is strictly to the right of B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\StrictlyRight` |
71+
| @ | SPATIAL_CONTAINED_BY | Returns TRUE if A's bounding box is contained by B's (**spatial version**) | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\SpatialContainedBy` |
72+
| ~ | SPATIAL_CONTAINS | Returns TRUE if A's bounding box contains B's (**spatial version**) | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\SpatialContains` |
73+
| ~= | SPATIAL_SAME | Returns TRUE if A's bounding box is the same as B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\SpatialSame` |
74+
| \|&> | OVERLAPS_ABOVE | Returns TRUE if A's bounding box overlaps or is above B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\OverlapsAbove` |
75+
| \|>> | STRICTLY_ABOVE | Returns TRUE if A's bounding box is strictly above B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\StrictlyAbove` |
76+
| &<\| | OVERLAPS_BELOW | Returns TRUE if A's bounding box overlaps or is below B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\OverlapsBelow` |
77+
| <<\| | STRICTLY_BELOW | Returns TRUE if A's bounding box is strictly below B's | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\StrictlyBelow` |
78+
| &&& | ND_OVERLAPS | Returns TRUE if A's n-D bounding box intersects B's n-D bounding box | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\NDimensionalOverlaps` |
7979

8080
**Usage Examples:**
8181
```sql
@@ -95,12 +95,12 @@ These operators calculate distances between geometries. All return numeric value
9595

9696
| PostgreSQL operator | Register for DQL as | Description | Implemented by |
9797
|---|---|---|---|
98-
| <-> | GEOMETRY_DISTANCE | Returns the 2D distance between A and B geometries | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\GeometryDistance` |
98+
| <-> | GEOMETRY_DISTANCE | Returns the 2D distance between A and B geometries | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\GeometryDistance` |
9999
| <@> | DISTANCE | Returns distance between points (legacy operator) | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance` |
100-
| \|=\| | TRAJECTORY_DISTANCE | Returns distance between trajectories at closest point of approach | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\TrajectoryDistance` |
101-
| <#> | BOUNDING_BOX_DISTANCE | Returns the 2D distance between A and B bounding boxes | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\BoundingBoxDistance` |
102-
| <<->> | ND_CENTROID_DISTANCE | Returns n-D distance between centroids of bounding boxes | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\NDimensionalCentroidDistance` |
103-
| <<#>> | ND_BOUNDING_BOX_DISTANCE | Returns the n-D distance between A and B bounding boxes | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\NDimensionalBoundingBoxDistance` |
100+
| \|=\| | TRAJECTORY_DISTANCE | Returns distance between trajectories at closest point of approach | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\TrajectoryDistance` |
101+
| <#> | BOUNDING_BOX_DISTANCE | Returns the 2D distance between A and B bounding boxes | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\BoundingBoxDistance` |
102+
| <<->> | ND_CENTROID_DISTANCE | Returns n-D distance between centroids of bounding boxes | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\NDimensionalCentroidDistance` |
103+
| <<#>> | ND_BOUNDING_BOX_DISTANCE | Returns the n-D distance between A and B bounding boxes | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\NDimensionalBoundingBoxDistance` |
104104

105105
**Usage Examples:**
106106
```sql
@@ -224,6 +224,63 @@ SELECT ND_CENTROID_DISTANCE(e.geometry3d1, e.geometry3d2) as distance FROM Entit
224224
| sign | SIGN | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Sign` |
225225
| width_bucket | WIDTH_BUCKET | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\WidthBucket` |
226226

227+
## PostGIS Spatial Relationship Functions
228+
229+
These functions determine spatial relationships between geometries. Most return boolean values and **should be used with `= TRUE` or `= FALSE` in DQL**, but there are exceptions: `ST_Relate(geom, geom)` returns text (intersection matrix) and `ST_LineCrossingDirection` returns integer (crossing behavior).
230+
231+
| PostgreSQL functions | Register for DQL as | Description | Implemented by |
232+
|---|---|---|---|
233+
| ST_3DDWithin | ST_3DDWITHIN | Tests if two 3D geometries are within a given 3D distance | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_3DDWithin` |
234+
| ST_3DDFullyWithin | ST_3DDFULLYWITHIN | Tests if two 3D geometries are entirely within a given 3D distance | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_3DDFullyWithin` |
235+
| ST_3DIntersects | ST_3DINTERSECTS | Tests if two geometries spatially intersect in 3D | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_3DIntersects` |
236+
| ST_Contains | ST_CONTAINS | Tests if every point of B lies in A, and their interiors have a point in common | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_Contains` |
237+
| ST_ContainsProperly | ST_CONTAINSPROPERLY | Tests if every point of B lies in the interior of A | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_ContainsProperly` |
238+
| ST_CoveredBy | ST_COVEREDBY | Tests if every point of A lies in B | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_CoveredBy` |
239+
| ST_Covers | ST_COVERS | Tests if every point of B lies in A | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_Covers` |
240+
| ST_Crosses | ST_CROSSES | Tests if two geometries have some, but not all, interior points in common | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_Crosses` |
241+
| ST_DFullyWithin | ST_DFULLYWITHIN | Tests if a geometry is entirely inside a distance of another | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_DFullyWithin` |
242+
| ST_Disjoint | ST_DISJOINT | Tests if two geometries have no points in common | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_Disjoint` |
243+
| ST_DWithin | ST_DWITHIN | Tests if two geometries are within a given distance | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_DWithin` |
244+
| ST_Equals | ST_EQUALS | Tests if two geometries include the same set of points | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_Equals` |
245+
| ST_Intersects | ST_INTERSECTS | Tests if two geometries intersect (they have at least one point in common) | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_Intersects` |
246+
| ST_LineCrossingDirection | ST_LINECROSSINGDIRECTION | Returns a number indicating the crossing behavior of two LineStrings | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_LineCrossingDirection` |
247+
| ST_OrderingEquals | ST_ORDERINGEQUALS | Tests if two geometries represent the same geometry and have points in the same directional order | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_OrderingEquals` |
248+
| ST_Overlaps | ST_OVERLAPS | Tests if two geometries have the same dimension and intersect, but each has at least one point not in the other | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_Overlaps` |
249+
| ST_PointInsideCircle | ST_POINTINSIDECIRCLE | Tests if a point geometry is inside a circle defined by a center and radius | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_PointInsideCircle` |
250+
| ST_Relate | ST_RELATE | Tests if two geometries have a topological relationship matching an Intersection Matrix pattern, or computes their Intersection Matrix | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_Relate` |
251+
| ST_RelateMatch | ST_RELATEMATCH | Tests if a DE-9IM Intersection Matrix matches an Intersection Matrix pattern | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_RelateMatch` |
252+
| ST_Touches | ST_TOUCHES | Tests if two geometries have at least one point in common, but their interiors do not intersect | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_Touches` |
253+
| ST_Within | ST_WITHIN | Tests if every point of A lies in B, and their interiors have a point in common | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS\ST_Within` |
254+
255+
**Usage Examples:**
256+
```sql
257+
-- Test if geometries intersect
258+
SELECT e FROM Entity e WHERE ST_Intersects(e.geometry, 'POINT(0 0)') = TRUE
259+
260+
-- Test if one geometry contains another
261+
SELECT e FROM Entity e WHERE ST_Contains(e.polygon, e.point) = TRUE
262+
263+
-- Test if geometries are within a distance
264+
SELECT e FROM Entity e WHERE ST_DWithin(e.geometry, 'POINT(0 0)', 1000) = TRUE
265+
266+
-- Test topological relationships with intersection matrix
267+
SELECT e FROM Entity e WHERE ST_Relate(e.geometry1, e.geometry2, 'T*T***T**') = TRUE
268+
269+
-- Test if point is inside circle
270+
SELECT e FROM Entity e WHERE ST_PointInsideCircle(e.point, 0, 0, 1000) = TRUE
271+
```
272+
273+
**📝 Notes:**
274+
- `ST_Relate` is a variadic function that accepts 2 or 3 arguments:
275+
- With 2 arguments: returns text (intersection matrix)
276+
- With 3 arguments: returns boolean (relationship test)
277+
- `ST_LineCrossingDirection` returns an integer (0, 1, -1, or 2) indicating crossing behavior:
278+
- `0`: No crossing
279+
- `1`: Left to right crossing
280+
- `-1`: Right to left crossing
281+
- `2`: Multiple crossings
282+
- All other functions return boolean values and should be used with `= TRUE` or `= FALSE` in DQL
283+
227284

228285
# Bonus Helpers
229286

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\BaseFunction;
8+
9+
/**
10+
* Implementation of PostGIS ST_3DDFullyWithin() function.
11+
*
12+
* Tests if two 3D geometries are entirely within a given 3D distance.
13+
*
14+
* @see https://postgis.net/docs/ST_3DDFullyWithin.html
15+
* @since 3.5
16+
*
17+
* @author Martin Georgiev <martin.georgiev@gmail.com>
18+
*
19+
* @example Using it in DQL: "WHERE ST_3DDFullyWithin(g.geometry1, g.geometry2, 1000) = TRUE"
20+
* Returns boolean, must be used with "= TRUE" or "= FALSE" in DQL.
21+
*/
22+
class ST_3DDFullyWithin extends BaseFunction
23+
{
24+
protected function customizeFunction(): void
25+
{
26+
$this->setFunctionPrototype('ST_3DDFullyWithin(%s, %s, %s)');
27+
$this->addNodeMapping('StringPrimary');
28+
$this->addNodeMapping('StringPrimary');
29+
$this->addNodeMapping('ArithmeticPrimary');
30+
}
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\BaseFunction;
8+
9+
/**
10+
* Implementation of PostGIS ST_3DDWithin() function.
11+
*
12+
* Tests if two 3D geometries are within a given 3D distance.
13+
*
14+
* @see https://postgis.net/docs/ST_3DDWithin.html
15+
* @since 3.5
16+
*
17+
* @author Martin Georgiev <martin.georgiev@gmail.com>
18+
*
19+
* @example Using it in DQL: "WHERE ST_3DDWithin(g.geometry1, g.geometry2, 1000) = TRUE"
20+
* Returns boolean, must be used with "= TRUE" or "= FALSE" in DQL.
21+
*/
22+
class ST_3DDWithin extends BaseFunction
23+
{
24+
protected function customizeFunction(): void
25+
{
26+
$this->setFunctionPrototype('ST_3DDWithin(%s, %s, %s)');
27+
$this->addNodeMapping('StringPrimary');
28+
$this->addNodeMapping('StringPrimary');
29+
$this->addNodeMapping('ArithmeticPrimary');
30+
}
31+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\BaseFunction;
8+
9+
/**
10+
* Implementation of PostGIS ST_3DIntersects() function.
11+
*
12+
* Tests if two geometries spatially intersect in 3D - only for points, linestrings, polygons, polyhedral surface (area).
13+
*
14+
* @see https://postgis.net/docs/ST_3DIntersects.html
15+
* @since 3.5
16+
*
17+
* @author Martin Georgiev <martin.georgiev@gmail.com>
18+
*
19+
* @example Using it in DQL: "WHERE ST_3DIntersects(g.geometry1, g.geometry2) = TRUE"
20+
* Returns boolean, must be used with "= TRUE" or "= FALSE" in DQL.
21+
*/
22+
class ST_3DIntersects extends BaseFunction
23+
{
24+
protected function customizeFunction(): void
25+
{
26+
$this->setFunctionPrototype('ST_3DIntersects(%s, %s)');
27+
$this->addNodeMapping('StringPrimary');
28+
$this->addNodeMapping('StringPrimary');
29+
}
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\BaseFunction;
8+
9+
/**
10+
* Implementation of PostGIS ST_Contains() function.
11+
*
12+
* Tests if every point of B lies in A, and their interiors have a point in common.
13+
*
14+
* @see https://postgis.net/docs/ST_Contains.html
15+
* @since 3.5
16+
*
17+
* @author Martin Georgiev <martin.georgiev@gmail.com>
18+
*
19+
* @example Using it in DQL: "WHERE ST_Contains(g.geometry1, g.geometry2) = TRUE"
20+
* Returns boolean, must be used with "= TRUE" or "= FALSE" in DQL.
21+
*/
22+
class ST_Contains extends BaseFunction
23+
{
24+
protected function customizeFunction(): void
25+
{
26+
$this->setFunctionPrototype('ST_Contains(%s, %s)');
27+
$this->addNodeMapping('StringPrimary');
28+
$this->addNodeMapping('StringPrimary');
29+
}
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\BaseFunction;
8+
9+
/**
10+
* Implementation of PostGIS ST_ContainsProperly() function.
11+
*
12+
* Tests if every point of B lies in the interior of A.
13+
*
14+
* @see https://postgis.net/docs/ST_ContainsProperly.html
15+
* @since 3.5
16+
*
17+
* @author Martin Georgiev <martin.georgiev@gmail.com>
18+
*
19+
* @example Using it in DQL: "WHERE ST_ContainsProperly(g.geometry1, g.geometry2) = TRUE"
20+
* Returns boolean, must be used with "= TRUE" or "= FALSE" in DQL.
21+
*/
22+
class ST_ContainsProperly extends BaseFunction
23+
{
24+
protected function customizeFunction(): void
25+
{
26+
$this->setFunctionPrototype('ST_ContainsProperly(%s, %s)');
27+
$this->addNodeMapping('StringPrimary');
28+
$this->addNodeMapping('StringPrimary');
29+
}
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\BaseFunction;
8+
9+
/**
10+
* Implementation of PostGIS ST_CoveredBy() function.
11+
*
12+
* Tests if every point of A lies in B.
13+
*
14+
* @see https://postgis.net/docs/ST_CoveredBy.html
15+
* @since 3.5
16+
*
17+
* @author Martin Georgiev <martin.georgiev@gmail.com>
18+
*
19+
* @example Using it in DQL: "WHERE ST_CoveredBy(g.geometry1, g.geometry2) = TRUE"
20+
* Returns boolean, must be used with "= TRUE" or "= FALSE" in DQL.
21+
*/
22+
class ST_CoveredBy extends BaseFunction
23+
{
24+
protected function customizeFunction(): void
25+
{
26+
$this->setFunctionPrototype('ST_CoveredBy(%s, %s)');
27+
$this->addNodeMapping('StringPrimary');
28+
$this->addNodeMapping('StringPrimary');
29+
}
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\BaseFunction;
8+
9+
/**
10+
* Implementation of PostGIS ST_Covers() function.
11+
*
12+
* Tests if every point of B lies in A.
13+
*
14+
* @see https://postgis.net/docs/ST_Covers.html
15+
* @since 3.5
16+
*
17+
* @author Martin Georgiev <martin.georgiev@gmail.com>
18+
*
19+
* @example Using it in DQL: "WHERE ST_Covers(g.geometry1, g.geometry2) = TRUE"
20+
* Returns boolean, must be used with "= TRUE" or "= FALSE" in DQL.
21+
*/
22+
class ST_Covers extends BaseFunction
23+
{
24+
protected function customizeFunction(): void
25+
{
26+
$this->setFunctionPrototype('ST_Covers(%s, %s)');
27+
$this->addNodeMapping('StringPrimary');
28+
$this->addNodeMapping('StringPrimary');
29+
}
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\BaseFunction;
8+
9+
/**
10+
* Implementation of PostGIS ST_Crosses() function.
11+
*
12+
* Tests if two geometries have some, but not all, interior points in common.
13+
*
14+
* @see https://postgis.net/docs/ST_Crosses.html
15+
* @since 3.5
16+
*
17+
* @author Martin Georgiev <martin.georgiev@gmail.com>
18+
*
19+
* @example Using it in DQL: "WHERE ST_Crosses(g.geometry1, g.geometry2) = TRUE"
20+
* Returns boolean, must be used with "= TRUE" or "= FALSE" in DQL.
21+
*/
22+
class ST_Crosses extends BaseFunction
23+
{
24+
protected function customizeFunction(): void
25+
{
26+
$this->setFunctionPrototype('ST_Crosses(%s, %s)');
27+
$this->addNodeMapping('StringPrimary');
28+
$this->addNodeMapping('StringPrimary');
29+
}
30+
}

0 commit comments

Comments
 (0)