-
자바 스프링 mysql 위치좌표(위도 경도) 정리, POINT DATAProject/NomadWorker 2022. 7. 22. 15:58
[한국외대 모각코] 도커 스터디 일정을 만든후 개인 공부를 한내용을 올린다.
다음 주 부터는 정기적으로 도커 내용이 TIL 에 들어 갈 듯 싶다.
내용 :자바 스프링 api 설계 주기능 : request 위도경도에 대한 response 로 주변 가게정보를 넘기는 api
Spring Boot
Spring jpa
mysql
자료 찾다보면 한번씩 하단 깃허브 와 관련된 블로그 자료를 볼것이다.
정말 감사함니다.. 대부분의 코드는 하단 깃헙을 참고하여 만들었습니다.
GitHub - wooody92/wooody92.github.io
Contribute to wooody92/wooody92.github.io development by creating an account on GitHub.
github.com
1. 버전확인 어쩌면 제일 중요한,,
mysql 크게 2 가지 버전이 있는데 v 5.6 과 v - 8이다 상황에 맞춰 gradle 이랑 yaml 을 맞춰 준다. 물론 hybernate 도..
1.application yml
jpa: hibernate: ddl-auto: update properties: hibernate: #show_sql: true format_sql: true default_batch_fetch_size: 100 dialect: org.hibernate.spatial.dialect.mysql.MySQL8SpatialDialect database-platform: org.hibernate.spatial.dialect.mysql.MySQL8SpatialDialect # database-platform: org.hibernate.spatial.dialect.mysql.MySQL56InnoDBSpatialDialect database: mysql
2.build.gradle. 자신의 hibernate version에 맞게,,
implementation group: 'org.hibernate', name: 'hibernate-spatial', version: '5.6.9.Final'
2 . data 넣기
Java sping 에서 import org.locationtech.jts.geom.Point;
을 import 후 변수를 Point type 으로 지정 하면 mysql 에서는 POINT 타입이 아닌 GEOMETRY 로 들어간다.
생성한 point data 종류를 확인을 하자. 제발,,
상황 geometry 타입에 (50.8 4.44) 넣고 싶다.
다음 쿼리는 mysql workbench 에서 넣었다.
UPDATE `testdb`.`place` SET `p_gpoint` = ST_GeomFromText('POINT(50.8 4.44)') WHERE (`p_id` = '7');
binary 데이터로 들어간것을 볼수가 있다. 출력을 해보자 ! LineString 이란 사각형 범위를 만드는 것이라 생각하면 된다.
mysql 에서는 안보여서 터미널 에서 실행했다.
방금 넣은 좌표 (50.8 4.44 ) 가 범위에 들어 가도록 좌표 범위를 적어주고 , 범위에 맞는다면 맞는 p_weekt 를 출력하게 한다.
// 쿼리문, SELECT p_weekt from testdb.place AS p WHERE MBRContains(ST_LINESTRINGFROMTEXT('LineString(60.8 4.492860, 50.149710 4.335226)'), p.p_gpoint);
자 이제 ,, javasping,jpa 를 이용하자.
DOMAIN
package hackathon.nomadworker.domain; import lombok.val; import org.locationtech.jts.geom.Point; import javax.persistence.*; import lombok.Getter; import lombok.Setter; import java.util.ArrayList; import java.util.List; @Entity @Getter @Setter public class Place { @Id @GeneratedValue @Column(name = "p_id") private long id; private String p_cate; private String p_name; private String p_weekt; private String p_weekndt; private String p_addr; private String p_image; private String p_storeType; private float p_latitude; private float p_longitude; private Integer rent_price; private Point p_gpoint; ... }
Repository
package hackathon.nomadworker.repository; import hackathon.nomadworker.domain.Place; import hackathon.nomadworker.util.Direction; import hackathon.nomadworker.util.GeometryUtil; import hackathon.nomadworker.util.Location; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; import javax.persistence.Query; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import java.util.List; @Repository @RequiredArgsConstructor public class PlaceRepository { private final EntityManager em; .. .. public List<Place> getNearByCoordinate(Double latitude, Double longitude, Double distance) { Location northEast = GeometryUtil .calculate(latitude, longitude, distance, Direction.NORTHEAST.getBearing()); Location southWest = GeometryUtil .calculate(latitude, longitude, distance, Direction.SOUTHWEST.getBearing()); double x1 = northEast.getLatitude(); double y1 = northEast.getLongitude(); double x2 = southWest.getLatitude(); double y2 = southWest.getLongitude(); System.out.println(x1); System.out.println(y1); System.out.println(x2); System.out.println(y2); String pointFormat = String.format("'LINESTRING(%f %f, %f %f)')", x1, y1, x2, y2); System.out.println(pointFormat); // Query query = em.createNativeQuery("SELECT p.p_id, p.p_cate, p.p_name,p.p_addr, p.p_image \n" + // "FROM place AS p \n"+ // "WHERE MBRContains(ST_LINESTRINGFROMTEXT(" + pointFormat + ", p.p_point)",Place.class).setMaxResults(15); Query query = em.createNativeQuery("SELECT * \n" + "FROM place AS p \n"+ "WHERE MBRContains(ST_LINESTRINGFROMTEXT(" + pointFormat + ",p.p_gpoint)",Place.class).setMaxResults(15); List<Place> places = query.getResultList(); System.out.println(places); return places; } }
Repo 단에서 원하는것만 가져올려고 하다가 에러 나서 전체를 * 가져 온후 서비스 단에서 원하는 정보만 걸러준다
Utils 총 3 가지의 class
package hackathon.nomadworker.util; import lombok.Getter; @Getter public enum Direction { NORTH(0.0), WEST(270.0), SOUTH(180.0), EAST(90.0), NORTHWEST(315.0), SOUTHWEST(225.0), SOUTHEAST(135.0), NORTHEAST(45.0); private final Double bearing; Direction(Double bearing) { this.bearing = bearing; }
package hackathon.nomadworker.util; public class GeometryUtil { public static Location calculate(Double baseLatitude, Double baseLongitude, Double distance, Double bearing) { Double radianLatitude = toRadian(baseLatitude); Double radianLongitude = toRadian(baseLongitude); Double radianAngle = toRadian(bearing); Double distanceRadius = distance / 6371.01; Double latitude = Math.asin(sin(radianLatitude) * cos(distanceRadius) + cos(radianLatitude) * sin(distanceRadius) * cos(radianAngle)); Double longitude = radianLongitude + Math.atan2(sin(radianAngle) * sin(distanceRadius) * cos(radianLatitude), cos(distanceRadius) - sin(radianLatitude) * sin(latitude)); longitude = normalizeLongitude(longitude); return new Location(toDegree(latitude), toDegree(longitude)); } private static Double toRadian(Double coordinate) { return coordinate * Math.PI / 180.0; } private static Double toDegree(Double coordinate) { return coordinate * 180.0 / Math.PI; } private static Double sin(Double coordinate) { return Math.sin(coordinate); } private static Double cos(Double coordinate) { return Math.cos(coordinate); } private static Double normalizeLongitude(Double longitude) { return (longitude + 540) % 360 - 180; } }
package hackathon.nomadworker.util; import lombok.Getter; @Getter public class Location { private Double latitude; private Double longitude; public Location(Double latitude, Double longitude) { this.latitude = latitude; this.longitude = longitude; } }
DTO. api requset, response 를 지정.
package hackathon.nomadworker.dto; import hackathon.nomadworker.domain.Place; import lombok.AllArgsConstructor; import lombok.Data; import org.locationtech.jts.geom.Point; public class PlaceDtos { @Data @AllArgsConstructor public static class PlaceResultResponse<T> { private String message; private int status; private T data; } ... @Data public static class PlaceDtoCoordinate { private long p_id; private String p_cate; private String p_name; private String p_image; public PlaceDtoCoordinate(Place place) { this.p_id = place.getId(); this.p_cate = place.getP_cate(); this.p_name = place.getP_name(); this.p_image = place.getP_image(); } } ... }
Service
package hackathon.nomadworker.service; import hackathon.nomadworker.domain.Place; import hackathon.nomadworker.repository.PlaceRepository; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import java.util.List; @Service @AllArgsConstructor public class PlaceService { private final PlaceRepository placeRepository; public List<Place> findPlacesByCategory(String place_tag) {return placeRepository.findPlacesByCategory(place_tag); } public List<Place> findPlacesByCoordinate(float latitude,float longitude) { // 반견 1km return placeRepository.getNearByCoordinate((double)latitude, (double)longitude,(double)1); } public List<Place> findPlacesall() { return placeRepository.findAll(); } }
API--
package hackathon.nomadworker.api; import hackathon.nomadworker.domain.Place; import hackathon.nomadworker.dto.PlaceDtos.*; import hackathon.nomadworker.service.PlaceService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.stream.Collectors; import java.util.List; @RestController @RequiredArgsConstructor public class PlaceApiController { private final PlaceService placeService; @GetMapping(value = "/api/place/near", produces = "application/json;charset=UTF-8") public PlaceResultResponse placeByCoordinateGet(@RequestHeader("Authorization") String u_uid, @RequestParam("latitude") float latitude, @RequestParam("longitude") float longitude) { List<Place> places = placeService.findPlacesByCoordinate(latitude,longitude); if (places.isEmpty()) { return new PlaceResultResponse("근처 장소 조회 실패", 400, null); } else { List<PlaceDtoCoordinate> collect = places.stream().map(place -> new PlaceDtoCoordinate(place)).collect(Collectors.toList()); return new PlaceResultResponse("근처 장소 조회 성공", 200, collect); } } }
결과.
(50.8 4.44) 을 넣었던 것이 근처 범위로 잘 나온다.
'Project > NomadWorker' 카테고리의 다른 글
Jsoup 웹 크롤링 , 스프링 부트 구글 지도 위도 경도 가져오기 (0) 2022.08.11