본문 바로가기
Develop

지도 검색 알고리즘

by 너드나무 2022. 5. 9.
728x90

들어가며...

모바일에서 전달하는 검색어, 위도, 경도 데이터를 이용하여 데이터베이스에 적재된 데이터를 Map에 표시하기 위한 결과 리스트 처리를 개발해본다.

준비사항

  1. 위도(float)
  2. 경도(float)
  3. 검색어(str)

필요 사항 정리

  1. 위도 경도 값을 활용한 거리 계산 및 정렬 방법
    1. business_latitude(float) 위도
    2. business_longtitude(float) 경도
    3. 위도 경도 거리 계산 공식 활용

지리좌표 거리 - 위키백과, 우리 모두의 백과사전 (wikipedia.org)

X = ( cos( 위도#1 ) * 6371 * 2 * 3.14 / 360 ) * | 경도#1 - 경도#2 |

Y = 111 * | 위도#1 - 위도#2 |

D = √ ( X² + Y² )

MySQL 검증 (거리 계산)

SELECT 
	business_idx, business_name, business_latitude, business_longtitude, business_address,
	(6371*acos(
		cos(radians(business_latitude))*cos(radians(37.59714945704228))*
			cos(radians(127.05584458104205)-radians(business_longtitude))
			+sin(radians(business_latitude))*sin(radians(37.59714945704228))))
	AS distance
FROM business
HAVING distance <= 5 -- 일정 거리 이내 조건부
ORDER BY distance;

 

Python 검증 (거리 계산)

statement = select(
    Business.business_idx,
    Business.business_name,
    Business.business_number,
    Business.business_latitude,
    Business.business_longtitude,
    Business.business_address,
    (6371*func.acos(
        func.cos(func.radians(Business.business_latitude))*
        func.cos(func.radians(c.customer_latitude))*
            func.cos(func.radians(c.customer_longtitude)-
                func.radians(Business.business_longtitude))+
            func.sin(
                func.radians(Business.business_latitude))*
            func.sin(func.radians(c.customer_latitude)
            )
        )).label('distance')
    ).order_by(
    'distance'
)

MySQL 검증 (검색어 필터링)

-- LIKE 연산자를 활용한 검색어 처리
SELECT 
	business_idx, business_name, business_latitude, business_longtitude, business_address,
	(6371*acos(
		cos(radians(business_latitude))*cos(radians(37.59714945704228))*
			cos(radians(127.05584458104205)-radians(business_longtitude))
			+sin(radians(business_latitude))*sin(radians(37.59714945704228))))
	AS distance
FROM business
WHERE business_name LIKE '%검색어%' OR business_address LIKE '%검색어%';

Python 검증 (검색어 필터링)

statement = select(
        BusinessAlert.business_idx,
    ).where(
        BusinessAlert.business_idx == b['business_idx'],
        or_(BusinessAlert.alert_title.like(f'%{c.customer_search}%'),
            BusinessAlert.alert_board.like(f'%{c.customer_search}%')
    )
)
728x90
반응형