-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLockerPinQueryService.java
More file actions
103 lines (89 loc) · 4.01 KB
/
Copy pathLockerPinQueryService.java
File metadata and controls
103 lines (89 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package com.zimdugo.locker.application.pin;
import com.zimdugo.locker.application.filter.LockerSearchFilterFactory;
import com.zimdugo.locker.application.common.LocationValidator;
import com.zimdugo.locker.application.search.LockerSearchResultQueryService;
import com.zimdugo.locker.application.result.search.LockerSearchItemResult;
import com.zimdugo.locker.application.result.pin.LockerPinItemResult;
import com.zimdugo.locker.application.result.pin.LockerPinResult;
import com.zimdugo.locker.domain.favorite.FavoriteLockerReader;
import com.zimdugo.locker.domain.locker.NearbyLocker;
import com.zimdugo.locker.domain.locker.NearbyLockerPlaceReader;
import com.zimdugo.locker.domain.search.LockerSearchFilter;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class LockerPinQueryService {
private final NearbyLockerPlaceReader nearbyLockerPlaceReader;
private final LockerPinAssembler lockerPinAssembler;
private final LockerSearchPinAssembler lockerSearchPinAssembler;
private final LockerPinClusterer lockerPinClusterer;
private final FavoriteLockerReader favoriteLockerReader;
private final LockerSearchResultQueryService lockerSearchResultQueryService;
public LockerPinResult getPins(Long userId, LockerPinQuery query) {
LocationValidator.validateBounds(query.swLat(), query.swLng(), query.neLat(), query.neLng()); //좌표 검증
LockerSearchFilter filter = LockerSearchFilterFactory.create(
query.sizeTypes(),
query.indoorOutdoorTypes(),
query.lockerTypes()
);
if (query.hasKeywordSearch()) {
return getSearchPins(userId, query, filter);
}
List<NearbyLocker> nearbyLockers = nearbyLockerPlaceReader.findWithinBounds(
query.swLat(),
query.swLng(),
query.neLat(),
query.neLng(),
filter
);
if (nearbyLockers.isEmpty()) {
return LockerPinResult.empty();
}
Set<Long> favoriteLockerIds = resolveFavoriteLockerIds(userId, nearbyLockers);
List<LockerPinItemResult> pins = lockerPinAssembler.assemble(nearbyLockers, favoriteLockerIds);
return LockerPinResult.of(lockerPinClusterer.cluster(pins, query.zoomLevel()));
}
private LockerPinResult getSearchPins(Long userId, LockerPinQuery query, LockerSearchFilter filter) {
if (query.userLat() == null || query.userLng() == null) {
return LockerPinResult.empty();
}
List<LockerSearchItemResult> items = lockerSearchResultQueryService.getDisplayableSearchItemsForPins(
userId,
query.userLat(),
query.userLng(),
query.keyword(),
filter
);
if (items.isEmpty()) {
return LockerPinResult.empty();
}
List<LockerPinItemResult> visiblePins = lockerSearchPinAssembler.assemble(items).stream()
.filter(pin -> isWithinBounds(pin, query))
.toList();
if (visiblePins.isEmpty()) {
return LockerPinResult.empty();
}
return LockerPinResult.of(lockerPinClusterer.cluster(visiblePins, query.zoomLevel()));
}
private boolean isWithinBounds(LockerPinItemResult pin, LockerPinQuery query) {
return pin.latitude() >= query.swLat()
&& pin.latitude() <= query.neLat()
&& pin.longitude() >= query.swLng()
&& pin.longitude() <= query.neLng();
}
private Set<Long> resolveFavoriteLockerIds(Long userId, List<NearbyLocker> lockers) {
if (userId == null) {
return Set.of();
}
Set<Long> lockerIds = lockers.stream()
.map(NearbyLocker::id)
.collect(Collectors.toSet());
return favoriteLockerReader.findFavoriteLockerIds(userId, lockerIds);
}
}