/**
  * Given an object or a string, return a Geometry
  *
  * @param mixed $input The GeoJSON string or object
  *
  * @return object Geometry
  */
 public function read($input)
 {
     if (is_string($input)) {
         $input = json_decode($input);
     }
     if (!is_object($input)) {
         throw new Exception('Invalid JSON');
     }
     if (!is_string($input->type)) {
         throw new Exception('Invalid JSON');
     }
     // Check to see if it's a FeatureCollection
     if ($input->type == 'FeatureCollection') {
         $features = array();
         foreach ($input->features as $feature) {
             $features[] = $this->read($feature);
         }
         $properties = [];
         if (isset($input->properties)) {
             $properties = array_merge($properties, (array) $input->properties);
         }
         if (isset($input->metadata)) {
             $properties = array_merge($properties, (array) $input->metadata);
         }
         // $properties = isset($input->properties) ? (array) $input->properties : [];
         return new FeatureCollection($features, $properties, @$input->id);
     }
     $adapter = new GeoJSON();
     // Check to see if it's a Feature
     if ($input->type == 'Feature') {
         $geometry = $adapter->read($input->geometry);
         $properties = isset($input->properties) ? (array) $input->properties : [];
         return new Feature($geometry, $properties, @$input->id);
     }
     return $adapter->read($input);
 }