Skip to content

Commit

Permalink
#23 [Fix] 위도 경도 계산 로직 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
JSoi committed Aug 1, 2022
1 parent 8539133 commit 329fadf
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public StorePagedResponseDto getStoreInRange(@RequestParam(required = false) Big
@RequestParam(required = false) List<String> facility,
@PageableDefault Pageable pageable,
@AuthenticationPrincipal User user) {
return storeService.getStoreInRange(latStart, latEnd, lngStart, lngEnd, category, facility, pageable, user == null ? null : user.getUsername());
return storeService.getStoreInTwoPointRange(latStart, latEnd, lngStart, lngEnd, category, facility, pageable, user == null ? null : user.getUsername());
}

@GetMapping("/point")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package com.mpnp.baechelin.store.repository;

import com.mpnp.baechelin.bookmark.domain.Bookmark;
import com.mpnp.baechelin.bookmark.domain.QBookmark;
import com.mpnp.baechelin.common.QueryDslSearch;
import com.mpnp.baechelin.common.QuerydslLocation;
import com.mpnp.baechelin.store.domain.QStore;
import com.mpnp.baechelin.store.domain.Store;
import com.mpnp.baechelin.store.dto.StoreCardResponseDto;
import com.mpnp.baechelin.user.domain.QUser;
import com.mpnp.baechelin.user.domain.User;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Constant;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.Path;
import com.querydsl.core.types.dsl.*;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.criterion.Projection;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
Expand All @@ -24,8 +20,11 @@

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.mpnp.baechelin.common.QueryDslSearch.getSearchBooleanBuilder;
import static com.mpnp.baechelin.common.QuerydslLocation.locTwoPointAndConditions;
Expand All @@ -42,7 +41,7 @@ public StoreQueryRepository(JPAQueryFactory queryFactory) {
this.queryFactory = queryFactory;
}

