double QgsComposerScaleBar::mapWidth() const { if ( !mComposerMap ) { return 0.0; } QgsRectangle composerMapRect = *( mComposerMap->currentMapExtent() ); if ( mUnits == MapUnits ) { return composerMapRect.width(); } else { QgsDistanceArea da; da.setEllipsoidalMode( mComposition->mapSettings().hasCrsTransformEnabled() ); da.setSourceCrs( mComposition->mapSettings().destinationCrs().srsid() ); da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", "WGS84" ) ); double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ), QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ) ); if ( mUnits == QgsComposerScaleBar::Feet ) { measure /= QGis::fromUnitToUnitFactor( QGis::Feet, QGis::Meters ); } else if ( mUnits == QgsComposerScaleBar::NauticalMiles ) { measure /= QGis::fromUnitToUnitFactor( QGis::NauticalMiles, QGis::Meters ); } return measure; } }
void QgsAttributeActionDialog::insertExpression() { QString selText = actionAction->textCursor().selectedText(); // edit the selected expression if there's one if ( selText.startsWith( "[%" ) && selText.endsWith( "%]" ) ) selText = selText.mid( 2, selText.size() - 4 ); // display the expression builder QgsExpressionContext context; context << QgsExpressionContextUtils::globalScope() << QgsExpressionContextUtils::projectScope() << QgsExpressionContextUtils::layerScope( mActions->layer() ); QgsExpressionBuilderDialog dlg( mActions->layer(), selText, this, "generic", context ); dlg.setWindowTitle( tr( "Insert expression" ) ); QgsDistanceArea myDa; myDa.setSourceCrs( mActions->layer()->crs().srsid() ); myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() ); myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); dlg.setGeomCalculator( myDa ); if ( dlg.exec() == QDialog::Accepted ) { QString expression = dlg.expressionBuilder()->expressionText(); //Only add the expression if the user has entered some text. if ( !expression.isEmpty() ) { actionAction->insertPlainText( "[%" + expression + "%]" ); } } }
double QgsComposerScaleBar::mapWidth() const { if ( !mComposerMap ) { return 0.0; } QgsRectangle composerMapRect = mComposerMap->extent(); if ( mUnits == MapUnits ) { return composerMapRect.width(); } else { QgsDistanceArea da; da.setEllipsoidalMode( mComposerMap->mapRenderer()->hasCrsTransformEnabled() ); da.setSourceCrs( mComposerMap->mapRenderer()->destinationCrs().srsid() ); da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", "WGS84" ) ); double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ), QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ) ); if ( mUnits == Feet ) { measure /= 0.3048; } return measure; } }
void TestQgsDistanceArea::unit_conversions() { // Do some very simple test of conversion and units QgsDistanceArea myDa; myDa.setEllipsoidalMode( false ); double inputValue; QGis::UnitType inputUnit; QGis::UnitType outputUnit; inputValue = 10000.0; inputUnit = QGis::Meters; outputUnit = QGis::Feet; //outputUnit = QGis::Meters; // First, convert from sq.meter to sq.feet Q_NOWARN_DEPRECATED_PUSH myDa.convertMeasurement( inputValue, inputUnit, outputUnit, true ); Q_NOWARN_DEPRECATED_POP QVERIFY( qAbs( inputValue - 107639.1041671 ) <= 0.0000001 ); // The print a text unit. This is i18n, so we should ignore the unit // and use the locale settings for separation of digits. QString myTxt = QgsDistanceArea::textUnit( inputValue, 7, inputUnit, true, false ); QString expectedTxt = QLocale::system().toString( 2.4710538146717, 'g', 1 + 7 ); QVERIFY( myTxt.startsWith( expectedTxt ) ); // Ignore units for now. }
QgsAttributeActionPropertiesDialog::QgsAttributeActionPropertiesDialog( QgsVectorLayer* layer, QWidget* parent ) : QDialog( parent ) , mLayer( layer ) { setupUi( this ); // display the expression builder QgsExpressionContext context; context << QgsExpressionContextUtils::globalScope() << QgsExpressionContextUtils::projectScope() << QgsExpressionContextUtils::layerScope( mLayer ); QgsDistanceArea myDa; myDa.setSourceCrs( mLayer->crs().srsid() ); myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() ); myDa.setEllipsoid( QgsProject::instance()->ellipsoid() ); mFieldExpression->setLayer( mLayer ); mFieldExpression->setGeomCalculator( myDa ); connect( mBrowseButton, SIGNAL( clicked( bool ) ), this, SLOT( browse() ) ); connect( mInsertFieldOrExpression, SIGNAL( clicked( bool ) ), this, SLOT( insertExpressionOrField() ) ); connect( mActionName, SIGNAL( textChanged( QString ) ), this, SLOT( updateButtons() ) ); connect( mActionText, SIGNAL( textChanged() ), this, SLOT( updateButtons() ) ); updateButtons(); }
void GlobePlugin::syncExtent() { osgEarth::Util::EarthManipulator* manip = dynamic_cast<osgEarth::Util::EarthManipulator*>( mOsgViewer->getCameraManipulator() ); //rotate earth to north and perpendicular to camera manip->setRotation( osg::Quat() ); //get mapCanvas->extent().height() in meters QgsRectangle extent = mQGisIface->mapCanvas()->extent(); QgsDistanceArea dist; dist.setEllipsoidalMode( true ); //dist.setProjectionsEnabled( true ); QgsPoint ll = QgsPoint( extent.xMinimum(), extent.yMinimum() ); QgsPoint ul = QgsPoint( extent.xMinimum(), extent.yMaximum() ); double height = dist.measureLine( ll, ul ); //camera viewing angle double viewAngle = 30; //camera distance double distance = height / tan( viewAngle * osg::PI / 180 ); //c = b*cotan(B(rad)) OE_NOTICE << "map extent: " << height << " camera distance: " << distance << std::endl; osgEarth::Util::Viewpoint viewpoint( osg::Vec3d( extent.center().x(), extent.center().y(), 0.0 ), 0.0, -90.0, distance ); manip->setViewpoint( viewpoint, 4.0 ); }
void TestQgsDistanceArea::collections() { //test measuring for collections QgsDistanceArea myDa; myDa.setSourceAuthId( "EPSG:4030" ); myDa.setEllipsoidalMode( true ); myDa.setEllipsoid( "WGS84" ); //collection of lines, should be sum of line length QgsGeometry lines( QgsGeometryFactory::geomFromWkt( "GeometryCollection( LineString(0 36.53, 5.76 -48.16), LineString(0 25.54, 24.20 36.70) )" ) ); double result = myDa.measureLength( &lines ); QGSCOMPARENEAR( result, 12006159, 1 ); result = myDa.measureArea( &lines ); QVERIFY( qgsDoubleNear( result, 0 ) ); //collection of polygons QgsGeometry polys( QgsGeometryFactory::geomFromWkt( "GeometryCollection( Polygon((0 36.53, 5.76 -48.16, 0 25.54, 0 36.53)), Polygon((10 20, 15 20, 15 10, 10 20)) )" ) ); result = myDa.measureArea( &polys ); QGSCOMPARENEAR( result, 670434859475LL, 1 ); result = myDa.measureLength( &polys ); QVERIFY( qgsDoubleNear( result, 0 ) ); //mixed collection QgsGeometry mixed( QgsGeometryFactory::geomFromWkt( "GeometryCollection( LineString(0 36.53, 5.76 -48.16), LineString(0 25.54, 24.20 36.70), Polygon((0 36.53, 5.76 -48.16, 0 25.54, 0 36.53)), Polygon((10 20, 15 20, 15 10, 10 20)) )" ) ); //measure area specifically result = myDa.measureArea( &mixed ); QGSCOMPARENEAR( result, 670434859475LL, 1 ); //measure length result = myDa.measureLength( &mixed ); QGSCOMPARENEAR( result, 12006159, 1 ); }
void GlobePlugin::syncExtent() { QgsMapCanvas* mapCanvas = mQGisIface->mapCanvas(); QgsMapRenderer* mapRenderer = mapCanvas->mapRenderer(); QgsRectangle extent = mapCanvas->extent(); osgEarth::Util::EarthManipulator* manip = dynamic_cast<osgEarth::Util::EarthManipulator*>( mOsgViewer->getCameraManipulator() ); //rotate earth to north and perpendicular to camera manip->setRotation( osg::Quat() ); QgsDistanceArea dist; dist.setSourceCrs( mapRenderer->destinationCrs().srsid() ); dist.setEllipsoidalMode( mapRenderer->hasCrsTransformEnabled() ); dist.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); QgsPoint ll = QgsPoint( extent.xMinimum(), extent.yMinimum() ); QgsPoint ul = QgsPoint( extent.xMinimum(), extent.yMaximum() ); double height = dist.measureLine( ll, ul ); //camera viewing angle double viewAngle = 30; //camera distance double distance = height / tan( viewAngle * osg::PI / 180 ); //c = b*cotan(B(rad)) OE_NOTICE << "map extent: " << height << " camera distance: " << distance << std::endl; osgEarth::Util::Viewpoint viewpoint( osg::Vec3d( extent.center().x(), extent.center().y(), 0.0 ), 0.0, -90.0, distance ); manip->setViewpoint( viewpoint, 4.0 ); }
void TestQgsDistanceArea::emptyPolygon() { QgsDistanceArea da; da.setSourceCrs( 3452 ); da.setEllipsoidalMode( true ); da.setEllipsoid( "WGS84" ); //test that measuring an empty polygon doesn't crash da.measurePolygon( QList< QgsPoint >() ); }
void TestQgsDistanceArea::regression13601() { //test regression #13601 QgsDistanceArea calc; calc.setEllipsoidalMode( true ); calc.setEllipsoid( "NONE" ); calc.setSourceCrs( 1108L ); QgsGeometry geom( QgsGeometryFactory::geomFromWkt( "Polygon ((252000 1389000, 265000 1389000, 265000 1385000, 252000 1385000, 252000 1389000))" ) ); QVERIFY( qgsDoubleNear( calc.measureArea( &geom ), 52000000, 0.0001 ) ); }
void TestQgsDistanceArea::regression14675() { //test regression #14675 QgsDistanceArea calc; calc.setEllipsoidalMode( true ); calc.setEllipsoid( "GRS80" ); calc.setSourceCrs( 145L ); QgsGeometry geom( QgsGeometryFactory::geomFromWkt( "Polygon ((917593.5791854317067191 6833700.00807378999888897, 917596.43389983859378844 6833700.67099479306489229, 917599.53056440979707986 6833700.78673478215932846, 917593.5791854317067191 6833700.00807378999888897))" ) ); //lots of tolerance here - the formulas get quite unstable with small areas due to division by very small floats QGSCOMPARENEAR( calc.measureArea( &geom ), 0.83301, 0.02 ); }
QDialog* QgisAppInterface::getFeatureForm( QgsVectorLayer *l, QgsFeature &f ) { QgsDistanceArea myDa; myDa.setSourceCrs( l->crs().srsid() ); myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() ); myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); QgsAttributeDialog *dialog = new QgsAttributeDialog( l, &f, false, myDa ); return dialog->dialog(); }
double Heatmap::mapUnitsOf( double meters, QgsCoordinateReferenceSystem layerCrs ) { // Worker to transform metres input to mapunits QgsDistanceArea da; da.setSourceCrs( layerCrs.srsid() ); da.setEllipsoid( layerCrs.ellipsoidAcronym() ); if ( da.geographic() ) { da.setEllipsoidalMode( true ); } return meters / da.measureLine( QgsPoint( 0.0, 0.0 ), QgsPoint( 0.0, 1.0 ) ); }
void TestQgsDistanceArea::measureUnits() { //test regression #13610 QgsDistanceArea calc; calc.setEllipsoidalMode( false ); calc.setEllipsoid( "NONE" ); calc.setSourceCrs( 254L ); QGis::UnitType units; QgsPoint p1( 1341683.9854275715, 408256.9562717728 ); QgsPoint p2( 1349321.7807031618, 408256.9562717728 ); double result = calc.measureLine( p1, p2, units ); //no OTF, result will be in CRS unit (feet) QCOMPARE( units, QGis::Feet ); QVERIFY( qgsDoubleNear( result, 7637.7952755903825, 0.001 ) ); calc.setEllipsoidalMode( true ); calc.setEllipsoid( "WGS84" ); result = calc.measureLine( p1, p2, units ); //OTF, result will be in meters QCOMPARE( units, QGis::Meters ); QVERIFY( qgsDoubleNear( result, 2328.0988253106957, 0.001 ) ); }
double HeatmapGui::mapUnitsOf( double dist, const QgsCoordinateReferenceSystem& layerCrs ) const { // converter function to transform layer input to mapunits // so that bounding box can be updated QgsDistanceArea da; da.setSourceCrs( layerCrs.srsid() ); da.setEllipsoid( layerCrs.ellipsoidAcronym() ); if ( da.geographic() ) { da.setEllipsoidalMode( true ); } double unitDistance = da.measureLine( QgsPoint( 0.0, 0.0 ), QgsPoint( 0.0, 1.0 ) ); QgsDebugMsg( QString( "Converted %1 layer to %2 map units" ).arg( dist ).arg( dist / unitDistance ) ); return dist / unitDistance; }
void TestQgsDistanceArea::test_distances() { // Read the file of Geod data // Column 0 (first) is latitude point 1 // Column 1 is longitude point 1 // Column 3 is latitude point 2 // Column 4 is longitude point 3 // Column 6 is the resulting distance in meters on the WGS84 ellipsoid // Note: lat is north/south, so the QgsPoint should be ( long, lat ) // See http://geographiclib.sourceforge.net/html/geodesic.html#testgeod // Set up DA QgsDistanceArea myDa; myDa.setSourceAuthId( "EPSG:4030" ); myDa.setEllipsoidalMode( true ); myDa.setEllipsoid( "WGS84" ); QString myFileName = QString( TEST_DATA_DIR ) + "/GeodTest-nano.dat"; QFile myFile( myFileName ); if ( ! myFile.open( QIODevice::ReadOnly | QIODevice::Text ) ) { QFAIL( "Couldn't open file" ); return; } QTextStream in( & myFile ); while ( !in.atEnd() ) { QString line = in.readLine(); // Some test points (antipodal) does not converge with the chosen algorithm! // See calcaulator at http://www.movable-type.co.uk/scripts/latlong-vincenty.html // These are commented out. if ( line[0] != '#' ) { QStringList myLineList = line.split( ' ' ); // Split fields on space. // Create points QgsPoint p1( myLineList[1].toDouble(), myLineList[0].toDouble() ); QgsPoint p2( myLineList[4].toDouble(), myLineList[3].toDouble() ); double result = myDa.measureLine( p1, p2 ); // QgsDebugMsg( QString( "Distance from %1 to %2 is %3" ).arg( p1.toString( 15 ) ).arg( p2.toString( 15 ) ).arg( result, 0, 'g', 15 ) ); // QgsDebugMsg( QString( "Distance should be %1" ).arg( myLineList[6] ) ); // Check result is less than 0.5mm from expected. QVERIFY( qAbs( result - myLineList[6].toDouble() ) < 0.0005 ); } } }
QgsAttributeDialog *QgsFeatureAction::newDialog( bool cloneFeature ) { QgsFeature *f = cloneFeature ? new QgsFeature( *mFeature ) : mFeature; QgsAttributeEditorContext context; QgsDistanceArea myDa; myDa.setSourceCrs( mLayer->crs() ); myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() ); myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); context.setDistanceArea( myDa ); context.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() ); QgsAttributeDialog *dialog = new QgsAttributeDialog( mLayer, f, cloneFeature, NULL, true, context ); if ( mLayer->actions()->size() > 0 ) { dialog->setContextMenuPolicy( Qt::ActionsContextMenu ); QAction *a = new QAction( tr( "Run actions" ), dialog ); a->setEnabled( false ); dialog->addAction( a ); for ( int i = 0; i < mLayer->actions()->size(); i++ ) { const QgsAction &action = mLayer->actions()->at( i ); if ( !action.runable() ) continue; QgsFeature& feat = const_cast<QgsFeature&>( *dialog->feature() ); QgsFeatureAction *a = new QgsFeatureAction( action.name(), feat, mLayer, i, -1, dialog ); dialog->addAction( a ); connect( a, SIGNAL( triggered() ), a, SLOT( execute() ) ); QAbstractButton *pb = dialog->findChild<QAbstractButton *>( action.name() ); if ( pb ) connect( pb, SIGNAL( clicked() ), a, SLOT( execute() ) ); } } return dialog; }
QgsAttributeDialog* QgisAppInterface::getFeatureForm( QgsVectorLayer *l, QgsFeature &feature ) { QgsDistanceArea myDa; myDa.setSourceCrs( l->crs().srsid() ); myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() ); myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); QgsAttributeEditorContext context; context.setDistanceArea( myDa ); context.setVectorLayerTools( qgis->vectorLayerTools() ); QgsAttributeDialog *dialog = new QgsAttributeDialog( l, &feature, false, qgis, true, context ); if ( !feature.isValid() ) { dialog->setMode( QgsAttributeForm::AddFeatureMode ); } return dialog; }
void GlobePlugin::syncExtent() { QgsMapCanvas* mapCanvas = mQGisIface->mapCanvas(); const QgsMapSettings &mapSettings = mapCanvas->mapSettings(); QgsRectangle extent = mapCanvas->extent(); long epsgGlobe = 4326; QgsCoordinateReferenceSystem globeCrs; globeCrs.createFromOgcWmsCrs( QString( "EPSG:%1" ).arg( epsgGlobe ) ); // transform extent to WGS84 if ( mapSettings.destinationCrs().authid().compare( QString( "EPSG:%1" ).arg( epsgGlobe ), Qt::CaseInsensitive ) != 0 ) { QgsCoordinateReferenceSystem srcCRS( mapSettings.destinationCrs() ); QgsCoordinateTransform* coordTransform = new QgsCoordinateTransform( srcCRS, globeCrs ); extent = coordTransform->transformBoundingBox( extent ); delete coordTransform; } osgEarth::Util::EarthManipulator* manip = dynamic_cast<osgEarth::Util::EarthManipulator*>( mOsgViewer->getCameraManipulator() ); //rotate earth to north and perpendicular to camera manip->setRotation( osg::Quat() ); QgsDistanceArea dist; dist.setSourceCrs( globeCrs ); dist.setEllipsoidalMode( true ); dist.setEllipsoid( "WGS84" ); QgsPoint ll = QgsPoint( extent.xMinimum(), extent.yMinimum() ); QgsPoint ul = QgsPoint( extent.xMinimum(), extent.yMaximum() ); double height = dist.measureLine( ll, ul ); //camera viewing angle double viewAngle = 30; //camera distance double distance = height / tan( viewAngle * osg::PI / 180 ); //c = b*cotan(B(rad)) OE_NOTICE << "map extent: " << height << " camera distance: " << distance << std::endl; osgEarth::Util::Viewpoint viewpoint( osg::Vec3d( extent.center().x(), extent.center().y(), 0.0 ), 0.0, -90.0, distance ); manip->setViewpoint( viewpoint, 4.0 ); }
double QgsComposerScaleBar::mapWidth() const { if ( !mComposerMap ) { return 0.0; } QgsRectangle composerMapRect = *( mComposerMap->currentMapExtent() ); if ( mUnits == MapUnits ) { return composerMapRect.width(); } else { QgsDistanceArea da; da.setEllipsoidalMode( mComposition->mapSettings().hasCrsTransformEnabled() ); da.setSourceCrs( mComposition->mapSettings().destinationCrs().srsid() ); da.setEllipsoid( mComposition->project()->ellipsoid() ); QgsUnitTypes::DistanceUnit units = QgsUnitTypes::DistanceMeters; double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ), QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ), units ); switch ( mUnits ) { case QgsComposerScaleBar::Feet: measure /= QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceFeet, units ); break; case QgsComposerScaleBar::NauticalMiles: measure /= QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceNauticalMiles, units ); break; case QgsComposerScaleBar::Meters: measure /= QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceMeters, units ); break; case QgsComposerScaleBar::MapUnits: //avoid warning break; } return measure; } }
void QgsBullsEyeWidget::createLayer( QString layerName ) { if ( layerName.isEmpty() ) { layerName = QInputDialog::getText( this, tr( "Layer Name" ), tr( "Enter name of new layer:" ) ); } if ( !layerName.isEmpty() ) { QgsDistanceArea da; da.setEllipsoid( "WGS84" ); da.setEllipsoidalMode( true ); da.setSourceCrs( mCanvas->mapSettings().destinationCrs() ); QgsRectangle extent = mCanvas->extent(); double extentHeight = da.measureLine( QgsPoint( extent.center().x(), extent.yMinimum() ), QgsPoint( extent.center().x(), extent.yMaximum() ) ); double interval = 0.5 * extentHeight * QGis::fromUnitToUnitFactor( QGis::Meters, QGis::NauticalMiles ) / 6; // Half height divided by nr rings+1, in nm QgsBullsEyeLayer* bullEyeLayer = new QgsBullsEyeLayer( layerName ); bullEyeLayer->setup( mCanvas->extent().center(), mCanvas->mapSettings().destinationCrs(), 5, interval, 45 ); QgsMapLayerRegistry::instance()->addMapLayer( bullEyeLayer ); mLayerTreeView->setCurrentLayer( bullEyeLayer ); } }
void TestQgsDistanceArea::basic() { QgsPoint p1( 1.0, 3.0 ), p2( -2.0, -1.0 ); QgsDistanceArea daA; double resultA, resultB, resultC; daA.setEllipsoid( GEO_NONE ); resultA = daA.measureLine( p1, p2 ); QCOMPARE( resultA, 5.0 ); // Now, on an ellipsoid. Always less? daA.setSourceCrs( 3006 ); daA.setEllipsoid( "WGS84" ); daA.setEllipsoidalMode( true ); resultA = daA.measureLine( p1, p2 ); QVERIFY( resultA < 5.0 ); // Test copy constructor QgsDistanceArea daB( daA ); resultB = daB.measureLine( p1, p2 ); QCOMPARE( resultA, resultB ); // Different Ellipsoid daB.setEllipsoid( "WGS72" ); resultB = daB.measureLine( p1, p2 ); QVERIFY( ! qFuzzyCompare( resultA, resultB ) ); // Test assignment QSharedPointer<QgsDistanceArea> daC( new QgsDistanceArea ); *daC = daB; resultC = daC->measureLine( p1, p2 ); QCOMPARE( resultB, resultC ); // Use parameter setting of ellipsoid radii (from WGS72 ) daA.setEllipsoid( 6378135.0, 6378135.0 - ( 6378135.0 / 298.26 ) ); resultA = daA.measureLine( p1, p2 ); QCOMPARE( resultA, resultB ); }
QgsAttributeActionPropertiesDialog::QgsAttributeActionPropertiesDialog( QgsAction::ActionType type, const QString& description, const QString& shortTitle, const QString& iconPath, const QString& actionText, bool capture, bool showInAttributeTable, QgsVectorLayer* layer, QWidget* parent ) : QDialog( parent ) , mLayer( layer ) { setupUi( this ); mActionType->setCurrentIndex( type ); mActionName->setText( description ); mShortTitle->setText( shortTitle ); mActionIcon->setText( iconPath ); mIconPreview->setPixmap( QPixmap( iconPath ) ); mActionText->setText( actionText ); mCaptureOutput->setChecked( capture ); mShowInAttributeTable->setChecked( showInAttributeTable ); // display the expression builder QgsExpressionContext context; context << QgsExpressionContextUtils::globalScope() << QgsExpressionContextUtils::projectScope() << QgsExpressionContextUtils::layerScope( mLayer ); QgsDistanceArea myDa; myDa.setSourceCrs( mLayer->crs().srsid() ); myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() ); myDa.setEllipsoid( QgsProject::instance()->ellipsoid() ); mFieldExpression->setLayer( mLayer ); mFieldExpression->setGeomCalculator( myDa ); connect( mBrowseButton, SIGNAL( clicked( bool ) ), this, SLOT( browse() ) ); connect( mInsertFieldOrExpression, SIGNAL( clicked( bool ) ), this, SLOT( insertExpressionOrField() ) ); connect( mActionName, SIGNAL( textChanged( QString ) ), this, SLOT( updateButtons() ) ); connect( mActionText, SIGNAL( textChanged() ), this, SLOT( updateButtons() ) ); connect( mChooseIconButton, SIGNAL( clicked( bool ) ), this, SLOT( chooseIcon() ) ); updateButtons(); }
QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( QgsFeature *feature, QgsMapLayer *layer ) { // Calculate derived attributes and insert: // measure distance or area depending on geometry type QMap< QString, QString > derivedAttributes; // init distance/area calculator QString ellipsoid = QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ); QgsDistanceArea calc; calc.setEllipsoidalMode( mCanvas->hasCrsTransformEnabled() ); calc.setEllipsoid( ellipsoid ); calc.setSourceCrs( layer->crs().srsid() ); QGis::WkbType wkbType = QGis::WKBNoGeometry; QGis::GeometryType geometryType = QGis::NoGeometry; if ( feature->geometry() ) { geometryType = feature->geometry()->type(); wkbType = feature->geometry()->wkbType(); } if ( geometryType == QGis::Line ) { double dist = calc.measure( feature->geometry() ); QGis::UnitType myDisplayUnits; convertMeasurement( calc, dist, myDisplayUnits, false ); QString str = calc.textUnit( dist, 3, myDisplayUnits, false ); // dist and myDisplayUnits are out params derivedAttributes.insert( tr( "Length" ), str ); if ( wkbType == QGis::WKBLineString || wkbType == QGis::WKBLineString25D ) { // Add the start and end points in as derived attributes QgsPoint pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, feature->geometry()->asPolyline().first() ); str = QLocale::system().toString( pnt.x(), 'g', 10 ); derivedAttributes.insert( tr( "firstX", "attributes get sorted; translation for lastX should be lexically larger than this one" ), str ); str = QLocale::system().toString( pnt.y(), 'g', 10 ); derivedAttributes.insert( tr( "firstY" ), str ); pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, feature->geometry()->asPolyline().last() ); str = QLocale::system().toString( pnt.x(), 'g', 10 ); derivedAttributes.insert( tr( "lastX", "attributes get sorted; translation for firstX should be lexically smaller than this one" ), str ); str = QLocale::system().toString( pnt.y(), 'g', 10 ); derivedAttributes.insert( tr( "lastY" ), str ); } } else if ( geometryType == QGis::Polygon ) { double area = calc.measure( feature->geometry() ); double perimeter = calc.measurePerimeter( feature->geometry() ); QGis::UnitType myDisplayUnits; convertMeasurement( calc, area, myDisplayUnits, true ); // area and myDisplayUnits are out params QString str = calc.textUnit( area, 3, myDisplayUnits, true ); derivedAttributes.insert( tr( "Area" ), str ); convertMeasurement( calc, perimeter, myDisplayUnits, false ); // perimeter and myDisplayUnits are out params str = calc.textUnit( perimeter, 3, myDisplayUnits, false ); derivedAttributes.insert( tr( "Perimeter" ), str ); } else if ( geometryType == QGis::Point && ( wkbType == QGis::WKBPoint || wkbType == QGis::WKBPoint25D ) ) { // Include the x and y coordinates of the point as a derived attribute QgsPoint pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, feature->geometry()->asPoint() ); QString str = QLocale::system().toString( pnt.x(), 'g', 10 ); derivedAttributes.insert( "X", str ); str = QLocale::system().toString( pnt.y(), 'g', 10 ); derivedAttributes.insert( "Y", str ); } return derivedAttributes; }
QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWidget *parent, Qt::WindowFlags flags ) : QDialog( parent, flags ) , mDock( 0 ) , mLayer( theLayer ) { setupUi( this ); // Fix selection color on loosing focus (Windows) setStyleSheet( QgisApp::instance()->styleSheet() ); setAttribute( Qt::WA_DeleteOnClose ); QSettings settings; // Initialize the window geometry restoreGeometry( settings.value( "/Windows/BetterAttributeTable/geometry" ).toByteArray() ); QgsAttributeEditorContext context; QgsDistanceArea myDa; myDa.setSourceCrs( mLayer->crs() ); myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() ); myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); context.setDistanceArea( myDa ); context.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() ); // Initialize dual view mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), QgsFeatureRequest(), context ); // Initialize filter gui elements mFilterActionMapper = new QSignalMapper( this ); mFilterColumnsMenu = new QMenu( this ); mActionFilterColumnsMenu->setMenu( mFilterColumnsMenu ); mApplyFilterButton->setDefaultAction( mActionApplyFilter ); // Set filter icon in a couple of places QIcon filterIcon = QgsApplication::getThemeIcon( "/mActionFilter.svg" ); mActionShowAllFilter->setIcon( filterIcon ); mActionAdvancedFilter->setIcon( filterIcon ); mActionSelectedFilter->setIcon( filterIcon ); mActionVisibleFilter->setIcon( filterIcon ); mActionEditedFilter->setIcon( filterIcon ); // Connect filter signals connect( mActionAdvancedFilter, SIGNAL( triggered() ), SLOT( filterExpressionBuilder() ) ); connect( mActionShowAllFilter, SIGNAL( triggered() ), SLOT( filterShowAll() ) ); connect( mActionSelectedFilter, SIGNAL( triggered() ), SLOT( filterSelected() ) ); connect( mActionVisibleFilter, SIGNAL( triggered() ), SLOT( filterVisible() ) ); connect( mActionEditedFilter, SIGNAL( triggered() ), SLOT( filterEdited() ) ); connect( mFilterActionMapper, SIGNAL( mapped( QObject* ) ), SLOT( filterColumnChanged( QObject* ) ) ); connect( mFilterQuery, SIGNAL( returnPressed() ), SLOT( filterQueryAccepted() ) ); connect( mActionApplyFilter, SIGNAL( triggered() ), SLOT( filterQueryAccepted() ) ); // info from layer to table connect( mLayer, SIGNAL( editingStarted() ), this, SLOT( editingToggled() ) ); connect( mLayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) ); connect( mLayer, SIGNAL( layerDeleted() ), this, SLOT( close() ) ); connect( mLayer, SIGNAL( selectionChanged() ), this, SLOT( updateTitle() ) ); connect( mLayer, SIGNAL( attributeAdded( int ) ), this, SLOT( columnBoxInit() ) ); connect( mLayer, SIGNAL( attributeDeleted( int ) ), this, SLOT( columnBoxInit() ) ); // connect table info to window connect( mMainView, SIGNAL( filterChanged() ), this, SLOT( updateTitle() ) ); // info from table to application connect( this, SIGNAL( saveEdits( QgsMapLayer * ) ), QgisApp::instance(), SLOT( saveEdits( QgsMapLayer * ) ) ); bool myDockFlag = settings.value( "/qgis/dockAttributeTable", false ).toBool(); if ( myDockFlag ) { mDock = new QgsAttributeTableDock( tr( "Attribute table - %1 (%n Feature(s))", "feature count", mMainView->featureCount() ).arg( mLayer->name() ), QgisApp::instance() ); mDock->setAllowedAreas( Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea ); mDock->setWidget( this ); connect( this, SIGNAL( destroyed() ), mDock, SLOT( close() ) ); QgisApp::instance()->addDockWidget( Qt::BottomDockWidgetArea, mDock ); } columnBoxInit(); updateTitle(); mRemoveSelectionButton->setIcon( QgsApplication::getThemeIcon( "/mActionUnselectAttributes.png" ) ); mSelectedToTopButton->setIcon( QgsApplication::getThemeIcon( "/mActionSelectedToTop.png" ) ); mCopySelectedRowsButton->setIcon( QgsApplication::getThemeIcon( "/mActionCopySelected.png" ) ); mZoomMapToSelectedRowsButton->setIcon( QgsApplication::getThemeIcon( "/mActionZoomToSelected.svg" ) ); mPanMapToSelectedRowsButton->setIcon( QgsApplication::getThemeIcon( "/mActionPanToSelected.svg" ) ); mInvertSelectionButton->setIcon( QgsApplication::getThemeIcon( "/mActionInvertSelection.png" ) ); mToggleEditingButton->setIcon( QgsApplication::getThemeIcon( "/mActionToggleEditing.svg" ) ); mSaveEditsButton->setIcon( QgsApplication::getThemeIcon( "/mActionSaveEdits.svg" ) ); mDeleteSelectedButton->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteSelected.svg" ) ); mOpenFieldCalculator->setIcon( QgsApplication::getThemeIcon( "/mActionCalculateField.png" ) ); mAddAttribute->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.png" ) ); mRemoveAttribute->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.png" ) ); mTableViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionOpenTable.png" ) ); mAttributeViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionPropertyItem.png" ) ); mExpressionSelectButton->setIcon( QgsApplication::getThemeIcon( "/mIconExpressionSelect.svg" ) ); mAddFeature->setIcon( QgsApplication::getThemeIcon( "/mActionNewTableRow.png" ) ); // toggle editing bool canChangeAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues; bool canDeleteFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteFeatures; bool canAddAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes; bool canDeleteAttributes = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteAttributes; bool canAddFeatures = mLayer->dataProvider()->capabilities() & QgsVectorDataProvider::AddFeatures; mToggleEditingButton->blockSignals( true ); mToggleEditingButton->setCheckable( true ); mToggleEditingButton->setChecked( mLayer->isEditable() ); mToggleEditingButton->setEnabled( canChangeAttributes && !mLayer->isReadOnly() ); mToggleEditingButton->blockSignals( false ); mSaveEditsButton->setEnabled( canChangeAttributes && mLayer->isEditable() ); mOpenFieldCalculator->setEnabled(( canChangeAttributes || canAddAttributes ) && mLayer->isEditable() ); mDeleteSelectedButton->setEnabled( canDeleteFeatures && mLayer->isEditable() ); mAddAttribute->setEnabled( canAddAttributes && mLayer->isEditable() ); mRemoveAttribute->setEnabled( canDeleteAttributes && mLayer->isEditable() ); mAddFeature->setEnabled( canAddFeatures && mLayer->isEditable() && mLayer->geometryType() == QGis::NoGeometry ); mAddFeature->setHidden( !canAddFeatures || mLayer->geometryType() != QGis::NoGeometry ); mMainViewButtonGroup->setId( mTableViewButton, QgsDualView::AttributeTable ); mMainViewButtonGroup->setId( mAttributeViewButton, QgsDualView::AttributeEditor ); // Load default attribute table filter QgsAttributeTableFilterModel::FilterMode defaultFilterMode = ( QgsAttributeTableFilterModel::FilterMode ) settings.value( "/qgis/attributeTableBehaviour", QgsAttributeTableFilterModel::ShowAll ).toInt(); switch ( defaultFilterMode ) { case QgsAttributeTableFilterModel::ShowVisible: filterVisible(); break; case QgsAttributeTableFilterModel::ShowSelected: filterSelected(); break; case QgsAttributeTableFilterModel::ShowAll: default: filterShowAll(); break; } }
QgsFieldCalculator::QgsFieldCalculator( QgsVectorLayer* vl ) : QDialog() , mVectorLayer( vl ) , mAttributeId( -1 ) { setupUi( this ); if ( !vl ) return; builder->setLayer( vl ); builder->loadFieldNames(); populateFields(); populateOutputFieldTypes(); connect( builder, SIGNAL( expressionParsed( bool ) ), this, SLOT( setOkButtonState() ) ); QgsDistanceArea myDa; myDa.setSourceCrs( vl->crs().srsid() ); myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() ); myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); builder->setGeomCalculator( myDa ); //default values for field width and precision mOutputFieldWidthSpinBox->setValue( 10 ); mOutputFieldPrecisionSpinBox->setValue( 3 ); if ( vl->providerType() == "ogr" && vl->storageType() == "ESRI Shapefile" ) { mOutputFieldNameLineEdit->setMaxLength( 10 ); } mUpdateExistingGroupBox->setEnabled( vl->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ); mNewFieldGroupBox->setEnabled( vl->dataProvider()->capabilities() & QgsVectorDataProvider::AddAttributes ); Q_ASSERT( mNewFieldGroupBox->isEnabled() || mUpdateExistingGroupBox->isEnabled() ); if ( mNewFieldGroupBox->isEnabled() ) { mNewFieldGroupBox->setChecked( true ); } else { mNewFieldGroupBox->setToolTip( tr( "Not available for layer" ) ); mUpdateExistingGroupBox->setChecked( true ); mUpdateExistingGroupBox->setCheckable( false ); } if ( mUpdateExistingGroupBox->isEnabled() ) { mUpdateExistingGroupBox->setChecked( !mNewFieldGroupBox->isEnabled() ); } else { mUpdateExistingGroupBox->setToolTip( tr( "Not available for layer" ) ); mNewFieldGroupBox->setChecked( true ); mNewFieldGroupBox->setCheckable( false ); } mOnlyUpdateSelectedCheckBox->setChecked( vl->selectedFeaturesIds().size() > 0 ); }
QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( QgsFeature *feature, QgsMapLayer *layer, const QgsPoint& layerPoint ) { // Calculate derived attributes and insert: // measure distance or area depending on geometry type QMap< QString, QString > derivedAttributes; // init distance/area calculator QString ellipsoid = QgsProject::instance()->ellipsoid(); QgsDistanceArea calc; calc.setEllipsoidalMode( mCanvas->hasCrsTransformEnabled() ); calc.setEllipsoid( ellipsoid ); calc.setSourceCrs( layer->crs().srsid() ); QgsWkbTypes::Type wkbType = QgsWkbTypes::NoGeometry; QgsWkbTypes::GeometryType geometryType = QgsWkbTypes::NullGeometry; QgsVertexId vId; QgsPointV2 closestPoint; if ( feature->hasGeometry() ) { geometryType = feature->geometry().type(); wkbType = feature->geometry().geometry()->wkbType(); //find closest vertex to clicked point closestPoint = QgsGeometryUtils::closestVertex( *feature->geometry().geometry(), QgsPointV2( layerPoint.x(), layerPoint.y() ), vId ); } if ( QgsWkbTypes::isMultiType( wkbType ) ) { QString str = QLocale::system().toString( static_cast<const QgsGeometryCollection*>( feature->geometry().geometry() )->numGeometries() ); derivedAttributes.insert( tr( "Parts" ), str ); str = QLocale::system().toString( vId.part + 1 ); derivedAttributes.insert( tr( "Part number" ), str ); } if ( geometryType == QgsWkbTypes::LineGeometry ) { double dist = calc.measureLength( feature->geometry() ); dist = calc.convertLengthMeasurement( dist, displayDistanceUnits() ); QString str = formatDistance( dist ); derivedAttributes.insert( tr( "Length" ), str ); const QgsCurve* curve = dynamic_cast< const QgsCurve* >( feature->geometry().geometry() ); if ( curve ) { str = QLocale::system().toString( curve->nCoordinates() ); derivedAttributes.insert( tr( "Vertices" ), str ); //add details of closest vertex to identify point closestVertexAttributes( *curve, vId, layer, derivedAttributes ); // Add the start and end points in as derived attributes QgsPoint pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPoint( curve->startPoint().x(), curve->startPoint().y() ) ); str = formatXCoordinate( pnt ); derivedAttributes.insert( tr( "firstX", "attributes get sorted; translation for lastX should be lexically larger than this one" ), str ); str = formatYCoordinate( pnt ); derivedAttributes.insert( tr( "firstY" ), str ); pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPoint( curve->endPoint().x(), curve->endPoint().y() ) ); str = formatXCoordinate( pnt ); derivedAttributes.insert( tr( "lastX", "attributes get sorted; translation for firstX should be lexically smaller than this one" ), str ); str = formatYCoordinate( pnt ); derivedAttributes.insert( tr( "lastY" ), str ); } } else if ( geometryType == QgsWkbTypes::PolygonGeometry ) { double area = calc.measureArea( feature->geometry() ); area = calc.convertAreaMeasurement( area, displayAreaUnits() ); QString str = formatArea( area ); derivedAttributes.insert( tr( "Area" ), str ); double perimeter = calc.measurePerimeter( feature->geometry() ); perimeter = calc.convertLengthMeasurement( perimeter, displayDistanceUnits() ); str = formatDistance( perimeter ); derivedAttributes.insert( tr( "Perimeter" ), str ); str = QLocale::system().toString( feature->geometry().geometry()->nCoordinates() ); derivedAttributes.insert( tr( "Vertices" ), str ); //add details of closest vertex to identify point closestVertexAttributes( *feature->geometry().geometry(), vId, layer, derivedAttributes ); } else if ( geometryType == QgsWkbTypes::PointGeometry && QgsWkbTypes::flatType( wkbType ) == QgsWkbTypes::Point ) { // Include the x and y coordinates of the point as a derived attribute QgsPoint pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, feature->geometry().asPoint() ); QString str = formatXCoordinate( pnt ); derivedAttributes.insert( "X", str ); str = formatYCoordinate( pnt ); derivedAttributes.insert( "Y", str ); if ( QgsWkbTypes::hasZ( wkbType ) ) { str = QLocale::system().toString( static_cast<const QgsPointV2*>( feature->geometry().geometry() )->z(), 'g', 10 ); derivedAttributes.insert( "Z", str ); } if ( QgsWkbTypes::hasM( wkbType ) ) { str = QLocale::system().toString( static_cast<const QgsPointV2*>( feature->geometry().geometry() )->m(), 'g', 10 ); derivedAttributes.insert( "M", str ); } } return derivedAttributes; }
void QgsFieldCalculator::accept() { // Set up QgsDistanceArea each time we (re-)calculate QgsDistanceArea myDa; myDa.setSourceCrs( mVectorLayer->crs().srsid() ); myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() ); myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); QString calcString = builder->expressionText(); QgsExpression exp( calcString ); exp.setGeomCalculator( myDa ); if ( !mVectorLayer || !mVectorLayer->isEditable() ) return; if ( ! exp.prepare( mVectorLayer->pendingFields() ) ) { QMessageBox::critical( 0, tr( "Evaluation error" ), exp.evalErrorString() ); return; } QApplication::setOverrideCursor( Qt::WaitCursor ); mVectorLayer->beginEditCommand( "Field calculator" ); //update existing field if ( mUpdateExistingGroupBox->isChecked() || !mNewFieldGroupBox->isEnabled() ) { QMap<QString, int>::const_iterator fieldIt = mFieldMap.find( mExistingFieldComboBox->currentText() ); if ( fieldIt != mFieldMap.end() ) { mAttributeId = fieldIt.value(); } } else { //create new field QgsField newField( mOutputFieldNameLineEdit->text(), ( QVariant::Type ) mOutputFieldTypeComboBox->itemData( mOutputFieldTypeComboBox->currentIndex(), Qt::UserRole ).toInt(), mOutputFieldTypeComboBox->itemData( mOutputFieldTypeComboBox->currentIndex(), Qt::UserRole + 1 ).toString(), mOutputFieldWidthSpinBox->value(), mOutputFieldPrecisionSpinBox->value() ); if ( !mVectorLayer->addAttribute( newField ) ) { QMessageBox::critical( 0, tr( "Provider error" ), tr( "Could not add the new field to the provider." ) ); mVectorLayer->destroyEditCommand(); return; } //get index of the new field const QgsFields& fields = mVectorLayer->pendingFields(); for ( int idx = 0; idx < fields.count(); ++idx ) { if ( fields[idx].name() == mOutputFieldNameLineEdit->text() ) { mAttributeId = idx; break; } } if ( ! exp.prepare( mVectorLayer->pendingFields() ) ) { QMessageBox::critical( 0, tr( "Evaluation error" ), exp.evalErrorString() ); return; } } if ( mAttributeId == -1 ) { mVectorLayer->destroyEditCommand(); QApplication::restoreOverrideCursor(); return; } //go through all the features and change the new attribute QgsFeature feature; bool calculationSuccess = true; QString error; bool onlySelected = mOnlyUpdateSelectedCheckBox->isChecked(); QgsFeatureIds selectedIds = mVectorLayer->selectedFeaturesIds(); bool useGeometry = exp.needsGeometry(); int rownum = 1; bool newField = !mUpdateExistingGroupBox->isChecked(); QVariant emptyAttribute; if ( newField ) emptyAttribute = QVariant( mVectorLayer->pendingFields()[mAttributeId].type() ); QgsFeatureIterator fit = mVectorLayer->getFeatures( QgsFeatureRequest().setFlags( useGeometry ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry ) ); while ( fit.nextFeature( feature ) ) { if ( onlySelected ) { if ( !selectedIds.contains( feature.id() ) ) { continue; } } exp.setCurrentRowNumber( rownum ); QVariant value = exp.evaluate( &feature ); if ( exp.hasEvalError() ) { calculationSuccess = false; error = exp.evalErrorString(); break; } else { mVectorLayer->changeAttributeValue( feature.id(), mAttributeId, value, newField ? emptyAttribute : feature.attributes().value( mAttributeId ) ); } rownum++; } QApplication::restoreOverrideCursor(); if ( !calculationSuccess ) { QMessageBox::critical( 0, tr( "Error" ), tr( "An error occured while evaluating the calculation string:\n%1" ).arg( error ) ); mVectorLayer->destroyEditCommand(); return; } mVectorLayer->endEditCommand(); QDialog::accept(); }
QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( QgsFeature *feature, QgsMapLayer *layer, const QgsPoint& layerPoint ) { // Calculate derived attributes and insert: // measure distance or area depending on geometry type QMap< QString, QString > derivedAttributes; // init distance/area calculator QString ellipsoid = QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ); QgsDistanceArea calc; calc.setEllipsoidalMode( mCanvas->hasCrsTransformEnabled() ); calc.setEllipsoid( ellipsoid ); calc.setSourceCrs( layer->crs().srsid() ); QgsWKBTypes::Type wkbType = QgsWKBTypes::NoGeometry; QGis::GeometryType geometryType = QGis::NoGeometry; QgsVertexId vId; QgsPointV2 closestPoint; if ( feature->constGeometry() ) { geometryType = feature->constGeometry()->type(); wkbType = feature->constGeometry()->geometry()->wkbType(); //find closest vertex to clicked point closestPoint = QgsGeometryUtils::closestVertex( *feature->constGeometry()->geometry(), QgsPointV2( layerPoint.x(), layerPoint.y() ), vId ); } if ( QgsWKBTypes::isMultiType( wkbType ) ) { QString str = QLocale::system().toString( static_cast<QgsGeometryCollectionV2*>( feature->constGeometry()->geometry() )->numGeometries() ); derivedAttributes.insert( tr( "Parts" ), str ); str = QLocale::system().toString( vId.part + 1 ); derivedAttributes.insert( tr( "Part number" ), str ); } if ( geometryType == QGis::Line ) { const QgsPolyline &pline = feature->constGeometry()->asPolyline(); double dist = calc.measureLength( feature->constGeometry() ); QGis::UnitType myDisplayUnits; convertMeasurement( calc, dist, myDisplayUnits, false ); QString str = calc.textUnit( dist, 3, myDisplayUnits, false ); // dist and myDisplayUnits are out params derivedAttributes.insert( tr( "Length" ), str ); str = QLocale::system().toString( pline.size() ); derivedAttributes.insert( tr( "Vertices" ), str ); //add details of closest vertex to identify point closestVertexAttributes( *feature->constGeometry()->geometry(), vId, layer, derivedAttributes ); if ( QgsWKBTypes::flatType( wkbType ) == QgsWKBTypes::LineString ) { // Add the start and end points in as derived attributes QgsPoint pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, pline.first() ); str = QLocale::system().toString( pnt.x(), 'g', 10 ); derivedAttributes.insert( tr( "firstX", "attributes get sorted; translation for lastX should be lexically larger than this one" ), str ); str = QLocale::system().toString( pnt.y(), 'g', 10 ); derivedAttributes.insert( tr( "firstY" ), str ); pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, pline.last() ); str = QLocale::system().toString( pnt.x(), 'g', 10 ); derivedAttributes.insert( tr( "lastX", "attributes get sorted; translation for firstX should be lexically smaller than this one" ), str ); str = QLocale::system().toString( pnt.y(), 'g', 10 ); derivedAttributes.insert( tr( "lastY" ), str ); } } else if ( geometryType == QGis::Polygon ) { double area = calc.measureArea( feature->constGeometry() ); double perimeter = calc.measurePerimeter( feature->constGeometry() ); QGis::UnitType myDisplayUnits; convertMeasurement( calc, area, myDisplayUnits, true ); // area and myDisplayUnits are out params QString str = calc.textUnit( area, 3, myDisplayUnits, true ); derivedAttributes.insert( tr( "Area" ), str ); convertMeasurement( calc, perimeter, myDisplayUnits, false ); // perimeter and myDisplayUnits are out params str = calc.textUnit( perimeter, 3, myDisplayUnits, false ); derivedAttributes.insert( tr( "Perimeter" ), str ); str = QLocale::system().toString( feature->constGeometry()->geometry()->nCoordinates() ); derivedAttributes.insert( tr( "Vertices" ), str ); //add details of closest vertex to identify point closestVertexAttributes( *feature->constGeometry()->geometry(), vId, layer, derivedAttributes ); } else if ( geometryType == QGis::Point && QgsWKBTypes::flatType( wkbType ) == QgsWKBTypes::Point ) { // Include the x and y coordinates of the point as a derived attribute QgsPoint pnt = mCanvas->mapSettings().layerToMapCoordinates( layer, feature->constGeometry()->asPoint() ); QString str = QLocale::system().toString( pnt.x(), 'g', 10 ); derivedAttributes.insert( "X", str ); str = QLocale::system().toString( pnt.y(), 'g', 10 ); derivedAttributes.insert( "Y", str ); if ( QgsWKBTypes::hasZ( wkbType ) ) { str = QLocale::system().toString( static_cast<QgsPointV2*>( feature->constGeometry()->geometry() )->z(), 'g', 10 ); derivedAttributes.insert( "Z", str ); } if ( QgsWKBTypes::hasM( wkbType ) ) { str = QLocale::system().toString( static_cast<QgsPointV2*>( feature->constGeometry()->geometry() )->m(), 'g', 10 ); derivedAttributes.insert( "M", str ); } } return derivedAttributes; }
QgsDiagramProperties::QgsDiagramProperties( QgsVectorLayer* layer, QWidget* parent, QgsMapCanvas *canvas ) : QWidget( parent ) , mMapCanvas( canvas ) { mLayer = layer; if ( !layer ) { return; } setupUi( this ); // get rid of annoying outer focus rect on Mac mDiagramOptionsListWidget->setAttribute( Qt::WA_MacShowFocusRect, false ); mDiagramTypeComboBox->blockSignals( true ); QPixmap pix = QgsApplication::getThemePixmap( "diagramNone" ); mDiagramTypeComboBox->addItem( pix, tr( "No diagrams" ), "None" ); pix = QgsApplication::getThemePixmap( "pie-chart" ); mDiagramTypeComboBox->addItem( pix, tr( "Pie chart" ), DIAGRAM_NAME_PIE ); pix = QgsApplication::getThemePixmap( "text" ); mDiagramTypeComboBox->addItem( pix, tr( "Text diagram" ), DIAGRAM_NAME_TEXT ); pix = QgsApplication::getThemePixmap( "histogram" ); mDiagramTypeComboBox->addItem( pix, tr( "Histogram" ), DIAGRAM_NAME_HISTOGRAM ); mDiagramTypeComboBox->blockSignals( false ); mScaleRangeWidget->setMapCanvas( QgisApp::instance()->mapCanvas() ); mSizeFieldExpressionWidget->registerExpressionContextGenerator( this ); mBackgroundColorButton->setColorDialogTitle( tr( "Select background color" ) ); mBackgroundColorButton->setAllowAlpha( true ); mBackgroundColorButton->setContext( "symbology" ); mBackgroundColorButton->setShowNoColor( true ); mBackgroundColorButton->setNoColorString( tr( "Transparent background" ) ); mDiagramPenColorButton->setColorDialogTitle( tr( "Select pen color" ) ); mDiagramPenColorButton->setAllowAlpha( true ); mDiagramPenColorButton->setContext( "symbology" ); mDiagramPenColorButton->setShowNoColor( true ); mDiagramPenColorButton->setNoColorString( tr( "Transparent outline" ) ); mMaxValueSpinBox->setShowClearButton( false ); connect( mFixedSizeRadio, SIGNAL( toggled( bool ) ), this, SLOT( scalingTypeChanged() ) ); connect( mAttributeBasedScalingRadio, SIGNAL( toggled( bool ) ), this, SLOT( scalingTypeChanged() ) ); mDiagramUnitComboBox->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels ); mDiagramLineUnitComboBox->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels ); QgsWkbTypes::GeometryType layerType = layer->geometryType(); if ( layerType == QgsWkbTypes::UnknownGeometry || layerType == QgsWkbTypes::NullGeometry ) { mDiagramTypeComboBox->setEnabled( false ); mDiagramFrame->setEnabled( false ); } //insert placement options mPlacementComboBox->blockSignals( true ); switch ( layerType ) { case QgsWkbTypes::PointGeometry: mPlacementComboBox->addItem( tr( "Around Point" ), QgsDiagramLayerSettings::AroundPoint ); mPlacementComboBox->addItem( tr( "Over Point" ), QgsDiagramLayerSettings::OverPoint ); mLinePlacementFrame->setVisible( false ); break; case QgsWkbTypes::LineGeometry: mPlacementComboBox->addItem( tr( "Around Line" ), QgsDiagramLayerSettings::Line ); mPlacementComboBox->addItem( tr( "Over Line" ), QgsDiagramLayerSettings::Horizontal ); mLinePlacementFrame->setVisible( true ); break; case QgsWkbTypes::PolygonGeometry: mPlacementComboBox->addItem( tr( "Around Centroid" ), QgsDiagramLayerSettings::AroundPoint ); mPlacementComboBox->addItem( tr( "Over Centroid" ), QgsDiagramLayerSettings::OverPoint ); mPlacementComboBox->addItem( tr( "Perimeter" ), QgsDiagramLayerSettings::Line ); mPlacementComboBox->addItem( tr( "Inside Polygon" ), QgsDiagramLayerSettings::Horizontal ); mLinePlacementFrame->setVisible( false ); break; default: break; } mPlacementComboBox->blockSignals( false ); mLabelPlacementComboBox->addItem( tr( "Height" ), QgsDiagramSettings::Height ); mLabelPlacementComboBox->addItem( tr( "x-height" ), QgsDiagramSettings::XHeight ); mScaleDependencyComboBox->addItem( tr( "Area" ), true ); mScaleDependencyComboBox->addItem( tr( "Diameter" ), false ); mDataDefinedXComboBox->addItem( tr( "None" ), -1 ); mDataDefinedYComboBox->addItem( tr( "None" ), -1 ); mAngleOffsetComboBox->addItem( tr( "Top" ), 90 * 16 ); mAngleOffsetComboBox->addItem( tr( "Right" ), 0 ); mAngleOffsetComboBox->addItem( tr( "Bottom" ), 270 * 16 ); mAngleOffsetComboBox->addItem( tr( "Left" ), 180 * 16 ); mDataDefinedVisibilityComboBox->addItem( tr( "None" ), -1 ); QSettings settings; // reset horiz strech of left side of options splitter (set to 1 for previewing in Qt Designer) QSizePolicy policy( mDiagramOptionsListFrame->sizePolicy() ); policy.setHorizontalStretch( 0 ); mDiagramOptionsListFrame->setSizePolicy( policy ); if ( !settings.contains( QString( "/Windows/Diagrams/OptionsSplitState" ) ) ) { // set left list widget width on intial showing QList<int> splitsizes; splitsizes << 115; mDiagramOptionsSplitter->setSizes( splitsizes ); } // restore dialog, splitters and current tab mDiagramOptionsSplitter->restoreState( settings.value( QString( "/Windows/Diagrams/OptionsSplitState" ) ).toByteArray() ); mDiagramOptionsListWidget->setCurrentRow( settings.value( QString( "/Windows/Diagrams/Tab" ), 0 ).toInt() ); // field combo and expression button mSizeFieldExpressionWidget->setLayer( mLayer ); QgsDistanceArea myDa; myDa.setSourceCrs( mLayer->crs().srsid() ); myDa.setEllipsoidalMode( QgisApp::instance()->mapCanvas()->mapSettings().hasCrsTransformEnabled() ); myDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); mSizeFieldExpressionWidget->setGeomCalculator( myDa ); //insert all attributes into the combo boxes const QgsFields& layerFields = layer->fields(); for ( int idx = 0; idx < layerFields.count(); ++idx ) { QTreeWidgetItem *newItem = new QTreeWidgetItem( mAttributesTreeWidget ); QString name = QString( "\"%1\"" ).arg( layerFields.at( idx ).name() ); newItem->setText( 0, name ); newItem->setData( 0, Qt::UserRole, name ); newItem->setFlags( newItem->flags() & ~Qt::ItemIsDropEnabled ); mDataDefinedXComboBox->addItem( layerFields.at( idx ).name(), idx ); mDataDefinedYComboBox->addItem( layerFields.at( idx ).name(), idx ); mDataDefinedVisibilityComboBox->addItem( layerFields.at( idx ).name(), idx ); } const QgsDiagramRenderer* dr = layer->diagramRenderer(); if ( !dr ) //no diagram renderer yet, insert reasonable default { mDiagramTypeComboBox->blockSignals( true ); mDiagramTypeComboBox->setCurrentIndex( 0 ); mDiagramTypeComboBox->blockSignals( false ); mFixedSizeRadio->setChecked( true ); mDiagramUnitComboBox->setUnit( QgsUnitTypes::RenderMillimeters ); mDiagramLineUnitComboBox->setUnit( QgsUnitTypes::RenderMillimeters ); mLabelPlacementComboBox->setCurrentIndex( mLabelPlacementComboBox->findText( tr( "x-height" ) ) ); mDiagramSizeSpinBox->setEnabled( true ); mDiagramSizeSpinBox->setValue( 15 ); mLinearScaleFrame->setEnabled( false ); mIncreaseMinimumSizeSpinBox->setEnabled( false ); mIncreaseMinimumSizeLabel->setEnabled( false ); mBarWidthSpinBox->setValue( 5 ); mScaleVisibilityGroupBox->setChecked( layer->hasScaleBasedVisibility() ); mScaleRangeWidget->setScaleRange( 1.0 / layer->maximumScale(), 1.0 / layer->minimumScale() ); // caution: layer uses scale denoms, widget uses true scales mShowAllCheckBox->setChecked( true ); mDataDefinedVisibilityGroupBox->setChecked( false ); mCheckBoxAttributeLegend->setChecked( true ); mCheckBoxSizeLegend->setChecked( false ); mSizeLegendSymbol.reset( QgsMarkerSymbol::createSimple( QgsStringMap() ) ); switch ( layerType ) { case QgsWkbTypes::PointGeometry: mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( QgsDiagramLayerSettings::AroundPoint ) ); break; case QgsWkbTypes::LineGeometry: mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( QgsDiagramLayerSettings::Line ) ); chkLineAbove->setChecked( true ); chkLineBelow->setChecked( false ); chkLineOn->setChecked( false ); chkLineOrientationDependent->setChecked( false ); break; case QgsWkbTypes::PolygonGeometry: mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( QgsDiagramLayerSettings::AroundPoint ) ); break; case QgsWkbTypes::UnknownGeometry: case QgsWkbTypes::NullGeometry: break; } mBackgroundColorButton->setColor( QColor( 255, 255, 255, 255 ) ); //force a refresh of widget status to match diagram type on_mDiagramTypeComboBox_currentIndexChanged( mDiagramTypeComboBox->currentIndex() ); } else // already a diagram renderer present { //single category renderer or interpolated one? if ( dr->rendererName() == "SingleCategory" ) { mFixedSizeRadio->setChecked( true ); } else { mAttributeBasedScalingRadio->setChecked( true ); } mDiagramSizeSpinBox->setEnabled( mFixedSizeRadio->isChecked() ); mLinearScaleFrame->setEnabled( mAttributeBasedScalingRadio->isChecked() ); mCheckBoxAttributeLegend->setChecked( dr->attributeLegend() ); mCheckBoxSizeLegend->setChecked( dr->sizeLegend() ); mSizeLegendSymbol.reset( dr->sizeLegendSymbol() ? dr->sizeLegendSymbol()->clone() : QgsMarkerSymbol::createSimple( QgsStringMap() ) ); QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( mSizeLegendSymbol.data(), mButtonSizeLegendSymbol->iconSize() ); mButtonSizeLegendSymbol->setIcon( icon ); //assume single category or linearly interpolated diagram renderer for now QList<QgsDiagramSettings> settingList = dr->diagramSettings(); if ( !settingList.isEmpty() ) { mDiagramFrame->setEnabled( settingList.at( 0 ).enabled ); mDiagramFont = settingList.at( 0 ).font; QSizeF size = settingList.at( 0 ).size; mBackgroundColorButton->setColor( settingList.at( 0 ).backgroundColor ); mTransparencySpinBox->setValue( settingList.at( 0 ).transparency * 100.0 / 255.0 ); mTransparencySlider->setValue( mTransparencySpinBox->value() ); mDiagramPenColorButton->setColor( settingList.at( 0 ).penColor ); mPenWidthSpinBox->setValue( settingList.at( 0 ).penWidth ); mDiagramSizeSpinBox->setValue(( size.width() + size.height() ) / 2.0 ); // caution: layer uses scale denoms, widget uses true scales mScaleRangeWidget->setScaleRange( 1.0 / ( settingList.at( 0 ).maxScaleDenominator > 0 ? settingList.at( 0 ).maxScaleDenominator : layer->maximumScale() ), 1.0 / ( settingList.at( 0 ).minScaleDenominator > 0 ? settingList.at( 0 ).minScaleDenominator : layer->minimumScale() ) ); mScaleVisibilityGroupBox->setChecked( settingList.at( 0 ).scaleBasedVisibility ); mDiagramUnitComboBox->setUnit( settingList.at( 0 ).sizeType ); mDiagramUnitComboBox->setMapUnitScale( settingList.at( 0 ).sizeScale ); mDiagramLineUnitComboBox->setUnit( settingList.at( 0 ).lineSizeUnit ); mDiagramLineUnitComboBox->setMapUnitScale( settingList.at( 0 ).lineSizeScale ); if ( settingList.at( 0 ).labelPlacementMethod == QgsDiagramSettings::Height ) { mLabelPlacementComboBox->setCurrentIndex( 0 ); } else { mLabelPlacementComboBox->setCurrentIndex( 1 ); } mAngleOffsetComboBox->setCurrentIndex( mAngleOffsetComboBox->findData( settingList.at( 0 ).angleOffset ) ); mOrientationLeftButton->setProperty( "direction", QgsDiagramSettings::Left ); mOrientationRightButton->setProperty( "direction", QgsDiagramSettings::Right ); mOrientationUpButton->setProperty( "direction", QgsDiagramSettings::Up ); mOrientationDownButton->setProperty( "direction", QgsDiagramSettings::Down ); switch ( settingList.at( 0 ).diagramOrientation ) { case QgsDiagramSettings::Left: mOrientationLeftButton->setChecked( true ); break; case QgsDiagramSettings::Right: mOrientationRightButton->setChecked( true ); break; case QgsDiagramSettings::Up: mOrientationUpButton->setChecked( true ); break; case QgsDiagramSettings::Down: mOrientationDownButton->setChecked( true ); break; } mBarWidthSpinBox->setValue( settingList.at( 0 ).barWidth ); mIncreaseSmallDiagramsCheck->setChecked( settingList.at( 0 ).minimumSize != 0 ); mIncreaseMinimumSizeSpinBox->setEnabled( mIncreaseSmallDiagramsCheck->isChecked() ); mIncreaseMinimumSizeLabel->setEnabled( mIncreaseSmallDiagramsCheck->isChecked() ); mIncreaseMinimumSizeSpinBox->setValue( settingList.at( 0 ).minimumSize ); if ( settingList.at( 0 ).scaleByArea ) { mScaleDependencyComboBox->setCurrentIndex( 0 ); } else { mScaleDependencyComboBox->setCurrentIndex( 1 ); } QList< QColor > categoryColors = settingList.at( 0 ).categoryColors; QList< QString > categoryAttributes = settingList.at( 0 ).categoryAttributes; QList< QString > categoryLabels = settingList.at( 0 ).categoryLabels; QList< QString >::const_iterator catIt = categoryAttributes.constBegin(); QList< QColor >::const_iterator coIt = categoryColors.constBegin(); QList< QString >::const_iterator labIt = categoryLabels.constBegin(); for ( ; catIt != categoryAttributes.constEnd(); ++catIt, ++coIt, ++labIt ) { QTreeWidgetItem *newItem = new QTreeWidgetItem( mDiagramAttributesTreeWidget ); newItem->setText( 0, *catIt ); newItem->setData( 0, Qt::UserRole, *catIt ); newItem->setFlags( newItem->flags() & ~Qt::ItemIsDropEnabled ); QColor col( *coIt ); col.setAlpha( 255 ); newItem->setBackground( 1, QBrush( col ) ); newItem->setText( 2, *labIt ); newItem->setFlags( newItem->flags() | Qt::ItemIsEditable ); } } if ( dr->rendererName() == "LinearlyInterpolated" ) { const QgsLinearlyInterpolatedDiagramRenderer* lidr = dynamic_cast<const QgsLinearlyInterpolatedDiagramRenderer*>( dr ); if ( lidr ) { mDiagramSizeSpinBox->setEnabled( false ); mLinearScaleFrame->setEnabled( true ); mMaxValueSpinBox->setValue( lidr->upperValue() ); mSizeSpinBox->setValue(( lidr->upperSize().width() + lidr->upperSize().height() ) / 2 ); if ( lidr->classificationAttributeIsExpression() ) { mSizeFieldExpressionWidget->setField( lidr->classificationAttributeExpression() ); } else { mSizeFieldExpressionWidget->setField( mLayer->fields().at( lidr->classificationAttribute() ).name() ); } } } const QgsDiagramLayerSettings *dls = layer->diagramLayerSettings(); if ( dls ) { mDiagramDistanceSpinBox->setValue( dls->distance() ); mPrioritySlider->setValue( dls->getPriority() ); mZIndexSpinBox->setValue( dls->getZIndex() ); mDataDefinedXComboBox->setCurrentIndex( mDataDefinedXComboBox->findData( dls->xPosColumn ) ); mDataDefinedYComboBox->setCurrentIndex( mDataDefinedYComboBox->findData( dls->yPosColumn ) ); if ( dls->xPosColumn != -1 || dls->yPosColumn != -1 ) { mDataDefinedPositionGroupBox->setChecked( true ); } mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( dls->getPlacement() ) ); chkLineAbove->setChecked( dls->linePlacementFlags() & QgsDiagramLayerSettings::AboveLine ); chkLineBelow->setChecked( dls->linePlacementFlags() & QgsDiagramLayerSettings::BelowLine ); chkLineOn->setChecked( dls->linePlacementFlags() & QgsDiagramLayerSettings::OnLine ); if ( !( dls->linePlacementFlags() & QgsDiagramLayerSettings::MapOrientation ) ) chkLineOrientationDependent->setChecked( true ); mShowAllCheckBox->setChecked( dls->showAllDiagrams() ); mDataDefinedVisibilityComboBox->setCurrentIndex( mDataDefinedVisibilityComboBox->findData( dls->showColumn ) ); if ( dls->showColumn != -1 ) { mDataDefinedVisibilityGroupBox->setChecked( true ); } } if ( dr->diagram() ) { mDiagramType = dr->diagram()->diagramName(); mDiagramTypeComboBox->blockSignals( true ); mDiagramTypeComboBox->setCurrentIndex( settingList.at( 0 ).enabled ? mDiagramTypeComboBox->findData( mDiagramType ) : 0 ); mDiagramTypeComboBox->blockSignals( false ); //force a refresh of widget status to match diagram type on_mDiagramTypeComboBox_currentIndexChanged( mDiagramTypeComboBox->currentIndex() ); if ( mDiagramTypeComboBox->currentIndex() == -1 ) { QMessageBox::warning( this, tr( "Unknown diagram type." ), tr( "The diagram type '%1' is unknown. A default type is selected for you." ).arg( mDiagramType ), QMessageBox::Ok ); mDiagramTypeComboBox->setCurrentIndex( mDiagramTypeComboBox->findData( DIAGRAM_NAME_PIE ) ); } } } // if ( !dr ) connect( mAddAttributeExpression, SIGNAL( clicked() ), this, SLOT( showAddAttributeExpressionDialog() ) ); connect( mTransparencySlider, SIGNAL( valueChanged( int ) ), mTransparencySpinBox, SLOT( setValue( int ) ) ); connect( mTransparencySpinBox, SIGNAL( valueChanged( int ) ), mTransparencySlider, SLOT( setValue( int ) ) ); }