Exemple #1
0
void QgsMapSettings::setDestinationCrs( const QgsCoordinateReferenceSystem &crs )
{
  mDestCRS = crs;
  mScaleCalculator.setMapUnits( crs.mapUnits() );
  // Since the map units have changed, force a recalculation of the scale.
  updateDerived();
}
QgsUnitTypes::DistanceUnit QgsLayoutItemScaleBar::guessUnits() const
{
  if ( !mMap )
    return QgsUnitTypes::DistanceMeters;

  QgsCoordinateReferenceSystem crs = mMap->crs();
  // start with crs units
  QgsUnitTypes::DistanceUnit unit = crs.mapUnits();
  if ( unit == QgsUnitTypes::DistanceDegrees || unit == QgsUnitTypes::DistanceUnknownUnit )
  {
    // geographic CRS, use metric units
    unit = QgsUnitTypes::DistanceMeters;
  }

  // try to pick reasonable choice between metric / imperial units
  double widthInSelectedUnits = mapWidth();
  double initialUnitsPerSegment = widthInSelectedUnits / 10.0; //default scalebar width equals half the map width
  switch ( unit )
  {
    case QgsUnitTypes::DistanceMeters:
    {
      if ( initialUnitsPerSegment > 1000.0 )
      {
        unit = QgsUnitTypes::DistanceKilometers;
      }
      break;
    }
    case QgsUnitTypes::DistanceFeet:
    {
      if ( initialUnitsPerSegment > 5419.95 )
      {
        unit = QgsUnitTypes::DistanceMiles;
      }
      break;
    }
    default:
      break;
  }

  return unit;
}
void QgsProcessingDistanceWidgetWrapper::setUnitParameterValue( const QVariant &value )
{
  QgsUnitTypes::DistanceUnit units = QgsUnitTypes::DistanceUnknownUnit;

  // evaluate value to layer
  QgsProcessingContext *context = nullptr;
  std::unique_ptr< QgsProcessingContext > tmpContext;
  if ( mProcessingContextGenerator )
    context = mProcessingContextGenerator->processingContext();

  if ( !context )
  {
    tmpContext = qgis::make_unique< QgsProcessingContext >();
    context = tmpContext.get();
  }

  QgsCoordinateReferenceSystem crs = QgsProcessingParameters::parameterAsCrs( parameterDefinition(), value, *context );
  if ( crs.isValid() )
  {
    units = crs.mapUnits();
  }

  setUnits( units );
}
/**************************** REGION ********************************/
void QgsGrassNewMapset::setRegionPage()
{
  QgsDebugMsg( "entered" );

  // Set defaults
  if ( !mRegionModified )
  {
    setGrassRegionDefaults();
  }

  // Create new projection
  QgsCoordinateReferenceSystem newCrs;
  if ( mProjRadioButton->isChecked() )
  {
    QgsDebugMsg( QString( "selectedCrsId() = %1" ).arg( mProjectionSelector->selectedCrsId() ) );

    if ( mProjectionSelector->selectedCrsId() > 0 )
    {
      newCrs.createFromSrsId( mProjectionSelector->selectedCrsId() );
      if ( ! newCrs.isValid() )
      {
        QgsGrass::warning( tr( "Cannot create projection." ) );
      }
    }
  }

  // Reproject previous region if it was modified
  // and if previous and current projection is valid
  if ( mRegionModified && newCrs.isValid() && mCrs.isValid()
       && newCrs.srsid() != mCrs.srsid() )
  {
    QgsCoordinateTransform trans( mCrs, newCrs );

    double n = mNorthLineEdit->text().toDouble();
    double s = mSouthLineEdit->text().toDouble();
    double e = mEastLineEdit->text().toDouble();
    double w = mWestLineEdit->text().toDouble();

    std::vector<QgsPoint> points;

    // TODO: this is not perfect
    points.push_back( QgsPoint( w, s ) );
    points.push_back( QgsPoint( e, n ) );

    bool ok = true;
    for ( int i = 0; i < 2; i++ )
    {
      try
      {
        points[i] = trans.transform( points[i] );
      }
      catch ( QgsCsException &cse )
      {
        Q_UNUSED( cse );
        QgsDebugMsg( "Cannot transform point" );
        ok = false;
        break;
      }
    }

    if ( ok )
    {
      int precision = newCrs.mapUnits() == QGis::Degrees ? 6 : 1;
      mNorthLineEdit->setText( qgsDoubleToString( points[1].y(), precision ) );
      mSouthLineEdit->setText( qgsDoubleToString( points[0].y(), precision ) );
      mEastLineEdit->setText( qgsDoubleToString( points[1].x(), precision ) );
      mWestLineEdit->setText( qgsDoubleToString( points[0].x(), precision ) );
    }
    else
    {
      QgsGrass::warning( tr( "Cannot reproject previously set region, default region set." ) );
      setGrassRegionDefaults();
    }
  }

  // Set current region projection
  mCrs = newCrs;

  // Enable / disable region selection widgets
  if ( mNoProjRadioButton->isChecked() )
  {
    mRegionMap->hide();
    mCurrentRegionButton->hide();
    mRegionsComboBox->hide();
    mRegionButton->hide();
    mSetRegionFrame->hide();
  }
  else
  {
    mRegionMap->show();
    mCurrentRegionButton->show();
    mRegionsComboBox->show();
    mRegionButton->show();
    mSetRegionFrame->show();

    QgsRectangle ext = mIface->mapCanvas()->extent();

    if ( ext.xMinimum() >= ext.xMaximum() || ext.yMinimum() >= ext.yMaximum() )
    {
      mCurrentRegionButton->setEnabled( false );
    }
  }

  checkRegion();

  if ( !mNoProjRadioButton->isChecked() )
  {
    drawRegion();
  }
}
Exemple #5
0
  tileMatrixInfo calculateTileMatrixInfo( const QString &crsStr, const QgsProject *project )
  {
    // Does the CRS have fixed tile matrices
    if ( fixedTileMatrixInfoMap.contains( crsStr ) )
      return fixedTileMatrixInfoMap[crsStr];

    // Does the CRS have already calculated tile matrices
    if ( calculatedTileMatrixInfoMap.contains( crsStr ) )
      return calculatedTileMatrixInfoMap[crsStr];

    tileMatrixInfo tmi;
    tmi.ref = crsStr;

    QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( crsStr );
    QgsCoordinateTransform crsTransform( wgs84, crs, project );
    try
    {
      tmi.extent = crsTransform.transformBoundingBox( crs.bounds() );
    }
    catch ( QgsCsException &cse )
    {
      Q_UNUSED( cse )
    }

    tmi.unit = crs.mapUnits();
    tmi.hasAxisInverted = crs.hasAxisInverted();

    // calculate tile matrix scale denominator
    double scaleDenominator = 0.0;
    int colRes = ( tmi.extent.xMaximum() - tmi.extent.xMinimum() ) / tileSize;
    int rowRes = ( tmi.extent.yMaximum() - tmi.extent.yMinimum() ) / tileSize;
    double UNIT_TO_M = QgsUnitTypes::fromUnitToUnitFactor( tmi.unit, QgsUnitTypes::DistanceMeters );
    if ( colRes > rowRes )
      scaleDenominator = std::ceil( colRes * UNIT_TO_M / POINTS_TO_M );
    else
      scaleDenominator = std::ceil( rowRes * UNIT_TO_M / POINTS_TO_M );

    // Update extent to get a square one
    QgsRectangle extent = tmi.extent;
    double res = POINTS_TO_M * scaleDenominator / UNIT_TO_M;
    int col = std::ceil( ( extent.xMaximum() - extent.xMinimum() ) / ( tileSize * res ) );
    int row = std::ceil( ( extent.yMaximum() - extent.yMinimum() ) / ( tileSize * res ) );
    if ( col > 1 || row > 1 )
    {
      // Update scale
      if ( col > row )
      {
        res = col * res;
        scaleDenominator = col * scaleDenominator;
      }
      else
      {
        res = row * res;
        scaleDenominator = row * scaleDenominator;
      }
      // set col and row to 1 for the square
      col = 1;
      row = 1;
    }
    // Calculate extent
    double left = ( extent.xMinimum() + ( extent.xMaximum() - extent.xMinimum() ) / 2.0 ) - ( col / 2.0 ) * ( tileSize * res );
    double bottom = ( extent.yMinimum() + ( extent.yMaximum() - extent.yMinimum() ) / 2.0 ) - ( row / 2.0 ) * ( tileSize * res );
    double right = ( extent.xMinimum() + ( extent.xMaximum() - extent.xMinimum() ) / 2.0 ) + ( col / 2.0 ) * ( tileSize * res );
    double top = ( extent.yMinimum() + ( extent.yMaximum() - extent.yMinimum() ) / 2.0 ) + ( row / 2.0 ) * ( tileSize * res );
    tmi.extent = QgsRectangle( left, bottom, right, top );

    tmi.resolution = res;
    tmi.scaleDenominator = scaleDenominator;

    calculatedTileMatrixInfoMap[crsStr] = tmi;

    return tmi;
  }