public Page<Store> findBetweenOnePointOrder(BigDecimal latStart,
public Page<Store> findBetweenTwoPointOrder(BigDecimal latStart,
BigDecimal latEnd,
BigDecimal lngStart,
BigDecimal lngEnd,
Expand All @@ -54,14 +53,66 @@ public Page<Store> findBetweenOnePointOrder(BigDecimal latStart,
return findBetweenOnePointOrderNullCase(builder, pageable);
BigDecimal nowLat = (latStart.add(latEnd)).divide(new BigDecimal("2"), 22, RoundingMode.HALF_UP);
BigDecimal nowLng = (lngStart.add(lngEnd)).divide(new BigDecimal("2"), 22, RoundingMode.HALF_UP);
List<Store> storeList =
NumberPath<Double> path = Expressions.numberPath(Double.class, "realdist");
List<Tuple> tupleList =
queryFactory
.selectFrom(store)
.select(store,
// ((store.latitude.subtract(nowLat)).abs().add(store.longitude.subtract(nowLng)).abs()).as(diff),
MathExpressions.acos(MathExpressions.cos(MathExpressions.radians(Expressions.constant(nowLat)))).multiply(6371)
.multiply(MathExpressions.cos(MathExpressions.radians(store.latitude)))
.multiply(MathExpressions.cos(MathExpressions.radians(store.longitude)
.subtract(MathExpressions.radians(Expressions.constant(nowLng)))))
.add(MathExpressions.sin(MathExpressions.radians(Expressions.constant(nowLat)))
.multiply(MathExpressions.sin(MathExpressions.radians(store.latitude)))).doubleValue().as(path)
)
.from(store)
.where(builder)
.orderBy(orderDistance(nowLat, nowLng))
.orderBy(path.desc())
.limit(pageable.getPageSize())
.offset(pageable.getOffset())
.fetch();
List<Store> storeList = tupleList.stream().map(tuple -> tuple.get(store)).collect(Collectors.toList());
int fetchCount = queryFactory.selectFrom(store).where(builder).fetch().size();
return new PageImpl<>(storeList, pageable, fetchCount);
}


public Page<Store> findBetweenOnePointOrder(BigDecimal latStart,
BigDecimal latEnd,
BigDecimal lngStart,
BigDecimal lngEnd,
BigDecimal lat,
BigDecimal lng,
String category,
List<String> facility,
Pageable pageable) {
BooleanBuilder builder = QuerydslLocation.locAndConditions(latStart, latEnd, lngStart, lngEnd, category, facility);
if (latStart == null || lngStart == null || lngEnd == null || latEnd == null)
return findBetweenOnePointOrderNullCase(builder, pageable);
BigDecimal latH = new BigDecimal("110.852");
BigDecimal lngH = new BigDecimal("78.847");
NumberPath<Double> path = Expressions.numberPath(Double.class, "realdist");

NumberPath<BigDecimal> diff = Expressions.numberPath(BigDecimal.class, "diff");
List<Tuple> tupleList =
queryFactory
.select(store,
// ((store.latitude.subtract(nowLat)).abs().add(store.longitude.subtract(nowLng)).abs()).as(diff),
MathExpressions.acos(MathExpressions.cos(MathExpressions.radians(Expressions.constant(lat)))).multiply(6371)
.multiply(MathExpressions.cos(MathExpressions.radians(store.latitude)))
.multiply(MathExpressions.cos(MathExpressions.radians(store.longitude)
.subtract(MathExpressions.radians(Expressions.constant(lng)))))
.add(MathExpressions.sin(MathExpressions.radians(Expressions.constant(lat)))
.multiply(MathExpressions.sin(MathExpressions.radians(store.latitude)))).doubleValue().as(path)
)
.from(store)
.where(builder)
// .orderBy(diff.asc())
.orderBy(path.asc())
.limit(pageable.getPageSize())
.offset(pageable.getOffset())
.fetch();
List<Store> storeList = tupleList.stream().map(tuple -> tuple.get(store)).collect(Collectors.toList());
int fetchCount = queryFactory.selectFrom(store).where(builder).fetch().size();
return new PageImpl<>(storeList, pageable, fetchCount);
}
Expand All @@ -77,10 +128,6 @@ private Page<Store> findBetweenOnePointOrderNullCase(BooleanBuilder builder,
return new PageImpl<>(storeList, pageable, storeList.size());
}

private OrderSpecifier<?> orderDistance(BigDecimal nowLat, BigDecimal nowLng) {
return QStore.store.latitude.subtract(nowLat).abs().add(QStore.store.longitude.subtract(nowLng)).abs().asc();
}

public Page<Store> findStoreOrderByPoint(BigDecimal lat,
BigDecimal lng,
String category,
Expand All @@ -93,7 +140,6 @@ public Page<Store> findStoreOrderByPoint(BigDecimal lat,
.selectFrom(store)
.where(builder)
.orderBy(store.pointAvg.desc())
.orderBy(orderDistance(lat, lng))
.limit(pageable.getPageSize())
.offset(pageable.getOffset())
.fetch();
Expand Down
30 changes: 21 additions & 9 deletions src/main/java/com/mpnp/baechelin/store/service/StoreService.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,19 @@ public class StoreService {
* @param socialId 유저 소셜 로그인 아이디
* @return 조건을 만족하는 업장의 DTO
*/
public StorePagedResponseDto getStoreInRange(BigDecimal latStart, BigDecimal latEnd, BigDecimal lngStart, BigDecimal lngEnd, String category, List<String> facility, Pageable pageable, String socialId) {
public StorePagedResponseDto getStoreInTwoPointRange(BigDecimal latStart, BigDecimal latEnd, BigDecimal lngStart, BigDecimal lngEnd, String category, List<String> facility, Pageable pageable, String socialId) {
// public List<StoreCardResponseDto> getStoreInRange(BigDecimal latStart, BigDecimal latEnd, BigDecimal lngStart, BigDecimal lngEnd, String category, List<String> facility, Pageable pageable, String socialId) {
User targetUser = socialId == null ? null : userRepository.findBySocialId(socialId);
Page<Store> betweenLngLat = storeQueryRepository.findBetweenOnePointOrder(latStart, latEnd, lngStart, lngEnd, category, facility, pageable);
Page<Store> betweenLngLat = storeQueryRepository.findBetweenTwoPointOrder(latStart, latEnd, lngStart, lngEnd, category, facility, pageable);
// store 가져와서 dto 매핑
return getStoreCardPagedResponseDto(targetUser, betweenLngLat);
}

public StorePagedResponseDto getStoreInOnePointRange(BigDecimal latStart, BigDecimal latEnd, BigDecimal lngStart, BigDecimal lngEnd, BigDecimal lat, BigDecimal lng,
String category, List<String> facility, Pageable pageable, String socialId) {
// public List<StoreCardResponseDto> getStoreInRange(BigDecimal latStart, BigDecimal latEnd, BigDecimal lngStart, BigDecimal lngEnd, String category, List<String> facility, Pageable pageable, String socialId) {
User targetUser = socialId == null ? null : userRepository.findBySocialId(socialId);
Page<Store> betweenLngLat = storeQueryRepository.findBetweenOnePointOrder(latStart, latEnd, lngStart, lngEnd, lat, lng, category, facility, pageable);
// store 가져와서 dto 매핑
return getStoreCardPagedResponseDto(targetUser, betweenLngLat);
}
Expand All @@ -69,9 +78,10 @@ public StorePagedResponseDto getStoreInRange(BigDecimal latStart, BigDecimal lat
* @return 위도, 경도, 카테고리, 배리어 프리, 페이징을 만족하는 배리어 프리 업장 리턴
*/
public StorePagedResponseDto getStoreInOnePointRange(BigDecimal lat, BigDecimal lng, String category, List<String> facility, Pageable pageable, String socialId) {
BigDecimal[] range = QuerydslLocation.getRange(lat, lng, 10);
if (range == null) return getStoreInRange(null, null, null, null, category, facility, pageable, socialId);
return getStoreInRange(range[0], range[1], range[2], range[3], category, facility, pageable, socialId);
BigDecimal[] range = QuerydslLocation.getRange(lat, lng, 3);
if (range == null)
return getStoreInOnePointRange(null, null, null, null,lat,lng, category, facility, pageable, socialId);
return getStoreInOnePointRange(range[0], range[1], range[2], range[3],lat,lng, category, facility, pageable, socialId);
}

public StorePagedResponseDto getStoreInRangeMap(BigDecimal lat, BigDecimal lng, String category, List<String> facility, Pageable pageable, String socialId) {
Expand Down Expand Up @@ -130,6 +140,7 @@ private StorePagedResponseDto getStoreCardPagedResponseDto(User targetUser, Page

/**
* 업장 상세 조회
*
* @param storeId 업장 아이디
* @param socialId 유저 social 아이디
* @return 업장 상세 정보
Expand All @@ -141,7 +152,7 @@ public StoreDetailResponseDto getStore(long storeId, String socialId) {

store.getStoreImageList().forEach(storeImage -> storeImageList.add(storeImage.getStoreImageUrl()));
store.getReviewList().forEach(review -> review.getReviewImageList()
.forEach(reviewImage -> storeImageList.add(reviewImage.getReviewImageUrl())));
.forEach(reviewImage -> storeImageList.add(reviewImage.getReviewImageUrl())));

User targetUser = socialId == null ? null : userRepository.findBySocialId(socialId);

Expand Down Expand Up @@ -191,9 +202,10 @@ public Map<String, List<String>> getSigungu(String sido) {

/**
* 업장 검색
* @param sido 시/도명
* @param sigungu 시/군/구명
* @param keyword 검색어
*
* @param sido 시/도명
* @param sigungu 시/군/구명
* @param keyword 검색어
* @param category 카테고리
* @param facility 배리어 프리 시설
* @param socialId 사용자 소셜 아이디
Expand Down

0 comments on commit 329fadf

Please sign in to comment.