void QgsRelationEditorWidget::addFeature()
{
  QgsAttributeMap keyAttrs;

  const QgsVectorLayerTools* vlTools = mEditorContext.vectorLayerTools();

  if ( mNmRelation.isValid() )
  {
    // n:m Relation: first let the user create a new feature on the other table
    // and autocreate a new linking feature.
    QgsFeature f;
    if ( vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), QgsGeometry(), &f ) )
    {
      QgsFeature flink( mRelation.referencingLayer()->fields() ); // Linking feature

      flink.setAttribute( mRelation.fieldPairs().at( 0 ).first, mFeature.attribute( mRelation.fieldPairs().at( 0 ).second ) );
      flink.setAttribute( mNmRelation.referencingFields().at( 0 ), f.attribute( mNmRelation.referencedFields().at( 0 ) ) );

      mRelation.referencingLayer()->addFeature( flink );

      updateUi();
    }
  }
  else
  {
    QgsFields fields = mRelation.referencingLayer()->fields();

    Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mRelation.fieldPairs() )
    {
      keyAttrs.insert( fields.indexFromName( fieldPair.referencingField() ), mFeature.attribute( fieldPair.referencedField() ) );
    }

    vlTools->addFeature( mDualView->masterModel()->layer(), keyAttrs );
  }
}
Exemple #2
0
QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateReferenceSystem &, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/
{
  QString fStr = "{\"type\": \"Feature\",\n";

  fStr += "   \"id\": ";
  fStr +=  QString::number( feat->id() );
  fStr += ",\n";

  QgsGeometry* geom = feat->geometry();
  if ( geom && mWithGeom )
  {
    QgsRectangle box = geom->boundingBox();

    fStr += " \"bbox\": [ " + QString::number( box.xMinimum(), 'f', 6 ).remove( QRegExp( "[0]{1,5}$" ) ) + ", " + QString::number( box.yMinimum(), 'f', 6 ).remove( QRegExp( "[0]{1,5}$" ) ) + ", " + QString::number( box.xMaximum(), 'f', 6 ).remove( QRegExp( "[0]{1,5}$" ) ) + ", " + QString::number( box.yMaximum(), 'f', 6 ).remove( QRegExp( "[0]{1,5}$" ) ) + "],\n";

    fStr += "  \"geometry\": ";
    fStr += geom->exportToGeoJSON();
    fStr += ",\n";
  }

  //read all attribute values from the feature
  fStr += "   \"properties\": {\n";
  QgsAttributeMap featureAttributes = feat->attributeMap();
  int attributeCounter = 0;
  for ( QgsAttributeMap::const_iterator it = featureAttributes.begin(); it != featureAttributes.end(); ++it )
  {
    QString attributeName = fields[it.key()].name();
    //skip attribute if it has edit type 'hidden'
    if ( hiddenAttributes.contains( attributeName ) )
    {
      continue;
    }

    if ( attributeCounter == 0 )
      fStr += "    \"";
    else
      fStr += "   ,\"";
    fStr += attributeName;
    fStr += "\": ";
    if ( it->type() == 6 || it->type() == 2 )
    {
      fStr +=  it->toString();
    }
    else
    {
      fStr += "\"";
      fStr +=  it->toString().replace( QString( "\"" ), QString( "\\\"" ) );
      fStr += "\"";
    }
    fStr += "\n";
    ++attributeCounter;
  }

  fStr += "   }\n";

  fStr += "  }";

  return fStr;
}
Exemple #3
0
void QgsGrassEdit::addAttributes( int field, int cat )
{
  QString *key = mProvider->key( field );

  QString lab;
  lab.sprintf( "%d:%d", field, cat );
  int tab = mAttributes->addTab( lab );
  mAttributes->setField( tab, field );

  QString catLabel;
  if ( key->isEmpty() )
  {
    catLabel = "Category";
  }
  else
  {
    catLabel = *key;
  }
  mAttributes->setCat( tab, catLabel, cat );

  if ( !key->isEmpty() )   // Database link defined
  {
    QVector<QgsField> *cols = mProvider->columns( field );

    if ( cols->size() == 0 )
    {
      QString str;
      str.setNum( field );
      QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot describe table for field %1" ).arg( str ) );
    }
    else
    {
      QgsAttributeMap *atts = mProvider->attributes( field, cat );

      if ( atts->size() == 0 )   // cannot select attributes
      {
        mAttributes->addTextRow( tab, "WARNING: ATTRIBUTES MISSING" );
      }
      else
      {
        for ( int j = 0; j < cols->size(); j++ )
        {
          QgsField col = ( *cols )[j];
          QVariant att = ( *atts )[j];
          QgsDebugMsg( QString( " name = %1" ).arg( col.name() ) );

          if ( col.name() != *key )
          {
            QgsDebugMsg( QString( " value = %1" ).arg( att.toString() ) );
            mAttributes->addAttribute( tab, col.name(), att.toString(), col.typeName() );
          }
        }
      }
      delete atts;
    }
    delete cols;
  }
}
Exemple #4
0
QString QgsActionManager::expandAction( QString action, const QgsAttributeMap &attributes,
                                        uint clickedOnValue )
{
  // This function currently replaces all %% characters in the action
  // with the value from values[clickedOnValue].second, and then
  // searches for all strings that go %attribute_name, where
  // attribute_name is found in values[x].first, and replaces any that
  // it finds by values[s].second.

  // Additional substitutions could include symbols for $CWD, $HOME,
  // etc (and their OSX and Windows equivalents)

  // This function will potentially fall apart if any of the
  // substitutions produce text that could match another
  // substitution. May be better to adopt a two pass approach - identify
  // all matches and their substitutions and then do a second pass
  // for the actual substitutions.

  QString expanded_action;
  if ( attributes.contains( clickedOnValue ) )
    expanded_action = action.replace( "%%", attributes[clickedOnValue].toString() );
  else
    expanded_action = action;

  const QgsFields &fields = mLayer->fields();

  for ( int i = 0; i < 4; i++ )
  {
    for ( QgsAttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); ++it )
    {
      int attrIdx = it.key();
      if ( attrIdx < 0 || attrIdx >= fields.count() )
        continue;

      QString to_replace;
      switch ( i )
      {
        case 0:
          to_replace = "[%" + fields[attrIdx].name() + ']';
          break;
        case 1:
          to_replace = "[%" + mLayer->attributeDisplayName( attrIdx ) + ']';
          break;
        case 2:
          to_replace = '%' + fields[attrIdx].name();
          break;
        case 3:
          to_replace = '%' + mLayer->attributeDisplayName( attrIdx );
          break;
      }

      expanded_action = expanded_action.replace( to_replace, it.value().toString() );
    }
  }

  return expanded_action;
}
Exemple #5
0
QDomElement QgsWFSServer::createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/
{
  //gml:FeatureMember
  QDomElement featureElement = doc.createElement( "gml:featureMember"/*wfs:FeatureMember*/ );

  //qgs:%TYPENAME%
  QDomElement typeNameElement = doc.createElement( "qgs:" + mTypeName.replace( QString( " " ), QString( "_" ) )/*qgs:%TYPENAME%*/ );
  typeNameElement.setAttribute( "fid", QString::number( feat->id() ) );
  featureElement.appendChild( typeNameElement );

  if ( mWithGeom )
  {
    //add geometry column (as gml)
    QgsGeometry* geom = feat->geometry();

    QDomElement geomElem = doc.createElement( "qgs:geometry" );
    QDomElement gmlElem = createGeometryElem( geom, doc );
    if ( !gmlElem.isNull() )
    {
      QgsRectangle box = geom->boundingBox();
      QDomElement bbElem = doc.createElement( "gml:boundedBy" );
      QDomElement boxElem = createBoxElem( &box, doc );

      if ( crs.isValid() )
      {
        boxElem.setAttribute( "srsName", crs.authid() );
        gmlElem.setAttribute( "srsName", crs.authid() );
      }

      bbElem.appendChild( boxElem );
      typeNameElement.appendChild( bbElem );

      geomElem.appendChild( gmlElem );
      typeNameElement.appendChild( geomElem );
    }
  }

  //read all attribute values from the feature
  QgsAttributeMap featureAttributes = feat->attributeMap();
  for ( QgsAttributeMap::const_iterator it = featureAttributes.begin(); it != featureAttributes.end(); ++it )
  {

    QString attributeName = fields[it.key()].name();
    //skip attribute if it has edit type 'hidden'
    if ( hiddenAttributes.contains( attributeName ) )
    {
      continue;
    }

    QDomElement fieldElem = doc.createElement( "qgs:" + attributeName.replace( QString( " " ), QString( "_" ) ) );
    QDomText fieldText = doc.createTextNode( it->toString() );
    fieldElem.appendChild( fieldText );
    typeNameElement.appendChild( fieldElem );
  }

  return featureElement;
}
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();
}
void QgsVectorLayerEditBuffer::updateAttributeMapIndex( QgsAttributeMap& map, int index, int offset ) const
{
  QgsAttributeMap updatedMap;
  for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it )
  {
    int attrIndex = it.key();
    updatedMap.insert( attrIndex < index ? attrIndex : attrIndex + offset, it.value() );
  }
  map = updatedMap;
}
Exemple #8
0
QgsAttributeMap QgsAttributes::toMap() const
{
  QgsAttributeMap map;
  for ( int idx = 0; idx < count(); ++idx )
  {
    QVariant v = at( idx );
    if ( v.isValid() )
      map.insert( idx, v );
  }
  return map;
}
Exemple #9
0
void QgsGPXProvider::changeAttributeValues( QgsGPSObject& obj, const QgsAttributeMap& attrs )
{

  QgsWaypoint* wpt = dynamic_cast<QgsWaypoint*>( &obj );
  QgsGPSExtended* ext = dynamic_cast<QgsGPSExtended*>( &obj );

  QgsAttributeMap::const_iterator aIter = attrs.begin();
  for ( ; aIter != attrs.end(); ++aIter )
  {
    int i = aIter.key();
    QVariant v = aIter.value();

    // common attributes
    switch ( indexToAttr[i] )
    {
      case NameAttr:    obj.name    = v.toString(); break;
      case CmtAttr:     obj.cmt     = v.toString(); break;
      case DscAttr:     obj.desc    = v.toString(); break;
      case SrcAttr:     obj.src     = v.toString(); break;
      case URLAttr:     obj.url     = v.toString(); break;
      case URLNameAttr: obj.urlname = v.toString(); break;
    }

    // waypoint-specific attributes
    if ( wpt != NULL )
    {
      if ( indexToAttr[i] == SymAttr )
        wpt->sym = v.toString();
      else if ( indexToAttr[i] == EleAttr )
      {
        bool eleIsOK;
        double ele = v.toDouble( &eleIsOK );
        if ( eleIsOK )
          wpt->ele = ele;
      }
    }

    // route- and track-specific attributes
    if ( ext != NULL )
    {
      if ( indexToAttr[i] == NumAttr )
      {
        bool numIsOK;
        int num = v.toInt( &numIsOK );
        if ( numIsOK )
          ext->number = num;
      }
    }

  }

}
void QgsOverlayAnalyzer::combineAttributeMaps( QgsAttributeMap& attributeMapA, QgsAttributeMap attributeMapB )
{
  QMap<int, QVariant>::const_iterator i = attributeMapB.constBegin();
  QVariant attribute;
  int fcount = attributeMapA.size();
  while ( i != attributeMapB.constEnd() )
  {
    attribute = i.value();
    attributeMapA.insert( fcount, attribute );
    ++i;
    ++fcount;
  }
}
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;
}
QSizeF QgsLinearlyInterpolatedDiagramRenderer::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c )
{
    Q_UNUSED( c );
    QgsAttributeMap::const_iterator attIt = attributes.find( mClassificationAttribute );
    if ( attIt == attributes.constEnd() )
    {
        return QSizeF(); //zero size if attribute is missing
    }
    double value = attIt.value().toDouble();

    //interpolate size
    double ratio = ( value - mLowerValue ) / ( mUpperValue - mLowerValue );
    return QSizeF( mUpperSize.width() * ratio + mLowerSize.width() * ( 1 - ratio ),
                   mUpperSize.height() * ratio + mLowerSize.height() * ( 1 - ratio ) );
}
bool QgsVectorLayerEditBuffer::changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues )
{
  bool success = true;
  for ( auto it = newValues.constBegin() ; it != newValues.constEnd(); ++it )
  {
    const int field = it.key();
    const QVariant newValue = it.value();
    QVariant oldValue;

    if ( oldValues.contains( field ) )
      oldValue = oldValues[field];

    success &= changeAttributeValue( fid, field, newValue, oldValue );
  }

  return success;
}
bool QgsComposerTextTable::getFeatureAttributes( QList<QgsAttributeMap>& attributes )
{
  attributes.clear();

  QList< QStringList >::const_iterator rowIt = mRowText.constBegin();
  QStringList currentStringList;
  for ( ; rowIt != mRowText.constEnd(); ++rowIt )
  {
    currentStringList = *rowIt;
    QgsAttributeMap map;
    for ( int i = 0; i < currentStringList.size(); ++i )
    {
      map.insert( i, QVariant( currentStringList.at( i ) ) );
    }
    attributes.append( map );
  }
  return true;
}
Exemple #15
0
QSizeF QgsPieDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is )
{
  Q_UNUSED( c );
  QgsAttributeMap::const_iterator attIt = attributes.find( is.classificationAttribute );
  if ( attIt == attributes.constEnd() )
  {
    return QSizeF(); //zero size if attribute is missing
  }

  double scaledValue = attIt.value().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;
}
bool QgsFeatureAction::editFeature()
{
  bool res = false;

  if ( !mLayer )
    return res;

  QgsAttributeDialog *dialog = newDialog( false );

  if ( !mLayer->isEditable() )
  {
    res = dialog->exec();
  }
  else
  {
    QgsAttributeMap src = mFeature.attributeMap();

    if ( dialog->exec() )
    {
      mLayer->beginEditCommand( text() );

      const QgsAttributeMap &dst = mFeature.attributeMap();
      for ( QgsAttributeMap::const_iterator it = dst.begin(); it != dst.end(); it++ )
      {
        if ( !src.contains( it.key() ) || it.value() != src[it.key()] )
        {
          mLayer->changeAttributeValue( mFeature.id(), it.key(), it.value() );
        }
      }

      mLayer->endEditCommand();
      res = true;
    }
    else
    {
      res = false;
    }
  }

  delete dialog;
  return res;
}
Exemple #17
0
void QgsGrassEdit::addCat( int line )
{
  int mode = mCatModeBox->currentIndex();
  int field = mFieldBox->currentText().toInt();
  int cat = mCatEntry->text().toInt();

  int type = mProvider->readLine( mPoints, mCats, line );
  if ( mode == CAT_MODE_NEXT || mode == CAT_MODE_MANUAL )
  {
    Vect_cat_set( mCats, field, cat );
  }

  line = mProvider->rewriteLine( line, type, mPoints, mCats );
  mSelectedLine = line;
  if ( mAttributes )
    mAttributes->setLine( line );
  updateSymb();
  increaseMaxCat();

  // Insert new DB record if link is defined and the record for this cat does not exist
  QString *key = mProvider->key( field );

  if ( !key->isEmpty() )   // Database link defined
  {
    QgsAttributeMap *atts = mProvider->attributes( field, cat );

    if ( atts->size() == 0 )   // Nothing selected
    {
      QString *error = mProvider->insertAttributes( field, cat );

      if ( !error->isEmpty() )
      {
        QMessageBox::warning( 0, tr( "Warning" ), *error );
      }
      delete error;
    }

    delete atts;
  }

  addAttributes( field, cat );
}
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;
}
void QgsMapToolChangeLabelProperties::applyChanges( const QgsAttributeMap& changes )
{
  QgsVectorLayer* vlayer = mCurrentLabel.layer;
  if ( !vlayer )
    return;

  if ( !changes.isEmpty() )
  {
    vlayer->beginEditCommand( tr( "Changed properties for label" ) + QStringLiteral( " '%1'" ).arg( currentLabelText( 24 ) ) );

    QgsAttributeMap::const_iterator changeIt = changes.constBegin();
    for ( ; changeIt != changes.constEnd(); ++changeIt )
    {
      vlayer->changeAttributeValue( mCurrentLabel.pos.featureId, changeIt.key(), changeIt.value() );
    }

    vlayer->endEditCommand();
    vlayer->triggerRepaint();
  }
}
Exemple #20
0
void QgsGPXProvider::changeAttributeValues( QgsGPSObject& obj, const QgsAttributeMap& attrs )
{
  QgsAttributeMap::const_iterator aIter;

  // TODO:
  if ( attrs.contains( NameAttr ) )
    obj.name = attrs[NameAttr].toString();
  if ( attrs.contains( CmtAttr ) )
    obj.cmt = attrs[CmtAttr].toString();
  if ( attrs.contains( DscAttr ) )
    obj.desc = attrs[DscAttr].toString();
  if ( attrs.contains( SrcAttr ) )
    obj.src = attrs[SrcAttr].toString();
  if ( attrs.contains( URLAttr ) )
    obj.url = attrs[URLAttr].toString();
  if ( attrs.contains( URLNameAttr ) )
    obj.urlname = attrs[URLNameAttr].toString();

  // waypoint-specific attributes
  QgsWaypoint* wpt = dynamic_cast<QgsWaypoint*>( &obj );
  if ( wpt != NULL )
  {
    if ( attrs.contains( SymAttr ) )
      wpt->sym = attrs[SymAttr].toString();
    if ( attrs.contains( EleAttr ) )
    {
      bool eleIsOK;
      double ele = attrs[EleAttr].toDouble( &eleIsOK );
      if ( eleIsOK )
        wpt->ele = ele;
    }
  }

  // route- and track-specific attributes
  QgsGPSExtended* ext = dynamic_cast<QgsGPSExtended*>( &obj );
  if ( ext != NULL )
  {
    if ( attrs.contains( NumAttr ) )
    {
      bool eleIsOK;
      double ele = attrs[NumAttr].toDouble( &eleIsOK );
      if ( eleIsOK )
        wpt->ele = ele;
    }
  }
}
QgsAttributeMap QgsMergeAttributesDialog::mergedAttributesMap() const
{
  if ( mFeatureList.size() < 1 )
  {
    return QgsAttributeMap();
  }

  QgsAttributeMap resultMap;
  for ( int i = 0; i < mTableWidget->columnCount(); i++ )
  {
    int idx = mTableWidget->horizontalHeaderItem( i )->data( Qt::UserRole ).toInt();

    QTableWidgetItem* currentItem = mTableWidget->item( mFeatureList.size() + 1, i );
    if ( !currentItem )
      continue;

    resultMap.insert( idx, currentItem->text() );
  }

  return resultMap;
}
Exemple #22
0
void QgsFeaturePool::updateFeature( QgsFeature& feature )
{
  QgsGeometryMap geometryMap;
  geometryMap.insert( feature.id(), QgsGeometry( feature.geometry()->geometry()->clone() ) );
  QgsChangedAttributesMap changedAttributesMap;
  QgsAttributeMap attribMap;
  for ( int i = 0, n = feature.attributes().size(); i < n; ++i )
  {
    attribMap.insert( i, feature.attributes().at( i ) );
  }
  changedAttributesMap.insert( feature.id(), attribMap );
  mLayerMutex.lock();
  mFeatureCache.remove( feature.id() ); // Remove to force reload on next get()
  mLayer->dataProvider()->changeGeometryValues( geometryMap );
  mLayer->dataProvider()->changeAttributeValues( changedAttributesMap );
  mLayerMutex.unlock();
  mIndexMutex.lock();
  mIndex.deleteFeature( feature );
  mIndex.insertFeature( feature );
  mIndexMutex.unlock();
}
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++ );
  }
}
void QgsRelationReferenceWidget::addEntry()
{
  QgsFeature f( mReferencedLayer->fields() );
  QgsAttributeMap attributes;

  // if custom text is in the combobox and the displayExpression is simply a field, use the current text for the new feature
  if ( mComboBox->itemText( mComboBox->currentIndex() ) != mComboBox->currentText() )
  {
    int fieldIdx = mReferencedLayer->fields().lookupField( mReferencedLayer->displayExpression() );

    if ( fieldIdx != -1 )
    {
      attributes.insert( fieldIdx, mComboBox->currentText() );
    }
  }

  if ( mEditorContext.vectorLayerTools()->addFeature( mReferencedLayer, attributes, QgsGeometry(), &f ) )
  {
    mComboBox->setIdentifierValue( f.attribute( mReferencingFieldIdx ) );
    mAddEntryButton->setEnabled( false );
  }
}
Exemple #25
0
int QgsGrassEdit::writeLine( int type, struct line_pnts *Points )
{
  int mode = mCatModeBox->currentIndex();
  int field = mFieldBox->currentText().toInt();
  int cat = mCatEntry->text().toInt();

  Vect_reset_cats( mCats );
  if ( mode == CAT_MODE_NEXT || mode == CAT_MODE_MANUAL )
  {
    Vect_cat_set( mCats, field, cat );

    // Insert new DB record if link is defined and the record for this cat does not exist
    QString *key = mProvider->key( field );

    if ( !key->isEmpty() )   // Database link defined
    {
      QgsAttributeMap *atts = mProvider->attributes( field, cat );

      if ( atts->count() == 0 )   // Nothing selected
      {
        QString *error = mProvider->insertAttributes( field, cat );

        if ( !error->isEmpty() )
        {
          QMessageBox::warning( 0, tr( "Warning" ), *error );
        }
        delete error;
      }

      delete atts;
    }
  }
  Vect_line_prune( Points );
  int line = mProvider->writeLine( type, Points, mCats );

  increaseMaxCat();
  return line;
}
void QgsRelationEditorWidget::addFeature()
{
  QgsAttributeMap keyAttrs;

  const QgsVectorLayerTools *vlTools = mEditorContext.vectorLayerTools();

  if ( mNmRelation.isValid() )
  {
    // n:m Relation: first let the user create a new feature on the other table
    // and autocreate a new linking feature.
    QgsFeature f;
    if ( vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), QgsGeometry(), &f ) )
    {
      // Fields of the linking table
      const QgsFields fields = mRelation.referencingLayer()->fields();

      // Expression context for the linking table
      QgsExpressionContext context = mRelation.referencingLayer()->createExpressionContext();

      QgsAttributeMap linkAttributes;
      Q_FOREACH ( const QgsRelation::FieldPair &fieldPair, mRelation.fieldPairs() )
      {
        int index = fields.indexOf( fieldPair.first );
        linkAttributes.insert( index,  mFeature.attribute( fieldPair.second ) );
      }

      Q_FOREACH ( const QgsRelation::FieldPair &fieldPair, mNmRelation.fieldPairs() )
      {
        int index = fields.indexOf( fieldPair.first );
        linkAttributes.insert( index, f.attribute( fieldPair.second ) );
      }
      QgsFeature linkFeature = QgsVectorLayerUtils::createFeature( mRelation.referencingLayer(), QgsGeometry(), linkAttributes, &context );

      mRelation.referencingLayer()->addFeature( linkFeature );

      updateUi();
    }
  }
