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 ); }
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 ); } } }
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; }
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(); }
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 ); }
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; }
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; } }
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; }
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++ ); } }
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 ); } }
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 ); } }
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; }
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; }
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; }
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 ); }
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; }