Code snippets for symfony 1.x

Navigation

Refine Tags

Snippets tagged "coordinates"

Validator for latitude / longitude

<?php
/**
 * This validator accepts either a four-member array such as
 * array( 'deg' => 12, 'min' => 34, 'sec' => 56, 'dir' => 'N' )
 * or a numeric value such as 12.3456
 */
class ynValidatorLatLong extends sfValidatorBase
{
  protected function configure($options = array(), $messages = array())
  {
    parent::configure( $options, $messages );
 
    $this->addRequiredOption('axis');  // 'latitude' || 'longitude'
 
    $this->addMessage('invalid_axis', 'The selected axis is invalid.');
  }
 
  protected function doClean( $value )
  {
    $max = 0;
 
    switch ( $this->getOption('axis') ) {
      case 'latitude':
        $max = 90;
        break;
 
      case 'longitude':
        $max = 180;
        break;
 
      default:
        throw new sfValidatorError($this, 'invalid_axis');
    }
 
    if ( is_array( $value ) ) {
      $value = $this->arrayToInt( $value );
    }
 
    if ( ! is_numeric( $value ) ) {
      throw new sfValidatorError($this, 'invalid');
    }
 
    if ( abs( $value ) > $max ) {
      throw new sfValidatorError($this, 'invalid');
    }
 
    return $value;
  }
 
  protected function arrayToInt( array $value )
  {
    if ( count( $value ) != 4 ) {
      throw new sfValidatorError($this, 'invalid');
    }
 
    if (
      ! isset( $value['deg'] )
      || ! isset( $value['min'] )
      || ! isset( $value['sec'] )
      || ! isset( $value['dir'] )
    ) {
      throw new sfValidatorError($this, 'invalid');
    }
 
    if ( preg_match( '/\D/', $value['deg'].$value['min'].$value['sec'] ) ) {
      // non-integer component
      throw new sfValidatorError($this, 'invalid');
    }
 
    $multiplier = 1;
 
    switch ( strtolower( $value['dir'] ) ) {
      case 'n':
        $axis = 'latitude';
        break;
 
      case 's':
        $axis = 'latitude';
        $multiplier = -1;
        break;
 
      case 'e':
        $axis = 'longitude';
        break;
 
      case 'w':
        $axis = 'longitude';
        $multiplier = -1;
        break;
 
      default:
        throw new sfValidatorError($this, 'invalid');
    }
 
    if ( $axis != $this->getOption('axis') ) {
      throw new sfValidatorError($this, 'invalid');
    }
 
    return ( $value['deg'] + $value['min']/60 + $value['sec']/60/60 ) * $multiplier;
  }
}
 
/*
 * UNIT TEST
 */
 
<?php
require_once dirname(__FILE__).'/../../bootstrap/unit.php';
 
$t = new lime_test();
 
$lat_validator = new ynValidatorLatLong( array( 'axis' => 'latitude' ) );
$lon_validator = new ynValidatorLatLong( array( 'axis' => 'longitude' ) );
 
$lat_good = array(
  array( 'deg' => 50, 'min' => 12, 'sec' => 14, 'dir' => 'N' ),
  array( 'deg' => 50, 'min' => 12, 'sec' => 14, 'dir' => 'S' ),
  50.456789,
  50,
  -50.456789,
  -50
);
 
$lat_bad = array(
  'three members' => array( 'deg' => 50, 'min' => 12, 'sec' => 14 ),
  'invalid n/s 1' => array( 'deg' => 50, 'min' => 12, 'sec' => 14, 'dir' => 'F' ),
  'invalid n/s 2' => array( 'deg' => 50, 'min' => 12, 'sec' => 14, 'dir' => 'E' ),
  'non-integer member' => array( 'deg' => 50, 'min' => 12, 'sec' => 14.2, 'dir' => 'N' ),
  'out of range' => array( 'deg' => 100, 'min' => 12, 'sec' => 14, 'dir' => 'N' ),
);
 
$lon_good = array(
  array( 'deg' => 150, 'min' => 12, 'sec' => 14, 'dir' => 'E' ),
  array( 'deg' => 150, 'min' => 12, 'sec' => 14, 'dir' => 'W' ),
  50.456789,
  50,
  -50.456789,
  -50
);
 
$lon_bad = array(
  'three members' => array( 'deg' => 150, 'min' => 12, 'sec' => 14 ),
  'invalid e/w 1' => array( 'deg' => 150, 'min' => 12, 'sec' => 14, 'dir' => 'F' ),
  'invalid e/w 2' => array( 'deg' => 150, 'min' => 12, 'sec' => 14, 'dir' => 'N' ),
  'non-integer member' => array( 'deg' => 150, 'min' => 12, 'sec' => 14.2, 'dir' => 'E' ),
  'out of range' => array( 'deg' => 200, 'min' => 12, 'sec' => 14, 'dir' => 'E' ),
);
 
foreach ( $lat_good as $value ) {
  try {
    $clean = $lat_validator->clean( $value );
    $t->ok( is_numeric( $clean ), 'is numeric' );
 
    if ( is_array( $value ) ) {
      switch( $value['dir'] ) {
        case 'E':
          $multiplier = 1;
          break;
        case 'W':
          $multiplier = -1;
          break;
      }
 
      $t->ok( abs($clean) >= $value['deg'] && abs($clean) <= $value['deg']+1, "value $clean makes sense" );
      $t->ok( $clean * $multipler >= 0, 'direction correct' );
    }
    else {
      $t->is( $value, $clean, 'value makes sense' );
    }
  }
  catch( sfValidatorError $e ) {
    $t->fail( $e->getMessage() );
  }
}
 
foreach ( $lat_bad as $message => $value ) {
  try {
    $lat_validator->clean( $value );
    $t->fail( $message );
  }
  catch( sfValidatorError $e ) {
    $t->pass( $message );
  }
}
 
foreach ( $lon_good as $value ) {
  try {
    $clean = $lon_validator->clean( $value );
    $t->ok( is_numeric( $clean ), 'is numeric' );
 
    if ( is_array( $value ) ) {
      switch( $value['dir'] ) {
        case 'E':
          $multiplier = 1;
          break;
        case 'W':
          $multiplier = -1;
          break;
      }
 
      $t->ok( abs($clean) >= $value['deg'] && abs($clean) <= $value['deg']+1, "value $clean makes sense" );
      $t->ok( $clean * $multipler >= 0, 'direction correct' );
    }
    else {
      $t->is( $value, $clean, 'value makes sense' );
    }
  }
  catch( sfValidatorError $e ) {
    $t->fail( $e->getMessage() );
  }
}
 
foreach ( $lon_bad as $message => $value ) {
  try {
    $lon_validator->clean( $value );
    $t->fail( $message );
  }
  catch( sfValidatorError $e ) {
    $t->pass( $message );
  }
}
 
by yitznewton on 2011-02-27, tagged coordinates  form  latitude  longitude  validator