public function parse($remaining_taf, $cavok = false)
 {
     $result = $this->consume($remaining_taf);
     $found = $result['found'];
     $new_remaining_taf = $result['remaining'];
     // handle the case where nothing has been found and taf is not cavok
     if ($found == null && !$cavok) {
         throw new ChunkDecoderException($remaining_taf, $new_remaining_taf, 'Bad format for clouds information', $this);
     }
     // default case: CAVOK or clear sky, no cloud layer
     $result = array('clouds' => array());
     // there are clouds, handle cloud layers and visibility
     if ($found != null && $found[2] == null) {
         for ($i = 3; $i <= 15; $i += 4) {
             if (trim($found[$i]) != null) {
                 $layer = new CloudLayer();
                 $layer_height = Value::toInt($found[$i + 2]);
                 if ($layer_height !== null) {
                     $layer_height_ft = $layer_height * 100;
                 } else {
                     $layer_height_ft = null;
                 }
                 $layer->setAmount($found[$i + 1])->setBaseHeight(Value::newValue($layer_height_ft, Value::FEET))->setType($found[$i + 3]);
                 $result['clouds'][] = $layer;
             }
         }
     }
     // return result + remaining taf
     return array('result' => $result, 'remaining_taf' => $new_remaining_taf);
 }
 public function parse($remaining_taf, $cavok = false)
 {
     $result = $this->consume($remaining_taf);
     $found = $result['found'];
     $new_remaining_taf = $result['remaining'];
     // temperatures are so often missing from forecasts we consider them as optional
     $max_temp = null;
     $min_temp = null;
     if ($found != null && trim($found[2]) != null && trim($found[6]) != null) {
         // retrieve found params
         $max_temp = new Temperature();
         $max_temp->setType($found[1]);
         $max_temp->setTemperature(Value::newIntValue($found[2], Value::DEGREE_CELSIUS));
         $max_temp->setDay(intval($found[3]));
         $max_temp->setHour(intval($found[4]));
         $min_temp = null;
         if (trim($found[5]) != null) {
             $min_temp = new Temperature();
             $min_temp->setType($found[5]);
             $min_temp->setTemperature(Value::newIntValue($found[6], Value::DEGREE_CELSIUS));
             $min_temp->setDay(intval($found[7]));
             $min_temp->setHour(intval($found[8]));
         }
         // handle the case where min and max temperatures are inconsistent
         if ($min_temp->getTemperature()->getValue() > $max_temp->getTemperature()->getValue()) {
             throw new ChunkDecoderException($remaining_taf, $new_remaining_taf, 'Inconsistent values for temperature information', $this);
         }
     }
     $result = array('maxTemperature' => $max_temp, 'minTemperature' => $min_temp);
     // return result + remaining taf
     return array('result' => $result, 'remaining_taf' => $new_remaining_taf);
 }
 public function parse($remaining_taf, $cavok = false)
 {
     $result = $this->consume($remaining_taf);
     $found = $result['found'];
     $new_remaining_taf = $result['remaining'];
     // handle the case where nothing has been found
     if ($found == null) {
         throw new ChunkDecoderException($remaining_taf, $new_remaining_taf, 'Bad format for surface wind information', $this);
     }
     // handle the case where nothing is observed
     if ($found[1] == '///' && $found[2] == '//') {
         throw new ChunkDecoderException($remaining_taf, $new_remaining_taf, 'No information measured for surface wind', $this);
     }
     // get unit used
     switch ($found[5]) {
         case "KT":
             $speed_unit = Value::KNOT;
             break;
         case "KPH":
             $speed_unit = Value::KILOMETER_PER_HOUR;
             break;
         case "MPS":
             $speed_unit = Value::METER_PER_SECOND;
             break;
     }
     // retrieve and validate found params
     $surface_wind = new SurfaceWind();
     // mean speed
     $surface_wind->setMeanSpeed(Value::newIntValue($found[2], $speed_unit));
     // mean direction
     if ($found[1] == 'VRB') {
         $surface_wind->setVariableDirection(true);
         $surface_wind->setMeanDirection(null);
     } else {
         $mean_dir = Value::newIntValue($found[1], Value::DEGREE);
         if ($mean_dir->getValue() < 0 || $mean_dir->getValue() > 360) {
             throw new ChunkDecoderException($remaining_taf, $new_remaining_taf, 'Wind direction should be in [0,360]', $this);
         }
         $surface_wind->setVariableDirection(false);
         $surface_wind->setMeanDirection($mean_dir);
     }
     // direction variations
     if (strlen($found[7]) > 0) {
         $min_dir_var = Value::newIntValue($found[7], Value::DEGREE);
         $max_dir_var = Value::newIntValue($found[8], Value::DEGREE);
         if ($min_dir_var->getValue() < 0 || $min_dir_var->getValue() > 360 || $max_dir_var->getValue() < 0 || $max_dir_var->getValue() > 360) {
             throw new ChunkDecoderException($remaining_taf, $new_remaining_taf, 'Wind direction variations should be in [0,360]', $this);
         }
         $surface_wind->setDirectionVariations($min_dir_var, $max_dir_var);
     }
     // speed variations
     if (strlen($found[4]) > 0) {
         $surface_wind->setSpeedVariations(Value::newIntValue($found[4], $speed_unit));
     }
     // return result + remaining metar
     return array('result' => array('surfaceWind' => $surface_wind), 'remaining_taf' => $new_remaining_taf);
 }
 public function parse($remaining_taf, $cavok = false)
 {
     $result = $this->consume($remaining_taf);
     $found = $result['found'];
     $new_remaining_taf = $result['remaining'];
     // handle the case where nothing has been found
     if ($found == null) {
         throw new ChunkDecoderException($remaining_taf, $new_remaining_taf, 'Bad format for visibility information', $this);
     }
     if ($found[1] == 'CAVOK') {
         // ceiling and visibility OK
         $cavok = true;
         $visibility = null;
     } elseif ($found[1] == '////') {
         // information not available
         $cavok = false;
         $visibility = null;
     } else {
         $cavok = false;
         $visibility = new Visibility();
         if (trim($found[2]) != null) {
             // icao visibility
             $visibility->setVisibility(Value::newIntValue($found[2], Value::METER));
         } else {
             // us visibility
             $main = intval($found[4]);
             $is_greater = $found[3] === 'P' ? true : false;
             $frac_top = intval($found[6]);
             $frac_bot = intval($found[7]);
             if ($frac_bot != 0) {
                 $vis_value = $main + $frac_top / $frac_bot;
             } else {
                 $vis_value = $main;
             }
             $visibility->setVisibility(Value::newValue($vis_value, Value::STATUTE_MILE));
             $visibility->setGreater($is_greater);
         }
     }
     $result = array('cavok' => $cavok, 'visibility' => $visibility);
     // return result + remaining taf
     return array('result' => $result, 'remaining_taf' => $new_remaining_taf);
 }
 /**
  *  Test invalid values
  */
 public function testValueErrors()
 {
     $newValue = new Value(null, null);
     $this->assertNull($newValue->getValue());
     $this->assertNull($newValue->newValue(null, null));
     $this->assertNull($newValue->newIntValue('AB', null)->getValue());
 }
 /**
  * Test "Trying to convert unsupported values" Exception during unit conversion.
  *
  * @param int    $value Original value
  * @param string $unit  Unit of value
  * @dataProvider getValueUnsupportedException
  */
 public function testValueUnsupportedException($value, $unit)
 {
     $value = new Value($value, $unit);
     $this->setExpectedException('Exception', 'Trying to convert unsupported values');
     $value->getConvertedValue($unit);
 }