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 QgsMapToolSimplify::canvasPressEvent( QMouseEvent * e ) { QgsVectorLayer * vlayer = currentVectorLayer(); QgsPoint layerCoords = mCanvas->getCoordinateTransform()->toMapPoint( e->pos().x(), e->pos().y() ); double r = QgsTolerance::vertexSearchRadius( vlayer, mCanvas->mapRenderer() ); QgsRectangle selectRect = QgsRectangle( layerCoords.x() - r, layerCoords.y() - r, layerCoords.x() + r, layerCoords.y() + r ); vlayer->select( QgsAttributeList(), selectRect, true ); QgsGeometry* geometry = QgsGeometry::fromPoint( layerCoords ); double minDistance = DBL_MAX; double currentDistance; QgsFeature f; mSelectedFeature.setValid( false ); while ( vlayer->nextFeature( f ) ) { currentDistance = geometry->distance( *( f.geometry() ) ); if ( currentDistance < minDistance ) { minDistance = currentDistance; mSelectedFeature = f; } } // delete previous rubberband (if any) removeRubberBand(); if ( mSelectedFeature.isValid() ) { if ( mSelectedFeature.geometry()->isMultipart() ) { QMessageBox::critical( 0, tr( "Unsupported operation" ), tr( "Multipart features are not supported for simplification." ) ); return; } mRubberBand = new QgsRubberBand( mCanvas ); mRubberBand->setToGeometry( mSelectedFeature.geometry(), 0 ); mRubberBand->setColor( Qt::red ); mRubberBand->setWidth( 2 ); mRubberBand->show(); //calculate boudaries for slidebar if ( calculateSliderBoudaries() ) { // show dialog as a non-modal window mSimplifyDialog->show(); } else { QMessageBox::warning( 0, tr( "Unsupported operation" ), tr( "This feature cannot be simplified. Check if feature has enough vertices to be simplified." ) ); } } }
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 ); }
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; }
void GlobePlugin::setupMap() { QSettings settings; QString cacheDirectory = settings.value( "cache/directory", QgsApplication::qgisSettingsDirPath() + "cache" ).toString(); TMSCacheOptions cacheOptions; cacheOptions.setPath( cacheDirectory.toStdString() ); MapOptions mapOptions; mapOptions.cache() = cacheOptions; osgEarth::Map *map = new osgEarth::Map( mapOptions ); //Default image layer GDALOptions driverOptions; driverOptions.url() = QDir::cleanPath( QgsApplication::pkgDataPath() + "/globe/world.tif" ).toStdString(); ImageLayerOptions layerOptions( "world", driverOptions ); layerOptions.cacheEnabled() = false; map->addImageLayer( new osgEarth::ImageLayer( layerOptions ) ); MapNodeOptions nodeOptions; //nodeOptions.proxySettings() = //nodeOptions.enableLighting() = false; //LoadingPolicy loadingPolicy( LoadingPolicy::MODE_SEQUENTIAL ); TerrainOptions terrainOptions; //terrainOptions.loadingPolicy() = loadingPolicy; terrainOptions.compositingTechnique() = TerrainOptions::COMPOSITING_MULTITEXTURE_FFP; nodeOptions.setTerrainOptions( terrainOptions ); // The MapNode will render the Map object in the scene graph. mMapNode = new osgEarth::MapNode( map, nodeOptions ); //prefill cache if ( !QFile::exists( cacheDirectory + "/worldwind_srtm" ) ) { copyFolder( QgsApplication::pkgDataPath() + "/globe/data/worldwind_srtm", cacheDirectory + "/globe/worldwind_srtm" ); } mRootNode = new osg::Group(); mRootNode->addChild( mMapNode ); // Add layers to the map layersChanged(); // model placement utils mElevationManager = new osgEarth::Util::ElevationManager( mMapNode->getMap() ); mElevationManager->setTechnique( osgEarth::Util::ElevationManager::TECHNIQUE_GEOMETRIC ); mElevationManager->setMaxTilesToCache( 50 ); mObjectPlacer = new osgEarth::Util::ObjectPlacer( mMapNode ); // place 3D model on point layer if ( mSettingsDialog.modelLayer() && !mSettingsDialog.modelPath().isEmpty() ) { osg::Node* model = osgDB::readNodeFile( mSettingsDialog.modelPath().toStdString() ); if ( model ) { QgsVectorLayer* layer = mSettingsDialog.modelLayer(); QgsAttributeList fetchAttributes; layer->select( fetchAttributes ); //TODO: select only visible features QgsFeature feature; while ( layer->nextFeature( feature ) ) { QgsPoint point = feature.geometry()->asPoint(); placeNode( model, point.y(), point.x() ); } } } }
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 QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas, QgsGeometry* selectGeometry, bool doContains, bool doDifference, bool singleSelect ) { if ( selectGeometry->type() != QGis::Polygon ) { return; } QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( canvas ); if ( vlayer == NULL ) { return; } // toLayerCoordinates will throw an exception for any 'invalid' points in // the rubber band. // For example, if you project a world map onto a globe using EPSG 2163 // and then click somewhere off the globe, an exception will be thrown. QgsGeometry selectGeomTrans( *selectGeometry ); if ( canvas->mapRenderer()->hasCrsTransformEnabled() ) { try { QgsCoordinateTransform ct( canvas->mapRenderer()->destinationCrs(), vlayer->crs() ); selectGeomTrans.transform( ct ); } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); // catch exception for 'invalid' point and leave existing selection unchanged QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) ); QMessageBox::warning( canvas, QObject::tr( "CRS Exception" ), QObject::tr( "Selection extends beyond layer's coordinate system." ) ); return; } } QApplication::setOverrideCursor( Qt::WaitCursor ); QgsDebugMsg( "Selection layer: " + vlayer->name() ); QgsDebugMsg( "Selection polygon: " + selectGeomTrans.exportToWkt() ); QgsDebugMsg( "doContains: " + QString( doContains ? "T" : "F" ) ); QgsDebugMsg( "doDifference: " + QString( doDifference ? "T" : "F" ) ); vlayer->select( QgsAttributeList(), selectGeomTrans.boundingBox(), true, true ); QgsFeatureIds newSelectedFeatures; QgsFeature f; QgsFeatureId closestFeatureId = 0; bool foundSingleFeature = false; double closestFeatureDist = std::numeric_limits<double>::max(); while ( vlayer->nextFeature( f ) ) { QgsGeometry* g = f.geometry(); if ( doContains ) { if ( !selectGeomTrans.contains( g ) ) continue; } else { if ( !selectGeomTrans.intersects( g ) ) continue; } if ( singleSelect ) { foundSingleFeature = true; double distance = g->distance( selectGeomTrans ); if ( distance <= closestFeatureDist ) { closestFeatureDist = distance; closestFeatureId = f.id(); } } else { newSelectedFeatures.insert( f.id() ); } } if ( singleSelect && foundSingleFeature ) { newSelectedFeatures.insert( closestFeatureId ); } QgsDebugMsg( "Number of new selected features: " + QString::number( newSelectedFeatures.size() ) ); QgsFeatureIds layerSelectedFeatures; if ( doDifference ) { layerSelectedFeatures = vlayer->selectedFeaturesIds(); QgsFeatureIds::const_iterator i = newSelectedFeatures.constEnd(); while ( i != newSelectedFeatures.constBegin() ) { --i; if ( layerSelectedFeatures.contains( *i ) ) { layerSelectedFeatures.remove( *i ); } else { layerSelectedFeatures.insert( *i ); } } } else { layerSelectedFeatures = newSelectedFeatures; } vlayer->setSelectedFeatures( layerSelectedFeatures ); QApplication::restoreOverrideCursor(); }
void QgsMapToolReshape::canvasReleaseEvent( QMouseEvent * e ) { //check if we operate on a vector layer //todo: move this to a function in parent class to avoid duplication QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ); if ( !vlayer ) { QMessageBox::information( 0, tr( "Not a vector layer" ), tr( "The current layer is not a vector layer" ) ); return; } if ( !vlayer->isEditable() ) { QMessageBox::information( 0, tr( "Layer not editable" ), tr( "Cannot edit the vector layer. Use 'Toggle Editing' to make it editable." ) ); return; } //add point to list and to rubber band int error = addVertex( e->pos() ); if ( error == 1 ) { //current layer is not a vector layer return; } else if ( error == 2 ) { //problem with coordinate transformation QMessageBox::information( 0, tr( "Coordinate transform error" ), tr( "Cannot transform the point to the layers coordinate system" ) ); return; } if ( e->button() == Qt::LeftButton ) { startCapturing(); } else if ( e->button() == Qt::RightButton ) { //find out bounding box of mCaptureList if ( size() < 1 ) { stopCapturing(); return; } QgsPoint firstPoint = points().at( 0 ); QgsRectangle bbox( firstPoint.x(), firstPoint.y(), firstPoint.x(), firstPoint.y() ); for ( int i = 1; i < size(); ++i ) { bbox.combineExtentWith( points().at( i ).x(), points().at( i ).y() ); } //query all the features that intersect bounding box of capture line vlayer->select( QgsAttributeList(), bbox, true, false ); QgsFeature f; int reshapeReturn; bool reshapeDone = false; vlayer->beginEditCommand( tr( "Reshape" ) ); while ( vlayer->nextFeature( f ) ) { //query geometry //call geometry->reshape(mCaptureList) //register changed geometry in vector layer QgsGeometry* geom = f.geometry(); if ( geom ) { reshapeReturn = geom->reshapeGeometry( points() ); if ( reshapeReturn == 0 ) { vlayer->changeGeometry( f.id(), geom ); reshapeDone = true; } } } if ( reshapeDone ) { vlayer->endEditCommand(); } else { vlayer->destroyEditCommand(); } stopCapturing(); } }
QWidget *QgsAttributeEditor::createAttributeEditor( QWidget *parent, QWidget *editor, QgsVectorLayer *vl, int idx, const QVariant &value ) { if ( !vl ) return NULL; QWidget *myWidget = NULL; QgsVectorLayer::EditType editType = vl->editType( idx ); const QgsField &field = vl->pendingFields()[idx]; QVariant::Type myFieldType = field.type(); 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: { QSettings settings; QString nullValue = settings.value( "qgis/nullValue", "NULL" ).toString(); const QgsVectorLayer::ValueRelationData &data = vl->valueRelation( idx ); QgsVectorLayer *layer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( data.mLayer ) ); QMap< QString, QString > map; if ( layer ) { int ki = layer->fieldNameIndex( data.mOrderByValue ? data.mValue : data.mKey ); int vi = layer->fieldNameIndex( data.mOrderByValue ? data.mKey : data.mValue ); if ( data.mAllowNull ) map.insert( nullValue, tr( "(no selection)" ) ); if ( ki >= 0 && vi >= 0 ) { layer->select( QgsAttributeList() << ki << vi, QgsRectangle(), false ); QgsFeature f; while ( layer->nextFeature( f ) ) { map.insert( f.attributeMap()[ ki ].toString(), f.attributeMap()[ vi ].toString() ); } } } QComboBox *cb = comboBox( editor, parent ); if ( cb ) { 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; } } 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 = NULL; 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 = NULL; 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 = NULL; 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 = NULL; 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::UniqueValuesEditable: case QgsVectorLayer::Immutable: { QLineEdit *le = NULL; QTextEdit *te = NULL; QPlainTextEdit *pte = NULL; if ( editor ) { le = qobject_cast<QLineEdit *>( editor ); te = qobject_cast<QTextEdit *>( editor ); pte = qobject_cast<QPlainTextEdit *>( 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 ); } le->setValidator( new QgsFieldValidator( le, field ) ); myWidget = le; } if ( te ) { te->setAcceptRichText( true ); myWidget = te; } if ( pte ) { myWidget = pte; } if ( myWidget ) { myWidget->setDisabled( editType == QgsVectorLayer::Immutable ); } } break; case QgsVectorLayer::Hidden: myWidget = NULL; break; case QgsVectorLayer::FileName: case QgsVectorLayer::Calendar: { QPushButton *pb = NULL; 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; } setValue( myWidget, vl, idx, value ); return myWidget; }
void QgsOfflineEditing::copyVectorLayer( QgsVectorLayer* layer, sqlite3* db, const QString& offlineDbPath ) { if ( layer == NULL ) { return; } QString tableName = layer->name(); // create table QString sql = QString( "CREATE TABLE '%1' (" ).arg( tableName ); QString delim = ""; const QgsFieldMap& fields = layer->dataProvider()->fields(); for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end() ; ++it ) { QString dataType = ""; QVariant::Type type = it.value().type(); if ( type == QVariant::Int ) { dataType = "INTEGER"; } else if ( type == QVariant::Double ) { dataType = "REAL"; } else if ( type == QVariant::String ) { dataType = "TEXT"; } else { showWarning( tr( "Unknown data type %1" ).arg( type ) ); } sql += delim + QString( "'%1' %2" ).arg( it.value().name() ).arg( dataType ); delim = ","; } sql += ")"; // add geometry column QString geomType = ""; switch ( layer->wkbType() ) { case QGis::WKBPoint: geomType = "POINT"; break; case QGis::WKBMultiPoint: geomType = "MULTIPOINT"; break; case QGis::WKBLineString: geomType = "LINESTRING"; break; case QGis::WKBMultiLineString: geomType = "MULTILINESTRING"; break; case QGis::WKBPolygon: geomType = "POLYGON"; break; case QGis::WKBMultiPolygon: geomType = "MULTIPOLYGON"; break; default: showWarning( tr( "QGIS wkbType %1 not supported" ).arg( layer->wkbType() ) ); break; }; QString sqlAddGeom = QString( "SELECT AddGeometryColumn('%1', 'Geometry', %2, '%3', 2)" ) .arg( tableName ) .arg( layer->crs().authid().startsWith( "EPSG:", Qt::CaseInsensitive ) ? layer->crs().authid().mid( 5 ).toLong() : 0 ) .arg( geomType ); // create spatial index QString sqlCreateIndex = QString( "SELECT CreateSpatialIndex('%1', 'Geometry')" ).arg( tableName ); int rc = sqlExec( db, sql ); if ( rc == SQLITE_OK ) { rc = sqlExec( db, sqlAddGeom ); if ( rc == SQLITE_OK ) { rc = sqlExec( db, sqlCreateIndex ); } } if ( rc == SQLITE_OK ) { // add new layer QgsVectorLayer* newLayer = new QgsVectorLayer( QString( "dbname='%1' table='%2'(Geometry) sql=" ) .arg( offlineDbPath ).arg( tableName ), tableName + " (offline)", "spatialite" ); if ( newLayer->isValid() ) { // mark as offline layer newLayer->setCustomProperty( CUSTOM_PROPERTY_IS_OFFLINE_EDITABLE, true ); // store original layer source newLayer->setCustomProperty( CUSTOM_PROPERTY_REMOTE_SOURCE, layer->source() ); newLayer->setCustomProperty( CUSTOM_PROPERTY_REMOTE_PROVIDER, layer->providerType() ); // copy style bool hasLabels = layer->hasLabelsEnabled(); if ( !hasLabels ) { // NOTE: copy symbology before adding the layer so it is displayed correctly copySymbology( layer, newLayer ); } // register this layer with the central layers registry QgsMapLayerRegistry::instance()->addMapLayer( newLayer ); if ( hasLabels ) { // NOTE: copy symbology of layers with labels enabled after adding to project, as it will crash otherwise (WORKAROUND) copySymbology( layer, newLayer ); } // TODO: layer order // copy features newLayer->startEditing(); QgsFeature f; // NOTE: force feature recount for PostGIS layer, else only visible features are counted, before iterating over all features (WORKAROUND) layer->setSubsetString( "" ); layer->select( layer->pendingAllAttributesList(), QgsRectangle(), true, false ); mProgressDialog->setupProgressBar( tr( "%v / %m features copied" ), layer->featureCount() ); int featureCount = 1; QList<int> remoteFeatureIds; while ( layer->nextFeature( f ) ) { remoteFeatureIds << f.id(); // NOTE: Spatialite provider ignores position of geometry column // fill gap in QgsAttributeMap if geometry column is not last (WORKAROUND) int column = 0; QgsAttributeMap newAttrMap; QgsAttributeMap attrMap = f.attributeMap(); for ( QgsAttributeMap::const_iterator it = attrMap.begin(); it != attrMap.end(); ++it ) { newAttrMap.insert( column++, it.value() ); } f.setAttributeMap( newAttrMap ); newLayer->addFeature( f, false ); mProgressDialog->setProgressValue( featureCount++ ); } if ( newLayer->commitChanges() ) { mProgressDialog->setupProgressBar( tr( "%v / %m features processed" ), layer->featureCount() ); featureCount = 1; // update feature id lookup int layerId = getOrCreateLayerId( db, newLayer->id() ); QList<int> offlineFeatureIds; newLayer->select( QgsAttributeList(), QgsRectangle(), false, false ); while ( newLayer->nextFeature( f ) ) { offlineFeatureIds << f.id(); } // NOTE: insert fids in this loop, as the db is locked during newLayer->nextFeature() sqlExec( db, "BEGIN" ); for ( int i = 0; i < remoteFeatureIds.size(); i++ ) { addFidLookup( db, layerId, offlineFeatureIds.at( i ), remoteFeatureIds.at( i ) ); mProgressDialog->setProgressValue( featureCount++ ); } sqlExec( db, "COMMIT" ); } else { showWarning( newLayer->commitErrors().join( "\n" ) ); } // remove remote layer QgsMapLayerRegistry::instance()->removeMapLayer( layer->id() ); } } }