QList<QgsSymbol *> QgsGraduatedSymbolRendererWidget::selectedSymbols()
{
  QList<QgsSymbol *> selectedSymbols;

  QItemSelectionModel *m = viewGraduated->selectionModel();
  QModelIndexList selectedIndexes = m->selectedRows( 1 );
  if ( m && !selectedIndexes.isEmpty() )
  {
    const QgsRangeList &ranges = mRenderer->ranges();
    QModelIndexList::const_iterator indexIt = selectedIndexes.constBegin();
    for ( ; indexIt != selectedIndexes.constEnd(); ++indexIt )
    {
      QStringList list = m->model()->data( *indexIt ).toString().split( ' ' );
      if ( list.size() < 3 )
      {
        continue;
      }
      // Not strictly necessary because the range should have been sanitized already
      // after user input, but being permissive never hurts
      bool ok = false;
      double lowerBound = qgsPermissiveToDouble( list.at( 0 ), ok );
      if ( ! ok )
        lowerBound = 0.0;
      double upperBound = qgsPermissiveToDouble( list.at( 2 ), ok );
      if ( ! ok )
        upperBound = 0.0;
      QgsSymbol *s = findSymbolForRange( lowerBound, upperBound, ranges );
      if ( s )
      {
        selectedSymbols.append( s );
      }
    }
  }
  return selectedSymbols;
}
void QgsGraduatedSymbolRendererWidget::changeRange( int rangeIdx )
{
  QgsLUDialog dialog( this );

  const QgsRendererRange &range = mRenderer->ranges()[rangeIdx];
  // Add arbitrary 2 to number of decimal places to retain a bit extra.
  // Ensures users can see if legend is not completely honest!
  int decimalPlaces = mRenderer->labelFormat().precision() + 2;
  if ( decimalPlaces < 0 ) decimalPlaces = 0;
  dialog.setLowerValue( QLocale().toString( range.lowerValue(), 'f', decimalPlaces ) );
  dialog.setUpperValue( QLocale().toString( range.upperValue(), 'f', decimalPlaces ) );

  if ( dialog.exec() == QDialog::Accepted )
  {
    bool ok = false;
    double lowerValue = qgsPermissiveToDouble( dialog.lowerValue(), ok );
    if ( ! ok )
      lowerValue = 0.0;
    double upperValue = qgsPermissiveToDouble( dialog.upperValue(), ok );
    if ( ! ok )
      upperValue = 0.0;
    mRenderer->updateRangeUpperValue( rangeIdx, upperValue );
    mRenderer->updateRangeLowerValue( rangeIdx, lowerValue );

    //If the boundaries have to stay linked, we update the ranges above and below, as well as their label if needed
    if ( cbxLinkBoundaries->isChecked() )
    {
      if ( rangeIdx > 0 )
      {
        mRenderer->updateRangeUpperValue( rangeIdx - 1, lowerValue );
      }

      if ( rangeIdx < mRenderer->ranges().size() - 1 )
      {
        mRenderer->updateRangeLowerValue( rangeIdx + 1, upperValue );
      }
    }
  }
  mHistogramWidget->refresh();
  emit widgetChanged();
}
示例#3
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;
}
示例#4
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;
}