void QgsCustomProjectionDialog::buttonBox_accepted() { //Update the current CRS: int i = leNameList->currentIndex().row(); if ( i != -1 ) { mCustomCRSnames[i] = leName->text(); mCustomCRSparameters[i] = teParameters->toPlainText(); } QgsDebugMsg( "We save the modified CRS." ); //Check if all CRS are valid: QgsCoordinateReferenceSystem CRS; for ( int i = 0; i < mCustomCRSids.size(); ++i ) { CRS.createFromProj4( mCustomCRSparameters[i] ); if ( !CRS.isValid() ) { QMessageBox::information( this, tr( "QGIS Custom Projection" ), tr( "The proj4 definition of '%1' is not valid." ).arg( mCustomCRSnames[i] ) ); return; } } //Modify the CRS changed: bool saveSuccess = true; for ( int i = 0; i < mCustomCRSids.size(); ++i ) { CRS.createFromProj4( mCustomCRSparameters[i] ); //Test if we just added this CRS (if it has no existing ID) if ( mCustomCRSids[i].isEmpty() ) { saveSuccess &= saveCrs( CRS, mCustomCRSnames[i], QString(), true ); } else { if ( mExistingCRSnames[mCustomCRSids[i]] != mCustomCRSnames[i] || mExistingCRSparameters[mCustomCRSids[i]] != mCustomCRSparameters[i] ) { saveSuccess &= saveCrs( CRS, mCustomCRSnames[i], mCustomCRSids[i], false ); } } if ( ! saveSuccess ) { QgsDebugMsg( QString( "Error when saving CRS '%1'" ).arg( mCustomCRSnames[i] ) ); } } QgsDebugMsg( "We remove the deleted CRS." ); for ( int i = 0; i < mDeletedCRSs.size(); ++i ) { saveSuccess &= deleteCrs( mDeletedCRSs[i] ); if ( ! saveSuccess ) { QgsDebugMsg( QString( "Problem for layer '%1'" ).arg( mCustomCRSparameters[i] ) ); } } if ( saveSuccess ) { accept(); } }
void QgsCustomProjectionDialog::populateList() { //Setup connection to the existing custom CRS database: sqlite3 *myDatabase; const char *myTail; sqlite3_stmt *myPreparedStatement; int myResult; //check the db is available myResult = sqlite3_open_v2( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase, SQLITE_OPEN_READONLY, NULL ); if ( myResult != SQLITE_OK ) { QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) ); // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. Q_ASSERT( myResult == SQLITE_OK ); } QString mySql = "select srs_id,description,parameters from tbl_srs"; QgsDebugMsg( QString( "Query to populate existing list:%1" ).arg( mySql ) ); myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail ); // XXX Need to free memory from the error msg if one is set if ( myResult == SQLITE_OK ) { QTreeWidgetItem *newItem; QString id, name, parameters; QgsCoordinateReferenceSystem crs; while ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW ) { id = QString::fromUtf8(( char* ) sqlite3_column_text( myPreparedStatement, 0 ) ); name = QString::fromUtf8(( char* ) sqlite3_column_text( myPreparedStatement, 1 ) ); parameters = QString::fromUtf8(( char* ) sqlite3_column_text( myPreparedStatement, 2 ) ); crs.createFromProj4( parameters ); existingCRSnames[id] = name; existingCRSparameters[id] = crs.toProj4(); newItem = new QTreeWidgetItem( leNameList, QStringList() ); newItem->setText( QGIS_CRS_NAME_COLUMN, name ); newItem->setText( QGIS_CRS_ID_COLUMN, id ); newItem->setText( QGIS_CRS_PARAMETERS_COLUMN, crs.toProj4() ); } } else { QgsDebugMsg( QString( "Populate list query failed: %1" ).arg( mySql ) ); } sqlite3_finalize( myPreparedStatement ); sqlite3_close( myDatabase ); leNameList->sortByColumn( QGIS_CRS_NAME_COLUMN, Qt::AscendingOrder ); QTreeWidgetItemIterator it( leNameList ); while ( *it ) { QString id = ( *it )->text( QGIS_CRS_ID_COLUMN ); customCRSids.push_back( id ); customCRSnames.push_back( existingCRSnames[id] ); customCRSparameters.push_back( existingCRSparameters[id] ); it++; } }
void QgsOptions::on_pbnSelectProjection_clicked() { QSettings settings; QgsGenericProjectionSelector * mySelector = new QgsGenericProjectionSelector( this ); //find out srs id of current proj4 string QgsCoordinateReferenceSystem refSys; if ( refSys.createFromProj4( txtGlobalWkt->toPlainText() ) ) { mySelector->setSelectedCrsId( refSys.srsid() ); } if ( mySelector->exec() ) { //! @todo changes this control name in gui to txtGlobalProjString txtGlobalWkt->setText( mySelector->selectedProj4String() ); QgsDebugMsg( QString( "------ Global Default Projection Selection set to ----------\n%1" ).arg( txtGlobalWkt->toPlainText() ) ); } else { QgsDebugMsg( "------ Global Default Projection Selection change cancelled ----------" ); QApplication::restoreOverrideCursor(); } }
void QgsCustomProjectionDialog::populateList() { //Setup connection to the existing custom CRS database: sqlite3_database_unique_ptr database; sqlite3_statement_unique_ptr preparedStatement; //check the db is available int result = database.open_v2( QgsApplication::qgisUserDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr ); if ( result != SQLITE_OK ) { QgsDebugMsg( QString( "Can't open database: %1" ).arg( database.errorMessage() ) ); // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. Q_ASSERT( result == SQLITE_OK ); } QString sql = QStringLiteral( "select srs_id,description,parameters from tbl_srs" ); QgsDebugMsg( QString( "Query to populate existing list:%1" ).arg( sql ) ); preparedStatement = database.prepare( sql, result ); if ( result == SQLITE_OK ) { QgsCoordinateReferenceSystem crs; while ( preparedStatement.step() == SQLITE_ROW ) { QString id = preparedStatement.columnAsText( 0 ); QString name = preparedStatement.columnAsText( 1 ); QString parameters = preparedStatement.columnAsText( 2 ); crs.createFromProj4( parameters ); mExistingCRSnames[id] = name; mExistingCRSparameters[id] = crs.toProj4(); QTreeWidgetItem *newItem = new QTreeWidgetItem( leNameList, QStringList() ); newItem->setText( QgisCrsNameColumn, name ); newItem->setText( QgisCrsIdColumn, id ); newItem->setText( QgisCrsParametersColumn, crs.toProj4() ); } } else { QgsDebugMsg( QString( "Populate list query failed: %1" ).arg( sql ) ); } preparedStatement.reset(); leNameList->sortByColumn( QgisCrsNameColumn, Qt::AscendingOrder ); QTreeWidgetItemIterator it( leNameList ); while ( *it ) { QString id = ( *it )->text( QgisCrsIdColumn ); mCustomCRSids.push_back( id ); mCustomCRSnames.push_back( mExistingCRSnames[id] ); mCustomCRSparameters.push_back( mExistingCRSparameters[id] ); it++; } }
bool QgsDistanceArea::setEllipsoid( const QString& ellipsoid ) { QString radius, parameter2; // // SQLITE3 stuff - get parameters for selected ellipsoid // sqlite3 *myDatabase; const char *myTail; sqlite3_stmt *myPreparedStatement; int myResult; // Shortcut if ellipsoid is none. if ( ellipsoid == GEO_NONE ) { mEllipsoid = GEO_NONE; return true; } // Check if we have a custom projection, and set from text string. // Format is "PARAMETER:<semi-major axis>:<semi minor axis> // Numbers must be with (optional) decimal point and no other separators (C locale) // Distances in meters. Flattening is calculated. if ( ellipsoid.startsWith( "PARAMETER" ) ) { QStringList paramList = ellipsoid.split( ':' ); bool semiMajorOk, semiMinorOk; double semiMajor = paramList[1].toDouble( & semiMajorOk ); double semiMinor = paramList[2].toDouble( & semiMinorOk ); if ( semiMajorOk && semiMinorOk ) { return setEllipsoid( semiMajor, semiMinor ); } else { return false; } } // Continue with PROJ.4 list of ellipsoids. //check the db is available myResult = sqlite3_open_v2( QgsApplication::srsDbFilePath().toUtf8().data(), &myDatabase, SQLITE_OPEN_READONLY, nullptr ); if ( myResult ) { QgsMessageLog::logMessage( QObject::tr( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) ); // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. return false; } // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list QString mySql = "select radius, parameter2 from tbl_ellipsoid where acronym='" + ellipsoid + '\''; myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail ); // XXX Need to free memory from the error msg if one is set if ( myResult == SQLITE_OK ) { if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW ) { radius = QString( reinterpret_cast< const char * >( sqlite3_column_text( myPreparedStatement, 0 ) ) ); parameter2 = QString( reinterpret_cast< const char * >( sqlite3_column_text( myPreparedStatement, 1 ) ) ); } } // close the sqlite3 statement sqlite3_finalize( myPreparedStatement ); sqlite3_close( myDatabase ); // row for this ellipsoid wasn't found? if ( radius.isEmpty() || parameter2.isEmpty() ) { QgsDebugMsg( QString( "setEllipsoid: no row in tbl_ellipsoid for acronym '%1'" ).arg( ellipsoid ) ); return false; } // get major semiaxis if ( radius.left( 2 ) == "a=" ) mSemiMajor = radius.mid( 2 ).toDouble(); else { QgsDebugMsg( QString( "setEllipsoid: wrong format of radius field: '%1'" ).arg( radius ) ); return false; } // get second parameter // one of values 'b' or 'f' is in field parameter2 // second one must be computed using formula: invf = a/(a-b) if ( parameter2.left( 2 ) == "b=" ) { mSemiMinor = parameter2.mid( 2 ).toDouble(); mInvFlattening = mSemiMajor / ( mSemiMajor - mSemiMinor ); } else if ( parameter2.left( 3 ) == "rf=" ) { mInvFlattening = parameter2.mid( 3 ).toDouble(); mSemiMinor = mSemiMajor - ( mSemiMajor / mInvFlattening ); } else { QgsDebugMsg( QString( "setEllipsoid: wrong format of parameter2 field: '%1'" ).arg( parameter2 ) ); return false; } QgsDebugMsg( QString( "setEllipsoid: a=%1, b=%2, 1/f=%3" ).arg( mSemiMajor ).arg( mSemiMinor ).arg( mInvFlattening ) ); // get spatial ref system for ellipsoid QString proj4 = "+proj=longlat +ellps=" + ellipsoid + " +no_defs"; QgsCoordinateReferenceSystem destCRS; destCRS.createFromProj4( proj4 ); //TODO: createFromProj4 used to save to the user database any new CRS // this behavior was changed in order to separate creation and saving. // Not sure if it necessary to save it here, should be checked by someone // familiar with the code (should also give a more descriptive name to the generated CRS) if ( destCRS.srsid() == 0 ) { QString myName = QString( " * %1 (%2)" ) .arg( QObject::tr( "Generated CRS", "A CRS automatically generated from layer info get this prefix for description" ), destCRS.toProj4() ); destCRS.saveAsUserCRS( myName ); } // // set transformation from project CRS to ellipsoid coordinates mCoordTransform->setDestCRS( destCRS ); mEllipsoid = ellipsoid; // precalculate some values for area calculations computeAreaInit(); return true; }
bool QgsDistanceArea::setEllipsoid( const QString& ellipsoid ) { QString radius, parameter2; // // SQLITE3 stuff - get parameters for selected ellipsoid // sqlite3 *myDatabase; const char *myTail; sqlite3_stmt *myPreparedStatement; int myResult; // Shortcut if ellipsoid is none. if ( ellipsoid == "NONE" ) { mEllipsoid = "NONE"; return true; } //check the db is available myResult = sqlite3_open( QgsApplication::srsDbFilePath().toUtf8().data(), &myDatabase ); if ( myResult ) { QgsMessageLog::logMessage( QObject::tr( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) ); // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. return false; } // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list QString mySql = "select radius, parameter2 from tbl_ellipsoid where acronym='" + ellipsoid + "'"; myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail ); // XXX Need to free memory from the error msg if one is set if ( myResult == SQLITE_OK ) { if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW ) { radius = QString(( char * )sqlite3_column_text( myPreparedStatement, 0 ) ); parameter2 = QString(( char * )sqlite3_column_text( myPreparedStatement, 1 ) ); } } // close the sqlite3 statement sqlite3_finalize( myPreparedStatement ); sqlite3_close( myDatabase ); // row for this ellipsoid wasn't found? if ( radius.isEmpty() || parameter2.isEmpty() ) { QgsDebugMsg( QString( "setEllipsoid: no row in tbl_ellipsoid for acronym '%1'" ).arg( ellipsoid ) ); return false; } // get major semiaxis if ( radius.left( 2 ) == "a=" ) mSemiMajor = radius.mid( 2 ).toDouble(); else { QgsDebugMsg( QString( "setEllipsoid: wrong format of radius field: '%1'" ).arg( radius ) ); return false; } // get second parameter // one of values 'b' or 'f' is in field parameter2 // second one must be computed using formula: invf = a/(a-b) if ( parameter2.left( 2 ) == "b=" ) { mSemiMinor = parameter2.mid( 2 ).toDouble(); mInvFlattening = mSemiMajor / ( mSemiMajor - mSemiMinor ); } else if ( parameter2.left( 3 ) == "rf=" ) { mInvFlattening = parameter2.mid( 3 ).toDouble(); mSemiMinor = mSemiMajor - ( mInvFlattening / mSemiMajor ); } else { QgsDebugMsg( QString( "setEllipsoid: wrong format of parameter2 field: '%1'" ).arg( parameter2 ) ); return false; } QgsDebugMsg( QString( "setEllipsoid: a=%1, b=%2, 1/f=%3" ).arg( mSemiMajor ).arg( mSemiMinor ).arg( mInvFlattening ) ); // get spatial ref system for ellipsoid QString proj4 = "+proj=longlat +ellps=" + ellipsoid + " +no_defs"; QgsCoordinateReferenceSystem destCRS; destCRS.createFromProj4( proj4 ); // set transformation from project CRS to ellipsoid coordinates mCoordTransform->setDestCRS( destCRS ); // precalculate some values for area calculations computeAreaInit(); mEllipsoid = ellipsoid; return true; }
bool QgsNorthArrowPlugin::calculateNorthDirection() { QgsMapCanvas& mapCanvas = *( qGisInterface->mapCanvas() ); bool goodDirn = false; if ( mapCanvas.layerCount() > 0 ) { QgsCoordinateReferenceSystem outputCRS = mapCanvas.mapRenderer()->destinationSrs(); if ( outputCRS.isValid() && !outputCRS.geographicFlag() ) { // Use a geographic CRS to get lat/long to work out direction QgsCoordinateReferenceSystem ourCRS; ourCRS.createFromProj4( "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" ); assert( ourCRS.isValid() ); QgsCoordinateTransform transform( outputCRS, ourCRS ); QgsRectangle extent = mapCanvas.extent(); QgsPoint p1( extent.center() ); // A point a bit above p1. XXX assumes that y increases up!! // May need to involve the maptopixel transform if this proves // to be a problem. QgsPoint p2( p1.x(), p1.y() + extent.height() * 0.25 ); // project p1 and p2 to geographic coords try { p1 = transform.transform( p1 ); p2 = transform.transform( p2 ); } catch ( QgsException &e ) { Q_UNUSED( e ); // just give up QgsDebugMsg( "North Arrow: Transformation error, quitting" ); return false; } // Work out the value of the initial heading one takes to go // from point p1 to point p2. The north direction is then that // many degrees anti-clockwise or vertical. // Take some care to not divide by zero, etc, and ensure that we // get sensible results for all possible values for p1 and p2. goodDirn = true; double angle = 0.0; // convert to radians for the equations below p1.multiply( PI / 180.0 ); p2.multiply( PI / 180.0 ); double y = sin( p2.x() - p1.x() ) * cos( p2.y() ); double x = cos( p1.y() ) * sin( p2.y() ) - sin( p1.y() ) * cos( p2.y() ) * cos( p2.x() - p1.x() ); if ( y > 0.0 ) { if ( x > TOL ) angle = atan( y / x ); else if ( x < -TOL ) angle = PI - atan( -y / x ); else angle = 0.5 * PI; } else if ( y < 0.0 ) { if ( x > TOL ) angle = -atan( -y / x ); else if ( x < -TOL ) angle = atan( y / x ) - PI; else angle = 1.5 * PI; } else { if ( x > TOL ) angle = 0.0; else if ( x < -TOL ) angle = PI; else { angle = 0.0; // p1 = p2 goodDirn = false; } } // And set the angle of the north arrow. Perhaps do something // different if goodDirn = false. mRotationInt = static_cast<int>( round( fmod( 360.0 - angle * 180.0 / PI, 360.0 ) ) ); } else { // For geographic CRS and for when there are no layers, set the // direction back to the default mRotationInt = 0; } } return goodDirn; }