Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#31] [FRATURE] 응급실 길찾기 #45

Merged
merged 6 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@

import lombok.RequiredArgsConstructor;

import com.nbe2.api.emergencyroom.dto.EmergencyRoomDirectionsResponse;
import com.nbe2.api.emergencyroom.dto.RealTimeEmergencyRoomResponse;
import com.nbe2.api.global.dto.Response;
import com.nbe2.domain.emergencyroom.Coordinate;
import com.nbe2.domain.emergencyroom.EmergencyRoomDirectionsInfo;
import com.nbe2.domain.emergencyroom.EmergencyRoomService;

@RestController
Expand Down Expand Up @@ -46,4 +48,15 @@ public Response<List<String>> saveSearEmergency(
emergencyRoomService.getEmergencyRoomListForName(hospitalName);
return Response.success(emergencyRoomListForName);
}

@GetMapping("/directions")
public Response<EmergencyRoomDirectionsResponse> directionsEmergency(
@RequestParam("myLocation") String myLocation,
@RequestParam("hospitalName") String hospitalName) {
EmergencyRoomDirectionsInfo emergencyRoomDirectionsInfo =
emergencyRoomService.directionsEmergencyRoom(myLocation, hospitalName);
EmergencyRoomDirectionsResponse emergencyRoomDirectionsResponse =
EmergencyRoomDirectionsResponse.to(emergencyRoomDirectionsInfo);
return Response.success(emergencyRoomDirectionsResponse);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package com.nbe2.api.emergencyroom.dto;

import java.util.List;

import lombok.Builder;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.nbe2.domain.emergencyroom.EmergencyRoomDirectionsInfo;

@Builder
public record EmergencyRoomDirectionsResponse(
@JsonProperty("code") Integer code,
@JsonProperty("message") String message,
@JsonProperty("currentDateTime") String currentDateTime,
@JsonProperty("route") Route route) {

@Builder
public record Route(@JsonProperty("traoptimal") List<Traoptimal> traoptimal) {}

@Builder
public record Traoptimal(
@JsonProperty("summary") Summary summary,
@JsonProperty("path") List<Double[]> path,
@JsonProperty("section") List<Section> section,
@JsonProperty("guide") List<Guide> guide) {}

@Builder
public record Summary(
@JsonProperty("start") Start start,
@JsonProperty("goal") Goal goal,
@JsonProperty("distance") Integer distance,
@JsonProperty("duration") Integer duration,
@JsonProperty("departureTime") String departureTime,
@JsonProperty("bbox") List<List<Double>> bbox,
@JsonProperty("tollFare") Integer tollFare,
@JsonProperty("taxiFare") Integer taxiFare,
@JsonProperty("fuelPrice") Integer fuelPrice) {}

@Builder
public record Start(@JsonProperty("location") List<Double> location) {}

@Builder
public record Goal(
@JsonProperty("location") List<Double> location, @JsonProperty("dir") Integer dir) {}

@Builder
public record Section(
@JsonProperty("pointIndex") Integer pointIndex,
@JsonProperty("pointCount") Integer pointCount,
@JsonProperty("distance") Integer distance,
@JsonProperty("name") String name,
@JsonProperty("congestion") Integer congestion,
@JsonProperty("speed") Integer speed) {}

@Builder
public record Guide(
@JsonProperty("pointIndex") Integer pointIndex,
@JsonProperty("type") Integer type,
@JsonProperty("instructions") String instructions,
@JsonProperty("distance") Integer distance,
@JsonProperty("duration") Integer duration) {}

public static EmergencyRoomDirectionsResponse to(EmergencyRoomDirectionsInfo e) {
return EmergencyRoomDirectionsResponse.builder()
.code(e.code())
.message(e.message())
.currentDateTime(e.currentDateTime())
.route(convertorRoute(e.route()))
.build();
}

private static EmergencyRoomDirectionsResponse.Route convertorRoute(
EmergencyRoomDirectionsInfo.Route route) {
List<EmergencyRoomDirectionsResponse.Traoptimal> traoptimalList =
route.traoptimal().stream()
.map(EmergencyRoomDirectionsResponse::convertorTraoptimal)
.toList();
return EmergencyRoomDirectionsResponse.Route.builder().traoptimal(traoptimalList).build();
}

private static EmergencyRoomDirectionsResponse.Traoptimal convertorTraoptimal(
EmergencyRoomDirectionsInfo.Traoptimal traoptimal) {
return EmergencyRoomDirectionsResponse.Traoptimal.builder()
.summary(convertoeSummary(traoptimal.summary()))
.path(traoptimal.path())
.section(convertorSections(traoptimal.section()))
.guide(convertorGuides(traoptimal.guide()))
.build();
}

private static EmergencyRoomDirectionsResponse.Summary convertoeSummary(
EmergencyRoomDirectionsInfo.Summary summary) {
return EmergencyRoomDirectionsResponse.Summary.builder()
.start(convertorStart(summary.start()))
.goal(convertorGoal(summary.goal()))
.distance(summary.distance())
.duration(summary.duration())
.departureTime(summary.departureTime())
.bbox(summary.bbox())
.tollFare(summary.tollFare())
.taxiFare(summary.taxiFare())
.fuelPrice(summary.fuelPrice())
.build();
}

private static List<EmergencyRoomDirectionsResponse.Section> convertorSections(
List<EmergencyRoomDirectionsInfo.Section> section) {
return section.stream().map(EmergencyRoomDirectionsResponse::convertorSection).toList();
}

private static EmergencyRoomDirectionsResponse.Section convertorSection(
EmergencyRoomDirectionsInfo.Section section) {
return EmergencyRoomDirectionsResponse.Section.builder()
.pointIndex(section.pointIndex())
.pointCount(section.pointCount())
.distance(section.distance())
.name(section.name())
.congestion(section.congestion())
.speed(section.speed())
.build();
}

private static List<EmergencyRoomDirectionsResponse.Guide> convertorGuides(
List<EmergencyRoomDirectionsInfo.Guide> guide) {
return guide.stream().map(EmergencyRoomDirectionsResponse::convertorGuide).toList();
}

private static EmergencyRoomDirectionsResponse.Guide convertorGuide(
EmergencyRoomDirectionsInfo.Guide guide) {
return EmergencyRoomDirectionsResponse.Guide.builder()
.type(guide.type())
.instructions(guide.instructions())
.distance(guide.distance())
.duration(guide.duration())
.build();
}

private static EmergencyRoomDirectionsResponse.Goal convertorGoal(
EmergencyRoomDirectionsInfo.Goal goal) {
return EmergencyRoomDirectionsResponse.Goal.builder()
.location(goal.location())
.dir(goal.dir())
.build();
}

private static EmergencyRoomDirectionsResponse.Start convertorStart(
EmergencyRoomDirectionsInfo.Start start) {
return EmergencyRoomDirectionsResponse.Start.builder().location(start.location()).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ public double distanceTo(Coordinate targetCoordinate) {

return Math.round(EARTH_RADIUS_KM * c * 100) / 100.0;
}

public String convertorLatitudeAndLongitude() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드명은 동사로 명명하는 게 좋을 거 같아서 convert가 나을 것 같습니당

아니면 getGps ..? 음 애매하네요 ㅋㅋㅋ

return longitude + "," + latitude;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ public interface EmergencyRoomClient {
List<RealTimeEmergencyRoomInfo> getRealTimeInfo(Region region);

List<EmergencyRoomInfo> getEmergencyRoomInfoData();

EmergencyRoomDirectionsInfo directionsEmergencyRoom(String start, String end);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getRouteToEmergencyRoom 이런거 어떨까요 아니면 find?

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.nbe2.domain.emergencyroom;

import org.springframework.stereotype.Component;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Component
public class EmergencyRoomDirections {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

별건 아닌데 Directions 라는 이름이 엔티티에 가깝다는 느낌이 들어서
혹시 Router 이런 이름은 어떠신가용


private final EmergencyRoomClient roomClient;

public EmergencyRoomDirectionsInfo directionsEmergencyRoom(
String myLocation, String latitudeAndLongitude) {
return roomClient.directionsEmergencyRoom(myLocation, latitudeAndLongitude);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.nbe2.domain.emergencyroom;

public interface EmergencyRoomDirectionsClient {

EmergencyRoomDirectionsInfo searchNaverDirections(String start, String end);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.nbe2.domain.emergencyroom;

import java.util.List;

import lombok.Builder;

import com.fasterxml.jackson.annotation.JsonProperty;

@Builder
public record EmergencyRoomDirectionsInfo(
@JsonProperty("code") Integer code,
@JsonProperty("message") String message,
@JsonProperty("currentDateTime") String currentDateTime,
@JsonProperty("route") Route route) {

@Builder
public record Route(@JsonProperty("traoptimal") List<Traoptimal> traoptimal) {}

@Builder
public record Traoptimal(
@JsonProperty("summary") Summary summary,
@JsonProperty("path") List<Double[]> path,
@JsonProperty("section") List<Section> section,
@JsonProperty("guide") List<Guide> guide) {}

@Builder
public record Summary(
@JsonProperty("start") Start start,
@JsonProperty("goal") Goal goal,
@JsonProperty("distance") Integer distance,
@JsonProperty("duration") Integer duration,
@JsonProperty("departureTime") String departureTime,
@JsonProperty("bbox") List<List<Double>> bbox,
@JsonProperty("tollFare") Integer tollFare,
@JsonProperty("taxiFare") Integer taxiFare,
@JsonProperty("fuelPrice") Integer fuelPrice) {}

@Builder
public record Start(@JsonProperty("location") List<Double> location) {}

@Builder
public record Goal(
@JsonProperty("location") List<Double> location, @JsonProperty("dir") Integer dir) {}

@Builder
public record Section(
@JsonProperty("pointIndex") Integer pointIndex,
@JsonProperty("pointCount") Integer pointCount,
@JsonProperty("distance") Integer distance,
@JsonProperty("name") String name,
@JsonProperty("congestion") Integer congestion,
@JsonProperty("speed") Integer speed) {}

@Builder
public record Guide(
@JsonProperty("pointIndex") Integer pointIndex,
@JsonProperty("type") Integer type,
@JsonProperty("instructions") String instructions,
@JsonProperty("distance") Integer distance,
@JsonProperty("duration") Integer duration) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,11 @@ public List<String> readByHospitalName(String hospitalName) {
.map(EmergencyRoom::getHpId)
.toList();
}

public Coordinate findByHospitalName(String hospitalName) {
return emergencyRoomRepository
.findByHospitalName(hospitalName)
.map(EmergencyRoom::getLocation)
.orElseThrow(() -> EmergencyRoomNotFoundException.EXCEPTION);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ public interface EmergencyRoomRepository extends JpaRepository<EmergencyRoom, Lo
List<EmergencyRoom> findByHospitalNameContaining(String name);

Optional<EmergencyRoom> findByHpId(String hpId);

Optional<EmergencyRoom> findByHospitalName(String hospitalName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class EmergencyRoomService {
private final DistanceCalculator distanceCalculator;
private final EmergencyRoomInitializer emergencyRoomInitializer;
private final EmergencyRoomReader emergencyRoomReader;
private final EmergencyRoomDirections emergencyRoomDirections;

@Transactional
public void init() {
Expand All @@ -32,4 +33,11 @@ public List<RealTimeEmergencyRoomWithDistance> getRealTimeEmergencyRooms(
public List<String> getEmergencyRoomListForName(String name) {
return emergencyRoomReader.readByHospitalName(name);
}

public EmergencyRoomDirectionsInfo directionsEmergencyRoom(
String myLocation, String hospitalName) {
Coordinate byHospitalLocation = emergencyRoomReader.findByHospitalName(hospitalName);
String latitudeAndLongitude = byHospitalLocation.convertorLatitudeAndLongitude();
return emergencyRoomDirections.directionsEmergencyRoom(myLocation, latitudeAndLongitude);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@

import lombok.RequiredArgsConstructor;

import com.nbe2.domain.emergencyroom.EmergencyRoomClient;
import com.nbe2.domain.emergencyroom.EmergencyRoomInfo;
import com.nbe2.domain.emergencyroom.RealTimeEmergencyRoomInfo;
import com.nbe2.domain.emergencyroom.Region;
import com.nbe2.domain.emergencyroom.*;
import com.nbe2.infra.naver.client.NaverApiClient;
import com.nbe2.infra.naver.dto.NaverDirectionsResponse;
import com.nbe2.infra.openapi.client.OpenApiFeignClient;
import com.nbe2.infra.openapi.dto.AllEmergencyRoomResponse;
import com.nbe2.infra.openapi.dto.EmergencyRoomResponse;
Expand All @@ -25,6 +24,7 @@
public class EmergencyRoomApiClient implements EmergencyRoomClient {

private final OpenApiFeignClient openApiFeignClient;
private final NaverApiClient naverApiClient;

@Override
public List<RealTimeEmergencyRoomInfo> getRealTimeInfo(Region region) {
Expand All @@ -42,6 +42,13 @@ public List<EmergencyRoomInfo> getEmergencyRoomInfoData() {
.collect(Collectors.toList());
}

@Override
public EmergencyRoomDirectionsInfo directionsEmergencyRoom(String start, String hospitalName) {
NaverDirectionsResponse realTimeEmergencyData =
naverApiClient.getEmergencyDirectionsData(start, hospitalName, "trafast");
return NaverDirectionsResponse.to(realTimeEmergencyData);
}

private List<EmergencyRoomInfo> getEmergencyData() {
return getAllEmergencyRoomData().parallelStream()
.map(ed -> openApiFeignClient.getEmergencyInfoData(ed.hpid(), 1, 1000).getItems())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.nbe2.infra.naver.client;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.nbe2.infra.naver.config.NaverApiClientConfiguration;
import com.nbe2.infra.naver.dto.NaverDirectionsResponse;

@FeignClient(
name = "naverApiClient",
url = "https://naveropenapi.apigw.ntruss.com/map-direction/v1/",
configuration = NaverApiClientConfiguration.class)
public interface NaverApiClient {

@GetMapping(value = "/driving")
NaverDirectionsResponse getEmergencyDirectionsData(
@RequestParam String goal, @RequestParam String start, @RequestParam String trafast);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.nbe2.infra.naver.config;

import org.springframework.context.annotation.Bean;

public class NaverApiClientConfiguration {

@Bean
public NaverRequestInterceptor naverRequestInterceptor() {
return new NaverRequestInterceptor();
}
}
Loading