2024-04-13 - 거리 표시하기 및 검색창 다시 구현

·2024년 4월 14일

프로젝트

목록 보기
48/57

개인프로젝트 남은 TODOs

  1. 검색결과 없을 경우에 대한 처리
  2. 조건별 추천검색어에서 '카페'라는 단어가 포함되어있다면 파싱하여 제외시켜 검색시키기
  3. 카페 찜버튼 에러
  4. 관리자에게 이메일 전송

cafeDetail 페이지에서 거리 표시하기

지도api에서 카페의 위도와 경도를 변수에 담아 ajax로 요청을 보내 거리를 표시하려고만 하면 NullPointerException이 뜨고 ajax가 success가 아닌 error로 떴다.

구조를 변경하기로 함

AS-IS

  • 수정전
    searchList.jsp > detail click > c.showcafeDetail?id='24' > cafeDetail.jsp > showLatLon > c.showcafeDetail?id='24' > cafeDetail.jsp
	$.ajax({
 	    type: "POST",
 	    url: "/usr/findcafe/cafeDetail", // 요청을 처리할 컨트롤러의 URL
 	   // contentType: "application/json",
 	    data: JSON.stringify({
 	    	lat: lat2, // 위도
 		    lon: lon2  // 경도
 	    }),
 	    dataType: 'json',
 	    success: function(response) {
 	        alert("위도와 경도를 서버로 전송했습니다.");
 	        // 성공적으로 처리되었을 때 실행할 코드
 	    },
 	    error: function(xhr, status, error) {
 	        alert(JSON.stringify(lat2 )); 
 	        // 오류 발생 시 실행할 코드
 	    }
 	});

TO-BE

  • 수정 후
    searchList.jsp > detail click > c.showcafeDetail?id='24' > cafeDetail.jsp > showLatLon >
    c.distance > showLatLon.success > ?? km 표시
		function showLatLon(lat2, lon2) {
			var myLat, myLon;
			// 크롬브라우저 전용 사용자의 위도와 경도를 불러오는 함수
			navigator.geolocation.getCurrentPosition(function(position) {
	            myLat = position.coords.latitude;
	            myLon = position.coords.longitude;	
	            $.ajax({
			        type: "POST",
			        url: "/usr/findcafe/distance", // 요청을 처리할 컨트롤러의 URL
			        contentType: "application/json", // id도 넘겨줘........ 
			        data: JSON.stringify({
			        	'myLat': myLat,
			        	'myLon': myLon,
			        	'cafeLat': lat2,
			        	'cafeLon': lon2
			        }),
			        //dataType: 'json',
			        success: function(distanceInKm) {
			            //alert("위도와 경도를 서버로 전송했습니다.\n * distanceInKm_Response : " + distanceInKm);
			            // 성공적으로 처리되었을 때 실행할 코드
			            $('.distance-num').text(distanceInKm+"km");
			        },
			        error: function(xhr, status, error) {
			            alert("에러면 표시 " + JSON.stringify(lat2));
			            // 오류 발생 시 실행할 코드
			            //JSON.stringify(lat2)
			        }
			    });
			});
		}
//컨트롤러
@ResponseBody
	@RequestMapping("/usr/findcafe/distance")
	public String distance(@RequestBody Map<String, Double> requestMap) {
		// 학원 위도경도
		Double myLat = requestMap.get("myLat");
		Double myLon = requestMap.get("myLon");
		Double cafeLat = requestMap.get("cafeLat");
		Double cafeLon = requestMap.get("cafeLon");
		double theta = myLon - cafeLon;
		double dist = Math.sin(deg2rad(myLat)) * Math.sin(deg2rad(cafeLat))
				+ Math.cos(deg2rad(myLat)) * Math.cos(deg2rad(cafeLat)) * Math.cos(deg2rad(theta));
		dist = Math.acos(dist);
		dist = rad2deg(dist);
		dist = dist * 60 * 1.1515 * 1609.344;

		String distanceInKm = String.format("%.1f", dist / 1000);

		System.out.println(distanceInKm + "km");

		return distanceInKm; // 단위 kilometer
	}
  • cafeDetail 메서드 안에서 showLatLon ajax를 호출 하고 있었고 ajax에서는 cafeDetail url을 또 호출 하고 있다보니, cafeDetail로 접속 시 페이지가 두번 로드 되는 문제가 발생

  • cafeDetail로 접속 시 showLatLon ajax가 distance메서드로 요청을 보내게끔 변경

  • 위도와 경도를 ajax로부터 받아서 거리를 계산하고 정제하는 모든 행위를 distance메서드에서 처리하게끔 변경

  • ajax로 부터 위도 경도가 변수로 잘 넘어와도 404와 415에러가 떠서 ajax코드 내에서 content type 추가, 데이터는 stringfy, 컨트롤러에서는 distance메서드에 @ResponseBody추가 및 파라미터에 @RequestBody를 추가함으로써 ajax와 컨트롤러간의 통신문제 해결 및 거리 표시 구현 완료

  • 여기까지는 사용자의 위도와 경도는 하드코딩으로 처리했으나,
    사용자의 위도와 경도를 구글크롬에서 가져와서 처리 하기 위해 아래의 메서드를 사용함

// 크롬브라우저 전용 사용자의 위도와 경도를 불러오는 함수
navigator.geolocation.getCurrentPosition(function(position) {
	            myLat = position.coords.latitude;
	            myLon = position.coords.longitude;

대전시청의 위도와 경도를 설정해놓았고, 대전시청에서부터 카페까지의 거리가 표시된다!
36.350392
127.384593

크롬에서 위치정보 수집을 허용을 해야 거리가 제대로 구현이 된다!

크롬 설정 -> 개인 정보 보호 및 보안 -> 사이트설정 -> 위치

참고)크롬 - 위치 정보요청 허용하는 방법
참고) 구글 - 사용자의 위치 변경하기

검색창 에러 해결

카페의 검색기능이 filter 다중선택 구현을 하면서 array로 받을 수 있게 처리해놓았었는데,
검색창에서는 검생키워드가 array가 아닌 string값으로 1개의 키워드를 ㅌ태워 보내기 때문에
검색창으로 키워드 검색이 되지 않았던 것!

구현 방법은 2가지가 있음.
1. 컨트롤러 filterCafes 메서드에서 keyword를 String or Array 조건문

  1. jsp -> function loadFilteredCafes(selectedKeywords, currentPage)에서
    selectedKeywords가 String 일때 Array로 변경(형변환)해서 무조건 배열처리하여 ajax 호출하는 방법

결과적으로 1번방법으로 구현

array로 키워드가 들어올때와 string으로 들어올때를 조건문으로 해결

// 키워드 선택 안했을 시 빈값이 String으로 들어와서 String(빈값) 여부 판단 후
		if (selectedKeywordsObject instanceof String == true) { 	
			// 검색창을 통한 키워드 검색 또는 빈값(카페찾기 page 바로 접근 시) 용도
			// 빈값인 경우 전체카페 리스트 보여줌
			String keyword = selectedKeywordsObject.toString();
			
			if(!"".equals(keyword)) {
				selectedKeywords.add(keyword);
			}
			
		} else {
			// 필터 전용
			selectedKeywords = (List<String>) selectedKeywordsObject;
		}
profile
hello world

0개의 댓글