Exemple #1
0
QSizeF QgsTextDiagram::diagramSize( const QgsFeature& feature, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is )
{
  QgsExpressionContext expressionContext = c.expressionContext();
  expressionContext.setFeature( feature );
  if ( feature.fields() )
    expressionContext.setFields( *feature.fields() );

  QVariant attrVal;
  if ( is.classificationAttributeIsExpression )
  {
    QgsExpression* expression = getExpression( is.classificationAttributeExpression, expressionContext );
    attrVal = expression->evaluate( &expressionContext );
  }
  else
  {
    attrVal = feature.attributes().at( is.classificationAttribute );
  }

  bool ok = false;
  double val = attrVal.toDouble( &ok );
  if ( !ok )
  {
    return QSizeF(); //zero size if attribute is missing
  }

  return sizeForValue( val, s, is );
}
void QgsExpressionSelectionDialog::on_mActionAddToSelection_triggered()
{
  QgsFeatureIds newSelection = mLayer->selectedFeaturesIds();
  QgsExpression* expression = new QgsExpression( mExpressionBuilder->expressionText() );

  const QgsFields fields = mLayer->fields();

  QgsFeatureIterator features = mLayer->getFeatures();

  expression->prepare( fields );

  QgsFeature feat;
  while ( features.nextFeature( feat ) )
  {
    if ( expression->evaluate( &feat, fields ).toBool() )
    {
      newSelection << feat.id();
    }
  }

  features.close();

  mLayer->setSelectedFeatures( newSelection );

  delete expression;
  saveRecent();
}
void QgsExpressionSelectionDialog::on_mActionSelectInstersect_triggered()
{
  const QgsFeatureIds &oldSelection = mLayer->selectedFeaturesIds();
  QgsFeatureIds newSelection;

  QgsExpression* expression = new QgsExpression( mExpressionBuilder->expressionText() );

  const QgsFields fields = mLayer->fields();

  expression->prepare( fields );

  QgsFeature feat;
  foreach ( const QgsFeatureId fid, oldSelection )
  {
    QgsFeatureIterator features = mLayer->getFeatures( QgsFeatureRequest().setFilterFid( fid ) );

    if ( features.nextFeature( feat ) )
    {
      if ( expression->evaluate( &feat, fields ).toBool() )
      {
        newSelection << feat.id();
      }
    }
    else
    {
      Q_ASSERT( false );
    }

    features.close();
  }
void QgsVectorLayerFeatureIterator::prepareExpressions()
{
  const QList<QgsExpressionFieldBuffer::ExpressionField> exps = mSource->mExpressionFieldBuffer->expressions();

  for ( int i = 0; i < mSource->mFields.count(); i++ )
  {
    if ( mSource->mFields.fieldOrigin( i ) == QgsFields::OriginExpression )
    {
      // Only prepare if there is no subset defined or the subset contains this field
      if ( !( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
           || mRequest.subsetOfAttributes().contains( i ) )
      {
        int oi = mSource->mFields.fieldOriginIndex( i );
        QgsExpression* exp = new QgsExpression( exps[oi].expression );
        exp->prepare( mSource->mFields );
        mExpressionFieldInfo.insert( i, exp );

        if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
        {
          QgsAttributeList attrs;
          Q_FOREACH( const QString& col, exp->referencedColumns() )
          {
            attrs.append( mSource->mFields.fieldNameIndex( col ) );
          }

          mRequest.setSubsetOfAttributes( mRequest.subsetOfAttributes() + attrs );
        }

        if ( exp->needsGeometry() )
        {
          mRequest.setFlags( mRequest.flags() & ~QgsFeatureRequest::NoGeometry );
        }
      }
    }
void QgsExpressionSelectionDialog::on_mActionSelectIntersect_triggered()
{
  const QgsFeatureIds &oldSelection = mLayer->selectedFeaturesIds();
  QgsFeatureIds newSelection;

  QgsExpression* expression = new QgsExpression( mExpressionBuilder->expressionText() );

  QgsExpressionContext context;
  context << QgsExpressionContextUtils::globalScope()
  << QgsExpressionContextUtils::projectScope()
  << QgsExpressionContextUtils::layerScope( mLayer );

  expression->prepare( &context );

  QgsFeature feat;
  Q_FOREACH ( const QgsFeatureId fid, oldSelection )
  {
    QgsFeatureIterator features = mLayer->getFeatures( QgsFeatureRequest().setFilterFid( fid ) );

    if ( features.nextFeature( feat ) )
    {
      context.setFeature( feat );
      if ( expression->evaluate( &context ).toBool() )
      {
        newSelection << feat.id();
      }
    }
    else
    {
      Q_ASSERT( false );
    }

    features.close();
  }
bool QgsVectorLayerLabelProvider::prepare( const QgsRenderContext &context, QSet<QString> &attributeNames )
{
  QgsPalLayerSettings &lyr = mSettings;
  const QgsMapSettings &mapSettings = mEngine->mapSettings();

  QgsDebugMsgLevel( "PREPARE LAYER " + mLayerId, 4 );

  if ( lyr.drawLabels )
  {
    if ( lyr.fieldName.isEmpty() )
    {
      return false;
    }

    if ( lyr.isExpression )
    {
      QgsExpression exp( lyr.fieldName );
      if ( exp.hasEvalError() )
      {
        QgsDebugMsgLevel( "Prepare error:" + exp.evalErrorString(), 4 );
        return false;
      }
    }
    else
    {
      // If we aren't an expression, we check to see if we can find the column.
      if ( mFields.lookupField( lyr.fieldName ) == -1 )
      {
        return false;
      }
    }
  }

  lyr.mCurFields = mFields;

  if ( lyr.drawLabels || lyr.obstacle )
  {
    if ( lyr.drawLabels )
    {
      // add field indices for label's text, from expression or field
      if ( lyr.isExpression )
      {
        // prepare expression for use in QgsPalLayerSettings::registerFeature()
        QgsExpression *exp = lyr.getLabelExpression();
        exp->prepare( &context.expressionContext() );
        if ( exp->hasEvalError() )
        {
          QgsDebugMsgLevel( "Prepare error:" + exp->evalErrorString(), 4 );
        }
        Q_FOREACH ( const QString &name, exp->referencedColumns() )
        {
          QgsDebugMsgLevel( "REFERENCED COLUMN = " + name, 4 );
          attributeNames.insert( name );
        }
      }
      else
      {
        attributeNames.insert( lyr.fieldName );
      }
    }
void QgsVectorLayerRenderer::prepareDiagrams( QgsVectorLayer* layer, QStringList& attributeNames )
{
  if ( !mContext.labelingEngine() )
    return;

  if ( !layer->diagramRenderer() || !layer->diagramLayerSettings() )
    return;

  mDiagrams = true;

  const QgsDiagramRendererV2* diagRenderer = layer->diagramRenderer();
  const QgsDiagramLayerSettings* diagSettings = layer->diagramLayerSettings();

  mContext.labelingEngine()->addDiagramLayer( layer, diagSettings ); // will make internal copy of diagSettings + initialize it

  //add attributes needed by the diagram renderer
  QList<QString> att = diagRenderer->diagramAttributes();
  QList<QString>::const_iterator attIt = att.constBegin();
  for ( ; attIt != att.constEnd(); ++attIt )
  {
    QgsExpression* expression = diagRenderer->diagram()->getExpression( *attIt, &mFields );
    QStringList columns = expression->referencedColumns();
    QStringList::const_iterator columnsIterator = columns.constBegin();
    for ( ; columnsIterator != columns.constEnd(); ++columnsIterator )
    {
      if ( !attributeNames.contains( *columnsIterator ) )
        attributeNames << *columnsIterator;
    }
  }

  const QgsLinearlyInterpolatedDiagramRenderer* linearlyInterpolatedDiagramRenderer = dynamic_cast<const QgsLinearlyInterpolatedDiagramRenderer*>( layer->diagramRenderer() );
  if ( linearlyInterpolatedDiagramRenderer != NULL )
  {
    if ( linearlyInterpolatedDiagramRenderer->classificationAttributeIsExpression() )
    {
      QgsExpression* expression = diagRenderer->diagram()->getExpression( linearlyInterpolatedDiagramRenderer->classificationAttributeExpression(), &mFields );
      QStringList columns = expression->referencedColumns();
      QStringList::const_iterator columnsIterator = columns.constBegin();
      for ( ; columnsIterator != columns.constEnd(); ++columnsIterator )
      {
        if ( !attributeNames.contains( *columnsIterator ) )
          attributeNames << *columnsIterator;
      }
    }
    else
    {
      QString name = mFields.at( linearlyInterpolatedDiagramRenderer->classificationAttribute() ).name();
      if ( !attributeNames.contains( name ) )
        attributeNames << name;
    }
  }

  //and the ones needed for data defined diagram positions
  if ( diagSettings->xPosColumn != -1 )
    attributeNames << mFields.at( diagSettings->xPosColumn ).name();
  if ( diagSettings->yPosColumn != -1 )
    attributeNames << mFields.at( diagSettings->yPosColumn ).name();
}
QColor QgsSimpleLineSymbolLayerV2::dxfColor( const QgsSymbolV2RenderContext& context ) const
{
  QgsExpression* strokeColorExpression = expression( "color" );
  if ( strokeColorExpression )
  {
    return ( QgsSymbolLayerV2Utils::decodeColor( strokeColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() ) );
  }
  return mColor;
}
void QgsMarkerLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSymbolV2RenderContext& context )
{
  double offset = mOffset;
  QgsExpression* offsetExpression = expression( "offset" );
  if ( offsetExpression )
  {
    offset = offsetExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
  }

  Placement placement = mPlacement;
  QgsExpression* placementExpression = expression( "placement" );
  if ( placementExpression )
  {
    QString placementString = placementExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
    if ( placementString.compare( "vertex", Qt::CaseInsensitive ) == 0 )
    {
      placement = Vertex;
    }
    else if ( placementString.compare( "lastvertex", Qt::CaseInsensitive ) == 0 )
    {
      placement = LastVertex;
    }
    else if ( placementString.compare( "firstvertex", Qt::CaseInsensitive ) == 0 )
    {
      placement = FirstVertex;
    }
    else if ( placementString.compare( "centerpoint", Qt::CaseInsensitive ) == 0 )
    {
      placement = CentralPoint;
    }
    else
    {
      placement = Interval;
    }
  }

  if ( offset == 0 )
  {
    if ( placement == Interval )
      renderPolylineInterval( points, context );
    else if ( placement == CentralPoint )
      renderPolylineCentral( points, context );
    else
      renderPolylineVertex( points, context, placement );
  }
  else
  {
    QPolygonF points2 = ::offsetLine( points, offset * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit ) );
    if ( placement == Interval )
      renderPolylineInterval( points2, context );
    else if ( placement == CentralPoint )
      renderPolylineCentral( points2, context );
    else
      renderPolylineVertex( points2, context, placement );
  }
}
Exemple #10
0
QgsExpression *QgsDiagram::getExpression( const QString &expression, const QgsExpressionContext &context )
{
  if ( !mExpressions.contains( expression ) )
  {
    QgsExpression *expr = new QgsExpression( expression );
    expr->prepare( &context );
    mExpressions[expression] = expr;
  }
  return mExpressions[expression];
}
Exemple #11
0
QSizeF QgsTextDiagram::diagramSize( const QgsFeature& feature, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is )
{
  Q_UNUSED( c );

  QVariant attrVal;
  if ( is.classificationAttributeIsExpression )
  {
    QgsExpression* expression = getExpression( is.classificationAttributeExpression, feature.fields() );
    attrVal = expression->evaluate( feature );
  }
  else
  {
    attrVal = feature.attributes()[is.classificationAttribute];
  }

  if ( !attrVal.isValid() )
  {
    return QSizeF(); //zero size if attribute is missing
  }

  double scaledValue = attrVal.toDouble();
  double scaledLowerValue = is.lowerValue;
  double scaledUpperValue = is.upperValue;
  double scaledLowerSizeWidth = is.lowerSize.width();
  double scaledLowerSizeHeight = is.lowerSize.height();
  double scaledUpperSizeWidth = is.upperSize.width();
  double scaledUpperSizeHeight = is.upperSize.height();

  // interpolate the squared value if scale by area
  if ( s.scaleByArea )
  {
    scaledValue = sqrt( scaledValue );
    scaledLowerValue = sqrt( scaledLowerValue );
    scaledUpperValue = sqrt( scaledUpperValue );
    scaledLowerSizeWidth = sqrt( scaledLowerSizeWidth );
    scaledLowerSizeHeight = sqrt( scaledLowerSizeHeight );
    scaledUpperSizeWidth = sqrt( scaledUpperSizeWidth );
    scaledUpperSizeHeight = sqrt( scaledUpperSizeHeight );
  }

  //interpolate size
  double scaledRatio = ( scaledValue - scaledLowerValue ) / ( scaledUpperValue - scaledLowerValue );

  QSizeF size = QSizeF( is.upperSize.width() * scaledRatio + is.lowerSize.width() * ( 1 - scaledRatio ),
                        is.upperSize.height() * scaledRatio + is.lowerSize.height() * ( 1 - scaledRatio ) );

  // Scale, if extension is smaller than the specified minimum
  if ( size.width() <= s.minimumSize && size.height() <= s.minimumSize )
  {
    size.scale( s.minimumSize, s.minimumSize, Qt::KeepAspectRatio );
  }

  return size;
}
double QgsSimpleLineSymbolLayerV2::dxfOffset( const QgsDxfExport& e, const QgsSymbolV2RenderContext& context ) const
{
  Q_UNUSED( e );
  double offset = mOffset;
  QgsExpression* offsetExpression = expression( "offset" );
  if ( offsetExpression )
  {
    offset = offsetExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
  }
  return offset;
}
double QgsSimpleLineSymbolLayerV2::dxfWidth( const QgsDxfExport& e, const QgsSymbolV2RenderContext& context ) const
{
  double width = mWidth;
  QgsExpression* strokeWidthExpression = expression( "width" );
  if ( strokeWidthExpression )
  {
    width = strokeWidthExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble() * e.mapUnitScaleFactor( e.symbologyScaleDenominator(), widthUnit(), e.mapUnits() );
  }
  else if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale )
  {
    width = mWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit, mWidthMapUnitScale );
  }

  return width * e.mapUnitScaleFactor( e.symbologyScaleDenominator(), widthUnit(), e.mapUnits() );
}
void QgsMarkerSymbolLayerV2::markerOffset( QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY )
{
  offsetX = mOffset.x();
  offsetY = mOffset.y();

  QgsExpression* offsetExpression = expression( "offset" );
  if ( offsetExpression )
  {
    QPointF offset = QgsSymbolLayerV2Utils::decodePoint( offsetExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
    offsetX = offset.x();
    offsetY = offset.y();
  }

  offsetX *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit );
  offsetY *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit );
}
QgsFeatureRequest::QgsFeatureRequest( const QgsExpression& expr )
    : mFilter( FilterExpression )
    , mFilterFid( -1 )
    , mFilterExpression( new QgsExpression( expr.expression() ) )
    , mFlags( 0 )
{
}
QSizeF QgsHistogramDiagram::diagramSize( const QgsFeature& feature, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is )
{
  QSizeF size;
  if ( feature.attributes().isEmpty() )
  {
    return size; //zero size if no attributes
  }

  if ( qgsDoubleNear( is.upperValue, is.lowerValue ) )
    return size; // invalid value range => zero size

  double maxValue = 0;

  QgsExpressionContext expressionContext = c.expressionContext();
  expressionContext.setFeature( feature );
  if ( !feature.fields().isEmpty() )
    expressionContext.setFields( feature.fields() );

  Q_FOREACH ( const QString& cat, s.categoryAttributes )
  {
    QgsExpression* expression = getExpression( cat, expressionContext );
    maxValue = qMax( expression->evaluate( &expressionContext ).toDouble(), maxValue );
  }

  // Scale, if extension is smaller than the specified minimum
  if ( maxValue < s.minimumSize )
  {
    maxValue = s.minimumSize;
  }

  switch ( s.diagramOrientation )
  {
    case QgsDiagramSettings::Up:
    case QgsDiagramSettings::Down:
      mScaleFactor = (( is.upperSize.width() - is.lowerSize.height() ) / ( is.upperValue - is.lowerValue ) );
      size.scale( s.barWidth * s.categoryAttributes.size(), maxValue * mScaleFactor, Qt::IgnoreAspectRatio );
      break;

    case QgsDiagramSettings::Right:
    case QgsDiagramSettings::Left:
      mScaleFactor = (( is.upperSize.width() - is.lowerSize.width() ) / ( is.upperValue - is.lowerValue ) );
      size.scale( maxValue * mScaleFactor, s.barWidth * s.categoryAttributes.size(), Qt::IgnoreAspectRatio );
      break;
  }

  return size;
}
bool QgsWFSUtils::expressionToOGCFilter( QgsExpression& exp, QDomDocument& doc )
{
  doc.clear();
  QDomElement filterElem = doc.createElement( "Filter" );
  doc.appendChild( filterElem );

  QgsExpressionOGCVisitor v( doc, filterElem );
  exp.acceptVisitor( v );
  return v.result();
}
Exemple #18
0
bool QgsWFSUtils::expressionToOGCFilter( QgsExpression& exp, QDomDocument& doc )
{
  doc.clear();
  QDomElement filterElem = doc.createElement( "Filter" );
  filterElem.setAttribute( "xmlns:ogc", "http://www.opengis.net/ogc" );
  doc.appendChild( filterElem );

  QgsExpressionOGCVisitor v( doc, filterElem );
  exp.acceptVisitor( v );
  return v.result();
}
bool QgsFeatureListModel::setDisplayExpression( const QString expression )
{
  const QgsFields fields = mFilterModel->layer()->dataProvider()->fields();

  QgsExpression* exp = new QgsExpression( expression );

  exp->prepare( fields );

  if ( exp->hasParserError() )
  {
    mParserErrorString = exp->parserErrorString();
    delete exp;
    return false;
  }

  delete mExpression;
  mExpression = exp;

  emit( dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ) ) );
  return true;
}
Exemple #20
0
void QgsMarkerSymbolLayerV2::markerOffset( const QgsSymbolV2RenderContext& context, double width, double height,
    QgsSymbolV2::OutputUnit widthUnit, QgsSymbolV2::OutputUnit heightUnit,
    double& offsetX, double& offsetY ) const
{
  offsetX = mOffset.x();
  offsetY = mOffset.y();

  QgsExpression* offsetExpression = expression( "offset" );
  if ( offsetExpression )
  {
    QPointF offset = QgsSymbolLayerV2Utils::decodePoint( offsetExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
    offsetX = offset.x();
    offsetY = offset.y();
  }

  offsetX *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit );
  offsetY *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit );

  HorizontalAnchorPoint horizontalAnchorPoint = mHorizontalAnchorPoint;
  VerticalAnchorPoint verticalAnchorPoint = mVerticalAnchorPoint;
  QgsExpression* horizontalAnchorExpression = expression( "horizontal_anchor_point" );
  if ( horizontalAnchorExpression )
  {
    horizontalAnchorPoint = decodeHorizontalAnchorPoint( horizontalAnchorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
  }
  QgsExpression* verticalAnchorExpression = expression( "vertical_anchor_point" );
  if ( verticalAnchorExpression )
  {
    verticalAnchorPoint = decodeVerticalAnchorPoint( verticalAnchorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
  }

  //correct horizontal position according to anchor point
  if ( horizontalAnchorPoint == HCenter && verticalAnchorPoint == VCenter )
  {
    return;
  }

  double anchorPointCorrectionX = width * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), widthUnit ) / 2.0;
  double anchorPointCorrectionY = height * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), heightUnit ) / 2.0;
  if ( horizontalAnchorPoint == Left )
  {
    offsetX += anchorPointCorrectionX;
  }
  else if ( horizontalAnchorPoint == Right )
  {
    offsetX -= anchorPointCorrectionX;
  }

  //correct vertical position according to anchor point
  if ( verticalAnchorPoint == Top )
  {
    offsetY += anchorPointCorrectionY;
  }
  else if ( verticalAnchorPoint == Bottom )
  {
    offsetY -= anchorPointCorrectionY;
  }
}
void QgsRuleBasedRendererV2::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
{
  double currentScale = context.rendererScale();
  // filter out rules which are not compatible with this scale

  mCurrentRules.clear();
  for ( QList<Rule>::iterator it = mRules.begin(); it != mRules.end(); ++it )
  {
    Rule& rule = *it;
    if ( rule.isScaleOK( currentScale ) )
      mCurrentRules.append( &rule );
  }

  QgsFieldMap pendingFields = vlayer->pendingFields();

  for ( QList<Rule*>::iterator it = mCurrentRules.begin(); it != mCurrentRules.end(); ++it )
  {
    Rule* rule = *it;
    QgsExpression* exp = rule->filter();
    if ( exp )
      exp->prepare( pendingFields );
    rule->symbol()->startRender( context );
  }
}
Exemple #22
0
bool QgsFeatureListModel::setDisplayExpression( const QString& expression )
{
    QgsExpression* exp = new QgsExpression( expression );

    QgsExpressionContext context;
    context << QgsExpressionContextUtils::globalScope()
            << QgsExpressionContextUtils::projectScope()
            << QgsExpressionContextUtils::layerScope( mFilterModel->layer() );

    exp->prepare( &context );

    if ( exp->hasParserError() )
    {
        mParserErrorString = exp->parserErrorString();
        delete exp;
        return false;
    }

    delete mExpression;
    mExpression = exp;

    emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ) );
    return true;
}
void QgsAttributeTypeDialog::defaultExpressionChanged()
{
  QString expression = mExpressionWidget->expression();
  if ( expression.isEmpty() )
  {
    mDefaultPreviewLabel->setText( QString() );
    return;
  }

  QgsExpressionContext context = mLayer->createExpressionContext();

  if ( !mPreviewFeature.isValid() )
  {
    // get first feature
    QgsFeatureIterator it = mLayer->getFeatures( QgsFeatureRequest().setLimit( 1 ) );
    it.nextFeature( mPreviewFeature );
  }

  context.setFeature( mPreviewFeature );

  QgsExpression exp = QgsExpression( expression );
  exp.prepare( &context );

  if ( exp.hasParserError() )
  {
    mDefaultPreviewLabel->setText( "<i>" + exp.parserErrorString() + "</i>" );
    return;
  }

  QVariant val = exp.evaluate( &context );
  if ( exp.hasEvalError() )
  {
    mDefaultPreviewLabel->setText( "<i>" + exp.evalErrorString() + "</i>" );
    return;
  }

  QString previewText = val.toString();

  QgsEditorWidgetFactory *factory = QgsEditorWidgetRegistry::instance()->factory( editorWidgetType() );
  if ( factory )
  {
    previewText = factory->representValue( mLayer, mFieldIdx, editorWidgetConfig(), QVariant(), val );
  }

  mDefaultPreviewLabel->setText( "<i>" + previewText + "</i>" );
}
    void test_from_ogc_filter()
    {
      QFETCH( QString, xmlText );
      QFETCH( QString, dumpText );

      QDomDocument doc;
      QVERIFY(doc.setContent(xmlText, true));
      QDomElement rootElem = doc.documentElement();

      QgsExpression* expr = QgsExpression::createFromOgcFilter( rootElem );
      QVERIFY( expr );

      qDebug("OGC XML  : %s", xmlText.toAscii().data() );
      qDebug("EXPR-DUMP: %s", expr->dump().toAscii().data() );

      if ( expr->hasParserError() )
        qDebug( "ERROR: %s ", expr->parserErrorString().toAscii().data() );
      QVERIFY( !expr->hasParserError() );

      QCOMPARE( dumpText, expr->dump() );

      delete expr;
    }
Exemple #25
0
QVariant QmlExpression::evaluate( const QString &expression ) const
{
  QgsExpression exp = QgsExpression( expression );
  exp.prepare( &mExpressionContext );
  return exp.evaluate( &mExpressionContext );
}
void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points, QgsSymbolV2RenderContext& context, Placement placement )
{
  if ( points.isEmpty() )
    return;

  QgsRenderContext& rc = context.renderContext();

  double origAngle = mMarker->angle();
  int i, maxCount;
  bool isRing = false;

  double offsetAlongLine = mOffsetAlongLine;
  QgsExpression* offsetAlongLineExpression = expression( "offset_along_line" );
  if ( offsetAlongLineExpression )
  {
    offsetAlongLine = offsetAlongLineExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
  }
  if ( offsetAlongLine != 0 )
  {
    //scale offset along line
    offsetAlongLine *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( rc, mOffsetAlongLineUnit, mOffsetAlongLineMapUnitScale );
  }

  if ( placement == FirstVertex )
  {
    i = 0;
    maxCount = 1;
  }
  else if ( placement == LastVertex )
  {
    i = points.count() - 1;
    maxCount = points.count();
  }
  else
  {
    i = 0;
    maxCount = points.count();
    if ( points.first() == points.last() )
      isRing = true;
  }

  if ( offsetAlongLine > 0 && ( placement == FirstVertex || placement == LastVertex ) )
  {
    double distance;
    distance = placement == FirstVertex ? offsetAlongLine : -offsetAlongLine;
    renderOffsetVertexAlongLine( points, i, distance, context );
    // restore original rotation
    mMarker->setAngle( origAngle );
    return;
  }

  for ( ; i < maxCount; ++i )
  {
    if ( isRing && placement == Vertex && i == points.count() - 1 )
    {
      continue; // don't draw the last marker - it has been drawn already
    }
    // rotate marker (if desired)
    if ( mRotateMarker )
    {
      double angle = markerAngle( points, isRing, i );
      mMarker->setAngle( origAngle + angle * 180 / M_PI );
    }

    mMarker->renderPoint( points.at( i ), context.feature(), rc, -1, context.selected() );
  }

  // restore original rotation
  mMarker->setAngle( origAngle );
}
void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points, QgsSymbolV2RenderContext& context )
{
  if ( points.isEmpty() )
    return;

  QPointF lastPt = points[0];
  double lengthLeft = 0; // how much is left until next marker
  bool first = mOffsetAlongLine ? false : true; //only draw marker at first vertex when no offset along line is set
  double origAngle = mMarker->angle();

  QgsRenderContext& rc = context.renderContext();
  double interval = mInterval;

  QgsExpression* intervalExpression = expression( "interval" );
  if ( intervalExpression )
  {
    interval = intervalExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
  }
  if ( interval <= 0 )
  {
    interval = 0.1;
  }
  double offsetAlongLine = mOffsetAlongLine;
  QgsExpression* offsetAlongLineExpression = expression( "offset_along_line" );
  if ( offsetAlongLineExpression )
  {
    offsetAlongLine = offsetAlongLineExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
  }

  double painterUnitInterval = interval * QgsSymbolLayerV2Utils::lineWidthScaleFactor( rc, mIntervalUnit, mIntervalMapUnitScale );
  lengthLeft = painterUnitInterval - offsetAlongLine * QgsSymbolLayerV2Utils::lineWidthScaleFactor( rc, mIntervalUnit, mIntervalMapUnitScale );

  for ( int i = 1; i < points.count(); ++i )
  {
    const QPointF& pt = points[i];

    if ( lastPt == pt ) // must not be equal!
      continue;

    // for each line, find out dx and dy, and length
    MyLine l( lastPt, pt );
    QPointF diff = l.diffForInterval( painterUnitInterval );

    // if there's some length left from previous line
    // use only the rest for the first point in new line segment
    double c = 1 - lengthLeft / painterUnitInterval;

    lengthLeft += l.length();

    // rotate marker (if desired)
    if ( mRotateMarker )
    {
      mMarker->setAngle( origAngle + ( l.angle() * 180 / M_PI ) );
    }

    // draw first marker
    if ( first )
    {
      mMarker->renderPoint( lastPt, context.feature(), rc, -1, context.selected() );
      first = false;
    }

    // while we're not at the end of line segment, draw!
    while ( lengthLeft > painterUnitInterval )
    {
      // "c" is 1 for regular point or in interval (0,1] for begin of line segment
      lastPt += c * diff;
      lengthLeft -= painterUnitInterval;
      mMarker->renderPoint( lastPt, context.feature(), rc, -1, context.selected() );
      c = 1; // reset c (if wasn't 1 already)
    }

    lastPt = pt;
  }

  // restore original rotation
  mMarker->setAngle( origAngle );

}
void QgsSimpleLineSymbolLayerV2::applyDataDefinedSymbology( QgsSymbolV2RenderContext& context, QPen& pen, QPen& selPen, double& offset )
{
  if ( mDataDefinedProperties.isEmpty() )
    return; // shortcut

  //data defined properties
  double scaledWidth = 0;
  QgsExpression* strokeWidthExpression = expression( "width" );
  if ( strokeWidthExpression )
  {
    scaledWidth = strokeWidthExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble()
                  * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit, mWidthMapUnitScale );
    pen.setWidthF( scaledWidth );
    selPen.setWidthF( scaledWidth );
  }
  else if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale )
  {
    scaledWidth = mWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit, mWidthMapUnitScale );
    pen.setWidthF( scaledWidth );
    selPen.setWidthF( scaledWidth );
  }

  //color
  QgsExpression* strokeColorExpression = expression( "color" );
  if ( strokeColorExpression )
  {
    pen.setColor( QgsSymbolLayerV2Utils::decodeColor( strokeColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() ) );
  }

  //offset
  QgsExpression* lineOffsetExpression = expression( "offset" );
  if ( lineOffsetExpression )
  {
    offset = lineOffsetExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
  }

  //dash dot vector
  QgsExpression* dashPatternExpression = expression( "customdash" );
  if ( dashPatternExpression )
  {
    double scaledWidth = mWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit, mWidthMapUnitScale );
    double dashWidthDiv = mPen.widthF();

    if ( strokeWidthExpression )
    {
      dashWidthDiv = pen.widthF();
      scaledWidth = pen.widthF();
    }

    //fix dash pattern width in Qt 4.8
    QStringList versionSplit = QString( qVersion() ).split( "." );
    if ( versionSplit.size() > 1
         && versionSplit.at( 1 ).toInt() >= 8
         && ( scaledWidth * context.renderContext().rasterScaleFactor() ) < 1.0 )
    {
      dashWidthDiv = 1.0;
    }

    QVector<qreal> dashVector;
    QStringList dashList = dashPatternExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString().split( ";" );
    QStringList::const_iterator dashIt = dashList.constBegin();
    for ( ; dashIt != dashList.constEnd(); ++dashIt )
    {
      dashVector.push_back( dashIt->toDouble() * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mCustomDashPatternUnit, mCustomDashPatternMapUnitScale ) / dashWidthDiv );
    }
    pen.setDashPattern( dashVector );
  }

  //join style
  QgsExpression* joinStyleExpression = expression( "joinstyle" );
  if ( joinStyleExpression )
  {
    QString joinStyleString = joinStyleExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
    pen.setJoinStyle( QgsSymbolLayerV2Utils::decodePenJoinStyle( joinStyleString ) );
  }

  //cap style
  QgsExpression* capStyleExpression = expression( "capstyle" );
  if ( capStyleExpression )
  {
    QString capStyleString = capStyleExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
    pen.setCapStyle( QgsSymbolLayerV2Utils::decodePenCapStyle( capStyleString ) );
  }
}
void QgsEllipseSymbolLayerV2::preparePath( const QString& symbolName, QgsSymbolV2RenderContext& context, const QgsFeature* f )
{
  mPainterPath = QPainterPath();
  const QgsRenderContext& ct = context.renderContext();

  double width = 0;

  QgsExpression* widthExpression = expression( "width" );
  if ( widthExpression ) //1. priority: data defined setting on symbol layer level
  {
    width = widthExpression->evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
  }
  else if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
  {
    width = mSize;
  }
  else //3. priority: global width setting
  {
    width = mSymbolWidth;
  }
  width *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( ct, mSymbolWidthUnit );

  double height = 0;
  QgsExpression* heightExpression = expression( "height" );
  if ( heightExpression ) //1. priority: data defined setting on symbol layer level
  {
    height =  heightExpression->evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
  }
  else if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
  {
    height = mSize;
  }
  else //3. priority: global height setting
  {
    height = mSymbolHeight;
  }
  height *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( ct, mSymbolHeightUnit );

  if ( symbolName == "circle" )
  {
    mPainterPath.addEllipse( QRectF( -width / 2.0, -height / 2.0, width, height ) );
  }
  else if ( symbolName == "rectangle" )
  {
    mPainterPath.addRect( QRectF( -width / 2.0, -height / 2.0, width, height ) );
  }
  else if ( symbolName == "cross" )
  {
    mPainterPath.moveTo( 0, -height / 2.0 );
    mPainterPath.lineTo( 0, height / 2.0 );
    mPainterPath.moveTo( -width / 2.0, 0 );
    mPainterPath.lineTo( width / 2.0, 0 );
  }
  else if ( symbolName == "triangle" )
  {
    mPainterPath.moveTo( 0, -height / 2.0 );
    mPainterPath.lineTo( -width / 2.0, height / 2.0 );
    mPainterPath.lineTo( width / 2.0, height / 2.0 );
    mPainterPath.lineTo( 0, -height / 2.0 );
  }
}
void QgsEllipseSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context )
{
  QgsExpression* outlineWidthExpression = expression( "outline_width" );
  QgsExpression* fillColorExpression = expression( "fill_color" );
  QgsExpression* outlineColorExpression = expression( "outline_color" );
  QgsExpression* widthExpression = expression( "width" );
  QgsExpression* heightExpression = expression( "height" );
  QgsExpression* symbolNameExpression = expression( "symbol_name" );
  QgsExpression* rotationExpression = expression( "rotation" );

  if ( outlineWidthExpression )
  {
    double width = outlineWidthExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
    width *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit );
    mPen.setWidthF( width );
  }
  if ( fillColorExpression )
  {
    QString colorString = fillColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
    mBrush.setColor( QColor( colorString ) );
  }
  if ( outlineColorExpression )
  {
    QString colorString = outlineColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
    mPen.setColor( QColor( colorString ) );
  }
  if ( widthExpression || heightExpression || symbolNameExpression )
  {
    QString symbolName =  mSymbolName;
    if ( symbolNameExpression )
    {
      symbolName = symbolNameExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
    }
    preparePath( symbolName, context, context.feature() );
  }

  //offset
  double offsetX = 0;
  double offsetY = 0;
  markerOffset( context, mSymbolWidth, mSymbolHeight, mSymbolWidthUnit, mSymbolHeightUnit, offsetX, offsetY );
  QPointF off( offsetX, offsetY );

  QPainter* p = context.renderContext().painter();
  if ( !p )
  {
    return;
  }

  //priority for rotation: 1. data defined symbol level, 2. symbol layer rotation (mAngle)
  double rotation = 0.0;
  if ( rotationExpression )
  {
    rotation = rotationExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
  }
  else if ( !qgsDoubleNear( mAngle, 0.0 ) )
  {
    rotation = mAngle;
  }
  if ( rotation )
    off = _rotatedOffset( off, rotation );

  QMatrix transform;
  transform.translate( point.x() + off.x(), point.y() + off.y() );
  if ( !qgsDoubleNear( rotation, 0.0 ) )
  {
    transform.rotate( rotation );
  }

  p->setPen( mPen );
  p->setBrush( mBrush );
  p->drawPath( transform.map( mPainterPath ) );
}