KAKAO_API_KEY=카카오 개발자 센터에서 발급 받은 REST API KEY
../domain/HubRouteEstimator.java
package org.spartahub.hubservice.domain;
import java.util.List;
/**
* 허브 다중 경유 총 거리 및 소요 시간 계산
* - 소요 시간은 hour 단위, 거리는 km 단위로 계산
* - 0번째는 거리 1번째는 소요시간
*/
public interface HubRouteEstimator {
double[] estimate(List<Hub> hubs);
}
../infrastructure/api/KakaoHubRouteEstimator.java
package org.spartahub.hubservice.infrastructure.api;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;
import org.spartahub.hubservice.domain.Hub;
import org.spartahub.hubservice.domain.HubRouteEstimator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class KakaoHubRouteEstimator implements HubRouteEstimator {
@Value("${kakao.restapi.key}")
private String apiKey;
@Override
public double[] estimate(List<Hub> hubs) {
if (hubs == null || hubs.isEmpty() || hubs.size() < 2) {
return null;
}
Map<String, Object> params = new HashMap<>();
Hub departure = hubs.getFirst(); // 출발지 허브
Hub arrival = hubs.getLast(); // 도착지 허브
// 출발지
params.put("origin", Map.of("name", departure.getHubName(), "x", departure.getLocation().getLongitude(), "y", departure.getLocation().getLatitude()));
// 도착지
params.put("destination", Map.of("name", arrival.getHubName(), "x", arrival.getLocation().getLongitude(), "y", arrival.getLocation().getLatitude()));
// 경유지
if (hubs.size() > 2) {
List<Map<String, Object>> waypoints = hubs.subList(1, hubs.size() - 1)
.stream()
.map(hub -> {
Map<String, Object> item = new HashMap<>();
item.put("name", hub.getHubName());
item.put("x", hub.getLocation().getLongitude());
item.put("y", hub.getLocation().getLatitude());
return item;
}).toList();
params.put("waypoints", waypoints);
}
ResponseEntity<JsonNode> response = RestClient.builder()
.baseUrl("<https://apis-navi.kakaomobility.com/v1/waypoints/directions>")
.build()
.post()
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "KakaoAK " + apiKey
)
.body(params)
.retrieve()
.toEntity(JsonNode.class);
if (response.getStatusCode().is2xxSuccessful()) {
double distance = 0.0, duration = 0.0;
try {
JsonNode nodes = response.getBody();
JsonNode routes = nodes.get("routes");
if (routes != null && routes.isArray()) {
for (JsonNode route : routes) {
distance += route.get("summary").get("distance").asDouble(0.0);
duration += route.get("summary").get("duration").asDouble(0.0);
}
}
return new double[] {distance / 1000.0, duration / 1000.0};
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
return null;
}
}
src/test/…/KakaoHubRouteEstimatorTest.java
package org.spartahub.hubservice.infrastructure.api;
import org.junit.jupiter.api.Test;
import org.spartahub.hubservice.domain.Hub;
import org.spartahub.hubservice.domain.HubRepository;
import org.spartahub.hubservice.domain.HubRouteEstimator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import java.util.Arrays;
import java.util.List;
@SpringBootTest
@ActiveProfiles("test")
public class KakaoHubRouteEstimatorTest {
@Autowired
HubRepository repository;
@Autowired
HubRouteEstimator estimator;
@Test
void hubRouteEstimatorTest() {
List<Hub> hubs = repository.findAll();
double[] item = estimator.estimate(hubs);
System.out.println("결과: " + Arrays.toString(item));
}
}
정상 계산이 되었다면