From 45efeeb509535b61b5c1592a573e8b598bfc7565 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Wed, 23 Aug 2017 01:22:26 -0400 Subject: [PATCH 01/57] MySQL 5.6 only --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 973da9db..00f9ce04 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,8 +8,6 @@ php: env: - MYSQL_VERSION=5.6 - - MYSQL_VERSION=5.7 - - MYSQL_VERSION=8.0 dist: trusty From 8bd0ccbb17623e58bc5f9fa96506ea2429bf92f0 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Wed, 23 Aug 2017 01:27:08 -0400 Subject: [PATCH 02/57] Removed st_distance_sphere() --- src/Eloquent/SpatialTrait.php | 21 ---------- tests/Unit/Eloquent/SpatialTraitTest.php | 49 ------------------------ 2 files changed, 70 deletions(-) diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index cc7d62b2..27f87109 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -83,17 +83,6 @@ public function scopeDistance($query, $distance, $geometry, $column_name, $exclu return $query; } - public function scopeDistanceSphere($query, $distance, $geometry, $column_name, $exclude_self = false) - { - $query->whereRaw("st_distance_sphere(`{$column_name}`, GeomFromText('{$geometry->toWkt()}')) <= {$distance}"); - - if ($exclude_self) { - $query->whereRaw("st_distance_sphere(`{$column_name}`, GeomFromText('{$geometry->toWkt()}')) != 0"); - } - - return $query; - } - public function scopeDistanceValue($query, $geometry, $column_name) { $columns = $query->getQuery()->columns; @@ -104,16 +93,6 @@ public function scopeDistanceValue($query, $geometry, $column_name) $query->selectRaw("st_distance(`{$column_name}`, GeomFromText('{$geometry->toWkt()}')) as distance"); } - public function scopeDistanceSphereValue($query, $geometry, $column_name) - { - $columns = $query->getQuery()->columns; - - if (! $columns) { - $query->select('*'); - } - $query->selectRaw("st_distance_sphere(`{$column_name}`, GeomFromText('{$geometry->toWkt()}')) as distance"); - } - public function scopeBounding($query, Geometry $bounds, $column_name) { return $query->whereRaw("st_intersects(GeomFromText('{$bounds->toWkt()}'), `{$column_name}`)"); diff --git a/tests/Unit/Eloquent/SpatialTraitTest.php b/tests/Unit/Eloquent/SpatialTraitTest.php index b91ec456..377c2010 100644 --- a/tests/Unit/Eloquent/SpatialTraitTest.php +++ b/tests/Unit/Eloquent/SpatialTraitTest.php @@ -214,29 +214,6 @@ public function testScopeDistanceExcludingSelf() $this->assertContains("st_distance(`point`, GeomFromText('POINT(2 1)')) != 0", $q->wheres[1]['sql']); } - public function testScopeDistanceSphere() - { - $point = new Point(1, 2); - $query = TestModel::DistanceSphere(10, $point, 'point'); - - $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); - $q = $query->getQuery(); - $this->assertNotEmpty($q->wheres); - $this->assertContains("st_distance_sphere(`point`, GeomFromText('POINT(2 1)')) <= 10", $q->wheres[0]['sql']); - } - - public function testScopeDistanceSphereExcludingSelf() - { - $point = new Point(1, 2); - $query = TestModel::DistanceSphere(10, $point, 'point', true); - - $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); - $q = $query->getQuery(); - $this->assertNotEmpty($q->wheres); - $this->assertContains("st_distance_sphere(`point`, GeomFromText('POINT(2 1)')) <= 10", $q->wheres[0]['sql']); - $this->assertContains("st_distance_sphere(`point`, GeomFromText('POINT(2 1)')) != 0", $q->wheres[1]['sql']); - } - public function testScopeDistanceValue() { $point = new Point(1, 2); @@ -263,32 +240,6 @@ public function testScopeDistanceValueWithSelect() $this->assertContains("st_distance(`point`, GeomFromText('POINT(2 1)')) as distance", $q->columns[1]->getValue()); } - public function testScopeDistanceSphereValue() - { - $point = new Point(1, 2); - $query = TestModel::DistanceSphereValue($point, 'point'); - - $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); - $q = $query->getQuery(); - $this->assertNotEmpty($q->columns); - $this->assertContains("*", $q->columns[0]); - $this->assertInstanceOf(\Illuminate\Database\Query\Expression::class, $q->columns[1]); - $this->assertContains("st_distance_sphere(`point`, GeomFromText('POINT(2 1)')) as distance", $q->columns[1]->getValue()); - } - - public function testScopeDistanceSphereValueWithSelect() - { - $point = new Point(1, 2); - $query = TestModel::select('some_column')->distanceSphereValue($point, 'point'); - - $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); - $q = $query->getQuery(); - $this->assertNotEmpty($q->columns); - $this->assertContains("some_column", $q->columns[0]); - $this->assertInstanceOf(\Illuminate\Database\Query\Expression::class, $q->columns[1]); - $this->assertContains("st_distance_sphere(`point`, GeomFromText('POINT(2 1)')) as distance", $q->columns[1]->getValue()); - } - private function buildTestPolygon(){ $point1 = new Point(1, 1); $point2 = new Point(1, 2); From 9a87a3d5b41b6456ecdcdd04f7cef40fe3258c3a Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Wed, 23 Aug 2017 01:29:18 -0400 Subject: [PATCH 03/57] Removed remaining st_distance_sphere() tests --- tests/Integration/SpatialTest.php | 34 ------------------------------- 1 file changed, 34 deletions(-) diff --git a/tests/Integration/SpatialTest.php b/tests/Integration/SpatialTest.php index c2a4e606..bbf0528f 100644 --- a/tests/Integration/SpatialTest.php +++ b/tests/Integration/SpatialTest.php @@ -225,25 +225,6 @@ public function testDistanceSphere() $loc3 = new GeometryModel(); $loc3->location = new Point(40.761434, -73.977619); // Distance from loc1: 870.06424066202 $loc3->save(); - - $a = GeometryModel::distanceSphere(200, $loc1->location, 'location')->get(); - $this->assertCount(2, $a); - $this->assertTrue($a->contains($loc1)); - $this->assertTrue($a->contains($loc2)); - $this->assertFalse($a->contains($loc3)); - - // Excluding self - $b = GeometryModel::distanceSphere(200, $loc1->location, 'location', true)->get(); - $this->assertCount(1, $b); - $this->assertFalse($b->contains($loc1)); - $this->assertTrue($b->contains($loc2)); - $this->assertFalse($b->contains($loc3)); - - $c = GeometryModel::distanceSphere(44.741406484587, $loc1->location, 'location')->get(); - $this->assertCount(1, $c); - $this->assertTrue($c->contains($loc1)); - $this->assertFalse($c->contains($loc2)); - $this->assertFalse($c->contains($loc3)); } public function testDistanceValue() @@ -262,21 +243,6 @@ public function testDistanceValue() $this->assertEquals(1.4142135623, $a[1]->distance); // PHP floats' 11th+ digits don't matter } - public function testDistanceSphereValue() { - $loc1 = new GeometryModel(); - $loc1->location = new Point(40.767864, -73.971732); - $loc1->save(); - - $loc2 = new GeometryModel(); - $loc2->location = new Point(40.767664, -73.971271); // Distance from loc1: 44.741406484588 - $loc2->save(); - - $a = GeometryModel::distanceSphereValue($loc1->location, 'location')->get(); - $this->assertCount(2, $a); - $this->assertEquals(0, $a[0]->distance); - $this->assertEquals(44.7414064845, $a[1]->distance); // PHP floats' 11th+ digits don't matter - } - public function testBounding() { $point = new Point(0, 0); From b3473de0c44b96c0990244809dcf47c32389f80b Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Fri, 25 Aug 2017 19:19:36 -0400 Subject: [PATCH 04/57] Adjusted versions in composer. --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 152030fa..4395d37d 100644 --- a/composer.json +++ b/composer.json @@ -10,13 +10,13 @@ } ], "require": { - "php": ">=5.5", + "php": ">=5.5.9", "illuminate/database": "^5.2", "geo-io/wkb-parser": "^1.0", "jmikola/geojson": "^1.0" }, "require-dev": { - "phpunit/phpunit": "~4.5||5.6.5", + "phpunit/phpunit": "~4.8", "mockery/mockery": "^0.9.9", "laravel/laravel": "^5.2", "codeclimate/php-test-reporter": "dev-master", From d7751bb12fa9d34a0951cbd119cd0a9005bafaff Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Fri, 25 Aug 2017 19:23:49 -0400 Subject: [PATCH 05/57] Removed scopeBounding() in favor of scopeIntersects(). Adjusted tests for MySQL 5.6. Also cleaned up unneeded Dockerfile. --- .gitignore | 2 +- Dockerfile | 17 ------- php.ini | 2 - src/Eloquent/SpatialTrait.php | 5 -- tests/Integration/SpatialTest.php | 65 ++++-------------------- tests/Unit/Eloquent/SpatialTraitTest.php | 11 +--- 6 files changed, 11 insertions(+), 91 deletions(-) delete mode 100644 Dockerfile delete mode 100644 php.ini diff --git a/.gitignore b/.gitignore index bc8baf5e..12a3a6e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ .idea/ vendor/ composer.lock -_db/ \ No newline at end of file +_db-*/ diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index b64ae7ac..00000000 --- a/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM php:7.0-cli - -RUN apt-get update && apt-get install -y unzip git - -COPY php.ini /usr/local/etc/php/ - -# Install and enable xdebug and pdo mysql -RUN pecl install xdebug-2.5.1 \ - && docker-php-ext-install pdo_mysql \ - && docker-php-ext-enable xdebug pdo_mysql - -# Install composer -RUN curl -o /tmp/composer-setup.php https://getcomposer.org/installer \ - && curl -o /tmp/composer-setup.sig https://composer.github.io/installer.sig \ - && php -r "if (hash('SHA384', file_get_contents('/tmp/composer-setup.php')) !== trim(file_get_contents('/tmp/composer-setup.sig'))) { unlink('/tmp/composer-setup.php'); echo 'Invalid installer' . PHP_EOL; exit(1); }" \ - && php /tmp/composer-setup.php --no-ansi --install-dir=/usr/local/bin --filename=composer --snapshot \ - && rm -f /tmp/composer-setup.* \ No newline at end of file diff --git a/php.ini b/php.ini deleted file mode 100644 index 5713fb66..00000000 --- a/php.ini +++ /dev/null @@ -1,2 +0,0 @@ -[Date] -date.timezone = UTC \ No newline at end of file diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index 27f87109..510011db 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -93,11 +93,6 @@ public function scopeDistanceValue($query, $geometry, $column_name) $query->selectRaw("st_distance(`{$column_name}`, GeomFromText('{$geometry->toWkt()}')) as distance"); } - public function scopeBounding($query, Geometry $bounds, $column_name) - { - return $query->whereRaw("st_intersects(GeomFromText('{$bounds->toWkt()}'), `{$column_name}`)"); - } - public function scopeComparison($query, $geometryColumn, $geometry, $relationship) { $query->whereRaw("st_{$relationship}(`{$geometryColumn}`, GeomFromText('{$geometry->toWkt()}'))"); diff --git a/tests/Integration/SpatialTest.php b/tests/Integration/SpatialTest.php index bbf0528f..92eebc9c 100644 --- a/tests/Integration/SpatialTest.php +++ b/tests/Integration/SpatialTest.php @@ -194,37 +194,22 @@ public function testDistance() $a = GeometryModel::distance(2, $loc1->location, 'location')->get(); $this->assertCount(2, $a); - $this->assertTrue($a->contains($loc1)); - $this->assertTrue($a->contains($loc2)); - $this->assertFalse($a->contains($loc3)); + $this->assertTrue($a->contains('location', $loc1->location)); + $this->assertTrue($a->contains('location', $loc2->location)); + $this->assertFalse($a->contains('location', $loc3->location)); // Excluding self $b = GeometryModel::distance(2, $loc1->location, 'location', true)->get(); $this->assertCount(1, $b); - $this->assertFalse($b->contains($loc1)); - $this->assertTrue($b->contains($loc2)); - $this->assertFalse($b->contains($loc3)); + $this->assertFalse($b->contains('location',$loc1->location)); + $this->assertTrue($b->contains('location',$loc2->location)); + $this->assertFalse($b->contains('location',$loc3->location)); $c = GeometryModel::distance(1, $loc1->location, 'location')->get(); $this->assertCount(1, $c); - $this->assertTrue($c->contains($loc1)); - $this->assertFalse($c->contains($loc2)); - $this->assertFalse($c->contains($loc3)); - } - - public function testDistanceSphere() - { - $loc1 = new GeometryModel(); - $loc1->location = new Point(40.767864, -73.971732); - $loc1->save(); - - $loc2 = new GeometryModel(); - $loc2->location = new Point(40.767664, -73.971271); // Distance from loc1: 44.741406484588 - $loc2->save(); - - $loc3 = new GeometryModel(); - $loc3->location = new Point(40.761434, -73.977619); // Distance from loc1: 870.06424066202 - $loc3->save(); + $this->assertTrue($c->contains('location', $loc1->location)); + $this->assertFalse($c->contains('location', $loc2->location)); + $this->assertFalse($c->contains('location', $loc3->location)); } public function testDistanceValue() @@ -242,36 +227,4 @@ public function testDistanceValue() $this->assertEquals(0, $a[0]->distance); $this->assertEquals(1.4142135623, $a[1]->distance); // PHP floats' 11th+ digits don't matter } - - public function testBounding() { - $point = new Point(0, 0); - - $linestring1 = \Grimzy\LaravelMysqlSpatial\Types\LineString::fromWkt("LINESTRING(1 1, 2 2)"); - $linestring2 = \Grimzy\LaravelMysqlSpatial\Types\LineString::fromWkt("LINESTRING(20 20, 24 24)"); - $linestring3 = \Grimzy\LaravelMysqlSpatial\Types\LineString::fromWkt("LINESTRING(0 10, 10 10)"); - - $geo1 = new GeometryModel(); - $geo1->location = $point; - $geo1->line = $linestring1; - $geo1->save(); - - $geo2 = new GeometryModel(); - $geo2->location = $point; - $geo2->line = $linestring2; - $geo2->save(); - - $geo3 = new GeometryModel(); - $geo3->location = $point; - $geo3->line = $linestring3; - $geo3->save(); - - $polygon = Polygon::fromWKT("POLYGON((0 10,10 10,10 0,0 0,0 10))"); - - $result = GeometryModel::Bounding($polygon, 'line')->get(); - $this->assertCount(2, $result); - $this->assertTrue($result->contains($geo1)); - $this->assertFalse($result->contains($geo2)); - $this->assertTrue($result->contains($geo3)); - - } } \ No newline at end of file diff --git a/tests/Unit/Eloquent/SpatialTraitTest.php b/tests/Unit/Eloquent/SpatialTraitTest.php index 377c2010..c8d06458 100644 --- a/tests/Unit/Eloquent/SpatialTraitTest.php +++ b/tests/Unit/Eloquent/SpatialTraitTest.php @@ -253,15 +253,6 @@ private function buildTestPolygon(){ return new \Grimzy\LaravelMysqlSpatial\Types\Polygon([$linestring1, $linestring2, $linestring3]); } - public function testScopeBounding() - { - $query = TestModel::Bounding($this->buildTestPolygon(), 'point'); - $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); - $q = $query->getQuery(); - $this->assertNotEmpty($q->wheres); - $this->assertContains("st_intersects(GeomFromText('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))'), `point`)", $q->wheres[0]['sql']); - } - public function testScopeComparison() { $query = TestModel::Comparison('point',$this->buildTestPolygon(),'within'); @@ -357,7 +348,7 @@ class TestModel extends Model { use \Grimzy\LaravelMysqlSpatial\Eloquent\SpatialTrait; - protected $spatialFields = ['point']; // TODO: only required when fetching, not saving + protected $spatialFields = ['point']; // only required when fetching, not saving public $timestamps = false; From 4f50a6357e8d911d3a8e0a7cfbdb3ac9c51fee1b Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Fri, 25 Aug 2017 21:34:57 -0400 Subject: [PATCH 06/57] Rearranged parameters of spatial analysis Eloquent scopes and fixed tests accordingly --- src/Eloquent/SpatialTrait.php | 10 +++++----- tests/Integration/SpatialTest.php | 8 ++++---- tests/Unit/Eloquent/SpatialTraitTest.php | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index 510011db..d3475ec8 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -72,25 +72,25 @@ public function getSpatialFields() } } - public function scopeDistance($query, $distance, $geometry, $column_name, $exclude_self = false) + public function scopeDistance($query, $geometryColumn, $geometry, $distance, $exclude_self = false) { - $query->whereRaw("st_distance(`{$column_name}`, GeomFromText('{$geometry->toWkt()}')) <= {$distance}"); + $query->whereRaw("st_distance(`{$geometryColumn}`, GeomFromText('{$geometry->toWkt()}')) <= {$distance}"); if ($exclude_self) { - $query->whereRaw("st_distance(`{$column_name}`, GeomFromText('{$geometry->toWkt()}')) != 0"); + $query->whereRaw("st_distance(`{$geometryColumn}`, GeomFromText('{$geometry->toWkt()}')) != 0"); } return $query; } - public function scopeDistanceValue($query, $geometry, $column_name) + public function scopeDistanceValue($query, $geometryColumn, $geometry) { $columns = $query->getQuery()->columns; if (! $columns) { $query->select('*'); } - $query->selectRaw("st_distance(`{$column_name}`, GeomFromText('{$geometry->toWkt()}')) as distance"); + $query->selectRaw("st_distance(`{$geometryColumn}`, GeomFromText('{$geometry->toWkt()}')) as distance"); } public function scopeComparison($query, $geometryColumn, $geometry, $relationship) diff --git a/tests/Integration/SpatialTest.php b/tests/Integration/SpatialTest.php index 92eebc9c..c8943cba 100644 --- a/tests/Integration/SpatialTest.php +++ b/tests/Integration/SpatialTest.php @@ -192,20 +192,20 @@ public function testDistance() $loc3->location = new Point(3, 3); // Distance from loc1: 2.8284271247462 $loc3->save(); - $a = GeometryModel::distance(2, $loc1->location, 'location')->get(); + $a = GeometryModel::distance('location', $loc1->location, 2)->get(); $this->assertCount(2, $a); $this->assertTrue($a->contains('location', $loc1->location)); $this->assertTrue($a->contains('location', $loc2->location)); $this->assertFalse($a->contains('location', $loc3->location)); // Excluding self - $b = GeometryModel::distance(2, $loc1->location, 'location', true)->get(); + $b = GeometryModel::distance('location', $loc1->location, 2, true)->get(); $this->assertCount(1, $b); $this->assertFalse($b->contains('location',$loc1->location)); $this->assertTrue($b->contains('location',$loc2->location)); $this->assertFalse($b->contains('location',$loc3->location)); - $c = GeometryModel::distance(1, $loc1->location, 'location')->get(); + $c = GeometryModel::distance('location', $loc1->location, 1)->get(); $this->assertCount(1, $c); $this->assertTrue($c->contains('location', $loc1->location)); $this->assertFalse($c->contains('location', $loc2->location)); @@ -222,7 +222,7 @@ public function testDistanceValue() $loc2->location = new Point(2, 2); // Distance from loc1: 1.4142135623731 $loc2->save(); - $a = GeometryModel::distanceValue($loc1->location, 'location')->get(); + $a = GeometryModel::distanceValue('location', $loc1->location)->get(); $this->assertCount(2, $a); $this->assertEquals(0, $a[0]->distance); $this->assertEquals(1.4142135623, $a[1]->distance); // PHP floats' 11th+ digits don't matter diff --git a/tests/Unit/Eloquent/SpatialTraitTest.php b/tests/Unit/Eloquent/SpatialTraitTest.php index c8d06458..b6947001 100644 --- a/tests/Unit/Eloquent/SpatialTraitTest.php +++ b/tests/Unit/Eloquent/SpatialTraitTest.php @@ -194,7 +194,7 @@ public function testInsertUpdateGeometryCollectionHasCorrectSql() public function testScopeDistance() { $point = new Point(1, 2); - $query = TestModel::Distance(10, $point, 'point'); + $query = TestModel::Distance('point', $point, 10); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -205,7 +205,7 @@ public function testScopeDistance() public function testScopeDistanceExcludingSelf() { $point = new Point(1, 2); - $query = TestModel::Distance(10, $point, 'point', true); + $query = TestModel::Distance('point', $point, 10, true); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -217,7 +217,7 @@ public function testScopeDistanceExcludingSelf() public function testScopeDistanceValue() { $point = new Point(1, 2); - $query = TestModel::DistanceValue($point, 'point'); + $query = TestModel::DistanceValue('point', $point); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -230,7 +230,7 @@ public function testScopeDistanceValue() public function testScopeDistanceValueWithSelect() { $point = new Point(1, 2); - $query = TestModel::select('some_column')->distanceValue($point, 'point'); + $query = TestModel::select('some_column')->distanceValue('point', $point); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); From 625a99cd7893aa3f760ffa4d17d16f7403fc25c2 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Fri, 25 Aug 2017 22:38:44 -0400 Subject: [PATCH 07/57] StyleCI patch :tophat: --- src/Connectors/ConnectionFactory.php | 8 +-- src/Doctrine/Geometry.php | 2 +- src/Doctrine/GeometryCollection.php | 2 +- src/Doctrine/LineString.php | 2 +- src/Doctrine/MultiLineString.php | 2 +- src/Doctrine/MultiPoint.php | 2 +- src/Doctrine/MultiPolygon.php | 2 +- src/Doctrine/Point.php | 2 +- src/Doctrine/Polygon.php | 2 +- src/Eloquent/Builder.php | 2 +- src/Eloquent/SpatialTrait.php | 6 +-- src/MysqlConnection.php | 4 +- src/Schema/Blueprint.php | 50 +++++++++++-------- src/Schema/Builder.php | 3 +- src/Schema/Grammars/MySqlGrammar.php | 29 +++++++---- src/SpatialServiceProvider.php | 29 +++++------ src/Types/Geometry.php | 2 +- src/Types/GeometryCollection.php | 13 ++--- src/Types/GeometryInterface.php | 2 +- src/Types/LineString.php | 2 +- src/Types/MultiLineString.php | 2 +- src/Types/MultiPoint.php | 2 +- src/Types/MultiPolygon.php | 16 +++--- src/Types/Point.php | 4 +- src/Types/PointCollection.php | 3 +- src/Types/Polygon.php | 2 +- tests/Integration/Migrations/CreateTables.php | 2 +- tests/Integration/Migrations/UpdateTables.php | 2 +- tests/Integration/Models/GeometryModel.php | 3 +- .../Models/NoSpatialFieldsModel.php | 3 +- tests/Integration/SpatialTest.php | 33 ++++++------ tests/Integration/Tools/ClassFinder.php | 38 ++++++++------ tests/Unit/Eloquent/BuilderTest.php | 6 ++- tests/Unit/Eloquent/SpatialTraitTest.php | 26 +++++----- tests/Unit/MysqlConnectionTest.php | 2 +- tests/Unit/Schema/BlueprintTest.php | 5 +- tests/Unit/Schema/BuilderTest.php | 3 +- tests/Unit/Stubs/PDOStub.php | 3 +- tests/Unit/Types/GeometryCollectionTest.php | 6 +-- tests/Unit/Types/LineStringTest.php | 2 +- tests/Unit/Types/MultiLineStringTest.php | 4 +- tests/Unit/Types/MultiPointTest.php | 2 +- tests/Unit/Types/MultiPolygonTest.php | 8 ++- tests/Unit/Types/PointTest.php | 2 +- tests/Unit/Types/PolygonTest.php | 4 +- 45 files changed, 190 insertions(+), 159 deletions(-) diff --git a/src/Connectors/ConnectionFactory.php b/src/Connectors/ConnectionFactory.php index cfa55692..ada8b7f7 100644 --- a/src/Connectors/ConnectionFactory.php +++ b/src/Connectors/ConnectionFactory.php @@ -8,11 +8,11 @@ class ConnectionFactory extends \Illuminate\Database\Connectors\ConnectionFactory { /** - * @param string $driver + * @param string $driver * @param \Closure|PDO $connection - * @param string $database - * @param string $prefix - * @param array $config + * @param string $database + * @param string $prefix + * @param array $config * * @return \Illuminate\Database\ConnectionInterface */ diff --git a/src/Doctrine/Geometry.php b/src/Doctrine/Geometry.php index c2115b37..e7e138f9 100644 --- a/src/Doctrine/Geometry.php +++ b/src/Doctrine/Geometry.php @@ -18,4 +18,4 @@ public function getName() { return self::GEOMETRY; } -} \ No newline at end of file +} diff --git a/src/Doctrine/GeometryCollection.php b/src/Doctrine/GeometryCollection.php index 0b75440c..16d106fb 100644 --- a/src/Doctrine/GeometryCollection.php +++ b/src/Doctrine/GeometryCollection.php @@ -18,4 +18,4 @@ public function getName() { return self::GEOMETRYCOLLECTION; } -} \ No newline at end of file +} diff --git a/src/Doctrine/LineString.php b/src/Doctrine/LineString.php index 6cf57fb0..9ba31476 100644 --- a/src/Doctrine/LineString.php +++ b/src/Doctrine/LineString.php @@ -18,4 +18,4 @@ public function getName() { return self::LINESTRING; } -} \ No newline at end of file +} diff --git a/src/Doctrine/MultiLineString.php b/src/Doctrine/MultiLineString.php index f9eba009..ffabd599 100644 --- a/src/Doctrine/MultiLineString.php +++ b/src/Doctrine/MultiLineString.php @@ -18,4 +18,4 @@ public function getName() { return self::MULTILINESTRING; } -} \ No newline at end of file +} diff --git a/src/Doctrine/MultiPoint.php b/src/Doctrine/MultiPoint.php index b1e2a7ee..894ce70c 100644 --- a/src/Doctrine/MultiPoint.php +++ b/src/Doctrine/MultiPoint.php @@ -18,4 +18,4 @@ public function getName() { return self::MULTIPOINT; } -} \ No newline at end of file +} diff --git a/src/Doctrine/MultiPolygon.php b/src/Doctrine/MultiPolygon.php index e6186c27..0d2e6185 100644 --- a/src/Doctrine/MultiPolygon.php +++ b/src/Doctrine/MultiPolygon.php @@ -18,4 +18,4 @@ public function getName() { return self::MULTIPOLYGON; } -} \ No newline at end of file +} diff --git a/src/Doctrine/Point.php b/src/Doctrine/Point.php index 7719d627..3e8365e9 100644 --- a/src/Doctrine/Point.php +++ b/src/Doctrine/Point.php @@ -18,4 +18,4 @@ public function getName() { return self::POINT; } -} \ No newline at end of file +} diff --git a/src/Doctrine/Polygon.php b/src/Doctrine/Polygon.php index 29edee31..e8c81c09 100644 --- a/src/Doctrine/Polygon.php +++ b/src/Doctrine/Polygon.php @@ -18,4 +18,4 @@ public function getName() { return self::POLYGON; } -} \ No newline at end of file +} diff --git a/src/Eloquent/Builder.php b/src/Eloquent/Builder.php index 92755567..ed0a15c9 100755 --- a/src/Eloquent/Builder.php +++ b/src/Eloquent/Builder.php @@ -22,4 +22,4 @@ protected function asWKT(GeometryInterface $geometry) { return $this->getQuery()->raw("GeomFromText('".$geometry->toWKT()."')"); } -} \ No newline at end of file +} diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index d3475ec8..a80edd51 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -23,7 +23,7 @@ trait SpatialTrait /** * Create a new Eloquent query builder for the model. * - * @param \Illuminate\Database\Query\Builder $query + * @param \Illuminate\Database\Query\Builder $query * * @return \Grimzy\LaravelMysqlSpatial\Eloquent\Builder */ @@ -87,7 +87,7 @@ public function scopeDistanceValue($query, $geometryColumn, $geometry) { $columns = $query->getQuery()->columns; - if (! $columns) { + if (!$columns) { $query->select('*'); } $query->selectRaw("st_distance(`{$geometryColumn}`, GeomFromText('{$geometry->toWkt()}')) as distance"); @@ -139,4 +139,4 @@ public function scopeDoesTouch($query, $geometryColumn, $geometry) { return $this->scopeComparison($query, $geometryColumn, $geometry, 'touches'); } -} \ No newline at end of file +} diff --git a/src/MysqlConnection.php b/src/MysqlConnection.php index 11d71cdb..62b220bd 100644 --- a/src/MysqlConnection.php +++ b/src/MysqlConnection.php @@ -8,7 +8,7 @@ public function __construct($pdo, $database = '', $tablePrefix = '', array $conf { parent::__construct($pdo, $database, $tablePrefix, $config); - if(class_exists('Doctrine\DBAL\Types\Type')) { + if (class_exists('Doctrine\DBAL\Types\Type')) { // Prevent geometry type fields from throwing a 'type not found' error when changing them $geometries = [ 'geometry', @@ -21,7 +21,7 @@ public function __construct($pdo, $database = '', $tablePrefix = '', array $conf 'geometrycollection', ]; $dbPlatform = $this->getDoctrineSchemaManager()->getDatabasePlatform(); - foreach($geometries as $type) { + foreach ($geometries as $type) { $dbPlatform->registerDoctrineTypeMapping($type, 'string'); } } diff --git a/src/Schema/Blueprint.php b/src/Schema/Blueprint.php index 479d724b..fb200a2b 100644 --- a/src/Schema/Blueprint.php +++ b/src/Schema/Blueprint.php @@ -5,9 +5,10 @@ class Blueprint extends \Illuminate\Database\Schema\Blueprint { /** - * Add a geometry column on the table + * Add a geometry column on the table. + * + * @param string $column * - * @param string $column * @return \Illuminate\Support\Fluent */ public function geometry($column) @@ -16,9 +17,10 @@ public function geometry($column) } /** - * Add a point column on the table + * Add a point column on the table. + * + * @param $column * - * @param $column * @return \Illuminate\Support\Fluent */ public function point($column) @@ -27,9 +29,10 @@ public function point($column) } /** - * Add a linestring column on the table + * Add a linestring column on the table. + * + * @param $column * - * @param $column * @return \Illuminate\Support\Fluent */ public function lineString($column) @@ -38,9 +41,10 @@ public function lineString($column) } /** - * Add a polygon column on the table + * Add a polygon column on the table. + * + * @param $column * - * @param $column * @return \Illuminate\Support\Fluent */ public function polygon($column) @@ -49,9 +53,10 @@ public function polygon($column) } /** - * Add a multipoint column on the table + * Add a multipoint column on the table. + * + * @param $column * - * @param $column * @return \Illuminate\Support\Fluent */ public function multiPoint($column) @@ -60,9 +65,10 @@ public function multiPoint($column) } /** - * Add a multilinestring column on the table + * Add a multilinestring column on the table. + * + * @param $column * - * @param $column * @return \Illuminate\Support\Fluent */ public function multiLineString($column) @@ -71,9 +77,10 @@ public function multiLineString($column) } /** - * Add a multipolygon column on the table + * Add a multipolygon column on the table. + * + * @param $column * - * @param $column * @return \Illuminate\Support\Fluent */ public function multiPolygon($column) @@ -82,9 +89,10 @@ public function multiPolygon($column) } /** - * Add a geometrycollection column on the table + * Add a geometrycollection column on the table. + * + * @param $column * - * @param $column * @return \Illuminate\Support\Fluent */ public function geometryCollection($column) @@ -93,10 +101,11 @@ public function geometryCollection($column) } /** - * Specify a spatial index for the table + * Specify a spatial index for the table. + * + * @param string|array $columns + * @param string $name * - * @param string|array $columns - * @param string $name * @return \Illuminate\Support\Fluent */ public function spatialIndex($columns, $name = null) @@ -107,7 +116,8 @@ public function spatialIndex($columns, $name = null) /** * Indicate that the given index should be dropped. * - * @param string|array $index + * @param string|array $index + * * @return \Illuminate\Support\Fluent */ public function dropSpatialIndex($index) diff --git a/src/Schema/Builder.php b/src/Schema/Builder.php index 2e0f6de3..baf8dc58 100644 --- a/src/Schema/Builder.php +++ b/src/Schema/Builder.php @@ -10,8 +10,9 @@ class Builder extends MySqlBuilder /** * Create a new command set with a Closure. * - * @param string $table + * @param string $table * @param Closure $callback + * * @return Blueprint */ protected function createBlueprint($table, Closure $callback = null) diff --git a/src/Schema/Grammars/MySqlGrammar.php b/src/Schema/Grammars/MySqlGrammar.php index 10d9263f..a904aa51 100644 --- a/src/Schema/Grammars/MySqlGrammar.php +++ b/src/Schema/Grammars/MySqlGrammar.php @@ -8,9 +8,10 @@ class MySqlGrammar extends \Illuminate\Database\Schema\Grammars\MySqlGrammar { /** - * Adds a statement to add a geometry column + * Adds a statement to add a geometry column. * * @param \Illuminate\Support\Fluent $column + * * @return string */ public function typeGeometry(Fluent $column) @@ -19,9 +20,10 @@ public function typeGeometry(Fluent $column) } /** - * Adds a statement to add a point column + * Adds a statement to add a point column. * * @param \Illuminate\Support\Fluent $column + * * @return string */ public function typePoint(Fluent $column) @@ -30,9 +32,10 @@ public function typePoint(Fluent $column) } /** - * Adds a statement to add a linestring column + * Adds a statement to add a linestring column. * * @param \Illuminate\Support\Fluent $column + * * @return string */ public function typeLinestring(Fluent $column) @@ -41,9 +44,10 @@ public function typeLinestring(Fluent $column) } /** - * Adds a statement to add a polygon column + * Adds a statement to add a polygon column. * * @param \Illuminate\Support\Fluent $column + * * @return string */ public function typePolygon(Fluent $column) @@ -52,9 +56,10 @@ public function typePolygon(Fluent $column) } /** - * Adds a statement to add a multipoint column + * Adds a statement to add a multipoint column. * * @param \Illuminate\Support\Fluent $column + * * @return string */ public function typeMultipoint(Fluent $column) @@ -63,9 +68,10 @@ public function typeMultipoint(Fluent $column) } /** - * Adds a statement to add a multilinestring column + * Adds a statement to add a multilinestring column. * * @param \Illuminate\Support\Fluent $column + * * @return string */ public function typeMultilinestring(Fluent $column) @@ -74,9 +80,10 @@ public function typeMultilinestring(Fluent $column) } /** - * Adds a statement to add a multipolygon column + * Adds a statement to add a multipolygon column. * * @param \Illuminate\Support\Fluent $column + * * @return string */ public function typeMultipolygon(Fluent $column) @@ -85,9 +92,10 @@ public function typeMultipolygon(Fluent $column) } /** - * Adds a statement to add a geometrycollection column + * Adds a statement to add a geometrycollection column. * * @param \Illuminate\Support\Fluent $column + * * @return string */ public function typeGeometrycollection(Fluent $column) @@ -98,8 +106,9 @@ public function typeGeometrycollection(Fluent $column) /** * Compile a spatial index key command. * - * @param \Grimzy\LaravelMysqlSpatial\Schema\Blueprint $blueprint - * @param \Illuminate\Support\Fluent $command + * @param \Grimzy\LaravelMysqlSpatial\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * * @return string */ public function compileSpatial(Blueprint $blueprint, Fluent $command) diff --git a/src/SpatialServiceProvider.php b/src/SpatialServiceProvider.php index 05a67777..89100de6 100644 --- a/src/SpatialServiceProvider.php +++ b/src/SpatialServiceProvider.php @@ -7,9 +7,7 @@ use Illuminate\Database\DatabaseServiceProvider; /** - * Class DatabaseServiceProvider - * - * @package Grimzy\LaravelMysqlSpatial + * Class DatabaseServiceProvider. */ class SpatialServiceProvider extends DatabaseServiceProvider { @@ -34,25 +32,24 @@ public function register() return new DatabaseManager($app, $app['db.factory']); }); - if(class_exists('Doctrine\DBAL\Types\Type')) { + if (class_exists('Doctrine\DBAL\Types\Type')) { // Prevent geometry type fields from throwing a 'type not found' error when changing them $geometries = [ - 'geometry' => "Grimzy\LaravelMysqlSpatial\Doctrine\Geometry", - 'point' => "Grimzy\LaravelMysqlSpatial\Doctrine\Point", - 'linestring' => "Grimzy\LaravelMysqlSpatial\Doctrine\LineString", - 'polygon' => "Grimzy\LaravelMysqlSpatial\Doctrine\Polygon", - 'multipoint' => "Grimzy\LaravelMysqlSpatial\Doctrine\MultiPoint", - 'multilinestring' => "Grimzy\LaravelMysqlSpatial\Doctrine\MultiLineString", - 'multipolygon' => "Grimzy\LaravelMysqlSpatial\Doctrine\MultiPolygon", - 'geometrycollection' => "Grimzy\LaravelMysqlSpatial\Doctrine\GeometryCollection" + 'geometry' => "Grimzy\LaravelMysqlSpatial\Doctrine\Geometry", + 'point' => "Grimzy\LaravelMysqlSpatial\Doctrine\Point", + 'linestring' => "Grimzy\LaravelMysqlSpatial\Doctrine\LineString", + 'polygon' => "Grimzy\LaravelMysqlSpatial\Doctrine\Polygon", + 'multipoint' => "Grimzy\LaravelMysqlSpatial\Doctrine\MultiPoint", + 'multilinestring' => "Grimzy\LaravelMysqlSpatial\Doctrine\MultiLineString", + 'multipolygon' => "Grimzy\LaravelMysqlSpatial\Doctrine\MultiPolygon", + 'geometrycollection' => "Grimzy\LaravelMysqlSpatial\Doctrine\GeometryCollection", ]; $typeNames = array_keys(\Doctrine\DBAL\Types\Type::getTypesMap()); - foreach($geometries as $type => $class) { - if(!in_array($type, $typeNames)) { + foreach ($geometries as $type => $class) { + if (!in_array($type, $typeNames)) { \Doctrine\DBAL\Types\Type::addType($type, $class); } } } - } -} \ No newline at end of file +} diff --git a/src/Types/Geometry.php b/src/Types/Geometry.php index 54042f8f..20ba8c12 100644 --- a/src/Types/Geometry.php +++ b/src/Types/Geometry.php @@ -69,4 +69,4 @@ public static function fromWKT($wkt) return static::fromString($wktArgument); } -} \ No newline at end of file +} diff --git a/src/Types/GeometryCollection.php b/src/Types/GeometryCollection.php index 86c944d9..734104f9 100755 --- a/src/Types/GeometryCollection.php +++ b/src/Types/GeometryCollection.php @@ -14,6 +14,7 @@ class GeometryCollection extends Geometry implements Countable /** * @param GeometryInterface[] $geometries + * * @throws InvalidArgumentException */ public function __construct(array $geometries) @@ -42,8 +43,8 @@ public function toWKT() public function __toString() { return implode(',', array_map(function (GeometryInterface $geometry) { - return $geometry->toWKT(); - }, $this->geometries)); + return $geometry->toWKT(); + }, $this->geometries)); } public static function fromString($wktArgument) @@ -51,10 +52,10 @@ public static function fromString($wktArgument) $geometry_strings = preg_split('/,\s*(?=[A-Za-z])/', $wktArgument); return new static(array_map(function ($geometry_string) { - $klass = Geometry::getWKTClass($geometry_string); + $klass = Geometry::getWKTClass($geometry_string); - return call_user_func($klass.'::fromWKT', $geometry_string); - }, $geometry_strings)); + return call_user_func($klass.'::fromWKT', $geometry_string); + }, $geometry_strings)); } public function count() @@ -63,7 +64,7 @@ public function count() } /** - * Convert to GeoJson GeometryCollection that is jsonable to GeoJSON + * Convert to GeoJson GeometryCollection that is jsonable to GeoJSON. * * @return \GeoJson\Geometry\GeometryCollection */ diff --git a/src/Types/GeometryInterface.php b/src/Types/GeometryInterface.php index 5e6312ba..330ec927 100644 --- a/src/Types/GeometryInterface.php +++ b/src/Types/GeometryInterface.php @@ -11,4 +11,4 @@ public static function fromWKT($wkt); public function __toString(); public static function fromString($wktArgument); -} \ No newline at end of file +} diff --git a/src/Types/LineString.php b/src/Types/LineString.php index e58a632e..851aa2dd 100644 --- a/src/Types/LineString.php +++ b/src/Types/LineString.php @@ -32,7 +32,7 @@ public function __toString() } /** - * Convert to GeoJson LineString that is jsonable to GeoJSON + * Convert to GeoJson LineString that is jsonable to GeoJSON. * * @return \GeoJson\Geometry\LineString */ diff --git a/src/Types/MultiLineString.php b/src/Types/MultiLineString.php index f4eee47e..b3172199 100644 --- a/src/Types/MultiLineString.php +++ b/src/Types/MultiLineString.php @@ -65,7 +65,7 @@ public function count() } /** - * Convert to GeoJson Point that is jsonable to GeoJSON + * Convert to GeoJson Point that is jsonable to GeoJSON. * * @return \GeoJson\Geometry\MultiLineString */ diff --git a/src/Types/MultiPoint.php b/src/Types/MultiPoint.php index 510408a5..8ed5d9d5 100644 --- a/src/Types/MultiPoint.php +++ b/src/Types/MultiPoint.php @@ -40,7 +40,7 @@ public function __toString() } /** - * Convert to GeoJson MultiPoint that is jsonable to GeoJSON + * Convert to GeoJson MultiPoint that is jsonable to GeoJSON. * * @return \GeoJson\Geometry\MultiPoint */ diff --git a/src/Types/MultiPolygon.php b/src/Types/MultiPolygon.php index 0b83b0d6..1763de8c 100644 --- a/src/Types/MultiPolygon.php +++ b/src/Types/MultiPolygon.php @@ -51,13 +51,14 @@ public static function fromString($wktArgument) /** * (PHP 5 >= 5.1.0)
- * Count elements of an object + * Count elements of an object. * * @link http://php.net/manual/en/countable.count.php + * * @return int The custom count as an integer. - *

- *

- * The return value is cast to an integer. + *

+ *

+ * The return value is cast to an integer. */ public function count() { @@ -65,7 +66,7 @@ public function count() } /** - * Get the polygons that make up this MultiPolygon + * Get the polygons that make up this MultiPolygon. * * @return array|Polygon[] */ @@ -80,7 +81,7 @@ public function getPolygons() * ")), ((", * "-1 -1,-1 -2,-2 -2,-2 -1,-1 -1", * ")), ((", - * "-1 -1,-1 -2,-2 -2,-2 -1,-1 -1))" + * "-1 -1,-1 -2,-2 -2,-2 -1,-1 -1))". * * Into: * "((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1))", @@ -88,6 +89,7 @@ public function getPolygons() * "((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1))" * * @param array $parts + * * @return array */ protected static function assembleParts(array $parts) @@ -109,7 +111,7 @@ protected static function assembleParts(array $parts) } /** - * Convert to GeoJson MultiPolygon that is jsonable to GeoJSON + * Convert to GeoJson MultiPolygon that is jsonable to GeoJSON. * * @return \GeoJson\Geometry\MultiPolygon */ diff --git a/src/Types/Point.php b/src/Types/Point.php index d01b81de..6e8eb44f 100644 --- a/src/Types/Point.php +++ b/src/Types/Point.php @@ -62,7 +62,7 @@ public function __toString() } /** - * Convert to GeoJson Point that is jsonable to GeoJSON + * Convert to GeoJson Point that is jsonable to GeoJSON. * * @return \GeoJson\Geometry\Point */ @@ -70,4 +70,4 @@ public function jsonSerialize() { return new \GeoJson\Geometry\Point([$this->getLng(), $this->getLat()]); } -} \ No newline at end of file +} diff --git a/src/Types/PointCollection.php b/src/Types/PointCollection.php index 07d15fe9..376b0d63 100755 --- a/src/Types/PointCollection.php +++ b/src/Types/PointCollection.php @@ -77,6 +77,7 @@ public function offsetExists($offset) /** * @param mixed $offset + * * @return null|Point */ public function offsetGet($offset) @@ -86,7 +87,7 @@ public function offsetGet($offset) public function offsetSet($offset, $value) { - if (! ($value instanceof Point)) { + if (!($value instanceof Point)) { throw new InvalidArgumentException('$value must be an instance of Point'); } diff --git a/src/Types/Polygon.php b/src/Types/Polygon.php index e863ce32..70df6a3a 100644 --- a/src/Types/Polygon.php +++ b/src/Types/Polygon.php @@ -12,7 +12,7 @@ public function toWKT() } /** - * Convert to GeoJson Polygon that is jsonable to GeoJSON + * Convert to GeoJson Polygon that is jsonable to GeoJSON. * * @return \GeoJson\Geometry\Polygon */ diff --git a/tests/Integration/Migrations/CreateTables.php b/tests/Integration/Migrations/CreateTables.php index e70d2b24..93f08704 100644 --- a/tests/Integration/Migrations/CreateTables.php +++ b/tests/Integration/Migrations/CreateTables.php @@ -42,4 +42,4 @@ public function down() Schema::drop('geometry'); Schema::drop('no_spatial_fields'); } -} \ No newline at end of file +} diff --git a/tests/Integration/Migrations/UpdateTables.php b/tests/Integration/Migrations/UpdateTables.php index 7ca73e87..a00ac00e 100644 --- a/tests/Integration/Migrations/UpdateTables.php +++ b/tests/Integration/Migrations/UpdateTables.php @@ -50,4 +50,4 @@ public function down() $table->point('location')->nullable()->change(); }); } -} \ No newline at end of file +} diff --git a/tests/Integration/Models/GeometryModel.php b/tests/Integration/Models/GeometryModel.php index c6a40dd9..0b08186a 100644 --- a/tests/Integration/Models/GeometryModel.php +++ b/tests/Integration/Models/GeometryModel.php @@ -1,4 +1,5 @@ register(SpatialServiceProvider::class); $app->make('Illuminate\Contracts\Console\Kernel')->bootstrap(); @@ -42,14 +43,14 @@ public function setUp() parent::setUp(); $this->onMigrations(function ($migrationClass) { - (new $migrationClass)->up(); + (new $migrationClass())->up(); }); } public function tearDown() { $this->onMigrations(function ($migrationClass) { - (new $migrationClass)->down(); + (new $migrationClass())->down(); }, true); parent::tearDown(); @@ -69,7 +70,7 @@ private function onMigrations(\Closure $closure, $reverse_sort = false) $fileSystem = new Filesystem(); $classFinder = new Tools\ClassFinder(); - $migrations = $fileSystem->files(__DIR__ . "/Migrations"); + $migrations = $fileSystem->files(__DIR__.'/Migrations'); $reverse_sort ? rsort($migrations, SORT_STRING) : sort($migrations, SORT_STRING); foreach ($migrations as $file) { @@ -80,14 +81,14 @@ private function onMigrations(\Closure $closure, $reverse_sort = false) } } - public function testSpatialFieldsNotDefinedException() { + public function testSpatialFieldsNotDefinedException() + { $geo = new NoSpatialFieldsModel(); $geo->geometry = new Point(1, 2); $geo->save(); $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\SpatialFieldsNotDefinedException::class); NoSpatialFieldsModel::all(); - } public function testInsertPoint() @@ -113,7 +114,7 @@ public function testInsertPolygon() $geo = new GeometryModel(); $geo->location = new Point(1, 2); - $geo->shape = Polygon::fromWKT("POLYGON((0 10,10 10,10 0,0 0,0 10))"); + $geo->shape = Polygon::fromWKT('POLYGON((0 10,10 10,10 0,0 0,0 10))'); $geo->save(); $this->assertDatabaseHas('geometry', ['id' => $geo->id]); } @@ -135,8 +136,8 @@ public function testInsertMultiPolygon() $geo->location = new Point(1, 2); $geo->multi_shapes = new MultiPolygon([ - Polygon::fromWKT("POLYGON((0 10,10 10,10 0,0 0,0 10))"), - Polygon::fromWKT("POLYGON((0 0,0 5,5 5,5 0,0 0))") + Polygon::fromWKT('POLYGON((0 10,10 10,10 0,0 0,0 10))'), + Polygon::fromWKT('POLYGON((0 0,0 5,5 5,5 0,0 0))'), ]); $geo->save(); $this->assertDatabaseHas('geometry', ['id' => $geo->id]); @@ -149,9 +150,9 @@ public function testInsertGeometryCollection() $geo->location = new Point(1, 2); $geo->multi_geometries = new GeometryCollection([ - Polygon::fromWKT("POLYGON((0 10,10 10,10 0,0 0,0 10))"), - Polygon::fromWKT("POLYGON((0 0,0 5,5 5,5 0,0 0))"), - new Point(0, 0) + Polygon::fromWKT('POLYGON((0 10,10 10,10 0,0 0,0 10))'), + Polygon::fromWKT('POLYGON((0 0,0 5,5 5,5 0,0 0))'), + new Point(0, 0), ]); $geo->save(); $this->assertDatabaseHas('geometry', ['id' => $geo->id]); @@ -201,9 +202,9 @@ public function testDistance() // Excluding self $b = GeometryModel::distance('location', $loc1->location, 2, true)->get(); $this->assertCount(1, $b); - $this->assertFalse($b->contains('location',$loc1->location)); - $this->assertTrue($b->contains('location',$loc2->location)); - $this->assertFalse($b->contains('location',$loc3->location)); + $this->assertFalse($b->contains('location', $loc1->location)); + $this->assertTrue($b->contains('location', $loc2->location)); + $this->assertFalse($b->contains('location', $loc3->location)); $c = GeometryModel::distance('location', $loc1->location, 1)->get(); $this->assertCount(1, $c); @@ -227,4 +228,4 @@ public function testDistanceValue() $this->assertEquals(0, $a[0]->distance); $this->assertEquals(1.4142135623, $a[1]->distance); // PHP floats' 11th+ digits don't matter } -} \ No newline at end of file +} diff --git a/tests/Integration/Tools/ClassFinder.php b/tests/Integration/Tools/ClassFinder.php index 0b545236..13a8263b 100644 --- a/tests/Integration/Tools/ClassFinder.php +++ b/tests/Integration/Tools/ClassFinder.php @@ -1,15 +1,16 @@ tokenIsNamespace($token)) { $namespace = $this->getNamespace($key + 2, $tokens); } elseif ($this->tokenIsClassOrInterface($token)) { - return ltrim($namespace . '\\' . $this->getClass($key + 2, $tokens), '\\'); + return ltrim($namespace.'\\'.$this->getClass($key + 2, $tokens), '\\'); } } } @@ -47,8 +49,9 @@ public function findClass($path) /** * Find the namespace in the tokens starting at a given key. * - * @param int $key - * @param array $tokens + * @param int $key + * @param array $tokens + * * @return string */ protected function getNamespace($key, array $tokens) @@ -69,8 +72,9 @@ protected function getNamespace($key, array $tokens) /** * Find the class in the tokens starting at a given key. * - * @param int $key - * @param array $tokens + * @param int $key + * @param array $tokens + * * @return string */ protected function getClass($key, array $tokens) @@ -91,7 +95,8 @@ protected function getClass($key, array $tokens) /** * Determine if the given token is a namespace keyword. * - * @param array|string $token + * @param array|string $token + * * @return bool */ protected function tokenIsNamespace($token) @@ -102,7 +107,8 @@ protected function tokenIsNamespace($token) /** * Determine if the given token is a class or interface keyword. * - * @param array|string $token + * @param array|string $token + * * @return bool */ protected function tokenIsClassOrInterface($token) @@ -113,7 +119,8 @@ protected function tokenIsClassOrInterface($token) /** * Determine if the given token is part of the namespace. * - * @param array|string $token + * @param array|string $token + * * @return bool */ protected function isPartOfNamespace($token) @@ -124,7 +131,8 @@ protected function isPartOfNamespace($token) /** * Determine if the given token is part of the class. * - * @param array|string $token + * @param array|string $token + * * @return bool */ protected function isPartOfClass($token) @@ -135,12 +143,12 @@ protected function isPartOfClass($token) /** * Determine if the given token is whitespace. * - * @param array|string $token + * @param array|string $token + * * @return bool */ protected function isWhitespace($token) { return is_array($token) && $token[0] == T_WHITESPACE; } - -} \ No newline at end of file +} diff --git a/tests/Unit/Eloquent/BuilderTest.php b/tests/Unit/Eloquent/BuilderTest.php index 21b4ac4a..d770026f 100644 --- a/tests/Unit/Eloquent/BuilderTest.php +++ b/tests/Unit/Eloquent/BuilderTest.php @@ -1,4 +1,6 @@ -assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->columns); - $this->assertContains("*", $q->columns[0]); + $this->assertContains('*', $q->columns[0]); $this->assertInstanceOf(\Illuminate\Database\Query\Expression::class, $q->columns[1]); $this->assertContains("st_distance(`point`, GeomFromText('POINT(2 1)')) as distance", $q->columns[1]->getValue()); } @@ -235,12 +235,13 @@ public function testScopeDistanceValueWithSelect() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->columns); - $this->assertContains("some_column", $q->columns[0]); + $this->assertContains('some_column', $q->columns[0]); $this->assertInstanceOf(\Illuminate\Database\Query\Expression::class, $q->columns[1]); $this->assertContains("st_distance(`point`, GeomFromText('POINT(2 1)')) as distance", $q->columns[1]->getValue()); } - private function buildTestPolygon(){ + private function buildTestPolygon() + { $point1 = new Point(1, 1); $point2 = new Point(1, 2); $linestring1 = new \Grimzy\LaravelMysqlSpatial\Types\LineString([$point1, $point2]); @@ -250,12 +251,13 @@ private function buildTestPolygon(){ $point5 = new Point(2, 2); $point6 = new Point(1, 1); $linestring3 = new \Grimzy\LaravelMysqlSpatial\Types\LineString([$point5, $point6]); + return new \Grimzy\LaravelMysqlSpatial\Types\Polygon([$linestring1, $linestring2, $linestring3]); } public function testScopeComparison() { - $query = TestModel::Comparison('point',$this->buildTestPolygon(),'within'); + $query = TestModel::Comparison('point', $this->buildTestPolygon(), 'within'); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -265,7 +267,7 @@ public function testScopeComparison() public function testScopeWithin() { - $query = TestModel::Within('point',$this->buildTestPolygon()); + $query = TestModel::Within('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -275,7 +277,7 @@ public function testScopeWithin() public function testScopeCrosses() { - $query = TestModel::Crosses('point',$this->buildTestPolygon()); + $query = TestModel::Crosses('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -285,7 +287,7 @@ public function testScopeCrosses() public function testScopeContains() { - $query = TestModel::Contains('point',$this->buildTestPolygon()); + $query = TestModel::Contains('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -295,7 +297,7 @@ public function testScopeContains() public function testScopeDisjoint() { - $query = TestModel::Disjoint('point',$this->buildTestPolygon()); + $query = TestModel::Disjoint('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -305,7 +307,7 @@ public function testScopeDisjoint() public function testScopeEquals() { - $query = TestModel::Equals('point',$this->buildTestPolygon()); + $query = TestModel::Equals('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -315,7 +317,7 @@ public function testScopeEquals() public function testScopeIntersects() { - $query = TestModel::Intersects('point',$this->buildTestPolygon()); + $query = TestModel::Intersects('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -325,7 +327,7 @@ public function testScopeIntersects() public function testScopeOverlaps() { - $query = TestModel::Overlaps('point',$this->buildTestPolygon()); + $query = TestModel::Overlaps('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -335,7 +337,7 @@ public function testScopeOverlaps() public function testScopeDoesTouch() { - $query = TestModel::DoesTouch('point',$this->buildTestPolygon()); + $query = TestModel::DoesTouch('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); diff --git a/tests/Unit/MysqlConnectionTest.php b/tests/Unit/MysqlConnectionTest.php index 463e1404..c630d990 100644 --- a/tests/Unit/MysqlConnectionTest.php +++ b/tests/Unit/MysqlConnectionTest.php @@ -20,4 +20,4 @@ public function testGetSchemaBuilder() $this->assertInstanceOf(Builder::class, $builder); } -} \ No newline at end of file +} diff --git a/tests/Unit/Schema/BlueprintTest.php b/tests/Unit/Schema/BlueprintTest.php index f61cf8ed..41dac43d 100644 --- a/tests/Unit/Schema/BlueprintTest.php +++ b/tests/Unit/Schema/BlueprintTest.php @@ -1,9 +1,10 @@ blueprint->geometrycollection('col'); } - - } diff --git a/tests/Unit/Schema/BuilderTest.php b/tests/Unit/Schema/BuilderTest.php index 0a9869a3..27371d09 100644 --- a/tests/Unit/Schema/BuilderTest.php +++ b/tests/Unit/Schema/BuilderTest.php @@ -1,10 +1,11 @@ collection = new GeometryCollection([$collection, $point]); } - public function testFromWKT() { /** - * @var GeometryCollection $geometryCollection + * @var GeometryCollection */ $geometryCollection = GeometryCollection::fromWKT('GEOMETRYCOLLECTION(POINT(2 3),LINESTRING(2 3,3 4))'); $this->assertInstanceOf(GeometryCollection::class, $geometryCollection); @@ -61,6 +60,5 @@ public function testJsonSerialize() '{"type":"GeometryCollection","geometries":[{"type":"LineString","coordinates":[[0,0],[1,0],[1,1],[0,1],[0,0]]},{"type":"Point","coordinates":[200,100]}]}', json_encode($this->collection->jsonSerialize()) ); - } } diff --git a/tests/Unit/Types/LineStringTest.php b/tests/Unit/Types/LineStringTest.php index 465a66dd..6d73d422 100644 --- a/tests/Unit/Types/LineStringTest.php +++ b/tests/Unit/Types/LineStringTest.php @@ -31,7 +31,7 @@ public function testToString() { $linestring = new LineString($this->points); - $this->assertEquals('0 0,1 1,2 2', (string)$linestring); + $this->assertEquals('0 0,1 1,2 2', (string) $linestring); } public function testJsonSerialize() diff --git a/tests/Unit/Types/MultiLineStringTest.php b/tests/Unit/Types/MultiLineStringTest.php index 90382175..ed1f0be8 100644 --- a/tests/Unit/Types/MultiLineStringTest.php +++ b/tests/Unit/Types/MultiLineStringTest.php @@ -1,8 +1,8 @@ multiPolygon = new MultiPolygon([$polygon1, $polygon2]); @@ -62,7 +61,6 @@ public function testFromWKT() $this->assertEquals(2, $polygon->count()); } - public function testToWKT() { $this->assertEquals( diff --git a/tests/Unit/Types/PointTest.php b/tests/Unit/Types/PointTest.php index ece13c3f..576dc039 100644 --- a/tests/Unit/Types/PointTest.php +++ b/tests/Unit/Types/PointTest.php @@ -50,7 +50,7 @@ public function testToString() $this->assertSame(1.3, $point->getLng()); $this->assertSame(2.0, $point->getLat()); - $this->assertEquals('1.3 2', (string)$point); + $this->assertEquals('1.3 2', (string) $point); } public function testJsonSerialize() diff --git a/tests/Unit/Types/PolygonTest.php b/tests/Unit/Types/PolygonTest.php index 064332a7..16c6f248 100644 --- a/tests/Unit/Types/PolygonTest.php +++ b/tests/Unit/Types/PolygonTest.php @@ -16,14 +16,13 @@ protected function setUp() new Point(0, 1), new Point(1, 1), new Point(1, 0), - new Point(0, 0) + new Point(0, 0), ] ); $this->polygon = new Polygon([$collection]); } - public function testFromWKT() { $polygon = Polygon::fromWKT('POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))'); @@ -44,6 +43,5 @@ public function testJsonSerialize() '{"type":"Polygon","coordinates":[[[0,0],[1,0],[1,1],[0,1],[0,0]]]}', json_encode($this->polygon) ); - } } From f841bf194aa1dbb2bee669d42bbee63eca4a2634 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sat, 26 Aug 2017 00:58:12 -0400 Subject: [PATCH 08/57] Added documentation. Updated readme. Updated composer.json. --- README.md | 48 ++++++++++++++++++++---- composer.json | 2 +- src/Eloquent/SpatialTrait.php | 17 +++++++++ tests/Unit/Eloquent/SpatialTraitTest.php | 24 ++++++------ 4 files changed, 70 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index f3ff7f06..34be89ba 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,11 @@ Laravel package to easily work with [MySQL Spatial Data Types](https://dev.mysql Please check the documentation for your MySQL version. MySQL's Extension for Spatial Data was added in MySQL 5.5 but many Spatial Functions were changed in 5.6 and 5.7. +**Versions** + +- `1.x.x`: MySQL 5.6 (also supports MySQL 5.5 but not all spatial analysis functions) +- `2.x.x`: MySQL 5.7 and 8.0 + ## Installation Add the package using composer: @@ -19,6 +24,12 @@ Add the package using composer: composer require grimzy/laravel-mysql-spatial ``` +For MySQL 5.6 and 5.5: + +```shell +composer require grimzy/laravel-mysql-spatial:^1.0 +``` + Register the service provider in `config/app.php`: ```php @@ -211,14 +222,35 @@ class UpdatePlacesTable extends Migration Available geometry classes: -- Point -- LineString -- Polygon -- MultiPoint -- MultiLineString -- MultiPolygon -- GeometryCollection - +- `Point($lat, $lng)` +- `MultiPoint(Point[])` +- `LineString(Point[])` +- `MultiLineString(LineString[])` +- `Polygon(LineString[])` +- `MultiPolygon(Polygon[])` +- `GeometryCollection(Geometry[])` *(a collection of spatial models)* + +## Scopes: Spatial analysis functions + +Spatial analysis functions are implemented using [Eloquent Local Scopes](https://laravel.com/docs/5.4/eloquent#local-scopes). + +Available scopes: + +- `distance($geometryColumn, $geometry, $distance)` +- `distanceExcludingSelf($geometryColumn, $geometry, $distance)` +- `distanceSphere($geometryColumn, $geometry, $distance)` +- `distanceSphereExcludingSelf($geometryColumn, $geometry, $distance)` +- `comparison($geometryColumn, $geometry, $relationship)` +- `within($geometryColumn, $polygon)` +- `crosses($geometryColumn, $geometry)` +- `contains($geometryColumn, $geometry)` +- `disjoint($geometryColumn, $geometry)` +- `equals($geometryColumn, $geometry)` +- `intersects($geometryColumn, $geometry)` +- `overlaps($geometryColumn, $geometry)` +- `touches($geometryColumn, $geometry)` + +*Note that behavior and availability of MySQL spatial analysis functions differs in each MySQL version (cf. [documentation](https://dev.mysql.com/doc/refman/5.7/en/spatial-function-reference.html)).* ## Credits diff --git a/composer.json b/composer.json index 4395d37d..958f2416 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-mysql-5.6": "1.0.x-dev" } } } diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index a80edd51..d332e161 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -7,6 +7,23 @@ use Grimzy\LaravelMysqlSpatial\Types\GeometryInterface; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; +/** + * Trait SpatialTrait + * + * @method static distance($geometryColumn, $geometry, $distance) + * @method static distanceExcludingSelf($geometryColumn, $geometry, $distance) + * @method static distanceSphere($geometryColumn, $geometry, $distance) + * @method static distanceSphereExcludingSelf($geometryColumn, $geometry, $distance) + * @method static comparison($geometryColumn, $geometry, $relationship) + * @method static within($geometryColumn, $polygon) + * @method static crosses($geometryColumn, $geometry) + * @method static contains($geometryColumn, $geometry) + * @method static disjoint($geometryColumn, $geometry) + * @method static equals($geometryColumn, $geometry) + * @method static intersects($geometryColumn, $geometry) + * @method static overlaps($geometryColumn, $geometry) + * @method static touches($geometryColumn, $geometry) + */ trait SpatialTrait { /* diff --git a/tests/Unit/Eloquent/SpatialTraitTest.php b/tests/Unit/Eloquent/SpatialTraitTest.php index 07c5ed55..b67a9695 100644 --- a/tests/Unit/Eloquent/SpatialTraitTest.php +++ b/tests/Unit/Eloquent/SpatialTraitTest.php @@ -194,7 +194,7 @@ public function testInsertUpdateGeometryCollectionHasCorrectSql() public function testScopeDistance() { $point = new Point(1, 2); - $query = TestModel::Distance('point', $point, 10); + $query = TestModel::distance('point', $point, 10); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -205,7 +205,7 @@ public function testScopeDistance() public function testScopeDistanceExcludingSelf() { $point = new Point(1, 2); - $query = TestModel::Distance('point', $point, 10, true); + $query = TestModel::distance('point', $point, 10, true); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -217,7 +217,7 @@ public function testScopeDistanceExcludingSelf() public function testScopeDistanceValue() { $point = new Point(1, 2); - $query = TestModel::DistanceValue('point', $point); + $query = TestModel::distanceValue('point', $point); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -257,7 +257,7 @@ private function buildTestPolygon() public function testScopeComparison() { - $query = TestModel::Comparison('point', $this->buildTestPolygon(), 'within'); + $query = TestModel::comparison('point', $this->buildTestPolygon(), 'within'); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -267,7 +267,7 @@ public function testScopeComparison() public function testScopeWithin() { - $query = TestModel::Within('point', $this->buildTestPolygon()); + $query = TestModel::within('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -277,7 +277,7 @@ public function testScopeWithin() public function testScopeCrosses() { - $query = TestModel::Crosses('point', $this->buildTestPolygon()); + $query = TestModel::crosses('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -287,7 +287,7 @@ public function testScopeCrosses() public function testScopeContains() { - $query = TestModel::Contains('point', $this->buildTestPolygon()); + $query = TestModel::contains('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -297,7 +297,7 @@ public function testScopeContains() public function testScopeDisjoint() { - $query = TestModel::Disjoint('point', $this->buildTestPolygon()); + $query = TestModel::disjoint('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -307,7 +307,7 @@ public function testScopeDisjoint() public function testScopeEquals() { - $query = TestModel::Equals('point', $this->buildTestPolygon()); + $query = TestModel::equals('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -317,7 +317,7 @@ public function testScopeEquals() public function testScopeIntersects() { - $query = TestModel::Intersects('point', $this->buildTestPolygon()); + $query = TestModel::intersects('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -327,7 +327,7 @@ public function testScopeIntersects() public function testScopeOverlaps() { - $query = TestModel::Overlaps('point', $this->buildTestPolygon()); + $query = TestModel::overlaps('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); @@ -337,7 +337,7 @@ public function testScopeOverlaps() public function testScopeDoesTouch() { - $query = TestModel::DoesTouch('point', $this->buildTestPolygon()); + $query = TestModel::doesTouch('point', $this->buildTestPolygon()); $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); From 82e70175a0f8513a74d614b1fbdbcceed7fe3a97 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sat, 26 Aug 2017 01:05:58 -0400 Subject: [PATCH 09/57] Minor typos. --- src/Eloquent/SpatialTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index d332e161..dcb86a3a 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -8,7 +8,7 @@ use Illuminate\Database\Eloquent\Builder as EloquentBuilder; /** - * Trait SpatialTrait + * Trait SpatialTrait. * * @method static distance($geometryColumn, $geometry, $distance) * @method static distanceExcludingSelf($geometryColumn, $geometry, $distance) From 52c700cad473396832ea3ad043a771ed0b5f0447 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sat, 26 Aug 2017 17:54:38 -0400 Subject: [PATCH 10/57] Minor typos. --- README.md | 2 +- src/Eloquent/SpatialTrait.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 34be89ba..207da6fc 100644 --- a/README.md +++ b/README.md @@ -248,7 +248,7 @@ Available scopes: - `equals($geometryColumn, $geometry)` - `intersects($geometryColumn, $geometry)` - `overlaps($geometryColumn, $geometry)` -- `touches($geometryColumn, $geometry)` +- `doesTouch($geometryColumn, $geometry)` *Note that behavior and availability of MySQL spatial analysis functions differs in each MySQL version (cf. [documentation](https://dev.mysql.com/doc/refman/5.7/en/spatial-function-reference.html)).* diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index dcb86a3a..649e2602 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -22,7 +22,7 @@ * @method static equals($geometryColumn, $geometry) * @method static intersects($geometryColumn, $geometry) * @method static overlaps($geometryColumn, $geometry) - * @method static touches($geometryColumn, $geometry) + * @method static doesTouch($geometryColumn, $geometry) */ trait SpatialTrait { From 062000315ca0960a1d1e6d238dec45b08dcda0b3 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 3 Sep 2017 13:07:45 -0400 Subject: [PATCH 11/57] Fixed testing dependencies --- composer.json | 5 +++-- tests/Integration/SpatialTest.php | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 958f2416..94c6e3e5 100644 --- a/composer.json +++ b/composer.json @@ -16,11 +16,12 @@ "jmikola/geojson": "^1.0" }, "require-dev": { - "phpunit/phpunit": "~4.8", + "phpunit/phpunit": "~4.8||~5.7", "mockery/mockery": "^0.9.9", "laravel/laravel": "^5.2", "codeclimate/php-test-reporter": "dev-master", - "doctrine/dbal": "^2.5" + "doctrine/dbal": "^2.5", + "laravel/browser-kit-testing": "^2.0" }, "autoload": { "psr-4": { diff --git a/tests/Integration/SpatialTest.php b/tests/Integration/SpatialTest.php index ab1f04a9..d89f6d4c 100644 --- a/tests/Integration/SpatialTest.php +++ b/tests/Integration/SpatialTest.php @@ -8,9 +8,9 @@ use Grimzy\LaravelMysqlSpatial\Types\Point; use Grimzy\LaravelMysqlSpatial\Types\Polygon; use Illuminate\Filesystem\Filesystem; -use Illuminate\Foundation\Testing\TestCase; +use Laravel\BrowserKitTesting\TestCase as BaseTestCase; -class SpatialTest extends TestCase +class SpatialTest extends BaseTestCase { /** * Boots the application. From 2848788f0f486f244da1da156032d2931d7531ff Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 3 Sep 2017 13:17:21 -0400 Subject: [PATCH 12/57] Add Laravel 5.5 Service Provider auto-discovery (patch from a-komarev 4d8d3e7c794e5c56ef441c252e46f23ecdb0198b) --- composer.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/composer.json b/composer.json index 94c6e3e5..8947186e 100644 --- a/composer.json +++ b/composer.json @@ -37,6 +37,11 @@ "extra": { "branch-alias": { "dev-mysql-5.6": "1.0.x-dev" + }, + "laravel": { + "providers": [ + "Grimzy\\LaravelMysqlSpatial\\SpatialServiceProvider" + ] } } } From 18118331e09bad69b3229b9c90e3f948eb177c0c Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 3 Sep 2017 13:41:20 -0400 Subject: [PATCH 13/57] Updated install instructions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 207da6fc..d64d62df 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ For MySQL 5.6 and 5.5: composer require grimzy/laravel-mysql-spatial:^1.0 ``` -Register the service provider in `config/app.php`: +For Laravel versions before 5.5 or if not using auto-discovery, register the service provider in `config/app.php`: ```php 'providers' => [ From 56287fbe1629f81a924b8e916960f524fff84a25 Mon Sep 17 00:00:00 2001 From: a-komarev Date: Tue, 5 Sep 2017 12:19:11 -0400 Subject: [PATCH 14/57] Class name resolution via ::class (cherry picked from commit 13d56c0) --- src/SpatialServiceProvider.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/SpatialServiceProvider.php b/src/SpatialServiceProvider.php index 89100de6..e1f185ae 100644 --- a/src/SpatialServiceProvider.php +++ b/src/SpatialServiceProvider.php @@ -35,14 +35,14 @@ public function register() if (class_exists('Doctrine\DBAL\Types\Type')) { // Prevent geometry type fields from throwing a 'type not found' error when changing them $geometries = [ - 'geometry' => "Grimzy\LaravelMysqlSpatial\Doctrine\Geometry", - 'point' => "Grimzy\LaravelMysqlSpatial\Doctrine\Point", - 'linestring' => "Grimzy\LaravelMysqlSpatial\Doctrine\LineString", - 'polygon' => "Grimzy\LaravelMysqlSpatial\Doctrine\Polygon", - 'multipoint' => "Grimzy\LaravelMysqlSpatial\Doctrine\MultiPoint", - 'multilinestring' => "Grimzy\LaravelMysqlSpatial\Doctrine\MultiLineString", - 'multipolygon' => "Grimzy\LaravelMysqlSpatial\Doctrine\MultiPolygon", - 'geometrycollection' => "Grimzy\LaravelMysqlSpatial\Doctrine\GeometryCollection", + 'geometry' => \Grimzy\LaravelMysqlSpatial\Doctrine\Geometry::class, + 'point' => \Grimzy\LaravelMysqlSpatial\Doctrine\Point::class, + 'linestring' => \Grimzy\LaravelMysqlSpatial\Doctrine\LineString::class, + 'polygon' => \Grimzy\LaravelMysqlSpatial\Doctrine\Polygon::class, + 'multipoint' => \Grimzy\LaravelMysqlSpatial\Doctrine\MultiPoint::class, + 'multilinestring' => \Grimzy\LaravelMysqlSpatial\Doctrine\MultiLineString::class, + 'multipolygon' => \Grimzy\LaravelMysqlSpatial\Doctrine\MultiPolygon::class, + 'geometrycollection' => \Grimzy\LaravelMysqlSpatial\Doctrine\GeometryCollection::class, ]; $typeNames = array_keys(\Doctrine\DBAL\Types\Type::getTypesMap()); foreach ($geometries as $type => $class) { From 86e46ed0c1ce5b87f9f4f50ad1cd6dc13e998789 Mon Sep 17 00:00:00 2001 From: a-komarev Date: Tue, 5 Sep 2017 21:03:24 -0400 Subject: [PATCH 15/57] Import fully qualified class names (cherry picked from commit 2f2cf36) --- src/Connectors/ConnectionFactory.php | 3 ++- src/MysqlConnection.php | 18 ++++++++++++---- src/Schema/Blueprint.php | 4 +++- src/Schema/Grammars/MySqlGrammar.php | 3 ++- src/SpatialServiceProvider.php | 31 ++++++++++++++++++---------- 5 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/Connectors/ConnectionFactory.php b/src/Connectors/ConnectionFactory.php index ada8b7f7..223cea13 100644 --- a/src/Connectors/ConnectionFactory.php +++ b/src/Connectors/ConnectionFactory.php @@ -3,9 +3,10 @@ namespace Grimzy\LaravelMysqlSpatial\Connectors; use Grimzy\LaravelMysqlSpatial\MysqlConnection; +use Illuminate\Database\Connectors\ConnectionFactory as IlluminateConnectionFactory; use PDO; -class ConnectionFactory extends \Illuminate\Database\Connectors\ConnectionFactory +class ConnectionFactory extends IlluminateConnectionFactory { /** * @param string $driver diff --git a/src/MysqlConnection.php b/src/MysqlConnection.php index 62b220bd..ae159f41 100644 --- a/src/MysqlConnection.php +++ b/src/MysqlConnection.php @@ -2,13 +2,18 @@ namespace Grimzy\LaravelMysqlSpatial; -class MysqlConnection extends \Illuminate\Database\MySqlConnection +use Doctrine\DBAL\Types\Type as DoctrineType; +use Grimzy\LaravelMysqlSpatial\Schema\Builder; +use Grimzy\LaravelMysqlSpatial\Schema\Grammars\MySqlGrammar; +use Illuminate\Database\MySqlConnection as IlluminateMySqlConnection; + +class MysqlConnection extends IlluminateMySqlConnection { public function __construct($pdo, $database = '', $tablePrefix = '', array $config = []) { parent::__construct($pdo, $database, $tablePrefix, $config); - if (class_exists('Doctrine\DBAL\Types\Type')) { + if (class_exists(DoctrineType::class)) { // Prevent geometry type fields from throwing a 'type not found' error when changing them $geometries = [ 'geometry', @@ -34,15 +39,20 @@ public function __construct($pdo, $database = '', $tablePrefix = '', array $conf */ protected function getDefaultSchemaGrammar() { - return $this->withTablePrefix(new Schema\Grammars\MySqlGrammar()); + return $this->withTablePrefix(new MySqlGrammar); } + /** + * Get a schema builder instance for the connection. + * + * @return \Illuminate\Database\Schema\MySqlBuilder + */ public function getSchemaBuilder() { if (is_null($this->schemaGrammar)) { $this->useDefaultSchemaGrammar(); } - return new Schema\Builder($this); + return new Builder($this); } } diff --git a/src/Schema/Blueprint.php b/src/Schema/Blueprint.php index fb200a2b..f0945f4d 100644 --- a/src/Schema/Blueprint.php +++ b/src/Schema/Blueprint.php @@ -2,7 +2,9 @@ namespace Grimzy\LaravelMysqlSpatial\Schema; -class Blueprint extends \Illuminate\Database\Schema\Blueprint +use Illuminate\Database\Schema\Blueprint as IlluminateBlueprint; + +class Blueprint extends IlluminateBlueprint { /** * Add a geometry column on the table. diff --git a/src/Schema/Grammars/MySqlGrammar.php b/src/Schema/Grammars/MySqlGrammar.php index a904aa51..61f015d1 100644 --- a/src/Schema/Grammars/MySqlGrammar.php +++ b/src/Schema/Grammars/MySqlGrammar.php @@ -3,9 +3,10 @@ namespace Grimzy\LaravelMysqlSpatial\Schema\Grammars; use Grimzy\LaravelMysqlSpatial\Schema\Blueprint; +use Illuminate\Database\Schema\Grammars\MySqlGrammar as IlluminateMySqlGrammar; use Illuminate\Support\Fluent; -class MySqlGrammar extends \Illuminate\Database\Schema\Grammars\MySqlGrammar +class MySqlGrammar extends IlluminateMySqlGrammar { /** * Adds a statement to add a geometry column. diff --git a/src/SpatialServiceProvider.php b/src/SpatialServiceProvider.php index e1f185ae..3b859f8e 100644 --- a/src/SpatialServiceProvider.php +++ b/src/SpatialServiceProvider.php @@ -2,7 +2,16 @@ namespace Grimzy\LaravelMysqlSpatial; +use Doctrine\DBAL\Types\Type as DoctrineType; use Grimzy\LaravelMysqlSpatial\Connectors\ConnectionFactory; +use Grimzy\LaravelMysqlSpatial\Doctrine\Geometry; +use Grimzy\LaravelMysqlSpatial\Doctrine\GeometryCollection; +use Grimzy\LaravelMysqlSpatial\Doctrine\LineString; +use Grimzy\LaravelMysqlSpatial\Doctrine\MultiLineString; +use Grimzy\LaravelMysqlSpatial\Doctrine\MultiPoint; +use Grimzy\LaravelMysqlSpatial\Doctrine\MultiPolygon; +use Grimzy\LaravelMysqlSpatial\Doctrine\Point; +use Grimzy\LaravelMysqlSpatial\Doctrine\Polygon; use Illuminate\Database\DatabaseManager; use Illuminate\Database\DatabaseServiceProvider; @@ -32,22 +41,22 @@ public function register() return new DatabaseManager($app, $app['db.factory']); }); - if (class_exists('Doctrine\DBAL\Types\Type')) { + if (class_exists(DoctrineType::class)) { // Prevent geometry type fields from throwing a 'type not found' error when changing them $geometries = [ - 'geometry' => \Grimzy\LaravelMysqlSpatial\Doctrine\Geometry::class, - 'point' => \Grimzy\LaravelMysqlSpatial\Doctrine\Point::class, - 'linestring' => \Grimzy\LaravelMysqlSpatial\Doctrine\LineString::class, - 'polygon' => \Grimzy\LaravelMysqlSpatial\Doctrine\Polygon::class, - 'multipoint' => \Grimzy\LaravelMysqlSpatial\Doctrine\MultiPoint::class, - 'multilinestring' => \Grimzy\LaravelMysqlSpatial\Doctrine\MultiLineString::class, - 'multipolygon' => \Grimzy\LaravelMysqlSpatial\Doctrine\MultiPolygon::class, - 'geometrycollection' => \Grimzy\LaravelMysqlSpatial\Doctrine\GeometryCollection::class, + 'geometry' => Geometry::class, + 'point' => Point::class, + 'linestring' => LineString::class, + 'polygon' => Polygon::class, + 'multipoint' => MultiPoint::class, + 'multilinestring' => MultiLineString::class, + 'multipolygon' => MultiPolygon::class, + 'geometrycollection' => GeometryCollection::class, ]; - $typeNames = array_keys(\Doctrine\DBAL\Types\Type::getTypesMap()); + $typeNames = array_keys(DoctrineType::getTypesMap()); foreach ($geometries as $type => $class) { if (!in_array($type, $typeNames)) { - \Doctrine\DBAL\Types\Type::addType($type, $class); + DoctrineType::addType($type, $class); } } } From ddaa86a0112ac295860bb5a9a692b1918f4d0f58 Mon Sep 17 00:00:00 2001 From: a-komarev Date: Tue, 5 Sep 2017 21:07:49 -0400 Subject: [PATCH 16/57] Return parentheses back to fix code style warning. (cherry picked from commit d9e9686) --- src/MysqlConnection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MysqlConnection.php b/src/MysqlConnection.php index ae159f41..320dc270 100644 --- a/src/MysqlConnection.php +++ b/src/MysqlConnection.php @@ -39,7 +39,7 @@ public function __construct($pdo, $database = '', $tablePrefix = '', array $conf */ protected function getDefaultSchemaGrammar() { - return $this->withTablePrefix(new MySqlGrammar); + return $this->withTablePrefix(new MySqlGrammar()); } /** From 8e21b14fc0074d0da7dfaa5ba4b63fd494b18f00 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sat, 9 Sep 2017 12:26:00 -0400 Subject: [PATCH 17/57] Added migration update geometry field test. (cherry picked from commit 34d172c) --- tests/Integration/Migrations/UpdateTables.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Integration/Migrations/UpdateTables.php b/tests/Integration/Migrations/UpdateTables.php index a00ac00e..46ebaccc 100644 --- a/tests/Integration/Migrations/UpdateTables.php +++ b/tests/Integration/Migrations/UpdateTables.php @@ -21,6 +21,7 @@ public function up() $table->point('location')->change(); // The other field changes are just here to test if change works with them, we're not changing anything + $table->geometry('geo')->default(null)->nullable()->change(); $table->lineString('line')->default(null)->nullable()->change(); $table->polygon('shape')->default(null)->nullable()->change(); $table->multiPoint('multi_locations')->default(null)->nullable()->change(); From fe4aaaf970f1a2e5fc37aa970c5bc206066a4d02 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sat, 9 Sep 2017 12:27:23 -0400 Subject: [PATCH 18/57] Testing for UnknownWKTTypeException. Replaced deprecated PhpUnit method. (cherry picked from commit bb9ded4) --- tests/Integration/SpatialTest.php | 2 +- tests/Unit/Types/GeometryTest.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/Integration/SpatialTest.php b/tests/Integration/SpatialTest.php index d89f6d4c..b333fe11 100644 --- a/tests/Integration/SpatialTest.php +++ b/tests/Integration/SpatialTest.php @@ -87,7 +87,7 @@ public function testSpatialFieldsNotDefinedException() $geo->geometry = new Point(1, 2); $geo->save(); - $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\SpatialFieldsNotDefinedException::class); + $this->expectException(\Grimzy\LaravelMysqlSpatial\Exceptions\SpatialFieldsNotDefinedException::class); NoSpatialFieldsModel::all(); } diff --git a/tests/Unit/Types/GeometryTest.php b/tests/Unit/Types/GeometryTest.php index 0c112e2c..f5043fa5 100644 --- a/tests/Unit/Types/GeometryTest.php +++ b/tests/Unit/Types/GeometryTest.php @@ -1,5 +1,6 @@ expectException(UnknownWKTTypeException::class); + Geometry::getWKTClass('TRIANGLE((0 0, 0 9, 9 0, 0 0))'); } public function testGetWKBClass() From 6cf74015cf5e7e85abd40ed1df7961140ae90815 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sat, 9 Sep 2017 15:29:20 -0400 Subject: [PATCH 19/57] Fixed exception messages. Removed useless return when creating multipoint. (cherry picked from commit 384f012) --- src/Types/MultiLineString.php | 2 +- src/Types/MultiPoint.php | 4 ---- src/Types/MultiPolygon.php | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Types/MultiLineString.php b/src/Types/MultiLineString.php index b3172199..2c6e8945 100644 --- a/src/Types/MultiLineString.php +++ b/src/Types/MultiLineString.php @@ -26,7 +26,7 @@ public function __construct(array $linestrings) }); if (count($linestrings) !== count($validated)) { - throw new InvalidArgumentException('$linestrings must be an array of Points'); + throw new InvalidArgumentException('$linestrings must be an array of LineString'); } $this->linestrings = $linestrings; diff --git a/src/Types/MultiPoint.php b/src/Types/MultiPoint.php index 8ed5d9d5..b3993605 100644 --- a/src/Types/MultiPoint.php +++ b/src/Types/MultiPoint.php @@ -21,10 +21,6 @@ public static function fromString($wktArgument) $matches = []; preg_match_all('/\(\s*(\d+\s+\d+)\s*\)/', trim($wktArgument), $matches); - if (count($matches) < 2) { - return new static([]); - } - $points = array_map(function ($pair) { return Point::fromPair($pair); }, $matches[1]); diff --git a/src/Types/MultiPolygon.php b/src/Types/MultiPolygon.php index 1763de8c..45339966 100644 --- a/src/Types/MultiPolygon.php +++ b/src/Types/MultiPolygon.php @@ -22,7 +22,7 @@ public function __construct(array $polygons) }); if (count($polygons) !== count($validated)) { - throw new InvalidArgumentException('$polygons must be an array of Points'); + throw new InvalidArgumentException('$polygons must be an array of Polygon'); } $this->polygons = $polygons; } From 3d2ae93c8cc9a0403776e77b55f8834645d23a52 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sat, 9 Sep 2017 15:34:46 -0400 Subject: [PATCH 20/57] Refactored and added some missing tests (cherry picked from commit 7af87a7) --- tests/Unit/Types/GeometryCollectionTest.php | 56 ++++++----- tests/Unit/Types/GeometryTest.php | 7 ++ tests/Unit/Types/MultiLineStringTest.php | 13 +++ tests/Unit/Types/MultiPointTest.php | 39 +++++++ tests/Unit/Types/MultiPolygonTest.php | 106 +++++++++++--------- 5 files changed, 149 insertions(+), 72 deletions(-) diff --git a/tests/Unit/Types/GeometryCollectionTest.php b/tests/Unit/Types/GeometryCollectionTest.php index f915d920..6ec8164e 100644 --- a/tests/Unit/Types/GeometryCollectionTest.php +++ b/tests/Unit/Types/GeometryCollectionTest.php @@ -6,28 +6,6 @@ class GeometryCollectionTest extends BaseTestCase { - /** - * @var GeometryCollection - */ - private $collection; - - protected function setUp() - { - $collection = new LineString( - [ - new Point(0, 0), - new Point(0, 1), - new Point(1, 1), - new Point(1, 0), - new Point(0, 0), - ] - ); - - $point = new Point(100, 200); - - $this->collection = new GeometryCollection([$collection, $point]); - } - public function testFromWKT() { /** @@ -45,7 +23,7 @@ public function testToWKT() { $this->assertEquals( 'GEOMETRYCOLLECTION(LINESTRING(0 0,1 0,1 1,0 1,0 0),POINT(200 100))', - $this->collection->toWKT() + $this->getGeometryCollection()->toWKT() ); } @@ -53,12 +31,40 @@ public function testJsonSerialize() { $this->assertInstanceOf( \GeoJson\Geometry\GeometryCollection::class, - $this->collection->jsonSerialize() + $this->getGeometryCollection()->jsonSerialize() ); $this->assertSame( '{"type":"GeometryCollection","geometries":[{"type":"LineString","coordinates":[[0,0],[1,0],[1,1],[0,1],[0,0]]},{"type":"Point","coordinates":[200,100]}]}', - json_encode($this->collection->jsonSerialize()) + json_encode($this->getGeometryCollection()->jsonSerialize()) + ); + } + + public function testInvalidArgumentExceptionNotArrayGeometries() { + $this->expectException(InvalidArgumentException::class); + $geometrycollection = new GeometryCollection([ + $this->getPoint(), + 1 + ]); + } + + private function getGeometryCollection() { + return new GeometryCollection([$this->getLineString(), $this->getPoint()]); + } + + private function getLineString() { + return new LineString( + [ + new Point(0, 0), + new Point(0, 1), + new Point(1, 1), + new Point(1, 0), + new Point(0, 0), + ] ); } + + private function getPoint() { + return new Point(100, 200); + } } diff --git a/tests/Unit/Types/GeometryTest.php b/tests/Unit/Types/GeometryTest.php index f5043fa5..59fe2bc9 100644 --- a/tests/Unit/Types/GeometryTest.php +++ b/tests/Unit/Types/GeometryTest.php @@ -117,5 +117,12 @@ public function testGetWKBClass() GeometryCollection::class, Geometry::fromWKB('0107000000020000000101000000000000000000f03f0000000000000040010200000002000000000000000000f03f000000000000004000000000000008400000000000001040') ); + + $prefix = "\0\0\0\0"; + $this->assertInstanceOf( + Point::class, + Geometry::fromWKB($prefix . '0101000000000000000000f03f0000000000000040') + ); + } } diff --git a/tests/Unit/Types/MultiLineStringTest.php b/tests/Unit/Types/MultiLineStringTest.php index ed1f0be8..64f9b57b 100644 --- a/tests/Unit/Types/MultiLineStringTest.php +++ b/tests/Unit/Types/MultiLineStringTest.php @@ -41,4 +41,17 @@ public function testJsonSerialize() json_encode($multilinestring) ); } + + public function testInvalidArgumentExceptionAtLeastOneEntry() { + $this->expectException(InvalidArgumentException::class); + $multilinestring = new MultiLineString([]); + } + + public function testInvalidArgumentExceptionNotArrayOfLineString() { + $this->expectException(InvalidArgumentException::class); + $multilinestring = new MultiLineString([ + new LineString([new Point(0, 0), new Point(1, 1)]), + new Point(0,1) + ]); + } } diff --git a/tests/Unit/Types/MultiPointTest.php b/tests/Unit/Types/MultiPointTest.php index 74df3d1f..c62706bf 100644 --- a/tests/Unit/Types/MultiPointTest.php +++ b/tests/Unit/Types/MultiPointTest.php @@ -22,6 +22,32 @@ public function testToWKT() $this->assertEquals('MULTIPOINT((0 0),(1 0),(1 1))', $multipoint->toWKT()); } + public function testGetPoints() + { + $multipoint = MultiPoint::fromWKT('MULTIPOINT((0 0),(1 0),(1 1))'); + + $this->assertInstanceOf(Point::class, $multipoint->getPoints()[0]); + } + + public function testToArray() + { + $multipoint = MultiPoint::fromWKT('MULTIPOINT((0 0),(1 0),(1 1))'); + + $this->assertInstanceOf(Point::class, $multipoint->toArray()[0]); + } + + public function testIteratorAggregate() { + $multipoint = MultiPoint::fromWKT('MULTIPOINT((0 0),(1 0),(1 1))'); + + foreach($multipoint as $value) { + $this->assertInstanceOf(Point::class, $value); + } + } + + public function testArrayAccess() { + + } + public function testJsonSerialize() { $collection = [new Point(0, 0), new Point(0, 1), new Point(1, 1)]; @@ -31,4 +57,17 @@ public function testJsonSerialize() $this->assertInstanceOf(\GeoJson\Geometry\MultiPoint::class, $multipoint->jsonSerialize()); $this->assertSame('{"type":"MultiPoint","coordinates":[[0,0],[1,0],[1,1]]}', json_encode($multipoint)); } + + public function testInvalidArgumentExceptionAtLeastOneEntry() { + $this->expectException(InvalidArgumentException::class); + $multipoint = new MultiPoint([]); + } + + public function testInvalidArgumentExceptionNotArrayOfLineString() { + $this->expectException(InvalidArgumentException::class); + $multipoint = new MultiPoint([ + new Point(0, 0), + 1 + ]); + } } diff --git a/tests/Unit/Types/MultiPolygonTest.php b/tests/Unit/Types/MultiPolygonTest.php index 9d3bf8c7..8f0a09fa 100644 --- a/tests/Unit/Types/MultiPolygonTest.php +++ b/tests/Unit/Types/MultiPolygonTest.php @@ -7,50 +7,6 @@ class MultiPolygonTest extends BaseTestCase { - /** - * @var MultiPolygon - */ - private $multiPolygon; - - protected function setUp() - { - $collection1 = new LineString( - [ - new Point(0, 0), - new Point(0, 1), - new Point(1, 1), - new Point(1, 0), - new Point(0, 0), - ] - ); - - $collection2 = new LineString( - [ - new Point(10, 10), - new Point(10, 20), - new Point(20, 20), - new Point(20, 10), - new Point(10, 10), - ] - ); - - $polygon1 = new Polygon([$collection1, $collection2]); - - $collection3 = new LineString( - [ - new Point(100, 100), - new Point(100, 200), - new Point(200, 200), - new Point(200, 100), - new Point(100, 100), - ] - ); - - $polygon2 = new Polygon([$collection3]); - - $this->multiPolygon = new MultiPolygon([$polygon1, $polygon2]); - } - public function testFromWKT() { $polygon = MultiPolygon::fromWKT( @@ -65,7 +21,7 @@ public function testToWKT() { $this->assertEquals( 'MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0),(10 10,20 10,20 20,10 20,10 10)),((100 100,200 100,200 200,100 200,100 100)))', - $this->multiPolygon->toWKT() + $this->getMultiPolygon()->toWKT() ); } @@ -89,10 +45,66 @@ public function testIssue12() public function testJsonSerialize() { - $this->assertInstanceOf(\GeoJson\Geometry\MultiPolygon::class, $this->multiPolygon->jsonSerialize()); + $this->assertInstanceOf(\GeoJson\Geometry\MultiPolygon::class, $this->getMultiPolygon()->jsonSerialize()); $this->assertSame( '{"type":"MultiPolygon","coordinates":[[[[0,0],[1,0],[1,1],[0,1],[0,0]],[[10,10],[20,10],[20,20],[10,20],[10,10]]],[[[100,100],[200,100],[200,200],[100,200],[100,100]]]]}', - json_encode($this->multiPolygon) + json_encode($this->getMultiPolygon()) ); } + + public function testInvalidArgumentExceptionNotArrayOfLineString() { + $this->expectException(InvalidArgumentException::class); + $multipolygon = new MultiPolygon([ + $this->getPolygon1(), + $this->getLineString1() + ]); + } + + private function getMultiPolygon() { + return new MultiPolygon([$this->getPolygon1(), $this->getPolygon2()]); + } + + private function getLineString1() { + return new LineString( + [ + new Point(0, 0), + new Point(0, 1), + new Point(1, 1), + new Point(1, 0), + new Point(0, 0), + ] + ); + } + + private function getLineString2() { + return new LineString( + [ + new Point(10, 10), + new Point(10, 20), + new Point(20, 20), + new Point(20, 10), + new Point(10, 10), + ] + ); + } + + private function getLineString3() { + return new LineString( + [ + new Point(100, 100), + new Point(100, 200), + new Point(200, 200), + new Point(200, 100), + new Point(100, 100), + ] + ); + } + + private function getPolygon1() { + return new Polygon([$this->getLineString1(), $this->getLineString2()]); + } + + private function getPolygon2() { + return new Polygon([$this->getLineString3()]); + } } From 719af7e9858e4ca8abcbee0c144f003147168e69 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 10 Sep 2017 12:41:48 -0400 Subject: [PATCH 21/57] Fixes #13: Unset $offset variable. (cherry picked from commit 3c9f983) --- src/Types/PointCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Types/PointCollection.php b/src/Types/PointCollection.php index 376b0d63..13e26563 100755 --- a/src/Types/PointCollection.php +++ b/src/Types/PointCollection.php @@ -67,7 +67,7 @@ public function insertPoint($index, Point $point) throw new InvalidArgumentException('$index is greater than the size of the array'); } - array_splice($this->points, $offset, 0, [$point]); + array_splice($this->points, $index, 0, [$point]); } public function offsetExists($offset) From 4a3c524790b2514c61c0e47cc56c2a95a6a16cf4 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 10 Sep 2017 12:44:09 -0400 Subject: [PATCH 22/57] Added tests for ArrayAccess, prependPoint, appendPoint, insertPoint. (cherry picked from commit 9a26d66) --- tests/Unit/Types/MultiPointTest.php | 64 +++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/Unit/Types/MultiPointTest.php b/tests/Unit/Types/MultiPointTest.php index c62706bf..6fecdcac 100644 --- a/tests/Unit/Types/MultiPointTest.php +++ b/tests/Unit/Types/MultiPointTest.php @@ -45,7 +45,71 @@ public function testIteratorAggregate() { } public function testArrayAccess() { + $point0 = new Point(0, 0); + $point1 = new Point(1, 1); + $multipoint = new MultiPoint([$point0, $point1]); + $this->assertEquals($point0, $multipoint[0]); + $this->assertEquals($point1, $multipoint[1]); + $point2 = new Point(2, 2); + + $multipoint[] = $point2; + $this->assertEquals($point2, $multipoint[2]); + + unset($multipoint[0]); + $this->assertNull($multipoint[0]); + $this->assertEquals($point1, $multipoint[1]); + $this->assertEquals($point2, $multipoint[2]); + + $point100 = new Point(100, 100); + $multipoint[100] = $point100; + $this->assertEquals($point100, $multipoint[100]); + + $this->expectException(InvalidArgumentException::class); + $multipoint[] = 1; + + } + + public function testPrependPoint() { + $point1 = new Point(1, 1); + $point2 = new Point(2, 2); + $multipoint = new MultiPoint([$point1, $point2]); + + $point0 = new Point(0, 0); + $multipoint->prependPoint($point0); + + $this->assertEquals($point0, $multipoint->getPoints()[0]); + $this->assertEquals($point1, $multipoint->getPoints()[1]); + $this->assertEquals($point2, $multipoint->getPoints()[2]); + } + + public function testAppendPoint() { + $point0 = new Point(0, 0); + $point1 = new Point(1, 1); + $multipoint = new MultiPoint([$point0, $point1]); + + $point2 = new Point(2, 2); + $multipoint->appendPoint($point2); + + $this->assertEquals($point0, $multipoint->getPoints()[0]); + $this->assertEquals($point1, $multipoint->getPoints()[1]); + $this->assertEquals($point2, $multipoint->getPoints()[2]); + } + + public function testInsertPoint() { + $point1 = new Point(1, 1); + $point3 = new Point(3, 3); + $multipoint = new MultiPoint([$point1, $point3]); + + $point2 = new Point(2, 2); + $multipoint->insertPoint(1, $point2); + + $this->assertEquals($point1, $multipoint->getPoints()[0]); + $this->assertEquals($point2, $multipoint->getPoints()[1]); + $this->assertEquals($point3, $multipoint->getPoints()[2]); + + $this->expectException(InvalidArgumentException::class); + $multipoint->insertPoint(100, new Point(100,100)); } public function testJsonSerialize() From 5c5d2c9ca3b38f28475f9953e94404e5c4924d37 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 10 Sep 2017 18:20:56 -0400 Subject: [PATCH 23/57] Fixed exception check for PhpUnit 4.8 (cherry picked from commit abb6d2a) --- tests/Integration/SpatialTest.php | 11 ++++++++++- tests/Unit/BaseTestCase.php | 9 +++++++++ tests/Unit/Types/GeometryCollectionTest.php | 2 +- tests/Unit/Types/GeometryTest.php | 2 +- tests/Unit/Types/MultiLineStringTest.php | 4 ++-- tests/Unit/Types/MultiPointTest.php | 8 ++++---- tests/Unit/Types/MultiPolygonTest.php | 2 +- 7 files changed, 28 insertions(+), 10 deletions(-) diff --git a/tests/Integration/SpatialTest.php b/tests/Integration/SpatialTest.php index b333fe11..02b45343 100644 --- a/tests/Integration/SpatialTest.php +++ b/tests/Integration/SpatialTest.php @@ -65,6 +65,15 @@ protected function assertDatabaseHas($table, array $data, $connection = null) } } + protected function assertException($exceptionName) { + if(method_exists(parent::class, 'expectException')) { + parent::expectException($exceptionName); + } + else { + $this->setExpectedException($exceptionName); + } + } + private function onMigrations(\Closure $closure, $reverse_sort = false) { $fileSystem = new Filesystem(); @@ -87,7 +96,7 @@ public function testSpatialFieldsNotDefinedException() $geo->geometry = new Point(1, 2); $geo->save(); - $this->expectException(\Grimzy\LaravelMysqlSpatial\Exceptions\SpatialFieldsNotDefinedException::class); + $this->assertException(\Grimzy\LaravelMysqlSpatial\Exceptions\SpatialFieldsNotDefinedException::class); NoSpatialFieldsModel::all(); } diff --git a/tests/Unit/BaseTestCase.php b/tests/Unit/BaseTestCase.php index 48c9accd..f82e6d90 100644 --- a/tests/Unit/BaseTestCase.php +++ b/tests/Unit/BaseTestCase.php @@ -6,4 +6,13 @@ public function tearDown() { Mockery::close(); } + + protected function assertException($exceptionName) { + if(method_exists(parent::class, 'expectException')) { + parent::expectException($exceptionName); + } + else { + $this->setExpectedException($exceptionName); + } + } } diff --git a/tests/Unit/Types/GeometryCollectionTest.php b/tests/Unit/Types/GeometryCollectionTest.php index 6ec8164e..67864edd 100644 --- a/tests/Unit/Types/GeometryCollectionTest.php +++ b/tests/Unit/Types/GeometryCollectionTest.php @@ -41,7 +41,7 @@ public function testJsonSerialize() } public function testInvalidArgumentExceptionNotArrayGeometries() { - $this->expectException(InvalidArgumentException::class); + $this->assertException(InvalidArgumentException::class); $geometrycollection = new GeometryCollection([ $this->getPoint(), 1 diff --git a/tests/Unit/Types/GeometryTest.php b/tests/Unit/Types/GeometryTest.php index 59fe2bc9..33a5b7bb 100644 --- a/tests/Unit/Types/GeometryTest.php +++ b/tests/Unit/Types/GeometryTest.php @@ -74,7 +74,7 @@ public function testGetWKTClass() GeometryCollection::class, Geometry::getWKTClass('GEOMETRYCOLLECTION(POINT(2 3),LINESTRING(2 3,3 4))') ); - $this->expectException(UnknownWKTTypeException::class); + $this->assertException(UnknownWKTTypeException::class); Geometry::getWKTClass('TRIANGLE((0 0, 0 9, 9 0, 0 0))'); } diff --git a/tests/Unit/Types/MultiLineStringTest.php b/tests/Unit/Types/MultiLineStringTest.php index 64f9b57b..99c4c368 100644 --- a/tests/Unit/Types/MultiLineStringTest.php +++ b/tests/Unit/Types/MultiLineStringTest.php @@ -43,12 +43,12 @@ public function testJsonSerialize() } public function testInvalidArgumentExceptionAtLeastOneEntry() { - $this->expectException(InvalidArgumentException::class); + $this->assertException(InvalidArgumentException::class); $multilinestring = new MultiLineString([]); } public function testInvalidArgumentExceptionNotArrayOfLineString() { - $this->expectException(InvalidArgumentException::class); + $this->assertException(InvalidArgumentException::class); $multilinestring = new MultiLineString([ new LineString([new Point(0, 0), new Point(1, 1)]), new Point(0,1) diff --git a/tests/Unit/Types/MultiPointTest.php b/tests/Unit/Types/MultiPointTest.php index 6fecdcac..27f2e6e2 100644 --- a/tests/Unit/Types/MultiPointTest.php +++ b/tests/Unit/Types/MultiPointTest.php @@ -65,7 +65,7 @@ public function testArrayAccess() { $multipoint[100] = $point100; $this->assertEquals($point100, $multipoint[100]); - $this->expectException(InvalidArgumentException::class); + $this->assertException(InvalidArgumentException::class); $multipoint[] = 1; } @@ -108,7 +108,7 @@ public function testInsertPoint() { $this->assertEquals($point2, $multipoint->getPoints()[1]); $this->assertEquals($point3, $multipoint->getPoints()[2]); - $this->expectException(InvalidArgumentException::class); + $this->assertException(InvalidArgumentException::class); $multipoint->insertPoint(100, new Point(100,100)); } @@ -123,12 +123,12 @@ public function testJsonSerialize() } public function testInvalidArgumentExceptionAtLeastOneEntry() { - $this->expectException(InvalidArgumentException::class); + $this->assertException(InvalidArgumentException::class); $multipoint = new MultiPoint([]); } public function testInvalidArgumentExceptionNotArrayOfLineString() { - $this->expectException(InvalidArgumentException::class); + $this->assertException(InvalidArgumentException::class); $multipoint = new MultiPoint([ new Point(0, 0), 1 diff --git a/tests/Unit/Types/MultiPolygonTest.php b/tests/Unit/Types/MultiPolygonTest.php index 8f0a09fa..925b6030 100644 --- a/tests/Unit/Types/MultiPolygonTest.php +++ b/tests/Unit/Types/MultiPolygonTest.php @@ -53,7 +53,7 @@ public function testJsonSerialize() } public function testInvalidArgumentExceptionNotArrayOfLineString() { - $this->expectException(InvalidArgumentException::class); + $this->assertException(InvalidArgumentException::class); $multipolygon = new MultiPolygon([ $this->getPolygon1(), $this->getLineString1() From 11798bdc7ffe083dd3f336974a1681fb6aec1b8c Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 10 Sep 2017 18:26:29 -0400 Subject: [PATCH 24/57] Style CI fix :performing_arts: (cherry picked from commit d5fa308) --- tests/Unit/Types/GeometryCollectionTest.php | 35 +++--- tests/Unit/Types/GeometryTest.php | 121 ++++---------------- tests/Unit/Types/MultiLineStringTest.php | 19 ++- tests/Unit/Types/MultiPointTest.php | 28 +++-- tests/Unit/Types/MultiPolygonTest.php | 63 +++++----- 5 files changed, 89 insertions(+), 177 deletions(-) diff --git a/tests/Unit/Types/GeometryCollectionTest.php b/tests/Unit/Types/GeometryCollectionTest.php index 67864edd..09e03297 100644 --- a/tests/Unit/Types/GeometryCollectionTest.php +++ b/tests/Unit/Types/GeometryCollectionTest.php @@ -21,50 +21,43 @@ public function testFromWKT() public function testToWKT() { - $this->assertEquals( - 'GEOMETRYCOLLECTION(LINESTRING(0 0,1 0,1 1,0 1,0 0),POINT(200 100))', - $this->getGeometryCollection()->toWKT() - ); + $this->assertEquals('GEOMETRYCOLLECTION(LINESTRING(0 0,1 0,1 1,0 1,0 0),POINT(200 100))', $this->getGeometryCollection()->toWKT()); } public function testJsonSerialize() { - $this->assertInstanceOf( - \GeoJson\Geometry\GeometryCollection::class, - $this->getGeometryCollection()->jsonSerialize() - ); + $this->assertInstanceOf(\GeoJson\Geometry\GeometryCollection::class, $this->getGeometryCollection()->jsonSerialize()); - $this->assertSame( - '{"type":"GeometryCollection","geometries":[{"type":"LineString","coordinates":[[0,0],[1,0],[1,1],[0,1],[0,0]]},{"type":"Point","coordinates":[200,100]}]}', - json_encode($this->getGeometryCollection()->jsonSerialize()) - ); + $this->assertSame('{"type":"GeometryCollection","geometries":[{"type":"LineString","coordinates":[[0,0],[1,0],[1,1],[0,1],[0,0]]},{"type":"Point","coordinates":[200,100]}]}', json_encode($this->getGeometryCollection()->jsonSerialize())); } - public function testInvalidArgumentExceptionNotArrayGeometries() { + public function testInvalidArgumentExceptionNotArrayGeometries() + { $this->assertException(InvalidArgumentException::class); $geometrycollection = new GeometryCollection([ $this->getPoint(), - 1 + 1, ]); } - private function getGeometryCollection() { + private function getGeometryCollection() + { return new GeometryCollection([$this->getLineString(), $this->getPoint()]); } - private function getLineString() { - return new LineString( - [ + private function getLineString() + { + return new LineString([ new Point(0, 0), new Point(0, 1), new Point(1, 1), new Point(1, 0), new Point(0, 0), - ] - ); + ]); } - private function getPoint() { + private function getPoint() + { return new Point(100, 200); } } diff --git a/tests/Unit/Types/GeometryTest.php b/tests/Unit/Types/GeometryTest.php index 33a5b7bb..769b19dc 100644 --- a/tests/Unit/Types/GeometryTest.php +++ b/tests/Unit/Types/GeometryTest.php @@ -14,115 +14,42 @@ class GeometryTest extends BaseTestCase { public function testGetWKTArgument() { - $this->assertEquals( - '0 0', - Geometry::getWKTArgument('POINT(0 0)') - ); - $this->assertEquals( - '0 0,1 1,1 2', - Geometry::getWKTArgument('LINESTRING(0 0,1 1,1 2)') - ); - $this->assertEquals( - '(0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1)', - Geometry::getWKTArgument('POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))') - ); - $this->assertEquals( - '(0 0),(1 2)', - Geometry::getWKTArgument('MULTIPOINT((0 0),(1 2))') - ); - $this->assertEquals( - '(0 0,1 1,1 2),(2 3,3 2,5 4)', - Geometry::getWKTArgument('MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))') - ); - $this->assertEquals( - '((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1))', - Geometry::getWKTArgument('MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))') - ); - $this->assertEquals( - 'POINT(2 3),LINESTRING(2 3,3 4)', - Geometry::getWKTArgument('GEOMETRYCOLLECTION(POINT(2 3),LINESTRING(2 3,3 4))') - ); + $this->assertEquals('0 0', Geometry::getWKTArgument('POINT(0 0)')); + $this->assertEquals('0 0,1 1,1 2', Geometry::getWKTArgument('LINESTRING(0 0,1 1,1 2)')); + $this->assertEquals('(0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1)', Geometry::getWKTArgument('POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))')); + $this->assertEquals('(0 0),(1 2)', Geometry::getWKTArgument('MULTIPOINT((0 0),(1 2))')); + $this->assertEquals('(0 0,1 1,1 2),(2 3,3 2,5 4)', Geometry::getWKTArgument('MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))')); + $this->assertEquals('((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1))', Geometry::getWKTArgument('MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))')); + $this->assertEquals('POINT(2 3),LINESTRING(2 3,3 4)', Geometry::getWKTArgument('GEOMETRYCOLLECTION(POINT(2 3),LINESTRING(2 3,3 4))')); } public function testGetWKTClass() { - $this->assertEquals( - Point::class, - Geometry::getWKTClass('POINT(0 0)') - ); - $this->assertEquals( - LineString::class, - Geometry::getWKTClass('LINESTRING(0 0,1 1,1 2)') - ); - $this->assertEquals( - Polygon::class, - Geometry::getWKTClass('POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))') - ); - $this->assertEquals( - MultiPoint::class, - Geometry::getWKTClass('MULTIPOINT((0 0),(1 2))') - ); - $this->assertEquals( - MultiLineString::class, - Geometry::getWKTClass('MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))') - ); - $this->assertEquals( - MultiPolygon::class, - Geometry::getWKTClass('MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))') - ); - $this->assertEquals( - GeometryCollection::class, - Geometry::getWKTClass('GEOMETRYCOLLECTION(POINT(2 3),LINESTRING(2 3,3 4))') - ); + $this->assertEquals(Point::class, Geometry::getWKTClass('POINT(0 0)')); + $this->assertEquals(LineString::class, Geometry::getWKTClass('LINESTRING(0 0,1 1,1 2)')); + $this->assertEquals(Polygon::class, Geometry::getWKTClass('POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))')); + $this->assertEquals(MultiPoint::class, Geometry::getWKTClass('MULTIPOINT((0 0),(1 2))')); + $this->assertEquals(MultiLineString::class, Geometry::getWKTClass('MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))')); + $this->assertEquals(MultiPolygon::class, Geometry::getWKTClass('MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))')); + $this->assertEquals(GeometryCollection::class, Geometry::getWKTClass('GEOMETRYCOLLECTION(POINT(2 3),LINESTRING(2 3,3 4))')); $this->assertException(UnknownWKTTypeException::class); Geometry::getWKTClass('TRIANGLE((0 0, 0 9, 9 0, 0 0))'); } public function testGetWKBClass() { - $this->assertInstanceOf( - Point::class, - Geometry::fromWKB('0101000000000000000000f03f0000000000000040') - ); + $this->assertInstanceOf(Point::class, Geometry::fromWKB('0101000000000000000000f03f0000000000000040')); - $this->assertInstanceOf( - LineString::class, - Geometry::fromWKB('010200000002000000000000000000f03f000000000000004000000000000008400000000000001040') - ); - $this->assertInstanceOf( - Polygon::class, - Geometry::fromWKB('01030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f0000000000000040') - ); - $this->assertInstanceOf( - MultiPoint::class, - Geometry::fromWKB('0104000000020000000101000000000000000000f03f0000000000000040010100000000000000000008400000000000001040') - ); - $this->assertInstanceOf( - MultiLineString::class, - Geometry::fromWKB('010500000001000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040') - ); - $this->assertInstanceOf( - MultiLineString::class, - Geometry::fromWKB('010500000002000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040010200000002000000000000000000144000000000000018400000000000001c400000000000002040') - ); - $this->assertInstanceOf( - MultiPolygon::class, - Geometry::fromWKB('01060000000200000001030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004001030000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640') - ); - $this->assertInstanceOf( - GeometryCollection::class, - Geometry::fromWKB('0107000000010000000101000000000000000000f03f0000000000000040') - ); - $this->assertInstanceOf( - GeometryCollection::class, - Geometry::fromWKB('0107000000020000000101000000000000000000f03f0000000000000040010200000002000000000000000000f03f000000000000004000000000000008400000000000001040') - ); + $this->assertInstanceOf(LineString::class, Geometry::fromWKB('010200000002000000000000000000f03f000000000000004000000000000008400000000000001040')); + $this->assertInstanceOf(Polygon::class, Geometry::fromWKB('01030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f0000000000000040')); + $this->assertInstanceOf(MultiPoint::class, Geometry::fromWKB('0104000000020000000101000000000000000000f03f0000000000000040010100000000000000000008400000000000001040')); + $this->assertInstanceOf(MultiLineString::class, Geometry::fromWKB('010500000001000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040')); + $this->assertInstanceOf(MultiLineString::class, Geometry::fromWKB('010500000002000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040010200000002000000000000000000144000000000000018400000000000001c400000000000002040')); + $this->assertInstanceOf(MultiPolygon::class, Geometry::fromWKB('01060000000200000001030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004001030000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640')); + $this->assertInstanceOf(GeometryCollection::class, Geometry::fromWKB('0107000000010000000101000000000000000000f03f0000000000000040')); + $this->assertInstanceOf(GeometryCollection::class, Geometry::fromWKB('0107000000020000000101000000000000000000f03f0000000000000040010200000002000000000000000000f03f000000000000004000000000000008400000000000001040')); $prefix = "\0\0\0\0"; - $this->assertInstanceOf( - Point::class, - Geometry::fromWKB($prefix . '0101000000000000000000f03f0000000000000040') - ); - + $this->assertInstanceOf(Point::class, Geometry::fromWKB($prefix.'0101000000000000000000f03f0000000000000040')); } } diff --git a/tests/Unit/Types/MultiLineStringTest.php b/tests/Unit/Types/MultiLineStringTest.php index 99c4c368..08360c7e 100644 --- a/tests/Unit/Types/MultiLineStringTest.php +++ b/tests/Unit/Types/MultiLineStringTest.php @@ -16,15 +16,13 @@ public function testFromWKT() public function testToWKT() { - $collection = new LineString( - [ + $collection = new LineString([ new Point(0, 0), new Point(0, 1), new Point(1, 1), new Point(1, 0), new Point(0, 0), - ] - ); + ]); $multilinestring = new MultiLineString([$collection]); @@ -36,22 +34,21 @@ public function testJsonSerialize() $multilinestring = MultiLineString::fromWKT('MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))'); $this->assertInstanceOf(\GeoJson\Geometry\MultiLineString::class, $multilinestring->jsonSerialize()); - $this->assertSame( - '{"type":"MultiLineString","coordinates":[[[0,0],[1,1],[1,2]],[[2,3],[3,2],[5,4]]]}', - json_encode($multilinestring) - ); + $this->assertSame('{"type":"MultiLineString","coordinates":[[[0,0],[1,1],[1,2]],[[2,3],[3,2],[5,4]]]}', json_encode($multilinestring)); } - public function testInvalidArgumentExceptionAtLeastOneEntry() { + public function testInvalidArgumentExceptionAtLeastOneEntry() + { $this->assertException(InvalidArgumentException::class); $multilinestring = new MultiLineString([]); } - public function testInvalidArgumentExceptionNotArrayOfLineString() { + public function testInvalidArgumentExceptionNotArrayOfLineString() + { $this->assertException(InvalidArgumentException::class); $multilinestring = new MultiLineString([ new LineString([new Point(0, 0), new Point(1, 1)]), - new Point(0,1) + new Point(0, 1), ]); } } diff --git a/tests/Unit/Types/MultiPointTest.php b/tests/Unit/Types/MultiPointTest.php index 27f2e6e2..6ca25b11 100644 --- a/tests/Unit/Types/MultiPointTest.php +++ b/tests/Unit/Types/MultiPointTest.php @@ -36,15 +36,17 @@ public function testToArray() $this->assertInstanceOf(Point::class, $multipoint->toArray()[0]); } - public function testIteratorAggregate() { + public function testIteratorAggregate() + { $multipoint = MultiPoint::fromWKT('MULTIPOINT((0 0),(1 0),(1 1))'); - foreach($multipoint as $value) { + foreach ($multipoint as $value) { $this->assertInstanceOf(Point::class, $value); } } - public function testArrayAccess() { + public function testArrayAccess() + { $point0 = new Point(0, 0); $point1 = new Point(1, 1); $multipoint = new MultiPoint([$point0, $point1]); @@ -67,10 +69,10 @@ public function testArrayAccess() { $this->assertException(InvalidArgumentException::class); $multipoint[] = 1; - } - public function testPrependPoint() { + public function testPrependPoint() + { $point1 = new Point(1, 1); $point2 = new Point(2, 2); $multipoint = new MultiPoint([$point1, $point2]); @@ -83,7 +85,8 @@ public function testPrependPoint() { $this->assertEquals($point2, $multipoint->getPoints()[2]); } - public function testAppendPoint() { + public function testAppendPoint() + { $point0 = new Point(0, 0); $point1 = new Point(1, 1); $multipoint = new MultiPoint([$point0, $point1]); @@ -96,7 +99,8 @@ public function testAppendPoint() { $this->assertEquals($point2, $multipoint->getPoints()[2]); } - public function testInsertPoint() { + public function testInsertPoint() + { $point1 = new Point(1, 1); $point3 = new Point(3, 3); $multipoint = new MultiPoint([$point1, $point3]); @@ -109,7 +113,7 @@ public function testInsertPoint() { $this->assertEquals($point3, $multipoint->getPoints()[2]); $this->assertException(InvalidArgumentException::class); - $multipoint->insertPoint(100, new Point(100,100)); + $multipoint->insertPoint(100, new Point(100, 100)); } public function testJsonSerialize() @@ -122,16 +126,18 @@ public function testJsonSerialize() $this->assertSame('{"type":"MultiPoint","coordinates":[[0,0],[1,0],[1,1]]}', json_encode($multipoint)); } - public function testInvalidArgumentExceptionAtLeastOneEntry() { + public function testInvalidArgumentExceptionAtLeastOneEntry() + { $this->assertException(InvalidArgumentException::class); $multipoint = new MultiPoint([]); } - public function testInvalidArgumentExceptionNotArrayOfLineString() { + public function testInvalidArgumentExceptionNotArrayOfLineString() + { $this->assertException(InvalidArgumentException::class); $multipoint = new MultiPoint([ new Point(0, 0), - 1 + 1, ]); } } diff --git a/tests/Unit/Types/MultiPolygonTest.php b/tests/Unit/Types/MultiPolygonTest.php index 925b6030..438b8f96 100644 --- a/tests/Unit/Types/MultiPolygonTest.php +++ b/tests/Unit/Types/MultiPolygonTest.php @@ -9,9 +9,7 @@ class MultiPolygonTest extends BaseTestCase { public function testFromWKT() { - $polygon = MultiPolygon::fromWKT( - 'MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))' - ); + $polygon = MultiPolygon::fromWKT('MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))'); $this->assertInstanceOf(MultiPolygon::class, $polygon); $this->assertEquals(2, $polygon->count()); @@ -19,26 +17,19 @@ public function testFromWKT() public function testToWKT() { - $this->assertEquals( - 'MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0),(10 10,20 10,20 20,10 20,10 10)),((100 100,200 100,200 200,100 200,100 100)))', - $this->getMultiPolygon()->toWKT() - ); + $this->assertEquals('MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0),(10 10,20 10,20 20,10 20,10 10)),((100 100,200 100,200 200,100 200,100 100)))', $this->getMultiPolygon()->toWKT()); } public function testGetPolygons() { - $polygon = MultiPolygon::fromWKT( - 'MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))' - ); + $polygon = MultiPolygon::fromWKT('MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))'); $this->assertInstanceOf(Polygon::class, $polygon->getPolygons()[0]); } public function testIssue12() { - $polygon = MultiPolygon::fromWKT( - 'MULTIPOLYGON(((-80.214554 25.769598 0 0,-80.2147 25.774514 0 0,-80.212983 25.77456 0 0,-80.212977 25.773597 0 0,-80.211448 25.773655 0 0,-80.211498 25.774579 0 0,-80.209432 25.774665 0 0,-80.209392 25.773667 0 0,-80.204387 25.773834 0 0,-80.199383 25.774324 0 0,-80.197718 25.774031 0 0,-80.197757 25.774975 0 0,-80.193655 25.775108 0 0,-80.193623 25.774134 0 0,-80.191855 25.772551 0 0,-80.193442 25.76969 0 0,-80.192231 25.768345 0 0,-80.192879 25.758009 0 0,-80.196301 25.759985 0 0,-80.195608 25.76152 0 0,-80.198856 25.761454 0 0,-80.200646 25.763287 0 0,-80.20401 25.763164 0 0,-80.204023 25.76367 0 0,-80.205673 25.763141 0 0,-80.214326 25.762935 0 0,-80.214451 25.765883 0 0,-80.214539 25.768649 0 0,-80.216203 25.76858 0 0,-80.214554 25.769598 0 0)))' - ); + $polygon = MultiPolygon::fromWKT('MULTIPOLYGON(((-80.214554 25.769598 0 0,-80.2147 25.774514 0 0,-80.212983 25.77456 0 0,-80.212977 25.773597 0 0,-80.211448 25.773655 0 0,-80.211498 25.774579 0 0,-80.209432 25.774665 0 0,-80.209392 25.773667 0 0,-80.204387 25.773834 0 0,-80.199383 25.774324 0 0,-80.197718 25.774031 0 0,-80.197757 25.774975 0 0,-80.193655 25.775108 0 0,-80.193623 25.774134 0 0,-80.191855 25.772551 0 0,-80.193442 25.76969 0 0,-80.192231 25.768345 0 0,-80.192879 25.758009 0 0,-80.196301 25.759985 0 0,-80.195608 25.76152 0 0,-80.198856 25.761454 0 0,-80.200646 25.763287 0 0,-80.20401 25.763164 0 0,-80.204023 25.76367 0 0,-80.205673 25.763141 0 0,-80.214326 25.762935 0 0,-80.214451 25.765883 0 0,-80.214539 25.768649 0 0,-80.216203 25.76858 0 0,-80.214554 25.769598 0 0)))'); $this->assertInstanceOf(MultiPolygon::class, $polygon); } @@ -46,65 +37,63 @@ public function testIssue12() public function testJsonSerialize() { $this->assertInstanceOf(\GeoJson\Geometry\MultiPolygon::class, $this->getMultiPolygon()->jsonSerialize()); - $this->assertSame( - '{"type":"MultiPolygon","coordinates":[[[[0,0],[1,0],[1,1],[0,1],[0,0]],[[10,10],[20,10],[20,20],[10,20],[10,10]]],[[[100,100],[200,100],[200,200],[100,200],[100,100]]]]}', - json_encode($this->getMultiPolygon()) - ); + $this->assertSame('{"type":"MultiPolygon","coordinates":[[[[0,0],[1,0],[1,1],[0,1],[0,0]],[[10,10],[20,10],[20,20],[10,20],[10,10]]],[[[100,100],[200,100],[200,200],[100,200],[100,100]]]]}', json_encode($this->getMultiPolygon())); } - public function testInvalidArgumentExceptionNotArrayOfLineString() { + public function testInvalidArgumentExceptionNotArrayOfLineString() + { $this->assertException(InvalidArgumentException::class); $multipolygon = new MultiPolygon([ $this->getPolygon1(), - $this->getLineString1() + $this->getLineString1(), ]); } - private function getMultiPolygon() { + private function getMultiPolygon() + { return new MultiPolygon([$this->getPolygon1(), $this->getPolygon2()]); } - private function getLineString1() { - return new LineString( - [ + private function getLineString1() + { + return new LineString([ new Point(0, 0), new Point(0, 1), new Point(1, 1), new Point(1, 0), new Point(0, 0), - ] - ); + ]); } - private function getLineString2() { - return new LineString( - [ + private function getLineString2() + { + return new LineString([ new Point(10, 10), new Point(10, 20), new Point(20, 20), new Point(20, 10), new Point(10, 10), - ] - ); + ]); } - private function getLineString3() { - return new LineString( - [ + private function getLineString3() + { + return new LineString([ new Point(100, 100), new Point(100, 200), new Point(200, 200), new Point(200, 100), new Point(100, 100), - ] - ); + ]); } - private function getPolygon1() { + private function getPolygon1() + { return new Polygon([$this->getLineString1(), $this->getLineString2()]); } - private function getPolygon2() { + private function getPolygon2() + { return new Polygon([$this->getLineString3()]); } } From d8ae366a52092ddefda18fe6e081a8234bd01114 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 10 Sep 2017 18:27:53 -0400 Subject: [PATCH 25/57] Style CI fix :performing_arts: (cherry picked from commit bab2c2e) --- tests/Integration/SpatialTest.php | 8 ++++---- tests/Unit/BaseTestCase.php | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/Integration/SpatialTest.php b/tests/Integration/SpatialTest.php index 02b45343..b2206f3b 100644 --- a/tests/Integration/SpatialTest.php +++ b/tests/Integration/SpatialTest.php @@ -65,11 +65,11 @@ protected function assertDatabaseHas($table, array $data, $connection = null) } } - protected function assertException($exceptionName) { - if(method_exists(parent::class, 'expectException')) { + protected function assertException($exceptionName) + { + if (method_exists(parent::class, 'expectException')) { parent::expectException($exceptionName); - } - else { + } else { $this->setExpectedException($exceptionName); } } diff --git a/tests/Unit/BaseTestCase.php b/tests/Unit/BaseTestCase.php index f82e6d90..44f323c5 100644 --- a/tests/Unit/BaseTestCase.php +++ b/tests/Unit/BaseTestCase.php @@ -6,12 +6,12 @@ public function tearDown() { Mockery::close(); } - - protected function assertException($exceptionName) { - if(method_exists(parent::class, 'expectException')) { + + protected function assertException($exceptionName) + { + if (method_exists(parent::class, 'expectException')) { parent::expectException($exceptionName); - } - else { + } else { $this->setExpectedException($exceptionName); } } From 446b5bb4818dcc935d682328befc3e51f297be0c Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 24 Sep 2017 14:59:02 -0400 Subject: [PATCH 26/57] PointCollection/MultiPoint: Implemented Arrayable and Jsonable and primarily using ArrayAccess for operations (#15). (cherry picked from commit afebcaf) --- src/Types/PointCollection.php | 98 +++++++++++++++++++---------- tests/Unit/Types/MultiPointTest.php | 83 +++++++++++++----------- 2 files changed, 112 insertions(+), 69 deletions(-) diff --git a/src/Types/PointCollection.php b/src/Types/PointCollection.php index 13e26563..de57dd3c 100755 --- a/src/Types/PointCollection.php +++ b/src/Types/PointCollection.php @@ -6,11 +6,12 @@ use ArrayIterator; use Countable; use Illuminate\Contracts\Support\Arrayable; +use Illuminate\Contracts\Support\Jsonable; use InvalidArgumentException; use IteratorAggregate; use JsonSerializable; -abstract class PointCollection implements IteratorAggregate, Arrayable, ArrayAccess, Countable, JsonSerializable +abstract class PointCollection implements IteratorAggregate, ArrayAccess, Arrayable, Countable, Jsonable, JsonSerializable { /** * @var Point[] @@ -36,11 +37,6 @@ public function __construct(array $points) $this->points = $points; } - public function getPoints() - { - return $this->points; - } - public function toArray() { return $this->points; @@ -51,35 +47,11 @@ public function getIterator() return new ArrayIterator($this->points); } - public function prependPoint(Point $point) - { - array_unshift($this->points, $point); - } - - public function appendPoint(Point $point) - { - $this->points[] = $point; - } - - public function insertPoint($index, Point $point) - { - if (count($this->points) - 1 < $index) { - throw new InvalidArgumentException('$index is greater than the size of the array'); - } - - array_splice($this->points, $index, 0, [$point]); - } - public function offsetExists($offset) { return isset($this->points[$offset]); } - /** - * @param mixed $offset - * - * @return null|Point - */ public function offsetGet($offset) { return $this->offsetExists($offset) ? $this->points[$offset] : null; @@ -87,12 +59,12 @@ public function offsetGet($offset) public function offsetSet($offset, $value) { - if (!($value instanceof Point)) { + if (! ($value instanceof Point)) { throw new InvalidArgumentException('$value must be an instance of Point'); } if (is_null($offset)) { - $this->appendPoint($value); + $this->points[] = $value; } else { $this->points[$offset] = $value; } @@ -108,10 +80,72 @@ public function count() return count($this->points); } + public function toJson($options = 0) + { + return json_encode($this, $options); + } + public function toPairList() { return implode(',', array_map(function (Point $point) { return $point->toPair(); }, $this->points)); } + + /** + * @return array|\Grimzy\LaravelMysqlSpatial\Types\Point[] + * + * @deprecated 2.1.0 Use $multipoint->toArray() instead + * + * @see IteratorAggregate + * @see ArrayAccess + * @see Arrayable + */ + public function getPoints() + { + return $this->points; + } + + /** + * @param \Grimzy\LaravelMysqlSpatial\Types\Point $point + * + * @deprecated 2.1.0 Use array_unshift($multipoint, $point); instead + * + * @see array_unshift + * @see ArrayAccess + */ + public function prependPoint(Point $point) + { + array_unshift($this->points, $point); + } + + /** + * @param \Grimzy\LaravelMysqlSpatial\Types\Point $point + * + * @deprecated 2.1.0 Use $multipoint[] = $point; instead + * + * @see ArrayAccess + */ + public function appendPoint(Point $point) + { + $this->points[] = $point; + } + + /** + * @param $index + * @param \Grimzy\LaravelMysqlSpatial\Types\Point $point + * + * @deprecated 2.1.0 Use array_splice($multipoint, $index, 0, [$point]); instead + * + * @see array_splice + * @see ArrayAccess + */ + public function insertPoint($index, Point $point) + { + if (count($this->points) - 1 < $index) { + throw new InvalidArgumentException('$index is greater than the size of the array'); + } + + array_splice($this->points, $index, 0, [$point]); + } } diff --git a/tests/Unit/Types/MultiPointTest.php b/tests/Unit/Types/MultiPointTest.php index 6ca25b11..0e0e0643 100644 --- a/tests/Unit/Types/MultiPointTest.php +++ b/tests/Unit/Types/MultiPointTest.php @@ -71,7 +71,41 @@ public function testArrayAccess() $multipoint[] = 1; } - public function testPrependPoint() + public function testToJson() + { + $collection = [new Point(0, 0), new Point(0, 1), new Point(1, 1)]; + + $multipoint = new MultiPoint($collection); + + $this->assertSame('{"type":"MultiPoint","coordinates":[[0,0],[1,0],[1,1]]}', $multipoint->toJson()); + } + + public function testJsonSerialize() + { + $collection = [new Point(0, 0), new Point(0, 1), new Point(1, 1)]; + + $multipoint = new MultiPoint($collection); + + $this->assertInstanceOf(\GeoJson\Geometry\MultiPoint::class, $multipoint->jsonSerialize()); + $this->assertSame('{"type":"MultiPoint","coordinates":[[0,0],[1,0],[1,1]]}', json_encode($multipoint)); + } + + public function testInvalidArgumentExceptionAtLeastOneEntry() + { + $this->assertException(InvalidArgumentException::class); + $multipoint = new MultiPoint([]); + } + + public function testInvalidArgumentExceptionNotArrayOfLineString() + { + $this->assertException(InvalidArgumentException::class); + $multipoint = new MultiPoint([ + new Point(0, 0), + 1, + ]); + } + + public function testDeprecatedPrependPoint() { $point1 = new Point(1, 1); $point2 = new Point(2, 2); @@ -80,12 +114,12 @@ public function testPrependPoint() $point0 = new Point(0, 0); $multipoint->prependPoint($point0); - $this->assertEquals($point0, $multipoint->getPoints()[0]); - $this->assertEquals($point1, $multipoint->getPoints()[1]); - $this->assertEquals($point2, $multipoint->getPoints()[2]); + $this->assertEquals($point0, $multipoint[0]); + $this->assertEquals($point1, $multipoint[1]); + $this->assertEquals($point2, $multipoint[2]); } - public function testAppendPoint() + public function testDeprecatedAppendPoint() { $point0 = new Point(0, 0); $point1 = new Point(1, 1); @@ -94,12 +128,12 @@ public function testAppendPoint() $point2 = new Point(2, 2); $multipoint->appendPoint($point2); - $this->assertEquals($point0, $multipoint->getPoints()[0]); - $this->assertEquals($point1, $multipoint->getPoints()[1]); - $this->assertEquals($point2, $multipoint->getPoints()[2]); + $this->assertEquals($point0, $multipoint[0]); + $this->assertEquals($point1, $multipoint[1]); + $this->assertEquals($point2, $multipoint[2]); } - public function testInsertPoint() + public function testDeprecatedInsertPoint() { $point1 = new Point(1, 1); $point3 = new Point(3, 3); @@ -108,36 +142,11 @@ public function testInsertPoint() $point2 = new Point(2, 2); $multipoint->insertPoint(1, $point2); - $this->assertEquals($point1, $multipoint->getPoints()[0]); - $this->assertEquals($point2, $multipoint->getPoints()[1]); - $this->assertEquals($point3, $multipoint->getPoints()[2]); + $this->assertEquals($point1, $multipoint[0]); + $this->assertEquals($point2, $multipoint[1]); + $this->assertEquals($point3, $multipoint[2]); $this->assertException(InvalidArgumentException::class); $multipoint->insertPoint(100, new Point(100, 100)); } - - public function testJsonSerialize() - { - $collection = [new Point(0, 0), new Point(0, 1), new Point(1, 1)]; - - $multipoint = new MultiPoint($collection); - - $this->assertInstanceOf(\GeoJson\Geometry\MultiPoint::class, $multipoint->jsonSerialize()); - $this->assertSame('{"type":"MultiPoint","coordinates":[[0,0],[1,0],[1,1]]}', json_encode($multipoint)); - } - - public function testInvalidArgumentExceptionAtLeastOneEntry() - { - $this->assertException(InvalidArgumentException::class); - $multipoint = new MultiPoint([]); - } - - public function testInvalidArgumentExceptionNotArrayOfLineString() - { - $this->assertException(InvalidArgumentException::class); - $multipoint = new MultiPoint([ - new Point(0, 0), - 1, - ]); - } } From 2b44c23b4cc88d7bdf7b8dcc46b066475a259d89 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 24 Sep 2017 18:06:27 -0400 Subject: [PATCH 27/57] Changed hierarchy of Spatial Types classes for #15. Implemented IteratorAggregate, ArrayAccess, Arrayable in GeometryCollection. Implemented Jsonable in Geometry. PointCollection, MultiLineString, and MultiPolygon now extend GeometryCollection. (cherry picked from commit a87e026) --- src/Types/Geometry.php | 8 +++- src/Types/GeometryCollection.php | 63 ++++++++++++++++++++++--- src/Types/LineString.php | 4 +- src/Types/MultiLineString.php | 22 ++++----- src/Types/MultiPoint.php | 6 +-- src/Types/MultiPolygon.php | 41 ++++++----------- src/Types/PointCollection.php | 79 +++++--------------------------- src/Types/Polygon.php | 6 +-- 8 files changed, 106 insertions(+), 123 deletions(-) diff --git a/src/Types/Geometry.php b/src/Types/Geometry.php index 20ba8c12..ee2ac6f8 100644 --- a/src/Types/Geometry.php +++ b/src/Types/Geometry.php @@ -4,8 +4,9 @@ use GeoIO\WKB\Parser\Parser; use Grimzy\LaravelMysqlSpatial\Exceptions\UnknownWKTTypeException; +use Illuminate\Contracts\Support\Jsonable; -abstract class Geometry implements GeometryInterface, \JsonSerializable +abstract class Geometry implements GeometryInterface, Jsonable, \JsonSerializable { protected static $wkb_types = [ 1 => Point::class, @@ -69,4 +70,9 @@ public static function fromWKT($wkt) return static::fromString($wktArgument); } + + public function toJson($options = 0) + { + return json_encode($this, $options); + } } diff --git a/src/Types/GeometryCollection.php b/src/Types/GeometryCollection.php index 734104f9..ee909246 100755 --- a/src/Types/GeometryCollection.php +++ b/src/Types/GeometryCollection.php @@ -2,15 +2,21 @@ namespace Grimzy\LaravelMysqlSpatial\Types; +use ArrayAccess; +use ArrayIterator; use Countable; +use Illuminate\Contracts\Support\Arrayable; use InvalidArgumentException; +use IteratorAggregate; -class GeometryCollection extends Geometry implements Countable +class GeometryCollection extends Geometry implements IteratorAggregate, ArrayAccess, Arrayable, Countable { /** + * The items contained in the spatial collection. + * * @var GeometryInterface[] */ - protected $geometries = []; + protected $items = []; /** * @param GeometryInterface[] $geometries @@ -27,12 +33,12 @@ public function __construct(array $geometries) throw new InvalidArgumentException('$geometries must be an array of Geometry objects'); } - $this->geometries = $geometries; + $this->items = $geometries; } public function getGeometries() { - return $this->geometries; + return $this->items; } public function toWKT() @@ -44,7 +50,7 @@ public function __toString() { return implode(',', array_map(function (GeometryInterface $geometry) { return $geometry->toWKT(); - }, $this->geometries)); + }, $this->items)); } public static function fromString($wktArgument) @@ -58,9 +64,52 @@ public static function fromString($wktArgument) }, $geometry_strings)); } + public function toArray() + { + return $this->items; + } + + public function getIterator() + { + return new ArrayIterator($this->items); + } + + public function offsetExists($offset) + { + return isset($this->items[$offset]); + } + + public function offsetGet($offset) + { + return $this->offsetExists($offset) ? $this->items[$offset] : null; + } + + public function offsetSet($offset, $value) + { + if (! ($value instanceof GeometryInterface)) { + throw new InvalidArgumentException('$value must be an instance of GeometryInterface'); + } + + if (is_null($offset)) { + $this->items[] = $value; + } else { + $this->items[$offset] = $value; + } + } + + public function offsetUnset($offset) + { + unset($this->items[$offset]); + } + public function count() { - return count($this->geometries); + return count($this->items); + } + + public function toJson($options = 0) + { + return json_encode($this, $options); } /** @@ -71,7 +120,7 @@ public function count() public function jsonSerialize() { $geometries = []; - foreach ($this->geometries as $geometry) { + foreach ($this->items as $geometry) { $geometries[] = $geometry->jsonSerialize(); } diff --git a/src/Types/LineString.php b/src/Types/LineString.php index 851aa2dd..64f64338 100644 --- a/src/Types/LineString.php +++ b/src/Types/LineString.php @@ -2,7 +2,7 @@ namespace Grimzy\LaravelMysqlSpatial\Types; -class LineString extends PointCollection implements GeometryInterface +class LineString extends PointCollection { public function toWKT() { @@ -39,7 +39,7 @@ public function __toString() public function jsonSerialize() { $points = []; - foreach ($this->points as $point) { + foreach ($this->items as $point) { $points[] = $point->jsonSerialize(); } diff --git a/src/Types/MultiLineString.php b/src/Types/MultiLineString.php index 2c6e8945..032aa2e6 100644 --- a/src/Types/MultiLineString.php +++ b/src/Types/MultiLineString.php @@ -2,16 +2,10 @@ namespace Grimzy\LaravelMysqlSpatial\Types; -use Countable; use InvalidArgumentException; -class MultiLineString extends Geometry implements Countable +class MultiLineString extends GeometryCollection { - /** - * @var LineString[] - */ - protected $linestrings = []; - /** * @param LineString[] $linestrings */ @@ -29,12 +23,12 @@ public function __construct(array $linestrings) throw new InvalidArgumentException('$linestrings must be an array of LineString'); } - $this->linestrings = $linestrings; + parent::__construct($linestrings); } public function getLineStrings() { - return $this->linestrings; + return $this->items; } public function toWKT() @@ -59,9 +53,13 @@ public function __toString() }, $this->getLineStrings())); } - public function count() + public function offsetSet($offset, $value) { - return count($this->linestrings); + if (! ($value instanceof LineString)) { + throw new InvalidArgumentException('$value must be an instance of LineString'); + } + + parent::offsetSet($offset, $value); } /** @@ -73,7 +71,7 @@ public function jsonSerialize() { $linestrings = []; - foreach ($this->linestrings as $linestring) { + foreach ($this->items as $linestring) { $linestrings[] = $linestring->jsonSerialize(); } diff --git a/src/Types/MultiPoint.php b/src/Types/MultiPoint.php index b3993605..8e0b0f82 100644 --- a/src/Types/MultiPoint.php +++ b/src/Types/MultiPoint.php @@ -2,7 +2,7 @@ namespace Grimzy\LaravelMysqlSpatial\Types; -class MultiPoint extends PointCollection implements GeometryInterface, \JsonSerializable +class MultiPoint extends PointCollection { public function toWKT() { @@ -32,7 +32,7 @@ public function __toString() { return implode(',', array_map(function (Point $point) { return sprintf('(%s)', $point->toPair()); - }, $this->points)); + }, $this->items)); } /** @@ -43,7 +43,7 @@ public function __toString() public function jsonSerialize() { $points = []; - foreach ($this->points as $point) { + foreach ($this->items as $point) { $points[] = $point->jsonSerialize(); } diff --git a/src/Types/MultiPolygon.php b/src/Types/MultiPolygon.php index 45339966..a4bb7660 100644 --- a/src/Types/MultiPolygon.php +++ b/src/Types/MultiPolygon.php @@ -2,16 +2,10 @@ namespace Grimzy\LaravelMysqlSpatial\Types; -use Countable; use InvalidArgumentException; -class MultiPolygon extends Geometry implements Countable +class MultiPolygon extends GeometryCollection { - /** - * @var Polygon[] - */ - protected $polygons; - /** * @param Polygon[] $polygons */ @@ -24,7 +18,7 @@ public function __construct(array $polygons) if (count($polygons) !== count($validated)) { throw new InvalidArgumentException('$polygons must be an array of Polygon'); } - $this->polygons = $polygons; + parent::__construct($polygons); } public function toWKT() @@ -36,7 +30,7 @@ public function __toString() { return implode(',', array_map(function (Polygon $polygon) { return sprintf('(%s)', (string) $polygon); - }, $this->polygons)); + }, $this->items)); } public static function fromString($wktArgument) @@ -49,22 +43,6 @@ public static function fromString($wktArgument) }, $polygons)); } - /** - * (PHP 5 >= 5.1.0)
- * Count elements of an object. - * - * @link http://php.net/manual/en/countable.count.php - * - * @return int The custom count as an integer. - *

