22
33import java .util .List ;
44
5+ import org .springframework .data .geo .Circle ;
6+ import org .springframework .data .geo .Distance ;
7+ import org .springframework .data .geo .Metrics ;
8+ import org .springframework .data .geo .Point ;
59import org .springframework .data .mongodb .core .MongoTemplate ;
610import org .springframework .data .mongodb .core .geo .GeoJsonPoint ;
7- import org .springframework .data .mongodb .core .geo .GeoJsonPolygon ;
811import org .springframework .data .mongodb .core .query .Criteria ;
912import org .springframework .data .mongodb .core .query .Query ;
1013import org .springframework .stereotype .Repository ;
@@ -22,7 +25,7 @@ public class AuctionCustomRepository {
2225 private final MongoTemplate mongoTemplate ;
2326
2427 public List <Auction > findByLocationRange (SearchAuctionRequest filter ) {
25- Criteria criteria = buildCriteria (filter );
28+ Criteria criteria = buildCircleCriteria (filter );
2629 Query query = new Query (criteria );
2730 query .fields ()
2831 .include ("gdsDspslDxdyLst" )
@@ -37,21 +40,41 @@ public List<Auction> findByLocationRange(SearchAuctionRequest filter) {
3740 }
3841
3942 public List <AuctionLocation > findLightweightByLocationRange (SearchAuctionLocationsRequest filter ) {
40- Criteria criteria = buildCriteria (filter );
43+ Criteria criteria = buildCircleCriteria (filter );
4144 Query query = new Query (criteria );
4245 query .fields ()
4346 .include ("location" )
4447 .include ("auctionStatus" );
4548 return mongoTemplate .find (query , AuctionLocation .class );
4649 }
4750
48- private Criteria buildCriteria (SearchAuctionRequest filter ) {
49- GeoJsonPoint ll = new GeoJsonPoint (filter .lbLng (), filter .lbLat ());
50- GeoJsonPoint ul = new GeoJsonPoint (filter .lbLng (), filter .rtLat ());
51- GeoJsonPoint ur = new GeoJsonPoint (filter .rtLng (), filter .rtLat ());
52- GeoJsonPoint lr = new GeoJsonPoint (filter .rtLng (), filter .lbLat ());
53- GeoJsonPolygon box = new GeoJsonPolygon (ll , ul , ur , lr , ll );
54- Criteria criteria = Criteria .where ("location" ).within (box );
51+ private Criteria buildCircleCriteria (SearchAuctionRequest filter ) {
52+ // Bounding box corners
53+ double minLng = filter .lbLng ();
54+ double maxLng = filter .rtLng ();
55+ double minLat = filter .lbLat ();
56+ double maxLat = filter .rtLat ();
57+
58+ // Center point
59+ double centerLng = (minLng + maxLng ) / 2 ;
60+ double centerLat = (minLat + maxLat ) / 2 ;
61+
62+ // Convert degrees to kilometers
63+ double kmPerLat = 111 ;
64+ double kmPerLng = 111 * Math .cos (Math .toRadians (centerLat ));
65+
66+ // Width and height in km
67+ double widthKm = (maxLng - minLng ) * kmPerLng ;
68+ double heightKm = (maxLat - minLat ) * kmPerLat ;
69+
70+ // Radius = half of diagonal
71+ double radiusKm = Math .sqrt (widthKm * widthKm + heightKm * heightKm ) / 2 ;
72+
73+ // Create circle (in kilometers)
74+ Circle sphere = new Circle (new Point (centerLng , centerLat ), new Distance (radiusKm , Metrics .KILOMETERS ));
75+
76+ // Build criteria: withinSphere uses 2dsphere index
77+ Criteria criteria = Criteria .where ("location" ).withinSphere (sphere );
5578 if (filter .isInProgress ()) {
5679 criteria = criteria .and ("auctionStatus" ).is ("진행" );
5780 } else {
@@ -60,13 +83,23 @@ private Criteria buildCriteria(SearchAuctionRequest filter) {
6083 return criteria ;
6184 }
6285
63- private Criteria buildCriteria (SearchAuctionLocationsRequest filter ) {
64- GeoJsonPoint ll = new GeoJsonPoint (filter .lbLng (), filter .lbLat ());
65- GeoJsonPoint ul = new GeoJsonPoint (filter .lbLng (), filter .rtLat ());
66- GeoJsonPoint ur = new GeoJsonPoint (filter .rtLng (), filter .rtLat ());
67- GeoJsonPoint lr = new GeoJsonPoint (filter .rtLng (), filter .lbLat ());
68- GeoJsonPolygon box = new GeoJsonPolygon (ll , ul , ur , lr , ll );
69- Criteria criteria = Criteria .where ("location" ).within (box );
86+ private Criteria buildCircleCriteria (SearchAuctionLocationsRequest filter ) {
87+ // Same logic for lightweight location search
88+ double minLng = filter .lbLng ();
89+ double maxLng = filter .rtLng ();
90+ double minLat = filter .lbLat ();
91+ double maxLat = filter .rtLat ();
92+
93+ double centerLng = (minLng + maxLng ) / 2 ;
94+ double centerLat = (minLat + maxLat ) / 2 ;
95+ double kmPerLat = 111 ;
96+ double kmPerLng = 111 * Math .cos (Math .toRadians (centerLat ));
97+ double widthKm = (maxLng - minLng ) * kmPerLng ;
98+ double heightKm = (maxLat - minLat ) * kmPerLat ;
99+ double radiusKm = Math .sqrt (widthKm * widthKm + heightKm * heightKm ) / 2 ;
100+ Circle sphere = new Circle (new Point (centerLng , centerLat ), new Distance (radiusKm , Metrics .KILOMETERS ));
101+
102+ Criteria criteria = Criteria .where ("location" ).withinSphere (sphere );
70103 if (filter .isInProgress ()) {
71104 criteria = criteria .and ("auctionStatus" ).is ("진행" );
72105 } else {
0 commit comments