Skip to content

Commit f255f0b

Browse files
authored
Add whereNotWithin and whereNotContains Builder method (#54)
* add-not-within done * Two functions added NotWithin and NotContains * .vscode ignored and unnecessary test point removed
1 parent 436dd27 commit f255f0b

File tree

5 files changed

+108
-0
lines changed

5 files changed

+108
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ build
55
composer.lock
66
coverage
77
vendor
8+
.vscode

.vscode/settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"workbench.colorCustomizations": {
3+
"activityBar.background": "#293019",
4+
"titleBar.activeBackground": "#394324",
5+
"titleBar.activeForeground": "#FAFBF7"
6+
}
7+
}

API.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ echo $geometryCollection[1]->latitude; // 0
5858
* [whereDistanceSphere](#whereDistanceSphere)
5959
* [orderByDistanceSphere](#orderByDistanceSphere)
6060
* [whereWithin](#whereWithin)
61+
* [whereNotWithin](#whereNotWithin)
6162
* [whereContains](#whereContains)
63+
* [whereNotContains](#whereNotContains)
6264
* [whereTouches](#whereTouches)
6365
* [whereIntersects](#whereIntersects)
6466
* [whereCrosses](#whereCrosses)
@@ -258,6 +260,26 @@ Place::query()
258260
```
259261
</details>
260262

263+
### whereNotWithin
264+
265+
Filters records by the [ST_Within](https://dev.mysql.com/doc/refman/8.0/en/spatial-relation-functions-object-shapes.html#function_st-within) function.
266+
267+
| parameter name | type
268+
| ------------------ | --------------------
269+
| `$column` | `string`
270+
| `$geometryOrColumn` | `Geometry \| string`
271+
272+
<details><summary>Example</summary>
273+
274+
```php
275+
Place::create(['location' => new Point(0, 0, 4326)]);
276+
277+
Place::query()
278+
->whereNotWithin('location', Polygon::fromJson('{"type":"Polygon","coordinates":[[[-1,-1],[1,-1],[1,1],[-1,1],[-1,-1]]]}'))
279+
->exists(); // false
280+
```
281+
</details>
282+
261283
### whereContains
262284

263285
Filters records by the [ST_Contains](https://dev.mysql.com/doc/refman/8.0/en/spatial-relation-functions-object-shapes.html#function_st-contains) function.
@@ -278,6 +300,26 @@ Place::query()
278300
```
279301
</details>
280302

303+
### whereNotContains
304+
305+
Filters records by the [ST_Contains](https://dev.mysql.com/doc/refman/8.0/en/spatial-relation-functions-object-shapes.html#function_st-contains) function.
306+
307+
| parameter name | type
308+
| ------------------ | --------------------
309+
| `$column` | `string`
310+
| `$geometryOrColumn` | `Geometry \| string`
311+
312+
<details><summary>Example</summary>
313+
314+
```php
315+
Place::create(['area' => Polygon::fromJson('{"type":"Polygon","coordinates":[[[-1,-1],[1,-1],[1,1],[-1,1],[-1,-1]]]}'),]);
316+
317+
Place::query()
318+
->whereNotContains('area', new Point(0, 0, 4326))
319+
->exists(); // false
320+
```
321+
</details>
322+
281323
### whereTouches
282324

283325
Filters records by the [ST_Touches](https://dev.mysql.com/doc/refman/8.0/en/spatial-relation-functions-object-shapes.html#function_st-touches) function.

src/SpatialBuilder.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,19 @@ public function whereWithin(string $column, Geometry|string $geometryOrColumn):
151151
return $this;
152152
}
153153

154+
public function whereNotWithin(string $column, Geometry|string $geometryOrColumn): self
155+
{
156+
$this->whereRaw(
157+
sprintf(
158+
'ST_WITHIN(%s, %s) = 0',
159+
"`{$column}`",
160+
$this->toExpression($geometryOrColumn),
161+
)
162+
);
163+
164+
return $this;
165+
}
166+
154167
public function whereContains(string $column, Geometry|string $geometryOrColumn): self
155168
{
156169
$this->whereRaw(
@@ -164,6 +177,19 @@ public function whereContains(string $column, Geometry|string $geometryOrColumn)
164177
return $this;
165178
}
166179

180+
public function whereNotContains(string $column, Geometry|string $geometryOrColumn): self
181+
{
182+
$this->whereRaw(
183+
sprintf(
184+
'ST_CONTAINS(%s, %s) = 0',
185+
"`{$column}`",
186+
$this->toExpression($geometryOrColumn),
187+
)
188+
);
189+
190+
return $this;
191+
}
192+
167193
public function whereTouches(string $column, Geometry|string $geometryOrColumn): self
168194
{
169195
$this->whereRaw(

tests/SpatialBuilderTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,21 @@
232232
expect($testPlacesWithinPolygon[0]->point)->toEqual($pointWithinPolygon);
233233
});
234234

235+
it('filters by not within', function (): void {
236+
$polygon = Polygon::fromJson('{"type":"Polygon","coordinates":[[[-1,-1],[1,-1],[1,1],[-1,1],[-1,-1]]]}', 4326);
237+
$pointWithinPolygon = new Point(0, 0, 4326);
238+
$pointOutsidePolygon = new Point(50, 50, 4326);
239+
TestPlace::factory()->create(['point' => $pointWithinPolygon]);
240+
TestPlace::factory()->create(['point' => $pointOutsidePolygon]);
241+
242+
/** @var TestPlace[] $testPlacesNotWithinPolygon */
243+
$testPlacesNotWithinPolygon = TestPlace::query()
244+
->whereNotWithin('point', $polygon)
245+
->get();
246+
247+
expect($testPlacesNotWithinPolygon)->toHaveCount(1);
248+
});
249+
235250
it('filters by contains', function (): void {
236251
$polygon = Polygon::fromJson('{"type":"Polygon","coordinates":[[[-1,-1],[1,-1],[1,1],[-1,1],[-1,-1]]]}', 4326);
237252
$pointWithinPolygon = new Point(0, 0, 4326);
@@ -249,6 +264,23 @@
249264
expect($testPlace2)->toBeNull();
250265
});
251266

267+
it('filters by not contains', function (): void {
268+
$polygon = Polygon::fromJson('{"type":"Polygon","coordinates":[[[-1,-1],[1,-1],[1,1],[-1,1],[-1,-1]]]}', 4326);
269+
$pointWithinPolygon = new Point(0, 0, 4326);
270+
$pointOutsidePolygon = new Point(50, 50, 4326);
271+
TestPlace::factory()->create(['polygon' => $polygon]);
272+
273+
$testPlace = TestPlace::query()
274+
->whereNotContains('polygon', $pointWithinPolygon)
275+
->first();
276+
$testPlace2 = TestPlace::query()
277+
->whereNotContains('polygon', $pointOutsidePolygon)
278+
->first();
279+
280+
expect($testPlace)->toBeNull();
281+
expect($testPlace2)->not->toBeNull();
282+
});
283+
252284
it('filters by touches', function (): void {
253285
$polygon = Polygon::fromJson('{"type":"Polygon","coordinates":[[[-1,-1],[0,-1],[0,0],[-1,0],[-1,-1]]]}', 4326);
254286
$pointTouchesPolygon = new Point(0, 0, 4326);

0 commit comments

Comments
 (0)