Skip to content

Commit e3308f5

Browse files
authored
Fix columns that their cast is Geometry (#127)
* fix geometry types * fixes
1 parent 9f17fd8 commit e3308f5

File tree

5 files changed

+114
-1
lines changed

5 files changed

+114
-1
lines changed

src/GeometryCast.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,27 @@ public function set($model, string $key, $value, array $attributes): ?Expression
6666
return $value;
6767
}
6868

69-
if (! ($value instanceof $this->className) || get_class($value) !== $this->className) {
69+
if (! $this->isCorrectGeometryType($value)) {
7070
$geometryType = is_object($value) ? $value::class : gettype($value);
7171
throw new InvalidArgumentException(
7272
sprintf('Expected %s, %s given.', $this->className, $geometryType)
7373
);
7474
}
7575

76+
/** @var Geometry $value */
77+
7678
return $value->toSqlExpression($model->getConnection());
7779
}
7880

81+
private function isCorrectGeometryType(mixed $value): bool
82+
{
83+
if ($this->className === Geometry::class && $value instanceof Geometry) {
84+
return true;
85+
}
86+
87+
return $value instanceof $this->className && get_class($value) === $this->className;
88+
}
89+
7990
private function extractWktFromExpression(ExpressionContract $expression, Connection $connection): string
8091
{
8192
$grammar = $connection->getQueryGrammar();

tests/Objects/GeometryTest.php

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@
77
use MatanYadaev\EloquentSpatial\Enums\Srid;
88
use MatanYadaev\EloquentSpatial\GeometryExpression;
99
use MatanYadaev\EloquentSpatial\Objects\Geometry;
10+
use MatanYadaev\EloquentSpatial\Objects\GeometryCollection;
1011
use MatanYadaev\EloquentSpatial\Objects\LineString;
12+
use MatanYadaev\EloquentSpatial\Objects\MultiLineString;
13+
use MatanYadaev\EloquentSpatial\Objects\MultiPoint;
14+
use MatanYadaev\EloquentSpatial\Objects\MultiPolygon;
1115
use MatanYadaev\EloquentSpatial\Objects\Point;
16+
use MatanYadaev\EloquentSpatial\Objects\Polygon;
1217
use MatanYadaev\EloquentSpatial\Tests\TestModels\TestPlace;
1318

1419
it('throws exception when generating geometry from other geometry WKB', function (): void {
@@ -135,3 +140,94 @@
135140
LineString::fromArray($pointGeoJsonArray);
136141
})->toThrow(InvalidArgumentException::class);
137142
});
143+
144+
it('creates a model record with geometry (point)', function (): void {
145+
// Arrange
146+
$point = Point::fromJson('{"type":"Point","coordinates":[0,180]}');
147+
148+
// Act
149+
/** @var TestPlace $testPlace */
150+
$testPlace = TestPlace::factory()->create(['geometry' => $point]);
151+
152+
// Assert
153+
expect($testPlace->geometry)->toBeInstanceOf(Point::class);
154+
expect($testPlace->geometry)->toEqual($point);
155+
});
156+
157+
it('creates a model record with geometry (line string)', function (): void {
158+
// Arrange
159+
$lineString = LineString::fromJson('{"type":"LineString","coordinates":[[180,0],[179,1]]}');
160+
161+
// Act
162+
/** @var TestPlace $testPlace */
163+
$testPlace = TestPlace::factory()->create(['geometry' => $lineString]);
164+
165+
// Assert
166+
expect($testPlace->geometry)->toBeInstanceOf(LineString::class);
167+
expect($testPlace->geometry)->toEqual($lineString);
168+
});
169+
170+
it('creates a model record with geometry (multi point)', function (): void {
171+
// Arrange
172+
$multiPoint = MultiPoint::fromJson('{"type":"MultiPoint","coordinates":[[180,0],[179,1]]}');
173+
174+
// Act
175+
/** @var TestPlace $testPlace */
176+
$testPlace = TestPlace::factory()->create(['geometry' => $multiPoint]);
177+
178+
// Assert
179+
expect($testPlace->geometry)->toBeInstanceOf(MultiPoint::class);
180+
expect($testPlace->geometry)->toEqual($multiPoint);
181+
});
182+
183+
it('creates a model record with geometry (multi line string)', function (): void {
184+
// Arrange
185+
$multiLineString = MultiLineString::fromJson('{"type":"MultiLineString","coordinates":[[[180,0],[179,1]]]}');
186+
187+
// Act
188+
/** @var TestPlace $testPlace */
189+
$testPlace = TestPlace::factory()->create(['geometry' => $multiLineString]);
190+
191+
// Assert
192+
expect($testPlace->geometry)->toBeInstanceOf(MultiLineString::class);
193+
expect($testPlace->geometry)->toEqual($multiLineString);
194+
});
195+
196+
it('creates a model record with geometry (polygon)', function (): void {
197+
// Arrange
198+
$polygon = Polygon::fromJson('{"type":"Polygon","coordinates":[[[180,0],[179,1],[180,1],[180,0]]]}');
199+
200+
// Act
201+
/** @var TestPlace $testPlace */
202+
$testPlace = TestPlace::factory()->create(['geometry' => $polygon]);
203+
204+
// Assert
205+
expect($testPlace->geometry)->toBeInstanceOf(Polygon::class);
206+
expect($testPlace->geometry)->toEqual($polygon);
207+
});
208+
209+
it('creates a model record with geometry (multi polygon)', function (): void {
210+
// Arrange
211+
$multiPolygon = MultiPolygon::fromJson('{"type":"MultiPolygon","coordinates":[[[[180,0],[179,1],[180,1],[180,0]]]]}');
212+
213+
// Act
214+
/** @var TestPlace $testPlace */
215+
$testPlace = TestPlace::factory()->create(['geometry' => $multiPolygon]);
216+
217+
// Assert
218+
expect($testPlace->geometry)->toBeInstanceOf(MultiPolygon::class);
219+
expect($testPlace->geometry)->toEqual($multiPolygon);
220+
});
221+
222+
it('creates a model record with geometry (geometry collection)', function (): void {
223+
// Arrange
224+
$geometryCollection = GeometryCollection::fromJson('{"type":"GeometryCollection","geometries":[{"type":"Point","coordinates":[0,180]}]}');
225+
226+
// Act
227+
/** @var TestPlace $testPlace */
228+
$testPlace = TestPlace::factory()->create(['geometry' => $geometryCollection]);
229+
230+
// Assert
231+
expect($testPlace->geometry)->toBeInstanceOf(GeometryCollection::class);
232+
expect($testPlace->geometry)->toEqual($geometryCollection);
233+
});