/*!
    \fn OptVectorLayer:: changeAttribute(QgsFeature& feature, int field, QVariant attr)
 */
bool OptVectorLayer:: changeAttribute(QgsFeature& feature, int field, QVariant attr)
{
  if ( !isEditable() )
  {
    startEditing();
  }
  if ( isModified() )
  {
    commitChanges();
  }

  QgsChangedAttributesMap attributeChanges;
  QgsAttributeMap newAttMap;
  newAttMap.insert(field, attr );
	attributeChanges.insert(feature.id(), newAttMap);
//{zhangliye2715} ;api changed
//   commitAttributeChanges(QgsAttributeIds(),
//           QgsNewAttributesMap(),
//           attributeChanges);
	dataProvider()->changeAttributeValues(attributeChanges);

  //commit or rollBack the change
  if ( isModified() )
  {
    commitChanges();
  }
  else
  {
    rollBack();
    return false;
  }

  //make the layer still editable for the next adding operation
  startEditing();

  return true;
}
void QgsOfflineEditing::committedAttributeValuesChanges( const QString& qgisLayerId, const QgsChangedAttributesMap& changedAttrsMap )
{
  sqlite3* db = openLoggingDb();
  if ( db == NULL )
  {
    return;
  }

  // insert log
  int layerId = getOrCreateLayerId( db, qgisLayerId );
  int commitNo = getCommitNo( db );

  for ( QgsChangedAttributesMap::const_iterator cit = changedAttrsMap.begin(); cit != changedAttrsMap.end(); ++cit )
  {
    QgsFeatureId fid = cit.key();
    if ( isAddedFeature( db, layerId, fid ) )
    {
      // skip added features
      continue;
    }
    QgsAttributeMap attrMap = cit.value();
    for ( QgsAttributeMap::const_iterator it = attrMap.begin(); it != attrMap.end(); ++it )
    {
      QString sql = QString( "INSERT INTO 'log_feature_updates' VALUES ( %1, %2, %3, %4, '%5' )" )
                    .arg( layerId )
                    .arg( commitNo )
                    .arg( fid )
                    .arg( it.key() ) // attr
                    .arg( it.value().toString() ); // value
      sqlExec( db, sql );
    }
  }

  increaseCommitNo( db );
  sqlite3_close( db );
}
Exemple #29
0
int QgsZonalStatistics::calculateStatistics( QgsFeedback *feedback )
{
  if ( !mPolygonLayer || mPolygonLayer->geometryType() != QgsWkbTypes::PolygonGeometry )
  {
    return 1;
  }

  QgsVectorDataProvider *vectorProvider = mPolygonLayer->dataProvider();
  if ( !vectorProvider )
  {
    return 2;
  }

  if ( !mRasterLayer )
  {
    return 3;
  }

  if ( mRasterLayer->bandCount() < mRasterBand )
  {
    return 4;
  }

  mRasterProvider = mRasterLayer->dataProvider();
  mInputNodataValue = mRasterProvider->sourceNoDataValue( mRasterBand );

  //get geometry info about raster layer
  int nCellsXProvider = mRasterProvider->xSize();
  int nCellsYProvider = mRasterProvider->ySize();
  double cellsizeX = mRasterLayer->rasterUnitsPerPixelX();
  if ( cellsizeX < 0 )
  {
    cellsizeX = -cellsizeX;
  }
  double cellsizeY = mRasterLayer->rasterUnitsPerPixelY();
  if ( cellsizeY < 0 )
  {
    cellsizeY = -cellsizeY;
  }
  QgsRectangle rasterBBox = mRasterProvider->extent();

  //add the new fields to the provider
  QList<QgsField> newFieldList;
  QString countFieldName;
  if ( mStatistics & QgsZonalStatistics::Count )
  {
    countFieldName = getUniqueFieldName( mAttributePrefix + "count", newFieldList );
    QgsField countField( countFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
    newFieldList.push_back( countField );
  }
  QString sumFieldName;
  if ( mStatistics & QgsZonalStatistics::Sum )
  {
    sumFieldName = getUniqueFieldName( mAttributePrefix + "sum", newFieldList );
    QgsField sumField( sumFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
    newFieldList.push_back( sumField );
  }
  QString meanFieldName;
  if ( mStatistics & QgsZonalStatistics::Mean )
  {
    meanFieldName = getUniqueFieldName( mAttributePrefix + "mean", newFieldList );
    QgsField meanField( meanFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
    newFieldList.push_back( meanField );
  }
  QString medianFieldName;
  if ( mStatistics & QgsZonalStatistics::Median )
  {
    medianFieldName = getUniqueFieldName( mAttributePrefix + "median", newFieldList );
    QgsField medianField( medianFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
    newFieldList.push_back( medianField );
  }
  QString stdevFieldName;
  if ( mStatistics & QgsZonalStatistics::StDev )
  {
    stdevFieldName = getUniqueFieldName( mAttributePrefix + "stdev", newFieldList );
    QgsField stdField( stdevFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
    newFieldList.push_back( stdField );
  }
  QString minFieldName;
  if ( mStatistics & QgsZonalStatistics::Min )
  {
    minFieldName = getUniqueFieldName( mAttributePrefix + "min", newFieldList );
    QgsField minField( minFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
    newFieldList.push_back( minField );
  }
  QString maxFieldName;
  if ( mStatistics & QgsZonalStatistics::Max )
  {
    maxFieldName = getUniqueFieldName( mAttributePrefix + "max", newFieldList );
    QgsField maxField( maxFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
    newFieldList.push_back( maxField );
  }
  QString rangeFieldName;
  if ( mStatistics & QgsZonalStatistics::Range )
  {
    rangeFieldName = getUniqueFieldName( mAttributePrefix + "range", newFieldList );
    QgsField rangeField( rangeFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
    newFieldList.push_back( rangeField );
  }
  QString minorityFieldName;
  if ( mStatistics & QgsZonalStatistics::Minority )
  {
    minorityFieldName = getUniqueFieldName( mAttributePrefix + "minority", newFieldList );
    QgsField minorityField( minorityFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
    newFieldList.push_back( minorityField );
  }
  QString majorityFieldName;
  if ( mStatistics & QgsZonalStatistics::Majority )
  {
    majorityFieldName = getUniqueFieldName( mAttributePrefix + "majority", newFieldList );
    QgsField majField( majorityFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
    newFieldList.push_back( majField );
  }
  QString varietyFieldName;
  if ( mStatistics & QgsZonalStatistics::Variety )
  {
    varietyFieldName = getUniqueFieldName( mAttributePrefix + "variety", newFieldList );
    QgsField varietyField( varietyFieldName, QVariant::Int, QStringLiteral( "int" ) );
    newFieldList.push_back( varietyField );
  }
  QString varianceFieldName;
  if ( mStatistics & QgsZonalStatistics::Variance )
  {
    varianceFieldName = getUniqueFieldName( mAttributePrefix + "variance", newFieldList );
    QgsField varianceField( varianceFieldName, QVariant::Double, QStringLiteral( "double precision" ) );
    newFieldList.push_back( varianceField );
  }
  vectorProvider->addAttributes( newFieldList );

  //index of the new fields
  int countIndex = mStatistics & QgsZonalStatistics::Count ? vectorProvider->fieldNameIndex( countFieldName ) : -1;
  int sumIndex = mStatistics & QgsZonalStatistics::Sum ? vectorProvider->fieldNameIndex( sumFieldName ) : -1;
  int meanIndex = mStatistics & QgsZonalStatistics::Mean ? vectorProvider->fieldNameIndex( meanFieldName ) : -1;
  int medianIndex = mStatistics & QgsZonalStatistics::Median ? vectorProvider->fieldNameIndex( medianFieldName ) : -1;
  int stdevIndex = mStatistics & QgsZonalStatistics::StDev ? vectorProvider->fieldNameIndex( stdevFieldName ) : -1;
  int minIndex = mStatistics & QgsZonalStatistics::Min ? vectorProvider->fieldNameIndex( minFieldName ) : -1;
  int maxIndex = mStatistics & QgsZonalStatistics::Max ? vectorProvider->fieldNameIndex( maxFieldName ) : -1;
  int rangeIndex = mStatistics & QgsZonalStatistics::Range ? vectorProvider->fieldNameIndex( rangeFieldName ) : -1;
  int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->fieldNameIndex( minorityFieldName ) : -1;
  int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->fieldNameIndex( majorityFieldName ) : -1;
  int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->fieldNameIndex( varietyFieldName ) : -1;
  int varianceIndex = mStatistics & QgsZonalStatistics::Variance ? vectorProvider->fieldNameIndex( varianceFieldName ) : -1;

  if ( ( mStatistics & QgsZonalStatistics::Count && countIndex == -1 )
       || ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 )
       || ( mStatistics & QgsZonalStatistics::Mean && meanIndex == -1 )
       || ( mStatistics & QgsZonalStatistics::Median && medianIndex == -1 )
       || ( mStatistics & QgsZonalStatistics::StDev && stdevIndex == -1 )
       || ( mStatistics & QgsZonalStatistics::Min && minIndex == -1 )
       || ( mStatistics & QgsZonalStatistics::Max && maxIndex == -1 )
       || ( mStatistics & QgsZonalStatistics::Range && rangeIndex == -1 )
       || ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 )
       || ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 )
       || ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 )
       || ( mStatistics & QgsZonalStatistics::Variance && varianceIndex == -1 )
     )
  {
    //failed to create a required field
    return 8;
  }

  //progress dialog
  long featureCount = vectorProvider->featureCount();

  //iterate over each polygon
  QgsFeatureRequest request;
  request.setSubsetOfAttributes( QgsAttributeList() );
  QgsFeatureIterator fi = vectorProvider->getFeatures( request );
  QgsFeature f;

  bool statsStoreValues = ( mStatistics & QgsZonalStatistics::Median ) ||
                          ( mStatistics & QgsZonalStatistics::StDev ) ||
                          ( mStatistics & QgsZonalStatistics::Variance );
  bool statsStoreValueCount = ( mStatistics & QgsZonalStatistics::Minority ) ||
                              ( mStatistics & QgsZonalStatistics::Majority );

  FeatureStats featureStats( statsStoreValues, statsStoreValueCount );
  int featureCounter = 0;

  QgsChangedAttributesMap changeMap;
  while ( fi.nextFeature( f ) )
  {
    if ( feedback && feedback->isCanceled() )
    {
      break;
    }

    if ( feedback )
    {
      feedback->setProgress( 100.0 * static_cast< double >( featureCounter ) / featureCount );
    }

    if ( !f.hasGeometry() )
    {
      ++featureCounter;
      continue;
    }
    QgsGeometry featureGeometry = f.geometry();

    QgsRectangle featureRect = featureGeometry.boundingBox().intersect( &rasterBBox );
    if ( featureRect.isEmpty() )
    {
      ++featureCounter;
      continue;
    }

    int offsetX, offsetY, nCellsX, nCellsY;
    if ( cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 )
    {
      ++featureCounter;
      continue;
    }

    //avoid access to cells outside of the raster (may occur because of rounding)
    if ( ( offsetX + nCellsX ) > nCellsXProvider )
    {
      nCellsX = nCellsXProvider - offsetX;
    }
    if ( ( offsetY + nCellsY ) > nCellsYProvider )
    {
      nCellsY = nCellsYProvider - offsetY;
    }

    statisticsFromMiddlePointTest( featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY,
                                   rasterBBox, featureStats );

    if ( featureStats.count <= 1 )
    {
      //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case
      statisticsFromPreciseIntersection( featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY,
                                         rasterBBox, featureStats );
    }

    //write the statistics value to the vector data provider
    QgsAttributeMap changeAttributeMap;
    if ( mStatistics & QgsZonalStatistics::Count )
      changeAttributeMap.insert( countIndex, QVariant( featureStats.count ) );
    if ( mStatistics & QgsZonalStatistics::Sum )
      changeAttributeMap.insert( sumIndex, QVariant( featureStats.sum ) );
    if ( featureStats.count > 0 )
    {
      double mean = featureStats.sum / featureStats.count;
      if ( mStatistics & QgsZonalStatistics::Mean )
        changeAttributeMap.insert( meanIndex, QVariant( mean ) );
      if ( mStatistics & QgsZonalStatistics::Median )
      {
        std::sort( featureStats.values.begin(), featureStats.values.end() );
        int size =  featureStats.values.count();
        bool even = ( size % 2 ) < 1;
        double medianValue;
        if ( even )
        {
          medianValue = ( featureStats.values.at( size / 2 - 1 ) + featureStats.values.at( size / 2 ) ) / 2;
        }
        else //odd
        {
          medianValue = featureStats.values.at( ( size + 1 ) / 2 - 1 );
        }
        changeAttributeMap.insert( medianIndex, QVariant( medianValue ) );
      }
      if ( mStatistics & QgsZonalStatistics::StDev || mStatistics & QgsZonalStatistics::Variance )
      {
        double sumSquared = 0;
        for ( int i = 0; i < featureStats.values.count(); ++i )
        {
          double diff = featureStats.values.at( i ) - mean;
          sumSquared += diff * diff;
        }
        double variance = sumSquared / featureStats.values.count();
        if ( mStatistics & QgsZonalStatistics::StDev )
        {
          double stdev = std::pow( variance, 0.5 );
          changeAttributeMap.insert( stdevIndex, QVariant( stdev ) );
        }
        if ( mStatistics & QgsZonalStatistics::Variance )
          changeAttributeMap.insert( varianceIndex, QVariant( variance ) );
      }
      if ( mStatistics & QgsZonalStatistics::Min )
        changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) );
      if ( mStatistics & QgsZonalStatistics::Max )
        changeAttributeMap.insert( maxIndex, QVariant( featureStats.max ) );
      if ( mStatistics & QgsZonalStatistics::Range )
        changeAttributeMap.insert( rangeIndex, QVariant( featureStats.max - featureStats.min ) );
      if ( mStatistics & QgsZonalStatistics::Minority || mStatistics & QgsZonalStatistics::Majority )
      {
        QList<int> vals = featureStats.valueCount.values();
        std::sort( vals.begin(), vals.end() );
        if ( mStatistics & QgsZonalStatistics::Minority )
        {
          float minorityKey = featureStats.valueCount.key( vals.first() );
          changeAttributeMap.insert( minorityIndex, QVariant( minorityKey ) );
        }
        if ( mStatistics & QgsZonalStatistics::Majority )
        {
          float majKey = featureStats.valueCount.key( vals.last() );
          changeAttributeMap.insert( majorityIndex, QVariant( majKey ) );
        }
      }
      if ( mStatistics & QgsZonalStatistics::Variety )
        changeAttributeMap.insert( varietyIndex, QVariant( featureStats.valueCount.count() ) );
    }

    changeMap.insert( f.id(), changeAttributeMap );
    ++featureCounter;
  }

  vectorProvider->changeAttributeValues( changeMap );

  if ( feedback )
  {
    feedback->setProgress( 100 );
  }

  mPolygonLayer->updateFields();

  if ( feedback && feedback->isCanceled() )
  {
    return 9;
  }

  return 0;
}
bool QgsFeatureAction::addFeature( const QgsAttributeMap& defaultAttributes )
{
  if ( !mLayer || !mLayer->isEditable() )
    return false;

  QgsVectorDataProvider *provider = mLayer->dataProvider();

  QSettings settings;
  bool reuseLastValues = settings.value( "/qgis/digitizing/reuseLastValues", false ).toBool();
  QgsDebugMsg( QString( "reuseLastValues: %1" ).arg( reuseLastValues ) );

  // add the fields to the QgsFeature
  const QgsFields& fields = mLayer->pendingFields();
  mFeature.initAttributes( fields.count() );
  for ( int idx = 0; idx < fields.count(); ++idx )
  {
    if ( defaultAttributes.contains( idx ) )
    {
      QgsDebugMsg( QString( "Using specified default %1 for %2" ).arg( defaultAttributes.value( idx ).toString() ).arg( idx ) );
      mFeature.setAttribute( idx, defaultAttributes.value( idx ) );
    }
    else if ( reuseLastValues && mLastUsedValues.contains( mLayer ) && mLastUsedValues[ mLayer ].contains( idx ) )
    {
      QgsDebugMsg( QString( "reusing %1 for %2" ).arg( mLastUsedValues[ mLayer ][idx].toString() ).arg( idx ) );
      mFeature.setAttribute( idx, mLastUsedValues[ mLayer ][idx] );
    }
    else
    {
      mFeature.setAttribute( idx, provider->defaultValue( idx ) );
    }
  }

  bool res = false;

  mLayer->beginEditCommand( text() );

  // show the dialog to enter attribute values
  bool isDisabledAttributeValuesDlg = settings.value( "/qgis/digitizing/disable_enter_attribute_values_dialog", false ).toBool();
  // override application-wide setting with any layer setting
  switch ( mLayer->featureFormSuppress() )
  {
    case QgsVectorLayer::SuppressOn:
      isDisabledAttributeValuesDlg = true;
      break;
    case QgsVectorLayer::SuppressOff:
      isDisabledAttributeValuesDlg = false;
      break;
    case QgsVectorLayer::SuppressDefault:
      break;
  }
  if ( isDisabledAttributeValuesDlg )
  {
    res = mLayer->addFeature( mFeature );
  }
  else
  {
    QgsAttributes origValues;
    if ( reuseLastValues )
      origValues = mFeature.attributes();

    QgsAttributeDialog *dialog = newDialog( false );
    if ( dialog->exec() )
    {
      if ( reuseLastValues )
      {
        for ( int idx = 0; idx < fields.count(); ++idx )
        {
          const QgsAttributes &newValues = mFeature.attributes();
          if ( origValues[idx] != newValues[idx] )
          {
            QgsDebugMsg( QString( "saving %1 for %2" ).arg( mLastUsedValues[ mLayer ][idx].toString() ).arg( idx ) );
            mLastUsedValues[ mLayer ][idx] = newValues[idx];
          }
        }
      }

      res = mLayer->addFeature( mFeature );
    }
    else
    {
      QgsDebugMsg( "Adding feature to layer failed" );
      res = false;
    }
  }

  if ( res )
    mLayer->endEditCommand();
  else
    mLayer->destroyEditCommand();

  return res;
}