- *

- * The return value is cast to an integer. - */ - public function count() - { - return count($this->polygons); - } - /** * Get the polygons that make up this MultiPolygon. * @@ -72,7 +50,7 @@ public function count() */ public function getPolygons() { - return $this->polygons; + return $this->items; } /** @@ -110,6 +88,15 @@ protected static function assembleParts(array $parts) return $polygons; } + public function offsetSet($offset, $value) + { + if (! ($value instanceof Polygon)) { + throw new InvalidArgumentException('$value must be an instance of Polygon'); + } + + parent::offsetSet($offset, $value); + } + /** * Convert to GeoJson MultiPolygon that is jsonable to GeoJSON. * @@ -118,7 +105,7 @@ protected static function assembleParts(array $parts) public function jsonSerialize() { $polygons = []; - foreach ($this->polygons as $polygon) { + foreach ($this->items as $polygon) { $polygons[] = $polygon->jsonSerialize(); } diff --git a/src/Types/PointCollection.php b/src/Types/PointCollection.php index de57dd3c..abc74cd8 100755 --- a/src/Types/PointCollection.php +++ b/src/Types/PointCollection.php @@ -3,21 +3,10 @@ namespace Grimzy\LaravelMysqlSpatial\Types; use ArrayAccess; -use ArrayIterator; -use Countable; -use Illuminate\Contracts\Support\Arrayable; -use Illuminate\Contracts\Support\Jsonable; use InvalidArgumentException; -use IteratorAggregate; -use JsonSerializable; -abstract class PointCollection implements IteratorAggregate, ArrayAccess, Arrayable, Countable, Jsonable, JsonSerializable +abstract class PointCollection extends GeometryCollection { - /** - * @var Point[] - */ - protected $points; - /** * @param Point[] $points */ @@ -34,27 +23,15 @@ public function __construct(array $points) if (count($points) !== count($validated)) { throw new InvalidArgumentException('$points must be an array of Points'); } - $this->points = $points; - } - public function toArray() - { - return $this->points; + parent::__construct($points); } - public function getIterator() - { - return new ArrayIterator($this->points); - } - - public function offsetExists($offset) - { - return isset($this->points[$offset]); - } - - public function offsetGet($offset) + public function toPairList() { - return $this->offsetExists($offset) ? $this->points[$offset] : null; + return implode(',', array_map(function (Point $point) { + return $point->toPair(); + }, $this->items)); } public function offsetSet($offset, $value) @@ -63,47 +40,15 @@ public function offsetSet($offset, $value) throw new InvalidArgumentException('$value must be an instance of Point'); } - if (is_null($offset)) { - $this->points[] = $value; - } else { - $this->points[$offset] = $value; - } - } - - public function offsetUnset($offset) - { - unset($this->points[$offset]); - } - - public function count() - { - return count($this->points); - } - - public function toJson($options = 0) - { - return json_encode($this, $options); - } - - public function toPairList() - { - return implode(',', array_map(function (Point $point) { - return $point->toPair(); - }, $this->points)); + parent::offsetSet($offset, $value); } /** * @return array|\Grimzy\LaravelMysqlSpatial\Types\Point[] - * - * @deprecated 2.1.0 Use $multipoint->toArray() instead - * - * @see IteratorAggregate - * @see ArrayAccess - * @see Arrayable */ public function getPoints() { - return $this->points; + return $this->items; } /** @@ -116,7 +61,7 @@ public function getPoints() */ public function prependPoint(Point $point) { - array_unshift($this->points, $point); + array_unshift($this->items, $point); } /** @@ -128,7 +73,7 @@ public function prependPoint(Point $point) */ public function appendPoint(Point $point) { - $this->points[] = $point; + $this->items[] = $point; } /** @@ -142,10 +87,10 @@ public function appendPoint(Point $point) */ public function insertPoint($index, Point $point) { - if (count($this->points) - 1 < $index) { + if (count($this->items) - 1 < $index) { throw new InvalidArgumentException('$index is greater than the size of the array'); } - array_splice($this->points, $index, 0, [$point]); + array_splice($this->items, $index, 0, [$point]); } } diff --git a/src/Types/Polygon.php b/src/Types/Polygon.php index 70df6a3a..87f8dd04 100644 --- a/src/Types/Polygon.php +++ b/src/Types/Polygon.php @@ -2,9 +2,7 @@ namespace Grimzy\LaravelMysqlSpatial\Types; -use Countable; - -class Polygon extends MultiLineString implements Countable +class Polygon extends MultiLineString { public function toWKT() { @@ -19,7 +17,7 @@ public function toWKT() public function jsonSerialize() { $linearrings = []; - foreach ($this->linestrings as $linestring) { + foreach ($this->items as $linestring) { $linearrings[] = new \GeoJson\Geometry\LinearRing($linestring->jsonSerialize()->getCoordinates()); } From 32e95ba5fd846444032959fa6b5b075fbb1ee075 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 24 Sep 2017 18:42:27 -0400 Subject: [PATCH 28/57] Removed duplicate implementation. (cherry picked from commit d1e8510) --- src/Types/GeometryCollection.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Types/GeometryCollection.php b/src/Types/GeometryCollection.php index ee909246..21dd9a75 100755 --- a/src/Types/GeometryCollection.php +++ b/src/Types/GeometryCollection.php @@ -107,11 +107,6 @@ public function count() return count($this->items); } - public function toJson($options = 0) - { - return json_encode($this, $options); - } - /** * Convert to GeoJson GeometryCollection that is jsonable to GeoJSON. * From 575bef7e2318369398cae4fe06b79a43882a8375 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 24 Sep 2017 20:32:42 -0400 Subject: [PATCH 29/57] Added tests for #15 (cherry picked from commit d179974) --- tests/Unit/Types/GeometryCollectionTest.php | 74 +++++++++++++++++++-- tests/Unit/Types/GeometryTest.php | 7 ++ tests/Unit/Types/MultiLineStringTest.php | 42 ++++++++++-- tests/Unit/Types/MultiPointTest.php | 71 ++++++-------------- tests/Unit/Types/MultiPolygonTest.php | 70 ++++++++++++++----- 5 files changed, 183 insertions(+), 81 deletions(-) diff --git a/tests/Unit/Types/GeometryCollectionTest.php b/tests/Unit/Types/GeometryCollectionTest.php index 09e03297..ac88a829 100644 --- a/tests/Unit/Types/GeometryCollectionTest.php +++ b/tests/Unit/Types/GeometryCollectionTest.php @@ -1,8 +1,10 @@ getGeometryCollection(); + + $this->assertInternalType('array', $geometryCollection->toArray()); + } + + public function testIteratorAggregate() + { + $geometryCollection = $this->getGeometryCollection(); + + foreach ($geometryCollection as $value) { + $this->assertInstanceOf(GeometryInterface::class, $value); + } + } + + public function testArrayAccess() + { + $linestring = $this->getLineString(); + $point = $this->getPoint(); + $geometryCollection = new GeometryCollection([$linestring, $point]); + + // assert getting + $this->assertEquals($linestring, $geometryCollection[0]); + $this->assertEquals($point, $geometryCollection[1]); + + // assert setting + $polygon = $this->getPolygon(); + $geometryCollection[] = $polygon; + $this->assertEquals($polygon, $geometryCollection[2]); + + // assert unset + unset($geometryCollection[0]); + $this->assertNull($geometryCollection[0]); + $this->assertEquals($point, $geometryCollection[1]); + $this->assertEquals($polygon, $geometryCollection[2]); + + // assert insert + $point100 = new Point(100, 100); + $geometryCollection[100] = $point100; + $this->assertEquals($point100, $geometryCollection[100]); + + // assert invalid + $this->assertException(InvalidArgumentException::class); + $geometryCollection[] = 1; + } + private function getGeometryCollection() { return new GeometryCollection([$this->getLineString(), $this->getPoint()]); @@ -48,16 +97,29 @@ private function getGeometryCollection() private function getLineString() { return new LineString([ - new Point(0, 0), - new Point(0, 1), - new Point(1, 1), - new Point(1, 0), - new Point(0, 0), - ]); + new Point(0, 0), + new Point(0, 1), + new Point(1, 1), + new Point(1, 0), + new Point(0, 0), + ]); } private function getPoint() { return new Point(100, 200); } + + private function getPolygon() + { + return new Polygon([ + new LineString([ + new Point(0, 0), + new Point(0, 1), + new Point(1, 1), + new Point(1, 0), + new Point(0, 0), + ]), + ]); + } } diff --git a/tests/Unit/Types/GeometryTest.php b/tests/Unit/Types/GeometryTest.php index 769b19dc..a763b948 100644 --- a/tests/Unit/Types/GeometryTest.php +++ b/tests/Unit/Types/GeometryTest.php @@ -52,4 +52,11 @@ public function testGetWKBClass() $prefix = "\0\0\0\0"; $this->assertInstanceOf(Point::class, Geometry::fromWKB($prefix.'0101000000000000000000f03f0000000000000040')); } + + public function testToJson() + { + $point = new Point(1, 1); + + $this->assertSame('{"type":"Point","coordinates":[1,1]}', $point->toJson()); + } } diff --git a/tests/Unit/Types/MultiLineStringTest.php b/tests/Unit/Types/MultiLineStringTest.php index 08360c7e..5f0760ec 100644 --- a/tests/Unit/Types/MultiLineStringTest.php +++ b/tests/Unit/Types/MultiLineStringTest.php @@ -17,12 +17,12 @@ public function testFromWKT() public function testToWKT() { $collection = new LineString([ - new Point(0, 0), - new Point(0, 1), - new Point(1, 1), - new Point(1, 0), - new Point(0, 0), - ]); + new Point(0, 0), + new Point(0, 1), + new Point(1, 1), + new Point(1, 0), + new Point(0, 0), + ]); $multilinestring = new MultiLineString([$collection]); @@ -51,4 +51,34 @@ public function testInvalidArgumentExceptionNotArrayOfLineString() new Point(0, 1), ]); } + + public function testArrayAccess() + { + $linestring0 = new LineString([ + new Point(0, 0), + new Point(1, 1), + ]); + $linestring1 = new LineString([ + new Point(1, 1), + new Point(2, 2), + ]); + + $multilinestring = new MultiLineString([$linestring0, $linestring1]); + + // assert getting + $this->assertEquals($linestring0, $multilinestring[0]); + $this->assertEquals($linestring1, $multilinestring[1]); + + // assert setting + $linestring2 = new LineString([ + new Point(2, 2), + new Point(3, 3), + ]); + $multilinestring[] = $linestring2; + $this->assertEquals($linestring2, $multilinestring[2]); + + // assert invalid + $this->assertException(InvalidArgumentException::class); + $multilinestring[] = 1; + } } diff --git a/tests/Unit/Types/MultiPointTest.php b/tests/Unit/Types/MultiPointTest.php index 0e0e0643..ee0bb94d 100644 --- a/tests/Unit/Types/MultiPointTest.php +++ b/tests/Unit/Types/MultiPointTest.php @@ -29,57 +29,6 @@ public function testGetPoints() $this->assertInstanceOf(Point::class, $multipoint->getPoints()[0]); } - public function testToArray() - { - $multipoint = MultiPoint::fromWKT('MULTIPOINT((0 0),(1 0),(1 1))'); - - $this->assertInstanceOf(Point::class, $multipoint->toArray()[0]); - } - - public function testIteratorAggregate() - { - $multipoint = MultiPoint::fromWKT('MULTIPOINT((0 0),(1 0),(1 1))'); - - foreach ($multipoint as $value) { - $this->assertInstanceOf(Point::class, $value); - } - } - - public function testArrayAccess() - { - $point0 = new Point(0, 0); - $point1 = new Point(1, 1); - $multipoint = new MultiPoint([$point0, $point1]); - - $this->assertEquals($point0, $multipoint[0]); - $this->assertEquals($point1, $multipoint[1]); - $point2 = new Point(2, 2); - - $multipoint[] = $point2; - $this->assertEquals($point2, $multipoint[2]); - - unset($multipoint[0]); - $this->assertNull($multipoint[0]); - $this->assertEquals($point1, $multipoint[1]); - $this->assertEquals($point2, $multipoint[2]); - - $point100 = new Point(100, 100); - $multipoint[100] = $point100; - $this->assertEquals($point100, $multipoint[100]); - - $this->assertException(InvalidArgumentException::class); - $multipoint[] = 1; - } - - public function testToJson() - { - $collection = [new Point(0, 0), new Point(0, 1), new Point(1, 1)]; - - $multipoint = new MultiPoint($collection); - - $this->assertSame('{"type":"MultiPoint","coordinates":[[0,0],[1,0],[1,1]]}', $multipoint->toJson()); - } - public function testJsonSerialize() { $collection = [new Point(0, 0), new Point(0, 1), new Point(1, 1)]; @@ -105,6 +54,26 @@ public function testInvalidArgumentExceptionNotArrayOfLineString() ]); } + public function testArrayAccess() + { + $point0 = new Point(0, 0); + $point1 = new Point(1, 1); + $multipoint = new MultiPoint([$point0, $point1]); + + // assert getting + $this->assertEquals($point0, $multipoint[0]); + $this->assertEquals($point1, $multipoint[1]); + + // assert setting + $point2 = new Point(2, 2); + $multipoint[] = $point2; + $this->assertEquals($point2, $multipoint[2]); + + // assert invalid + $this->assertException(InvalidArgumentException::class); + $multipoint[] = 1; + } + public function testDeprecatedPrependPoint() { $point1 = new Point(1, 1); diff --git a/tests/Unit/Types/MultiPolygonTest.php b/tests/Unit/Types/MultiPolygonTest.php index 438b8f96..f8c87375 100644 --- a/tests/Unit/Types/MultiPolygonTest.php +++ b/tests/Unit/Types/MultiPolygonTest.php @@ -49,6 +49,27 @@ public function testInvalidArgumentExceptionNotArrayOfLineString() ]); } + public function testArrayAccess() + { + $polygon0 = $this->getPolygon1(); + $polygon1 = $this->getPolygon2(); + + $multipolygon = new MultiPolygon([$polygon0, $polygon1]); + + // assert getting + $this->assertEquals($polygon0, $multipolygon[0]); + $this->assertEquals($polygon1, $multipolygon[1]); + + // assert setting + $polygon2 = $this->getPolygon3(); + $multipolygon[] = $polygon2; + $this->assertEquals($polygon2, $multipolygon[2]); + + // assert invalid + $this->assertException(InvalidArgumentException::class); + $multipolygon[] = 1; + } + private function getMultiPolygon() { return new MultiPolygon([$this->getPolygon1(), $this->getPolygon2()]); @@ -57,34 +78,34 @@ private function getMultiPolygon() private function getLineString1() { return new LineString([ - new Point(0, 0), - new Point(0, 1), - new Point(1, 1), - new Point(1, 0), - new Point(0, 0), - ]); + new Point(0, 0), + new Point(0, 1), + new Point(1, 1), + new Point(1, 0), + new Point(0, 0), + ]); } private function getLineString2() { return new LineString([ - new Point(10, 10), - new Point(10, 20), - new Point(20, 20), - new Point(20, 10), - new Point(10, 10), - ]); + new Point(10, 10), + new Point(10, 20), + new Point(20, 20), + new Point(20, 10), + new Point(10, 10), + ]); } private function getLineString3() { return new LineString([ - new Point(100, 100), - new Point(100, 200), - new Point(200, 200), - new Point(200, 100), - new Point(100, 100), - ]); + new Point(100, 100), + new Point(100, 200), + new Point(200, 200), + new Point(200, 100), + new Point(100, 100), + ]); } private function getPolygon1() @@ -96,4 +117,17 @@ private function getPolygon2() { return new Polygon([$this->getLineString3()]); } + + private function getPolygon3() + { + return new Polygon([ + new LineString([ + new Point(10, 10), + new Point(10, 20), + new Point(20, 20), + new Point(20, 10), + new Point(10, 10), + ]), + ]); + } } From 6af11ee8ef5f7d0fb105100d2ea8d3841637ca92 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 24 Sep 2017 20:44:32 -0400 Subject: [PATCH 30/57] Style CI fix :performing_arts: (cherry picked from commit d602134) --- src/Types/GeometryCollection.php | 2 +- src/Types/MultiLineString.php | 2 +- src/Types/MultiPolygon.php | 2 +- src/Types/PointCollection.php | 5 +---- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Types/GeometryCollection.php b/src/Types/GeometryCollection.php index 21dd9a75..3f857dd4 100755 --- a/src/Types/GeometryCollection.php +++ b/src/Types/GeometryCollection.php @@ -86,7 +86,7 @@ public function offsetGet($offset) public function offsetSet($offset, $value) { - if (! ($value instanceof GeometryInterface)) { + if (!($value instanceof GeometryInterface)) { throw new InvalidArgumentException('$value must be an instance of GeometryInterface'); } diff --git a/src/Types/MultiLineString.php b/src/Types/MultiLineString.php index 032aa2e6..25f3389d 100644 --- a/src/Types/MultiLineString.php +++ b/src/Types/MultiLineString.php @@ -55,7 +55,7 @@ public function __toString() public function offsetSet($offset, $value) { - if (! ($value instanceof LineString)) { + if (!($value instanceof LineString)) { throw new InvalidArgumentException('$value must be an instance of LineString'); } diff --git a/src/Types/MultiPolygon.php b/src/Types/MultiPolygon.php index a4bb7660..36f0937e 100644 --- a/src/Types/MultiPolygon.php +++ b/src/Types/MultiPolygon.php @@ -90,7 +90,7 @@ protected static function assembleParts(array $parts) public function offsetSet($offset, $value) { - if (! ($value instanceof Polygon)) { + if (!($value instanceof Polygon)) { throw new InvalidArgumentException('$value must be an instance of Polygon'); } diff --git a/src/Types/PointCollection.php b/src/Types/PointCollection.php index abc74cd8..af586b28 100755 --- a/src/Types/PointCollection.php +++ b/src/Types/PointCollection.php @@ -36,7 +36,7 @@ public function toPairList() public function offsetSet($offset, $value) { - if (! ($value instanceof Point)) { + if (!($value instanceof Point)) { throw new InvalidArgumentException('$value must be an instance of Point'); } @@ -55,7 +55,6 @@ public function getPoints() * @param \Grimzy\LaravelMysqlSpatial\Types\Point $point * * @deprecated 2.1.0 Use array_unshift($multipoint, $point); instead - * * @see array_unshift * @see ArrayAccess */ @@ -68,7 +67,6 @@ public function prependPoint(Point $point) * @param \Grimzy\LaravelMysqlSpatial\Types\Point $point * * @deprecated 2.1.0 Use $multipoint[] = $point; instead - * * @see ArrayAccess */ public function appendPoint(Point $point) @@ -81,7 +79,6 @@ public function appendPoint(Point $point) * @param \Grimzy\LaravelMysqlSpatial\Types\Point $point * * @deprecated 2.1.0 Use array_splice($multipoint, $index, 0, [$point]); instead - * * @see array_splice * @see ArrayAccess */ From 17550d381414368caf811fbecb527b3927d23b84 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 24 Sep 2017 22:03:10 -0400 Subject: [PATCH 31/57] camelCased $lineString. (cherry picked from commit 0fc7e33) --- src/Types/MultiLineString.php | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Types/MultiLineString.php b/src/Types/MultiLineString.php index 25f3389d..7d8dcd18 100644 --- a/src/Types/MultiLineString.php +++ b/src/Types/MultiLineString.php @@ -7,23 +7,23 @@ class MultiLineString extends GeometryCollection { /** - * @param LineString[] $linestrings + * @param LineString[] $lineStrings */ - public function __construct(array $linestrings) + public function __construct(array $lineStrings) { - if (count($linestrings) < 1) { - throw new InvalidArgumentException('$linestrings must contain at least one entry'); + if (count($lineStrings) < 1) { + throw new InvalidArgumentException('$lineStrings must contain at least one entry'); } - $validated = array_filter($linestrings, function ($value) { + $validated = array_filter($lineStrings, function ($value) { return $value instanceof LineString; }); - if (count($linestrings) !== count($validated)) { - throw new InvalidArgumentException('$linestrings must be an array of LineString'); + if (count($lineStrings) !== count($validated)) { + throw new InvalidArgumentException('$lineStrings must be an array of LineString'); } - parent::__construct($linestrings); + parent::__construct($lineStrings); } public function getLineStrings() @@ -39,17 +39,17 @@ public function toWKT() public static function fromString($wktArgument) { $str = preg_split('/\)\s*,\s*\(/', substr(trim($wktArgument), 1, -1)); - $linestrings = array_map(function ($data) { + $lineStrings = array_map(function ($data) { return LineString::fromString($data); }, $str); - return new static($linestrings); + return new static($lineStrings); } public function __toString() { - return implode(',', array_map(function (LineString $linestring) { - return sprintf('(%s)', (string) $linestring); + return implode(',', array_map(function (LineString $lineString) { + return sprintf('(%s)', (string) $lineString); }, $this->getLineStrings())); } @@ -69,12 +69,12 @@ public function offsetSet($offset, $value) */ public function jsonSerialize() { - $linestrings = []; + $lineStrings = []; - foreach ($this->items as $linestring) { - $linestrings[] = $linestring->jsonSerialize(); + foreach ($this->items as $lineString) { + $lineStrings[] = $lineString->jsonSerialize(); } - return new \GeoJson\Geometry\MultiLineString($linestrings); + return new \GeoJson\Geometry\MultiLineString($lineStrings); } } From 8bb1de91050fa9237f92f05221fa71752d7f3f35 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 24 Sep 2017 22:08:07 -0400 Subject: [PATCH 32/57] camelCased $linearRing. (cherry picked from commit e90ed9e) --- src/Types/Polygon.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Types/Polygon.php b/src/Types/Polygon.php index 87f8dd04..6710da3c 100644 --- a/src/Types/Polygon.php +++ b/src/Types/Polygon.php @@ -16,11 +16,11 @@ public function toWKT() */ public function jsonSerialize() { - $linearrings = []; - foreach ($this->items as $linestring) { - $linearrings[] = new \GeoJson\Geometry\LinearRing($linestring->jsonSerialize()->getCoordinates()); + $linearRings = []; + foreach ($this->items as $lineString) { + $linearRings[] = new \GeoJson\Geometry\LinearRing($lineString->jsonSerialize()->getCoordinates()); } - return new \GeoJson\Geometry\Polygon($linearrings); + return new \GeoJson\Geometry\Polygon($linearRings); } } From 6337d150c67a00612d505b9d6a2671bb8229f118 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 31 Dec 2017 18:53:16 +0200 Subject: [PATCH 33/57] Fixes #33: Updated code climate's badges in documentation :bowtie: (cherry picked from commit 489d1c7) --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d64d62df..68985768 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ # Laravel MySQL Spatial extension [![Build Status](https://img.shields.io/travis/grimzy/laravel-mysql-spatial.svg?style=flat-square)](https://travis-ci.org/grimzy/laravel-mysql-spatial) -[![Code Climate](https://img.shields.io/codeclimate/github/grimzy/laravel-mysql-spatial/badges/gpa.svg?style=flat-square)](https://codeclimate.com/github/grimzy/laravel-mysql-spatial) -[![Code Climate](https://img.shields.io/codeclimate/coverage/github/grimzy/laravel-mysql-spatial.svg?style=flat-square)](https://codeclimate.com/github/grimzy/laravel-mysql-spatial/coverage) -[![Packagist](https://img.shields.io/packagist/v/grimzy/laravel-mysql-spatial.svg?style=flat-square)](https://packagist.org/packages/grimzy/laravel-mysql-spatial) +[![Code Climate](https://img.shields.io/codeclimate/maintainability/grimzy/laravel-mysql-spatial.svg?style=flat-square)](https://codeclimate.com/github/grimzy/laravel-mysql-spatial/maintainability) +[![Code Climate](https://img.shields.io/codeclimate/c/grimzy/laravel-mysql-spatial.svg?style=flat-square&colorB=4BCA2A)](https://codeclimate.com/github/grimzy/laravel-mysql-spatial/test_coverage)[![Packagist](https://img.shields.io/packagist/v/grimzy/laravel-mysql-spatial.svg?style=flat-square)](https://packagist.org/packages/grimzy/laravel-mysql-spatial) [![Packagist](https://img.shields.io/packagist/dt/grimzy/laravel-mysql-spatial.svg?style=flat-square)](https://packagist.org/packages/grimzy/laravel-mysql-spatial) [![license](https://img.shields.io/github/license/mashape/apistatus.svg?style=flat-square)](LICENSE) From 4ca6a89a6f4a1cb2be165203e3e9349dc15862a8 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 1 Oct 2017 10:02:40 +0200 Subject: [PATCH 34/57] Added fromJson($geoJson) to GeometryInterface (#23) (cherry picked from commit 8e0119e7da42cd2ab59f21cacdc2ae7009abd8ef) --- src/Exceptions/InvalidGeoJsonException.php | 7 ++ src/Types/Geometry.php | 18 +++ src/Types/GeometryCollection.php | 21 ++++ src/Types/GeometryInterface.php | 2 + src/Types/LineString.php | 24 +++- src/Types/MultiLineString.php | 27 ++++- src/Types/MultiPoint.php | 24 +++- src/Types/MultiPolygon.php | 31 ++++- src/Types/Point.php | 24 +++- src/Types/Polygon.php | 28 ++++- tests/Unit/Eloquent/SpatialTraitTest.php | 18 +++ .../Unit/Schema/Grammars/MySqlGrammarTest.php | 20 ++++ tests/Unit/Types/GeometryCollectionTest.php | 14 +++ tests/Unit/Types/GeometryTest.php | 107 ++++++++++++++++++ tests/Unit/Types/LineStringTest.php | 13 +++ tests/Unit/Types/MultiLineStringTest.php | 18 +++ tests/Unit/Types/MultiPointTest.php | 15 +++ tests/Unit/Types/MultiPolygonTest.php | 26 +++++ tests/Unit/Types/PointTest.php | 12 ++ tests/Unit/Types/PolygonTest.php | 22 ++++ 20 files changed, 465 insertions(+), 6 deletions(-) create mode 100644 src/Exceptions/InvalidGeoJsonException.php diff --git a/src/Exceptions/InvalidGeoJsonException.php b/src/Exceptions/InvalidGeoJsonException.php new file mode 100644 index 00000000..f913cf04 --- /dev/null +++ b/src/Exceptions/InvalidGeoJsonException.php @@ -0,0 +1,7 @@ +getType() === 'FeatureCollection') { + return GeometryCollection::fromJson($geoJson); + } + + if($geoJson->getType() === 'Feature') { + $geoJson = $geoJson->getGeometry(); + } + + $type = '\Grimzy\LaravelMysqlSpatial\Types\\'.$geoJson->getType(); + return $type::fromJson($geoJson); + } + public function toJson($options = 0) { return json_encode($this, $options); diff --git a/src/Types/GeometryCollection.php b/src/Types/GeometryCollection.php index 3f857dd4..26a4b439 100755 --- a/src/Types/GeometryCollection.php +++ b/src/Types/GeometryCollection.php @@ -5,6 +5,9 @@ use ArrayAccess; use ArrayIterator; use Countable; +use GeoJson\Feature\FeatureCollection; +use GeoJson\GeoJson; +use Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException; use Illuminate\Contracts\Support\Arrayable; use InvalidArgumentException; use IteratorAggregate; @@ -107,6 +110,24 @@ public function count() return count($this->items); } + public static function fromJson ($geoJson) + { + if(is_string($geoJson)) { + $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); + } + + if(!is_a($geoJson, FeatureCollection::class)) { + throw new InvalidGeoJsonException('Expected ' . FeatureCollection::class . ', got ' . get_class($geoJson)); + } + + $set = []; + foreach ($geoJson->getFeatures() as $feature) { + $set[] = parent::fromJson($feature); + } + + return new GeometryCollection($set); + } + /** * Convert to GeoJson GeometryCollection that is jsonable to GeoJSON. * diff --git a/src/Types/GeometryInterface.php b/src/Types/GeometryInterface.php index 330ec927..aca2bfb0 100644 --- a/src/Types/GeometryInterface.php +++ b/src/Types/GeometryInterface.php @@ -11,4 +11,6 @@ public static function fromWKT($wkt); public function __toString(); public static function fromString($wktArgument); + + public static function fromJson($geoJson); } diff --git a/src/Types/LineString.php b/src/Types/LineString.php index 64f64338..59cd3662 100644 --- a/src/Types/LineString.php +++ b/src/Types/LineString.php @@ -2,6 +2,10 @@ namespace Grimzy\LaravelMysqlSpatial\Types; +use GeoJson\GeoJson; +use GeoJson\Geometry\LineString as GeoJsonLineString; +use Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException; + class LineString extends PointCollection { public function toWKT() @@ -31,6 +35,24 @@ public function __toString() return $this->toPairList(); } + public static function fromJson ($geoJson) + { + if(is_string($geoJson)) { + $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); + } + + if(!is_a($geoJson, GeoJsonLineString::class)) { + throw new InvalidGeoJsonException('Expected ' . GeoJsonLineString::class . ', got ' . get_class($geoJson)); + } + + $set = []; + foreach($geoJson->getCoordinates() as $coordinate) { + $set[] = new Point($coordinate[1], $coordinate[0]); + } + + return new LineString($set); + } + /** * Convert to GeoJson LineString that is jsonable to GeoJSON. * @@ -43,6 +65,6 @@ public function jsonSerialize() $points[] = $point->jsonSerialize(); } - return new \GeoJson\Geometry\LineString($points); + return new GeoJsonLineString($points); } } diff --git a/src/Types/MultiLineString.php b/src/Types/MultiLineString.php index 7d8dcd18..025fb4e3 100644 --- a/src/Types/MultiLineString.php +++ b/src/Types/MultiLineString.php @@ -2,6 +2,9 @@ namespace Grimzy\LaravelMysqlSpatial\Types; +use GeoJson\GeoJson; +use GeoJson\Geometry\MultiLineString as GeoJsonMultiLineString; +use Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException; use InvalidArgumentException; class MultiLineString extends GeometryCollection @@ -62,6 +65,28 @@ public function offsetSet($offset, $value) parent::offsetSet($offset, $value); } + public static function fromJson ($geoJson) + { + if(is_string($geoJson)) { + $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); + } + + if(!is_a($geoJson, GeoJsonMultiLineString::class)) { + throw new InvalidGeoJsonException('Expected ' . GeoJsonMultiLineString::class . ', got ' . get_class($geoJson)); + } + + $set = []; + foreach($geoJson->getCoordinates() as $coordinates) { + $points = []; + foreach($coordinates as $coordinate) { + $points[] = new Point($coordinate[1], $coordinate[0]); + } + $set[] = new LineString($points); + } + + return new MultiLineString($set); + } + /** * Convert to GeoJson Point that is jsonable to GeoJSON. * @@ -75,6 +100,6 @@ public function jsonSerialize() $lineStrings[] = $lineString->jsonSerialize(); } - return new \GeoJson\Geometry\MultiLineString($lineStrings); + return new GeoJsonMultiLineString($lineStrings); } } diff --git a/src/Types/MultiPoint.php b/src/Types/MultiPoint.php index 8e0b0f82..60fad9a5 100644 --- a/src/Types/MultiPoint.php +++ b/src/Types/MultiPoint.php @@ -2,6 +2,10 @@ namespace Grimzy\LaravelMysqlSpatial\Types; +use GeoJson\GeoJson; +use GeoJson\Geometry\MultiPoint as GeoJsonMultiPoint; +use Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException; + class MultiPoint extends PointCollection { public function toWKT() @@ -35,6 +39,24 @@ public function __toString() }, $this->items)); } + public static function fromJson ($geoJson) + { + if(is_string($geoJson)) { + $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); + } + + if(!is_a($geoJson, GeoJsonMultiPoint::class)) { + throw new InvalidGeoJsonException('Expected ' . GeoJsonMultiPoint::class . ', got ' . get_class($geoJson)); + } + + $set = []; + foreach($geoJson->getCoordinates() as $coordinate) { + $set[] = new Point($coordinate[1], $coordinate[0]); + } + + return new MultiPoint($set); + } + /** * Convert to GeoJson MultiPoint that is jsonable to GeoJSON. * @@ -47,6 +69,6 @@ public function jsonSerialize() $points[] = $point->jsonSerialize(); } - return new \GeoJson\Geometry\MultiPoint($points); + return new GeoJsonMultiPoint($points); } } diff --git a/src/Types/MultiPolygon.php b/src/Types/MultiPolygon.php index 36f0937e..927df911 100644 --- a/src/Types/MultiPolygon.php +++ b/src/Types/MultiPolygon.php @@ -2,6 +2,9 @@ namespace Grimzy\LaravelMysqlSpatial\Types; +use GeoJson\GeoJson; +use GeoJson\Geometry\MultiPolygon as GeoJsonMultiPolygon; +use Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException; use InvalidArgumentException; class MultiPolygon extends GeometryCollection @@ -97,6 +100,32 @@ public function offsetSet($offset, $value) parent::offsetSet($offset, $value); } + public static function fromJson ($geoJson) + { + if(is_string($geoJson)) { + $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); + } + + if(!is_a($geoJson, GeoJsonMultiPolygon::class)) { + throw new InvalidGeoJsonException('Expected ' . GeoJsonMultiPolygon::class . ', got ' . get_class($geoJson)); + } + + $set = []; + foreach($geoJson->getCoordinates() as $polygonCoordinates) { + $lineStrings = []; + foreach($polygonCoordinates as $lineStringCoordinates) { + $points = []; + foreach($lineStringCoordinates as $lineStringCoordinate) { + $points[] = new Point($lineStringCoordinate[1], $lineStringCoordinate[0]); + } + $lineStrings[] = new LineString($points); + } + $set[] = new Polygon($lineStrings); + } + + return new MultiPolygon($set); + } + /** * Convert to GeoJson MultiPolygon that is jsonable to GeoJSON. * @@ -109,6 +138,6 @@ public function jsonSerialize() $polygons[] = $polygon->jsonSerialize(); } - return new \GeoJson\Geometry\MultiPolygon($polygons); + return new GeoJsonMultiPolygon($polygons); } } diff --git a/src/Types/Point.php b/src/Types/Point.php index 6e8eb44f..07148355 100644 --- a/src/Types/Point.php +++ b/src/Types/Point.php @@ -2,6 +2,10 @@ namespace Grimzy\LaravelMysqlSpatial\Types; +use GeoJson\GeoJson; +use GeoJson\Geometry\Point as GeoJsonPoint; +use Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException; + class Point extends Geometry { protected $lat; @@ -61,6 +65,24 @@ public function __toString() return $this->getLng().' '.$this->getLat(); } + /** + * @param $geoJson \GeoJson\Feature\Feature|string + * @return \Grimzy\LaravelMysqlSpatial\Types\Point + */ + public static function fromJson ($geoJson) + { + if(is_string($geoJson)) { + $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); + } + + if(!is_a($geoJson, GeoJsonPoint::class)) { + throw new InvalidGeoJsonException('Expected ' . GeoJsonPoint::class . ', got ' . get_class($geoJson)); + } + + $coordinates = $geoJson->getCoordinates(); + return new Point($coordinates[1], $coordinates[0]); + } + /** * Convert to GeoJson Point that is jsonable to GeoJSON. * @@ -68,6 +90,6 @@ public function __toString() */ public function jsonSerialize() { - return new \GeoJson\Geometry\Point([$this->getLng(), $this->getLat()]); + return new GeoJsonPoint([$this->getLng(), $this->getLat()]); } } diff --git a/src/Types/Polygon.php b/src/Types/Polygon.php index 6710da3c..c9850c11 100644 --- a/src/Types/Polygon.php +++ b/src/Types/Polygon.php @@ -2,6 +2,10 @@ namespace Grimzy\LaravelMysqlSpatial\Types; +use GeoJson\GeoJson; +use GeoJson\Geometry\Polygon as GeoJsonPolygon; +use Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException; + class Polygon extends MultiLineString { public function toWKT() @@ -9,6 +13,28 @@ public function toWKT() return sprintf('POLYGON(%s)', (string) $this); } + public static function fromJson ($geoJson) + { + if(is_string($geoJson)) { + $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); + } + + if(!is_a($geoJson, GeoJsonPolygon::class)) { + throw new InvalidGeoJsonException('Expected ' . GeoJsonPolygon::class . ', got ' . get_class($geoJson)); + } + + $set = []; + foreach($geoJson->getCoordinates() as $coordinates) { + $points = []; + foreach($coordinates as $coordinate) { + $points[] = new Point($coordinate[1], $coordinate[0]); + } + $set[] = new LineString($points); + } + + return new Polygon($set); + } + /** * Convert to GeoJson Polygon that is jsonable to GeoJSON. * @@ -21,6 +47,6 @@ public function jsonSerialize() $linearRings[] = new \GeoJson\Geometry\LinearRing($lineString->jsonSerialize()->getCoordinates()); } - return new \GeoJson\Geometry\Polygon($linearRings); + return new GeoJsonPolygon($linearRings); } } diff --git a/tests/Unit/Eloquent/SpatialTraitTest.php b/tests/Unit/Eloquent/SpatialTraitTest.php index b67a9695..16fea735 100644 --- a/tests/Unit/Eloquent/SpatialTraitTest.php +++ b/tests/Unit/Eloquent/SpatialTraitTest.php @@ -1,5 +1,6 @@ assertContains("GeomFromText('GEOMETRYCOLLECTION(POINT(2 1),LINESTRING(3 2,3 3))')", $this->queries[1]); } + public function testSettingRawAttributes() { + $attributes['point'] = '0101000000000000000000f03f0000000000000040'; + + $this->model->setRawAttributes($attributes); + $this->assertInstanceOf(Point::class, ($this->model->point)); + } + + public function testSpatialFieldsNotDefinedException() { + $model = new TestNoSpatialModel(); + $this->setExpectedException(SpatialFieldsNotDefinedException::class); + $model->getSpatialFields(); + } + public function testScopeDistance() { $point = new Point(1, 2); @@ -389,6 +403,10 @@ public function testmodels() } } +class TestNoSpatialModel extends Model { + use \Grimzy\LaravelMysqlSpatial\Eloquent\SpatialTrait; +} + class TestPDO extends PDO { public $queries = []; diff --git a/tests/Unit/Schema/Grammars/MySqlGrammarTest.php b/tests/Unit/Schema/Grammars/MySqlGrammarTest.php index 2040e4ab..4773a2ea 100644 --- a/tests/Unit/Schema/Grammars/MySqlGrammarTest.php +++ b/tests/Unit/Schema/Grammars/MySqlGrammarTest.php @@ -86,6 +86,26 @@ public function testAddingGeometryCollection() $this->assertContains('GEOMETRYCOLLECTION', $statements[0]); } + public function testAddRemoveSpatialIndex() + { + $blueprint = new Blueprint('test'); + $blueprint->point('foo'); + $blueprint->spatialIndex('foo'); + $addStatements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertEquals(2, count($addStatements)); + $this->assertContains('alter table `test` add spatial `test_foo_spatial`(`foo`)', $addStatements[1]); + + $blueprint->dropSpatialIndex(['foo']); + $blueprint->dropSpatialIndex('test_foo_spatial'); + $dropStatements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $expectedSql = 'alter table `test` drop index `test_foo_spatial`'; + $this->assertEquals(5, count($dropStatements)); + $this->assertContains($expectedSql, $dropStatements[3]); + $this->assertContains($expectedSql, $dropStatements[4]); + } + /** * @return Connection */ diff --git a/tests/Unit/Types/GeometryCollectionTest.php b/tests/Unit/Types/GeometryCollectionTest.php index ac88a829..b8089c4f 100644 --- a/tests/Unit/Types/GeometryCollectionTest.php +++ b/tests/Unit/Types/GeometryCollectionTest.php @@ -89,6 +89,20 @@ public function testArrayAccess() $geometryCollection[] = 1; } + public function testFromJson() { + $geometryCollection = GeometryCollection::fromJson('{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[1,2]}},{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[3,4]}}]}'); + $this->assertInstanceOf(GeometryCollection::class, $geometryCollection); + $geometryCollectionPoints = $geometryCollection->getGeometries(); + $this->assertEquals(2, count($geometryCollectionPoints)); + $this->assertEquals(new Point(2, 1), $geometryCollectionPoints[0]); + $this->assertEquals(new Point(4, 3), $geometryCollectionPoints[1]); + } + + public function testInvalidGeoJsonException() { + $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); + GeometryCollection::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); + } + private function getGeometryCollection() { return new GeometryCollection([$this->getLineString(), $this->getPoint()]); diff --git a/tests/Unit/Types/GeometryTest.php b/tests/Unit/Types/GeometryTest.php index a763b948..3068864d 100644 --- a/tests/Unit/Types/GeometryTest.php +++ b/tests/Unit/Types/GeometryTest.php @@ -53,6 +53,113 @@ public function testGetWKBClass() $this->assertInstanceOf(Point::class, Geometry::fromWKB($prefix.'0101000000000000000000f03f0000000000000040')); } + public function testFromJsonPoint() + { + $point = Geometry::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); + $this->assertInstanceOf(Point::class, $point); + $this->assertEquals(1.2, $point->getLat()); + $this->assertEquals(3.4, $point->getLng()); + } + + public function testFromJsonLineString() + { + $lineString = Geometry::fromJson('{"type": "LineString","coordinates":[[1,1],[2,2]]}'); + $this->assertInstanceOf(LineString::class, $lineString); + $lineStringPoints = $lineString->getGeometries(); + $this->assertEquals(new Point(1, 1), $lineStringPoints[0]); + $this->assertEquals(new Point(2, 2), $lineStringPoints[1]); + } + + public function testFromJsonPolygon() + { + $polygon1 = Geometry::fromJson('{"type": "Polygon","coordinates":[[[1,1],[2,1],[2,2],[1,2],[1,1]]]}'); + $this->assertInstanceOf(Polygon::class, $polygon1); + $polygonLineStrings1 = $polygon1->getGeometries(); + $this->assertEquals(1, count($polygonLineStrings1)); + $this->assertEquals(new Point(1, 1), $polygonLineStrings1[0][0]); + $this->assertEquals(new Point(1, 2), $polygonLineStrings1[0][1]); + $this->assertEquals(new Point(2, 2), $polygonLineStrings1[0][2]); + $this->assertEquals(new Point(2, 1), $polygonLineStrings1[0][3]); + $this->assertEquals(new Point(1, 1), $polygonLineStrings1[0][4]); + + $polygon2 = Geometry::fromJson('{"type":"Polygon","coordinates":[[[1,1],[2,1],[2,2],[1,2],[1,1]],[[1.2,1.2],[1.6,1.2],[1.6,1.8],[1.2,1.8],[1.2,1.2]]]}'); + $this->assertInstanceOf(Polygon::class, $polygon2); + $polygonLineStrings2 = $polygon2->getGeometries(); + $this->assertEquals(2, count($polygonLineStrings2)); + $this->assertEquals(new Point(1, 1), $polygonLineStrings2[0][0]); + $this->assertEquals(new Point(1, 2), $polygonLineStrings2[0][1]); + $this->assertEquals(new Point(2, 2), $polygonLineStrings2[0][2]); + $this->assertEquals(new Point(2, 1), $polygonLineStrings2[0][3]); + $this->assertEquals(new Point(1, 1), $polygonLineStrings2[0][4]); + $this->assertEquals(new Point(1.2, 1.2), $polygonLineStrings2[1][0]); + $this->assertEquals(new Point(1.2, 1.6), $polygonLineStrings2[1][1]); + $this->assertEquals(new Point(1.8, 1.6), $polygonLineStrings2[1][2]); + $this->assertEquals(new Point(1.8, 1.2), $polygonLineStrings2[1][3]); + $this->assertEquals(new Point(1.2, 1.2), $polygonLineStrings2[1][4]); + } + + public function testFromJsonMultiPoint() + { + $multiPoint = Geometry::fromJson('{"type":"MultiPoint","coordinates":[[1,1],[2,1],[2,2]]}'); + $this->assertInstanceOf(MultiPoint::class, $multiPoint); + $multiPointPoints = $multiPoint->getGeometries(); + $this->assertEquals(3, count($multiPointPoints)); + $this->assertEquals(new Point(1, 1), $multiPointPoints[0]); + $this->assertEquals(new Point(1, 2), $multiPointPoints[1]); + $this->assertEquals(new Point(2, 2), $multiPointPoints[2]); + } + + public function testFromJsonMultiLineString() + { + $multiLineString = Geometry::fromJson('{"type":"MultiLineString","coordinates":[[[1,1],[1,2],[1,3]],[[2,1],[2,2],[2,3]]]}'); + $this->assertInstanceOf(MultiLineString::class, $multiLineString); + $multiLineStringLineStrings = $multiLineString->getGeometries(); + $this->assertEquals(2, count($multiLineStringLineStrings)); + $this->assertEquals(new Point(1, 1), $multiLineStringLineStrings[0][0]); + $this->assertEquals(new Point(2, 1), $multiLineStringLineStrings[0][1]); + $this->assertEquals(new Point(3, 1), $multiLineStringLineStrings[0][2]); + $this->assertEquals(new Point(1, 2), $multiLineStringLineStrings[1][0]); + $this->assertEquals(new Point(2, 2), $multiLineStringLineStrings[1][1]); + $this->assertEquals(new Point(3, 2), $multiLineStringLineStrings[1][2]); + } + + public function testFromJsonMultiPolygon() { + $multiPolygon = Geometry::fromJson('{"type":"MultiPolygon","coordinates":[[[[1,1],[1,2],[2,2],[2,1],[1,1]]],[[[0,0],[0,1],[1,1],[1,0],[0,0]]]]}'); + $this->assertInstanceOf(MultiPolygon::class, $multiPolygon); + $multiPolygonPolygons = $multiPolygon->getGeometries(); + $this->assertEquals(2, count($multiPolygonPolygons)); + $this->assertEquals(new Polygon([new LineString([ + new Point(1, 1), + new Point(2, 1), + new Point(2, 2), + new Point(1, 2), + new Point(1, 1) + ])]), $multiPolygonPolygons[0]); + $this->assertEquals(new Polygon([new LineString([ + new Point(0, 0), + new Point(1, 0), + new Point(1, 1), + new Point(0, 1), + new Point(0, 0) + ])]), $multiPolygonPolygons[1]); + } + + public function testFromJsonPointFeature() { + $point = Geometry::fromJson('{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[3.4,1.2]}}'); + $this->assertInstanceOf(Point::class, $point); + $this->assertEquals(1.2, $point->getLat()); + $this->assertEquals(3.4, $point->getLng()); + } + + public function testFromJsonMultiPointFeatureCollection() { + $geometryCollection = Geometry::fromJson('{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[1,2]}},{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[3,4]}}]}'); + $this->assertInstanceOf(GeometryCollection::class, $geometryCollection); + $geometryCollectionPoints = $geometryCollection->getGeometries(); + $this->assertEquals(2, count($geometryCollectionPoints)); + $this->assertEquals(new Point(2, 1), $geometryCollectionPoints[0]); + $this->assertEquals(new Point(4, 3), $geometryCollectionPoints[1]); + } + public function testToJson() { $point = new Point(1, 1); diff --git a/tests/Unit/Types/LineStringTest.php b/tests/Unit/Types/LineStringTest.php index 6d73d422..063b967c 100644 --- a/tests/Unit/Types/LineStringTest.php +++ b/tests/Unit/Types/LineStringTest.php @@ -34,6 +34,19 @@ public function testToString() $this->assertEquals('0 0,1 1,2 2', (string) $linestring); } + public function testFromJson() { + $lineString = LineString::fromJson('{"type": "LineString","coordinates":[[1,1],[2,2]]}'); + $this->assertInstanceOf(LineString::class, $lineString); + $lineStringPoints = $lineString->getGeometries(); + $this->assertEquals(new Point(1, 1), $lineStringPoints[0]); + $this->assertEquals(new Point(2, 2), $lineStringPoints[1]); + } + + public function testInvalidGeoJsonException() { + $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); + LineString::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); + } + public function testJsonSerialize() { $lineString = new LineString($this->points); diff --git a/tests/Unit/Types/MultiLineStringTest.php b/tests/Unit/Types/MultiLineStringTest.php index 5f0760ec..f67f137d 100644 --- a/tests/Unit/Types/MultiLineStringTest.php +++ b/tests/Unit/Types/MultiLineStringTest.php @@ -29,6 +29,24 @@ public function testToWKT() $this->assertSame('MULTILINESTRING((0 0,1 0,1 1,0 1,0 0))', $multilinestring->toWKT()); } + public function testFromJson() { + $multiLineString = MultiLineString::fromJson('{"type":"MultiLineString","coordinates":[[[1,1],[1,2],[1,3]],[[2,1],[2,2],[2,3]]]}'); + $this->assertInstanceOf(MultiLineString::class, $multiLineString); + $multiLineStringLineStrings = $multiLineString->getGeometries(); + $this->assertEquals(2, count($multiLineStringLineStrings)); + $this->assertEquals(new Point(1, 1), $multiLineStringLineStrings[0][0]); + $this->assertEquals(new Point(2, 1), $multiLineStringLineStrings[0][1]); + $this->assertEquals(new Point(3, 1), $multiLineStringLineStrings[0][2]); + $this->assertEquals(new Point(1, 2), $multiLineStringLineStrings[1][0]); + $this->assertEquals(new Point(2, 2), $multiLineStringLineStrings[1][1]); + $this->assertEquals(new Point(3, 2), $multiLineStringLineStrings[1][2]); + } + + public function testInvalidGeoJsonException() { + $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); + MultiLineString::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); + } + public function testJsonSerialize() { $multilinestring = MultiLineString::fromWKT('MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))'); diff --git a/tests/Unit/Types/MultiPointTest.php b/tests/Unit/Types/MultiPointTest.php index ee0bb94d..926ad06b 100644 --- a/tests/Unit/Types/MultiPointTest.php +++ b/tests/Unit/Types/MultiPointTest.php @@ -29,6 +29,21 @@ public function testGetPoints() $this->assertInstanceOf(Point::class, $multipoint->getPoints()[0]); } + public function testFromJson() { + $multiPoint = MultiPoint::fromJson('{"type":"MultiPoint","coordinates":[[1,1],[2,1],[2,2]]}'); + $this->assertInstanceOf(MultiPoint::class, $multiPoint); + $multiPointPoints = $multiPoint->getGeometries(); + $this->assertEquals(3, count($multiPointPoints)); + $this->assertEquals(new Point(1, 1), $multiPointPoints[0]); + $this->assertEquals(new Point(1, 2), $multiPointPoints[1]); + $this->assertEquals(new Point(2, 2), $multiPointPoints[2]); + } + + public function testInvalidGeoJsonException() { + $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); + MultiPoint::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); + } + public function testJsonSerialize() { $collection = [new Point(0, 0), new Point(0, 1), new Point(1, 1)]; diff --git a/tests/Unit/Types/MultiPolygonTest.php b/tests/Unit/Types/MultiPolygonTest.php index f8c87375..02a12f3d 100644 --- a/tests/Unit/Types/MultiPolygonTest.php +++ b/tests/Unit/Types/MultiPolygonTest.php @@ -34,6 +34,32 @@ public function testIssue12() $this->assertInstanceOf(MultiPolygon::class, $polygon); } + public function testFromJson() { + $multiPolygon = MultiPolygon::fromJson('{"type":"MultiPolygon","coordinates":[[[[1,1],[1,2],[2,2],[2,1],[1,1]]],[[[0,0],[0,1],[1,1],[1,0],[0,0]]]]}'); + $this->assertInstanceOf(MultiPolygon::class, $multiPolygon); + $multiPolygonPolygons = $multiPolygon->getGeometries(); + $this->assertEquals(2, count($multiPolygonPolygons)); + $this->assertEquals(new Polygon([new LineString([ + new Point(1, 1), + new Point(2, 1), + new Point(2, 2), + new Point(1, 2), + new Point(1, 1) + ])]), $multiPolygonPolygons[0]); + $this->assertEquals(new Polygon([new LineString([ + new Point(0, 0), + new Point(1, 0), + new Point(1, 1), + new Point(0, 1), + new Point(0, 0) + ])]), $multiPolygonPolygons[1]); + } + + public function testInvalidGeoJsonException() { + $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); + MultiPolygon::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); + } + public function testJsonSerialize() { $this->assertInstanceOf(\GeoJson\Geometry\MultiPolygon::class, $this->getMultiPolygon()->jsonSerialize()); diff --git a/tests/Unit/Types/PointTest.php b/tests/Unit/Types/PointTest.php index 576dc039..0c0c9502 100644 --- a/tests/Unit/Types/PointTest.php +++ b/tests/Unit/Types/PointTest.php @@ -53,6 +53,18 @@ public function testToString() $this->assertEquals('1.3 2', (string) $point); } + public function testFromJson() { + $point = Point::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); + $this->assertInstanceOf(Point::class, $point); + $this->assertEquals(1.2, $point->getLat()); + $this->assertEquals(3.4, $point->getLng()); + } + + public function testInvalidGeoJsonException() { + $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); + Point::fromJson('{"type": "LineString","coordinates":[[1,1],[2,2]]}'); + } + public function testJsonSerialize() { $point = new Point(1.2, 3.4); diff --git a/tests/Unit/Types/PolygonTest.php b/tests/Unit/Types/PolygonTest.php index 16c6f248..76320144 100644 --- a/tests/Unit/Types/PolygonTest.php +++ b/tests/Unit/Types/PolygonTest.php @@ -36,6 +36,28 @@ public function testToWKT() $this->assertEquals('POLYGON((0 0,1 0,1 1,0 1,0 0))', $this->polygon->toWKT()); } + public function testFromJson() { + $polygon = Polygon::fromJson('{"type":"Polygon","coordinates":[[[1,1],[2,1],[2,2],[1,2],[1,1]],[[1.2,1.2],[1.6,1.2],[1.6,1.8],[1.2,1.8],[1.2,1.2]]]}'); + $this->assertInstanceOf(Polygon::class, $polygon); + $polygonLineStrings = $polygon->getGeometries(); + $this->assertEquals(2, count($polygonLineStrings)); + $this->assertEquals(new Point(1, 1), $polygonLineStrings[0][0]); + $this->assertEquals(new Point(1, 2), $polygonLineStrings[0][1]); + $this->assertEquals(new Point(2, 2), $polygonLineStrings[0][2]); + $this->assertEquals(new Point(2, 1), $polygonLineStrings[0][3]); + $this->assertEquals(new Point(1, 1), $polygonLineStrings[0][4]); + $this->assertEquals(new Point(1.2, 1.2), $polygonLineStrings[1][0]); + $this->assertEquals(new Point(1.2, 1.6), $polygonLineStrings[1][1]); + $this->assertEquals(new Point(1.8, 1.6), $polygonLineStrings[1][2]); + $this->assertEquals(new Point(1.8, 1.2), $polygonLineStrings[1][3]); + $this->assertEquals(new Point(1.2, 1.2), $polygonLineStrings[1][4]); + } + + public function testInvalidGeoJsonException() { + $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); + Polygon::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); + } + public function testJsonSerialize() { $this->assertInstanceOf(\GeoJson\Geometry\Polygon::class, $this->polygon->jsonSerialize()); From 84ed34abd848a60f6a6be7427308a82d0f862a6c Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 1 Oct 2017 10:10:58 +0200 Subject: [PATCH 35/57] Style CI fix :performing_arts: (cherry picked from commit 8add88a0ea711b62249e52d71d32dc9fa17125e4) --- src/Exceptions/InvalidGeoJsonException.php | 2 +- src/Types/Geometry.php | 10 ++++++---- src/Types/GeometryCollection.php | 10 +++++----- src/Types/LineString.php | 12 ++++++------ src/Types/MultiLineString.php | 14 +++++++------- src/Types/MultiPoint.php | 12 ++++++------ src/Types/MultiPolygon.php | 16 ++++++++-------- src/Types/Point.php | 12 +++++++----- src/Types/Polygon.php | 14 +++++++------- tests/Unit/Eloquent/SpatialTraitTest.php | 9 ++++++--- tests/Unit/Types/GeometryCollectionTest.php | 6 ++++-- tests/Unit/Types/GeometryTest.php | 15 +++++++++------ tests/Unit/Types/LineStringTest.php | 6 ++++-- tests/Unit/Types/MultiLineStringTest.php | 6 ++++-- tests/Unit/Types/MultiPointTest.php | 6 ++++-- tests/Unit/Types/MultiPolygonTest.php | 10 ++++++---- tests/Unit/Types/PointTest.php | 6 ++++-- tests/Unit/Types/PolygonTest.php | 6 ++++-- 18 files changed, 98 insertions(+), 74 deletions(-) diff --git a/src/Exceptions/InvalidGeoJsonException.php b/src/Exceptions/InvalidGeoJsonException.php index f913cf04..3374fdb7 100644 --- a/src/Exceptions/InvalidGeoJsonException.php +++ b/src/Exceptions/InvalidGeoJsonException.php @@ -4,4 +4,4 @@ class InvalidGeoJsonException extends \RuntimeException { -} \ No newline at end of file +} diff --git a/src/Types/Geometry.php b/src/Types/Geometry.php index 0b0fded8..a46baed3 100644 --- a/src/Types/Geometry.php +++ b/src/Types/Geometry.php @@ -72,20 +72,22 @@ public static function fromWKT($wkt) return static::fromString($wktArgument); } - public static function fromJson($geoJson) { - if(is_string($geoJson)) { + public static function fromJson($geoJson) + { + if (is_string($geoJson)) { $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); } - if($geoJson->getType() === 'FeatureCollection') { + if ($geoJson->getType() === 'FeatureCollection') { return GeometryCollection::fromJson($geoJson); } - if($geoJson->getType() === 'Feature') { + if ($geoJson->getType() === 'Feature') { $geoJson = $geoJson->getGeometry(); } $type = '\Grimzy\LaravelMysqlSpatial\Types\\'.$geoJson->getType(); + return $type::fromJson($geoJson); } diff --git a/src/Types/GeometryCollection.php b/src/Types/GeometryCollection.php index 26a4b439..2e1f0321 100755 --- a/src/Types/GeometryCollection.php +++ b/src/Types/GeometryCollection.php @@ -110,14 +110,14 @@ public function count() return count($this->items); } - public static function fromJson ($geoJson) + public static function fromJson($geoJson) { - if(is_string($geoJson)) { + if (is_string($geoJson)) { $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); } - if(!is_a($geoJson, FeatureCollection::class)) { - throw new InvalidGeoJsonException('Expected ' . FeatureCollection::class . ', got ' . get_class($geoJson)); + if (!is_a($geoJson, FeatureCollection::class)) { + throw new InvalidGeoJsonException('Expected '.FeatureCollection::class.', got '.get_class($geoJson)); } $set = []; @@ -125,7 +125,7 @@ public static function fromJson ($geoJson) $set[] = parent::fromJson($feature); } - return new GeometryCollection($set); + return new self($set); } /** diff --git a/src/Types/LineString.php b/src/Types/LineString.php index 59cd3662..02097edd 100644 --- a/src/Types/LineString.php +++ b/src/Types/LineString.php @@ -35,22 +35,22 @@ public function __toString() return $this->toPairList(); } - public static function fromJson ($geoJson) + public static function fromJson($geoJson) { - if(is_string($geoJson)) { + if (is_string($geoJson)) { $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); } - if(!is_a($geoJson, GeoJsonLineString::class)) { - throw new InvalidGeoJsonException('Expected ' . GeoJsonLineString::class . ', got ' . get_class($geoJson)); + if (!is_a($geoJson, GeoJsonLineString::class)) { + throw new InvalidGeoJsonException('Expected '.GeoJsonLineString::class.', got '.get_class($geoJson)); } $set = []; - foreach($geoJson->getCoordinates() as $coordinate) { + foreach ($geoJson->getCoordinates() as $coordinate) { $set[] = new Point($coordinate[1], $coordinate[0]); } - return new LineString($set); + return new self($set); } /** diff --git a/src/Types/MultiLineString.php b/src/Types/MultiLineString.php index 025fb4e3..dd3342fd 100644 --- a/src/Types/MultiLineString.php +++ b/src/Types/MultiLineString.php @@ -65,26 +65,26 @@ public function offsetSet($offset, $value) parent::offsetSet($offset, $value); } - public static function fromJson ($geoJson) + public static function fromJson($geoJson) { - if(is_string($geoJson)) { + if (is_string($geoJson)) { $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); } - if(!is_a($geoJson, GeoJsonMultiLineString::class)) { - throw new InvalidGeoJsonException('Expected ' . GeoJsonMultiLineString::class . ', got ' . get_class($geoJson)); + if (!is_a($geoJson, GeoJsonMultiLineString::class)) { + throw new InvalidGeoJsonException('Expected '.GeoJsonMultiLineString::class.', got '.get_class($geoJson)); } $set = []; - foreach($geoJson->getCoordinates() as $coordinates) { + foreach ($geoJson->getCoordinates() as $coordinates) { $points = []; - foreach($coordinates as $coordinate) { + foreach ($coordinates as $coordinate) { $points[] = new Point($coordinate[1], $coordinate[0]); } $set[] = new LineString($points); } - return new MultiLineString($set); + return new self($set); } /** diff --git a/src/Types/MultiPoint.php b/src/Types/MultiPoint.php index 60fad9a5..fb55f9e8 100644 --- a/src/Types/MultiPoint.php +++ b/src/Types/MultiPoint.php @@ -39,22 +39,22 @@ public function __toString() }, $this->items)); } - public static function fromJson ($geoJson) + public static function fromJson($geoJson) { - if(is_string($geoJson)) { + if (is_string($geoJson)) { $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); } - if(!is_a($geoJson, GeoJsonMultiPoint::class)) { - throw new InvalidGeoJsonException('Expected ' . GeoJsonMultiPoint::class . ', got ' . get_class($geoJson)); + if (!is_a($geoJson, GeoJsonMultiPoint::class)) { + throw new InvalidGeoJsonException('Expected '.GeoJsonMultiPoint::class.', got '.get_class($geoJson)); } $set = []; - foreach($geoJson->getCoordinates() as $coordinate) { + foreach ($geoJson->getCoordinates() as $coordinate) { $set[] = new Point($coordinate[1], $coordinate[0]); } - return new MultiPoint($set); + return new self($set); } /** diff --git a/src/Types/MultiPolygon.php b/src/Types/MultiPolygon.php index 927df911..aba2b6d1 100644 --- a/src/Types/MultiPolygon.php +++ b/src/Types/MultiPolygon.php @@ -100,22 +100,22 @@ public function offsetSet($offset, $value) parent::offsetSet($offset, $value); } - public static function fromJson ($geoJson) + public static function fromJson($geoJson) { - if(is_string($geoJson)) { + if (is_string($geoJson)) { $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); } - if(!is_a($geoJson, GeoJsonMultiPolygon::class)) { - throw new InvalidGeoJsonException('Expected ' . GeoJsonMultiPolygon::class . ', got ' . get_class($geoJson)); + if (!is_a($geoJson, GeoJsonMultiPolygon::class)) { + throw new InvalidGeoJsonException('Expected '.GeoJsonMultiPolygon::class.', got '.get_class($geoJson)); } $set = []; - foreach($geoJson->getCoordinates() as $polygonCoordinates) { + foreach ($geoJson->getCoordinates() as $polygonCoordinates) { $lineStrings = []; - foreach($polygonCoordinates as $lineStringCoordinates) { + foreach ($polygonCoordinates as $lineStringCoordinates) { $points = []; - foreach($lineStringCoordinates as $lineStringCoordinate) { + foreach ($lineStringCoordinates as $lineStringCoordinate) { $points[] = new Point($lineStringCoordinate[1], $lineStringCoordinate[0]); } $lineStrings[] = new LineString($points); @@ -123,7 +123,7 @@ public static function fromJson ($geoJson) $set[] = new Polygon($lineStrings); } - return new MultiPolygon($set); + return new self($set); } /** diff --git a/src/Types/Point.php b/src/Types/Point.php index 07148355..2a149e80 100644 --- a/src/Types/Point.php +++ b/src/Types/Point.php @@ -67,20 +67,22 @@ public function __toString() /** * @param $geoJson \GeoJson\Feature\Feature|string + * * @return \Grimzy\LaravelMysqlSpatial\Types\Point */ - public static function fromJson ($geoJson) + public static function fromJson($geoJson) { - if(is_string($geoJson)) { + if (is_string($geoJson)) { $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); } - if(!is_a($geoJson, GeoJsonPoint::class)) { - throw new InvalidGeoJsonException('Expected ' . GeoJsonPoint::class . ', got ' . get_class($geoJson)); + if (!is_a($geoJson, GeoJsonPoint::class)) { + throw new InvalidGeoJsonException('Expected '.GeoJsonPoint::class.', got '.get_class($geoJson)); } $coordinates = $geoJson->getCoordinates(); - return new Point($coordinates[1], $coordinates[0]); + + return new self($coordinates[1], $coordinates[0]); } /** diff --git a/src/Types/Polygon.php b/src/Types/Polygon.php index c9850c11..9c10cecc 100644 --- a/src/Types/Polygon.php +++ b/src/Types/Polygon.php @@ -13,26 +13,26 @@ public function toWKT() return sprintf('POLYGON(%s)', (string) $this); } - public static function fromJson ($geoJson) + public static function fromJson($geoJson) { - if(is_string($geoJson)) { + if (is_string($geoJson)) { $geoJson = GeoJson::jsonUnserialize(json_decode($geoJson)); } - if(!is_a($geoJson, GeoJsonPolygon::class)) { - throw new InvalidGeoJsonException('Expected ' . GeoJsonPolygon::class . ', got ' . get_class($geoJson)); + if (!is_a($geoJson, GeoJsonPolygon::class)) { + throw new InvalidGeoJsonException('Expected '.GeoJsonPolygon::class.', got '.get_class($geoJson)); } $set = []; - foreach($geoJson->getCoordinates() as $coordinates) { + foreach ($geoJson->getCoordinates() as $coordinates) { $points = []; - foreach($coordinates as $coordinate) { + foreach ($coordinates as $coordinate) { $points[] = new Point($coordinate[1], $coordinate[0]); } $set[] = new LineString($points); } - return new Polygon($set); + return new self($set); } /** diff --git a/tests/Unit/Eloquent/SpatialTraitTest.php b/tests/Unit/Eloquent/SpatialTraitTest.php index 16fea735..ef762408 100644 --- a/tests/Unit/Eloquent/SpatialTraitTest.php +++ b/tests/Unit/Eloquent/SpatialTraitTest.php @@ -192,14 +192,16 @@ public function testInsertUpdateGeometryCollectionHasCorrectSql() $this->assertContains("GeomFromText('GEOMETRYCOLLECTION(POINT(2 1),LINESTRING(3 2,3 3))')", $this->queries[1]); } - public function testSettingRawAttributes() { + public function testSettingRawAttributes() + { $attributes['point'] = '0101000000000000000000f03f0000000000000040'; $this->model->setRawAttributes($attributes); $this->assertInstanceOf(Point::class, ($this->model->point)); } - public function testSpatialFieldsNotDefinedException() { + public function testSpatialFieldsNotDefinedException() + { $model = new TestNoSpatialModel(); $this->setExpectedException(SpatialFieldsNotDefinedException::class); $model->getSpatialFields(); @@ -403,7 +405,8 @@ public function testmodels() } } -class TestNoSpatialModel extends Model { +class TestNoSpatialModel extends Model +{ use \Grimzy\LaravelMysqlSpatial\Eloquent\SpatialTrait; } diff --git a/tests/Unit/Types/GeometryCollectionTest.php b/tests/Unit/Types/GeometryCollectionTest.php index b8089c4f..07759c5f 100644 --- a/tests/Unit/Types/GeometryCollectionTest.php +++ b/tests/Unit/Types/GeometryCollectionTest.php @@ -89,7 +89,8 @@ public function testArrayAccess() $geometryCollection[] = 1; } - public function testFromJson() { + public function testFromJson() + { $geometryCollection = GeometryCollection::fromJson('{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[1,2]}},{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[3,4]}}]}'); $this->assertInstanceOf(GeometryCollection::class, $geometryCollection); $geometryCollectionPoints = $geometryCollection->getGeometries(); @@ -98,7 +99,8 @@ public function testFromJson() { $this->assertEquals(new Point(4, 3), $geometryCollectionPoints[1]); } - public function testInvalidGeoJsonException() { + public function testInvalidGeoJsonException() + { $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); GeometryCollection::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); } diff --git a/tests/Unit/Types/GeometryTest.php b/tests/Unit/Types/GeometryTest.php index 3068864d..51b400ec 100644 --- a/tests/Unit/Types/GeometryTest.php +++ b/tests/Unit/Types/GeometryTest.php @@ -123,7 +123,8 @@ public function testFromJsonMultiLineString() $this->assertEquals(new Point(3, 2), $multiLineStringLineStrings[1][2]); } - public function testFromJsonMultiPolygon() { + public function testFromJsonMultiPolygon() + { $multiPolygon = Geometry::fromJson('{"type":"MultiPolygon","coordinates":[[[[1,1],[1,2],[2,2],[2,1],[1,1]]],[[[0,0],[0,1],[1,1],[1,0],[0,0]]]]}'); $this->assertInstanceOf(MultiPolygon::class, $multiPolygon); $multiPolygonPolygons = $multiPolygon->getGeometries(); @@ -133,25 +134,27 @@ public function testFromJsonMultiPolygon() { new Point(2, 1), new Point(2, 2), new Point(1, 2), - new Point(1, 1) + new Point(1, 1), ])]), $multiPolygonPolygons[0]); $this->assertEquals(new Polygon([new LineString([ new Point(0, 0), new Point(1, 0), new Point(1, 1), new Point(0, 1), - new Point(0, 0) + new Point(0, 0), ])]), $multiPolygonPolygons[1]); } - public function testFromJsonPointFeature() { + public function testFromJsonPointFeature() + { $point = Geometry::fromJson('{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[3.4,1.2]}}'); $this->assertInstanceOf(Point::class, $point); $this->assertEquals(1.2, $point->getLat()); $this->assertEquals(3.4, $point->getLng()); } - - public function testFromJsonMultiPointFeatureCollection() { + + public function testFromJsonMultiPointFeatureCollection() + { $geometryCollection = Geometry::fromJson('{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[1,2]}},{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[3,4]}}]}'); $this->assertInstanceOf(GeometryCollection::class, $geometryCollection); $geometryCollectionPoints = $geometryCollection->getGeometries(); diff --git a/tests/Unit/Types/LineStringTest.php b/tests/Unit/Types/LineStringTest.php index 063b967c..9300e3f1 100644 --- a/tests/Unit/Types/LineStringTest.php +++ b/tests/Unit/Types/LineStringTest.php @@ -34,7 +34,8 @@ public function testToString() $this->assertEquals('0 0,1 1,2 2', (string) $linestring); } - public function testFromJson() { + public function testFromJson() + { $lineString = LineString::fromJson('{"type": "LineString","coordinates":[[1,1],[2,2]]}'); $this->assertInstanceOf(LineString::class, $lineString); $lineStringPoints = $lineString->getGeometries(); @@ -42,7 +43,8 @@ public function testFromJson() { $this->assertEquals(new Point(2, 2), $lineStringPoints[1]); } - public function testInvalidGeoJsonException() { + public function testInvalidGeoJsonException() + { $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); LineString::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); } diff --git a/tests/Unit/Types/MultiLineStringTest.php b/tests/Unit/Types/MultiLineStringTest.php index f67f137d..df7b42e4 100644 --- a/tests/Unit/Types/MultiLineStringTest.php +++ b/tests/Unit/Types/MultiLineStringTest.php @@ -29,7 +29,8 @@ public function testToWKT() $this->assertSame('MULTILINESTRING((0 0,1 0,1 1,0 1,0 0))', $multilinestring->toWKT()); } - public function testFromJson() { + public function testFromJson() + { $multiLineString = MultiLineString::fromJson('{"type":"MultiLineString","coordinates":[[[1,1],[1,2],[1,3]],[[2,1],[2,2],[2,3]]]}'); $this->assertInstanceOf(MultiLineString::class, $multiLineString); $multiLineStringLineStrings = $multiLineString->getGeometries(); @@ -42,7 +43,8 @@ public function testFromJson() { $this->assertEquals(new Point(3, 2), $multiLineStringLineStrings[1][2]); } - public function testInvalidGeoJsonException() { + public function testInvalidGeoJsonException() + { $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); MultiLineString::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); } diff --git a/tests/Unit/Types/MultiPointTest.php b/tests/Unit/Types/MultiPointTest.php index 926ad06b..1e9bf7f4 100644 --- a/tests/Unit/Types/MultiPointTest.php +++ b/tests/Unit/Types/MultiPointTest.php @@ -29,7 +29,8 @@ public function testGetPoints() $this->assertInstanceOf(Point::class, $multipoint->getPoints()[0]); } - public function testFromJson() { + public function testFromJson() + { $multiPoint = MultiPoint::fromJson('{"type":"MultiPoint","coordinates":[[1,1],[2,1],[2,2]]}'); $this->assertInstanceOf(MultiPoint::class, $multiPoint); $multiPointPoints = $multiPoint->getGeometries(); @@ -39,7 +40,8 @@ public function testFromJson() { $this->assertEquals(new Point(2, 2), $multiPointPoints[2]); } - public function testInvalidGeoJsonException() { + public function testInvalidGeoJsonException() + { $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); MultiPoint::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); } diff --git a/tests/Unit/Types/MultiPolygonTest.php b/tests/Unit/Types/MultiPolygonTest.php index 02a12f3d..adcac1e1 100644 --- a/tests/Unit/Types/MultiPolygonTest.php +++ b/tests/Unit/Types/MultiPolygonTest.php @@ -34,7 +34,8 @@ public function testIssue12() $this->assertInstanceOf(MultiPolygon::class, $polygon); } - public function testFromJson() { + public function testFromJson() + { $multiPolygon = MultiPolygon::fromJson('{"type":"MultiPolygon","coordinates":[[[[1,1],[1,2],[2,2],[2,1],[1,1]]],[[[0,0],[0,1],[1,1],[1,0],[0,0]]]]}'); $this->assertInstanceOf(MultiPolygon::class, $multiPolygon); $multiPolygonPolygons = $multiPolygon->getGeometries(); @@ -44,18 +45,19 @@ public function testFromJson() { new Point(2, 1), new Point(2, 2), new Point(1, 2), - new Point(1, 1) + new Point(1, 1), ])]), $multiPolygonPolygons[0]); $this->assertEquals(new Polygon([new LineString([ new Point(0, 0), new Point(1, 0), new Point(1, 1), new Point(0, 1), - new Point(0, 0) + new Point(0, 0), ])]), $multiPolygonPolygons[1]); } - public function testInvalidGeoJsonException() { + public function testInvalidGeoJsonException() + { $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); MultiPolygon::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); } diff --git a/tests/Unit/Types/PointTest.php b/tests/Unit/Types/PointTest.php index 0c0c9502..257f6a45 100644 --- a/tests/Unit/Types/PointTest.php +++ b/tests/Unit/Types/PointTest.php @@ -53,14 +53,16 @@ public function testToString() $this->assertEquals('1.3 2', (string) $point); } - public function testFromJson() { + public function testFromJson() + { $point = Point::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); $this->assertInstanceOf(Point::class, $point); $this->assertEquals(1.2, $point->getLat()); $this->assertEquals(3.4, $point->getLng()); } - public function testInvalidGeoJsonException() { + public function testInvalidGeoJsonException() + { $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); Point::fromJson('{"type": "LineString","coordinates":[[1,1],[2,2]]}'); } diff --git a/tests/Unit/Types/PolygonTest.php b/tests/Unit/Types/PolygonTest.php index 76320144..de923c2f 100644 --- a/tests/Unit/Types/PolygonTest.php +++ b/tests/Unit/Types/PolygonTest.php @@ -36,7 +36,8 @@ public function testToWKT() $this->assertEquals('POLYGON((0 0,1 0,1 1,0 1,0 0))', $this->polygon->toWKT()); } - public function testFromJson() { + public function testFromJson() + { $polygon = Polygon::fromJson('{"type":"Polygon","coordinates":[[[1,1],[2,1],[2,2],[1,2],[1,1]],[[1.2,1.2],[1.6,1.2],[1.6,1.8],[1.2,1.8],[1.2,1.2]]]}'); $this->assertInstanceOf(Polygon::class, $polygon); $polygonLineStrings = $polygon->getGeometries(); @@ -53,7 +54,8 @@ public function testFromJson() { $this->assertEquals(new Point(1.2, 1.2), $polygonLineStrings[1][4]); } - public function testInvalidGeoJsonException() { + public function testInvalidGeoJsonException() + { $this->setExpectedException(\Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException::class); Polygon::fromJson('{"type":"Point","coordinates":[3.4,1.2]}'); } From 7e7ee8a668b5213cc65140b7d90a57e60a8b2ebe Mon Sep 17 00:00:00 2001 From: Chrissi2812 Date: Tue, 18 Dec 2018 17:18:56 +0100 Subject: [PATCH 36/57] fixed php 7.1 incompatibilities --- src/Schema/Blueprint.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Schema/Blueprint.php b/src/Schema/Blueprint.php index f0945f4d..9507e31e 100644 --- a/src/Schema/Blueprint.php +++ b/src/Schema/Blueprint.php @@ -21,13 +21,14 @@ public function geometry($column) /** * Add a point column on the table. * - * @param $column + * @param string $column + * @param null|int $srid * * @return \Illuminate\Support\Fluent */ - public function point($column) + public function point($column, $srid = null) { - return $this->addColumn('point', $column); + return $this->addColumn('point', $column, compact('srid')); } /** From df0ded97642dfb9623b6407ef5a35caf6e99eacb Mon Sep 17 00:00:00 2001 From: Mohammad Nourinik Date: Tue, 5 Jun 2018 14:20:17 +0200 Subject: [PATCH 37/57] Fix testPoint. (cherry picked from commit 254aa68b3440bd1236388df8e5ab90caecaad832) --- tests/Unit/Schema/BlueprintTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Schema/BlueprintTest.php b/tests/Unit/Schema/BlueprintTest.php index 41dac43d..da335520 100644 --- a/tests/Unit/Schema/BlueprintTest.php +++ b/tests/Unit/Schema/BlueprintTest.php @@ -32,7 +32,7 @@ public function testPoint() { $this->blueprint ->shouldReceive('addColumn') - ->with('point', 'col') + ->with('point', 'col', ['srid' => null]) ->once(); $this->blueprint->point('col'); From bb0836afd67a67369cfbe7908820aaac85ab0378 Mon Sep 17 00:00:00 2001 From: jl9404 Date: Sat, 27 Oct 2018 01:45:26 -0400 Subject: [PATCH 38/57] Fix Geometry::fromWKB function to allow various SRID (cherry picked from commit a1982786169502ab3f1ac56278ca180538add3c2) --- src/Types/Geometry.php | 6 +----- tests/Unit/Eloquent/SpatialTraitTest.php | 2 +- tests/Unit/Types/GeometryTest.php | 21 +++++++++++---------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/Types/Geometry.php b/src/Types/Geometry.php index a46baed3..c0df8ec3 100644 --- a/src/Types/Geometry.php +++ b/src/Types/Geometry.php @@ -55,11 +55,7 @@ public static function getWKTClass($value) public static function fromWKB($wkb) { // mysql adds 4 NUL bytes at the start of the binary - $prefix = "\0\0\0\0"; - if (substr($wkb, 0, strlen($prefix)) == $prefix) { - $wkb = substr($wkb, strlen($prefix)); - } - + $wkb = substr($wkb, 4); $parser = new Parser(new Factory()); return $parser->parse($wkb); diff --git a/tests/Unit/Eloquent/SpatialTraitTest.php b/tests/Unit/Eloquent/SpatialTraitTest.php index ef762408..d53e02e7 100644 --- a/tests/Unit/Eloquent/SpatialTraitTest.php +++ b/tests/Unit/Eloquent/SpatialTraitTest.php @@ -194,7 +194,7 @@ public function testInsertUpdateGeometryCollectionHasCorrectSql() public function testSettingRawAttributes() { - $attributes['point'] = '0101000000000000000000f03f0000000000000040'; + $attributes['point'] = "\0\0\0\0".'0101000000000000000000f03f0000000000000040'; $this->model->setRawAttributes($attributes); $this->assertInstanceOf(Point::class, ($this->model->point)); diff --git a/tests/Unit/Types/GeometryTest.php b/tests/Unit/Types/GeometryTest.php index 51b400ec..8bd765a7 100644 --- a/tests/Unit/Types/GeometryTest.php +++ b/tests/Unit/Types/GeometryTest.php @@ -38,18 +38,19 @@ public function testGetWKTClass() public function testGetWKBClass() { - $this->assertInstanceOf(Point::class, Geometry::fromWKB('0101000000000000000000f03f0000000000000040')); + $prefix = "\0\0\0\0"; + + $this->assertInstanceOf(Point::class, Geometry::fromWKB($prefix.'0101000000000000000000f03f0000000000000040')); - $this->assertInstanceOf(LineString::class, Geometry::fromWKB('010200000002000000000000000000f03f000000000000004000000000000008400000000000001040')); - $this->assertInstanceOf(Polygon::class, Geometry::fromWKB('01030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f0000000000000040')); - $this->assertInstanceOf(MultiPoint::class, Geometry::fromWKB('0104000000020000000101000000000000000000f03f0000000000000040010100000000000000000008400000000000001040')); - $this->assertInstanceOf(MultiLineString::class, Geometry::fromWKB('010500000001000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040')); - $this->assertInstanceOf(MultiLineString::class, Geometry::fromWKB('010500000002000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040010200000002000000000000000000144000000000000018400000000000001c400000000000002040')); - $this->assertInstanceOf(MultiPolygon::class, Geometry::fromWKB('01060000000200000001030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004001030000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640')); - $this->assertInstanceOf(GeometryCollection::class, Geometry::fromWKB('0107000000010000000101000000000000000000f03f0000000000000040')); - $this->assertInstanceOf(GeometryCollection::class, Geometry::fromWKB('0107000000020000000101000000000000000000f03f0000000000000040010200000002000000000000000000f03f000000000000004000000000000008400000000000001040')); + $this->assertInstanceOf(LineString::class, Geometry::fromWKB($prefix.'010200000002000000000000000000f03f000000000000004000000000000008400000000000001040')); + $this->assertInstanceOf(Polygon::class, Geometry::fromWKB($prefix.'01030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f0000000000000040')); + $this->assertInstanceOf(MultiPoint::class, Geometry::fromWKB($prefix.'0104000000020000000101000000000000000000f03f0000000000000040010100000000000000000008400000000000001040')); + $this->assertInstanceOf(MultiLineString::class, Geometry::fromWKB($prefix.'010500000001000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040')); + $this->assertInstanceOf(MultiLineString::class, Geometry::fromWKB($prefix.'010500000002000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040010200000002000000000000000000144000000000000018400000000000001c400000000000002040')); + $this->assertInstanceOf(MultiPolygon::class, Geometry::fromWKB($prefix.'01060000000200000001030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004001030000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640')); + $this->assertInstanceOf(GeometryCollection::class, Geometry::fromWKB($prefix.'0107000000010000000101000000000000000000f03f0000000000000040')); + $this->assertInstanceOf(GeometryCollection::class, Geometry::fromWKB($prefix.'0107000000020000000101000000000000000000f03f0000000000000040010200000002000000000000000000f03f000000000000004000000000000008400000000000001040')); - $prefix = "\0\0\0\0"; $this->assertInstanceOf(Point::class, Geometry::fromWKB($prefix.'0101000000000000000000f03f0000000000000040')); } From 91ed5e8230dd5b637477b2e8a0b779aafda87e27 Mon Sep 17 00:00:00 2001 From: Matan Yadaev Date: Tue, 27 Aug 2019 21:41:29 +0200 Subject: [PATCH 39/57] upgrade laravel (cherry picked from commit 235770485bab5eec8dcaf09aaf5e0f33d73c85a1) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8947186e..f8d83962 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require-dev": { "phpunit/phpunit": "~4.8||~5.7", "mockery/mockery": "^0.9.9", - "laravel/laravel": "^5.2", + "laravel/laravel": "^5.2|^6.0", "codeclimate/php-test-reporter": "dev-master", "doctrine/dbal": "^2.5", "laravel/browser-kit-testing": "^2.0" From f5a25e1d1d10a53a1deac5c9aa4e60212da9e603 Mon Sep 17 00:00:00 2001 From: Matan Yadaev Date: Tue, 27 Aug 2019 21:43:49 +0200 Subject: [PATCH 40/57] upgrade illuminate database (cherry picked from commit d54ae9967572f4290751db336e86b1390a99e1d4) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f8d83962..0026da46 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ ], "require": { "php": ">=5.5.9", - "illuminate/database": "^5.2", + "illuminate/database": "^5.2|^6.0", "geo-io/wkb-parser": "^1.0", "jmikola/geojson": "^1.0" }, From 529cfed694e9b03b360e346eb6745eac946e792b Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Mon, 2 Sep 2019 12:50:30 -0400 Subject: [PATCH 41/57] Fix Travis build memory exhaustion during composer install (cherry picked from commit 8cab456a66a32b6cd738e6ee6fe9afb91494198c) --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 00f9ce04..a2448a44 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ services: - docker before_install: + - "memory_limit=2G" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - sudo /etc/init.d/mysql stop - make start_db V=$MYSQL_VERSION From 968875aaf342161ea955da5f6afd3c33e5e751cb Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Mon, 2 Sep 2019 12:57:08 -0400 Subject: [PATCH 42/57] Typo (cherry picked from commit 451da77d0c80e37ee8fe221a231c9e58b39d7800) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a2448a44..e39c3e0a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ services: - docker before_install: - - "memory_limit=2G" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini + - echo "memory_limit=2G" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - sudo /etc/init.d/mysql stop - make start_db V=$MYSQL_VERSION From 00b88297e2823084538b53c424d8b1202eb2c4e1 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sat, 21 Sep 2019 17:46:25 +0000 Subject: [PATCH 43/57] Apply fixes from StyleCI [ci skip] [skip ci] --- src/Schema/Blueprint.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Schema/Blueprint.php b/src/Schema/Blueprint.php index 9507e31e..d061da26 100644 --- a/src/Schema/Blueprint.php +++ b/src/Schema/Blueprint.php @@ -34,7 +34,7 @@ public function point($column, $srid = null) /** * Add a linestring column on the table. * - * @param $column + * @param $column * * @return \Illuminate\Support\Fluent */ @@ -46,7 +46,7 @@ public function lineString($column) /** * Add a polygon column on the table. * - * @param $column + * @param $column * * @return \Illuminate\Support\Fluent */ @@ -58,7 +58,7 @@ public function polygon($column) /** * Add a multipoint column on the table. * - * @param $column + * @param $column * * @return \Illuminate\Support\Fluent */ @@ -70,7 +70,7 @@ public function multiPoint($column) /** * Add a multilinestring column on the table. * - * @param $column + * @param $column * * @return \Illuminate\Support\Fluent */ @@ -82,7 +82,7 @@ public function multiLineString($column) /** * Add a multipolygon column on the table. * - * @param $column + * @param $column * * @return \Illuminate\Support\Fluent */ @@ -94,7 +94,7 @@ public function multiPolygon($column) /** * Add a geometrycollection column on the table. * - * @param $column + * @param $column * * @return \Illuminate\Support\Fluent */ From a623639ee190779cb0c46d0c21fbe2606224d8b1 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Mon, 2 Mar 2020 23:33:39 -0500 Subject: [PATCH 44/57] Port of v2.1.0 (Resolves SQL injection vulnerability: PR #51) --- composer.json | 3 +- src/Eloquent/BaseBuilder.php | 17 +++ src/Eloquent/Builder.php | 2 +- src/Eloquent/SpatialExpression.php | 18 +++ src/Eloquent/SpatialTrait.php | 59 ++++++++- .../UnknownSpatialRelationFunction.php | 7 ++ src/MysqlConnection.php | 1 + tests/Integration/SpatialTest.php | 8 ++ tests/Unit/Eloquent/BuilderTest.php | 32 ++--- tests/Unit/Eloquent/SpatialTraitTest.php | 115 +++++++++++++----- 10 files changed, 204 insertions(+), 58 deletions(-) create mode 100644 src/Eloquent/BaseBuilder.php create mode 100644 src/Eloquent/SpatialExpression.php create mode 100644 src/Exceptions/UnknownSpatialRelationFunction.php diff --git a/composer.json b/composer.json index 0026da46..5c7f0ac7 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,8 @@ "laravel": { "providers": [ "Grimzy\\LaravelMysqlSpatial\\SpatialServiceProvider" - ] + ], + "require": "5.5.*" } } } diff --git a/src/Eloquent/BaseBuilder.php b/src/Eloquent/BaseBuilder.php new file mode 100644 index 00000000..33c0f21c --- /dev/null +++ b/src/Eloquent/BaseBuilder.php @@ -0,0 +1,17 @@ +getSpatialValue() : $binding; + }, $bindings); + + return parent::cleanBindings($bindings); + } +} diff --git a/src/Eloquent/Builder.php b/src/Eloquent/Builder.php index ed0a15c9..6230ed17 100755 --- a/src/Eloquent/Builder.php +++ b/src/Eloquent/Builder.php @@ -20,6 +20,6 @@ public function update(array $values) protected function asWKT(GeometryInterface $geometry) { - return $this->getQuery()->raw("GeomFromText('".$geometry->toWKT()."')"); + return new SpatialExpression($geometry); } } diff --git a/src/Eloquent/SpatialExpression.php b/src/Eloquent/SpatialExpression.php new file mode 100644 index 00000000..7bc88178 --- /dev/null +++ b/src/Eloquent/SpatialExpression.php @@ -0,0 +1,18 @@ +value->toWkt(); + } +} diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index 649e2602..7076a864 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -3,6 +3,7 @@ namespace Grimzy\LaravelMysqlSpatial\Eloquent; use Grimzy\LaravelMysqlSpatial\Exceptions\SpatialFieldsNotDefinedException; +use Grimzy\LaravelMysqlSpatial\Exceptions\UnknownSpatialRelationFunction; use Grimzy\LaravelMysqlSpatial\Types\Geometry; use Grimzy\LaravelMysqlSpatial\Types\GeometryInterface; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; @@ -37,6 +38,17 @@ trait SpatialTrait public $geometries = []; + protected $stRelations = [ + 'within', + 'crosses', + 'contains', + 'disjoint', + 'equals', + 'intersects', + 'overlaps', + 'touches', + ]; + /** * Create a new Eloquent query builder for the model. * @@ -49,12 +61,21 @@ public function newEloquentBuilder($query) return new Builder($query); } + protected function newBaseQueryBuilder() + { + $connection = $this->getConnection(); + + return new BaseBuilder( + $connection, $connection->getQueryGrammar(), $connection->getPostProcessor() + ); + } + protected function performInsert(EloquentBuilder $query, array $options = []) { foreach ($this->attributes as $key => $value) { if ($value instanceof GeometryInterface) { $this->geometries[$key] = $value; //Preserve the geometry objects prior to the insert - $this->attributes[$key] = $this->getConnection()->raw(sprintf("GeomFromText('%s')", $value->toWKT())); + $this->attributes[$key] = new SpatialExpression($value); } } @@ -89,12 +110,27 @@ public function getSpatialFields() } } + public function isColumnAllowed($geometryColumn) + { + if (!in_array($geometryColumn, $this->getSpatialFields())) { + throw new SpatialFieldsNotDefinedException(); + } + return true; + } + public function scopeDistance($query, $geometryColumn, $geometry, $distance, $exclude_self = false) { - $query->whereRaw("st_distance(`{$geometryColumn}`, GeomFromText('{$geometry->toWkt()}')) <= {$distance}"); + $this->isColumnAllowed($geometryColumn); + + $query->whereRaw("st_distance(`$geometryColumn`, ST_GeomFromText(?)) <= ?", [ + $geometry->toWkt(), + $distance, + ]); if ($exclude_self) { - $query->whereRaw("st_distance(`{$geometryColumn}`, GeomFromText('{$geometry->toWkt()}')) != 0"); + $query->whereRaw("st_distance(`$geometryColumn`, ST_GeomFromText(?)) != 0", [ + $geometry->toWkt(), + ]); } return $query; @@ -102,17 +138,30 @@ public function scopeDistance($query, $geometryColumn, $geometry, $distance, $ex public function scopeDistanceValue($query, $geometryColumn, $geometry) { + $this->isColumnAllowed($geometryColumn); + $columns = $query->getQuery()->columns; if (!$columns) { $query->select('*'); } - $query->selectRaw("st_distance(`{$geometryColumn}`, GeomFromText('{$geometry->toWkt()}')) as distance"); + + $query->selectRaw("st_distance(`$geometryColumn`, ST_GeomFromText(?)) as distance", [ + $geometry->toWkt(), + ]); } public function scopeComparison($query, $geometryColumn, $geometry, $relationship) { - $query->whereRaw("st_{$relationship}(`{$geometryColumn}`, GeomFromText('{$geometry->toWkt()}'))"); + $this->isColumnAllowed($geometryColumn); + + if (!in_array($relationship, $this->stRelations)) { + throw new UnknownSpatialRelationFunction($relationship); + } + + $query->whereRaw("st_{$relationship}(`$geometryColumn`, ST_GeomFromText(?))", [ + $geometry->toWkt(), + ]); return $query; } diff --git a/src/Exceptions/UnknownSpatialRelationFunction.php b/src/Exceptions/UnknownSpatialRelationFunction.php new file mode 100644 index 00000000..58733348 --- /dev/null +++ b/src/Exceptions/UnknownSpatialRelationFunction.php @@ -0,0 +1,7 @@ +getDoctrineSchemaManager()->getDatabasePlatform(); foreach ($geometries as $type) { diff --git a/tests/Integration/SpatialTest.php b/tests/Integration/SpatialTest.php index b2206f3b..1d1eb2a5 100644 --- a/tests/Integration/SpatialTest.php +++ b/tests/Integration/SpatialTest.php @@ -29,6 +29,14 @@ public function createApplication() $app['config']->set('database.connections.mysql.database', 'spatial_test'); $app['config']->set('database.connections.mysql.username', 'root'); $app['config']->set('database.connections.mysql.password', ''); + $app['config']->set('database.connections.mysql.modes', [ + 'ONLY_FULL_GROUP_BY', + 'STRICT_TRANS_TABLES', + 'NO_ZERO_IN_DATE', + 'NO_ZERO_DATE', + 'ERROR_FOR_DIVISION_BY_ZERO', + 'NO_ENGINE_SUBSTITUTION', + ]); return $app; } diff --git a/tests/Unit/Eloquent/BuilderTest.php b/tests/Unit/Eloquent/BuilderTest.php index d770026f..b77c6c4e 100644 --- a/tests/Unit/Eloquent/BuilderTest.php +++ b/tests/Unit/Eloquent/BuilderTest.php @@ -4,6 +4,7 @@ use BaseTestCase; use Grimzy\LaravelMysqlSpatial\Eloquent\Builder; +use Grimzy\LaravelMysqlSpatial\Eloquent\SpatialExpression; use Grimzy\LaravelMysqlSpatial\Eloquent\SpatialTrait; use Grimzy\LaravelMysqlSpatial\MysqlConnection; use Grimzy\LaravelMysqlSpatial\Types\LineString; @@ -36,50 +37,39 @@ protected function setUp() public function testUpdatePoint() { - $this->queryBuilder - ->shouldReceive('raw') - ->with("GeomFromText('POINT(2 1)')") - ->once(); - + $point = new Point(1, 2); $this->queryBuilder ->shouldReceive('update') + ->with(['point' => new SpatialExpression($point)]) ->once(); - $this->builder->update(['point' => new Point(1, 2)]); + $this->builder->update(['point' => $point]); } public function testUpdateLinestring() { - $this->queryBuilder - ->shouldReceive('raw') - ->with("GeomFromText('LINESTRING(0 0,1 1,2 2)')") - ->once(); + $linestring = new LineString([new Point(0, 0), new Point(1, 1), new Point(2, 2)]); $this->queryBuilder ->shouldReceive('update') + ->with(['linestring' => new SpatialExpression($linestring)]) ->once(); - $linestring = new LineString([new Point(0, 0), new Point(1, 1), new Point(2, 2)]); - $this->builder->update(['linestring' => $linestring]); } public function testUpdatePolygon() { - $this->queryBuilder - ->shouldReceive('raw') - ->with("GeomFromText('POLYGON((0 0,1 0),(1 0,1 1),(1 1,0 0))')") - ->once(); - - $this->queryBuilder - ->shouldReceive('update') - ->once(); - $linestrings[] = new LineString([new Point(0, 0), new Point(0, 1)]); $linestrings[] = new LineString([new Point(0, 1), new Point(1, 1)]); $linestrings[] = new LineString([new Point(1, 1), new Point(0, 0)]); $polygon = new Polygon($linestrings); + $this->queryBuilder + ->shouldReceive('update') + ->with(['polygon' => new SpatialExpression($polygon)]) + ->once(); + $this->builder->update(['polygon' => $polygon]); } } diff --git a/tests/Unit/Eloquent/SpatialTraitTest.php b/tests/Unit/Eloquent/SpatialTraitTest.php index d53e02e7..f70b8cbb 100644 --- a/tests/Unit/Eloquent/SpatialTraitTest.php +++ b/tests/Unit/Eloquent/SpatialTraitTest.php @@ -37,14 +37,15 @@ public function testInsertUpdatePointHasCorrectSql() $this->model->save(); $this->assertStringStartsWith('insert', $this->queries[0]); - $this->assertContains("GeomFromText('POINT(2 1)')", $this->queries[0]); + $this->assertContains('insert into `test_models` (`point`) values (ST_GeomFromText(?))', $this->queries[0]); + // TODO: assert bindings in query $this->assertTrue($this->model->exists); $this->model->point = new Point(1, 2); $this->model->save(); $this->assertStringStartsWith('update', $this->queries[1]); - $this->assertContains("GeomFromText('POINT(2 1)')", $this->queries[1]); + $this->assertContains('update `test_models` set `point` = ST_GeomFromText(?) where `id` = ?', $this->queries[1]); } public function testInsertUpdateLineStringHasCorrectSql() @@ -58,14 +59,16 @@ public function testInsertUpdateLineStringHasCorrectSql() $this->model->save(); $this->assertStringStartsWith('insert', $this->queries[0]); - $this->assertContains("GeomFromText('LINESTRING(2 1,3 2)')", $this->queries[0]); + $this->assertContains('insert into `test_models` (`linestring`) values (ST_GeomFromText(?))', $this->queries[0]); + // TODO: assert bindings in query $this->assertTrue($this->model->exists); $this->model->linestring = new \Grimzy\LaravelMysqlSpatial\Types\LineString([$point1, $point2]); $this->model->save(); $this->assertStringStartsWith('update', $this->queries[1]); - $this->assertContains("GeomFromText('LINESTRING(2 1,3 2)')", $this->queries[1]); + $this->assertContains('update `test_models` set `linestring` = ST_GeomFromText(?) where `id` = ?', $this->queries[1]); + // TODO: assert bindings in query } public function testInsertUpdatePolygonHasCorrectSql() @@ -83,13 +86,15 @@ public function testInsertUpdatePolygonHasCorrectSql() $this->model->save(); $this->assertStringStartsWith('insert', $this->queries[0]); - $this->assertContains("GeomFromText('POLYGON((2 1,3 2),(2 3,1 2))')", $this->queries[0]); + $this->assertContains('insert into `test_models` (`polygon`) values (ST_GeomFromText(?))', $this->queries[0]); + // TODO: assert bindings in query $this->assertTrue($this->model->exists); $this->model->polygon = new \Grimzy\LaravelMysqlSpatial\Types\Polygon([$linestring1, $linestring2]); $this->model->save(); $this->assertStringStartsWith('update', $this->queries[1]); - $this->assertContains("GeomFromText('POLYGON((2 1,3 2),(2 3,1 2))')", $this->queries[1]); + $this->assertContains('update `test_models` set `polygon` = ST_GeomFromText(?) where `id` = ?', $this->queries[1]); + // TODO: assert bindings in query } public function testInsertUpdateMultiPointHasCorrectSql() @@ -103,14 +108,16 @@ public function testInsertUpdateMultiPointHasCorrectSql() $this->model->save(); $this->assertStringStartsWith('insert', $this->queries[0]); - $this->assertContains("GeomFromText('MULTIPOINT((2 1),(3 2))')", $this->queries[0]); + $this->assertContains('insert into `test_models` (`multipoint`) values (ST_GeomFromText(?))', $this->queries[0]); + // TODO: assert bindings in query $this->assertTrue($this->model->exists); $this->model->multipoint = new \Grimzy\LaravelMysqlSpatial\Types\MultiPoint([$point1, $point2]); $this->model->save(); $this->assertStringStartsWith('update', $this->queries[1]); - $this->assertContains("GeomFromText('MULTIPOINT((2 1),(3 2))')", $this->queries[1]); + $this->assertContains('update `test_models` set `multipoint` = ST_GeomFromText(?) where `id` = ?', $this->queries[1]); + // TODO: assert bindings in query } public function testInsertUpdateMultiLineStringHasCorrectSql() @@ -128,13 +135,15 @@ public function testInsertUpdateMultiLineStringHasCorrectSql() $this->model->save(); $this->assertStringStartsWith('insert', $this->queries[0]); - $this->assertContains("GeomFromText('MULTILINESTRING((2 1,3 2),(2 3,1 2))')", $this->queries[0]); + $this->assertContains('insert into `test_models` (`multilinestring`) values (ST_GeomFromText(?))', $this->queries[0]); + // TODO: assert bindings in query $this->assertTrue($this->model->exists); $this->model->multilinestring = new \Grimzy\LaravelMysqlSpatial\Types\MultiLineString([$linestring1, $linestring2]); $this->model->save(); $this->assertStringStartsWith('update', $this->queries[1]); - $this->assertContains("GeomFromText('MULTILINESTRING((2 1,3 2),(2 3,1 2))')", $this->queries[1]); + $this->assertContains('update `test_models` set `multilinestring` = ST_GeomFromText(?) where `id` = ?', $this->queries[1]); + // TODO: assert bindings in query } public function testInsertUpdateMultiPolygonHasCorrectSql() @@ -161,13 +170,15 @@ public function testInsertUpdateMultiPolygonHasCorrectSql() $this->model->save(); $this->assertStringStartsWith('insert', $this->queries[0]); - $this->assertContains("GeomFromText('MULTIPOLYGON(((2 1,3 2),(2 3,1 2)),((5 4,6 5),(5 6,4 5)))')", $this->queries[0]); + $this->assertContains('insert into `test_models` (`multipolygon`) values (ST_GeomFromText(?))', $this->queries[0]); + // TODO: assert bindings in query $this->assertTrue($this->model->exists); $this->model->multipolygon = new \Grimzy\LaravelMysqlSpatial\Types\MultiPolygon([$polygon1, $polygon2]); $this->model->save(); $this->assertStringStartsWith('update', $this->queries[1]); - $this->assertContains("GeomFromText('MULTIPOLYGON(((2 1,3 2),(2 3,1 2)),((5 4,6 5),(5 6,4 5)))')", $this->queries[1]); + $this->assertContains('update `test_models` set `multipolygon` = ST_GeomFromText(?) where `id` = ?', $this->queries[1]); + // TODO: assert bindings in query } public function testInsertUpdateGeometryCollectionHasCorrectSql() @@ -183,13 +194,15 @@ public function testInsertUpdateGeometryCollectionHasCorrectSql() $this->model->save(); $this->assertStringStartsWith('insert', $this->queries[0]); - $this->assertContains("GeomFromText('GEOMETRYCOLLECTION(POINT(2 1),LINESTRING(3 2,3 3))')", $this->queries[0]); + $this->assertContains('insert into `test_models` (`geometrycollection`) values (ST_GeomFromText(?))', $this->queries[0]); + // TODO: assert bindings in query $this->assertTrue($this->model->exists); $this->model->geometrycollection = new \Grimzy\LaravelMysqlSpatial\Types\GeometryCollection([$point1, $linestring1]); $this->model->save(); $this->assertStringStartsWith('update', $this->queries[1]); - $this->assertContains("GeomFromText('GEOMETRYCOLLECTION(POINT(2 1),LINESTRING(3 2,3 3))')", $this->queries[1]); + $this->assertContains('update `test_models` set `geometrycollection` = ST_GeomFromText(?) where `id` = ?', $this->queries[1]); + // TODO: assert bindings in query } public function testSettingRawAttributes() @@ -215,7 +228,11 @@ public function testScopeDistance() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->wheres); - $this->assertContains("st_distance(`point`, GeomFromText('POINT(2 1)')) <= 10", $q->wheres[0]['sql']); + $bindings = $q->getRawBindings()['where']; + $this->assertNotEmpty($bindings); + $this->assertEquals('st_distance(`point`, ST_GeomFromText(?)) <= ?', $q->wheres[0]['sql']); + $this->assertEquals('POINT(2 1)', $bindings[0]); + $this->assertEquals(10, $bindings[1]); } public function testScopeDistanceExcludingSelf() @@ -226,8 +243,13 @@ public function testScopeDistanceExcludingSelf() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->wheres); - $this->assertContains("st_distance(`point`, GeomFromText('POINT(2 1)')) <= 10", $q->wheres[0]['sql']); - $this->assertContains("st_distance(`point`, GeomFromText('POINT(2 1)')) != 0", $q->wheres[1]['sql']); + $bindings = $q->getRawBindings()['where']; + $this->assertNotEmpty($bindings); + $this->assertEquals('st_distance(`point`, ST_GeomFromText(?)) <= ?', $q->wheres[0]['sql']); + $this->assertEquals('st_distance(`point`, ST_GeomFromText(?)) != 0', $q->wheres[1]['sql']); + $this->assertEquals('POINT(2 1)', $bindings[0]); + $this->assertEquals(10, $bindings[1]); + $this->assertEquals('POINT(2 1)', $bindings[2]); } public function testScopeDistanceValue() @@ -238,9 +260,12 @@ public function testScopeDistanceValue() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->columns); - $this->assertContains('*', $q->columns[0]); + $bindings = $q->getRawBindings()['select']; + $this->assertNotEmpty($bindings); + $this->assertEquals('*', $q->columns[0]); $this->assertInstanceOf(\Illuminate\Database\Query\Expression::class, $q->columns[1]); - $this->assertContains("st_distance(`point`, GeomFromText('POINT(2 1)')) as distance", $q->columns[1]->getValue()); + $this->assertEquals('st_distance(`point`, ST_GeomFromText(?)) as distance', $q->columns[1]->getValue()); + $this->assertEquals('POINT(2 1)', $bindings[0]); } public function testScopeDistanceValueWithSelect() @@ -251,9 +276,12 @@ public function testScopeDistanceValueWithSelect() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->columns); - $this->assertContains('some_column', $q->columns[0]); + $bindings = $q->getRawBindings()['select']; + $this->assertNotEmpty($bindings); + $this->assertEquals('some_column', $q->columns[0]); $this->assertInstanceOf(\Illuminate\Database\Query\Expression::class, $q->columns[1]); - $this->assertContains("st_distance(`point`, GeomFromText('POINT(2 1)')) as distance", $q->columns[1]->getValue()); + $this->assertEquals('st_distance(`point`, ST_GeomFromText(?)) as distance', $q->columns[1]->getValue()); + $this->assertEquals('POINT(2 1)', $bindings[0]); } private function buildTestPolygon() @@ -278,7 +306,10 @@ public function testScopeComparison() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->wheres); - $this->assertContains("st_within(`point`, GeomFromText('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))'))", $q->wheres[0]['sql']); + $bindings = $q->getRawBindings()['where']; + $this->assertNotEmpty($bindings); + $this->assertContains('st_within(`point`, ST_GeomFromText(?))', $q->wheres[0]['sql']); + $this->assertEquals('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))', $bindings[0]); } public function testScopeWithin() @@ -288,7 +319,10 @@ public function testScopeWithin() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->wheres); - $this->assertContains("st_within(`point`, GeomFromText('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))'))", $q->wheres[0]['sql']); + $bindings = $q->getRawBindings()['where']; + $this->assertNotEmpty($bindings); + $this->assertContains('st_within(`point`, ST_GeomFromText(?))', $q->wheres[0]['sql']); + $this->assertEquals('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))', $bindings[0]); } public function testScopeCrosses() @@ -298,7 +332,10 @@ public function testScopeCrosses() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->wheres); - $this->assertContains("st_crosses(`point`, GeomFromText('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))'))", $q->wheres[0]['sql']); + $bindings = $q->getRawBindings()['where']; + $this->assertNotEmpty($bindings); + $this->assertContains('st_crosses(`point`, ST_GeomFromText(?))', $q->wheres[0]['sql']); + $this->assertEquals('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))', $bindings[0]); } public function testScopeContains() @@ -308,7 +345,10 @@ public function testScopeContains() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->wheres); - $this->assertContains("st_contains(`point`, GeomFromText('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))'))", $q->wheres[0]['sql']); + $bindings = $q->getRawBindings()['where']; + $this->assertNotEmpty($bindings); + $this->assertContains('st_contains(`point`, ST_GeomFromText(?))', $q->wheres[0]['sql']); + $this->assertEquals('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))', $bindings[0]); } public function testScopeDisjoint() @@ -318,7 +358,10 @@ public function testScopeDisjoint() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->wheres); - $this->assertContains("st_disjoint(`point`, GeomFromText('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))'))", $q->wheres[0]['sql']); + $bindings = $q->getRawBindings()['where']; + $this->assertNotEmpty($bindings); + $this->assertContains('st_disjoint(`point`, ST_GeomFromText(?))', $q->wheres[0]['sql']); + $this->assertEquals('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))', $bindings[0]); } public function testScopeEquals() @@ -328,7 +371,10 @@ public function testScopeEquals() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->wheres); - $this->assertContains("st_equals(`point`, GeomFromText('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))'))", $q->wheres[0]['sql']); + $bindings = $q->getRawBindings()['where']; + $this->assertNotEmpty($bindings); + $this->assertContains('st_equals(`point`, ST_GeomFromText(?))', $q->wheres[0]['sql']); + $this->assertEquals('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))', $bindings[0]); } public function testScopeIntersects() @@ -338,7 +384,10 @@ public function testScopeIntersects() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->wheres); - $this->assertContains("st_intersects(`point`, GeomFromText('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))'))", $q->wheres[0]['sql']); + $bindings = $q->getRawBindings()['where']; + $this->assertNotEmpty($bindings); + $this->assertContains('st_intersects(`point`, ST_GeomFromText(?))', $q->wheres[0]['sql']); + $this->assertEquals('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))', $bindings[0]); } public function testScopeOverlaps() @@ -348,7 +397,10 @@ public function testScopeOverlaps() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->wheres); - $this->assertContains("st_overlaps(`point`, GeomFromText('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))'))", $q->wheres[0]['sql']); + $bindings = $q->getRawBindings()['where']; + $this->assertNotEmpty($bindings); + $this->assertContains('st_overlaps(`point`, ST_GeomFromText(?))', $q->wheres[0]['sql']); + $this->assertEquals('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))', $bindings[0]); } public function testScopeDoesTouch() @@ -358,7 +410,10 @@ public function testScopeDoesTouch() $this->assertInstanceOf(\Grimzy\LaravelMysqlSpatial\Eloquent\Builder::class, $query); $q = $query->getQuery(); $this->assertNotEmpty($q->wheres); - $this->assertContains("st_touches(`point`, GeomFromText('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))'))", $q->wheres[0]['sql']); + $bindings = $q->getRawBindings()['where']; + $this->assertNotEmpty($bindings); + $this->assertContains('st_touches(`point`, ST_GeomFromText(?))', $q->wheres[0]['sql']); + $this->assertEquals('POLYGON((1 1,2 1),(2 1,2 2),(2 2,1 1))', $bindings[0]); } } From 097836979dce39b89267ce57378c15d682d3e2a3 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Tue, 3 Mar 2020 04:34:00 +0000 Subject: [PATCH 45/57] Apply fixes from StyleCI [ci skip] [skip ci] --- src/Eloquent/SpatialTrait.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index 7076a864..5ef5c222 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -115,6 +115,7 @@ public function isColumnAllowed($geometryColumn) if (!in_array($geometryColumn, $this->getSpatialFields())) { throw new SpatialFieldsNotDefinedException(); } + return true; } From 925dc5f15c64ddee2cac0dc2855f0d0c370d513d Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Mon, 2 Mar 2020 23:38:16 -0500 Subject: [PATCH 46/57] Removed mistakenly added conf in composer.json --- composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 5c7f0ac7..0026da46 100644 --- a/composer.json +++ b/composer.json @@ -41,8 +41,7 @@ "laravel": { "providers": [ "Grimzy\\LaravelMysqlSpatial\\SpatialServiceProvider" - ], - "require": "5.5.*" + ] } } } From 60b27954b7d85fe22a328ab5b4a3f6cbf6f39a31 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Mon, 2 Mar 2020 23:57:32 -0500 Subject: [PATCH 47/57] Updated build (added PHP 7.2 and 7.3) --- .travis.yml | 4 +++- composer.json | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e39c3e0a..96ae5a57 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,8 @@ php: - '5.6' - '7.0' - '7.1' + - '7.2' + - '7.3' env: - MYSQL_VERSION=5.6 @@ -17,7 +19,7 @@ services: - docker before_install: - - echo "memory_limit=2G" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini + - echo "memory_limit=23G" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - sudo /etc/init.d/mysql stop - make start_db V=$MYSQL_VERSION diff --git a/composer.json b/composer.json index 0026da46..8e345e42 100644 --- a/composer.json +++ b/composer.json @@ -11,14 +11,14 @@ ], "require": { "php": ">=5.5.9", - "illuminate/database": "^5.2|^6.0", + "illuminate/database": "^5.2||^6.0", "geo-io/wkb-parser": "^1.0", "jmikola/geojson": "^1.0" }, "require-dev": { "phpunit/phpunit": "~4.8||~5.7", "mockery/mockery": "^0.9.9", - "laravel/laravel": "^5.2|^6.0", + "laravel/laravel": "^5.2||^6.0", "codeclimate/php-test-reporter": "dev-master", "doctrine/dbal": "^2.5", "laravel/browser-kit-testing": "^2.0" From 205e20192765ff78cf6d0afb565f4f26fdd4d519 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Tue, 3 Mar 2020 00:01:08 -0500 Subject: [PATCH 48/57] :laughing: :laughing: :laughing: --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 96ae5a57..5b5e88d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ services: - docker before_install: - - echo "memory_limit=23G" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini + - echo "memory_limit=3G" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - sudo /etc/init.d/mysql stop - make start_db V=$MYSQL_VERSION From 6508a7ffb22993e2818e1d92353dd73d0da4286b Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Tue, 3 Mar 2020 01:09:16 -0500 Subject: [PATCH 49/57] Port of validation when creating spatial collections --- composer.json | 2 + src/Types/GeometryCollection.php | 70 ++++++++++++++++++--- src/Types/LineString.php | 7 +++ src/Types/MultiLineString.php | 26 ++------ src/Types/MultiPolygon.php | 20 ++---- src/Types/PointCollection.php | 25 ++------ tests/Unit/BaseTestCase.php | 6 +- tests/Unit/Eloquent/SpatialTraitTest.php | 3 +- tests/Unit/Types/GeometryCollectionTest.php | 10 ++- tests/Unit/Types/GeometryTest.php | 5 +- tests/Unit/Types/MultiLineStringTest.php | 15 ++++- tests/Unit/Types/MultiPointTest.php | 20 ++++-- tests/Unit/Types/MultiPolygonTest.php | 10 ++- 13 files changed, 138 insertions(+), 81 deletions(-) diff --git a/composer.json b/composer.json index 8e345e42..84b7921d 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,8 @@ ], "require": { "php": ">=5.5.9", + "ext-pdo": "*", + "ext-json": "*", "illuminate/database": "^5.2||^6.0", "geo-io/wkb-parser": "^1.0", "jmikola/geojson": "^1.0" diff --git a/src/Types/GeometryCollection.php b/src/Types/GeometryCollection.php index 2e1f0321..69d7fe29 100755 --- a/src/Types/GeometryCollection.php +++ b/src/Types/GeometryCollection.php @@ -14,6 +14,20 @@ class GeometryCollection extends Geometry implements IteratorAggregate, ArrayAccess, Arrayable, Countable { + /** + * The minimum number of items required to create this collection. + * + * @var int + */ + protected $minimumCollectionItems = 1; + + /** + * The class of the items in the collection. + * + * @var string + */ + protected $collectionItemType = GeometryInterface::class; + /** * The items contained in the spatial collection. * @@ -28,13 +42,7 @@ class GeometryCollection extends Geometry implements IteratorAggregate, ArrayAcc */ public function __construct(array $geometries) { - $validated = array_filter($geometries, function ($value) { - return $value instanceof GeometryInterface; - }); - - if (count($geometries) !== count($validated)) { - throw new InvalidArgumentException('$geometries must be an array of Geometry objects'); - } + $this->validateItems($geometries); $this->items = $geometries; } @@ -89,9 +97,7 @@ public function offsetGet($offset) public function offsetSet($offset, $value) { - if (!($value instanceof GeometryInterface)) { - throw new InvalidArgumentException('$value must be an instance of GeometryInterface'); - } + $this->validateItemType($value); if (is_null($offset)) { $this->items[] = $value; @@ -142,4 +148,48 @@ public function jsonSerialize() return new \GeoJson\Geometry\GeometryCollection($geometries); } + + /** + * Checks whether the items are valid to create this collection. + * + * @param array $items + */ + protected function validateItems(array $items) { + $this->validateItemCount($items); + + foreach ($items as $item) { + $this->validateItemType($item); + } + } + + /** + * Checks whether the array has enough items to generate a valid WKT. + * + * @param array $items + * + * @see $minimumCollectionItems + */ + protected function validateItemCount(array $items) { + if (count($items) < $this->minimumCollectionItems) { + $entries = $this->minimumCollectionItems === 1 ? 'entry' : 'entries'; + throw new InvalidArgumentException(sprintf( + '%s must contain at least %d %s', get_class($this), $this->minimumCollectionItems, $entries + )); + } + } + + /** + * Checks the type of the items in the array. + * + * @param $item + * + * @see $collectionItemType + */ + protected function validateItemType($item) { + if (!$item instanceof $this->collectionItemType) { + throw new InvalidArgumentException(sprintf( + '%s must be a collection of %s', get_class($this), $this->collectionItemType + )); + } + } } diff --git a/src/Types/LineString.php b/src/Types/LineString.php index 02097edd..8c226444 100644 --- a/src/Types/LineString.php +++ b/src/Types/LineString.php @@ -8,6 +8,13 @@ class LineString extends PointCollection { + /** + * The minimum number of items required to create this collection. + * + * @var int + */ + protected $minimumCollectionItems = 2; + public function toWKT() { return sprintf('LINESTRING(%s)', $this->toPairList()); diff --git a/src/Types/MultiLineString.php b/src/Types/MultiLineString.php index dd3342fd..64707d6a 100644 --- a/src/Types/MultiLineString.php +++ b/src/Types/MultiLineString.php @@ -5,29 +5,15 @@ use GeoJson\GeoJson; use GeoJson\Geometry\MultiLineString as GeoJsonMultiLineString; use Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException; -use InvalidArgumentException; class MultiLineString extends GeometryCollection { /** - * @param LineString[] $lineStrings + * The class of the items in the collection. + * + * @var string */ - public function __construct(array $lineStrings) - { - if (count($lineStrings) < 1) { - throw new InvalidArgumentException('$lineStrings must contain at least one entry'); - } - - $validated = array_filter($lineStrings, function ($value) { - return $value instanceof LineString; - }); - - if (count($lineStrings) !== count($validated)) { - throw new InvalidArgumentException('$lineStrings must be an array of LineString'); - } - - parent::__construct($lineStrings); - } + protected $collectionItemType = LineString::class; public function getLineStrings() { @@ -58,9 +44,7 @@ public function __toString() public function offsetSet($offset, $value) { - if (!($value instanceof LineString)) { - throw new InvalidArgumentException('$value must be an instance of LineString'); - } + $this->validateItemType($value); parent::offsetSet($offset, $value); } diff --git a/src/Types/MultiPolygon.php b/src/Types/MultiPolygon.php index aba2b6d1..16f2769c 100644 --- a/src/Types/MultiPolygon.php +++ b/src/Types/MultiPolygon.php @@ -10,19 +10,11 @@ class MultiPolygon extends GeometryCollection { /** - * @param Polygon[] $polygons + * The class of the items in the collection. + * + * @var string */ - public function __construct(array $polygons) - { - $validated = array_filter($polygons, function ($value) { - return $value instanceof Polygon; - }); - - if (count($polygons) !== count($validated)) { - throw new InvalidArgumentException('$polygons must be an array of Polygon'); - } - parent::__construct($polygons); - } + protected $collectionItemType = Polygon::class; public function toWKT() { @@ -93,9 +85,7 @@ protected static function assembleParts(array $parts) public function offsetSet($offset, $value) { - if (!($value instanceof Polygon)) { - throw new InvalidArgumentException('$value must be an instance of Polygon'); - } + $this->validateItemType($value); parent::offsetSet($offset, $value); } diff --git a/src/Types/PointCollection.php b/src/Types/PointCollection.php index af586b28..30d1b8de 100755 --- a/src/Types/PointCollection.php +++ b/src/Types/PointCollection.php @@ -8,24 +8,11 @@ abstract class PointCollection extends GeometryCollection { /** - * @param Point[] $points + * The class of the items in the collection. + * + * @var string */ - public function __construct(array $points) - { - if (count($points) < 2) { - throw new InvalidArgumentException('$points must contain at least two entries'); - } - - $validated = array_filter($points, function ($value) { - return $value instanceof Point; - }); - - if (count($points) !== count($validated)) { - throw new InvalidArgumentException('$points must be an array of Points'); - } - - parent::__construct($points); - } + protected $collectionItemType = Point::class; public function toPairList() { @@ -36,9 +23,7 @@ public function toPairList() public function offsetSet($offset, $value) { - if (!($value instanceof Point)) { - throw new InvalidArgumentException('$value must be an instance of Point'); - } + $this->validateItemType($value); parent::offsetSet($offset, $value); } diff --git a/tests/Unit/BaseTestCase.php b/tests/Unit/BaseTestCase.php index 44f323c5..0b53a414 100644 --- a/tests/Unit/BaseTestCase.php +++ b/tests/Unit/BaseTestCase.php @@ -7,12 +7,14 @@ public function tearDown() Mockery::close(); } - protected function assertException($exceptionName) + protected function assertException($exceptionName, $exceptionMessage = '', $exceptionCode = 0) { if (method_exists(parent::class, 'expectException')) { parent::expectException($exceptionName); + parent::expectExceptionMessage($exceptionMessage); + parent::expectExceptionCode($exceptionCode); } else { - $this->setExpectedException($exceptionName); + $this->setExpectedException($exceptionName, $exceptionMessage, $exceptionCode); } } } diff --git a/tests/Unit/Eloquent/SpatialTraitTest.php b/tests/Unit/Eloquent/SpatialTraitTest.php index f70b8cbb..2678cc07 100644 --- a/tests/Unit/Eloquent/SpatialTraitTest.php +++ b/tests/Unit/Eloquent/SpatialTraitTest.php @@ -46,6 +46,7 @@ public function testInsertUpdatePointHasCorrectSql() $this->assertStringStartsWith('update', $this->queries[1]); $this->assertContains('update `test_models` set `point` = ST_GeomFromText(?) where `id` = ?', $this->queries[1]); + // TODO: assert bindings in query } public function testInsertUpdateLineStringHasCorrectSql() @@ -421,7 +422,7 @@ class TestModel extends Model { use \Grimzy\LaravelMysqlSpatial\Eloquent\SpatialTrait; - protected $spatialFields = ['point']; // only required when fetching, not saving + protected $spatialFields = ['point']; // TODO: only required when fetching, not saving public $timestamps = false; diff --git a/tests/Unit/Types/GeometryCollectionTest.php b/tests/Unit/Types/GeometryCollectionTest.php index 07759c5f..8f5b9081 100644 --- a/tests/Unit/Types/GeometryCollectionTest.php +++ b/tests/Unit/Types/GeometryCollectionTest.php @@ -35,7 +35,10 @@ public function testJsonSerialize() public function testInvalidArgumentExceptionNotArrayGeometries() { - $this->assertException(InvalidArgumentException::class); + $this->assertException( + InvalidArgumentException::class, + 'Grimzy\LaravelMysqlSpatial\Types\GeometryCollection must be a collection of Grimzy\LaravelMysqlSpatial\Types\GeometryInterface' + ); $geometrycollection = new GeometryCollection([ $this->getPoint(), 1, @@ -85,7 +88,10 @@ public function testArrayAccess() $this->assertEquals($point100, $geometryCollection[100]); // assert invalid - $this->assertException(InvalidArgumentException::class); + $this->assertException( + InvalidArgumentException::class, + 'Grimzy\LaravelMysqlSpatial\Types\GeometryCollection must be a collection of Grimzy\LaravelMysqlSpatial\Types\GeometryInterface' + ); $geometryCollection[] = 1; } diff --git a/tests/Unit/Types/GeometryTest.php b/tests/Unit/Types/GeometryTest.php index 8bd765a7..e51022d5 100644 --- a/tests/Unit/Types/GeometryTest.php +++ b/tests/Unit/Types/GeometryTest.php @@ -32,7 +32,10 @@ public function testGetWKTClass() $this->assertEquals(MultiLineString::class, Geometry::getWKTClass('MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))')); $this->assertEquals(MultiPolygon::class, Geometry::getWKTClass('MULTIPOLYGON(((0 0,4 0,4 4,0 4,0 0),(1 1,2 1,2 2,1 2,1 1)), ((-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))')); $this->assertEquals(GeometryCollection::class, Geometry::getWKTClass('GEOMETRYCOLLECTION(POINT(2 3),LINESTRING(2 3,3 4))')); - $this->assertException(UnknownWKTTypeException::class); + $this->assertException( + UnknownWKTTypeException::class, + 'Type was TRIANGLE' + ); Geometry::getWKTClass('TRIANGLE((0 0, 0 9, 9 0, 0 0))'); } diff --git a/tests/Unit/Types/MultiLineStringTest.php b/tests/Unit/Types/MultiLineStringTest.php index df7b42e4..563ecbd1 100644 --- a/tests/Unit/Types/MultiLineStringTest.php +++ b/tests/Unit/Types/MultiLineStringTest.php @@ -59,13 +59,19 @@ public function testJsonSerialize() public function testInvalidArgumentExceptionAtLeastOneEntry() { - $this->assertException(InvalidArgumentException::class); + $this->assertException( + InvalidArgumentException::class, + 'Grimzy\LaravelMysqlSpatial\Types\MultiLineString must contain at least 1 entry' + ); $multilinestring = new MultiLineString([]); } public function testInvalidArgumentExceptionNotArrayOfLineString() { - $this->assertException(InvalidArgumentException::class); + $this->assertException( + InvalidArgumentException::class, + 'Grimzy\LaravelMysqlSpatial\Types\MultiLineString must be a collection of Grimzy\LaravelMysqlSpatial\Types\LineString' + ); $multilinestring = new MultiLineString([ new LineString([new Point(0, 0), new Point(1, 1)]), new Point(0, 1), @@ -98,7 +104,10 @@ public function testArrayAccess() $this->assertEquals($linestring2, $multilinestring[2]); // assert invalid - $this->assertException(InvalidArgumentException::class); + $this->assertException( + InvalidArgumentException::class, + 'Grimzy\LaravelMysqlSpatial\Types\MultiLineString must be a collection of Grimzy\LaravelMysqlSpatial\Types\LineString' + ); $multilinestring[] = 1; } } diff --git a/tests/Unit/Types/MultiPointTest.php b/tests/Unit/Types/MultiPointTest.php index 1e9bf7f4..6e94af87 100644 --- a/tests/Unit/Types/MultiPointTest.php +++ b/tests/Unit/Types/MultiPointTest.php @@ -58,13 +58,19 @@ public function testJsonSerialize() public function testInvalidArgumentExceptionAtLeastOneEntry() { - $this->assertException(InvalidArgumentException::class); + $this->assertException( + InvalidArgumentException::class, + 'Grimzy\LaravelMysqlSpatial\Types\MultiPoint must contain at least 1 entry' + ); $multipoint = new MultiPoint([]); } public function testInvalidArgumentExceptionNotArrayOfLineString() { - $this->assertException(InvalidArgumentException::class); + $this->assertException( + InvalidArgumentException::class, + 'Grimzy\LaravelMysqlSpatial\Types\MultiPoint must be a collection of Grimzy\LaravelMysqlSpatial\Types\Point' + ); $multipoint = new MultiPoint([ new Point(0, 0), 1, @@ -87,7 +93,10 @@ public function testArrayAccess() $this->assertEquals($point2, $multipoint[2]); // assert invalid - $this->assertException(InvalidArgumentException::class); + $this->assertException( + InvalidArgumentException::class, + 'Grimzy\LaravelMysqlSpatial\Types\MultiPoint must be a collection of Grimzy\LaravelMysqlSpatial\Types\Point' + ); $multipoint[] = 1; } @@ -132,7 +141,10 @@ public function testDeprecatedInsertPoint() $this->assertEquals($point2, $multipoint[1]); $this->assertEquals($point3, $multipoint[2]); - $this->assertException(InvalidArgumentException::class); + $this->assertException( + InvalidArgumentException::class, + '$index is greater than the size of the array' + ); $multipoint->insertPoint(100, new Point(100, 100)); } } diff --git a/tests/Unit/Types/MultiPolygonTest.php b/tests/Unit/Types/MultiPolygonTest.php index adcac1e1..f4df9983 100644 --- a/tests/Unit/Types/MultiPolygonTest.php +++ b/tests/Unit/Types/MultiPolygonTest.php @@ -70,7 +70,10 @@ public function testJsonSerialize() public function testInvalidArgumentExceptionNotArrayOfLineString() { - $this->assertException(InvalidArgumentException::class); + $this->assertException( + InvalidArgumentException::class, + 'Grimzy\LaravelMysqlSpatial\Types\MultiPolygon must be a collection of Grimzy\LaravelMysqlSpatial\Types\Polygon' + ); $multipolygon = new MultiPolygon([ $this->getPolygon1(), $this->getLineString1(), @@ -94,7 +97,10 @@ public function testArrayAccess() $this->assertEquals($polygon2, $multipolygon[2]); // assert invalid - $this->assertException(InvalidArgumentException::class); + $this->assertException( + InvalidArgumentException::class, + 'Grimzy\LaravelMysqlSpatial\Types\MultiPolygon must be a collection of Grimzy\LaravelMysqlSpatial\Types\Polygon' + ); $multipolygon[] = 1; } From ce1d086b365fd984a10921f46c8c6cedec362cda Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Tue, 3 Mar 2020 06:09:34 +0000 Subject: [PATCH 50/57] Apply fixes from StyleCI [ci skip] [skip ci] --- src/Types/GeometryCollection.php | 10 +++++++--- src/Types/MultiPolygon.php | 1 - 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Types/GeometryCollection.php b/src/Types/GeometryCollection.php index 69d7fe29..28251a38 100755 --- a/src/Types/GeometryCollection.php +++ b/src/Types/GeometryCollection.php @@ -154,7 +154,8 @@ public function jsonSerialize() * * @param array $items */ - protected function validateItems(array $items) { + protected function validateItems(array $items) + { $this->validateItemCount($items); foreach ($items as $item) { @@ -169,9 +170,11 @@ protected function validateItems(array $items) { * * @see $minimumCollectionItems */ - protected function validateItemCount(array $items) { + protected function validateItemCount(array $items) + { if (count($items) < $this->minimumCollectionItems) { $entries = $this->minimumCollectionItems === 1 ? 'entry' : 'entries'; + throw new InvalidArgumentException(sprintf( '%s must contain at least %d %s', get_class($this), $this->minimumCollectionItems, $entries )); @@ -185,7 +188,8 @@ protected function validateItemCount(array $items) { * * @see $collectionItemType */ - protected function validateItemType($item) { + protected function validateItemType($item) + { if (!$item instanceof $this->collectionItemType) { throw new InvalidArgumentException(sprintf( '%s must be a collection of %s', get_class($this), $this->collectionItemType diff --git a/src/Types/MultiPolygon.php b/src/Types/MultiPolygon.php index 16f2769c..cd03f8bb 100644 --- a/src/Types/MultiPolygon.php +++ b/src/Types/MultiPolygon.php @@ -5,7 +5,6 @@ use GeoJson\GeoJson; use GeoJson\Geometry\MultiPolygon as GeoJsonMultiPolygon; use Grimzy\LaravelMysqlSpatial\Exceptions\InvalidGeoJsonException; -use InvalidArgumentException; class MultiPolygon extends GeometryCollection { From 7ab5153560d660b71cb737cc0109000cd622cf40 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sat, 7 Mar 2020 12:02:36 -0500 Subject: [PATCH 51/57] Laravel 7 compatibility (MySQL 6) --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 8e345e42..e0251d60 100644 --- a/composer.json +++ b/composer.json @@ -11,14 +11,14 @@ ], "require": { "php": ">=5.5.9", - "illuminate/database": "^5.2||^6.0", + "illuminate/database": "^5.2||^6.0||^7.0", "geo-io/wkb-parser": "^1.0", "jmikola/geojson": "^1.0" }, "require-dev": { "phpunit/phpunit": "~4.8||~5.7", "mockery/mockery": "^0.9.9", - "laravel/laravel": "^5.2||^6.0", + "laravel/laravel": "^5.2||^6.0||^7.0", "codeclimate/php-test-reporter": "dev-master", "doctrine/dbal": "^2.5", "laravel/browser-kit-testing": "^2.0" From a51d5d380a6f65389ff506d6d31ccd8d3bf5e5fe Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sat, 7 Mar 2020 17:02:53 +0000 Subject: [PATCH 52/57] Apply fixes from StyleCI [ci skip] [skip ci] --- src/Eloquent/SpatialTrait.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index 5ef5c222..54119b59 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -66,7 +66,9 @@ protected function newBaseQueryBuilder() $connection = $this->getConnection(); return new BaseBuilder( - $connection, $connection->getQueryGrammar(), $connection->getPostProcessor() + $connection, + $connection->getQueryGrammar(), + $connection->getPostProcessor() ); } From 26e6bdefea3bfff88f4f9e5868b2a378c5c70fdf Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 8 Mar 2020 21:45:44 +0000 Subject: [PATCH 53/57] Apply fixes from StyleCI [ci skip] [skip ci] --- src/Types/GeometryCollection.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Types/GeometryCollection.php b/src/Types/GeometryCollection.php index 28251a38..b199feff 100755 --- a/src/Types/GeometryCollection.php +++ b/src/Types/GeometryCollection.php @@ -176,7 +176,10 @@ protected function validateItemCount(array $items) $entries = $this->minimumCollectionItems === 1 ? 'entry' : 'entries'; throw new InvalidArgumentException(sprintf( - '%s must contain at least %d %s', get_class($this), $this->minimumCollectionItems, $entries + '%s must contain at least %d %s', + get_class($this), + $this->minimumCollectionItems, + $entries )); } } @@ -192,7 +195,9 @@ protected function validateItemType($item) { if (!$item instanceof $this->collectionItemType) { throw new InvalidArgumentException(sprintf( - '%s must be a collection of %s', get_class($this), $this->collectionItemType + '%s must be a collection of %s', + get_class($this), + $this->collectionItemType )); } } From 8439802e62a0394b9a30c688ac4080c6a9723f44 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 8 Mar 2020 17:31:46 -0400 Subject: [PATCH 54/57] Set $minimumCollectionItems to 0 for GeometryCollection and MultiPolygon. Adjusted child classes. Added/update tests. (cherry picked from commit 534dddc9d2f43550618196c4bfa4f4751acbb983) --- src/Types/GeometryCollection.php | 6 +++++- src/Types/MultiLineString.php | 7 +++++++ src/Types/MultiPoint.php | 7 +++++++ src/Types/MultiPolygon.php | 7 +++++++ tests/Integration/SpatialTest.php | 11 +++++++++++ tests/Unit/Types/GeometryCollectionTest.php | 22 +++++++++++++++++++++ tests/Unit/Types/MultiPolygonTest.php | 11 ++++++++++- 7 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/Types/GeometryCollection.php b/src/Types/GeometryCollection.php index b199feff..4311685a 100755 --- a/src/Types/GeometryCollection.php +++ b/src/Types/GeometryCollection.php @@ -19,7 +19,7 @@ class GeometryCollection extends Geometry implements IteratorAggregate, ArrayAcc * * @var int */ - protected $minimumCollectionItems = 1; + protected $minimumCollectionItems = 0; /** * The class of the items in the collection. @@ -66,6 +66,10 @@ public function __toString() public static function fromString($wktArgument) { + if (empty($wktArgument)) { + return new static([]); + } + $geometry_strings = preg_split('/,\s*(?=[A-Za-z])/', $wktArgument); return new static(array_map(function ($geometry_string) { diff --git a/src/Types/MultiLineString.php b/src/Types/MultiLineString.php index 64707d6a..dd815ebf 100644 --- a/src/Types/MultiLineString.php +++ b/src/Types/MultiLineString.php @@ -8,6 +8,13 @@ class MultiLineString extends GeometryCollection { + /** + * The minimum number of items required to create this collection. + * + * @var int + */ + protected $minimumCollectionItems = 1; + /** * The class of the items in the collection. * diff --git a/src/Types/MultiPoint.php b/src/Types/MultiPoint.php index fb55f9e8..eafa7c0e 100644 --- a/src/Types/MultiPoint.php +++ b/src/Types/MultiPoint.php @@ -8,6 +8,13 @@ class MultiPoint extends PointCollection { + /** + * The minimum number of items required to create this collection. + * + * @var int + */ + protected $minimumCollectionItems = 1; + public function toWKT() { return sprintf('MULTIPOINT(%s)', (string) $this); diff --git a/src/Types/MultiPolygon.php b/src/Types/MultiPolygon.php index cd03f8bb..0a5b6784 100644 --- a/src/Types/MultiPolygon.php +++ b/src/Types/MultiPolygon.php @@ -8,6 +8,13 @@ class MultiPolygon extends GeometryCollection { + /** + * The minimum number of items required to create this collection. + * + * @var int + */ + protected $minimumCollectionItems = 1; + /** * The class of the items in the collection. * diff --git a/tests/Integration/SpatialTest.php b/tests/Integration/SpatialTest.php index 1d1eb2a5..f8ebe62b 100644 --- a/tests/Integration/SpatialTest.php +++ b/tests/Integration/SpatialTest.php @@ -175,6 +175,17 @@ public function testInsertGeometryCollection() $this->assertDatabaseHas('geometry', ['id' => $geo->id]); } + public function testInsertEmptyGeometryCollection() + { + $geo = new GeometryModel(); + + $geo->location = new Point(1, 2); + + $geo->multi_geometries = new GeometryCollection([]); + $geo->save(); + $this->assertDatabaseHas('geometry', ['id' => $geo->id]); + } + public function testUpdate() { $geo = new GeometryModel(); diff --git a/tests/Unit/Types/GeometryCollectionTest.php b/tests/Unit/Types/GeometryCollectionTest.php index 8f5b9081..4576a77b 100644 --- a/tests/Unit/Types/GeometryCollectionTest.php +++ b/tests/Unit/Types/GeometryCollectionTest.php @@ -33,6 +33,28 @@ public function testJsonSerialize() $this->assertSame('{"type":"GeometryCollection","geometries":[{"type":"LineString","coordinates":[[0,0],[1,0],[1,1],[0,1],[0,0]]},{"type":"Point","coordinates":[200,100]}]}', json_encode($this->getGeometryCollection()->jsonSerialize())); } + public function testCanCreateEmptyGeometryCollection() + { + $geometryCollection = new GeometryCollection([]); + $this->assertInstanceOf(GeometryCollection::class, $geometryCollection); + } + + public function testFromWKTWithEmptyGeometryCollection() + { + /** + * @var GeometryCollection + */ + $geometryCollection = GeometryCollection::fromWKT('GEOMETRYCOLLECTION()'); + $this->assertInstanceOf(GeometryCollection::class, $geometryCollection); + + $this->assertEquals(0, $geometryCollection->count()); + } + + public function testToWKTWithEmptyGeometryCollection() + { + $this->assertEquals('GEOMETRYCOLLECTION()', (new GeometryCollection([]))->toWKT()); + } + public function testInvalidArgumentExceptionNotArrayGeometries() { $this->assertException( diff --git a/tests/Unit/Types/MultiPolygonTest.php b/tests/Unit/Types/MultiPolygonTest.php index f4df9983..98e3ba2e 100644 --- a/tests/Unit/Types/MultiPolygonTest.php +++ b/tests/Unit/Types/MultiPolygonTest.php @@ -68,7 +68,16 @@ public function testJsonSerialize() $this->assertSame('{"type":"MultiPolygon","coordinates":[[[[0,0],[1,0],[1,1],[0,1],[0,0]],[[10,10],[20,10],[20,20],[10,20],[10,10]]],[[[100,100],[200,100],[200,200],[100,200],[100,100]]]]}', json_encode($this->getMultiPolygon())); } - public function testInvalidArgumentExceptionNotArrayOfLineString() + public function testInvalidArgumentExceptionAtLeastOneEntry() + { + $this->assertException( + InvalidArgumentException::class, + 'Grimzy\LaravelMysqlSpatial\Types\MultiPolygon must contain at least 1 entry' + ); + $multipolygon = new MultiPolygon([]); + } + + public function testInvalidArgumentExceptionNotArrayOfPolygon() { $this->assertException( InvalidArgumentException::class, From 65543ee4e550b05742fa21c7b6281a81064571e0 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 8 Mar 2020 20:58:58 -0400 Subject: [PATCH 55/57] Fix issue where the WKB of empty GeometryCollections was not getting parsed --- src/Eloquent/SpatialTrait.php | 2 +- tests/Integration/Models/GeometryModel.php | 2 +- tests/Integration/SpatialTest.php | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index 54119b59..499e677a 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -95,7 +95,7 @@ public function setRawAttributes(array $attributes, $sync = false) $spatial_fields = $this->getSpatialFields(); foreach ($attributes as $attribute => &$value) { - if (in_array($attribute, $spatial_fields) && is_string($value) && strlen($value) >= 15) { + if (in_array($attribute, $spatial_fields) && is_string($value) && strlen($value) >= 13) { $value = Geometry::fromWKB($value); } } diff --git a/tests/Integration/Models/GeometryModel.php b/tests/Integration/Models/GeometryModel.php index 0b08186a..0565fd35 100644 --- a/tests/Integration/Models/GeometryModel.php +++ b/tests/Integration/Models/GeometryModel.php @@ -9,5 +9,5 @@ class GeometryModel extends Model protected $table = 'geometry'; - protected $spatialFields = ['location', 'line']; + protected $spatialFields = ['location', 'line', 'multi_geometries']; } diff --git a/tests/Integration/SpatialTest.php b/tests/Integration/SpatialTest.php index f8ebe62b..4a300ec0 100644 --- a/tests/Integration/SpatialTest.php +++ b/tests/Integration/SpatialTest.php @@ -184,6 +184,9 @@ public function testInsertEmptyGeometryCollection() $geo->multi_geometries = new GeometryCollection([]); $geo->save(); $this->assertDatabaseHas('geometry', ['id' => $geo->id]); + + $geo2 = GeometryModel::find($geo->id); + $this->assertInstanceOf(GeometryCollection::class, $geo2->multi_geometries); } public function testUpdate() From 60399e56eea513c644195b3dc77137feef7a80cb Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 8 Mar 2020 21:31:22 -0400 Subject: [PATCH 56/57] MySQL 5.6 saves null instead of empty GeometryCollection --- tests/Integration/SpatialTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Integration/SpatialTest.php b/tests/Integration/SpatialTest.php index 4a300ec0..cd99ec42 100644 --- a/tests/Integration/SpatialTest.php +++ b/tests/Integration/SpatialTest.php @@ -186,7 +186,7 @@ public function testInsertEmptyGeometryCollection() $this->assertDatabaseHas('geometry', ['id' => $geo->id]); $geo2 = GeometryModel::find($geo->id); - $this->assertInstanceOf(GeometryCollection::class, $geo2->multi_geometries); + $this->assertNull($geo2->multi_geometries); // MySQL 5.6 saves null instead of empty GeometryCollection } public function testUpdate() From 0b9dcd831c1979c343962483ad6a7a7650e52994 Mon Sep 17 00:00:00 2001 From: Joseph Estefane Date: Sun, 8 Mar 2020 22:07:50 -0400 Subject: [PATCH 57/57] Fix CodeClimate reporting for mysql-5.6 branch --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5b5e88d9..14518a32 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,11 +27,12 @@ install: composer install before_script: - mkdir -p build/logs + - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + - chmod +x ./cc-test-reporter + - ./cc-test-reporter before-build script: vendor/bin/phpunit --coverage-clover build/logs/clover.xml after_script: - php vendor/bin/coveralls -v - - vendor/bin/test-reporter - - + - ./cc-test-reporter after-build --coverage-input-type clover --exit-code $TRAVIS_TEST_RESULT