Skip to content

Commit

Permalink
Merge pull request #2 from Seoul-Public-Data/feat/2
Browse files Browse the repository at this point in the history
[feat]  500m 내의 cctv 정보 반환 api 추가
  • Loading branch information
syyling authored Apr 8, 2024
2 parents d39d3fb + a7f261a commit 6c1f975
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package seouldata.seoul_backend.cctv.application.dto.request;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

public class CctvRequest {

@Getter
@NoArgsConstructor
public static class CctvNearRequest {
private double userLon;
private double userLat;

@Builder
public CctvNearRequest(double userLon, double userLat) {
this.userLon = userLon;
this.userLat = userLat;
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package seouldata.seoul_backend.cctv.application.dto.response;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

public class CctvResponse {

@Getter
@NoArgsConstructor
public static class CctvNearResponse {
private Long number;
private String autonomousRegion;
private String address;
private Double lon;
private Double lat;

@Builder
public CctvNearResponse(Long number, String autonomousRegion, String address,
Double lon, Double lat) {
this.number = number;
this.autonomousRegion = autonomousRegion;
this.address = address;
this.lon = lon;
this.lat = lat;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package seouldata.seoul_backend.cctv.domain.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "an_cctv")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class AnCctv {

private Long number;
private String autonomousRegion;
@Id
private String address;
private Double lon;
private Double lat;

@Builder
public AnCctv(Long number, String autonomousRegion, String address,
Double lon, Double lat) {
this.number = number;
this.autonomousRegion = autonomousRegion;
this.address = address;
this.lon = lon;
this.lat = lat;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package seouldata.seoul_backend.cctv.domain.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import seouldata.seoul_backend.cctv.domain.entity.AnCctv;

public interface AnCctvRepository extends JpaRepository<AnCctv, String> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package seouldata.seoul_backend.cctv.domain.service;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import seouldata.seoul_backend.cctv.application.dto.request.CctvRequest;
import seouldata.seoul_backend.cctv.application.dto.response.CctvResponse;
import seouldata.seoul_backend.cctv.domain.entity.AnCctv;
import seouldata.seoul_backend.cctv.domain.repository.AnCctvRepository;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Transactional
public class AnCctvService {

private final AnCctvRepository anCctvRepository;

public List<CctvResponse.CctvNearResponse> getCctvNear(CctvRequest.CctvNearRequest cctvNearRequest) {

// 사용자의 위치
double userLon = cctvNearRequest.getUserLon();
double userLat = cctvNearRequest.getUserLat();

// 모든 cctv 위치 가져오기
List<AnCctv> allCctvs = anCctvRepository.findAll();
// List<AnCctv> allCctvs = all.stream().distinct()
// .collect(Collectors.toList());


// 500m이내에 있는 cctv 정보 가져오기
List<CctvResponse.CctvNearResponse> nearCctvs = new ArrayList<>();

for (AnCctv cctv : allCctvs) {
double lon = cctv.getLon();
double lat = cctv.getLat();

double distance = calculationDistance(userLon, userLat, lon, lat);

if(distance <= 500) {
CctvResponse.CctvNearResponse nearCctv = CctvResponse.CctvNearResponse.builder()
.address(cctv.getAddress())
.autonomousRegion(cctv.getAutonomousRegion())
.lat(cctv.getLat())
.lon(cctv.getLon())
.number(cctv.getNumber())
.build();
nearCctvs.add(nearCctv);
}
}

return nearCctvs;

}

// 하버 사인 적용하여 두 점 사이 거리 구하기
public double calculationDistance(double userLon, double userLat, double lon, double lat) {
double earthRadius = 6371000; // 지구 반지름(미터)

double dLat = Math.toRadians(lat - userLat);
double dLon = Math.toRadians(lon - userLon);

double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.cos(Math.toRadians(userLat)) * Math.cos(Math.toRadians(lat))
* Math.sin(dLon / 2) * Math.sin(dLon / 2);

double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return earthRadius * c;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package seouldata.seoul_backend.cctv.presentation;

import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import seouldata.seoul_backend.cctv.application.dto.request.CctvRequest;
import seouldata.seoul_backend.cctv.application.dto.response.CctvResponse;
import seouldata.seoul_backend.cctv.domain.service.AnCctvService;

import java.util.List;

@RestController
@RequiredArgsConstructor
public class AnCctvController {
private final AnCctvService anCctvService;

@GetMapping("/api/cctv")
public ResponseEntity getCctvNear(@RequestBody CctvRequest.CctvNearRequest cctvNearRequest) {
List<CctvResponse.CctvNearResponse> cctvNear = anCctvService.getCctvNear(cctvNearRequest);
return ResponseEntity.ok(cctvNear);
}

}

0 comments on commit 6c1f975

Please sign in to comment.