/*
   ===========================================================================
   This function converts rectangular XYZ coordinates into
   corresponding spherical coordinates Lat, Lon.

   x = R * cos(Lon) * cos(Lat)
   y = R * sin(Lon) * cos(Lat)
   z = R * sin(Lat)

   Lon = Arctan(y/x)
   Lat = Arctan(z / sqrt(x^2 + y^2))
     R = sqrt(x^2 + y^2 + z^2)

   ERRORS:
   FALSE is returned if argument is non-numeric.

   NO DEPENDENCIES
   ===========================================================================
*/
   function XYZ_to_Lat_Lon_R ($xyzStr, $Decimals=16)
{
// Read signed XYZ coord strings ('x.xxx y.yyy z.zzz') format and
// normalize (single) spacing between elements, if necessary.
   $w = trim($xyzStr);
   $w = Str_Replace(',', ' ', $w);
   $w = Str_Replace(';', ' ', $w);
   $w = Str_Replace('|', ' ', $w);

// Normalize (single) spacing of ('x y z') coords.
   $xyz = PReg_Replace("/\s+/", " ", trim($w));

// Return error message if any non-numeric arguments.
   if (Is_Numeric("$xyz " . trim($Decimals)))
  {return "ERROR: XYZ_to_Lat_Lon_R()\n\nAll arguments must be numeric.";}

// Return error message if not 6 numerical elements.
// There must be 3 matching XYZ-coordinates in
// 'x.xxx  y.yyy  z.zzz' format.
   if (substr_count($xyz, ' ') < 2)
  {return "ERROR: XYZ_to_Lat_Lon_R()\n\nRequires 2 or 3 arguments.";}

// Parse individual XYZ values.
   list($x, $y, $z) = PReg_Split("[ ]", $xyz);

// Compute spherical coords in degrees
// and the spherical radius.
   $Lon = Rad2Deg(atan2($y, $x));
   $Lat = Rad2Deg(atan($z / sqrt($x*$x + $y*$y)));
   $R   = sqrt($x*$x + $y*$y + $z*$z);

// Format and return computations output.
   $Lat = SPrintF("%+1.12f", $Lat); //  +11.123456789012
   $Lon = SPrintF("%+1.12f", $Lon); // -111.123456789012
   $R   = SPrintF("%1.12f", $R);

   return "$Lat $Lon $R";

} // End of  XYZ_to_Lat_Lon_R (...)