input('latitude'), longitude: (float) $request->input('longitude'), speed: $request->filled('speed') ? (float) $request->input('speed') : null, bearing: $request->filled('bearing') ? (float) $request->input('bearing') : null, accuracy: $request->filled('accuracy') ? (float) $request->input('accuracy') : null, altitude: $request->filled('altitude') ? (float) $request->input('altitude') : null, timestamp: $request->filled('timestamp') ? new \DateTime($request->input('timestamp')) : null, ); } /** * Create DTO from array. */ public static function fromArray(array $data): self { return new self( latitude: (float) ($data['latitude'] ?? $data['lat'] ?? 0), longitude: (float) ($data['longitude'] ?? $data['lng'] ?? 0), speed: isset($data['speed']) ? (float) $data['speed'] : null, bearing: isset($data['bearing']) ? (float) $data['bearing'] : null, accuracy: isset($data['accuracy']) ? (float) $data['accuracy'] : null, altitude: isset($data['altitude']) ? (float) $data['altitude'] : null, timestamp: isset($data['timestamp']) ? new \DateTime($data['timestamp']) : null, ); } /** * Convert to array. */ public function toArray(): array { return array_filter([ 'latitude' => $this->latitude, 'longitude' => $this->longitude, 'speed' => $this->speed, 'bearing' => $this->bearing, 'accuracy' => $this->accuracy, 'altitude' => $this->altitude, 'timestamp' => $this->timestamp?->format('Y-m-d H:i:s'), ], fn ($value) => $value !== null); } /** * Convert to Firebase format. */ public function toFirebaseFormat(): array { return [ 'lat' => $this->latitude, 'lng' => $this->longitude, 'speed' => $this->speed, 'bearing' => $this->bearing, 'accuracy' => $this->accuracy, 'timestamp' => ($this->timestamp ?? now())->getTimestamp() * 1000, // JavaScript timestamp ]; } /** * Check if location is valid. */ public function isValid(): bool { return $this->latitude >= -90 && $this->latitude <= 90 && $this->longitude >= -180 && $this->longitude <= 180; } /** * Check if accuracy is acceptable. */ public function hasAcceptableAccuracy(?float $threshold = null): bool { if ($this->accuracy === null) { return true; } $threshold = $threshold ?? config('restaurant-delivery.firebase.location.accuracy_threshold', 50); return $this->accuracy <= $threshold; } }