generated from spatie/package-skeleton-laravel
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e1e1530
commit 0f030f1
Showing
1 changed file
with
177 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
# Upgrading | ||
|
||
## From 1.x to 2.x | ||
Magellan 2.x introduce some breaking changes, which enforces some migrations. | ||
The following 5 Steps provide all the necessary information by examples. | ||
|
||
### Step 1: Migrate Model | ||
With Magellan 2.x we move from having a trait with casting logic to the [default Laravel Way of using casters](https://laravel.com/docs/master/eloquent-mutators#attribute-casting) and cleaned the available caster using the `castUsing` functionality for a better syntax. | ||
|
||
#### In Magellan 1.x | ||
```php | ||
use Clickbar\Magellan\Database\Eloquent\HasPostgisColumns; | ||
use Clickbar\Magellan\Cast\BBoxCast; | ||
|
||
class Port extends Model | ||
{ | ||
use HasPostgisColumns; | ||
|
||
protected array $postgisColumns = [ | ||
'location' => [ | ||
'type' => 'geometry', | ||
'srid' => 4326, | ||
], | ||
]; | ||
|
||
protected array $casts = [ | ||
'bounding_box' => BBoxCast::class | ||
]; | ||
} | ||
``` | ||
|
||
#### In Magellan 2.x | ||
```php | ||
use Clickbar\Magellan\Data\Geometries\Point; | ||
use Clickbar\Magellan\Data\Boxes\Box2D; | ||
|
||
class Port extends Model | ||
{ | ||
protected array $casts = [ | ||
'location' => Point::class, | ||
'bounding_box' => Box2D::class, | ||
]; | ||
} | ||
``` | ||
|
||
Remove the `HasPostgisColumns` trait and the `$postgisColumns` array and add the appropriate cast based on the geometry in the database (e.g. Point::class, Geometry::class, LineString::class, ...). | ||
Also change from the generic `BBoxCast` to the appropriate Box model class (e.g. `Box2D::class` or `Box3D::class`). | ||
|
||
### Step 2: Migrate stSelect, stWhere, ... | ||
With the 2.x release we've removed the custom st query builder methods. You can now use the default Laravel methods. | ||
This introduced several other changes that needs to be done. | ||
|
||
#### In Magellan 1.x: | ||
```php | ||
$currentShipPosition = Point::makeGeodetic(50.107471773560114, 8.679861151457937); | ||
$portsWithDistance = Port::select(['name', 'country']) | ||
->stSelect(ST::distanceSphere($currentShipPosition, 'location'), as: 'distance_to_ship') | ||
->stWhere(ST::distanceSphere($currentShipPosition, 'location'), '<=', 50000) | ||
->stOrderBy(ST::distanceSphere($currentShipPosition, 'location')) | ||
->get(); | ||
``` | ||
|
||
##### In Magellan 2.x: | ||
```php | ||
$currentShipPosition = Point::makeGeodetic(50.107471773560114, 8.679861151457937); | ||
$portsWithDistance = Port::select(['name', 'country']) | ||
->addSelect(ST::distanceSphere($currentShipPosition, 'location')->as('distance_to_ship')) | ||
->where(ST::distanceSphere($currentShipPosition, 'location'), '<=', 50000) | ||
->orderBy(ST::distanceSphere($currentShipPosition, 'location')) | ||
->withMagellanCasts() // <-- automatically adds casts for st functions returning geometry or bbox | ||
->get(); | ||
``` | ||
|
||
For almost all methods, we can simply remove the st- prefix and use the default Laravel method. | ||
|
||
`stSelect` is a special case: It acted like an `addSelect` and also automatically took care of the casting. Therefore, it must be replaced by a call to `addSelect` and we also need to add a call to `withMagellanCasts()`. | ||
|
||
In fact, in this concrete example, we can now completely get rid of the `addSelect` by merging it into the other `select`: | ||
```php | ||
$portsWithDistance = Port::select([ | ||
'name', | ||
'country', | ||
ST::distanceSphere($currentShipPosition, 'location')->as('distance_to_ship'), | ||
]) | ||
``` | ||
|
||
### Step 3: Migrate `GeometryType` Enum | ||
The 1.x version of Magellan always used a `::geometry` cast under the hood for all parameters that expected any kind of geometry. In case there was a function that could also take geography, the function had an optional parameter named `$geometryType` which could be used to tell Magellan to use `::geography` instead. | ||
With Magellan 2.x we decided to remove this. Even the most amount of ST_functions of PostGis are defined on geometry only, we wanted to give back the developer a bit more control and also responsibility. | ||
|
||
If you want to cast your input, you now need to use the `AsGeometry` and `AsGeography` cast expressions around the geometry you want to cast. | ||
But let's look at this using an example. | ||
If you want to use st_buffer to buffer a geometry using a radius in meters, you need a geography as input instead of geometry. | ||
|
||
#### In Magellan 1.x | ||
```php | ||
$bufferedPorts = Port::query() | ||
->stSelect(ST::buffer('location', 50, geometryType: GeometryType::geography), as: 'buffered_location')) | ||
->get(); | ||
``` | ||
|
||
#### In Magellan 2.x | ||
```php | ||
$bufferedPorts = Port::query() | ||
->select(new Aliased(ST::buffer(new AsGeography('location'), 50)->as('buffered_location'))) | ||
->withCasts(['buffered_location' => Polygon::class]) // or ->withMagellanCasts() | ||
->get(); | ||
``` | ||
|
||
### Step 4: Migrate SRID transformation on insert/update | ||
> **_NOTE_** Only relevant if you used magellan.eloquent.transform_to_database_projection = true in config. | ||
#### In Magellan 1.x | ||
```php | ||
Port::create([ | ||
'name' => 'Magellan Home Port', | ||
'country' => 'Germany', | ||
'location' => Point::make(473054.9891044726, 5524365.310057224, srid: 25832), | ||
]); | ||
|
||
// -- or -- | ||
|
||
$port = Port::find(1); | ||
$port->location = Point::make(473054.9891044726, 5524365.310057224, srid: 25832); | ||
$port->save(); | ||
``` | ||
|
||
#### In Magellan 2.x | ||
|
||
With the removal of the `HasPostgisColumns` trait we also removed the auto transform feature. | ||
If you relied on this, you now need to transform it directly on insert or update using `ST::transform`: | ||
|
||
```php | ||
$point = Point::make(473054.9891044726, 5524365.310057224, srid: 25832); | ||
|
||
Port::create([ | ||
'name' => 'Magellan Home Port', | ||
'country' => 'Germany', | ||
'location' => ST::transform($point, 4326), | ||
]); | ||
|
||
// -- or -- | ||
|
||
$port = Port::find(1); | ||
|
||
$port->query()->update([ | ||
'location' => ST::transform(Point::make(473054.9891044726, 5524365.310057224, srid: 25832), 4326), | ||
]); | ||
``` | ||
|
||
### Step 5: Migrate GeometryWKBCast | ||
> **_NOTE_** Only relevant if you used the `GeometryWKBCast` directly somewhere | ||
#### In Magellan 1.x | ||
```php | ||
$hullWithArea = Port::select('country') | ||
->stSelect(ST::convexHull(ST::collect('location')), 'hull') | ||
->stSelect(ST::area(ST::convexHull(ST::collect('location')))) | ||
->groupBy('country') | ||
->withCasts(['hull' => GeometryWKBCast::class]) | ||
->first(); | ||
``` | ||
|
||
#### In Magellan 2.x | ||
```php | ||
$hullWithArea = Port::query() | ||
->select([ | ||
'country', | ||
ST::convexHull(ST::collect('location'))->as('hull'), | ||
ST::area(ST::convexHull(ST::collect('location'))), | ||
]) | ||
->groupBy('country') | ||
->withCasts(['hull' => Polygon::class]) | ||
->first(); | ||
``` | ||
We removed the `GeometryWKBCast` class and added new casters using the appropriate Geometry class. | ||
|