/**
  * Extracts a {@see \Beluga\GIS\Longitude} instance from defined string value and returns it by reference with the
  * $output parameter. The Method returns TRUE on success, FALSE otherwise.
  *
  * @param string                   $str    The string that should be parsed.
  * @param \Beluga\GIS\Longitude|null &$output Returns the resulting Longitude reference, if the method returns TRUE
  * @return boolean
  */
 public static function TryParseString(string $str, &$output) : bool
 {
     if (!\is_string($str)) {
         return false;
     }
     if (TypeTool::IsDecimal($str, true)) {
         # 40.446195 oder -79.948862
         $data = AbstractElement::_DecToDDMS(\doubleval(\str_replace(',', '.', $str)), true);
         try {
             $output = new Longitude($data['DIR'], $data['DEG'], $data['MIN'], $data['SEC']);
         } catch (\Throwable $ex) {
             return false;
         }
         return true;
     }
     $str = \preg_replace('~(\\s+deg)~i', '°', $str);
     $dir = null;
     $deg = null;
     $min = null;
     $sec = null;
     if (\preg_match('~^([NS])(.+)$~i', $str, $m)) {
         $dir = $m[1];
         $str = \trim($m[2]);
     } else {
         if (\preg_match('~^(.+)([NS])$~i', $str, $m)) {
             $dir = $m[2];
             $str = \trim($m[1]);
         } else {
             if (\preg_match('~^(-?)\\d+°~', $str, $m)) {
                 if (isset($m[1]) && $m[1] == '-') {
                     $dir = 'S';
                     $str = \substr($str, 1);
                 } else {
                     $dir = 'N';
                 }
             } else {
                 return false;
             }
         }
     }
     if (\preg_match('~^(\\d{1,3})[°d:]\\s*(\\d{1,2})[:\'](.+)$~', \trim($str), $m)) {
         try {
             $output = new Longitude($dir, \trim($m[1]), \trim($m[2]), \rtrim(\trim($m[3]), '"'));
         } catch (\Throwable $ex) {
             return false;
         }
         return true;
     }
     if (TypeTool::IsDecimal($str, true)) {
         $data = AbstractElement::_DecToDDMS(\doubleval(\str_replace(',', '.', $str)), true);
         try {
             $output = new Longitude($data['DIR'], $data['DEG'], $data['MIN'], $data['SEC']);
         } catch (\Throwable $ex) {
             return false;
         }
         return true;
     }
     if (\preg_match('~^(\\d{1,3})°\\s+([\\d.]+)\'?$~', \trim($str), $m)) {
         try {
             $output = new Longitude($dir, \trim($m[1]), \doubleval(\str_replace(',', '.', \trim($m[2]))));
         } catch (\Throwable $ex) {
             return false;
         }
         return true;
     }
     if (\preg_match('~^(\\d{1,3})°\\s+([\\d.]+)"\\s+([\\d.]+)\'?$~', \trim($str), $m)) {
         try {
             $output = new Longitude($dir, \trim($m[1]), \doubleval(\str_replace(',', '.', \trim($m[2]))), \doubleval(\str_replace(',', '.', \trim($m[3]))));
         } catch (\Throwable $ex) {
             return false;
         }
         return true;
     }
     return false;
 }
 /**
  * Extracts a {@see \Beluga\GIS\Coordinate} instance from defined string value and returns it by reference with the
  * $output parameter. The Method returns TRUE on success, FALSE otherwise.
  *
  * @param  string  $str The string to parse
  * @param  \Beluga\GIS\Coordinate|null &$output Returns the resulting Coordinate reference, if the method returns TRUE
  * @return boolean
  */
 public static function TryParseString(string $str, &$output) : bool
 {
     if (empty($str)) {
         return false;
     }
     if (false !== ($res = Converter::ParseUtm2LL(Ellipsoid::TYPE_WGS_84, $str))) {
         # UTM: 10T E 549142 N 5280803
         try {
             $output = new Coordinate($res['Latitude'], $res['Longitude']);
         } catch (\Throwable $ex) {
             return false;
         }
         return true;
     }
     $laStr = null;
     $loStr = null;
     $tmp = \explode(', ', $str);
     if (\count($tmp) == 2) {
         $tmp[0] = \trim($tmp[0]);
         $tmp[1] = \trim($tmp[1]);
         if (\preg_match('~^([NS].+|.+[NS])$~', $tmp[0])) {
             try {
                 $output = new Coordinate($tmp[0], \trim($tmp[1]));
             } catch (\Throwable $ex) {
                 return false;
             }
             return true;
         }
         if (\preg_match('~^([EW].+|.+[EW])$~', $tmp[0])) {
             try {
                 $output = new Coordinate(\trim($tmp[1]), $tmp[0]);
             } catch (\Throwable $ex) {
                 return false;
             }
             if (!$output->isValid()) {
                 $output = null;
                 return false;
             }
             return true;
         } else {
             $loStr = \trim($tmp[1]);
             if (TypeTool::IsDecimal($loStr)) {
                 # 40.446195, -79.948862
                 try {
                     $output = new Coordinate(\trim(\rtrim($tmp[0], ' ,')), $loStr);
                 } catch (\Throwable $ex) {
                     return false;
                 }
                 if (!$output->isValid()) {
                     $output = null;
                     return false;
                 }
                 return true;
             }
         }
     }
     $tmp = \explode(' ', $str);
     if (\count($tmp) == 2) {
         if (\preg_match('~^([NS].+|.+[NS])$~', $tmp[0])) {
             try {
                 $output = new Coordinate($tmp[0], \trim($tmp[1]));
             } catch (\Throwable $ex) {
                 return false;
             }
             if (!$output->isValid()) {
                 $output = null;
                 return false;
             }
             return true;
         }
         if (\preg_match('~^([EW].+|.+[EW])$~', $tmp[0])) {
             try {
                 $output = new Coordinate(\trim($tmp[1]), $tmp[0]);
             } catch (\Throwable $ex) {
                 return false;
             }
             if (!$output->isValid()) {
                 $output = null;
                 return false;
             }
             return true;
         } else {
             $loStr = \trim($tmp[1]);
             if (TypeTool::IsDecimal($loStr)) {
                 # 40.446195, -79.948862
                 try {
                     $output = new Coordinate(\trim(\rtrim($tmp[0], ' ,')), $loStr);
                 } catch (\Throwable $ex) {
                     return false;
                 }
                 if (!$output->isValid()) {
                     $output = null;
                     return false;
                 }
                 return true;
             }
         }
         return false;
     }
     $tmp[0] = \strtoupper($tmp[0]);
     $tc = \count($tmp);
     $max = $tc - 1;
     if (\preg_match('~^[NSEW]$~', $tmp[0])) {
         switch ($tmp[0]) {
             case 'N':
             case 'S':
                 self::normalizeForNS($laStr, $loStr, $tc, $max, $tmp);
                 try {
                     $output = new Coordinate($laStr, $loStr);
                 } catch (\Throwable $ex) {
                     return false;
                 }
                 if (!$output->isValid()) {
                     $output = null;
                     return false;
                 }
                 return true;
             default:
                 $loStr = $tmp[0];
                 $i = 1;
                 $nc = \trim($tmp[$i]);
                 while ($i < $tc && !\preg_match('~^[NS]$~', $nc)) {
                     $loStr .= " {$nc}";
                     ++$i;
                     $nc = \trim($tmp[$i]);
                 }
                 ++$i;
                 if ($i >= $max) {
                     return false;
                 }
                 $laStr = $nc;
                 $laStr .= ' ' . \join(' ', \array_slice($tmp, $i));
                 try {
                     $output = new Coordinate($laStr, $loStr);
                 } catch (\Throwable $ex) {
                     return false;
                 }
                 if (!$output->isValid()) {
                     $output = null;
                     return false;
                 }
                 return true;
         }
     }
     if (\preg_match('~^[NSEW]$~', $tmp[$max])) {
         switch ($tmp[$max]) {
             case 'N':
             case 'S':
                 $laStr = $tmp[$max];
                 $i = $max - 1;
                 $nc = \trim($tmp[$i]);
                 while ($i >= 0 && !\preg_match('~^[EW]$~', $nc)) {
                     $laStr .= "{$nc} {$laStr}";
                     --$i;
                     $nc = \trim($tmp[$i]);
                 }
                 --$i;
                 if ($i <= 0) {
                     return false;
                 }
                 $loStr = $nc;
                 $loStr = \join(' ', \array_slice($tmp, 0, $i + 1)) . ' ' . $loStr;
                 try {
                     $output = new Coordinate($laStr, $loStr);
                 } catch (\Throwable $ex) {
                     return false;
                 }
                 if (!$output->isValid()) {
                     $output = null;
                     return false;
                 }
                 return true;
             default:
                 $loStr = $tmp[$max];
                 $i = $max - 1;
                 $nc = \trim($tmp[$i]);
                 while ($i >= 0 && !\preg_match('~^[NS]$~', $nc)) {
                     $loStr .= "{$nc} {$loStr}";
                     --$i;
                     $nc = \trim($tmp[$i]);
                 }
                 --$i;
                 if ($i <= 0) {
                     return false;
                 }
                 $laStr = $nc;
                 $laStr = \join(' ', \array_slice($tmp, 0, $i + 1)) . ' ' . $laStr;
                 try {
                     $output = new Coordinate($laStr, $loStr);
                 } catch (\Throwable $ex) {
                     return false;
                 }
                 if (!$output->isValid()) {
                     $output = null;
                     return false;
                 }
                 return true;
         }
     }
     if ($tc != 4) {
         return false;
     }
     $tmp[0] = \preg_replace('~[^\\d-]~', '', $tmp[0]);
     $tmp[1] = \preg_replace('~[^\\d.]~', '', $tmp[1]);
     $tmp[2] = \preg_replace('~[^\\d-]~', '', $tmp[2]);
     $tmp[3] = \preg_replace('~[^\\d.]~', '', $tmp[3]);
     # 40° 26.7717, -79° 56.93172
     $direction = null;
     if ($tmp[0][0] == '-') {
         $direction = 'S';
         $tmp[0] = \substr($tmp[0], 1);
     } else {
         $direction = 'N';
     }
     $latElement = null;
     try {
         $latElement = new Latitude($direction, \intval($tmp[0]), \doubleval($tmp[1]));
     } catch (\Throwable $ex) {
         return false;
     }
     if ($tmp[2][0] == '-') {
         $direction = 'W';
         $tmp[2] = \substr($tmp[2], 1);
     } else {
         $direction = 'E';
     }
     $lonElement = null;
     try {
         $lonElement = new Longitude($direction, \intval($tmp[2]), \doubleval($tmp[3]));
     } catch (\Throwable $ex) {
         return false;
     }
     $output = new Coordinate($latElement, $lonElement);
     if (!$output->isValid()) {
         $output = null;
         return false;
     }
     return true;
 }