Exemple #1
0
double QgsScaleComboBox::toDouble( const QString &scaleString, bool *returnOk )
{
  bool ok = false;
  QString scaleTxt( scaleString );

  double denominator = qgsPermissiveToDouble( scaleTxt, ok );
  double scale = !qgsDoubleNear( denominator, 0.0 ) ? 1.0 / denominator : 0.0;
  if ( ok )
  {
    // Create a text version and set that text and rescan
    // Idea is to get the same rounding.
    scaleTxt = toString( scale );
  }
  else
  {
    // It is now either X:Y or not valid
    QStringList txtList = scaleTxt.split( ':' );
    if ( 2 == txtList.size() )
    {
      bool okX = false;
      bool okY = false;
      int x = qgsPermissiveToInt( txtList[ 0 ], okX );
      int y = qgsPermissiveToInt( txtList[ 1 ], okY );
      if ( okX && okY && x != 0 )
      {
        // Scale is fraction of x and y
        scale = static_cast<  double >( y ) / static_cast< double >( x );
        ok = true;
      }
    }
  }

  // Set up optional return flag
  if ( returnOk )
  {
    *returnOk = ok;
  }
  return scale;
}
Exemple #2
0
bool QgsField::convertCompatible( QVariant &v ) const
{
  if ( v.isNull() )
  {
    v.convert( d->type );
    return true;
  }

  if ( d->type == QVariant::Int && v.toInt() != v.toLongLong() )
  {
    v = QVariant( d->type );
    return false;
  }

  // Give it a chance to convert to double since for not '.' locales
  // we accept both comma and dot as decimal point
  if ( d->type == QVariant::Double && v.type() == QVariant::String )
  {
    QVariant tmp( v );
    if ( !tmp.convert( d->type ) )
    {
      // This might be a string with thousand separator: use locale to convert
      bool ok = false;
      double d = qgsPermissiveToDouble( v.toString(), ok );
      if ( ok )
      {
        v = QVariant( d );
        return true;
      }
      // For not 'dot' locales, we also want to accept '.'
      if ( QLocale().decimalPoint() != '.' )
      {
        d = QLocale( QLocale::C ).toDouble( v.toString(), &ok );
        if ( ok )
        {
          v = QVariant( d );
          return true;
        }
      }
    }
  }

  // For string representation of an int we also might have thousand separator
  if ( d->type == QVariant::Int && v.type() == QVariant::String )
  {
    QVariant tmp( v );
    if ( !tmp.convert( d->type ) )
    {
      // This might be a string with thousand separator: use locale to convert
      bool ok;
      int i = qgsPermissiveToInt( v.toString(), ok );
      if ( ok )
      {
        v = QVariant( i );
        return true;
      }
    }
  }

  // For string representation of a long we also might have thousand separator
  if ( d->type == QVariant::LongLong && v.type() == QVariant::String )
  {
    QVariant tmp( v );
    if ( !tmp.convert( d->type ) )
    {
      // This might be a string with thousand separator: use locale to convert
      bool ok;
      qlonglong l = qgsPermissiveToLongLong( v.toString(), ok );
      if ( ok )
      {
        v = QVariant( l );
        return true;
      }
    }
  }

  //String representations of doubles in QVariant will return false to convert( QVariant::Int )
  //work around this by first converting to double, and then checking whether the double is convertible to int
  if ( d->type == QVariant::Int && v.canConvert( QVariant::Double ) )
  {
    bool ok = false;
    double dbl = v.toDouble( &ok );
    if ( !ok )
    {
      //couldn't convert to number
      v = QVariant( d->type );
      return false;
    }

    double round = std::round( dbl );
    if ( round  > std::numeric_limits<int>::max() || round < -std::numeric_limits<int>::max() )
    {
      //double too large to fit in int
      v = QVariant( d->type );
      return false;
    }
    v = QVariant( static_cast< int >( std::round( dbl ) ) );
    return true;
  }


  if ( !v.convert( d->type ) )
  {
    v = QVariant( d->type );
    return false;
  }

  if ( d->type == QVariant::Double && d->precision > 0 )
  {
    double s = std::pow( 10, d->precision );
    double d = v.toDouble() * s;
    v = QVariant( ( d < 0 ? std::ceil( d - 0.5 ) : std::floor( d + 0.5 ) ) / s );
    return true;
  }

  if ( d->type == QVariant::String && d->length > 0 && v.toString().length() > d->length )
  {
    v = v.toString().left( d->length );
    return false;
  }

  return true;
}