'boolean', 'allowed_radius' => 'integer', 'hq_latitude' => 'decimal:8', 'hq_longitude' => 'decimal:8', ]; protected $attributes = [ 'use_gps' => false, 'allowed_radius' => 100, ]; // ========================================================================= // 헬퍼 메서드 // ========================================================================= /** * GPS 설정 완료 여부 */ public function isGpsConfigured(): bool { return $this->use_gps && $this->hq_latitude !== null && $this->hq_longitude !== null; } /** * 좌표가 허용 범위 내인지 확인 */ public function isWithinRadius(float $latitude, float $longitude): bool { if (! $this->isGpsConfigured()) { return true; // GPS 미설정 시 항상 허용 } $distance = $this->calculateDistance( $this->hq_latitude, $this->hq_longitude, $latitude, $longitude ); return $distance <= $this->allowed_radius; } /** * 두 좌표 간 거리 계산 (미터) * Haversine 공식 사용 */ private function calculateDistance(float $lat1, float $lon1, float $lat2, float $lon2): float { $earthRadius = 6371000; // 지구 반경 (미터) $lat1Rad = deg2rad($lat1); $lat2Rad = deg2rad($lat2); $deltaLat = deg2rad($lat2 - $lat1); $deltaLon = deg2rad($lon2 - $lon1); $a = sin($deltaLat / 2) * sin($deltaLat / 2) + cos($lat1Rad) * cos($lat2Rad) * sin($deltaLon / 2) * sin($deltaLon / 2); $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); return $earthRadius * $c; } }