Created
June 19, 2024 14:38
-
-
Save Gummibeer/367a3463c5b022fcb1839966892abf10 to your computer and use it in GitHub Desktop.
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
<?php | |
namespace App\Geotools\Data; | |
use App\Geotools\Casts\GeographyCast; | |
use App\Geotools\Contracts\GeoJsonable; | |
use App\Geotools\Contracts\WellKnownTextable; | |
use App\Geotools\GeoJson\GeoJson; | |
use App\Geotools\GeoJson\Point; | |
use App\Geotools\Value\WktString; | |
use Illuminate\Contracts\Database\Eloquent\Castable; | |
use Illuminate\Contracts\Database\Eloquent\CastsAttributes; | |
use League\Geotools\Coordinate\Coordinate as LeagueCoordinate; | |
use League\Geotools\Coordinate\CoordinateInterface; | |
/** | |
* @readonly | |
*/ | |
class Coordinate extends LeagueCoordinate implements Castable, GeoJsonable, WellKnownTextable | |
{ | |
public static function fromLatLng(float $latitude, float $longitude): static | |
{ | |
return new static([$latitude, $longitude]); | |
} | |
public static function instance(CoordinateInterface $coordinate): static | |
{ | |
return static::fromLatLng($coordinate->getLatitude(), $coordinate->getLongitude()); | |
} | |
public static function castUsing(array $arguments): CastsAttributes | |
{ | |
return new GeographyCast(); | |
} | |
public function toWkt(): WktString | |
{ | |
return new WktString("POINT({$this->getLongitude()} {$this->getLatitude()})"); | |
} | |
public function toGeoJson(): GeoJson | |
{ | |
return new Point( | |
latitude: $this->getLatitude(), | |
longitude: $this->getLongitude(), | |
); | |
} | |
} |
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
<?php | |
namespace App\Geotools\Casts; | |
use App\Geotools\Contracts\WellKnownTextable; | |
use App\Geotools\Data\Coordinate; | |
use GeoIO\WKB\Parser\Parser; | |
use Illuminate\Contracts\Database\Eloquent\CastsAttributes; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Database\Query\Expression; | |
use InvalidArgumentException; | |
class GeographyCast implements CastsAttributes | |
{ | |
public function get(Model $model, string $key, mixed $value, array $attributes): ?Coordinate | |
{ | |
if ($value === null) { | |
return null; | |
} | |
if (is_string($value)) { | |
return app(Parser::class)->parse($value); | |
} | |
throw new InvalidArgumentException(); | |
} | |
public function set(Model $model, string $key, mixed $value, array $attributes): ?Expression | |
{ | |
if ($value === null) { | |
return null; | |
} | |
if ($value instanceof WellKnownTextable) { | |
return $model->getConnection()->raw("ST_GeogFromText('{$value->toWkt()}')"); | |
} | |
throw new InvalidArgumentException(); | |
} | |
} |
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
<?php | |
namespace App\Geotools; | |
use App\Geotools\Data\Coordinate; | |
use BadMethodCallException; | |
use GeoIO\Factory; | |
use InvalidArgumentException; | |
class GeographyFactory implements Factory | |
{ | |
public function createPoint($dimension, array $coordinates, $srid = null): Coordinate | |
{ | |
if ($dimension !== '2D') { | |
throw new InvalidArgumentException(); | |
} | |
return Coordinate::fromLatLng( | |
latitude: $coordinates['y'], | |
longitude: $coordinates['x'], | |
); | |
} | |
public function createLineString($dimension, array $points, $srid = null) | |
{ | |
throw new BadMethodCallException(); | |
} | |
public function createLinearRing($dimension, array $points, $srid = null) | |
{ | |
throw new BadMethodCallException(); | |
} | |
public function createPolygon($dimension, array $lineStrings, $srid = null) | |
{ | |
throw new BadMethodCallException(); | |
} | |
public function createMultiPoint($dimension, array $points, $srid = null) | |
{ | |
throw new BadMethodCallException(); | |
} | |
public function createMultiLineString($dimension, array $lineStrings, $srid = null) | |
{ | |
throw new BadMethodCallException(); | |
} | |
public function createMultiPolygon($dimension, array $polygons, $srid = null) | |
{ | |
throw new BadMethodCallException(); | |
} | |
public function createGeometryCollection($dimension, array $geometries, $srid = null) | |
{ | |
throw new BadMethodCallException(); | |
} | |
} |
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
<?php | |
namespace App\Geotools\GeoJson; | |
use App\Geotools\Enums\GeoJsonType; | |
use Illuminate\Contracts\Support\Arrayable; | |
use Illuminate\Contracts\Support\Jsonable; | |
use JsonSerializable; | |
abstract readonly class GeoJson implements Arrayable, Jsonable, JsonSerializable | |
{ | |
public function __construct( | |
public GeoJsonType $type, | |
) { | |
} | |
public function toArray(): array | |
{ | |
return [ | |
'type' => $this->type->value, | |
]; | |
} | |
public function toJson($options = 0): string | |
{ | |
return json_encode($this, JSON_THROW_ON_ERROR | $options); | |
} | |
public function jsonSerialize(): array | |
{ | |
return $this->toArray(); | |
} | |
} |
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
<?php | |
namespace App\Geotools\Contracts; | |
use App\Geotools\GeoJson\GeoJson; | |
interface GeoJsonable | |
{ | |
public function toGeoJson(): GeoJson; | |
} |
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
<?php | |
namespace App\Geotools\Enums; | |
enum GeoJsonType: string | |
{ | |
case LineString = 'LineString'; | |
case MultiLineString = 'MultiLineString'; | |
case MultiPoint = 'MultiPoint'; | |
case MultiPolygon = 'MultiPolygon'; | |
case Point = 'Point'; | |
case Polygon = 'Polygon'; | |
case Feature = 'Feature'; | |
case FeatureCollection = 'FeatureCollection'; | |
case GeometryCollection = 'GeometryCollection'; | |
} |
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
<?php | |
namespace App\Geotools; | |
use GeoIO\Factory; | |
use GeoIO\WKB\Parser\Parser; | |
use Illuminate\Support\ServiceProvider; | |
class GeotoolsServiceProvider extends ServiceProvider | |
{ | |
public function register(): void | |
{ | |
$this->app->scoped(Factory::class, GeographyFactory::class); | |
$this->app->scoped(Parser::class); | |
} | |
} |
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
<?php | |
namespace App\Geotools\GeoJson; | |
use App\Geotools\Enums\GeoJsonType; | |
readonly class Point extends GeoJson | |
{ | |
public function __construct( | |
public float $latitude, | |
public float $longitude, | |
) { | |
parent::__construct(GeoJsonType::Point); | |
} | |
public function toArray(): array | |
{ | |
return array_merge([ | |
'coordinates' => [ | |
$this->longitude, | |
$this->latitude, | |
], | |
], parent::toArray()); | |
} | |
} |
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
<?php | |
namespace App\Geotools\Enums; | |
enum PostgisType: string | |
{ | |
case Geometry = 'geometry'; | |
case Geography = 'geography'; | |
} |
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
<?php | |
namespace App\Geotools\Contracts; | |
use App\Geotools\Value\WktString; | |
interface WellKnownTextable | |
{ | |
public function toWkt(): WktString; | |
} |
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
<?php | |
namespace App\Geotools\Value; | |
use Stringable; | |
readonly class WktString implements Stringable | |
{ | |
public function __construct(public string $value) | |
{ | |
} | |
public function __toString(): string | |
{ | |
return $this->value; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment