void QgsAttributeTypeLoadDialog::loadDataToValueMap()
{
  mValueMap.clear();
  int idx = keyComboBox->itemData( keyComboBox->currentIndex() ).toInt();
  int idx2 = valueComboBox->itemData( valueComboBox->currentIndex() ).toInt();
  QgsMapLayer* dataLayer = QgsMapLayerRegistry::instance()->mapLayer( layerComboBox->currentText() );
  QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer *>( dataLayer );
  if ( vLayer == NULL )
  {
    return;
  }

  QgsVectorDataProvider* dataProvider = vLayer->dataProvider();
  dataProvider->enableGeometrylessFeatures( true );

  QgsAttributeList attributeList = QgsAttributeList();
  attributeList.append( idx );
  attributeList.append( idx2 );
  vLayer->select( attributeList, QgsRectangle(), false );

  QgsFeature f;
  while ( vLayer->nextFeature( f ) )
  {
    QVariant val = f.attributeMap()[idx];
    if ( val.isValid() && !val.isNull() && !val.toString().isEmpty() )
    {
      mValueMap.insert( f.attributeMap()[idx2].toString(), val );
    }
  }
  dataProvider->enableGeometrylessFeatures( false );
}
void QgsAttributeTypeLoadDialog::createPreview( int fieldIndex, bool full )
{
  previewTableWidget->clearContents();

  for ( int i = previewTableWidget->rowCount() - 1; i > 0; i-- )
  {
    previewTableWidget->removeRow( i );
  }
  if ( layerComboBox->currentIndex() < 0 || fieldIndex < 0 )
  {
    //when nothing is selected there is no reason for preview
    return;
  }
  int idx = keyComboBox->itemData( keyComboBox->currentIndex() ).toInt();
  int idx2 = valueComboBox->itemData( valueComboBox->currentIndex() ).toInt();
  QgsMapLayer* dataLayer = QgsMapLayerRegistry::instance()->mapLayer( layerComboBox->currentText() );
  QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer *>( dataLayer );
  if ( vLayer == NULL )
  {
    return;
  }

  QgsVectorDataProvider* dataProvider = vLayer->dataProvider();
  dataProvider->enableGeometrylessFeatures( true );

  QgsAttributeList attributeList = QgsAttributeList();
  attributeList.append( idx );
  attributeList.append( idx2 );
  vLayer->select( attributeList, QgsRectangle(), false );

  QgsFeature f;
  QMap<QString, QVariant> valueMap;
  while ( vLayer->nextFeature( f ) )
  {
    QVariant val1 = f.attributeMap()[idx];
    QVariant val2 = f.attributeMap()[idx2];
    if ( val1.isValid() && !val1.isNull() && !val1.toString().isEmpty()
         && val2.isValid() && !val2.isNull() && !val2.toString().isEmpty() )
    {
      valueMap.insert( val1.toString(), val2.toString() );
    }
    if ( !full && valueMap.size() > 8 )
      break; //just first entries all on button
  }
  int row = 0;
  for ( QMap<QString, QVariant>::iterator mit = valueMap.begin(); mit != valueMap.end(); mit++, row++ )
  {
    previewTableWidget->insertRow( row );
    previewTableWidget->setItem( row, 0, new QTableWidgetItem( mit.value().toString() ) );
    previewTableWidget->setItem( row, 1, new QTableWidgetItem( mit.key() ) );
  }

  dataProvider->enableGeometrylessFeatures( false );
}
Beispiel #3
0
void QgsGeometryAnalyzer::bufferFeature( QgsFeature& f, int nProcessedFeatures, QgsVectorFileWriter* vfw, bool dissolve,
    QgsGeometry** dissolveGeometry, double bufferDistance, int bufferDistanceField )
{
  double currentBufferDistance;
  QgsGeometry* featureGeometry = f.geometry();
  QgsGeometry* tmpGeometry = 0;
  QgsGeometry* bufferGeometry = 0;

  if ( !featureGeometry )
  {
    return;
  }

  //create buffer
  if ( bufferDistanceField == -1 )
  {
    currentBufferDistance = bufferDistance;
  }
  else
  {
    currentBufferDistance = f.attributeMap()[bufferDistanceField].toDouble();
  }
  bufferGeometry = featureGeometry->buffer( currentBufferDistance, 5 );

  if ( dissolve )
  {
    if ( nProcessedFeatures == 0 )
    {
      *dissolveGeometry = bufferGeometry;
    }
    else
    {
      tmpGeometry = *dissolveGeometry;
      *dissolveGeometry = ( *dissolveGeometry )->combine( bufferGeometry );
      delete tmpGeometry;
      delete bufferGeometry;
    }
  }
  else //dissolve
  {
    QgsFeature newFeature;
    newFeature.setGeometry( bufferGeometry );
    newFeature.setAttributeMap( f.attributeMap() );

    //add it to vector file writer
    if ( vfw )
    {
      vfw->addFeature( newFeature );
    }
  }
}
Beispiel #4
0
bool QgsMapToolLabel::dataDefinedPosition( QgsVectorLayer* vlayer, int featureId, double& x, bool& xSuccess, double& y, bool& ySuccess, int& xCol, int& yCol ) const
{
    xSuccess = false;
    ySuccess = false;

    if ( !vlayer )
    {
        return false;
    }

    if ( mCurrentLabelPos.isDiagram )
    {
        if ( !diagramMoveable( vlayer, xCol, yCol ) )
        {
            return false;
        }
    }
    else if ( !labelMoveable( vlayer, xCol, yCol ) )
    {
        return false;
    }

    QgsFeature f;
    if ( !vlayer->featureAtId( featureId, f, false, true ) )
    {
        return false;
    }

    QgsAttributeMap attributes = f.attributeMap();
    x = attributes[xCol].toDouble( &xSuccess );
    y = attributes[yCol].toDouble( &ySuccess );

    return true;
}
Beispiel #5
0
void QgsMapToolLabel::currentAlignment( QString& hali, QString& vali )
{
    hali = "Left";
    vali = "Bottom";

    QgsFeature f;
    if ( !currentFeature( f ) )
    {
        return;
    }
    const QgsAttributeMap& featureAttributes = f.attributeMap();

    bool settingsOk;
    QgsPalLayerSettings& labelSettings = currentLabelSettings( &settingsOk );
    if ( settingsOk )
    {
        QMap< QgsPalLayerSettings::DataDefinedProperties, int > ddProperties = labelSettings.dataDefinedProperties;

        QMap< QgsPalLayerSettings::DataDefinedProperties, int >::const_iterator haliIter = ddProperties.find( QgsPalLayerSettings::Hali );
        if ( haliIter != ddProperties.constEnd() )
        {
            hali = featureAttributes[*haliIter].toString();
        }

        QMap< QgsPalLayerSettings::DataDefinedProperties, int >::const_iterator valiIter = ddProperties.find( QgsPalLayerSettings::Vali );
        if ( valiIter != ddProperties.constEnd() )
        {
            vali = featureAttributes[*valiIter].toString();
        }
    }
}
void QgsSearchQueryBuilder::getFieldValues( int limit )
{
  if ( !mLayer )
  {
    return;
  }
  // clear the values list
  mModelValues->clear();

  // determine the field type
  QString fieldName = mModelFields->data( lstFields->currentIndex() ).toString();
  int fieldIndex = mFieldMap[fieldName];
  QgsField field = mLayer->pendingFields()[fieldIndex];//provider->fields()[fieldIndex];
  bool numeric = ( field.type() == QVariant::Int || field.type() == QVariant::Double );

  QgsFeature feat;
  QString value;

  QgsAttributeList attrs;
  attrs.append( fieldIndex );

  mLayer->select( attrs, QgsRectangle(), false );

  lstValues->setCursor( Qt::WaitCursor );
  // Block for better performance
  mModelValues->blockSignals( true );
  lstValues->setUpdatesEnabled( false );

  /**MH: keep already inserted values in a set. Querying is much faster compared to QStandardItemModel::findItems*/
  QSet<QString> insertedValues;

  while ( mLayer->nextFeature( feat ) &&
          ( limit == 0 || mModelValues->rowCount() != limit ) )
  {
    const QgsAttributeMap& attributes = feat.attributeMap();
    value = attributes[fieldIndex].toString();

    if ( !numeric )
    {
      // put string in single quotes and escape single quotes in the string
      value = "'" + value.replace( "'", "''" ) + "'";
    }

    // add item only if it's not there already
    if ( !insertedValues.contains( value ) )
    {
      QStandardItem *myItem = new QStandardItem( value );
      myItem->setEditable( false );
      mModelValues->insertRow( mModelValues->rowCount(), myItem );
      insertedValues.insert( value );
    }
  }
  // Unblock for normal use
  mModelValues->blockSignals( false );
  lstValues->setUpdatesEnabled( true );
  // TODO: already sorted, signal emit to refresh model
  mModelValues->sort( 0 );
  lstValues->setCursor( Qt::ArrowCursor );
}
QVariant QgsFilter::propertyIndexValue( const QgsFeature& f ) const
{
    QgsAttributeMap featureAttributes = f.attributeMap();
    QgsAttributeMap::const_iterator f_it = featureAttributes.find( mPropertyIndex );
    if ( f_it == featureAttributes.constEnd() )
    {
        return QVariant();
    }
    return f_it.value();
}
Beispiel #8
0
void QgsFieldCalculator::getFieldValues( int limit )
{
    mValueListWidget->clear();

    if ( !mVectorLayer )
    {
        return;
    }

    QListWidgetItem* currentItem = mFieldsListWidget->currentItem();
    if ( !currentItem )
    {
        return;
    }

    QMap<QString, int>::const_iterator attIt = mFieldMap.find( currentItem->text() );
    if ( attIt == mFieldMap.constEnd() )
    {
        return;
    }

    int attributeIndex = attIt.value();
    QgsField field = mVectorLayer->pendingFields()[attributeIndex];
    bool numeric = ( field.type() == QVariant::Int || field.type() == QVariant::Double );

    QgsAttributeList attList;
    attList << attributeIndex;

    mVectorLayer->select( attList, QgsRectangle(), false );
    QgsFeature f;
    int resultCounter = 0;

    mValueListWidget->setUpdatesEnabled( false );
    mValueListWidget->blockSignals( true );
    QSet<QString> insertedValues;

    while ( mVectorLayer->nextFeature( f ) && ( limit == 0 || resultCounter != limit ) )
    {
        QString value = f.attributeMap()[attributeIndex].toString();
        if ( !numeric )
        {
            value = ( "'" + value + "'" );
        }
        //QList<QListWidgetItem *> existingItems = mValueListWidget->findItems(value, Qt::MatchExactly);
        //if(existingItems.isEmpty())
        if ( !insertedValues.contains( value ) )
        {
            mValueListWidget->addItem( value );
            insertedValues.insert( value );
            ++resultCounter;
        }
    }
    mValueListWidget->setUpdatesEnabled( true );
    mValueListWidget->blockSignals( false );
}
Beispiel #9
0
void QgsOverlayAnalyzer::intersectFeature( QgsFeature& f, QgsVectorFileWriter* vfw,
    QgsVectorLayer* vl, QgsSpatialIndex* index )
{
  QgsGeometry* featureGeometry = f.geometry();
  QgsGeometry* intersectGeometry = 0;
  QgsFeature overlayFeature;

  if ( !featureGeometry )
  {
    return;
  }

  QList<int> intersects;
  intersects = index->intersects( featureGeometry->boundingBox() );
  QList<int>::const_iterator it = intersects.constBegin();
  QgsFeature outFeature;
  for ( ; it != intersects.constEnd(); ++it )
  {
    if ( !vl->featureAtId( *it, overlayFeature, true, true ) )
    {
      continue;
    }

    if ( featureGeometry->intersects( overlayFeature.geometry() ) )
    {
      intersectGeometry = featureGeometry->intersection( overlayFeature.geometry() );

      outFeature.setGeometry( intersectGeometry );
      QgsAttributeMap attributeMapA = f.attributeMap();
      QgsAttributeMap attributeMapB = overlayFeature.attributeMap();
      combineAttributeMaps( attributeMapA, attributeMapB );
      outFeature.setAttributeMap( attributeMapA );

      //add it to vector file writer
      if ( vfw )
      {
        vfw->addFeature( outFeature );
      }
    }
  }
}
void QgsVectorDataProvider::uniqueValues( int index, QList<QVariant> &values, int limit )
{
  QgsFeature f;
  QgsAttributeList keys;
  keys.append( index );
  select( keys, QgsRectangle(), false );

  QSet<QString> set;
  values.clear();

  while ( nextFeature( f ) )
  {
    if ( !set.contains( f.attributeMap()[index].toString() ) )
    {
      values.append( f.attributeMap()[index] );
      set.insert( f.attributeMap()[index].toString() );
    }

    if ( limit >= 0 && values.size() >= limit )
      break;
  }
}
QString QgsPointDisplacementRenderer::getLabel( const QgsFeature& f )
{
  QString attribute;
  QgsAttributeMap attMap = f.attributeMap();
  if ( attMap.size() > 0 )
  {
    QgsAttributeMap::const_iterator valIt = attMap.find( mLabelIndex );
    if ( valIt != attMap.constEnd() )
    {
      attribute = valIt->toString();
    }
  }
  return attribute;
}
Beispiel #12
0
void QgsGeometryAnalyzer::addEventLayerFeature( QgsFeature& feature, QgsGeometry* geom, QgsGeometry* lineGeom, QgsVectorFileWriter* fileWriter, QgsFeatureList& memoryFeatures,
    int offsetField, double offsetScale, bool forceSingleType )
{
  if ( !geom )
  {
    return;
  }

  QList<QgsGeometry*> geomList;
  if ( forceSingleType )
  {
    geomList = geom->asGeometryCollection();
  }
  else
  {
    geomList.push_back( geom );
  }

  QList<QgsGeometry*>::iterator geomIt = geomList.begin();
  for ( ; geomIt != geomList.end(); ++geomIt )
  {
    //consider offset
    if ( offsetField >= 0 )
    {
      double offsetVal = feature.attributeMap()[offsetField].toDouble();
      offsetVal *= offsetScale;
      createOffsetGeometry( *geomIt, lineGeom, offsetVal );
    }

    feature.setGeometry( *geomIt );
    if ( fileWriter )
    {
      fileWriter->addFeature( feature );
    }
    else
    {
      memoryFeatures << feature;
    }
  }

  if ( forceSingleType )
  {
    delete geom;
  }
}
Beispiel #13
0
QString QgsLabel::fieldValue( int attr, QgsFeature &feature )
{
  if ( mLabelFieldIdx[attr] == -1 )
  {
    return QString();
  }

  const QgsAttributeMap& attrs = feature.attributeMap();
  QgsAttributeMap::const_iterator it = attrs.find( mLabelFieldIdx[attr] );

  if ( it != attrs.end() )
  {
    return it->toString();
  }
  else
  {
    return QString();
  }
}
int QgsDiagramRenderer::classificationValue( const QgsFeature& f, QVariant& value ) const
{
  //find out attribute value of the feature
  QgsAttributeMap featureAttributes = f.attributeMap();

  QgsAttributeMap::const_iterator iter;

  if ( value.type() == QVariant::String ) //string type
  {
    //we can only handle one classification field for strings
    if ( mClassificationAttributes.size() > 1 )
    {
      return 1;
    }

    iter = featureAttributes.find( mClassificationAttributes.first() );
    if ( iter == featureAttributes.constEnd() )
    {
      return 2;
    }
    value = iter.value();
  }
  else //numeric type
  {
    double currentValue;
    double totalValue = 0;

    QList<int>::const_iterator list_it = mClassificationAttributes.constBegin();
    for ( ; list_it != mClassificationAttributes.constEnd(); ++list_it )
    {
      QgsAttributeMap::const_iterator iter = featureAttributes.find( *list_it );
      if ( iter == featureAttributes.constEnd() )
      {
        continue;
      }
      currentValue = iter.value().toDouble();
      totalValue += currentValue;
    }
    value = QVariant( totalValue );
  }
  return 0;
}
Beispiel #15
0
QString QgsMapToolLabel::currentLabelText()
{
    QgsVectorLayer* vlayer = currentLayer();
    if ( !vlayer )
    {
        return "";
    }

    QString labelField = vlayer->customProperty( "labeling/fieldName" ).toString();
    if ( !labelField.isEmpty() )
    {
        int labelFieldId = vlayer->fieldNameIndex( labelField );
        QgsFeature f;
        if ( vlayer->featureAtId( mCurrentLabelPos.featureId, f, false, true ) )
        {
            return f.attributeMap()[labelFieldId].toString();
        }
    }
    return "";
}
bool QgsComposerAttributeTable::getFeatureAttributes( QList<QgsAttributeMap>& attributes )
{
  if ( !mVectorLayer )
  {
    return false;
  }
  attributes.clear();

  QgsRectangle selectionRect;
  if ( mComposerMap && mShowOnlyVisibleFeatures )
  {
    selectionRect = mComposerMap->extent();
  }

  if ( mDisplayAttributes.size() < 1 )
  {
    mVectorLayer->select( mVectorLayer->pendingAllAttributesList(), selectionRect, mShowOnlyVisibleFeatures, mShowOnlyVisibleFeatures );
  }
  else
  {
    mVectorLayer->select( mDisplayAttributes.toList(), selectionRect, mShowOnlyVisibleFeatures, mShowOnlyVisibleFeatures );
  }
  QgsFeature f;
  int counter = 0;
  while ( mVectorLayer->nextFeature( f ) && counter < mMaximumNumberOfFeatures )
  {
    attributes.push_back( f.attributeMap() );
    ++counter;
  }

  //sort the list, starting with the last attribute
  QgsComposerAttributeTableCompare c;
  for ( int i = mSortInformation.size() - 1; i >= 0; --i )
  {
    c.setSortColumn( mSortInformation.at( i ).first );
    c.setAscending( mSortInformation.at( i ).second );
    qStableSort( attributes.begin(), attributes.end(), c );
  }
  return true;
}
void QgsOfflineEditing::applyFeaturesAdded( QgsVectorLayer* offlineLayer, QgsVectorLayer* remoteLayer, sqlite3* db, int layerId )
{
  QString sql = QString( "SELECT \"fid\" FROM 'log_added_features' WHERE \"layer_id\" = %1" ).arg( layerId );
  QList<int> newFeatureIds = sqlQueryInts( db, sql );

  // get new features from offline layer
  QgsFeatureList features;
  for ( int i = 0; i < newFeatureIds.size(); i++ )
  {
    QgsFeature feature;
    if ( offlineLayer->featureAtId( newFeatureIds.at( i ), feature, true, true ) )
    {
      features << feature;
    }
  }

  // copy features to remote layer
  mProgressDialog->setupProgressBar( tr( "%v / %m features added" ), features.size() );

  int i = 1;
  for ( QgsFeatureList::iterator it = features.begin(); it != features.end(); ++it )
  {
    QgsFeature f = *it;

    // NOTE: Spatialite provider ignores position of geometry column
    // restore gap in QgsAttributeMap if geometry column is not last (WORKAROUND)
    QMap<int, int> attrLookup = attributeLookup( offlineLayer, remoteLayer );
    QgsAttributeMap newAttrMap;
    QgsAttributeMap attrMap = f.attributeMap();
    for ( QgsAttributeMap::const_iterator it = attrMap.begin(); it != attrMap.end(); ++it )
    {
      newAttrMap.insert( attrLookup[ it.key()], it.value() );
    }
    f.setAttributeMap( newAttrMap );

    remoteLayer->addFeature( f, false );

    mProgressDialog->setProgressValue( i++ );
  }
}
Beispiel #18
0
void QgsGeometryAnalyzer::simplifyFeature( QgsFeature& f, QgsVectorFileWriter* vfw, double tolerance )
{
  QgsGeometry* featureGeometry = f.geometry();
  QgsGeometry* tmpGeometry = 0;

  if ( !featureGeometry )
  {
    return;
  }
  // simplify feature
  tmpGeometry = featureGeometry->simplify( tolerance );

  QgsFeature newFeature;
  newFeature.setGeometry( tmpGeometry );
  newFeature.setAttributeMap( f.attributeMap() );

  //add it to vector file writer
  if ( vfw )
  {
    vfw->addFeature( newFeature );
  }
}
Beispiel #19
0
void QgsGeometryAnalyzer::centroidFeature( QgsFeature& f, QgsVectorFileWriter* vfw )
{
  QgsGeometry* featureGeometry = f.geometry();
  QgsGeometry* tmpGeometry = 0;

  if ( !featureGeometry )
  {
    return;
  }

  tmpGeometry = featureGeometry->centroid();

  QgsFeature newFeature;
  newFeature.setGeometry( tmpGeometry );
  newFeature.setAttributeMap( f.attributeMap() );

  //add it to vector file writer
  if ( vfw )
  {
    vfw->addFeature( newFeature );
  }
}
Beispiel #20
0
bool QgsMapToolLabel::dataDefinedRotation( QgsVectorLayer* vlayer, int featureId, double& rotation, bool& rotationSuccess, bool ignoreXY )
{
    rotationSuccess = false;
    if ( !vlayer )
    {
        return false;
    }

    int rotationCol;
    if ( !layerIsRotatable( vlayer, rotationCol ) )
    {
        return false;
    }

    QgsFeature f;
    if ( !vlayer->featureAtId( featureId, f, false, true ) )
    {
        return false;
    }

    QgsAttributeMap attributes = f.attributeMap();

    //test, if data defined x- and y- values are not null. Otherwise, the position is determined by PAL and the rotation cannot be fixed
    if ( !ignoreXY )
    {
        int xCol, yCol;
        double x, y;
        bool xSuccess, ySuccess;
        if ( !dataDefinedPosition( vlayer, featureId, x, xSuccess, y, ySuccess, xCol, yCol ) || !xSuccess || !ySuccess )
        {
            return false;
        }
    }

    rotation = attributes[rotationCol].toDouble( &rotationSuccess );
    return true;
}
Beispiel #21
0
bool QgsMapToolLabel::dataDefinedShowHide( QgsVectorLayer* vlayer, int featureId, int& show, bool& showSuccess, int& showCol )
{
    showSuccess = false;
    if ( !vlayer )
    {
        return false;
    }

    if ( !layerCanShowHide( vlayer, showCol ) )
    {
        return false;
    }

    QgsFeature f;
    if ( !vlayer->featureAtId( featureId, f, false, true ) )
    {
        return false;
    }

    QgsAttributeMap attributes = f.attributeMap();

    show = attributes[showCol].toInt( &showSuccess );
    return true;
}
Beispiel #22
0
void QgsPalLabeling::registerDiagramFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context )
{
  //get diagram layer settings, diagram renderer
  QHash<QgsVectorLayer*, QgsDiagramLayerSettings>::iterator layerIt = mActiveDiagramLayers.find( layer );
  if ( layerIt == mActiveDiagramLayers.constEnd() )
  {
    return;
  }

  //convert geom to geos
  QgsGeometry* geom = feat.geometry();

  if ( layerIt.value().ct && !willUseLayer( layer ) ) // reproject the geometry if feature not already transformed for labeling
  {
    geom->transform( *( layerIt.value().ct ) );
  }

  GEOSGeometry* geos_geom = geom->asGeos();
  if ( geos_geom == 0 )
  {
    return; // invalid geometry
  }

  //create PALGeometry with diagram = true
  QgsPalGeometry* lbl = new QgsPalGeometry( feat.id(), "", GEOSGeom_clone( geos_geom ) );
  lbl->setIsDiagram( true );

  // record the created geometry - it will be deleted at the end.
  layerIt.value().geometries.append( lbl );

  double diagramWidth = 0;
  double diagramHeight = 0;
  QgsDiagramRendererV2* dr = layerIt.value().renderer;
  if ( dr )
  {
    QSizeF diagSize = dr->sizeMapUnits( feat.attributeMap(), context );
    if ( diagSize.isValid() )
    {
      diagramWidth = diagSize.width();
      diagramHeight = diagSize.height();
    }

    //append the diagram attributes to lbl
    QList<int> diagramAttrib = dr->diagramAttributes();
    QList<int>::const_iterator diagAttIt = diagramAttrib.constBegin();
    for ( ; diagAttIt != diagramAttrib.constEnd(); ++diagAttIt )
    {
      lbl->addDiagramAttribute( *diagAttIt, feat.attributeMap()[*diagAttIt] );
    }
  }

  // register feature to the layer
  int ddColX = layerIt.value().xPosColumn;
  int ddColY = layerIt.value().yPosColumn;
  double ddPosX = 0.0;
  double ddPosY = 0.0;
  bool ddPos = ( ddColX >= 0 && ddColY >= 0 );
  if ( ddPos )
  {
    bool posXOk, posYOk;
    //data defined diagram position is always centered
    ddPosX = feat.attributeMap()[ddColX].toDouble( &posXOk ) - diagramWidth / 2.0;
    ddPosY = feat.attributeMap()[ddColY].toDouble( &posYOk ) - diagramHeight / 2.0;
    if ( !posXOk || !posYOk )
    {
      ddPos = false;
    }
    else
    {
      const QgsCoordinateTransform* ct = layerIt.value().ct;
      if ( ct )
      {
        double z = 0;
        ct->transformInPlace( ddPosX, ddPosY, z );
      }
    }
  }

  try
  {
    if ( !layerIt.value().palLayer->registerFeature( lbl->strId(), lbl, diagramWidth, diagramHeight, "", ddPosX, ddPosY, ddPos ) )
    {
      return;
    }
  }
  catch ( std::exception &e )
  {
    Q_UNUSED( e );
    QgsDebugMsg( QString( "Ignoring feature %1 due PAL exception: " ).arg( feat.id() ) + QString::fromLatin1( e.what() ) );
    return;
  }

  pal::Feature* palFeat = layerIt.value().palLayer->getFeature( lbl->strId() );
  QgsPoint ptZero = layerIt.value().xform->toMapCoordinates( 0, 0 );
  QgsPoint ptOne = layerIt.value().xform->toMapCoordinates( 1, 0 );
  palFeat->setDistLabel( qAbs( ptOne.x() - ptZero.x() ) * layerIt.value().dist );
}
QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value, QMap<int, QWidget*> &proxyWidgets )
{
  if ( !vl )
    return 0;

  QWidget *myWidget = 0;
  QgsVectorLayer::EditType editType = vl->editType( idx );
  const QgsField &field = vl->pendingFields()[idx];
  QVariant::Type myFieldType = field.type();

  bool synchronized = false;

  switch ( editType )
  {
    case QgsVectorLayer::UniqueValues:
    {
      QList<QVariant> values;
      vl->dataProvider()->uniqueValues( idx, values );

      QComboBox *cb = comboBox( editor, parent );
      if ( cb )
      {
        cb->setEditable( false );

        for ( QList<QVariant>::iterator it = values.begin(); it != values.end(); it++ )
          cb->addItem( it->toString(), it->toString() );

        myWidget = cb;
      }

    }
    break;

    case QgsVectorLayer::Enumeration:
    {
      QStringList enumValues;
      vl->dataProvider()->enumValues( idx, enumValues );

      QComboBox *cb = comboBox( editor, parent );
      if ( cb )
      {
        QStringList::const_iterator s_it = enumValues.constBegin();
        for ( ; s_it != enumValues.constEnd(); ++s_it )
        {
          cb->addItem( *s_it, *s_it );
        }

        myWidget = cb;
      }
    }
    break;

    case QgsVectorLayer::ValueMap:
    {
      const QMap<QString, QVariant> &map = vl->valueMap( idx );

      QComboBox *cb = comboBox( editor, parent );
      if ( cb )
      {
        for ( QMap<QString, QVariant>::const_iterator it = map.begin(); it != map.end(); it++ )
        {
          cb->addItem( it.key(), it.value() );
        }

        myWidget = cb;
      }
    }
    break;

    case QgsVectorLayer::ValueRelation:
    {
      const QgsVectorLayer::ValueRelationData &data = vl->valueRelation( idx );

      QgsVectorLayer *layer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( data.mLayer ) );
      QMap< QString, QString > map;

      int fi = -1;
      if ( layer )
      {
        int ki = layer->fieldNameIndex( data.mOrderByValue ? data.mValue : data.mKey );
        int vi = layer->fieldNameIndex( data.mOrderByValue ? data.mKey : data.mValue );

        if ( !data.mFilterAttributeColumn.isNull() )
          fi = layer->fieldNameIndex( data.mFilterAttributeColumn );

        if ( ki >= 0 && vi >= 0 )
        {
          QgsAttributeList attributes;
          attributes << ki;
          attributes << vi;
          if ( fi >= 0 )
            attributes << fi;
          layer->select( attributes, QgsRectangle(), false );
          QgsFeature f;
          while ( layer->nextFeature( f ) )
          {
            if ( fi >= 0 && f.attributeMap()[ fi ].toString() != data.mFilterAttributeValue )
              continue;

            map.insert( f.attributeMap()[ ki ].toString(), f.attributeMap()[ vi ].toString() );
          }
        }
      }

      if ( !data.mAllowMulti )
      {
        QComboBox *cb = comboBox( editor, parent );
        if ( cb )
        {
          if ( data.mAllowNull )
          {
            QSettings settings;
            cb->addItem( tr( "(no selection)" ), settings.value( "qgis/nullValue", "NULL" ).toString() );
          }

          for ( QMap< QString, QString >::const_iterator it = map.begin(); it != map.end(); it++ )
          {
            if ( data.mOrderByValue )
              cb->addItem( it.key(), it.value() );
            else
              cb->addItem( it.value(), it.key() );
          }

          myWidget = cb;
        }
      }
      else
      {
        QListWidget *lw = listWidget( editor, parent );
        if ( lw )
        {
          QStringList checkList = value.toString().remove( QChar( '{' ) ).remove( QChar( '}' ) ).split( "," );

          for ( QMap< QString, QString >::const_iterator it = map.begin(); it != map.end(); it++ )
          {
            QListWidgetItem *item;
            if ( data.mOrderByValue )
            {
              item = new QListWidgetItem( it.key() );
              item->setData( Qt::UserRole, it.value() );
              item->setCheckState( checkList.contains( it.value() ) ? Qt::Checked : Qt::Unchecked );
            }
            else
            {
              item = new QListWidgetItem( it.value() );
              item->setData( Qt::UserRole, it.key() );
              item->setCheckState( checkList.contains( it.key() ) ? Qt::Checked : Qt::Unchecked );
            }
            lw->addItem( item );
          }

          myWidget = lw;
        }
      }
    }
    break;

    case QgsVectorLayer::Classification:
    {
      QMap<QString, QString> classes;

      const QgsUniqueValueRenderer *uvr = dynamic_cast<const QgsUniqueValueRenderer *>( vl->renderer() );
      if ( uvr )
      {
        const QList<QgsSymbol *> symbols = uvr->symbols();

        for ( int i = 0; i < symbols.size(); i++ )
        {
          QString label = symbols[i]->label();
          QString name = symbols[i]->lowerValue();

          if ( label == "" )
            label = name;

          classes.insert( name, label );
        }
      }

      const QgsCategorizedSymbolRendererV2 *csr = dynamic_cast<const QgsCategorizedSymbolRendererV2 *>( vl->rendererV2() );
      if ( csr )
      {
        const QgsCategoryList &categories = (( QgsCategorizedSymbolRendererV2 * )csr )->categories(); // FIXME: QgsCategorizedSymbolRendererV2::categories() should be const
        for ( int i = 0; i < categories.size(); i++ )
        {
          QString label = categories[i].label();
          QString value = categories[i].value().toString();
          if ( label.isEmpty() )
            label = value;
          classes.insert( value, label );
        }
      }

      QComboBox *cb = comboBox( editor, parent );
      if ( cb )
      {
        for ( QMap<QString, QString>::const_iterator it = classes.begin(); it != classes.end(); it++ )
        {
          cb->addItem( it.value(), it.key() );
        }

        myWidget = cb;
      }
    }
    break;

    case QgsVectorLayer::DialRange:
    case QgsVectorLayer::SliderRange:
    case QgsVectorLayer::EditRange:
    {
      if ( myFieldType == QVariant::Int )
      {
        int min = vl->range( idx ).mMin.toInt();
        int max = vl->range( idx ).mMax.toInt();
        int step = vl->range( idx ).mStep.toInt();

        if ( editType == QgsVectorLayer::EditRange )
        {
          QSpinBox *sb = 0;

          if ( editor )
            sb = qobject_cast<QSpinBox *>( editor );
          else
            sb = new QSpinBox( parent );

          if ( sb )
          {
            sb->setRange( min, max );
            sb->setSingleStep( step );

            myWidget = sb;
          }
        }
        else
        {
          QAbstractSlider *sl = 0;

          if ( editor )
          {
            sl = qobject_cast<QAbstractSlider*>( editor );
          }
          else if ( editType == QgsVectorLayer::DialRange )
          {
            sl = new QDial( parent );
          }
          else
          {
            sl = new QSlider( Qt::Horizontal, parent );
          }

          if ( sl )
          {
            sl->setRange( min, max );
            sl->setSingleStep( step );

            myWidget = sl;
          }
        }
        break;
      }
      else if ( myFieldType == QVariant::Double )
      {
        QDoubleSpinBox *dsb = 0;
        if ( editor )
          dsb = qobject_cast<QDoubleSpinBox*>( editor );
        else
          dsb = new QDoubleSpinBox( parent );

        if ( dsb )
        {
          double min = vl->range( idx ).mMin.toDouble();
          double max = vl->range( idx ).mMax.toDouble();
          double step = vl->range( idx ).mStep.toDouble();

          dsb->setRange( min, max );
          dsb->setSingleStep( step );

          myWidget = dsb;
        }
        break;
      }
    }

    case QgsVectorLayer::CheckBox:
    {
      QCheckBox *cb = 0;
      if ( editor )
        cb = qobject_cast<QCheckBox*>( editor );
      else
        cb = new QCheckBox( parent );

      if ( cb )
      {
        myWidget = cb;
        break;
      }
    }

    // fall-through

    case QgsVectorLayer::LineEdit:
    case QgsVectorLayer::TextEdit:
    case QgsVectorLayer::UuidGenerator:
    case QgsVectorLayer::UniqueValuesEditable:
    case QgsVectorLayer::Immutable:
    {
      QLineEdit *le = 0;
      QTextEdit *te = 0;
      QPlainTextEdit *pte = 0;
      QComboBox * cb = 0;

      if ( editor )
      {
        le = qobject_cast<QLineEdit *>( editor );
        te = qobject_cast<QTextEdit *>( editor );
        pte = qobject_cast<QPlainTextEdit *>( editor );
        cb = qobject_cast<QComboBox *>( editor );
      }
      else if ( editType == QgsVectorLayer::TextEdit )
      {
        pte = new QPlainTextEdit( parent );
      }
      else
      {
        le = new QLineEdit( parent );
      }

      if ( le )
      {
        if ( editType == QgsVectorLayer::UniqueValuesEditable )
        {
          QList<QVariant> values;
          vl->dataProvider()->uniqueValues( idx, values );

          QStringList svalues;
          for ( QList<QVariant>::const_iterator it = values.begin(); it != values.end(); it++ )
            svalues << it->toString();

          QCompleter *c = new QCompleter( svalues );
          c->setCompletionMode( QCompleter::PopupCompletion );
          le->setCompleter( c );
        }

        if ( editType == QgsVectorLayer::UuidGenerator )
        {
          le->setReadOnly( true );
        }

        le->setValidator( new QgsFieldValidator( le, field ) );

        myWidget = le;
      }

      if ( te )
      {
        te->setAcceptRichText( true );
        myWidget = te;
      }

      if ( pte )
      {
        myWidget = pte;
      }

      if ( cb )
      {
        myWidget = cb;
      }

      if ( myWidget )
      {
        myWidget->setDisabled( editType == QgsVectorLayer::Immutable );

        QgsStringRelay* relay = NULL;

        QMap<int, QWidget*>::const_iterator it = proxyWidgets.find( idx );
        if ( it != proxyWidgets.end() )
        {
          QObject* obj = qvariant_cast<QObject*>( (*it)->property( "QgisAttrEditProxy" ) );
          relay = qobject_cast<QgsStringRelay*>( obj );
        }
        else
        {
          relay = new QgsStringRelay( myWidget );
        }

        if ( cb && cb->isEditable() )
        {
          synchronized =  connect( relay, SIGNAL( textChanged( QString ) ), myWidget, SLOT( setEditText( QString ) ) );
          synchronized &= connect( myWidget, SIGNAL( editTextChanged( QString ) ), relay, SLOT( changeText( QString ) ) );
        }
        else
        {
          synchronized =  connect( relay, SIGNAL( textChanged( QString ) ), myWidget, SLOT( setText( QString ) ) );
          synchronized &= connect( myWidget, SIGNAL( textChanged( QString ) ), relay, SLOT( changeText( QString ) ) );
        }

        if ( !cb || cb->isEditable() )
        {
          myWidget->setProperty( "QgisAttrEditProxy", QVariant( QMetaType::QObjectStar, &relay ) );
        }
      }
    }
    break;

    case QgsVectorLayer::Hidden:
      myWidget = 0;
      break;

    case QgsVectorLayer::FileName:
    case QgsVectorLayer::Calendar:
    {
      QPushButton *pb = 0;
      QLineEdit *le = qobject_cast<QLineEdit *>( editor );
      if ( le )
      {
        if ( le )
          myWidget = le;

        if ( editor->parent() )
        {
          pb = editor->parent()->findChild<QPushButton *>();
        }
      }
      else
      {
        le = new QLineEdit();

        pb = new QPushButton( tr( "..." ) );

        QHBoxLayout *hbl = new QHBoxLayout();
        hbl->addWidget( le );
        hbl->addWidget( pb );

        myWidget = new QWidget( parent );
        myWidget->setBackgroundRole( QPalette::Window );
        myWidget->setAutoFillBackground( true );
        myWidget->setLayout( hbl );
      }

      if ( pb )
      {
        if ( editType == QgsVectorLayer::FileName )
          connect( pb, SIGNAL( clicked() ), new QgsAttributeEditor( pb ), SLOT( selectFileName() ) );
        if ( editType == QgsVectorLayer::Calendar )
          connect( pb, SIGNAL( clicked() ), new QgsAttributeEditor( pb ), SLOT( selectDate() ) );
      }
    }
    break;
  }

  QMap<int, QWidget*>::const_iterator it = proxyWidgets.find( idx );
  if ( it != proxyWidgets.end() )
  {
    if ( !synchronized )
    {
      myWidget->setEnabled( false );
    }
  }
  else
  {
    proxyWidgets.insert( idx, myWidget );
  }

  setValue( myWidget, vl, idx, value );

  return myWidget;
}
QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
  QgsVectorLayer* vlayer,
  QString attrName,
  int classes,
  Mode mode,
  QgsSymbolV2* symbol,
  QgsVectorColorRampV2* ramp )
{
  if ( classes < 1 )
    return NULL;

  int attrNum = vlayer->fieldNameIndex( attrName );

  double minimum = vlayer->minimumValue( attrNum ).toDouble();
  double maximum = vlayer->maximumValue( attrNum ).toDouble();
  QgsDebugMsg( QString( "min %1 // max %2" ).arg( minimum ).arg( maximum ) );

  QList<double> breaks;
  QList<int> labels;
  if ( mode == EqualInterval )
  {
    breaks = _calcEqualIntervalBreaks( minimum, maximum, classes );
  }
  else if ( mode == Pretty )
  {
    breaks = _calcPrettyBreaks( minimum, maximum, classes );
  }
  else if ( mode == Quantile || mode == Jenks || mode == StdDev )
  {
    // get values from layer
    QList<double> values;
    QgsFeature f;
    QgsAttributeList lst;
    lst.append( attrNum );
    vlayer->select( lst, QgsRectangle(), false );
    while ( vlayer->nextFeature( f ) )
      values.append( f.attributeMap()[attrNum].toDouble() );
    // calculate the breaks
    if ( mode == Quantile )
    {
      breaks = _calcQuantileBreaks( values, classes );
    }
    else if ( mode == Jenks )
    {
      breaks = _calcJenksBreaks( values, classes, minimum, maximum );
    }
    else if ( mode == StdDev )
    {
      breaks = _calcStdDevBreaks( values, classes, labels );
    }
  }
  else
  {
    Q_ASSERT( false );
  }

  QgsRangeList ranges;
  double lower, upper = minimum;
  QString label;

  // "breaks" list contains all values at class breaks plus maximum as last break
  int i = 0;
  for ( QList<double>::iterator it = breaks.begin(); it != breaks.end(); ++it, ++i )
  {
    lower = upper; // upper border from last interval
    upper = *it;
    if ( mode == StdDev )
    {
      if ( i == 0 )
      {
        label = "< " + QString::number( labels[i], 'i', 0 ) + " Std Dev";
      }
      else if ( i == labels.count() - 1 )
      {
        label = ">= " + QString::number( labels[i-1], 'i', 0 ) + " Std Dev";
      }
      else
      {
        label = QString::number( labels[i-1], 'i', 0 ) + " Std Dev" + " - " + QString::number( labels[i], 'i', 0 ) + " Std Dev";
      }
    }
    else
    {
      label = QString::number( lower, 'f', 4 ) + " - " + QString::number( upper, 'f', 4 );
    }

    QgsSymbolV2* newSymbol = symbol->clone();
    double colorValue = ( breaks.count() > 1 ? ( double ) i / ( breaks.count() - 1 ) : 0 );
    newSymbol->setColor( ramp->color( colorValue ) ); // color from (0 / cl-1) to (cl-1 / cl-1)

    ranges.append( QgsRendererRangeV2( lower, upper, newSymbol, label ) );
  }

  QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( attrName, ranges );
  r->setSourceSymbol( symbol->clone() );
  r->setSourceColorRamp( ramp->clone() );
  r->setMode( mode );
  return r;
}
Beispiel #25
0
int QgsInterpolator::cacheBaseData()
{
  if ( mLayerData.size() < 1 )
  {
    return 0;
  }

  //reserve initial memory for 100000 vertices
  mCachedBaseData.clear();
  mCachedBaseData.reserve( 100000 );

  QList<LayerData>::iterator v_it = mLayerData.begin();

  for ( ; v_it != mLayerData.end(); ++v_it )
  {
    if ( v_it->vectorLayer == 0 )
    {
      continue;
    }

    QgsVectorDataProvider* provider = v_it->vectorLayer->dataProvider();
    if ( !provider )
    {
      return 2;
    }

    QgsAttributeList attList;
    if ( !v_it->zCoordInterpolation )
    {
      attList.push_back( v_it->interpolationAttribute );
    }

    provider->select( attList );

    QgsFeature theFeature;
    double attributeValue = 0.0;
    bool attributeConversionOk = false;

    while ( provider->nextFeature( theFeature ) )
    {
      if ( !v_it->zCoordInterpolation )
      {
        QgsAttributeMap attMap = theFeature.attributeMap();
        QgsAttributeMap::const_iterator att_it = attMap.find( v_it->interpolationAttribute );
        if ( att_it == attMap.end() ) //attribute not found, something must be wrong (e.g. NULL value)
        {
          continue;
        }
        attributeValue = att_it.value().toDouble( &attributeConversionOk );
        if ( !attributeConversionOk || qIsNaN( attributeValue ) ) //don't consider vertices with attributes like 'nan' for the interpolation
        {
          continue;
        }
      }

      if ( addVerticesToCache( theFeature.geometry(), v_it->zCoordInterpolation, attributeValue ) != 0 )
      {
        return 3;
      }
    }
  }

  return 0;
}
void QgsGraduatedSymbolRenderer::renderFeature( QPainter * p, QgsFeature & f, QImage* img, bool selected, double widthScale, double rasterScaleFactor )
{
  QgsSymbol* theSymbol = symbolForFeature( &f );
  if ( !theSymbol )
  {
    if ( img && mGeometryType == QGis::Point )
    {
      img->fill( 0 );
    }
    else if ( mGeometryType != QGis::Point )
    {
      p->setPen( Qt::NoPen );
      p->setBrush( Qt::NoBrush );
    }
    return;
  }

  //set the qpen and qpainter to the right values
  // Point
  if ( img && mGeometryType == QGis::Point )
  {
    double fieldScale = 1.0;
    double rotation = 0.0;

    if ( theSymbol->scaleClassificationField() >= 0 )
    {
      //first find out the value for the scale classification attribute
      const QgsAttributeMap& attrs = f.attributeMap();
      fieldScale = sqrt( fabs( attrs[theSymbol->scaleClassificationField()].toDouble() ) );
      QgsDebugMsg( QString( "Feature has field scale factor %1" ).arg( fieldScale ) );
    }
    if ( theSymbol->rotationClassificationField() >= 0 )
    {
      const QgsAttributeMap& attrs = f.attributeMap();
      rotation = attrs[theSymbol->rotationClassificationField()].toDouble();
      QgsDebugMsg( QString( "Feature has rotation factor %1" ).arg( rotation ) );
    }
    *img = theSymbol->getPointSymbolAsImage( widthScale, selected, mSelectionColor, fieldScale, rotation, rasterScaleFactor );
  }

  // Line, polygon
  if ( mGeometryType != QGis::Point )
  {
    if ( !selected )
    {
      QPen pen = theSymbol->pen();
      pen.setWidthF( widthScale * pen.widthF() );
      p->setPen( pen );

      if ( mGeometryType == QGis::Polygon )
      {
        QBrush brush = theSymbol->brush();
        scaleBrush( brush, rasterScaleFactor ); //scale brush content for printout
        p->setBrush( brush );
      }
    }
    else
    {
      QPen pen = theSymbol->pen();
      pen.setWidthF( widthScale * pen.widthF() );

      if ( mGeometryType == QGis::Polygon )
      {
        QBrush brush = theSymbol->brush();
        scaleBrush( brush, rasterScaleFactor ); //scale brush content for printout
        brush.setColor( mSelectionColor );
        p->setBrush( brush );
      }
      else //dont draw outlines in selection colour for polys otherwise they appear merged
      {
        pen.setColor( mSelectionColor );
      }
      p->setPen( pen );
    }
  }
}
void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder, const QVector< QgsPoint >& additionalPoints,
    QVector< QgsPoint >& tiedPoint ) const
{
  QgsVectorLayer *vl = myLayer();

  if ( vl == NULL )
    return;

  int featureCount = ( int ) vl->featureCount() * 2;
  int step = 0;

  QgsCoordinateTransform ct;
  QgsDistanceArea da;
  ct.setSourceCrs( vl->crs() );

  if ( builder->coordinateTransformEnabled() )
  {
    ct.setDestCRS( builder->destinationCrs() );
    da.setProjectionsEnabled( true );
    //
    //da.setSourceCrs( builder->destinationCrs().srsid() );
    //
  }
  else
  {
    ct.setDestCRS( vl->crs() );
    da.setProjectionsEnabled( false );
  }

  tiedPoint = QVector< QgsPoint >( additionalPoints.size(), QgsPoint( 0.0, 0.0 ) );
  TiePointInfo tmpInfo;
  tmpInfo.mLength = infinity();

  QVector< TiePointInfo > pointLengthMap( additionalPoints.size(), tmpInfo );
  QVector< TiePointInfo >::iterator pointLengthIt;

  // begin: tie points to the graph
  QgsAttributeList la;
  vl->select( la );
  QgsFeature feature;
  while ( vl->nextFeature( feature ) )
  {
    QgsMultiPolyline mpl;
    if ( feature.geometry()->wkbType() == QGis::WKBLineString )
    {
      mpl.push_back( feature.geometry()->asPolyline() );
    }else if ( feature.geometry()->wkbType() == QGis::WKBMultiLineString )
    {
      mpl = feature.geometry()->asMultiPolyline();
    }

    QgsMultiPolyline::iterator mplIt;
    for ( mplIt = mpl.begin(); mplIt != mpl.end(); ++mplIt )
    {
      QgsPoint pt1, pt2;
      bool isFirstPoint = true;
      QgsPolyline::iterator pointIt;
      for ( pointIt = mplIt->begin(); pointIt != mplIt->end(); ++pointIt )
      {
        pt2 = builder->addVertex( ct.transform( *pointIt ) );
        if ( !isFirstPoint )
        {
          int i = 0;
          for ( i = 0; i != additionalPoints.size(); ++i )
          {
            TiePointInfo info;
            if ( pt1 == pt2 )
            {
              info.mLength = additionalPoints[ i ].sqrDist( pt1 );
              info.mTiedPoint = pt1;
            }
            else
            {
              info.mLength = additionalPoints[ i ].sqrDistToSegment( pt1.x(), pt1.y(), pt2.x(), pt2.y(), info.mTiedPoint );
            }
            if ( pointLengthMap[ i ].mLength > info.mLength )
            {
              info.mTiedPoint = builder->addVertex( info.mTiedPoint );
              info.mFirstPoint = pt1;
              info.mLastPoint = pt2;

              pointLengthMap[ i ] = info;
              tiedPoint[ i ] = info.mTiedPoint;
            }
          }
        }
        pt1 = pt2;
        isFirstPoint = false;
      }
    }
    emit buildProgress( ++step, featureCount );
  }
  // end: tie points to graph

  if ( mDirectionFieldId != -1 )
  {
    la.push_back( mDirectionFieldId );
  }
  if ( mSpeedFieldId != -1 )
  {
    la.push_back( mSpeedFieldId );
  }

  SpeedUnit su = SpeedUnit::byName( mSpeedUnitName );

  // begin graph construction
  vl->select( la );
  while ( vl->nextFeature( feature ) )
  {
    QgsAttributeMap attr = feature.attributeMap();
    int directionType = mDefaultDirection;
    QgsAttributeMap::const_iterator it;
    // What direction have feature?
    for ( it = attr.constBegin(); it != attr.constEnd(); ++it )
    {
      if ( it.key() != mDirectionFieldId )
      {
        continue;
      }
      QString str = it.value().toString();
      if ( str == mBothDirectionValue )
      {
        directionType = 3;
      }
      else if ( str == mDirectDirectionValue )
      {
        directionType = 1;
      }
      else if ( str == mReverseDirectionValue )
      {
        directionType = 2;
      }
    }
    // What speed have feature?
    double speed = 0.0;
    for ( it = attr.constBegin(); it != attr.constEnd(); ++it )
    {
      if ( it.key() != mSpeedFieldId )
      {
        continue;
      }
      speed = it.value().toDouble();
    }
    if ( speed <= 0.0 )
    {
      speed = mDefaultSpeed;
    }

    // begin features segments and add arc to the Graph;
    QgsMultiPolyline mpl;
    if ( feature.geometry()->wkbType() == QGis::WKBLineString )
    {
      mpl.push_back( feature.geometry()->asPolyline() );
    }else if ( feature.geometry()->wkbType() == QGis::WKBMultiLineString )
    {
      mpl = feature.geometry()->asMultiPolyline();
    }
    QgsMultiPolyline::iterator mplIt;
    for ( mplIt = mpl.begin(); mplIt != mpl.end(); ++mplIt )
    {
      QgsPoint pt1, pt2;
      bool isFirstPoint = true;
      QgsPolyline::iterator pointIt;
      for ( pointIt = mplIt->begin(); pointIt != mplIt->end(); ++pointIt )
      {
        pt2 = builder->addVertex( ct.transform( *pointIt ) );

        std::map< double, QgsPoint > pointsOnArc;
        pointsOnArc[ 0.0 ] = pt1;
        pointsOnArc[ pt1.sqrDist( pt2 )] = pt2;

        for ( pointLengthIt = pointLengthMap.begin(); pointLengthIt != pointLengthMap.end(); ++pointLengthIt )
        {
          if ( pointLengthIt->mFirstPoint == pt1 && pointLengthIt->mLastPoint == pt2 )
          {
            QgsPoint tiedPoint = pointLengthIt->mTiedPoint;
            pointsOnArc[ pt1.sqrDist( tiedPoint )] = tiedPoint;
          }
        }

        if ( !isFirstPoint )
        {
          std::map< double, QgsPoint >::iterator pointsIt;
          QgsPoint pt1;
          QgsPoint pt2;
          bool isFirstPoint = true;
          for ( pointsIt = pointsOnArc.begin(); pointsIt != pointsOnArc.end(); ++pointsIt )
          {
            pt2 = pointsIt->second;
            if ( !isFirstPoint )
            {
              double cost = da.measureLine( pt1, pt2 );
              if ( directionType == 1 ||
                   directionType == 3 )
              {
                builder->addArc( pt1, pt2, cost, speed*su.multipler(), feature.id() );
              }
              if ( directionType == 2 ||
                   directionType == 3 )
              {
                builder->addArc( pt2, pt1, cost, speed*su.multipler(), feature.id() );
              }
            }
            pt1 = pt2;
            isFirstPoint = false;
          }
        } // if ( !isFirstPoint )
        pt1 = pt2;
        isFirstPoint = false;
      }
    } // for (it = pl.begin(); it != pl.end(); ++it)
    emit buildProgress( ++step, featureCount );
  } // while( vl->nextFeature(feature) )
} // makeGraph( RgGraphBuilder *builder, const QgsRectangle& rt )
void QgsLabelPropertyDialog::init( const QString& layerId, int featureId )
{
  if ( !mMapRenderer )
  {
    return;
  }

  //get feature attributes
  QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerId ) );
  if ( !vlayer )
  {
    return;
  }

  QgsFeature f;
  if ( !vlayer->featureAtId( featureId, f, false, true ) )
  {
    return;
  }
  const QgsAttributeMap& attributeValues = f.attributeMap();

  //get layerproperties. Problem: only for pallabeling...
  QgsPalLabeling* lbl = dynamic_cast<QgsPalLabeling*>( mMapRenderer->labelingEngine() );
  if ( !lbl )
  {
    return;
  }

  blockElementSignals( true );

  //get label field and fill line edit
  QString labelFieldName = vlayer->customProperty( "labeling/fieldName" ).toString();
  if ( !labelFieldName.isEmpty() )
  {
    mCurrentLabelField = vlayer->fieldNameIndex( labelFieldName );
    mLabelTextLineEdit->setText( attributeValues[mCurrentLabelField].toString() );
    const QgsFieldMap& layerFields = vlayer->pendingFields();
    switch ( layerFields[mCurrentLabelField].type() )
    {
      case QVariant::Double:
        mLabelTextLineEdit->setValidator( new QDoubleValidator( this ) );
        break;
      case QVariant::Int:
      case QVariant::UInt:
      case QVariant::LongLong:
        mLabelTextLineEdit->setValidator( new QIntValidator( this ) );
        break;
      default:
        break;
    }
  }

  //get attributes of the feature and fill data defined values
  QgsPalLayerSettings& layerSettings = lbl->layer( layerId );
  mLabelFont = layerSettings.textFont;

  //set all the gui elements to the default values
  mFontSizeSpinBox->setValue( layerSettings.textFont.pointSizeF() );
  mBufferColorButton->setColor( layerSettings.textColor );
  mLabelDistanceSpinBox->setValue( layerSettings.dist );
  mBufferSizeSpinBox->setValue( layerSettings.bufferSize );
  mMinScaleSpinBox->setValue( layerSettings.scaleMin );
  mMaxScaleSpinBox->setValue( layerSettings.scaleMax );
  mHaliComboBox->setCurrentIndex( mHaliComboBox->findText( "Left" ) );
  mValiComboBox->setCurrentIndex( mValiComboBox->findText( "Bottom" ) );

  disableGuiElements();

  mDataDefinedProperties = layerSettings.dataDefinedProperties;
  QMap< QgsPalLayerSettings::DataDefinedProperties, int >::const_iterator propIt = mDataDefinedProperties.constBegin();

  for ( ; propIt != mDataDefinedProperties.constEnd(); ++propIt )
  {
    switch ( propIt.key() )
    {
      case QgsPalLayerSettings::Show:
        mShowLabelChkbx->setEnabled( true );
        mShowLabelChkbx->setChecked( attributeValues[propIt.value()].toInt() != 0 );
        break;
      case QgsPalLayerSettings::AlwaysShow:
        mAlwaysShowChkbx->setEnabled( true );
        mAlwaysShowChkbx->setChecked( attributeValues[propIt.value()].toBool() );
        break;
      case QgsPalLayerSettings::MinScale:
        mMinScaleSpinBox->setEnabled( true );
        mMinScaleSpinBox->setValue( attributeValues[propIt.value()].toInt() );
        break;
      case QgsPalLayerSettings::MaxScale:
        mMaxScaleSpinBox->setEnabled( true );
        mMaxScaleSpinBox->setValue( attributeValues[propIt.value()].toInt() );
        break;
      case QgsPalLayerSettings::Size:
        mFontSizeSpinBox->setEnabled( true );
        mLabelFont.setPointSizeF( attributeValues[propIt.value()].toDouble() );
        mFontSizeSpinBox->setValue( attributeValues[propIt.value()].toDouble() );
        break;
      case QgsPalLayerSettings::BufferSize:
        mBufferSizeSpinBox->setEnabled( true );
        mBufferSizeSpinBox->setValue( attributeValues[propIt.value()].toDouble() );
        break;
      case QgsPalLayerSettings::PositionX:
        mXCoordSpinBox->setEnabled( true );
        mXCoordSpinBox->setValue( attributeValues[propIt.value()].toDouble() );
        break;
      case QgsPalLayerSettings::PositionY:
        mYCoordSpinBox->setEnabled( true );
        mYCoordSpinBox->setValue( attributeValues[propIt.value()].toDouble() );
        break;
      case QgsPalLayerSettings::LabelDistance:
        mLabelDistanceSpinBox->setEnabled( true );
        mLabelDistanceSpinBox->setValue( attributeValues[propIt.value()].toDouble() );
        break;
      case QgsPalLayerSettings::Hali:
        mHaliComboBox->setEnabled( true );
        mHaliComboBox->setCurrentIndex( mHaliComboBox->findText( attributeValues[propIt.value()].toString() ) );
        break;
      case QgsPalLayerSettings::Vali:
        mValiComboBox->setEnabled( true );
        mValiComboBox->setCurrentIndex( mValiComboBox->findText( attributeValues[propIt.value()].toString() ) );
        break;
      case QgsPalLayerSettings::BufferColor:
        mBufferColorButton->setEnabled( true );
        mBufferColorButton->setColor( QColor( attributeValues[propIt.value()].toString() ) );
        break;
      case QgsPalLayerSettings::Color:
        mFontColorButton->setEnabled( true );
        mFontColorButton->setColor( QColor( attributeValues[propIt.value()].toString() ) );
        break;
      case QgsPalLayerSettings::Rotation:
        mRotationSpinBox->setEnabled( true );
        mRotationSpinBox->setValue( attributeValues[propIt.value()].toDouble() );
        break;

        //font related properties
      case QgsPalLayerSettings::Bold:
        mLabelFont.setBold( attributeValues[propIt.value()].toBool() );
        break;
      case QgsPalLayerSettings::Italic:
        mLabelFont.setItalic( attributeValues[propIt.value()].toBool() );
        break;
      case QgsPalLayerSettings::Underline:
        mLabelFont.setUnderline( attributeValues[propIt.value()].toBool() );
        break;
      case QgsPalLayerSettings::Strikeout:
        mLabelFont.setStrikeOut( attributeValues[propIt.value()].toBool() );
        break;
      case QgsPalLayerSettings::Family:
        mLabelFont.setFamily( attributeValues[propIt.value()].toString() );
        break;
      default:
        break;
    }
  }
  mFontPushButton->setEnabled( labelFontEditingPossible() );
  blockElementSignals( false );
}
Beispiel #29
0
void QgsPalLayerSettings::registerFeature( QgsFeature& f, const QgsRenderContext& context )
{

  QString labelText;
  if ( formatNumbers == true
       && ( f.attributeMap()[fieldIndex].type() == QVariant::Int || f.attributeMap()[fieldIndex].type() == QVariant::Double ) )
  {
    QString numberFormat;
    double d = f.attributeMap()[fieldIndex].toDouble();
    if ( d > 0 && plusSign == true )
    {
      numberFormat.append( "+" );
    }
    numberFormat.append( "%1" );
    labelText = numberFormat.arg( d, 0, 'f', decimals );
  }
  else
  {
    labelText = f.attributeMap()[fieldIndex].toString();
  }

  double labelX, labelY; // will receive label size
  QFont labelFont = textFont;

  //data defined label size?
  QMap< DataDefinedProperties, int >::const_iterator it = dataDefinedProperties.find( QgsPalLayerSettings::Size );
  if ( it != dataDefinedProperties.constEnd() )
  {
    //find out size
    QVariant size = f.attributeMap().value( *it );
    if ( size.isValid() )
    {
      double sizeDouble = size.toDouble();
      if ( sizeDouble <= 0 )
      {
        return;
      }
      labelFont.setPixelSize( sizeToPixel( sizeDouble, context ) );
    }
    QFontMetricsF labelFontMetrics( labelFont );
    calculateLabelSize( &labelFontMetrics, labelText, labelX, labelY );
  }
  else
  {
    calculateLabelSize( fontMetrics, labelText, labelX, labelY );
  }

  QgsGeometry* geom = f.geometry();

  if ( ct ) // reproject the geometry if necessary
    geom->transform( *ct );

  if ( !checkMinimumSizeMM( context, geom, minFeatureSize ) )
  {
    return;
  }

  // CLIP the geometry if it is bigger than the extent
  QgsGeometry* geomClipped = NULL;
  GEOSGeometry* geos_geom;
  bool do_clip = !extentGeom->contains( geom );
  if ( do_clip )
  {
    geomClipped = geom->intersection( extentGeom ); // creates new geometry
    geos_geom = geomClipped->asGeos();
  }
  else
  {
    geos_geom = geom->asGeos();
  }

  if ( geos_geom == NULL )
    return; // invalid geometry
  GEOSGeometry* geos_geom_clone = GEOSGeom_clone( geos_geom );
  if ( do_clip )
    delete geomClipped;

  //data defined position / alignment / rotation?
  bool dataDefinedPosition = false;
  bool dataDefinedRotation = false;
  double xPos = 0.0, yPos = 0.0, angle = 0.0;
  bool ddXPos, ddYPos;

  QMap< DataDefinedProperties, int >::const_iterator dPosXIt = dataDefinedProperties.find( QgsPalLayerSettings::PositionX );
  if ( dPosXIt != dataDefinedProperties.constEnd() )
  {
    QMap< DataDefinedProperties, int >::const_iterator dPosYIt = dataDefinedProperties.find( QgsPalLayerSettings::PositionY );
    if ( dPosYIt != dataDefinedProperties.constEnd() )
    {
      //data defined position. But field values could be NULL -> positions will be generated by PAL
      xPos = f.attributeMap().value( *dPosXIt ).toDouble( &ddXPos );
      yPos = f.attributeMap().value( *dPosYIt ).toDouble( &ddYPos );

      if ( ddXPos && ddYPos )
      {
        dataDefinedPosition = true;
        //x/y shift in case of alignment
        double xdiff = 0;
        double ydiff = 0;

        //horizontal alignment
        QMap< DataDefinedProperties, int >::const_iterator haliIt = dataDefinedProperties.find( QgsPalLayerSettings::Hali );
        if ( haliIt != dataDefinedProperties.end() )
        {
          QString haliString = f.attributeMap().value( *haliIt ).toString();
          if ( haliString.compare( "Center", Qt::CaseInsensitive ) == 0 )
          {
            xdiff -= labelX / 2.0;
          }
          else if ( haliString.compare( "Right", Qt::CaseInsensitive ) == 0 )
          {
            xdiff -= labelX;
          }
        }

        //vertical alignment
        QMap< DataDefinedProperties, int >::const_iterator valiIt = dataDefinedProperties.find( QgsPalLayerSettings::Vali );
        if ( valiIt != dataDefinedProperties.constEnd() )
        {
          QString valiString = f.attributeMap().value( *valiIt ).toString();
          if ( valiString.compare( "Bottom", Qt::CaseInsensitive ) != 0 )
          {
            if ( valiString.compare( "Top", Qt::CaseInsensitive ) == 0 || valiString.compare( "Cap", Qt::CaseInsensitive ) == 0 )
            {
              ydiff -= labelY;
            }
            else
            {
              QFontMetrics labelFontMetrics( labelFont );
              double descentRatio = labelFontMetrics.descent() / labelFontMetrics.height();

              if ( valiString.compare( "Base", Qt::CaseInsensitive ) == 0 )
              {
                ydiff -= labelY * descentRatio;
              }
              else if ( valiString.compare( "Half", Qt::CaseInsensitive ) == 0 )
              {
                ydiff -= labelY * descentRatio;
                ydiff -= labelY * 0.5 * ( 1 - descentRatio );
              }
            }
          }
        }

        //data defined rotation?
        QMap< DataDefinedProperties, int >::const_iterator rotIt = dataDefinedProperties.find( QgsPalLayerSettings::Rotation );
        if ( rotIt != dataDefinedProperties.constEnd() )
        {
          dataDefinedRotation = true;
          angle = f.attributeMap().value( *rotIt ).toDouble() * M_PI / 180;
          //adjust xdiff and ydiff because the hali/vali point needs to be the rotation center
          double xd = xdiff * cos( angle ) - ydiff * sin( angle );
          double yd = xdiff * sin( angle ) + ydiff * cos( angle );
          xdiff = xd;
          ydiff = yd;
        }

        //project xPos and yPos from layer to map CRS
        double z = 0;
        if ( ct )
        {
          ct->transformInPlace( xPos, yPos, z );
        }

        yPos += ydiff;
        xPos += xdiff;

      }
    }
  }

  QgsPalGeometry* lbl = new QgsPalGeometry( f.id(), labelText, geos_geom_clone );

  // record the created geometry - it will be deleted at the end.
  geometries.append( lbl );

  // register feature to the layer
  try
  {
    if ( !palLayer->registerFeature( lbl->strId(), lbl, labelX, labelY, labelText.toUtf8().constData(),
                                     xPos, yPos, dataDefinedPosition, angle, dataDefinedRotation ) )
      return;
  }
  catch ( std::exception &e )
  {
    Q_UNUSED( e );
    QgsDebugMsg( QString( "Ignoring feature %1 due PAL exception: " ).arg( f.id() ) + QString::fromLatin1( e.what() ) );
    return;
  }

  // TODO: only for placement which needs character info
  pal::Feature* feat = palLayer->getFeature( lbl->strId() );
  feat->setLabelInfo( lbl->info( fontMetrics, xform, rasterCompressFactor ) );

  // TODO: allow layer-wide feature dist in PAL...?

  //data defined label-feature distance?
  double distance = dist;
  QMap< DataDefinedProperties, int >::const_iterator dDistIt = dataDefinedProperties.find( QgsPalLayerSettings::LabelDistance );
  if ( dDistIt != dataDefinedProperties.constEnd() )
  {
    distance = f.attributeMap().value( *dDistIt ).toDouble();
  }

  if ( distance != 0 )
  {
    if ( distInMapUnits ) //convert distance from mm/map units to pixels
    {
      distance /= context.mapToPixel().mapUnitsPerPixel();
    }
    else //mm
    {
      distance *= vectorScaleFactor;
    }
    feat->setDistLabel( qAbs( ptOne.x() - ptZero.x() )* distance );
  }

  //add parameters for data defined labeling to QgsPalGeometry
  QMap< DataDefinedProperties, int >::const_iterator dIt = dataDefinedProperties.constBegin();
  for ( ; dIt != dataDefinedProperties.constEnd(); ++dIt )
  {
    lbl->addDataDefinedValue( dIt.key(), f.attributeMap()[dIt.value()] );
  }
}
void QgsMapToolRotatePointSymbols::canvasPressEvent( QMouseEvent *e )
{
  if ( !mCanvas )
  {
    return;
  }

  mActiveLayer = currentVectorLayer();
  if ( !mActiveLayer )
  {
    notifyNotVectorLayer();
    return;
  }

  if ( !mActiveLayer->isEditable() )
  {
    notifyNotEditableLayer();
    return;
  }

  if ( mActiveLayer->geometryType() != QGis::Point )
  {
    return;
  }

  //find the closest feature to the pressed position
  QgsMapCanvasSnapper canvasSnapper( mCanvas );
  QList<QgsSnappingResult> snapResults;
  if ( canvasSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToVertex, -1 ) != 0 || snapResults.size() < 1 )
  {
    QMessageBox::critical( 0, tr( "No point feature" ), tr( "No point feature was detected at the clicked position. Please click closer to the feature or enhance the search tolerance under Settings->Options->Digitizing->Serch radius for vertex edits" ) );
    return; //error during snapping
  }

  mFeatureNumber = snapResults.at( 0 ).snappedAtGeometry;

  //get list with renderer rotation attributes
  if ( layerRotationAttributes( mActiveLayer, mCurrentRotationAttributes ) != 0 )
  {
    return;
  }

  if ( mCurrentRotationAttributes.size() < 1 )
  {
    QMessageBox::critical( 0, tr( "No rotation Attributes" ), tr( "The active point layer does not have a rotation attribute" ) );
    return;
  }

  mSnappedPoint = toCanvasCoordinates( snapResults.at( 0 ).snappedVertex );

  //find out initial arrow direction
  QgsFeature pointFeature;
  if ( !mActiveLayer->featureAtId( mFeatureNumber, pointFeature, false, true ) )
  {
    return;
  }
  const QgsAttributeMap pointFeatureAttributes = pointFeature.attributeMap();
  const QgsAttributeMap::const_iterator attIt = pointFeatureAttributes.find( mCurrentRotationAttributes.at( 0 ) );
  if ( attIt == pointFeatureAttributes.constEnd() )
  {
    return;
  }

  mCurrentRotationFeature = attIt.value().toDouble();
  createPixmapItem( pointFeature );
  if ( mRotationItem )
  {
    mRotationItem->setPointLocation( snapResults.at( 0 ).snappedVertex );
  }
  mCurrentMouseAzimut = calculateAzimut( e->pos() );
  setPixmapItemRotation(( int )( mCurrentMouseAzimut ) );
  mRotating = true;
}