@@ -18,50 +18,31 @@ public function scopeSelectDistanceTo(Builder $query, string $column, Point $poi
1818 $ query ->select ('* ' );
1919 }
2020
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+ };
3026 }
3127
3228 public function scopeWithinDistanceTo (Builder $ query , string $ column , Point $ point , int $ distance ): void
3329 {
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+ };
5035 }
5136
5237 public function scopeOrderByDistanceTo (Builder $ query , string $ column , Point $ point , string $ direction = 'asc ' ): void
5338 {
5439 $ direction = strtolower ($ direction ) === 'asc ' ? 'asc ' : 'desc ' ;
5540
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+ };
6546 }
6647
6748 public function newQuery (): Builder
@@ -85,4 +66,88 @@ public function getLocationCastedAttributes(): Collection
8566 {
8667 return collect ($ this ->getCasts ())->filter (fn ($ cast ) => $ cast === LocationCast::class)->keys ();
8768 }
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+ }
88153}
0 commit comments