diff --git a/src/Eloquent/Builder.php b/src/Eloquent/Builder.php index 6230ed17..616e58dc 100755 --- a/src/Eloquent/Builder.php +++ b/src/Eloquent/Builder.php @@ -2,11 +2,18 @@ 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; class Builder extends EloquentBuilder { + /** + * @var SpatialTrait + */ + protected $model; + public function update(array $values) { foreach ($values as $key => &$value) { @@ -22,4 +29,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) + { + $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..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; @@ -130,170 +128,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; } }