diff --git a/API.md b/API.md index d8bb72a..5e29149 100644 --- a/API.md +++ b/API.md @@ -2,19 +2,19 @@ ## Available geometry classes -* `Point(float $latitude, float $longitude, int|Srid $srid = 0)` - [MySQL Point](https://dev.mysql.com/doc/refman/8.0/en/gis-class-point.html) -* `MultiPoint(Point[] | Collection $geometries, int|Srid $srid = 0)` - [MySQL MultiPoint](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multipoint.html) -* `LineString(Point[] | Collection $geometries, int|Srid $srid = 0)` - [MySQL LineString](https://dev.mysql.com/doc/refman/8.0/en/gis-class-linestring.html) -* `MultiLineString(LineString[] | Collection $geometries, int|Srid $srid = 0)` - [MySQL MultiLineString](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multilinestring.html) -* `Polygon(LineString[] | Collection $geometries, int|Srid $srid = 0)` - [MySQL Polygon](https://dev.mysql.com/doc/refman/8.0/en/gis-class-polygon.html) -* `MultiPolygon(Polygon[] | Collection $geometries, int|Srid $srid = 0)` - [MySQL MultiPolygon](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multipolygon.html) -* `GeometryCollection(Geometry[] | Collection $geometries, int|Srid $srid = 0)` - [MySQL GeometryCollection](https://dev.mysql.com/doc/refman/8.0/en/gis-class-geometrycollection.html) +* `Point(float $latitude, float $longitude, int|Srid|null $srid = null)` - [MySQL Point](https://dev.mysql.com/doc/refman/8.0/en/gis-class-point.html) +* `MultiPoint(Point[] | Collection $geometries, int|Srid|null $srid = null)` - [MySQL MultiPoint](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multipoint.html) +* `LineString(Point[] | Collection $geometries, int|Srid|null $srid = null)` - [MySQL LineString](https://dev.mysql.com/doc/refman/8.0/en/gis-class-linestring.html) +* `MultiLineString(LineString[] | Collection $geometries, int|Srid|null $srid = null)` - [MySQL MultiLineString](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multilinestring.html) +* `Polygon(LineString[] | Collection $geometries, int|Srid|null $srid = null)` - [MySQL Polygon](https://dev.mysql.com/doc/refman/8.0/en/gis-class-polygon.html) +* `MultiPolygon(Polygon[] | Collection $geometries, int|Srid|null $srid = null)` - [MySQL MultiPolygon](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multipolygon.html) +* `GeometryCollection(Geometry[] | Collection $geometries, int|Srid|null $srid = null)` - [MySQL GeometryCollection](https://dev.mysql.com/doc/refman/8.0/en/gis-class-geometrycollection.html) Geometry classes can be also created by these static methods: -* `fromArray(array $geometry, int|Srid $srid = 0)` - Creates a geometry object from a [GeoJSON](https://en.wikipedia.org/wiki/GeoJSON) array. -* `fromJson(string $geoJson, int|Srid $srid = 0)` - Creates a geometry object from a [GeoJSON](https://en.wikipedia.org/wiki/GeoJSON) string. -* `fromWkt(string $wkt, int|Srid $srid = 0)` - Creates a geometry object from a [WKT](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry). +* `fromArray(array $geometry, int|Srid|null $srid = null)` - Creates a geometry object from a [GeoJSON](https://en.wikipedia.org/wiki/GeoJSON) array. +* `fromJson(string $geoJson, int|Srid|null $srid = null)` - Creates a geometry object from a [GeoJSON](https://en.wikipedia.org/wiki/GeoJSON) string. +* `fromWkt(string $wkt, int|Srid|null $srid = null)` - Creates a geometry object from a [WKT](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry). * `fromWkb(string $wkb)` - Creates a geometry object from a [WKB](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary). ## Available geometry class methods diff --git a/README.md b/README.md index 1655894..0ac9a46 100644 --- a/README.md +++ b/README.md @@ -256,6 +256,25 @@ $place = Place::create([ echo $place->coordinates->toCustomArray(); // ['longitude' => -0.1217424, 'latitude' => 51.5032973] ``` +## Set default SRID + +By default, the SRID is set to 0 (EPSG:0). +You can set the default SRID for your application by setting the `SRID` constant in a service provider's `boot` method: + +```php +use MatanYadaev\EloquentSpatial\Enums\Srid; +use Illuminate\Support\ServiceProvider; + +class AppServiceProvider extends ServiceProvider +{ + public function boot(): void + { + // Set the default SRID to WGS84 (EPSG:4326) + EloquentSpatial::setDefaultSrid(Srid::WGS84); + } +} +``` + ## Development Here are some useful commands for development: diff --git a/src/EloquentSpatial.php b/src/EloquentSpatial.php index 39995ee..9a0ebaa 100644 --- a/src/EloquentSpatial.php +++ b/src/EloquentSpatial.php @@ -4,6 +4,7 @@ namespace MatanYadaev\EloquentSpatial; +use MatanYadaev\EloquentSpatial\Enums\Srid; use MatanYadaev\EloquentSpatial\Objects\GeometryCollection; use MatanYadaev\EloquentSpatial\Objects\LineString; use MatanYadaev\EloquentSpatial\Objects\MultiLineString; @@ -35,6 +36,8 @@ class EloquentSpatial /** @var class-string */ public static string $polygon = Polygon::class; + public static int $defaultSrid = 0; + /** * @param class-string $class */ @@ -104,4 +107,9 @@ public static function usePolygon(string $class): string return static::$polygon; } + + public static function setDefaultSrid(Srid|int $srid): void + { + static::$defaultSrid = $srid instanceof Srid ? $srid->value : $srid; + } } diff --git a/src/Helper.php b/src/Helper.php new file mode 100644 index 0000000..fe1c880 --- /dev/null +++ b/src/Helper.php @@ -0,0 +1,23 @@ +value; + } + + if (is_int($srid)) { + return $srid; + } + + return EloquentSpatial::$defaultSrid; + } +} diff --git a/src/Objects/Geometry.php b/src/Objects/Geometry.php index d7ef0e7..7cae616 100644 --- a/src/Objects/Geometry.php +++ b/src/Objects/Geometry.php @@ -21,6 +21,7 @@ use MatanYadaev\EloquentSpatial\Factory; use MatanYadaev\EloquentSpatial\GeometryCast; use MatanYadaev\EloquentSpatial\GeometryExpression; +use MatanYadaev\EloquentSpatial\Helper; use Stringable; use WKB as geoPHPWkb; @@ -28,7 +29,7 @@ abstract class Geometry implements Arrayable, Castable, Jsonable, JsonSerializab { use Macroable; - public int $srid = 0; + public int $srid; abstract public function toWkt(): string; @@ -90,10 +91,10 @@ public static function fromWkb(string $wkb): static /** * @throws InvalidArgumentException */ - public static function fromWkt(string $wkt, int|Srid $srid = 0): static + public static function fromWkt(string $wkt, int|Srid|null $srid = null): static { $geometry = Factory::parse($wkt); - $geometry->srid = $srid instanceof Srid ? $srid->value : $srid; + $geometry->srid = Helper::getSrid($srid); if (! ($geometry instanceof static)) { throw new InvalidArgumentException( @@ -107,10 +108,10 @@ public static function fromWkt(string $wkt, int|Srid $srid = 0): static /** * @throws InvalidArgumentException */ - public static function fromJson(string $geoJson, int|Srid $srid = 0): static + public static function fromJson(string $geoJson, int|Srid|null $srid = null): static { $geometry = Factory::parse($geoJson); - $geometry->srid = $srid instanceof Srid ? $srid->value : $srid; + $geometry->srid = Helper::getSrid($srid); if (! ($geometry instanceof static)) { throw new InvalidArgumentException( @@ -126,7 +127,7 @@ public static function fromJson(string $geoJson, int|Srid $srid = 0): static * * @throws JsonException */ - public static function fromArray(array $geometry, int|Srid $srid = 0): static + public static function fromArray(array $geometry, int|Srid|null $srid = null): static { $geoJson = json_encode($geometry, JSON_THROW_ON_ERROR); diff --git a/src/Objects/GeometryCollection.php b/src/Objects/GeometryCollection.php index 13b339b..6e6a42e 100644 --- a/src/Objects/GeometryCollection.php +++ b/src/Objects/GeometryCollection.php @@ -9,6 +9,7 @@ use Illuminate\Support\Str; use InvalidArgumentException; use MatanYadaev\EloquentSpatial\Enums\Srid; +use MatanYadaev\EloquentSpatial\Helper; class GeometryCollection extends Geometry implements ArrayAccess { @@ -24,14 +25,14 @@ class GeometryCollection extends Geometry implements ArrayAccess * * @throws InvalidArgumentException */ - public function __construct(Collection|array $geometries, int|Srid $srid = 0) + public function __construct(Collection|array $geometries, int|Srid|null $srid = null) { if (is_array($geometries)) { $geometries = collect($geometries); } $this->geometries = $geometries; - $this->srid = $srid instanceof Srid ? $srid->value : $srid; + $this->srid = Helper::getSrid($srid); $this->validateGeometriesType(); $this->validateGeometriesCount(); diff --git a/src/Objects/MultiLineString.php b/src/Objects/MultiLineString.php index 1a370d9..7cce57d 100644 --- a/src/Objects/MultiLineString.php +++ b/src/Objects/MultiLineString.php @@ -26,10 +26,10 @@ class MultiLineString extends GeometryCollection * * @throws InvalidArgumentException */ - public function __construct(Collection|array $geometries, int|Srid $srid = 0) + public function __construct(Collection|array $geometries, int|Srid|null $srid = null) { // @phpstan-ignore-next-line - parent::__construct($geometries, $this->srid = $srid instanceof Srid ? $srid->value : $srid); + parent::__construct($geometries, $srid); } public function toWkt(): string diff --git a/src/Objects/MultiPolygon.php b/src/Objects/MultiPolygon.php index 2a1f40a..0e29c27 100644 --- a/src/Objects/MultiPolygon.php +++ b/src/Objects/MultiPolygon.php @@ -26,10 +26,10 @@ class MultiPolygon extends GeometryCollection * * @throws InvalidArgumentException */ - public function __construct(Collection|array $geometries, int|Srid $srid = 0) + public function __construct(Collection|array $geometries, int|Srid|null $srid = null) { // @phpstan-ignore-next-line - parent::__construct($geometries, $this->srid = $srid instanceof Srid ? $srid->value : $srid); + parent::__construct($geometries, $srid); } public function toWkt(): string diff --git a/src/Objects/Point.php b/src/Objects/Point.php index 187e633..a3abf65 100644 --- a/src/Objects/Point.php +++ b/src/Objects/Point.php @@ -5,6 +5,7 @@ namespace MatanYadaev\EloquentSpatial\Objects; use MatanYadaev\EloquentSpatial\Enums\Srid; +use MatanYadaev\EloquentSpatial\Helper; class Point extends Geometry { @@ -12,11 +13,11 @@ class Point extends Geometry public float $longitude; - public function __construct(float $latitude, float $longitude, int|Srid $srid = 0) + public function __construct(float $latitude, float $longitude, int|Srid|null $srid = null) { $this->latitude = $latitude; $this->longitude = $longitude; - $this->srid = $srid instanceof Srid ? $srid->value : $srid; + $this->srid = Helper::getSrid($srid); } public function toWkt(): string diff --git a/src/Objects/PointCollection.php b/src/Objects/PointCollection.php index 345449f..3791938 100644 --- a/src/Objects/PointCollection.php +++ b/src/Objects/PointCollection.php @@ -24,9 +24,9 @@ abstract class PointCollection extends GeometryCollection * * @throws InvalidArgumentException */ - public function __construct(Collection|array $geometries, int|Srid $srid = 0) + public function __construct(Collection|array $geometries, int|Srid|null $srid = null) { // @phpstan-ignore-next-line - parent::__construct($geometries, $this->srid = $srid instanceof Srid ? $srid->value : $srid); + parent::__construct($geometries, $srid); } } diff --git a/tests/Objects/GeometryCollectionTest.php b/tests/Objects/GeometryCollectionTest.php index 29bc435..30399b6 100644 --- a/tests/Objects/GeometryCollectionTest.php +++ b/tests/Objects/GeometryCollectionTest.php @@ -72,7 +72,9 @@ expect($testPlace->geometry_collection->srid)->toBe(Srid::WGS84->value); }); -it('creates geometry collection from JSON', function (): void { +it('creates geometry collection with default 0 SRID from JSON', function (): void { + // Arrange + EloquentSpatial::setDefaultSrid(0); $geometryCollection = new GeometryCollection([ new Polygon([ new LineString([ @@ -86,9 +88,39 @@ new Point(0, 180), ]); + // Act $geometryCollectionFromJson = GeometryCollection::fromJson('{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[[[180,0],[179,1],[178,2],[177,3],[180,0]]]},{"type":"Point","coordinates":[180,0]}]}'); + // Assert expect($geometryCollectionFromJson)->toEqual($geometryCollection); + expect($geometryCollectionFromJson->srid)->toBe(0); +}); + +it('creates geometry collection with default 4326 SRID from JSON', function (): void { + // Arrange + EloquentSpatial::setDefaultSrid(Srid::WGS84); + $geometryCollection = new GeometryCollection([ + new Polygon([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + new Point(2, 178), + new Point(3, 177), + new Point(0, 180), + ]), + ]), + new Point(0, 180), + ]); + + // Act + $geometryCollectionFromJson = GeometryCollection::fromJson('{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[[[180,0],[179,1],[178,2],[177,3],[180,0]]]},{"type":"Point","coordinates":[180,0]}]}'); + + // Assert + expect($geometryCollectionFromJson->toWkt())->toBe($geometryCollection->toWkt()); + expect($geometryCollectionFromJson->srid)->toBe(Srid::WGS84->value); + + // Cleanup + EloquentSpatial::setDefaultSrid(0); }); it('creates geometry collection with SRID from JSON', function (): void { @@ -110,7 +142,9 @@ expect($geometryCollectionFromJson)->toEqual($geometryCollection); }); -it('creates geometry collection from array', function (): void { +it('creates geometry collection with default 0 SRID from array', function (): void { + // Arrange + EloquentSpatial::setDefaultSrid(0); $geometryCollection = new GeometryCollection([ new Polygon([ new LineString([ @@ -124,9 +158,39 @@ new Point(0, 180), ]); + // Act $geometryCollectionFromJson = GeometryCollection::fromArray(json_decode('{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[[[180,0],[179,1],[178,2],[177,3],[180,0]]]},{"type":"Point","coordinates":[180,0]}]}', true)); + // Assert expect($geometryCollectionFromJson)->toEqual($geometryCollection); + expect($geometryCollectionFromJson->srid)->toBe(0); +}); + +it('creates geometry collection with default 4326 SRID from array', function (): void { + // Arrange + EloquentSpatial::setDefaultSrid(Srid::WGS84); + $geometryCollection = new GeometryCollection([ + new Polygon([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + new Point(2, 178), + new Point(3, 177), + new Point(0, 180), + ]), + ]), + new Point(0, 180), + ]); + + // Act + $geometryCollectionFromJson = GeometryCollection::fromArray(json_decode('{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[[[180,0],[179,1],[178,2],[177,3],[180,0]]]},{"type":"Point","coordinates":[180,0]}]}', true)); + + // Assert + expect($geometryCollectionFromJson->toWkt())->toBe($geometryCollection->toWkt()); + expect($geometryCollectionFromJson->srid)->toBe(Srid::WGS84->value); + + // Cleanup + EloquentSpatial::setDefaultSrid(0); }); it('creates geometry collection with SRID from array', function (): void { @@ -264,7 +328,9 @@ expect($featureCollectionJson)->toBe($expectedFeatureCollectionJson); }); -it('creates geometry collection from WKT', function (): void { +it('creates geometry collection with default 0 SRID from WKT', function (): void { + // Arrange + EloquentSpatial::setDefaultSrid(0); $geometryCollection = new GeometryCollection([ new Polygon([ new LineString([ @@ -278,11 +344,40 @@ new Point(0, 180), ]); + // Act $geometryCollectionFromWkt = GeometryCollection::fromWkt('GEOMETRYCOLLECTION(POLYGON((180 0, 179 1, 178 2, 177 3, 180 0)), POINT(180 0))'); + // Assert expect($geometryCollectionFromWkt)->toEqual($geometryCollection); }); +it('creates geometry collection with default 4326 SRID from WKT', function (): void { + // Arrange + EloquentSpatial::setDefaultSrid(Srid::WGS84); + $geometryCollection = new GeometryCollection([ + new Polygon([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + new Point(2, 178), + new Point(3, 177), + new Point(0, 180), + ]), + ]), + new Point(0, 180), + ]); + + // Act + $geometryCollectionFromWkt = GeometryCollection::fromWkt('GEOMETRYCOLLECTION(POLYGON((180 0, 179 1, 178 2, 177 3, 180 0)), POINT(180 0))'); + + // Assert + expect($geometryCollectionFromWkt->toWkt())->toBe($geometryCollection->toWkt()); + expect($geometryCollectionFromWkt->srid)->toBe(Srid::WGS84->value); + + // Cleanup + EloquentSpatial::setDefaultSrid(0); +}); + it('creates geometry collection with SRID from WKT', function (): void { $geometryCollection = new GeometryCollection([ new Polygon([ diff --git a/tests/Objects/PointTest.php b/tests/Objects/PointTest.php index 26f3934..ff002d8 100644 --- a/tests/Objects/PointTest.php +++ b/tests/Objects/PointTest.php @@ -36,12 +36,33 @@ expect($testPlace->point->srid)->toBe(Srid::WGS84->value); }); -it('creates point from JSON', function (): void { +it('creates point with default 0 SRID from JSON', function (): void { + // Arrange + EloquentSpatial::setDefaultSrid(0); + $point = new Point(0, 180); + + // Act + $pointFromJson = Point::fromJson('{"type":"Point","coordinates":[180,0]}'); + + // Assert + expect($pointFromJson)->toEqual($point); + expect($pointFromJson->srid)->toBe(0); +}); + +it('creates point with default 4326 SRID from JSON', function (): void { + // Arrange + EloquentSpatial::setDefaultSrid(Srid::WGS84); $point = new Point(0, 180); + // Act $pointFromJson = Point::fromJson('{"type":"Point","coordinates":[180,0]}'); + // Assert expect($pointFromJson)->toEqual($point); + expect($pointFromJson->srid)->toBe(Srid::WGS84->value); + + // Cleanup + EloquentSpatial::setDefaultSrid(0); }); it('creates point with SRID from JSON', function (): void { @@ -52,12 +73,33 @@ expect($pointFromJson)->toEqual($point); }); -it('creates point from array', function (): void { +it('creates point with default 0 SRID from array', function (): void { + // Arrange + EloquentSpatial::setDefaultSrid(0); + $point = new Point(0, 180); + + // Act + $pointFromJson = Point::fromArray(['type' => 'Point', 'coordinates' => [180, 0]]); + + // Assert + expect($pointFromJson)->toEqual($point); + expect($pointFromJson->srid)->toBe(0); +}); + +it('creates point with default 4326 SRID from array', function (): void { + // Arrange + EloquentSpatial::setDefaultSrid(Srid::WGS84); $point = new Point(0, 180); + // Act $pointFromJson = Point::fromArray(['type' => 'Point', 'coordinates' => [180, 0]]); + // Assert expect($pointFromJson)->toEqual($point); + expect($pointFromJson->srid)->toBe(Srid::WGS84->value); + + // Cleanup + EloquentSpatial::setDefaultSrid(0); }); it('creates point with SRID from array', function (): void { @@ -83,12 +125,31 @@ })->toThrow(InvalidArgumentException::class); }); -it('creates point from WKT', function (): void { +it('creates point with default 0 SRID from WKT', function (): void { + // Arrange + EloquentSpatial::setDefaultSrid(0); + $point = new Point(0, 180); + + $pointFromWkt = Point::fromWkt('POINT(180 0)'); + + expect($pointFromWkt)->toEqual($point); + expect($pointFromWkt->srid)->toBe(0); +}); + +it('creates point with default 4326 SRID from WKT', function (): void { + // Arrange + EloquentSpatial::setDefaultSrid(Srid::WGS84); $point = new Point(0, 180); + // Act $pointFromWkt = Point::fromWkt('POINT(180 0)'); + // Assert expect($pointFromWkt)->toEqual($point); + expect($pointFromWkt->srid)->toBe(Srid::WGS84->value); + + // Cleanup + EloquentSpatial::setDefaultSrid(0); }); it('creates point with SRID from WKT', function (): void {