Exemple #6
0
  QList< tileMatrixSetDef > getTileMatrixSetList( const QgsProject *project, const QString &tms_ref )
  {
    QList< tileMatrixSetDef > tmsList;

    bool gridsDefined = false;
    QStringList wmtsGridList = project->readListEntry( QStringLiteral( "WMTSGrids" ), QStringLiteral( "CRS" ), QStringList(), &gridsDefined );
    if ( gridsDefined )
    {
      if ( !tms_ref.isEmpty() && !wmtsGridList.contains( tms_ref ) )
      {
        throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) );
      }

      QStringList wmtsGridConfigList = project->readListEntry( QStringLiteral( "WMTSGrids" ), QStringLiteral( "Config" ) );
      for ( const QString &c : wmtsGridConfigList )
      {
        QStringList config = c.split( ',' );
        QString crsStr = config[0];
        if ( !tms_ref.isEmpty() && tms_ref != crsStr )
        {
          continue;
        }

        tileMatrixInfo tmi;
        double fixedTop = 0.0;
        double fixedLeft = 0.0;
        double resolution = -1.0;
        int col = -1;
        int row = -1;
        // Does the CRS have fixed tile matrices
        if ( fixedTileMatrixInfoMap.contains( crsStr ) )
        {
          tmi = fixedTileMatrixInfoMap[crsStr];
          // Calculate resolution based on scale denominator
          resolution = tmi.resolution;
          // Get fixed corner
          QgsRectangle extent = tmi.extent;
          fixedTop = extent.yMaximum();
          fixedLeft = extent.xMinimum();
          // Get numbers of column and row for the resolution to cover the extent
          col = std::ceil( ( extent.xMaximum() - extent.xMinimum() ) / ( tileSize * resolution ) );
          row = std::ceil( ( extent.yMaximum() - extent.yMinimum() ) / ( tileSize * resolution ) );
        }
        else
        {
          tmi.ref = crsStr;

          fixedTop = QVariant( config[1] ).toDouble();
          fixedLeft = QVariant( config[2] ).toDouble();
          double minScale = QVariant( config[3] ).toDouble();

          tmi.scaleDenominator = minScale;

          QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( crsStr );
          tmi.unit = crs.mapUnits();
          tmi.hasAxisInverted = crs.hasAxisInverted();

          QgsCoordinateTransform crsTransform( QgsCoordinateReferenceSystem::fromOgcWmsCrs( GEO_EPSG_CRS_AUTHID ), crs, project );
          try
          {
            // firstly transform CRS bounds expressed in WGS84 to CRS
            QgsRectangle extent = crsTransform.transformBoundingBox( crs.bounds() );
            // Calculate resolution based on scale denominator
            resolution = POINTS_TO_M * minScale / QgsUnitTypes::fromUnitToUnitFactor( tmi.unit, QgsUnitTypes::DistanceMeters );
            // Get numbers of column and row for the resolution to cover the extent
            col = std::ceil( ( extent.xMaximum() - extent.xMinimum() ) / ( tileSize * resolution ) );
            row = std::ceil( ( extent.yMaximum() - extent.yMinimum() ) / ( tileSize * resolution ) );
            // Calculate extent
            double bottom =  fixedTop - row * tileSize * resolution;
            double right =  fixedLeft + col * tileSize * resolution;
            tmi.extent = QgsRectangle( fixedLeft, bottom, right, fixedTop );
          }
          catch ( QgsCsException &cse )
          {
            Q_UNUSED( cse )
            continue;
          }
        }
        // get lastLevel
        tmi.lastLevel = QVariant( config[4] ).toInt();

        QList< tileMatrixDef > tileMatrixList;
        for ( int i = 0; i <= tmi.lastLevel; ++i )
        {
          double scale = tmi.scaleDenominator / std::pow( 2, i );
          double res = resolution / std::pow( 2, i );

          tileMatrixDef tm;
          tm.resolution = res;
          tm.scaleDenominator = scale;
          tm.col = col * std::pow( 2, i );
          tm.row = row * std::pow( 2, i );
          tm.left = fixedLeft;
          tm.top = fixedTop;
          tileMatrixList.append( tm );
        }

        tileMatrixSetDef tms;
        tms.ref = tmi.ref;
        tms.extent = tmi.extent;
        tms.unit = tmi.unit;
        tms.hasAxisInverted = tmi.hasAxisInverted;
        tms.tileMatrixList = tileMatrixList;

        tmsList.append( tms );
      }
      return tmsList;
    }

    double minScale = project->readNumEntry( QStringLiteral( "WMTSMinScale" ), QStringLiteral( "/" ), -1.0 );
    if ( minScale == -1.0 )
    {
      minScale = getProjectMinScale( project );
    }

    QStringList crsList = QgsServerProjectUtils::wmsOutputCrsList( *project );
    if ( !tms_ref.isEmpty() && !crsList.contains( tms_ref ) )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) );
    }
    for ( const QString &crsStr : crsList )
    {
      if ( !tms_ref.isEmpty() && tms_ref != crsStr )
      {
        continue;
      }
      tileMatrixInfo tmi = calculateTileMatrixInfo( crsStr, project );
      if ( tmi.scaleDenominator > 0.0 )
      {
        tmsList.append( calculateTileMatrixSet( tmi, minScale ) );
      }
    }

    return tmsList;
  }