tests/TestModels/TestPlace.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Database\Eloquent\Factories\HasFactory;
66
use Illuminate\Database\Eloquent\Model;
7+
use MatanYadaev\EloquentSpatial\Objects\Geometry;
78
use MatanYadaev\EloquentSpatial\Objects\GeometryCollection;
89
use MatanYadaev\EloquentSpatial\Objects\LineString;
910
use MatanYadaev\EloquentSpatial\Objects\MultiLineString;
@@ -15,6 +16,7 @@
1516
use MatanYadaev\EloquentSpatial\Traits\HasSpatial;
1617

1718
/**
19+
* @property Geometry $geometry
1820
* @property Point $point
1921
* @property MultiPoint $multi_point
2022
* @property LineString $line_string
@@ -35,6 +37,7 @@ class TestPlace extends Model
3537

3638
protected $fillable = [
3739
'address',
40+
'geometry',
3841
'point',
3942
'multi_point',
4043
'line_string',
@@ -46,6 +49,7 @@ class TestPlace extends Model
4649
];
4750

4851
protected $casts = [
52+
'geometry' => Geometry::class,
4953
'point' => Point::class,
5054
'multi_point' => MultiPoint::class,
5155
'line_string' => LineString::class,

tests/database/migrations-laravel-<=10/0000_00_00_000000_create_test_places_table.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public function up(): void
1313
$table->timestamps();
1414
$table->string('name');
1515
$table->string('address');
16+
$table->geometry('geometry')->nullable();
1617
$table->point('point')->isGeometry()->nullable();
1718
$table->multiPoint('multi_point')->isGeometry()->nullable();
1819
$table->lineString('line_string')->isGeometry()->nullable();

tests/database/migrations-laravel->=11/0000_00_00_000000_create_test_places_table.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public function up(): void
1313
$table->timestamps();
1414
$table->string('name');
1515
$table->string('address');
16+
$table->geometry('geometry', subtype: 'geometry')->nullable();
1617
$table->geometry('point', subtype: 'point')->nullable();
1718
$table->geometry('multi_point', subtype: 'multipoint')->nullable();
1819
$table->geometry('line_string', subtype: 'linestring')->nullable();

0 commit comments

Comments
 (0)