diff --git a/.run/Fix formatting.run.xml b/.run/Fix formatting.run.xml
new file mode 100644
index 0000000..58c6cbe
--- /dev/null
+++ b/.run/Fix formatting.run.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/Static code analysis.run.xml b/.run/Static code analysis.run.xml
new file mode 100644
index 0000000..02486cf
--- /dev/null
+++ b/.run/Static code analysis.run.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/Test.run.xml b/.run/Test.run.xml
new file mode 100644
index 0000000..4fc55d4
--- /dev/null
+++ b/.run/Test.run.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/API.md b/API.md
index 95c0552..c256179 100644
--- a/API.md
+++ b/API.md
@@ -1,23 +1,28 @@
# API
-## Available spatial classes
+## Available geometry classes
-* `Point(float $latitude, float $longitude)` - [MySQL Point](https://dev.mysql.com/doc/refman/8.0/en/gis-class-point.html)
-* `MultiPoint(Point[] | Collection)` - [MySQL MultiPoint](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multipoint.html)
-* `LineString(Point[] | Collection)` - [MySQL LineString](https://dev.mysql.com/doc/refman/8.0/en/gis-class-linestring.html)
-* `MultiLineString(LineString[] | Collection)` - [MySQL MultiLineString](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multilinestring.html)
-* `Polygon(LineString[] | Collection)` - [MySQL Polygon](https://dev.mysql.com/doc/refman/8.0/en/gis-class-polygon.html)
-* `MultiPolygon(Polygon[] | Collection)` - [MySQL MultiPolygon](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multipolygon.html)
-* `GeometryCollection(Geometry[] | Collection)` - [MySQL GeometryCollection](https://dev.mysql.com/doc/refman/8.0/en/gis-class-geometrycollection.html)
+* `Point(float $latitude, float $longitude, int $srid = 0)` - [MySQL Point](https://dev.mysql.com/doc/refman/8.0/en/gis-class-point.html)
+* `MultiPoint(Point[] | Collection, int $srid = 0)` - [MySQL MultiPoint](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multipoint.html)
+* `LineString(Point[] | Collection, int $srid = 0)` - [MySQL LineString](https://dev.mysql.com/doc/refman/8.0/en/gis-class-linestring.html)
+* `MultiLineString(LineString[] | Collection, int $srid = 0)` - [MySQL MultiLineString](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multilinestring.html)
+* `Polygon(LineString[] | Collection, int $srid = 0)` - [MySQL Polygon](https://dev.mysql.com/doc/refman/8.0/en/gis-class-polygon.html)
+* `MultiPolygon(Polygon[] | Collection, int $srid = 0)` - [MySQL MultiPolygon](https://dev.mysql.com/doc/refman/8.0/en/gis-class-multipolygon.html)
+* `GeometryCollection(Geometry[] | Collection, int $srid = 0)` - [MySQL GeometryCollection](https://dev.mysql.com/doc/refman/8.0/en/gis-class-geometrycollection.html)
-## Available spatial functions
+Geometry classes can be also created by these static methods:
-Every geometry class has these functions:
+* `fromJson(string $geoJson, int $srid = 0)` - Creates a geometry object from a [GeoJSON](https://en.wikipedia.org/wiki/GeoJSON) string.
+* `fromWkt(string $wkt, int $srid = 0)` - Creates a geometry object from a [WKT](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry).
+* `fromWkb(string $wkb, int $srid = 0)` - 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
* `toArray()` - Serializes the geometry object into a GeoJSON associative array.
* `toJson()` - Serializes the geometry object into an GeoJSON string.
-* `fromJson(string $geoJson)` - Deserializes a geometry object from a GeoJSON string. (static method)
* `toFeatureCollectionJson()` - Serializes the geometry object into an GeoJSON's FeatureCollection string.
+* `toWkt()` - Serializes the geometry object into a WKT.
+* `toWkb()` - Serializes the geometry object into a WKB.
* `getCoordinates()` - Returns the coordinates of the geometry object.
In addition, `GeometryCollection` also has these functions:
@@ -40,7 +45,7 @@ $geometryCollection = new GeometryCollection([
]);
echo $geometryCollection->getGeometries()[1]->latitude; // 180
-// can also access as an array:
+// or access as an array:
echo $geometryCollection[1]->latitude; // 180
```
@@ -59,6 +64,7 @@ echo $geometryCollection[1]->latitude; // 180
* [whereCrosses](#whereCrosses)
* [whereDisjoint](#whereDisjoint)
* [whereEquals](#whereEquals)
+* [whereSrid](#whereSrid)
### withDistance
@@ -372,3 +378,24 @@ Place::query()
```
+### whereSrid
+
+Filters records by the [ST_Srid](https://dev.mysql.com/doc/refman/8.0/en/gis-general-property-functions.html#function_st-srid) function.
+
+| parameter name | type
+| ------------------ | --------------------
+| `$column` | `string`
+| `$operator` | `string`
+| `$value` | `int`
+
+Example
+
+```php
+Place::create(['location' => new Point(0, 0, 4326)]);
+
+Place::query()
+ ->whereSrid('location', '=', 4326)
+ ->exists(); // true
+```
+
+
diff --git a/README.md b/README.md
index 615415e..dd049ab 100644
--- a/README.md
+++ b/README.md
@@ -102,7 +102,12 @@ use MatanYadaev\EloquentSpatial\Objects\Point;
$londonEye = Place::create([
'name' => 'London Eye',
- 'location' => new Point(51.5032973, -0.1195537)
+ 'location' => new Point(51.5032973, -0.1217424),
+]);
+
+$whiteHouse = Place::create([
+ 'name' => 'White House',
+ 'location' => new Point(38.8976763, -77.0365298, 4326), // with SRID
]);
$vaticanCity = Place::create([
@@ -119,8 +124,8 @@ $vaticanCity = Place::create([
new Point(12.457734346389769, 41.905918239316286),
new Point(12.45572805404663, 41.90637337450963),
new Point(12.455363273620605, 41.90746728266806),
- ])
- ])
+ ]),
+ ]),
])
```
@@ -128,7 +133,9 @@ Retrieve a record with spatial data:
```php
echo $londonEye->location->latitude; // 51.5032973
-echo $londonEye->location->longitude; // -0.1195537
+echo $londonEye->location->longitude; // -0.1217424
+
+echo $whiteHouse->location->srid; // 4326
echo $vacationCity->area->toJson(); // {"type":"Polygon","coordinates":[[[41.90746728266806,12.455363273620605],[41.906636872349075,12.450309991836548],[41.90197359839437,12.445632219314575],[41.90027269624499,12.447413206100464],[41.90000118654431,12.457906007766724],[41.90281205461268,12.458517551422117],[41.903107507989986,12.457584142684937],[41.905918239316286,12.457734346389769],[41.90637337450963,12.45572805404663],[41.90746728266806,12.455363273620605]]]}
```
@@ -170,13 +177,12 @@ Place::query()->whereDistance(...); // This is IDE-friendly
Place::whereDistance(...); // This is not
```
-## Tests
+## Development
-``` bash
-composer phpunit
-# or with coverage
-composer phpunit-coverage
-```
+* Test: `composer pest`
+* Test with coverage: `composer pest-coverage`
+* Type check: `composer phpstan`
+* Format: `composer php-cs-fixer`
## Changelog
diff --git a/src/Factory.php b/src/Factory.php
index e2dbc15..f946a03 100644
--- a/src/Factory.php
+++ b/src/Factory.php
@@ -25,13 +25,8 @@
class Factory
{
- public static function parse(string $value, bool $isWkb): Geometry
+ public static function parse(string $value): Geometry
{
- if ($isWkb) {
- // MySQL adds 4 NULL bytes at the start of the WKB
- $value = substr($value, 4);
- }
-
try {
/** @var geoPHPGeometry|false $geoPHPGeometry */
$geoPHPGeometry = geoPHP::load($value);
@@ -46,14 +41,14 @@ public static function parse(string $value, bool $isWkb): Geometry
protected static function createFromGeometry(geoPHPGeometry $geometry): Geometry
{
+ $srid = is_int($geometry->getSRID()) ? $geometry->getSRID() : 0;
+
if ($geometry instanceof geoPHPPoint) {
if ($geometry->coords[0] === null || $geometry->coords[1] === null) {
- if (! isset($geoPHPGeometry) || ! $geoPHPGeometry) {
- throw new InvalidArgumentException('Invalid spatial value');
- }
+ throw new InvalidArgumentException('Invalid spatial value');
}
- return new Point($geometry->coords[1], $geometry->coords[0]);
+ return new Point($geometry->coords[1], $geometry->coords[0], $srid);
}
/** @var geoPHPGeometryCollection $geometry */
@@ -63,25 +58,25 @@ protected static function createFromGeometry(geoPHPGeometry $geometry): Geometry
});
if ($geometry::class === geoPHPMultiPoint::class) {
- return new MultiPoint($components);
+ return new MultiPoint($components, $srid);
}
if ($geometry::class === geoPHPLineString::class) {
- return new LineString($components);
+ return new LineString($components, $srid);
}
if ($geometry::class === geoPHPPolygon::class) {
- return new Polygon($components);
+ return new Polygon($components, $srid);
}
if ($geometry::class === geoPHPMultiLineString::class) {
- return new MultiLineString($components);
+ return new MultiLineString($components, $srid);
}
if ($geometry::class === geoPHPMultiPolygon::class) {
- return new MultiPolygon($components);
+ return new MultiPolygon($components, $srid);
}
- return new GeometryCollection($components);
+ return new GeometryCollection($components, $srid);
}
}
diff --git a/src/GeometryCast.php b/src/GeometryCast.php
index 6275c5f..9f665cf 100644
--- a/src/GeometryCast.php
+++ b/src/GeometryCast.php
@@ -27,56 +27,64 @@ public function __construct(string $className)
/**
* @param Model $model
* @param string $key
- * @param string|Expression|null $wkbOrWKt
+ * @param string|Expression|null $value
* @param array $attributes
* @return Geometry|null
*/
- public function get($model, string $key, $wkbOrWKt, array $attributes): ?Geometry
+ public function get($model, string $key, $value, array $attributes): ?Geometry
{
- if (! $wkbOrWKt) {
+ if (! $value) {
return null;
}
- if ($wkbOrWKt instanceof Expression) {
- $wkt = $this->extractWktFromExpression($wkbOrWKt);
+ if ($value instanceof Expression) {
+ $wkt = $this->extractWktFromExpression($value);
+ $srid = $this->extractSridFromExpression($value);
- return $this->className::fromWkt($wkt);
+ return $this->className::fromWkt($wkt, $srid);
}
- return $this->className::fromWkb($wkbOrWKt);
+ return $this->className::fromWkb($value);
}
/**
* @param Model $model
* @param string $key
- * @param Geometry|mixed|null $geometry
+ * @param Geometry|mixed|null $value
* @param array $attributes
* @return Expression|null
*
* @throws InvalidArgumentException
*/
- public function set($model, string $key, $geometry, array $attributes): Expression|null
+ public function set($model, string $key, $value, array $attributes): Expression|null
{
- if (! $geometry) {
+ if (! $value) {
return null;
}
- if (! ($geometry instanceof $this->className)) {
- $geometryType = is_object($geometry) ? $geometry::class : gettype($geometry);
+ if (! ($value instanceof $this->className)) {
+ $geometryType = is_object($value) ? $value::class : gettype($value);
throw new InvalidArgumentException(
sprintf('Expected %s, %s given.', static::class, $geometryType)
);
}
- $wkt = $geometry->toWkt(withFunction: true);
+ $wkt = $value->toWkt();
- return DB::raw("ST_GeomFromText('{$wkt}')");
+ return DB::raw("ST_GeomFromText('{$wkt}', {$value->srid})");
}
private function extractWktFromExpression(Expression $expression): string
{
- preg_match('/ST_GeomFromText\(\'(.+)\'\)/', (string) $expression, $match);
+ preg_match('/ST_GeomFromText\(\'(.+)\', .+\)/', (string) $expression, $match);
return $match[1];
}
+
+ private function extractSridFromExpression(Expression $expression): int
+ {
+ preg_match('/ST_GeomFromText\(\'.+\', (.+)\)/', (string) $expression, $match);
+
+ return (int) $match[1];
+ }
}
diff --git a/src/Objects/Geometry.php b/src/Objects/Geometry.php
index 3f9f167..5434313 100644
--- a/src/Objects/Geometry.php
+++ b/src/Objects/Geometry.php
@@ -18,6 +18,8 @@
abstract class Geometry implements Castable, Arrayable, Jsonable, JsonSerializable
{
+ public int $srid = 0;
+
abstract public function toWkt(bool $withFunction = true): string;
/**
@@ -33,10 +35,14 @@ public function toJson($options = 0): string
public function toWkb(): string
{
- $geoPHPGeometry = geoPHP::load($this->toWkt());
+ $geoPHPGeometry = geoPHP::load($this->toJson());
+
+ $sridInBinary = pack('L', $this->srid);
// @phpstan-ignore-next-line
- return (new geoPHPWkb)->write($geoPHPGeometry, true);
+ $wkbWithoutSrid = (new geoPHPWkb)->write($geoPHPGeometry);
+
+ return $sridInBinary.$wkbWithoutSrid;
}
/**
@@ -47,7 +53,14 @@ public function toWkb(): string
*/
public static function fromWkb(string $wkb): static
{
- $geometry = Factory::parse($wkb, true);
+ $srid = substr($wkb, 0, 4);
+ // @phpstan-ignore-next-line
+ $srid = unpack('L', $srid)[1];
+
+ $wkb = substr($wkb, 4);
+
+ $geometry = Factory::parse($wkb);
+ $geometry->srid = $srid;
if (! ($geometry instanceof static)) {
throw new InvalidArgumentException(
@@ -60,13 +73,15 @@ public static function fromWkb(string $wkb): static
/**
* @param string $wkt
+ * @param int $srid
* @return static
*
* @throws InvalidArgumentException
*/
- public static function fromWkt(string $wkt): static
+ public static function fromWkt(string $wkt, int $srid = 0): static
{
- $geometry = Factory::parse($wkt, false);
+ $geometry = Factory::parse($wkt);
+ $geometry->srid = $srid;
if (! ($geometry instanceof static)) {
throw new InvalidArgumentException(
@@ -79,13 +94,15 @@ public static function fromWkt(string $wkt): static
/**
* @param string $geoJson
+ * @param int $srid
* @return static
*
* @throws InvalidArgumentException
*/
- public static function fromJson(string $geoJson): static
+ public static function fromJson(string $geoJson, int $srid = 0): static
{
- $geometry = Factory::parse($geoJson, false);
+ $geometry = Factory::parse($geoJson);
+ $geometry->srid = $srid;
if (! ($geometry instanceof static)) {
throw new InvalidArgumentException(
diff --git a/src/Objects/GeometryCollection.php b/src/Objects/GeometryCollection.php
index a15603a..19a77bc 100644
--- a/src/Objects/GeometryCollection.php
+++ b/src/Objects/GeometryCollection.php
@@ -20,16 +20,18 @@ class GeometryCollection extends Geometry implements ArrayAccess
/**
* @param Collection|array $geometries
+ * @param int $srid
*
* @throws InvalidArgumentException
*/
- public function __construct(Collection|array $geometries)
+ public function __construct(Collection|array $geometries, int $srid = 0)
{
if (is_array($geometries)) {
$geometries = collect($geometries);
}
$this->geometries = $geometries;
+ $this->srid = $srid;
$this->validateGeometriesType();
$this->validateGeometriesCount();
@@ -154,9 +156,9 @@ protected function toCollectionWkt(bool $withFunction): string
{
return $this->geometries
->map(static function (Geometry $geometry) use ($withFunction): string {
- return (string) $geometry->toWkt($withFunction);
+ return $geometry->toWkt($withFunction);
})
- ->join(',');
+ ->join(', ');
}
/**
diff --git a/src/Objects/MultiLineString.php b/src/Objects/MultiLineString.php
index dfc3fba..6d16e49 100644
--- a/src/Objects/MultiLineString.php
+++ b/src/Objects/MultiLineString.php
@@ -22,13 +22,14 @@ class MultiLineString extends GeometryCollection
/**
* @param Collection|array $geometries
+ * @param int $srid
*
* @throws InvalidArgumentException
*/
- public function __construct(Collection|array $geometries)
+ public function __construct(Collection|array $geometries, int $srid = 0)
{
// @phpstan-ignore-next-line
- parent::__construct($geometries);
+ parent::__construct($geometries, $srid);
}
public function toWkt(bool $withFunction = true): string
diff --git a/src/Objects/MultiPolygon.php b/src/Objects/MultiPolygon.php
index a038860..d86fabd 100644
--- a/src/Objects/MultiPolygon.php
+++ b/src/Objects/MultiPolygon.php
@@ -22,13 +22,14 @@ class MultiPolygon extends GeometryCollection
/**
* @param Collection|array $geometries
+ * @param int $srid
*
* @throws InvalidArgumentException
*/
- public function __construct(Collection|array $geometries)
+ public function __construct(Collection|array $geometries, int $srid = 0)
{
// @phpstan-ignore-next-line
- parent::__construct($geometries);
+ parent::__construct($geometries, $srid);
}
public function toWkt(bool $withFunction = true): string
diff --git a/src/Objects/Point.php b/src/Objects/Point.php
index 15a1888..e5d65a1 100644
--- a/src/Objects/Point.php
+++ b/src/Objects/Point.php
@@ -10,10 +10,11 @@ class Point extends Geometry
public float $longitude;
- public function __construct(float $latitude, float $longitude)
+ public function __construct(float $latitude, float $longitude, int $srid = 0)
{
$this->latitude = $latitude;
$this->longitude = $longitude;
+ $this->srid = $srid;
}
public function toWkt(bool $withFunction = true): string
diff --git a/src/Objects/PointCollection.php b/src/Objects/PointCollection.php
index f04a3f9..71a807a 100644
--- a/src/Objects/PointCollection.php
+++ b/src/Objects/PointCollection.php
@@ -20,12 +20,13 @@ abstract class PointCollection extends GeometryCollection
/**
* @param Collection|array $geometries
+ * @param int $srid
*
* @throws InvalidArgumentException
*/
- public function __construct(Collection|array $geometries)
+ public function __construct(Collection|array $geometries, int $srid = 0)
{
// @phpstan-ignore-next-line
- parent::__construct($geometries);
+ parent::__construct($geometries, $srid);
}
}
diff --git a/src/SpatialBuilder.php b/src/SpatialBuilder.php
index 0b316e8..2e1729b 100644
--- a/src/SpatialBuilder.php
+++ b/src/SpatialBuilder.php
@@ -242,6 +242,24 @@ public function whereEquals(string $column, Geometry|string $geometryOrColumn):
return $this;
}
+ public function whereSrid(
+ string $column,
+ string $operator,
+ int|float $value
+ ): self
+ {
+ $this->whereRaw(
+ sprintf(
+ 'ST_SRID(%s) %s %s',
+ "`{$column}`",
+ $operator,
+ $value,
+ )
+ );
+
+ return $this;
+ }
+
protected function toExpression(Geometry|string $geometryOrColumn): Expression
{
if ($geometryOrColumn instanceof Geometry) {
diff --git a/tests/GeometryCastTest.php b/tests/GeometryCastTest.php
index 43b4d75..b1ebcf4 100644
--- a/tests/GeometryCastTest.php
+++ b/tests/GeometryCastTest.php
@@ -38,8 +38,8 @@
});
it('gets original geometry field', function (): void {
- $point = new Point(180, 0);
- $point2 = new Point(0, 0);
+ $point = new Point(180, 0, 4326);
+ $point2 = new Point(0, 0, 4326);
/** @var TestPlace $testPlace */
$testPlace = TestPlace::factory()->create(['point' => $point]);
diff --git a/tests/Objects/GeometryCollectionTest.php b/tests/Objects/GeometryCollectionTest.php
index 5ffa774..9ffede0 100644
--- a/tests/Objects/GeometryCollectionTest.php
+++ b/tests/Objects/GeometryCollectionTest.php
@@ -30,6 +30,26 @@
expect($testPlace->geometry_collection)->toEqual($geometryCollection);
});
+it('creates a model record with geometry collection with SRID', function (): void {
+ $geometryCollection = new GeometryCollection([
+ new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]),
+ new Point(180, 0),
+ ], 4326);
+
+ /** @var TestPlace $testPlace */
+ $testPlace = TestPlace::factory()->create(['geometry_collection' => $geometryCollection]);
+
+ expect($testPlace->geometry_collection->srid)->toBe(4326);
+});
+
it('creates geometry collection from JSON', function (): void {
$geometryCollection = new GeometryCollection([
new Polygon([
@@ -49,6 +69,25 @@
expect($geometryCollectionFromJson)->toEqual($geometryCollection);
});
+it('creates geometry collection with SRID from JSON', function (): void {
+ $geometryCollection = new GeometryCollection([
+ new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]),
+ new Point(180, 0),
+ ], 4326);
+
+ $geometryCollectionFromJson = GeometryCollection::fromJson('{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]},{"type":"Point","coordinates":[0,180]}]}', 4326);
+
+ expect($geometryCollectionFromJson)->toEqual($geometryCollection);
+});
+
it('creates geometry collection from feature collection JSON', function (): void {
$geometryCollection = new GeometryCollection([
new Polygon([
@@ -108,6 +147,82 @@
expect($featureCollectionJson)->toBe($expectedFeatureCollectionJson);
});
+it('creates geometry collection from WKT', function (): void {
+ $geometryCollection = new GeometryCollection([
+ new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]),
+ new Point(180, 0),
+ ]);
+
+ $geometryCollectionFromWkt = GeometryCollection::fromWkt('GEOMETRYCOLLECTION(POLYGON((0 180, 1 179, 2 178, 3 177, 0 180)),POINT(0 180))');
+
+ expect($geometryCollectionFromWkt)->toEqual($geometryCollection);
+});
+
+it('creates geometry collection with SRID from WKT', function (): void {
+ $geometryCollection = new GeometryCollection([
+ new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]),
+ new Point(180, 0),
+ ], 4326);
+
+ $geometryCollectionFromWkt = GeometryCollection::fromWkt('GEOMETRYCOLLECTION(POLYGON((0 180, 1 179, 2 178, 3 177, 0 180)),POINT(0 180))', 4326);
+
+ expect($geometryCollectionFromWkt)->toEqual($geometryCollection);
+});
+
+it('creates geometry collection from WKB', function (): void {
+ $geometryCollection = new GeometryCollection([
+ new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]),
+ new Point(180, 0),
+ ]);
+
+ $geometryCollectionFromWkb = GeometryCollection::fromWkb($geometryCollection->toWkb());
+
+ expect($geometryCollectionFromWkb)->toEqual($geometryCollection);
+});
+
+it('creates geometry collection with SRID from WKB', function (): void {
+ $geometryCollection = new GeometryCollection([
+ new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]),
+ new Point(180, 0),
+ ], 4326);
+
+ $geometryCollectionFromWkb = GeometryCollection::fromWkb($geometryCollection->toWkb());
+
+ expect($geometryCollectionFromWkb)->toEqual($geometryCollection);
+});
+
it('does not throw exception when geometry collection has no geometries', function (): void {
$geometryCollection = new GeometryCollection([]);
diff --git a/tests/Objects/LineStringTest.php b/tests/Objects/LineStringTest.php
index 7981c33..a0abe7b 100644
--- a/tests/Objects/LineStringTest.php
+++ b/tests/Objects/LineStringTest.php
@@ -21,6 +21,18 @@
expect($testPlace->line_string)->toEqual($lineString);
});
+it('creates a model record with line string with SRID', function (): void {
+ $lineString = new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ ], 4326);
+
+ /** @var TestPlace $testPlace */
+ $testPlace = TestPlace::factory()->create(['line_string' => $lineString]);
+
+ expect($testPlace->line_string->srid)->toBe(4326);
+});
+
it('creates line string from JSON', function (): void {
$lineString = new LineString([
new Point(180, 0),
@@ -32,6 +44,17 @@
expect($lineStringFromJson)->toEqual($lineString);
});
+it('creates line string with SRID from JSON', function (): void {
+ $lineString = new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ ], 4326);
+
+ $lineStringFromJson = LineString::fromJson('{"type":"LineString","coordinates":[[0,180],[1,179]]}', 4326);
+
+ expect($lineStringFromJson)->toEqual($lineString);
+});
+
it('generates line string JSON', function (): void {
$lineString = new LineString([
new Point(180, 0),
@@ -56,6 +79,50 @@
expect($featureCollectionJson)->toBe($expectedFeatureCollectionJson);
});
+it('creates line string from WKT', function (): void {
+ $lineString = new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ ]);
+
+ $lineStringFromWkt = LineString::fromWkt('LINESTRING(0 180, 1 179)');
+
+ expect($lineStringFromWkt)->toEqual($lineString);
+});
+
+it('creates line string with SRID from WKT', function (): void {
+ $lineString = new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ ], 4326);
+
+ $lineStringFromWkt = LineString::fromWkt('LINESTRING(0 180, 1 179)', 4326);
+
+ expect($lineStringFromWkt)->toEqual($lineString);
+});
+
+it('creates line string from WKB', function (): void {
+ $lineString = new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ ]);
+
+ $lineStringFromWkb = LineString::fromWkb($lineString->toWkb());
+
+ expect($lineStringFromWkb)->toEqual($lineString);
+});
+
+it('creates line string with SRID from WKB', function (): void {
+ $lineString = new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ ], 4326);
+
+ $lineStringFromWkb = LineString::fromWkb($lineString->toWkb());
+
+ expect($lineStringFromWkb)->toEqual($lineString);
+});
+
it('throws exception when line string has less than two points', function (): void {
expect(function (): void {
new LineString([
diff --git a/tests/Objects/MultiLineStringTest.php b/tests/Objects/MultiLineStringTest.php
index 6767163..68810d3 100644
--- a/tests/Objects/MultiLineStringTest.php
+++ b/tests/Objects/MultiLineStringTest.php
@@ -23,6 +23,20 @@
expect($testPlace->multi_line_string)->toEqual($multiLineString);
});
+it('creates a model record with multi line string with SRID', function (): void {
+ $multiLineString = new MultiLineString([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ ]),
+ ], 4326);
+
+ /** @var TestPlace $testPlace */
+ $testPlace = TestPlace::factory()->create(['multi_line_string' => $multiLineString]);
+
+ expect($testPlace->multi_line_string->srid)->toBe(4326);
+});
+
it('creates multi line string from JSON', function (): void {
$multiLineString = new MultiLineString([
new LineString([
@@ -36,6 +50,19 @@
expect($multiLineStringFromJson)->toEqual($multiLineString);
});
+it('creates multi line string with SRID from JSON', function (): void {
+ $multiLineString = new MultiLineString([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ ]),
+ ], 4326);
+
+ $multiLineStringFromJson = MultiLineString::fromJson('{"type":"MultiLineString","coordinates":[[[0,180],[1,179]]]}', 4326);
+
+ expect($multiLineStringFromJson)->toEqual($multiLineString);
+});
+
it('generates multi line string JSON', function (): void {
$multiLineString = new MultiLineString([
new LineString([
@@ -64,6 +91,58 @@
expect($featureCollectionJson)->toBe($expectedFeatureCollectionJson);
});
+it('creates multi line string from WKT', function (): void {
+ $multiLineString = new MultiLineString([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ ]),
+ ]);
+
+ $multiLineStringFromWkt = MultiLineString::fromWkt('MULTILINESTRING((0 180, 1 179))', );
+
+ expect($multiLineStringFromWkt)->toEqual($multiLineString);
+});
+
+it('creates multi line string with SRID from WKT', function (): void {
+ $multiLineString = new MultiLineString([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ ]),
+ ], 4326);
+
+ $multiLineStringFromWkt = MultiLineString::fromWkt('MULTILINESTRING((0 180, 1 179))', 4326);
+
+ expect($multiLineStringFromWkt)->toEqual($multiLineString);
+});
+
+it('creates multi line string from WKB', function (): void {
+ $multiLineString = new MultiLineString([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ ]),
+ ]);
+
+ $multiLineStringFromWkb = MultiLineString::fromWkb($multiLineString->toWkb());
+
+ expect($multiLineStringFromWkb)->toEqual($multiLineString);
+});
+
+it('creates multi line string with SRID from WKB', function (): void {
+ $multiLineString = new MultiLineString([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ ]),
+ ], 4326);
+
+ $multiLineStringFromWkb = MultiLineString::fromWkb($multiLineString->toWkb());
+
+ expect($multiLineStringFromWkb)->toEqual($multiLineString);
+});
+
it('throws exception when multi line string has no line strings', function (): void {
expect(function (): void {
new MultiLineString([]);
diff --git a/tests/Objects/MultiPointTest.php b/tests/Objects/MultiPointTest.php
index 7e748da..04dd058 100644
--- a/tests/Objects/MultiPointTest.php
+++ b/tests/Objects/MultiPointTest.php
@@ -20,6 +20,17 @@
expect($testPlace->multi_point)->toEqual($multiPoint);
});
+it('creates a model record with multi point with SRID', function (): void {
+ $multiPoint = new MultiPoint([
+ new Point(180, 0),
+ ], 4326);
+
+ /** @var TestPlace $testPlace */
+ $testPlace = TestPlace::factory()->create(['multi_point' => $multiPoint]);
+
+ expect($testPlace->multi_point->srid)->toBe(4326);
+});
+
it('creates multi point from JSON', function (): void {
$multiPoint = new MultiPoint([
new Point(180, 0),
@@ -30,6 +41,16 @@
expect($multiPointFromJson)->toEqual($multiPoint);
});
+it('creates multi point with SRID from JSON', function (): void {
+ $multiPoint = new MultiPoint([
+ new Point(180, 0),
+ ], 4326);
+
+ $multiPointFromJson = MultiPoint::fromJson('{"type":"MultiPoint","coordinates":[[0,180]]}', 4326);
+
+ expect($multiPointFromJson)->toEqual($multiPoint);
+});
+
it('generates multi point JSON', function (): void {
$multiPoint = new MultiPoint([
new Point(180, 0),
@@ -52,6 +73,46 @@
expect($multiPointFeatureCollectionJson)->toBe($expectedFeatureCollectionJson);
});
+it('creates multi point from WKT', function (): void {
+ $multiPoint = new MultiPoint([
+ new Point(180, 0),
+ ]);
+
+ $multiPointFromWkt = MultiPoint::fromWkt('MULTIPOINT(0 180)');
+
+ expect($multiPointFromWkt)->toEqual($multiPoint);
+});
+
+it('creates multi point with SRID from WKT', function (): void {
+ $multiPoint = new MultiPoint([
+ new Point(180, 0),
+ ], 4326);
+
+ $multiPointFromWkt = MultiPoint::fromWkt('MULTIPOINT(0 180)', 4326);
+
+ expect($multiPointFromWkt)->toEqual($multiPoint);
+});
+
+it('creates multi point from WKB', function (): void {
+ $multiPoint = new MultiPoint([
+ new Point(180, 0),
+ ]);
+
+ $multiPointFromWkb = MultiPoint::fromWkb($multiPoint->toWkb());
+
+ expect($multiPointFromWkb)->toEqual($multiPoint);
+});
+
+it('creates multi point with SRID from WKB', function (): void {
+ $multiPoint = new MultiPoint([
+ new Point(180, 0),
+ ], 4326);
+
+ $multiPointFromWkb = MultiPoint::fromWkb($multiPoint->toWkb());
+
+ expect($multiPointFromWkb)->toEqual($multiPoint);
+});
+
it('throws exception when multi point has no points', function (): void {
expect(function (): void {
new MultiPoint([]);
diff --git a/tests/Objects/MultiPolygonTest.php b/tests/Objects/MultiPolygonTest.php
index a1d666e..7fc0d4c 100644
--- a/tests/Objects/MultiPolygonTest.php
+++ b/tests/Objects/MultiPolygonTest.php
@@ -29,6 +29,25 @@
expect($testPlace->multi_polygon)->toEqual($multiPolygon);
});
+it('creates a model record with multi polygon with SRID', function (): void {
+ $multiPolygon = new MultiPolygon([
+ new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]),
+ ], 4326);
+
+ /** @var TestPlace $testPlace */
+ $testPlace = TestPlace::factory()->create(['multi_polygon' => $multiPolygon]);
+
+ expect($testPlace->multi_polygon->srid)->toBe(4326);
+});
+
it('creates multi polygon from JSON', function (): void {
$multiPolygon = new MultiPolygon([
new Polygon([
@@ -47,6 +66,24 @@
expect($multiPolygonFromJson)->toEqual($multiPolygon);
});
+it('creates multi polygon with SRID from JSON', function (): void {
+ $multiPolygon = new MultiPolygon([
+ new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]),
+ ], 4326);
+
+ $multiPolygonFromJson = MultiPolygon::fromJson('{"type":"MultiPolygon","coordinates":[[[[0,180],[1,179],[2,178],[3,177],[0,180]]]]}', 4326);
+
+ expect($multiPolygonFromJson)->toEqual($multiPolygon);
+});
+
it('generates multi polygon JSON', function (): void {
$multiPolygon = new MultiPolygon([
new Polygon([
@@ -85,6 +122,78 @@
expect($featureCollectionJson)->toBe($expectedFeatureCollectionJson);
});
+it('creates multi polygon from WKT', function (): void {
+ $multiPolygon = new MultiPolygon([
+ new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]),
+ ]);
+
+ $multiPolygonFromWkt = MultiPolygon::fromWkt('MULTIPOLYGON(((0 180, 1 179, 2 178, 3 177, 0 180)))');
+
+ expect($multiPolygonFromWkt)->toEqual($multiPolygon);
+});
+
+it('creates multi polygon with SRID from WKT', function (): void {
+ $multiPolygon = new MultiPolygon([
+ new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]),
+ ], 4326);
+
+ $multiPolygonFromWkt = MultiPolygon::fromWkt('MULTIPOLYGON(((0 180, 1 179, 2 178, 3 177, 0 180)))', 4326);
+
+ expect($multiPolygonFromWkt)->toEqual($multiPolygon);
+});
+
+it('creates multi polygon from WKB', function (): void {
+ $multiPolygon = new MultiPolygon([
+ new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]),
+ ]);
+
+ $multiPolygonFromWkb = MultiPolygon::fromWkb($multiPolygon->toWkb());
+
+ expect($multiPolygonFromWkb)->toEqual($multiPolygon);
+});
+
+it('creates multi polygon with SRID from WKB', function (): void {
+ $multiPolygon = new MultiPolygon([
+ new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]),
+ ], 4326);
+
+ $multiPolygonFromWkb = MultiPolygon::fromWkb($multiPolygon->toWkb());
+
+ expect($multiPolygonFromWkb)->toEqual($multiPolygon);
+});
+
it('throws exception when multi polygon has no polygons', function (): void {
expect(function (): void {
new MultiPolygon([]);
diff --git a/tests/Objects/PointTest.php b/tests/Objects/PointTest.php
index 4b3c716..d486cd4 100644
--- a/tests/Objects/PointTest.php
+++ b/tests/Objects/PointTest.php
@@ -16,6 +16,15 @@
expect($testPlace->point)->toEqual($point);
});
+it('creates a model record with point with SRID', function (): void {
+ $point = new Point(180, 0, 4326);
+
+ /** @var TestPlace $testPlace */
+ $testPlace = TestPlace::factory()->create(['point' => $point]);
+
+ expect($testPlace->point->srid)->toBe(4326);
+});
+
it('creates point from JSON', function (): void {
$point = new Point(180, 0);
@@ -24,6 +33,14 @@
expect($pointFromJson)->toEqual($point);
});
+it('creates point with SRID from JSON', function (): void {
+ $point = new Point(180, 0, 4326);
+
+ $pointFromJson = Point::fromJson('{"type":"Point","coordinates":[0,180]}', 4326);
+
+ expect($pointFromJson)->toEqual($point);
+});
+
it('generates point json', function (): void {
$point = new Point(180, 0);
@@ -38,3 +55,35 @@
Point::fromJson('{"type":"Point","coordinates":[]}');
})->toThrow(InvalidArgumentException::class);
});
+
+it('creates point from WKT', function (): void {
+ $point = new Point(180, 0);
+
+ $pointFromWkt = Point::fromWkt('POINT(0 180)');
+
+ expect($pointFromWkt)->toEqual($point);
+});
+
+it('creates point with SRID from WKT', function (): void {
+ $point = new Point(180, 0, 4326);
+
+ $pointFromWkt = Point::fromWkt('POINT(0 180)', 4326);
+
+ expect($pointFromWkt)->toEqual($point);
+});
+
+it('creates point from WKB', function (): void {
+ $point = new Point(180, 0);
+
+ $pointFromWkb = Point::fromWkb($point->toWkb());
+
+ expect($pointFromWkb)->toEqual($point);
+});
+
+it('creates point with SRID from WKB', function (): void {
+ $point = new Point(180, 0, 4326);
+
+ $pointFromWkb = Point::fromWkb($point->toWkb());
+
+ expect($pointFromWkb)->toEqual($point);
+});
diff --git a/tests/Objects/PolygonTest.php b/tests/Objects/PolygonTest.php
index 9b910d6..9923bea 100644
--- a/tests/Objects/PolygonTest.php
+++ b/tests/Objects/PolygonTest.php
@@ -26,6 +26,23 @@
expect($testPlace->polygon)->toEqual($polygon);
});
+it('creates a model record with polygon with SRID', function (): void {
+ $polygon = new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ], 4326);
+
+ /** @var TestPlace $testPlace */
+ $testPlace = TestPlace::factory()->create(['polygon' => $polygon]);
+
+ expect($testPlace->polygon->srid)->toBe(4326);
+});
+
it('creates polygon from JSON', function (): void {
$polygon = new Polygon([
new LineString([
@@ -42,6 +59,22 @@
expect($polygonFromJson)->toEqual($polygon);
});
+it('creates polygon with SRID from JSON', function (): void {
+ $polygon = new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ], 4326);
+
+ $polygonFromJson = Polygon::fromJson('{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}', 4326);
+
+ expect($polygonFromJson)->toEqual($polygon);
+});
+
it('generates polygon JSON', function (): void {
$polygon = new Polygon([
new LineString([
@@ -76,6 +109,70 @@
expect($featureCollectionJson)->toBe($expectedFeatureCollectionJson);
});
+it('creates polygon from WKT', function (): void {
+ $polygon = new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]);
+
+ $polygonFromWkt = Polygon::fromWkt('POLYGON((0 180, 1 179, 2 178, 3 177, 0 180))');
+
+ expect($polygonFromWkt)->toEqual($polygon);
+});
+
+it('creates polygon with SRID from WKT', function (): void {
+ $polygon = new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ], 4326);
+
+ $polygonFromWkt = Polygon::fromWkt('POLYGON((0 180, 1 179, 2 178, 3 177, 0 180))', 4326);
+
+ expect($polygonFromWkt)->toEqual($polygon);
+});
+
+it('creates polygon from WKB', function (): void {
+ $polygon = new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ]);
+
+ $polygonFromWkb = Polygon::fromWkb($polygon->toWkb());
+
+ expect($polygonFromWkb)->toEqual($polygon);
+});
+
+it('creates polygon with SRID from WKB', function (): void {
+ $polygon = new Polygon([
+ new LineString([
+ new Point(180, 0),
+ new Point(179, 1),
+ new Point(178, 2),
+ new Point(177, 3),
+ new Point(180, 0),
+ ]),
+ ], 4326);
+
+ $polygonFromWkb = Polygon::fromWkb($polygon->toWkb());
+
+ expect($polygonFromWkb)->toEqual($polygon);
+});
+
it('throws exception when polygon has no line strings', function (): void {
expect(function (): void {
new Polygon([]);
diff --git a/tests/SpatialBuilderTest.php b/tests/SpatialBuilderTest.php
index f5fd43a..214b5f7 100644
--- a/tests/SpatialBuilderTest.php
+++ b/tests/SpatialBuilderTest.php
@@ -283,3 +283,18 @@
expect($testPlaces)->toHaveCount(1);
expect($testPlaces[0]->point)->toEqual($point1);
});
+
+it('filters by SRID', function (): void {
+ $point1 = new Point(0, 0, 4326);
+ $point2 = new Point(50, 50, 0);
+ TestPlace::factory()->create(['point' => $point1]);
+ TestPlace::factory()->create(['point' => $point2]);
+
+ /** @var TestPlace[] $testPlaces */
+ $testPlaces = TestPlace::query()
+ ->whereSrid('point', '=', 4326)
+ ->get();
+
+ expect($testPlaces)->toHaveCount(1);
+ expect($testPlaces[0]->point)->toEqual($point1);
+});