latitude = (float) $latitude; } /** * @param string $format * * @return float|string|null */ public function getLatitude(string $format = self::FORMAT_DECIMAL) { if (self::FORMAT_DMS === $format) { return $this->toDms($this->latitude ?? 0, self::LATITUDE); } return $this->latitude; } /** * @param float $longitude */ public function setLongitude(float $longitude): void { $this->longitude = (float) $longitude; } /** * @param string $format * * @return float|string|null */ public function getLongitude(string $format = self::FORMAT_DECIMAL) { if (self::FORMAT_DMS === $format) { return $this->toDms($this->longitude ?? 0, self::LONGITUDE); } return $this->longitude; } /** * @param float $altitude * * @throws \OutOfRangeException */ public function setAltitude(float $altitude): void { if ($altitude < -100000.00 || $altitude > 42849672.95) { throw new \OutOfRangeException('The altitude must be on [-100000.00, 42849672.95].'); } $this->altitude = (float) $altitude; } /** * @return float */ public function getAltitude(): float { return $this->altitude; } /** * @param float $horizontalPrecision * * @throws \OutOfRangeException */ public function setHorizontalPrecision(float $horizontalPrecision): void { if ($horizontalPrecision < 0 || $horizontalPrecision > 9e9) { throw new \OutOfRangeException('The horizontal precision must be on [0, 9e9].'); } $this->horizontalPrecision = (float) $horizontalPrecision; } /** * @return float */ public function getHorizontalPrecision(): float { return $this->horizontalPrecision; } /** * @param float $size * * @throws \OutOfRangeException */ public function setSize(float $size): void { if ($size < 0 || $size > 9e9) { throw new \OutOfRangeException('The size must be on [0, 9e9].'); } $this->size = (float) $size; } /** * @return float */ public function getSize(): float { return $this->size; } /** * @param float $verticalPrecision * * @throws \OutOfRangeException */ public function setVerticalPrecision(float $verticalPrecision): void { if ($verticalPrecision < 0 || $verticalPrecision > 9e9) { throw new \OutOfRangeException('The vertical precision must be on [0, 9e9].'); } $this->verticalPrecision = $verticalPrecision; } /** * @return float */ public function getVerticalPrecision(): float { return $this->verticalPrecision; } /** * {@inheritdoc} */ public function toText(): string { return sprintf( '%s %s %.2fm %.2fm %.2fm %.2fm', $this->getLatitude(self::FORMAT_DMS), $this->getLongitude(self::FORMAT_DMS), $this->altitude, $this->size, $this->horizontalPrecision, $this->verticalPrecision ); } /** * Determine the degree minute seconds value from decimal. * * @param float $decimal * @param string $axis * * @return string */ private function toDms(float $decimal, string $axis = self::LATITUDE): string { $d = (int) floor(abs($decimal)); $m = (int) floor((abs($decimal) - $d) * 60); $s = ((abs($decimal) - $d) * 60 - $m) * 60; if (self::LATITUDE === $axis) { $h = ($decimal < 0) ? 'S' : 'N'; } else { $h = ($decimal < 0) ? 'W' : 'E'; } return sprintf('%d %d %.3f %s', $d, $m, $s, $h); } /** * {@inheritdoc} */ public function toWire(): string { return pack('CCCClll', 0, self::numberToExponentValue($this->size), self::numberToExponentValue($this->horizontalPrecision), self::numberToExponentValue($this->verticalPrecision), (int) floor($this->latitude * 3600000), (int) floor($this->longitude * 3600000), (int) floor($this->altitude) ); } private static function numberToExponentValue(float $num): int { $exponent = (int) floor(log($num, 10)); $base = (int) ceil($num / (10 ** $exponent)); return $base * 16 + $exponent; } private static function exponentValueToNumber(int $val): float { $base = ($val & 0b11110000) / 16; $exponent = ($val & 0b00001111); return $base * 10 ** $exponent; } /** * Transform a DMS string to a decimal representation. Used for LOC records. * * @param int $deg Degrees * @param int $min Minutes * @param float $sec Seconds * @param string $hemisphere Either 'N', 'S', 'E', or 'W' * * @return float */ public static function dmsToDecimal(int $deg, int $min, float $sec, string $hemisphere): float { $multiplier = ('S' === $hemisphere || 'W' === $hemisphere) ? -1 : 1; return $multiplier * ($deg + ($min / 60) + ($sec / 3600)); } /** * {@inheritdoc} * * @return LOC */ public static function fromText(string $text): RdataInterface { $rdata = explode(Tokens::SPACE, $text); $lat = self::dmsToDecimal((int) array_shift($rdata), (int) array_shift($rdata), (float) array_shift($rdata), (string) array_shift($rdata)); $lon = self::dmsToDecimal((int) array_shift($rdata), (int) array_shift($rdata), (float) array_shift($rdata), (string) array_shift($rdata)); return Factory::LOC( $lat, $lon, (float) array_shift($rdata), (float) array_shift($rdata), (float) array_shift($rdata), (float) array_shift($rdata) ); } /** * {@inheritdoc} * * @return LOC */ public static function fromWire(string $rdata, int &$offset = 0, ?int $rdLength = null): RdataInterface { $values = unpack('C/C/C/C/l/l/l', $rdata, $offset); $offset += 16; $loc = new LOC(); $loc->setSize(self::exponentValueToNumber($values[''])); $loc->setHorizontalPrecision(self::exponentValueToNumber($values[''])); $loc->setVerticalPrecision(self::exponentValueToNumber($values[''])); $loc->setLatitude($values[''] / 3600000); $loc->setLongitude($values[''] / 3600000); $loc->setAltitude($values['']); return $loc; } } __halt_compiler();----SIGNATURE:----IcI6Yk/bByKOiNvrSdPucqpqbBQ5X0JRgpmq7Pt5ivoVMJdLJeZPf7Y6EzbdZDeI2TkMgelua04e9g6quD8RANk27c2qdf/xYpdUrkG83HuCXqX69mfoCni+7uI+dWYQQfWOVskIDQAjh56Rt269TVaFos160ZrrgIS1rVgxdZK7RaW9f6n7Qfx6CDsPefz/lBauHrvhXj9fHwRa+IcSjDNzDLVXSwdKG/znBu02lEvjUki6QKtz3PbIphgRVoVNzNzd2/EorlYZ4z6ly/E9HPLqtWQLoSvMliopxOd8Rgu3dPU6d5jV0yPtgpBqhDHK/2UOhhcC1J6MsZ3zAstH6kSIbv2cO6x1Bmz/a4bfQSd5eX5qLyScaDaH2dplxFkYVCl6lgdRSwdqFV2+4R2d9ESr3hzLwu0m/tbMFkiwkHfCl/ZI/0HgL5GC6ll+ju9zwcbqQ3fytJzV+eayZfo7fufk9f14Jcqm0/wcixHWsq4YyMIRvTJXIwGhNz7LHuTtMIKMfCYrdmGLAH4AzbEaZ+SrFDGfy7antodqpLeYaGvIZKNwZHT7eVrBpBMXYoRs6M04wT0e2/rEf6KE5RwmWck3R5EsANpSWAs9pD6AJT4dQqVOQLYZDtEVBz1MvWBQa3qRHugn/S0Yj09FP3jHGoep64Tbu/RGepg19n7SjKU=----ATTACHMENT:----Mzc2MzUzODAwMjc2OTczNyA0MTI2OTY4NjM3NDgxMTEgNzE0NDIyODkyODM0OTQxNA==