From b300287f80047edf82b84b1ebdc523f8803cbfa5 Mon Sep 17 00:00:00 2001 From: Matan Yadaev Date: Thu, 5 Nov 2020 11:33:42 +0200 Subject: [PATCH 1/2] use builder methods instead of scopes --- src/Eloquent/Builder.php | 179 ++++++++++++++++++++++++++++++++++ src/Eloquent/SpatialTrait.php | 165 +------------------------------ 2 files changed, 183 insertions(+), 161 deletions(-) diff --git a/src/Eloquent/Builder.php b/src/Eloquent/Builder.php index 6230ed17..a4f31dc6 100755 --- a/src/Eloquent/Builder.php +++ b/src/Eloquent/Builder.php @@ -2,11 +2,19 @@ namespace Grimzy\LaravelMysqlSpatial\Eloquent; +use Grimzy\LaravelMysqlSpatial\Exceptions\UnknownSpatialFunctionException; +use Grimzy\LaravelMysqlSpatial\Exceptions\UnknownSpatialRelationFunction; use Grimzy\LaravelMysqlSpatial\Types\GeometryInterface; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; +use Illuminate\Database\Query\Builder as QueryBuilder; class Builder extends EloquentBuilder { + /** + * @var SpatialTrait + */ + protected $model; + public function update(array $values) { foreach ($values as $key => &$value) { @@ -22,4 +30,175 @@ protected function asWKT(GeometryInterface $geometry) { return new SpatialExpression($geometry); } + + public function distance($geometryColumn, $geometry, $distance) + { + $this->model->isColumnAllowed($geometryColumn); + + $this->whereRaw("st_distance(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat')) <= ?", [ + $geometry->toWkt(), + $geometry->getSrid(), + $distance, + ]); + + return $this; + } + + public function distanceExcludingSelf($geometryColumn, $geometry, $distance) + { + $this->model->isColumnAllowed($geometryColumn); + + $this->distance($geometryColumn, $geometry, $distance); + + $this->whereRaw("st_distance(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat')) != 0", [ + $geometry->toWkt(), + $geometry->getSrid(), + ]); + + return $this; + } + + public function distanceValue($geometryColumn, $geometry) + { + $this->model->isColumnAllowed($geometryColumn); + + $columns = $this->getQuery()->columns; + + if (!$columns) { + $this->select('*'); + } + + $this->selectRaw("st_distance(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat')) as distance", [ + $geometry->toWkt(), + $geometry->getSrid(), + ]); + + return $this; + } + + public function distanceSphere($geometryColumn, $geometry, $distance) + { + $this->model->isColumnAllowed($geometryColumn); + + $this->whereRaw("st_distance_sphere(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat')) <= ?", [ + $geometry->toWkt(), + $geometry->getSrid(), + $distance, + ]); + + return $this; + } + + public function distanceSphereExcludingSelf($geometryColumn, $geometry, $distance) + { + $this->model->isColumnAllowed($geometryColumn); + + $this->distanceSphere($geometryColumn, $geometry, $distance); + + $this->whereRaw("st_distance_sphere($geometryColumn, ST_GeomFromText(?, ?, 'axis-order=long-lat')) != 0", [ + $geometry->toWkt(), + $geometry->getSrid(), + ]); + + return $this; + } + + public function distanceSphereValue($geometryColumn, $geometry) + { + $this->model->isColumnAllowed($geometryColumn); + + $columns = $this->getQuery()->columns; + + if (!$columns) { + $this->select('*'); + } + $this->selectRaw("st_distance_sphere(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat')) as distance", [ + $geometry->toWkt(), + $geometry->getSrid(), + ]); + + return $this; + } + + public function comparison($geometryColumn, $geometry, $relationship): self + { + $this->model->isColumnAllowed($geometryColumn); + + if (!in_array($relationship, $this->model->getStRelations())) { + throw new UnknownSpatialRelationFunction($relationship); + } + + $this->whereRaw("st_{$relationship}(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat'))", [ + $geometry->toWkt(), + $geometry->getSrid(), + ]); + + return $this; + } + + public function within($geometryColumn, $polygon) + { + return $this->comparison($geometryColumn, $polygon, 'within'); + } + + public function crosses($geometryColumn, $geometry) + { + return $this->comparison($geometryColumn, $geometry, 'crosses'); + } + + public function contains($geometryColumn, $geometry) + { + return $this->comparison($geometryColumn, $geometry, 'contains'); + } + + public function disjoint($geometryColumn, $geometry) + { + return $this->comparison($geometryColumn, $geometry, 'disjoint'); + } + + public function equals($geometryColumn, $geometry) + { + return $this->comparison($geometryColumn, $geometry, 'equals'); + } + + public function intersects($geometryColumn, $geometry) + { + return $this->comparison($geometryColumn, $geometry, 'intersects'); + } + + public function overlaps($geometryColumn, $geometry) + { + return $this->comparison($geometryColumn, $geometry, 'overlaps'); + } + + public function doesTouch($geometryColumn, $geometry) + { + return $this->comparison($geometryColumn, $geometry, 'touches'); + } + + public function orderBySpatial($geometryColumn, $geometry, $orderFunction, $direction = 'asc') + { + $this->model->isColumnAllowed($geometryColumn); + + if (!in_array($orderFunction, $this->model->getStOrderFunctions())) { + throw new UnknownSpatialFunctionException($orderFunction); + } + + $this->orderByRaw("st_{$orderFunction}(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat')) {$direction}", [ + $geometry->toWkt(), + $geometry->getSrid(), + ]); + + return $this; + } + + public function orderByDistance($geometryColumn, $geometry, $direction = 'asc') + { + return $this->orderBySpatial($geometryColumn, $geometry, 'distance', $direction); + } + + public function orderByDistanceSphere($geometryColumn, $geometry, $direction = 'asc') + { + return $this->orderBySpatial($geometryColumn, $geometry, 'distance_sphere', $direction); + } } diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index 5cc3f4b1..2f649989 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -130,170 +130,13 @@ public function isColumnAllowed($geometryColumn) return true; } - public function scopeDistance($query, $geometryColumn, $geometry, $distance) + public function getStRelations() { - $this->isColumnAllowed($geometryColumn); - - $query->whereRaw("st_distance(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat')) <= ?", [ - $geometry->toWkt(), - $geometry->getSrid(), - $distance, - ]); - - return $query; - } - - public function scopeDistanceExcludingSelf($query, $geometryColumn, $geometry, $distance) - { - $this->isColumnAllowed($geometryColumn); - - $query = $this->scopeDistance($query, $geometryColumn, $geometry, $distance); - - $query->whereRaw("st_distance(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat')) != 0", [ - $geometry->toWkt(), - $geometry->getSrid(), - ]); - - return $query; - } - - public function scopeDistanceValue($query, $geometryColumn, $geometry) - { - $this->isColumnAllowed($geometryColumn); - - $columns = $query->getQuery()->columns; - - if (!$columns) { - $query->select('*'); - } - - $query->selectRaw("st_distance(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat')) as distance", [ - $geometry->toWkt(), - $geometry->getSrid(), - ]); - } - - public function scopeDistanceSphere($query, $geometryColumn, $geometry, $distance) - { - $this->isColumnAllowed($geometryColumn); - - $query->whereRaw("st_distance_sphere(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat')) <= ?", [ - $geometry->toWkt(), - $geometry->getSrid(), - $distance, - ]); - - return $query; - } - - public function scopeDistanceSphereExcludingSelf($query, $geometryColumn, $geometry, $distance) - { - $this->isColumnAllowed($geometryColumn); - - $query = $this->scopeDistanceSphere($query, $geometryColumn, $geometry, $distance); - - $query->whereRaw("st_distance_sphere($geometryColumn, ST_GeomFromText(?, ?, 'axis-order=long-lat')) != 0", [ - $geometry->toWkt(), - $geometry->getSrid(), - ]); - - return $query; - } - - public function scopeDistanceSphereValue($query, $geometryColumn, $geometry) - { - $this->isColumnAllowed($geometryColumn); - - $columns = $query->getQuery()->columns; - - if (!$columns) { - $query->select('*'); - } - $query->selectRaw("st_distance_sphere(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat')) as distance", [ - $geometry->toWkt(), - $geometry->getSrid(), - ]); - } - - public function scopeComparison($query, $geometryColumn, $geometry, $relationship) - { - $this->isColumnAllowed($geometryColumn); - - if (!in_array($relationship, $this->stRelations)) { - throw new UnknownSpatialRelationFunction($relationship); - } - - $query->whereRaw("st_{$relationship}(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat'))", [ - $geometry->toWkt(), - $geometry->getSrid(), - ]); - - return $query; - } - - public function scopeWithin($query, $geometryColumn, $polygon) - { - return $this->scopeComparison($query, $geometryColumn, $polygon, 'within'); - } - - public function scopeCrosses($query, $geometryColumn, $geometry) - { - return $this->scopeComparison($query, $geometryColumn, $geometry, 'crosses'); - } - - public function scopeContains($query, $geometryColumn, $geometry) - { - return $this->scopeComparison($query, $geometryColumn, $geometry, 'contains'); - } - - public function scopeDisjoint($query, $geometryColumn, $geometry) - { - return $this->scopeComparison($query, $geometryColumn, $geometry, 'disjoint'); - } - - public function scopeEquals($query, $geometryColumn, $geometry) - { - return $this->scopeComparison($query, $geometryColumn, $geometry, 'equals'); - } - - public function scopeIntersects($query, $geometryColumn, $geometry) - { - return $this->scopeComparison($query, $geometryColumn, $geometry, 'intersects'); - } - - public function scopeOverlaps($query, $geometryColumn, $geometry) - { - return $this->scopeComparison($query, $geometryColumn, $geometry, 'overlaps'); - } - - public function scopeDoesTouch($query, $geometryColumn, $geometry) - { - return $this->scopeComparison($query, $geometryColumn, $geometry, 'touches'); - } - - public function scopeOrderBySpatial($query, $geometryColumn, $geometry, $orderFunction, $direction = 'asc') - { - $this->isColumnAllowed($geometryColumn); - - if (!in_array($orderFunction, $this->stOrderFunctions)) { - throw new UnknownSpatialFunctionException($orderFunction); - } - - $query->orderByRaw("st_{$orderFunction}(`$geometryColumn`, ST_GeomFromText(?, ?, 'axis-order=long-lat')) {$direction}", [ - $geometry->toWkt(), - $geometry->getSrid(), - ]); - - return $query; - } - - public function scopeOrderByDistance($query, $geometryColumn, $geometry, $direction = 'asc') - { - return $this->scopeOrderBySpatial($query, $geometryColumn, $geometry, 'distance', $direction); + return $this->stRelations; } - public function scopeOrderByDistanceSphere($query, $geometryColumn, $geometry, $direction = 'asc') + public function getStOrderFunctions() { - return $this->scopeOrderBySpatial($query, $geometryColumn, $geometry, 'distance_sphere', $direction); + return $this->stOrderFunctions; } } From 8a96b5d6c3ed31821fc62227c8a8d55696574bc7 Mon Sep 17 00:00:00 2001 From: Matan Yadaev Date: Thu, 5 Nov 2020 11:44:11 +0200 Subject: [PATCH 2/2] remove type-hint; remove unused imports --- src/Eloquent/Builder.php | 3 +-- src/Eloquent/SpatialTrait.php | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Eloquent/Builder.php b/src/Eloquent/Builder.php index a4f31dc6..616e58dc 100755 --- a/src/Eloquent/Builder.php +++ b/src/Eloquent/Builder.php @@ -6,7 +6,6 @@ use Grimzy\LaravelMysqlSpatial\Exceptions\UnknownSpatialRelationFunction; use Grimzy\LaravelMysqlSpatial\Types\GeometryInterface; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; -use Illuminate\Database\Query\Builder as QueryBuilder; class Builder extends EloquentBuilder { @@ -120,7 +119,7 @@ public function distanceSphereValue($geometryColumn, $geometry) return $this; } - public function comparison($geometryColumn, $geometry, $relationship): self + public function comparison($geometryColumn, $geometry, $relationship) { $this->model->isColumnAllowed($geometryColumn); diff --git a/src/Eloquent/SpatialTrait.php b/src/Eloquent/SpatialTrait.php index 2f649989..1c48a60f 100755 --- a/src/Eloquent/SpatialTrait.php +++ b/src/Eloquent/SpatialTrait.php @@ -3,8 +3,6 @@ namespace Grimzy\LaravelMysqlSpatial\Eloquent; use Grimzy\LaravelMysqlSpatial\Exceptions\SpatialFieldsNotDefinedException; -use Grimzy\LaravelMysqlSpatial\Exceptions\UnknownSpatialFunctionException; -use Grimzy\LaravelMysqlSpatial\Exceptions\UnknownSpatialRelationFunction; use Grimzy\LaravelMysqlSpatial\Types\Geometry; use Grimzy\LaravelMysqlSpatial\Types\GeometryInterface; use Illuminate\Database\Eloquent\Builder as EloquentBuilder;