public class AddressResolver {
private static final String KAKAO_API_URL = "https://dapi.kakao.com/v2/local/search/address.json?query=";
private static final String API_KEY = "";
private List<AddressData> addressDataList;
private int rowIndex;
public AddressResolver(String excelFilePath) {
this.addressDataList = new ArrayList<>();
this.rowIndex = 0;
loadAddressData(excelFilePath);
}
public void resolveAddresses() {
for (AddressData addressData : addressDataList) {
try {
resolveAddress(addressData);
Thread.sleep(200);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
private void resolveAddress(AddressData addressData) throws IOException {
String keyword = URLEncoder.encode(addressData.getAddress(), "UTF-8");
String apiUrl = KAKAO_API_URL + keyword;
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpGet httpGet = new HttpGet(apiUrl);
httpGet.addHeader("Authorization", "KakaoAK " + API_KEY);
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
HttpEntity entity = response.getEntity();
String responseBody = EntityUtils.toString(entity);
JsonObject jsonObject = JsonParser.parseString(responseBody).getAsJsonObject();
JsonArray documents = jsonObject.getAsJsonArray("documents");
if (documents.size() > 0) {
JsonObject document = documents.get(0).getAsJsonObject();
double latitude = document.get("y").getAsDouble();
double longitude = document.get("x").getAsDouble();
addressData.setLatitude(latitude);
addressData.setLongitude(longitude);
} else {
addressData.setLatitude(0);
addressData.setLongitude(0);
}
}
}
}
public void saveAddressData(String excelFilePath) throws IOException {
try (Workbook workbook = new XSSFWorkbook()) {
Sheet sheet = workbook.createSheet();
for (AddressData addressData : addressDataList) {
Row row = sheet.createRow(rowIndex);
row.createCell(0).setCellValue(addressData.getAddress());
row.createCell(1).setCellValue(addressData.getLatitude());
row.createCell(2).setCellValue(addressData.getLongitude());
rowIndex++;
}
try (FileOutputStream outputStream = new FileOutputStream(excelFilePath)) {
workbook.write(outputStream);
System.out.println("주소 데이터가 엑셀에 저장되었습니다!");
}
}
}
private void loadAddressData(String excelFilePath) {
try (Workbook workbook = new XSSFWorkbook(new FileInputStream(excelFilePath))) {
Sheet sheet = workbook.getSheetAt(0);
while (true) {
Row row = sheet.getRow(rowIndex);
if (row == null) {
break;
}
Cell cell = row.getCell(0);
if (cell != null) {
String address = cell.getStringCellValue();
addressDataList.add(new AddressData(address));
}
rowIndex++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String inputExcelFilePath = "src/main/resources/전통주_데이터.xlsx";
String outputExcelFilePath = "src/main/resources/전통주_데이터_카카오.xlsx";
AddressResolver addressResolver = new AddressResolver(inputExcelFilePath);
addressResolver.resolveAddresses();
try {
addressResolver.saveAddressData(outputExcelFilePath);
} catch (IOException e) {
e.printStackTrace();
}
}
}
class AddressData {
private String address;
private double latitude;
private double longitude;
public AddressData(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
}
간단하게 기능만 구현될 수 있게 작성했다 카카오 지도 api를 사용해서 위치 데이터를 기반으로 위도 경도 값을 받아올 수 있다
엑셀 데이터를 사용해서 엑셀에 있는 위치 데이터를 카카오 지도 api에 보낼 수 있게 했고 거기서 생긴 위도 경도 값을 다시 엑셀에 넣어 주었다
Controller
@Operation(summary = "전통주 지도 조회", description = "요청시 쿼리 파라미터로 좌측상단 좌표, 우측상단 좌표 보내주세요")
@GetMapping("/map")
public ResponseEntity<Slice<GetMapInDrinksResponse>> getMapInDrinks(@RequestParam Double startX, @RequestParam Double startY, @RequestParam Double endX, @RequestParam Double endY, @RequestParam int page, @RequestParam int size) {
Slice<GetMapInDrinksResponse> drinks = drinkService.getMapInDrinks(startX, startY, endX, endY, page, size);
return new ResponseEntity(drinks, HttpStatus.OK);
}
페이지네이션을 위해 page, size를 받았다
Service
public Slice<GetMapInDrinksResponse> getMapInDrinks(Double startX, Double startY, Double endX, Double endY, int page, int size) {
PageRequest pageRequest = PageRequest.of(page, size);
Slice<MapInDrinkData> drinkData = drinkRepository.findDrinksByCoordinate(pageRequest, startX, startY, endX, endY);
return new SliceImpl<>(getGetMapInDrinksResponses(drinkData), drinkData.getPageable(), drinkData.hasNext());
}
Repository
@Query("SELECT new co.kr.jurumarble.drink.domain.dto.MapInDrinkData(d.id, d.name, d.region, d.latitude, d.longitude) FROM Drink d " +
"WHERE (d.latitude BETWEEN :startX AND :endX AND d.longitude BETWEEN :startY AND :endY) " +
"ORDER BY d.name")
Slice<MapInDrinkData> findDrinksByCoordinate(PageRequest pageRequest, @Param("startX") Double startX, @Param("startY") Double startY, @Param("endX") Double endX, @Param("endY") Double endY);