void QgsMapToolViewshed::drawFinished()
{
  QString layerid = QgsProject::instance()->readEntry( "Heightmap", "layer" );
  QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( layerid );
  if ( !layer || layer->type() != QgsMapLayer::RasterLayer )
  {
    QgisApp::instance()->messageBar()->pushMessage( tr( "No heightmap is defined in the project." ), tr( "Right-click a raster layer in the layer tree and select it to be used as heightmap." ), QgsMessageBar::INFO, 10 );
    reset();
    return;
  }

  QgsCoordinateReferenceSystem canvasCrs = canvas()->mapSettings().destinationCrs();
  double curRadius;
  QgsPoint center;
  double trash;
  getPart( 0, center, curRadius, trash, trash );

  QGis::UnitType measureUnit = canvasCrs.mapUnits();
  QgsDistanceArea().convertMeasurement( curRadius, measureUnit, QGis::Meters, false );

  QgsViewshedDialog viewshedDialog( curRadius );
  connect( &viewshedDialog, SIGNAL( radiusChanged( double ) ), this, SLOT( adjustRadius( double ) ) );
  if ( viewshedDialog.exec() == QDialog::Rejected )
  {
    reset();
    return;
  }

  QString outputFileName = QString( "viewshed_%1,%2.tif" ).arg( center.x() ).arg( center.y() );
  QString outputFile = QgsTemporaryFile::createNewFile( outputFileName );

  QVector<QgsPoint> filterRegion;
  QgsPolygon poly = QgsGeometry( getRubberBand()->geometry()->clone() ).asPolygon();
  if ( !poly.isEmpty() )
  {
    filterRegion = poly.front();
  }
  getPart( 0, center, curRadius, trash, trash );

  if ( mCanvas->mapSettings().mapUnits() == QGis::Degrees )
  {
    // Need to compute radius in meters
    QgsDistanceArea da;
    da.setSourceCrs( mCanvas->mapSettings().destinationCrs() );
    da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
    da.setEllipsoidalMode( mCanvas->mapSettings().hasCrsTransformEnabled() );
    curRadius = da.measureLine( center, QgsPoint( center.x() + curRadius, center.y() ) );
    QGis::UnitType measureUnits = mCanvas->mapSettings().mapUnits();
    da.convertMeasurement( curRadius, measureUnits, QGis::Meters, false );
  }

  double heightConv = QGis::fromUnitToUnitFactor( QgsCoordinateFormat::instance()->getHeightDisplayUnit(), QGis::Meters );

  QProgressDialog p( tr( "Calculating viewshed..." ), tr( "Abort" ), 0, 0 );
  p.setWindowTitle( tr( "Viewshed" ) );
  p.setWindowModality( Qt::ApplicationModal );
  bool displayVisible = viewshedDialog.getDisplayMode() == QgsViewshedDialog::DisplayVisibleArea;
  int accuracyFactor = viewshedDialog.getAccuracyFactor();
  QApplication::setOverrideCursor( Qt::WaitCursor );
  bool success = QgsViewshed::computeViewshed( layer->source(), outputFile, "GTiff", center, canvasCrs, viewshedDialog.getObserverHeight() * heightConv, viewshedDialog.getTargetHeight() * heightConv, viewshedDialog.getHeightRelativeToGround(), curRadius, QGis::Meters, filterRegion, displayVisible, accuracyFactor, &p );
  QApplication::restoreOverrideCursor();
  if ( success )
  {
    QgsRasterLayer* layer = new QgsRasterLayer( outputFile, tr( "Viewshed [%1]" ).arg( center.toString() ) );
    QgsColorRampShader* rampShader = new QgsColorRampShader();
    if ( displayVisible )
    {
      QList<QgsColorRampShader::ColorRampItem> colorRampItems = QList<QgsColorRampShader::ColorRampItem>()
          << QgsColorRampShader::ColorRampItem( 0, QColor( 0, 0, 0, 0 ), "" )
          << QgsColorRampShader::ColorRampItem( 255, QColor( 0, 255, 0 ), tr( "Visible" ) );
      rampShader->setColorRampItemList( colorRampItems );
    }
    else
    {
      QList<QgsColorRampShader::ColorRampItem> colorRampItems = QList<QgsColorRampShader::ColorRampItem>()
          << QgsColorRampShader::ColorRampItem( 0, QColor( 0, 0, 0, 0 ), "" )
          << QgsColorRampShader::ColorRampItem( 0, QColor( 255, 0, 0 ), tr( "Invisible" ) );
      rampShader->setColorRampItemList( colorRampItems );
    }
    QgsRasterShader* shader = new QgsRasterShader();
    shader->setRasterShaderFunction( rampShader );
    QgsSingleBandPseudoColorRenderer* renderer = new QgsSingleBandPseudoColorRenderer( 0, 1, shader );
    layer->setRenderer( renderer );
    QgsMapLayerRegistry::instance()->addMapLayer( layer );
    QgsPinAnnotationItem* pin = new QgsPinAnnotationItem( canvas() );
    pin->setMapPosition( center, canvasCrs );
    pin->setItemFlags( pin->itemFlags() | QgsAnnotationItem::ItemMapPositionLocked );
    QgisApp::instance()->itemCouplingManager()->addCoupling( layer, pin );
  }
  else
  {
    QMessageBox::critical( 0, tr( "Error" ), tr( "Failed to compute viewshed." ) );
  }
  reset();
}