지대한 6 months ago
parent
commit
06ab6ee75f
  1. 15
      app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/service/ControlService.java
  2. 125
      common/util/src/main/java/kr/co/palnet/kac/util/CoordUtil.java
  3. 13
      http-client/http/ws.http

15
app/kac-websocket-app/src/main/java/kr/co/palnet/kac/websocket/service/ControlService.java

@ -2,13 +2,17 @@ package kr.co.palnet.kac.websocket.service;
import kr.co.palnet.kac.common.model.common.DroneControlDto;
import kr.co.palnet.kac.common.model.common.DroneDto;
import kr.co.palnet.kac.util.CoordUtil;
import kr.co.palnet.kac.websocket.core.model.BoundaryCoordinates;
import kr.co.palnet.kac.websocket.core.storage.ControlStorage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@RequiredArgsConstructor
@ -16,17 +20,22 @@ import java.util.*;
public class ControlService {
public List<DroneControlDto> getList(List<BoundaryCoordinates> coordinatesList) {
List<CoordUtil.Coordinates> polygon = coordinatesList.stream().map(bc -> CoordUtil.Coordinates.builder().x(bc.getLon()).y(bc.getLat()).build()).toList();
ControlStorage controlStorage = ControlStorage.getInstance();
List<DroneControlDto> controlDtoList = controlStorage.getList();
if (controlDtoList == null || controlDtoList.isEmpty()) return new ArrayList<>();
controlDtoList.sort(Comparator.reverseOrder());
List<DroneControlDto> result = controlDtoList.stream().filter(controlDto ->
// CoordUtil.isInsidePolygon(polygon, CoordUtil.Coordinates.builder().x(controlDto.getLon()).y(controlDto.getLat()).build())
CoordUtil.isInsideRectangle(polygon, CoordUtil.Coordinates.builder().x(controlDto.getLon()).y(controlDto.getLat()).build())
).sorted(Comparator.reverseOrder()).toList();
return controlDtoList;
return result;
}
public DroneControlDto dronDtoToControlDtoConvert(DroneDto dronDto) {
ControlStorage controlCache = ControlStorage.getInstance();

125
common/util/src/main/java/kr/co/palnet/kac/util/CoordUtil.java

@ -4,7 +4,11 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@Slf4j
public class CoordUtil {
@ -15,8 +19,13 @@ public class CoordUtil {
public static class Coordinates {
public double x;
public double y;
public String toString() {
return String.format("[x:: %s, y:: %s]", x, y);
}
}
// 좌표 두 거리간의 거리
public static double calculateDistance(Coordinates c1, Coordinates c2) {
double earthRadius = 6371; // 지구의 반지름 (단위: km)
@ -36,4 +45,120 @@ public class CoordUtil {
return distance;
}
// 특정 좌표가 다각형의 내부에 포함 여부 확인
public static boolean isInsidePolygon(List<Coordinates> polygon, Coordinates point) {
if (polygon.size() < 3) {
log.warn("polygon size more then 3 point.");
return false;
}
int intersectCount = 0;
for (int i = 0; i < polygon.size(); i++) {
Coordinates start = polygon.get(i);
Coordinates end = polygon.get((i + 1) % polygon.size());
// [무시] 주어진 좌표로 부터 선분이 좌측에 있을 경우 제외한다.
if (point.x > Math.max(start.x, end.x)) {
// log.info(">>> x pass -- px: {}, sx: {}, ex: {}", point.x, start.x, end.x);
continue;
}
// [무시] 주어진 좌표로 부터 선분이 위에 있거나 아래 있을 경우 교차 되지 않으므로 제외한다.
if (point.y < Math.min(start.y, end.y) || point.y > Math.max(start.y, end.y)) {
// log.info(">>> y pass -- py: {}, sy: {}, ey: {}", point.y, start.y, end.y);
continue;
}
// [선분위] 수직 선분 위에 주어진 좌표가 존재할 경우
if (point.x == start.x && point.x == end.x) {
// log.info("[선분위] 수직 선분 위에 주어진 좌표가 존재할 경우 {} - {} - {}", point, start, end);
return true;
}
// 수평 선분
if (start.y == end.y) {
if (point.y == start.y && point.x >= Math.min(start.x, start.y) && point.x <= Math.max(start.x, end.x)) {
// [선분위] 수평 선분 위에 주어진 좌표가 존재할 경우
// log.info("[선분위] 수평 선분 위에 주어진 좌표가 존재할 경우 {} - {} - {}", point, start, end);
return true;
} else {
// [무시] 그외 수평 선분은 제외
continue;
}
}
// [무시] 선분의 끝점이 주어진 좌표 y와 동일할 경우 아래에 있는 선분은 제외
if (point.y == Math.max(start.y, end.y)) {
// log.info("[무시] 선분의 끝점이 주어진 좌표 y와 동일할 경우 아래에 있는 선분은 제외");
continue;
}
double x = (point.y - start.y) * (end.x - start.x) / (end.y - start.y) + start.x;
// [선분위] 주어진 좌표가 선분 위에 존재할 경우
if (x == point.x) {
// log.info("[선분위] 주어진 좌표가 선분 위에 존재할 경우 {} - {} - {}", point, start, end);
return true;
}
if (x > point.x) {
intersectCount++;
}
}
return intersectCount % 2 == 1;
}
// 직사각형 내부 포함 여부
public static boolean isInsideRectangle(List<Coordinates> polygon, Coordinates point) {
if (polygon == null || polygon.size() != 4) {
log.warn("polygon size only 4 point");
return false;
}
double maxX = polygon.getFirst().getX();
double minX = polygon.getFirst().getX();
;
double maxY = polygon.getFirst().getY();
;
double minY = polygon.getFirst().getY();
;
for (int i = 1; i < polygon.size(); i++) {
if (polygon.get(i).getX() > maxX) {
maxX = polygon.get(i).getX();
}
if (polygon.get(i).getX() < minX) {
minX = polygon.get(i).getX();
}
if (polygon.get(i).getY() > maxY) {
maxY = polygon.get(i).getY();
}
if (polygon.get(i).getY() < minY) {
minY = polygon.get(i).getY();
}
}
if (point.getX() >= minX && point.getX() <= maxX && point.getY() >= minY && point.getY() <= maxY) {
return true;
}
return false;
}
// public static void main(String[] args) {
// List<Coordinates> polygon = new ArrayList<>();
// polygon.add(Coordinates.builder().x(15.0).y(10.0).build());
// polygon.add(Coordinates.builder().x(10.0).y(15.0).build());
// polygon.add(Coordinates.builder().x(10.0).y(20.0).build());
// polygon.add(Coordinates.builder().x(15.0).y(20.0).build());
// polygon.add(Coordinates.builder().x(20.0).y(15.0).build());
// polygon.add(Coordinates.builder().x(15.0).y(15.0).build());
//
// for (int i = 21; i >= 9; i--) {
// for (int j = 9; j <= 21; j++) {
// Coordinates p = Coordinates.builder().x(j).y(i).build();
// boolean flag = CoordUtil.isInsidePolygon(polygon, p);
// System.out.printf("%s ", flag ? "◼" : "◻");
// }
// System.out.println();
// }
// }
}

13
http-client/http/ws.http

@ -6,8 +6,17 @@ WEBSOCKET {{wsHost}}/ws
"type": "CURRENT_DRONE",
"body": [
{
"lat": 111.000,
"lon": 222.22
"lat": 35.36,
"lon": 126.6
},{
"lat": 36.46,
"lon": 126.6
},{
"lat": 36.46,
"lon": 127.77
},{
"lat": 35.36,
"lon": 127.77
}
]
}

Loading…
Cancel
Save