Exemplo n.º 1
0
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++;
  }
}
Exemplo n.º 2
0
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++;
  }
}
Exemplo n.º 3
0
void QgsCustomProjectionDialog::on_pbnAdd_clicked()
{
  QString name = tr( "new CRS" );
  QString id = "";
  QgsCoordinateReferenceSystem parameters;

  QTreeWidgetItem* 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, parameters.toProj4() );
  customCRSnames.push_back( name );
  customCRSids.push_back( id );
  customCRSparameters.push_back( parameters.toProj4() );
  leNameList->setCurrentItem( newItem );
}
Exemplo n.º 4
0
void QgsCustomProjectionDialog::pbnCopyCRS_clicked()
{
  std::unique_ptr< QgsProjectionSelectionDialog > selector = qgis::make_unique< QgsProjectionSelectionDialog >( this );
  if ( selector->exec() )
  {
    QgsCoordinateReferenceSystem srs = selector->crs();
    if ( leNameList->topLevelItemCount() == 0 )
    {
      pbnAdd_clicked();
    }
    teParameters->setPlainText( srs.toProj4() );
    mCustomCRSparameters[leNameList->currentIndex().row()] = srs.toProj4();
    leNameList->currentItem()->setText( QgisCrsParametersColumn, srs.toProj4() );

  }
}
Exemplo n.º 5
0
void QgsCustomProjectionDialog::pbnAdd_clicked()
{
  QString name = tr( "new CRS" );
  QString id;
  QgsCoordinateReferenceSystem parameters;

  QTreeWidgetItem *newItem = new QTreeWidgetItem( leNameList, QStringList() );

  newItem->setText( QgisCrsNameColumn, name );
  newItem->setText( QgisCrsIdColumn, id );
  newItem->setText( QgisCrsParametersColumn, parameters.toProj4() );
  mCustomCRSnames.push_back( name );
  mCustomCRSids.push_back( id );
  mCustomCRSparameters.push_back( parameters.toProj4() );
  leNameList->setCurrentItem( newItem );
  leName->selectAll();
  leName->setFocus();
}
Exemplo n.º 6
0
void QgsCustomProjectionDialog::on_pbnCopyCRS_clicked()
{
  QgsGenericProjectionSelector *mySelector = new QgsGenericProjectionSelector( this );
  if ( mySelector->exec() )
  {
    QgsCoordinateReferenceSystem srs;
    QString id = mySelector->selectedAuthId();
    srs.createFromOgcWmsCrs( id );
    if ( leNameList->topLevelItemCount() == 0 )
    {
      on_pbnAdd_clicked();
    }
    teParameters->setPlainText( srs.toProj4() );
    customCRSparameters[leNameList->currentIndex().row()] = srs.toProj4();
    leNameList->currentItem()->setText( QGIS_CRS_PARAMETERS_COLUMN, srs.toProj4() );

  }
  delete mySelector;
}
Exemplo n.º 7
0
void QgsSLDConfigParser::setCrsForLayer( const QDomElement& layerElem, QgsMapLayer* ml ) const
{
  //create CRS if specified as attribute ("epsg" or "proj")
  QString epsg = layerElem.attribute( QStringLiteral( "epsg" ), QLatin1String( "" ) );
  if ( !epsg.isEmpty() )
  {
    bool conversionOk;
    int epsgnr = epsg.toInt( &conversionOk );
    if ( conversionOk )
    {
      //set spatial ref sys
      QgsCoordinateReferenceSystem srs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:%1" ).arg( epsgnr ) );
      ml->setCrs( srs );
    }
  }
  else
  {
    QString projString = layerElem.attribute( QStringLiteral( "proj" ), QLatin1String( "" ) );
    if ( !projString.isEmpty() )
    {
      QgsCoordinateReferenceSystem srs = QgsCoordinateReferenceSystem::fromProj4( projString );
      //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 ( srs.srsid() == 0 )
      {
        QString myName = QStringLiteral( " * %1 (%2)" )
                         .arg( QObject::tr( "Generated CRS", "A CRS automatically generated from layer info get this prefix for description" ),
                               srs.toProj4() );
        srs.saveAsUserCrs( myName );
      }

      ml->setCrs( srs );
    }
  }
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
bool QgsCustomProjectionDialog::saveCRS( QgsCoordinateReferenceSystem myCRS, QString myName, QString myId, bool newEntry )
{
  QString mySql;
  int return_id;
  QString myProjectionAcronym  = myCRS.projectionAcronym();
  QString myEllipsoidAcronym   =  myCRS.ellipsoidAcronym();
  QgsDebugMsg( QString( "Saving a CRS:%1, %2, %3" ).arg( myName ).arg( myCRS.toProj4() ).arg( newEntry ) );
  if ( newEntry )
  {
    return_id = myCRS.saveAsUserCRS( myName );
    if ( return_id == -1 )
      return false;
    else
      myId = QString::number( return_id );
  }
  else
  {
    mySql = "update tbl_srs set description="
            + quotedValue( myName )
            + ",projection_acronym=" + quotedValue( myProjectionAcronym )
            + ",ellipsoid_acronym=" + quotedValue( myEllipsoidAcronym )
            + ",parameters=" + quotedValue( myCRS.toProj4() )
            + ",is_geo=0" // <--shamelessly hard coded for now
            + " where srs_id=" + quotedValue( myId )
            ;
    QgsDebugMsg( mySql );
    sqlite3      *myDatabase;
    const char   *myTail;
    sqlite3_stmt *myPreparedStatement;
    int           myResult;
    //check if the db is available
    myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8(), &myDatabase );
    if ( myResult != SQLITE_OK )
    {
      QgsDebugMsg( QString( "Can't open database: %1 \n please notify  QGIS developers of this error \n %2 (file name) " ).arg( sqlite3_errmsg( myDatabase ) ).arg( QgsApplication::qgisUserDbFilePath() ) );
      // XXX This will likely never happen since on open, sqlite creates the
      //     database if it does not exist.
      Q_ASSERT( myResult == SQLITE_OK );
    }
    myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
    sqlite3_step( myPreparedStatement );
    // XXX Need to free memory from the error msg if one is set
    if ( myResult != SQLITE_OK )
    {
      QgsDebugMsg( QString( "failed to write to database in custom projection dialog: %1 [%2]" ).arg( mySql ).arg( sqlite3_errmsg( myDatabase ) ) );
    }

    sqlite3_finalize( myPreparedStatement );
    // close sqlite3 db
    sqlite3_close( myDatabase );
    if ( myResult != SQLITE_OK )
      return false;
  }
  existingCRSparameters[myId] = myCRS.toProj4();
  existingCRSnames[myId] = myName;

  QgsCRSCache::instance()->updateCRSCache( QString( "USER:%1" ).arg( myId ) );

  // If we have a projection acronym not in the user db previously, add it.
  // This is a must, or else we can't select it from the vw_srs table.
  // Actually, add it always and let the SQL PRIMARY KEY remove duplicates.
  insertProjection( myProjectionAcronym );

  return true;
}
Exemplo n.º 10
0
void QgsGrassModule::run()
{
  QgsDebugMsg( "called." );

  if ( mProcess.state() == QProcess::Running )
  {
    mProcess.kill();
    mRunButton->setText( tr( "Run" ) );
  }
  else
  {
    //QString command;
    QStringList arguments;

    //mProcess.clearArguments();
    //mProcess.addArgument( mXName );
    //command = mXName;

    // Check if options are ready
    QStringList readyErrors = mOptions->ready();
    if ( readyErrors.size() > 0 )
    {
      QString err;
      for ( int i = 0; i < readyErrors.size(); i++ )
      {
        err.append( readyErrors.at( i ) + "<br>" );
      }
      QMessageBox::warning( 0, tr( "Warning" ), err );
      return;
    }

    // Check/set region
    struct Cell_head tempWindow;
    bool resetRegion = false;
    QgsCoordinateReferenceSystem crs;
    if ( mOptions->requestsRegion() ) // direct always
    {
      if ( !mOptions->inputRegion( &tempWindow, crs, false ) )
      {
        QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot get input region" ) );
        return;
      }
      resetRegion = true;
    }
    else if ( mOptions->usesRegion() )
    {
      QStringList outsideRegion = mOptions->checkRegion();
      if ( outsideRegion.size() > 0 )
      {
        QMessageBox questionBox( QMessageBox::Question, tr( "Warning" ),
                                 tr( "Input %1 outside current region!" ).arg( outsideRegion.join( QStringLiteral( "," ) ) ),
                                 QMessageBox::Ok | QMessageBox::Cancel );
        QPushButton *resetButton = nullptr;
        if ( QgsGrass::versionMajor() > 6 || ( QgsGrass::versionMajor() == 6 && QgsGrass::versionMinor() >= 1 ) )
        {
          resetButton = questionBox.addButton( tr( "Use Input Region" ), QMessageBox::DestructiveRole );
        }
        questionBox.exec();
        QAbstractButton *clicked = questionBox.clickedButton();
        if ( clicked == questionBox.button( QMessageBox::Cancel ) )
          return;
        if ( clicked == resetButton )
          resetRegion = true;

        if ( resetRegion )
        {
          if ( !mOptions->inputRegion( &tempWindow, crs, true ) )
          {
            QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot get input region" ) );
            return;
          }
        }
      }
    }

    // In direct mode user is warned by select file dialog
    if ( !mDirect )
    {
      // Check if output exists
      QStringList outputExists = mOptions->checkOutput();
      if ( outputExists.size() > 0 )
      {
        QMessageBox::StandardButton ret = QMessageBox::question( 0, QStringLiteral( "Warning" ),
                                          tr( "Output %1 exists! Overwrite?" ).arg( outputExists.join( QStringLiteral( "," ) ) ),
                                          QMessageBox::Ok | QMessageBox::Cancel );

        if ( ret == QMessageBox::Cancel )
          return;

        arguments.append( QStringLiteral( "--o" ) );
      }
    }

    // Remember output maps
    mOutputVector = mOptions->output( QgsGrassModuleOption::Vector );
    QgsDebugMsg( QString( "mOutputVector.size() = %1" ).arg( mOutputVector.size() ) );
    mOutputRaster = mOptions->output( QgsGrassModuleOption::Raster );
    QgsDebugMsg( QString( "mOutputRaster.size() = %1" ).arg( mOutputRaster.size() ) );
    mSuccess = false;
    mViewButton->setEnabled( false );

    QStringList list = mOptions->arguments();
    list << arguments;

    QStringList argumentsHtml;
    for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
    {
      QgsDebugMsg( "option: " + ( *it ) );
      //command.append ( " " + *it );
      arguments.append( *it );
      //mProcess.addArgument( *it );

      // Quote options with special characters so that user
      // can copy-paste-run the command
      if ( it->contains( QRegExp( "[ <>\\$|;&]" ) ) )
      {
        argumentsHtml.append( "\"" + *it + "\"" );
      }
      else
      {
        argumentsHtml.append( *it );
      }
    }

    /* WARNING - TODO: there was a bug in GRASS 6.0.0 / 6.1.CVS (< 2005-04-29):
     * db_start_driver set GISRC_MODE_MEMORY eviroment variable to 1 if
     * G_get_gisrc_mode() == G_GISRC_MODE_MEMORY but the variable wasn't unset
     * if  G_get_gisrc_mode() == G_GISRC_MODE_FILE. Because QGIS GRASS provider starts drivers in
     * G_GISRC_MODE_MEMORY mode, the variable remains set in variable when a module is run
     * -> unset GISRC_MODE_MEMORY. Remove later once 6.1.x / 6.0.1 is widespread.
    *   */
    putenv( ( char * ) "GISRC_MODE_MEMORY" ); // unset

    mOutputTextBrowser->clear();

    QProcessEnvironment environment = processEnvironment( mDirect );
    environment.insert( QStringLiteral( "GRASS_HTML_BROWSER" ), QgsGrassUtils::htmlBrowserPath() );

    // Warning: it is not useful to write requested region to WIND file and
    //          reset then to original because it is reset before
    //          the region is read by a module even if waitForStarted() is used
    //          -> necessary to pass region as environment variable
    //             but the feature is available in GRASS 6.1 only since 23.3.2006
    if ( resetRegion )
    {
      QString reg = QgsGrass::regionString( &tempWindow );
      QgsDebugMsg( "reg: " + reg );
      environment.insert( QStringLiteral( "GRASS_REGION" ), reg );
    }

    if ( mDirect )
    {
      QStringList variables;
      setDirectLibraryPath( environment );
#ifdef Q_OS_WIN
      variables << "PATH";
#elif defined(Q_OS_MAC)
      variables << "DYLD_LIBRARY_PATH";
#else
      variables << QStringLiteral( "LD_LIBRARY_PATH" );
#endif
      environment.insert( QStringLiteral( "QGIS_PREFIX_PATH" ), QgsApplication::prefixPath() );
      if ( crs.isValid() ) // it should always be valid
      {
        environment.insert( QStringLiteral( "QGIS_GRASS_CRS" ), crs.toProj4() );
      }
      // Suppress debug output
      environment.insert( QStringLiteral( "QGIS_DEBUG" ), QStringLiteral( "-1" ) );

      // Print some important variables
      variables << QStringLiteral( "QGIS_PREFIX_PATH" ) << QStringLiteral( "QGIS_GRASS_CRS" ) << QStringLiteral( "GRASS_REGION" );
      Q_FOREACH ( const QString &v, variables )
      {
        mOutputTextBrowser->append( v + "=" + environment.value( v ) + "<BR>" );
      }
    }

    QString commandHtml = mXName + " " + argumentsHtml.join( QStringLiteral( " " ) );

    QgsDebugMsg( "command: " + commandHtml );
    commandHtml.replace( QLatin1String( "&" ), QLatin1String( "&amp;" ) );
    commandHtml.replace( QLatin1String( "<" ), QLatin1String( "&lt;" ) );
    commandHtml.replace( QLatin1String( ">" ), QLatin1String( "&gt;" ) );
    mOutputTextBrowser->append( "<B>" +  commandHtml + "</B>" );

    // I was not able to get scripts working on Windows
    // via QProcess and sh.exe (MinGW). g.parser runs wellQProcessEnvironment::systemE
    // and it sets parameters correctly as environment variables
    // but it fails (without error) to re-run the script with
    // execlp(). And I could not figure out why it fails.
    // Because of this problem we simulate here what g.parser
    // normally does and that way we can avoid it.

    QStringList execArguments = QgsGrassModule::execArguments( mXName );

    if ( execArguments.size() == 0 )
    {
      QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot find module %1" ).arg( mXName ) );
      return;
    }

#ifdef Q_OS_WIN
    // we already know it exists from execArguments()
    QString exe = QgsGrass::findModule( mXName );
    QFileInfo fi( exe );
    if ( !fi.isExecutable() )
    {
      QStringList usedFlagNames;

      // Set environment variables
      for ( int i = 0; i < arguments.size(); i++ )
      {
        QString arg = arguments.at( i );
        //QString env;
        if ( arg.at( 0 ) == '-' ) //flag
        {
          //env = "GIS_FLAG_" + QString( arg.at( 1 ).toUpper() ) + "=1";
          environment.insert( "GIS_FLAG_" + QString( arg.at( 1 ).toUpper() ), "1" );
          usedFlagNames.append( arg.at( 1 ) );
        }
        else // option
        {
          QStringList opt = arg.split( "=" );
          //env = "GIS_OPT_" + opt.takeFirst().toUpper();
          //env += "=" + opt.join( "=" ); // rejoin rest
          environment.insert( "GIS_OPT_" + opt.takeFirst().toUpper(), opt.join( "=" ) );
        }
        //environment.append( env );
      }

      // Set remaining flags
      QStringList allFlagNames = mOptions->flagNames();
      for ( int i = 0; i < allFlagNames.size(); i++ )
      {
        bool used = false;
        for ( int j = 0; j < usedFlagNames.size(); j++ )
        {
          if ( usedFlagNames.at( j ) == allFlagNames.at( i ) )
          {
            used = true;
            break;
          }
        }
        if ( used )
          continue;
        //QString env = "GIS_FLAG_"
        //              + QString( allFlagNames.at( i ).toUpper() )
        //              + "=0";
        //QgsDebugMsg( "set: " + env );
        //environment.append( env );
        environment.insert( "GIS_FLAG_" + QString( allFlagNames.at( i ).toUpper() ), "0" );
      }

      arguments.clear();
      arguments.append( "@ARGS_PARSED@" );
    }
#endif

    QString cmd = execArguments.takeFirst();
    execArguments += arguments;

    // Freeze output vector on Windows
    mOptions->freezeOutput();

    mProcess.setProcessEnvironment( environment );
    mProcess.start( cmd, execArguments );
    emit moduleStarted();

    mProcess.waitForStarted();
    if ( mProcess.state() != QProcess::Running )
    {
      QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot start module: %1" ).arg( mProcess.errorString() ) );
      return;
    }

    mTabWidget->setCurrentIndex( 1 );
    mRunButton->setText( tr( "Stop" ) );
  }
Exemplo n.º 11
0
bool QgsCustomProjectionDialog::saveCrs( QgsCoordinateReferenceSystem parameters, const QString &name, const QString &existingId, bool newEntry )
{
  QString id = existingId;
  QString sql;
  int returnId;
  QString projectionAcronym = parameters.projectionAcronym();
  QString ellipsoidAcronym = parameters.ellipsoidAcronym();
  QgsDebugMsg( QString( "Saving a CRS:%1, %2, %3" ).arg( name, parameters.toProj4() ).arg( newEntry ) );
  if ( newEntry )
  {
    returnId = parameters.saveAsUserCrs( name );
    if ( returnId == -1 )
      return false;
    else
      id = QString::number( returnId );
  }
  else
  {
    sql = "update tbl_srs set description="
          + quotedValue( name )
          + ",projection_acronym=" + quotedValue( projectionAcronym )
          + ",ellipsoid_acronym=" + quotedValue( ellipsoidAcronym )
          + ",parameters=" + quotedValue( parameters.toProj4() )
          + ",is_geo=0" // <--shamelessly hard coded for now
          + " where srs_id=" + quotedValue( id )
          ;
    QgsDebugMsg( sql );
    sqlite3_database_unique_ptr database;
    //check if the db is available
    int result = database.open( QgsApplication::qgisUserDatabaseFilePath() );
    if ( result != SQLITE_OK )
    {
      QgsDebugMsg( QString( "Can't open database: %1 \n please notify  QGIS developers of this error \n %2 (file name) " ).arg( database.errorMessage(),
                   QgsApplication::qgisUserDatabaseFilePath() ) );
      // XXX This will likely never happen since on open, sqlite creates the
      //     database if it does not exist.
      Q_ASSERT( result == SQLITE_OK );
    }
    sqlite3_statement_unique_ptr preparedStatement = database.prepare( sql, result );
    if ( result != SQLITE_OK || preparedStatement.step() != SQLITE_DONE )
    {
      QgsDebugMsg( QString( "failed to write to database in custom projection dialog: %1 [%2]" ).arg( sql, database.errorMessage() ) );
    }

    preparedStatement.reset();
    if ( result != SQLITE_OK )
      return false;
  }
  mExistingCRSparameters[id] = parameters.toProj4();
  mExistingCRSnames[id] = name;

  QgsCoordinateReferenceSystem::invalidateCache();
  QgsCoordinateTransformCache::instance()->invalidateCrs( QStringLiteral( "USER:%1" ).arg( id ) );

  // If we have a projection acronym not in the user db previously, add it.
  // This is a must, or else we can't select it from the vw_srs table.
  // Actually, add it always and let the SQL PRIMARY KEY remove duplicates.
  insertProjection( projectionAcronym );

  return true;
}
Exemplo n.º 12
0
QgsExpressionContextScope* QgsExpressionContextUtils::projectScope( const QgsProject* project )
{
  QgsExpressionContextScope* scope = new QgsExpressionContextScope( QObject::tr( "Project" ) );

  if ( !project )
    return scope;

  const QVariantMap vars = project->customVariables();

  QVariantMap::const_iterator it = vars.constBegin();

  for ( ; it != vars.constEnd(); ++it )
  {
    scope->setVariable( it.key(), it.value() );
  }

  //add other known project variables
  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_title" ), project->title(), true ) );
  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_path" ), project->fileInfo().filePath(), true ) );
  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_folder" ), project->fileInfo().dir().path(), true ) );
  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_filename" ), project->fileInfo().fileName(), true ) );
  QgsCoordinateReferenceSystem projectCrs = project->crs();
  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_crs" ), projectCrs.authid(), true ) );
  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "project_crs_definition" ), projectCrs.toProj4(), true ) );

  scope->addFunction( QStringLiteral( "project_color" ), new GetNamedProjectColor() );
  return scope;
}
Exemplo n.º 13
0
bool QgsDistanceArea::setEllipsoid( const QString& ellipsoid )
{
  // 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.
  QgsEllipsoidCache::Params params = QgsEllipsoidCache::instance()->getParams( ellipsoid );

  // row for this ellipsoid wasn't found?
  if ( params.radius.isEmpty() || params.parameter2.isEmpty() )
  {
    QgsDebugMsg( QString( "setEllipsoid: no row in tbl_ellipsoid for acronym '%1'" ).arg( ellipsoid ) );
    return false;
  }

  // get major semiaxis
  if ( params.radius.left( 2 ) == "a=" )
    mSemiMajor = params.radius.mid( 2 ).toDouble();
  else
  {
    QgsDebugMsg( QString( "setEllipsoid: wrong format of radius field: '%1'" ).arg( params.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 ( params.parameter2.left( 2 ) == "b=" )
  {
    mSemiMinor = params.parameter2.mid( 2 ).toDouble();
    mInvFlattening = mSemiMajor / ( mSemiMajor - mSemiMinor );
  }
  else if ( params.parameter2.left( 3 ) == "rf=" )
  {
    mInvFlattening = params.parameter2.mid( 3 ).toDouble();
    mSemiMinor = mSemiMajor - ( mSemiMajor / mInvFlattening );
  }
  else
  {
    QgsDebugMsg( QString( "setEllipsoid: wrong format of parameter2 field: '%1'" ).arg( params.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 = QgsCRSCache::instance()->crsByProj4( 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" ) )
                     .arg( 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;
}