Skip to content

Commit

Permalink
[feat] 산책 경로 생성 API #29
Browse files Browse the repository at this point in the history
  • Loading branch information
suhhyun524 committed Feb 22, 2024
1 parent 5329667 commit 9b73658
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 9 deletions.
8 changes: 7 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.mysql:mysql-connector-j'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
Expand All @@ -37,6 +38,11 @@ dependencies {
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
implementation 'org.modelmapper:modelmapper:3.1.1'

implementation("com.squareup.okhttp3:okhttp")
implementation("com.squareup.okhttp3:logging-interceptor")

implementation group: 'org.json', name: 'json', version: '20231013'

// swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.4'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-api:2.0.4'
Expand Down
20 changes: 14 additions & 6 deletions src/main/java/sungdong29/backend/domain/walk/WalkController.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,31 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import sungdong29.backend.domain.walk.dto.response.WalkPathResponseDTO;
import sungdong29.backend.domain.walk.service.WalkService;
import sungdong29.backend.global.config.user.UserDetails;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping
@RequestMapping(value = "/walk")
@Tag(name = "Walk")
public class WalkController {
private final WalkService walkService;

@Operation(summary = "산책로 경로 반환")
@GetMapping("places/{placeId}")
public WalkPathResponseDTO getWalkPath(
@RequestParam String xCoordinate,
@RequestParam String yCoordinate,
@PathVariable Long placeId
) {
return walkService.getWalkPath(xCoordinate, yCoordinate, placeId);
}

@Operation(summary = "산책 기록 저장")
@GetMapping(value = "places/{placeId}/walk")
@PostMapping(value = "places/{placeId}")
public ResponseEntity<Void> createWalkRecord(
@AuthenticationPrincipal UserDetails userDetails,
@PathVariable Long placeId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package sungdong29.backend.domain.walk.dto.response;

import lombok.Builder;
import sungdong29.backend.domain.walk.vo.WalkPathVo;

import java.util.List;

public class WalkPathListResponseDTO {

List<WalkPathVo> walkPathList;

@Builder
private WalkPathListResponseDTO(List<WalkPathVo> walkPathList) {
this.walkPathList = walkPathList;
}

public static WalkPathListResponseDTO from(List<WalkPathVo> walkPathList) {
return WalkPathListResponseDTO.builder()
.walkPathList(walkPathList)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package sungdong29.backend.domain.walk.dto.response;

import lombok.Builder;
import lombok.Getter;
import sungdong29.backend.domain.walk.domain.Walk;

import java.util.List;

@Getter
public class WalkPathResponseDTO {

private Long id;
private String name;
private List<String> lineString;

@Builder
private WalkPathResponseDTO(
Long id,
String name,
List<String> lineString) {
this.id = id;
this.name = name;
this.lineString = lineString;
}

public static WalkPathResponseDTO of(Walk walk, List<String> lineString) {
return WalkPathResponseDTO.builder()
.id(walk.getId())
.name(walk.getName())
.lineString(lineString)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package sungdong29.backend.domain.walk.helper;

import lombok.RequiredArgsConstructor;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import okhttp3.*;

import org.springframework.stereotype.Component;
import sungdong29.backend.domain.place.domain.Place;
import sungdong29.backend.domain.walk.domain.Walk;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Component
@RequiredArgsConstructor
public class WalkHelper {

@Value("${openapi.tmap.key}")
private String TMAP_APP_KEY;

public List<String> getLineString(String xCoordinate, String yCoordinate, Place place, Walk walk) {
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
String jsonString = "{\"startX\":" + xCoordinate + ",\"startY\":" + yCoordinate + ",\"endX\":" + place.getXCoordinate() + ",\"endY\":" + place.getYCoordinate() + ",\"passList\":\"" + walk.getXCoordinate() + ", " + walk.getYCoordinate() + "\",\"startName\":\"내 위치\",\"endName\":\"" + place.getName() + "\"}";
RequestBody body = RequestBody.create(jsonString, mediaType);
Request request = new Request.Builder()
.url("https://apis.openapi.sk.com/tmap/routes/pedestrian?version=1&callback=function")
.post(body)
.addHeader("accept", "application/json")
.addHeader("content-type", "application/json")
.addHeader("appKey", TMAP_APP_KEY)
.build();
try {
Response response = client.newCall(request).execute();
String stringResponse = response.body().string();

return extractLineStringCoordinates(stringResponse);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

private static List<String> extractLineStringCoordinates(String stringResponse) {
List<String> lineStringCoordinates = new ArrayList<>();

JSONObject jsonObject = new JSONObject(stringResponse);
JSONArray features = jsonObject.getJSONArray("features");

for (int i = 0; i < features.length(); i++) {
JSONObject feature = features.getJSONObject(i);
JSONObject geometry = feature.getJSONObject("geometry");

if ("LineString".equals(geometry.getString("type"))) {
JSONArray coordinatesArray = geometry.getJSONArray("coordinates");

if (i == 0) {
// For the first LineString, include all coordinates
for (int j = 0; j < coordinatesArray.length(); j++) {
JSONArray coordinate = coordinatesArray.getJSONArray(j);
lineStringCoordinates.add(coordinate.toString());
}
} else {
// For other LineStrings, exclude the first coordinate
for (int j = 1; j < coordinatesArray.length(); j++) {
JSONArray coordinate = coordinatesArray.getJSONArray(j);
lineStringCoordinates.add(coordinate.toString());
}
}
}
}

return lineStringCoordinates;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,46 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import sungdong29.backend.domain.place.domain.Place;
import sungdong29.backend.domain.place.helper.PlaceHelper;
import sungdong29.backend.domain.place.repository.PlaceRepository;
import sungdong29.backend.domain.user.domain.User;
import sungdong29.backend.domain.walk.domain.Walk;
import sungdong29.backend.domain.walk.domain.WalkHistory;
import sungdong29.backend.domain.walk.dto.response.WalkPathResponseDTO;
import sungdong29.backend.domain.walk.helper.WalkHelper;
import sungdong29.backend.domain.walk.repository.WalkHistoryRepository;
import sungdong29.backend.domain.walk.repository.WalkRepository;
import sungdong29.backend.global.config.user.UserDetails;

import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class WalkService {
private final WalkRepository walkRepository;
private final WalkHistoryRepository walkHistoryRepository;
private final PlaceRepository placeRepository;
private final PlaceHelper placeHelper;
private final WalkHelper walkHelper;

@Transactional
public WalkPathResponseDTO getWalkPath(String xCoordinate, String yCoordinate, Long placeId) {
Place place = placeHelper.getPlaceById(placeId);

// List<Walk> walks = walkRepository.findAllByDistanceAsc(xCoordinate, yCoordinate, place.getXCoordinate(), place.getYCoordinate());
Walk walk = walkRepository.findClosestWalk(xCoordinate, yCoordinate, place.getXCoordinate(), place.getYCoordinate());

List<String> lineString = walkHelper.getLineString(xCoordinate, yCoordinate, place, walk);
return WalkPathResponseDTO.of(walk, lineString);
}

@Transactional
public void createWalkRecord(UserDetails userDetails, Long placeId) {
User user = userDetails.getUser();
Place place = placeRepository.findById(placeId).orElseThrow();

Walk walk = Walk.of(user, place);
walkRepository.save(walk);
WalkHistory walkHistory = WalkHistory.of(user, place);
walkHistoryRepository.save(walkHistory);
}
}
35 changes: 35 additions & 0 deletions src/main/java/sungdong29/backend/domain/walk/vo/WalkPathVo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package sungdong29.backend.domain.walk.vo;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import sungdong29.backend.domain.walk.domain.Walk;

import java.util.List;

@Getter
@NoArgsConstructor
public class WalkPathVo {

private Long id;
private String name;
private List<String> lineString;

@Builder
private WalkPathVo(
Long id,
String name,
List<String> lineString) {
this.id = id;
this.name = name;
this.lineString = lineString;
}

public static WalkPathVo of(Walk walk, List<String> lineString) {
return WalkPathVo.builder()
.id(walk.getId())
.name(walk.getName())
.lineString(lineString)
.build();
}
}

0 comments on commit 9b73658

Please sign in to comment.