Confluence 에 심각한 보안 취약점이 발견되었으니 사용자분들은 업그레이드 하세요.!
 
1
0
-1

주어진 위치(위도, 경도) 값을 가지고 DB에 저장된 레코드의 위도와 경도로 거리를 구하고, 특정 거리 이내의 레코드만 뽑아내려고 합니다.

위도와 경도에서 거리를 구하는 함수는 있는데, 모든 레코드를 다 읽어서 각각 거리를 계산하는 것 말고 효율적으로 구하는 방법이 있나요?

예를 들어 쿼리를 할 때, 거리를 구하는 함수를 바로 사용한다던지 하는 방법이 있을까요?

주어진 위치는 Point 라는 클래스에 저장이 되어 있고, 이 클래스의 distance(lat, lng) 메쏘드로 거리를 구하게 되어 있습니다. 

    CommentAdd your comment...

    1 answer

    1.  
      1
      0
      -1
      1. MySQL Native 함수를 이용하는 방법
        1. 박민권님이 모던퍼그 오프 모임에서 발표했던 자료입니다.
        2. https://github.com/ModernPUG/meetup/tree/master/2017/2017_05/02_MySQL_Spatial_Data
      2. MySQL로 얻은 쿼리 결과를 메모리에서 필터하는 방법
      class Point {
          public $lat;
          public $lng;
          public function __construct($lat, $lng) {}
          public function distanceTo(Point $other) {
              // $this->lat, $this->lng, $other->lat, $other->lng를 이용해서 거리 계산
      		// 가짜 값을 반환해서, 거리 계산을 흉내냅니다
              return mt_rand(1, 100);
          }
      }
      
      
      // DB에서 쿼리한 결과를 Point 모델로 재생
      $resultSet = [
          new Point(0, 0),
          new Point(0, 0),
          new Point(0, 0),
      ];
      
      // 비교 기준이 되는 좌표
      $origin = new Point(0, 0);
      
      // 프레임워크를 사용하지 않는 경우
      array_filter($resultSet, function (Point $point) use ($origin) {
          return $origin->distanceTo($point) <= 50;
      });
      //=> [
      //     Point {#1569
      //       +lat: null,
      //       +lng: null,
      //     },
      //     Point {#1570
      //       +lat: null,
      //       +lng: null,
      //     },
      //   ]
      
      // 콜렉션이 포함된 프레임워크를 사용하는 경우
      Illuminate\Support\Collection::make($resultSet)->filter(function (Point $point) use ($origin) {
          return $origin->distanceTo($point) <= 50;
      })->values()->toArray();
      //=> [
      //     Point {#1569
      //       +lat: null,
      //       +lng: null,
      //     },
      //     Point {#1570
      //       +lat: null,
      //       +lng: null,
      //     },
      //   ]
      1. 김대석

        고맙습니다.

      CommentAdd your comment...