@@ -18,50 +18,31 @@ public function scopeSelectDistanceTo(Builder $query, string $column, Point $poi
18
18
$ query ->select ('* ' );
19
19
}
20
20
21
- $ query ->selectRaw (
22
- "ST_Distance(ST_SRID( {$ column }, ?), ST_SRID(Point(?, ?), ?)) as distance " ,
23
- [
24
- $ point ->getSrid (),
25
- $ point ->getLng (),
26
- $ point ->getLat (),
27
- $ point ->getSrid (),
28
- ]
29
- );
21
+ match (DB ::connection ()->getDriverName ()) {
22
+ 'pgsql ' , 'mysql ' => $ this ->selectDistanceToMysqlAndPostgres ($ query , $ column , $ point ),
23
+ 'mariadb ' => $ this ->selectDistanceToMariaDb ($ query , $ column , $ point ),
24
+ default => throw new \Exception ('Unsupported database driver ' ),
25
+ };
30
26
}
31
27
32
28
public function scopeWithinDistanceTo (Builder $ query , string $ column , Point $ point , int $ distance ): void
33
29
{
34
- $ query
35
- ->whereRaw ("ST_AsText( {$ column }) != ? " , [
36
- 'POINT(0 0) ' ,
37
- ])
38
- ->whereRaw (
39
- "ST_Distance(ST_SRID( {$ column }, ?), ST_SRID(Point(?, ?), ?)) <= ? " ,
40
- [
41
- ...[
42
- $ point ->getSrid (),
43
- $ point ->getLng (),
44
- $ point ->getLat (),
45
- $ point ->getSrid (),
46
- ],
47
- $ distance ,
48
- ]
49
- );
30
+ match (DB ::connection ()->getDriverName ()) {
31
+ 'pgsql ' , 'mysql ' => $ this ->withinDistanceToMysqlAndPostgres ($ query , $ column , $ point , $ distance ),
32
+ 'mariadb ' => $ this ->withinDistanceToMariaDb ($ query , $ column , $ point , $ distance ),
33
+ default => throw new \Exception ('Unsupported database driver ' ),
34
+ };
50
35
}
51
36
52
37
public function scopeOrderByDistanceTo (Builder $ query , string $ column , Point $ point , string $ direction = 'asc ' ): void
53
38
{
54
39
$ direction = strtolower ($ direction ) === 'asc ' ? 'asc ' : 'desc ' ;
55
40
56
- $ query ->orderByRaw (
57
- "ST_Distance(ST_SRID( {$ column }, ?), ST_SRID(Point(?, ?), ?)) " . $ direction ,
58
- [
59
- $ point ->getSrid (),
60
- $ point ->getLng (),
61
- $ point ->getLat (),
62
- $ point ->getSrid (),
63
- ]
64
- );
41
+ match (DB ::connection ()->getDriverName ()) {
42
+ 'pgsql ' , 'mysql ' => $ this ->orderByDistanceToMysqlAndPostgres ($ query , $ column , $ point , $ direction ),
43
+ 'mariadb ' => $ this ->orderByDistanceToMariaDb ($ query , $ column , $ point , $ direction ),
44
+ default => throw new \Exception ('Unsupported database driver ' ),
45
+ };
65
46
}
66
47
67
48
public function newQuery (): Builder
@@ -85,4 +66,88 @@ public function getLocationCastedAttributes(): Collection
85
66
{
86
67
return collect ($ this ->getCasts ())->filter (fn ($ cast ) => $ cast === LocationCast::class)->keys ();
87
68
}
69
+
70
+ private function selectDistanceToMysqlAndPostgres (Builder $ query , string $ column , Point $ point ): Builder
71
+ {
72
+ return $ query ->selectRaw (
73
+ "ST_Distance(ST_SRID( {$ column }, ?), ST_SRID(Point(?, ?), ?)) as distance " ,
74
+ [
75
+ $ point ->getSrid (),
76
+ $ point ->getLng (),
77
+ $ point ->getLat (),
78
+ $ point ->getSrid (),
79
+ ]
80
+ );
81
+ }
82
+
83
+ private function selectDistanceToMariaDb (Builder $ query , string $ column , Point $ point ): Builder
84
+ {
85
+ return $ query ->selectRaw (
86
+ "ST_Distance(ST_SRID( {$ column }), ST_SRID(Point(?, ?))) as distance " ,
87
+ [
88
+ $ point ->getLng (),
89
+ $ point ->getLat (),
90
+ ]
91
+ );
92
+ }
93
+
94
+ private function withinDistanceToMysqlAndPostgres (Builder $ query , string $ column , Point $ point , int $ distance ): Builder
95
+ {
96
+ return $ query
97
+ ->whereRaw ("ST_AsText( {$ column }) != ? " , [
98
+ 'POINT(0 0) ' ,
99
+ ])
100
+ ->whereRaw (
101
+ "ST_Distance(ST_SRID( {$ column }, ?), ST_SRID(Point(?, ?), ?)) <= ? " ,
102
+ [
103
+ ...[
104
+ $ point ->getSrid (),
105
+ $ point ->getLng (),
106
+ $ point ->getLat (),
107
+ $ point ->getSrid (),
108
+ ],
109
+ $ distance ,
110
+ ]
111
+ );
112
+ }
113
+
114
+ private function withinDistanceToMariaDb (Builder $ query , string $ column , Point $ point , int $ distance ): Builder
115
+ {
116
+ return $ query
117
+ ->whereRaw ("ST_AsText( {$ column }) != ? " , [
118
+ 'POINT(0 0) ' ,
119
+ ])
120
+ ->whereRaw (
121
+ "ST_Distance(ST_SRID( {$ column }), ST_SRID(Point(?, ?))) <= ? " ,
122
+ [
123
+ $ point ->getLng (),
124
+ $ point ->getLat (),
125
+ $ distance ,
126
+ ]
127
+ );
128
+ }
129
+
130
+ private function orderByDistanceToMysqlAndPostgres (Builder $ query , string $ column , Point $ point , string $ direction = 'asc ' ): Builder
131
+ {
132
+ return $ query ->orderByRaw (
133
+ "ST_Distance(ST_SRID( {$ column }, ?), ST_SRID(Point(?, ?), ?)) " . $ direction ,
134
+ [
135
+ $ point ->getSrid (),
136
+ $ point ->getLng (),
137
+ $ point ->getLat (),
138
+ $ point ->getSrid (),
139
+ ]
140
+ );
141
+ }
142
+
143
+ private function orderByDistanceToMariaDb (Builder $ query , string $ column , Point $ point , string $ direction = 'asc ' ): Builder
144
+ {
145
+ return $ query ->orderByRaw (
146
+ "ST_Distance(ST_SRID( {$ column }), ST_SRID(Point(?, ?))) " . $ direction ,
147
+ [
148
+ $ point ->getLng (),
149
+ $ point ->getLat (),
150
+ ]
151
+ );
152
+ }
88
153
}
0 commit comments