QVariant CustomLayerOrderModel::data( const QModelIndex& index, int role ) const
{
  QString id = mOrder.at( index.row() );

  if ( role == Qt::DisplayRole )
  {
    QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( id );
    if ( layer )
      return layer->name();
  }

  if ( role == Qt::UserRole + 1 )
  {
    QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( id );
    if ( layer )
      return layer->id();
  }

  if ( role == Qt::CheckStateRole )
  {
    QgsLayerTreeLayer* nodeLayer = mBridge->rootGroup()->findLayer( id );
    if ( nodeLayer )
      return nodeLayer->isVisible();
  }

  return QVariant();
}
QStringList QgsServerProjectParser::wcsLayerNames() const
{
  QStringList layerNameList;

  QMap<QString, QgsMapLayer*> layerMap;
  projectLayerMap( layerMap );

  QgsMapLayer* currentLayer = nullptr;
  QStringList wcsIdList = wcsLayers();
  QStringList::const_iterator wcsIdIt = wcsIdList.constBegin();
  for ( ; wcsIdIt != wcsIdList.constEnd(); ++wcsIdIt )
  {
    QMap<QString, QgsMapLayer*>::const_iterator layerMapIt = layerMap.find( *wcsIdIt );
    if ( layerMapIt != layerMap.constEnd() )
    {
      currentLayer = layerMapIt.value();
      if ( currentLayer )
      {
        layerNameList.append( mUseLayerIDs ? currentLayer->id() : currentLayer->name() );
      }
    }
  }

  return layerNameList;
}
static void _addLayerTreeNodeToUriList( QgsLayerTreeNode *node, QgsMimeDataUtils::UriList &uris )
{
  if ( QgsLayerTree::isGroup( node ) )
  {
    Q_FOREACH ( QgsLayerTreeNode *child, QgsLayerTree::toGroup( node )->children() )
      _addLayerTreeNodeToUriList( child, uris );
  }
  else if ( QgsLayerTree::isLayer( node ) )
  {
    QgsLayerTreeLayer *nodeLayer = QgsLayerTree::toLayer( node );
    QgsMapLayer *layer = nodeLayer->layer();
    if ( !layer )
      return;

    QgsMimeDataUtils::Uri uri;
    uri.name = layer->name();
    uri.uri = layer->dataProvider()->dataSourceUri();
    uri.providerKey = layer->dataProvider()->name();

    switch ( layer->type() )
    {
      case QgsMapLayer::VectorLayer:
      {
        uri.layerType = QStringLiteral( "vector" );
        if ( uri.providerKey == QStringLiteral( "memory" ) )
        {
          QUrl url = QUrl::fromEncoded( uri.uri.toUtf8() );
          url.addQueryItem( QStringLiteral( "pid" ), QString::number( QCoreApplication::applicationPid() ) );
          url.addQueryItem( QStringLiteral( "layerid" ), layer->id() );
          uri.uri = QString( url.toEncoded() );
        }
        break;
      }
      case QgsMapLayer::RasterLayer:
      {
        uri.layerType = QStringLiteral( "raster" );
        break;
      }

      case QgsMapLayer::MeshLayer:
      case QgsMapLayer::PluginLayer:
      {
        // plugin layers do not have a standard way of storing their URI...
        return;
      }
    }
    uris << uri;
  }
}
Beispiel #4
0
void QgsLayerTreeLayer::attachToLayer()
{
    // layer is not necessarily already loaded
    QgsMapLayer* l = QgsMapLayerRegistry::instance()->mapLayer( mLayerId );
    if ( l )
    {
        mLayer = l;
        mLayerName = l->name();
    }
    else
    {
        if ( mLayerName.isEmpty() )
            mLayerName = "(?)";
        // wait for the layer to be eventually loaded
        connect( QgsMapLayerRegistry::instance(), SIGNAL( layersAdded( QList<QgsMapLayer*> ) ), this, SLOT( registryLayersAdded( QList<QgsMapLayer*> ) ) );
    }
}
Beispiel #5
0
void QgsLegendModel::updateLayer( QStandardItem* layerItem )
{
  QgsDebugMsg( "Entered." );
  QgsComposerLayerItem* lItem = dynamic_cast<QgsComposerLayerItem*>( layerItem );
  if ( lItem )
  {
    QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() );
    if ( mapLayer )
    {
      //delete all the entries under layer item
      int currentRowCount = lItem->rowCount();
      for ( int i = currentRowCount - 1; i >= 0; --i )
      {
        lItem->removeRow( i );
      }

      QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer*>( mapLayer );

      //set layer name as item text
      QString label = mapLayer->name();
      if ( vLayer && lItem->showFeatureCount() )
      {
        label += QString( " [%1]" ).arg( vLayer->featureCount() );
      }
      layerItem->setText( label );

      if ( vLayer )
      {
        if ( vLayer->isUsingRendererV2() )
        {
          addVectorLayerItemsV2( lItem, vLayer );
        }
        else
        {
          addVectorLayerItems( lItem, vLayer );
        }
      }

      QgsRasterLayer* rLayer = qobject_cast<QgsRasterLayer*>( mapLayer );
      if ( rLayer )
      {
        addRasterLayerItems( lItem, rLayer );
      }
    }
  }
}
Beispiel #6
0
QgsAddJoinDialog::QgsAddJoinDialog( QgsVectorLayer* layer, QWidget * parent, Qt::WindowFlags f ): QDialog( parent, f ), mLayer( layer )
{
  setupUi( this );

  if ( !mLayer )
  {
    return;
  }

  //insert possible vector layers into mJoinLayerComboBox

  mJoinLayerComboBox->blockSignals( true );
  const QMap<QString, QgsMapLayer*>& layerList = QgsMapLayerRegistry::instance()->mapLayers();
  QMap<QString, QgsMapLayer*>::const_iterator layerIt = layerList.constBegin();
  for ( ; layerIt != layerList.constEnd(); ++layerIt )
  {
    QgsMapLayer* currentLayer = layerIt.value();
    if ( currentLayer->type() == QgsMapLayer::VectorLayer )
    {
      QgsVectorLayer* currentVectorLayer = dynamic_cast<QgsVectorLayer*>( currentLayer );
      if ( currentVectorLayer && currentVectorLayer != mLayer )
      {
        if ( currentVectorLayer->dataProvider() && currentVectorLayer->dataProvider()->supportsSubsetString() )
          mJoinLayerComboBox->addItem( currentLayer->name(), QVariant( currentLayer->id() ) );
      }
    }
  }
  mJoinLayerComboBox->blockSignals( false );
  on_mJoinLayerComboBox_currentIndexChanged( mJoinLayerComboBox->currentIndex() );

  //insert possible target fields
  QgsVectorDataProvider* provider = mLayer->dataProvider();
  if ( provider )
  {
    const QgsFields& layerFields = provider->fields();
    for ( int idx = 0; idx < layerFields.count(); ++idx )
    {
      mTargetFieldComboBox->addItem( layerFields[idx].name(), idx );
    }
  }

  mCacheInMemoryCheckBox->setChecked( true );
}
Beispiel #7
0
void QgsAddJoinDialog::on_mJoinLayerComboBox_currentIndexChanged( int index )
{
  mJoinFieldComboBox->clear();
  QString layerId = mJoinLayerComboBox->itemData( index ).toString();
  QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( layerId );
  QgsVectorLayer* vLayer = dynamic_cast<QgsVectorLayer*>( layer );
  if ( !vLayer )
  {
    return;
  }

  QStandardItemModel* subsetModel = new QStandardItemModel( this );

  const QgsFields& layerFields = vLayer->pendingFields();
  for ( int idx = 0; idx < layerFields.count(); ++idx )
  {
    mJoinFieldComboBox->addItem( layerFields[idx].name(), idx );
    QStandardItem* subsetItem = new QStandardItem( layerFields[idx].name() );
    subsetItem->setCheckable( true );
    //subsetItem->setFlags( subsetItem->flags() | Qt::ItemIsUserCheckable );
    subsetModel->appendRow( subsetItem );
  }

  //does provider support creation of attribute indices?
  QgsVectorDataProvider* dp = vLayer->dataProvider();
  if ( dp && ( dp->capabilities() & QgsVectorDataProvider::CreateAttributeIndex ) )
  {
    mCreateIndexCheckBox->setEnabled( true );
  }
  else
  {
    mCreateIndexCheckBox->setEnabled( false );
    mCreateIndexCheckBox->setChecked( false );
  }

  mJoinFieldsSubsetView->setModel( subsetModel );

  if ( !mUseCustomPrefix->isChecked() )
  {
    mCustomPrefix->setText( layer->name() + "_" );
  }
}
void QgsMapStylingWidget::updateCurrentWidgetLayer( int currentPage )
{
  mBlockAutoApply = true;

  QgsMapLayer* layer = mCurrentLayer;
  mUndoWidget->setUndoStack( layer->undoStackStyles() );

  mLayerTitleLabel->setText( layer->name() );

  if ( layer->type() == QgsMapLayer::VectorLayer )
  {
    mStackedWidget->setCurrentIndex( mVectorPage );
    if ( currentPage == mLabelTabIndex )
    {
      mLabelingWidget->setLayer( layer );
    }
    if ( currentPage == mStyleTabIndex )
    {
      // TODO Refactor props dialog so we don't have to do this
      QScrollArea* area = qobject_cast<QScrollArea*>( mMapStyleTabs->widget( mStyleTabIndex ) );
      QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer*>( layer );
      mVectorStyleWidget = new QgsRendererV2PropertiesDialog( vlayer, QgsStyleV2::defaultStyle(), true );
      connect( mVectorStyleWidget, SIGNAL( widgetChanged() ), this, SLOT( autoApply() ) );
      area->setWidget( mVectorStyleWidget );
    }
    QString errorMsg;
    QDomDocument doc( "style" );
    mLastStyleXml = doc.createElement( "style" );
    doc.appendChild( mLastStyleXml );
    mCurrentLayer->writeSymbology( mLastStyleXml, doc, errorMsg );
  }
  else if ( layer->type() == QgsMapLayer::RasterLayer )
  {
    mStackedWidget->setCurrentIndex( mNotSupportedPage );
  }
  else if ( layer->type() == QgsMapLayer::PluginLayer )
  {
    mStackedWidget->setCurrentIndex( mNotSupportedPage );
  }

  mBlockAutoApply = false;
}
void QgsDxfPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& context, QgsPalLayerSettings& tmpLyr, DrawLabelType drawType, double dpiRatio )
{
  Q_UNUSED( context );
  Q_UNUSED( drawType );
  Q_UNUSED( dpiRatio );
  //debug: print label infos
  if ( mDxfExport )
  {
    //label text
    QString text = (( QgsPalGeometry* )label->getFeaturePart()->getUserGeometry() )->text();

    //layer name
    QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( QString( label->getLayerName() ) );
    if ( !layer )
    {
      return;
    }
    QString layerName = mDxfExport->dxfLayerName( layer->name() );

    //angle
    double angle = label->getAlpha() * 180 / M_PI;

    //debug: show label rectangle
    /*QgsPolyline line;
    for( int i = 0; i < 4; ++i )
    {
        line.append( QgsPoint( label->getX( i ), label->getY( i ) ) );
    }
    mDxfExport->writePolyline( line, layerName, "CONTINUOUS", 1, 0.01, true );*/

    QStringList textList = text.split( "\n" );
    double textHeight = label->getHeight() / textList.size();
    QFontMetricsF fm( tmpLyr.textFont );
    double textAscent = textHeight * fm.ascent() / fm.height();

    for ( int i = 0; i < textList.size(); ++i )
    {
      mDxfExport->writeText( layerName, textList.at( i ), QgsPoint( label->getX(), label->getY() + ( textList.size() - 1 - i ) * textHeight ), textAscent, angle, mDxfExport->closestColorMatch( tmpLyr.textColor.rgb() ) );
    }
  }
}
Beispiel #10
0
void QgsLegendModel::updateLayerItemText( QStandardItem* layerItem )
{
  QgsComposerLayerItem* lItem = dynamic_cast<QgsComposerLayerItem*>( layerItem );
  if ( !lItem ) return;

  QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() );
  if ( !mapLayer ) return;

  QString label = lItem->userText().isEmpty() ? mapLayer->name() : lItem->userText();

  QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer*>( mapLayer );
  if ( vLayer )
  {
    addVectorLayerItemsV2( lItem, vLayer );
    if ( lItem->showFeatureCount() )
    {
      label += QString( " [%1]" ).arg( vLayer->featureCount() );
    }
  }
  lItem->setText( label );
}
Beispiel #11
0
QgsDxfExportDialog::QgsDxfExportDialog( const QList<QgsMapLayer*>& layerKeys, QWidget* parent, Qt::WindowFlags f ): QDialog( parent, f )
{
  setupUi( this );
  connect( mFileLineEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( setOkEnabled() ) );
  connect( this, SIGNAL( accepted() ), this, SLOT( saveSettings() ) );
  connect( mSelectAllButton, SIGNAL( clicked() ), this, SLOT( selectAll() ) );
  connect( mUnSelectAllButton, SIGNAL( clicked() ), this, SLOT( unSelectAll() ) );

  QList<QgsMapLayer*>::const_iterator layerIt = layerKeys.constBegin();
  for ( ; layerIt != layerKeys.constEnd(); ++layerIt )
  {
    QgsMapLayer* layer = *layerIt;
    if ( layer )
    {
      if ( layer->type() == QgsMapLayer::VectorLayer )
      {
        QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( layer );
        if ( !vl->hasGeometryType() )
          continue;
        QListWidgetItem* layerItem = new QListWidgetItem( layer->name() );
        layerItem->setData( Qt::UserRole, layer->id() );
        layerItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
        layerItem->setCheckState( Qt::Checked );
        mLayersListWidget->addItem( layerItem );
      }
    }
  }

  //last dxf symbology mode
  QSettings s;
  mSymbologyModeComboBox->setCurrentIndex( s.value( "qgis/lastDxfSymbologyMode", "2" ).toInt() );
  //last symbol scale
  mSymbologyScaleLineEdit->setText( s.value( "qgis/lastSymbologyExportScale", "50000" ).toString() );

  buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
}
Beispiel #12
0
  QDomElement getFeatureTypeListElement( QDomDocument &doc, QgsServerInterface *serverIface, const QgsProject *project )
  {
    QgsAccessControl *accessControl = serverIface->accessControls();

    //wfs:FeatureTypeList element
    QDomElement featureTypeListElement = doc.createElement( QStringLiteral( "FeatureTypeList" )/*wfs:FeatureTypeList*/ );
    //wfs:Operations element
    QDomElement operationsElement = doc.createElement( QStringLiteral( "Operations" )/*wfs:Operations*/ );
    featureTypeListElement.appendChild( operationsElement );
    //wfs:Query element
    QDomElement queryElement = doc.createElement( QStringLiteral( "Query" )/*wfs:Query*/ );
    operationsElement.appendChild( queryElement );

    QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
    QStringList wfstUpdateLayersId = QgsServerProjectUtils::wfstUpdateLayerIds( *project );
    QStringList wfstInsertLayersId = QgsServerProjectUtils::wfstInsertLayerIds( *project );
    QStringList wfstDeleteLayersId = QgsServerProjectUtils::wfstDeleteLayerIds( *project );
    for ( int i = 0; i < wfsLayerIds.size(); ++i )
    {
      QgsMapLayer *layer = project->mapLayer( wfsLayerIds.at( i ) );
      if ( layer->type() != QgsMapLayer::LayerType::VectorLayer )
      {
        continue;
      }
      if ( accessControl && !accessControl->layerReadPermission( layer ) )
      {
        continue;
      }

      QDomElement layerElem = doc.createElement( QStringLiteral( "FeatureType" ) );

      //create Name
      QDomElement nameElem = doc.createElement( QStringLiteral( "Name" ) );
      QString typeName = layer->name();
      if ( !layer->shortName().isEmpty() )
        typeName = layer->shortName();
      typeName = typeName.replace( QLatin1String( " " ), QLatin1String( "_" ) );
      QDomText nameText = doc.createTextNode( typeName );
      nameElem.appendChild( nameText );
      layerElem.appendChild( nameElem );

      //create Title
      QDomElement titleElem = doc.createElement( QStringLiteral( "Title" ) );
      QString title = layer->title();
      if ( title.isEmpty() )
      {
        title = layer->name();
      }
      QDomText titleText = doc.createTextNode( title );
      titleElem.appendChild( titleText );
      layerElem.appendChild( titleElem );

      //create Abstract
      QString abstract = layer->abstract();
      if ( !abstract.isEmpty() )
      {
        QDomElement abstractElem = doc.createElement( QStringLiteral( "Abstract" ) );
        QDomText abstractText = doc.createTextNode( abstract );
        abstractElem.appendChild( abstractText );
        layerElem.appendChild( abstractElem );
      }

      //create keywords
      QString keywords = layer->keywordList();
      if ( !keywords.isEmpty() )
      {
        QDomElement keywordsElem = doc.createElement( QStringLiteral( "Keywords" ) );
        QDomText keywordsText = doc.createTextNode( keywords );
        keywordsElem.appendChild( keywordsText );
        layerElem.appendChild( keywordsElem );
      }

      //create SRS
      QDomElement srsElem = doc.createElement( QStringLiteral( "SRS" ) );
      QDomText srsText = doc.createTextNode( layer->crs().authid() );
      srsElem.appendChild( srsText );
      layerElem.appendChild( srsElem );

      //create LatLongBoundingBox
      QgsRectangle layerExtent = layer->extent();
      QDomElement bBoxElement = doc.createElement( QStringLiteral( "LatLongBoundingBox" ) );
      bBoxElement.setAttribute( QStringLiteral( "minx" ), QString::number( layerExtent.xMinimum() ) );
      bBoxElement.setAttribute( QStringLiteral( "miny" ), QString::number( layerExtent.yMinimum() ) );
      bBoxElement.setAttribute( QStringLiteral( "maxx" ), QString::number( layerExtent.xMaximum() ) );
      bBoxElement.setAttribute( QStringLiteral( "maxy" ), QString::number( layerExtent.yMaximum() ) );
      layerElem.appendChild( bBoxElement );

      // layer metadata URL
      QString metadataUrl = layer->metadataUrl();
      if ( !metadataUrl.isEmpty() )
      {
        QDomElement metaUrlElem = doc.createElement( QStringLiteral( "MetadataURL" ) );
        QString metadataUrlType = layer->metadataUrlType();
        metaUrlElem.setAttribute( QStringLiteral( "type" ), metadataUrlType );
        QString metadataUrlFormat = layer->metadataUrlFormat();
        if ( metadataUrlFormat == QLatin1String( "text/xml" ) )
        {
          metaUrlElem.setAttribute( QStringLiteral( "format" ), QStringLiteral( "XML" ) );
        }
        else
        {
          metaUrlElem.setAttribute( QStringLiteral( "format" ), QStringLiteral( "TXT" ) );
        }
        QDomText metaUrlText = doc.createTextNode( metadataUrl );
        metaUrlElem.appendChild( metaUrlText );
        layerElem.appendChild( metaUrlElem );
      }

      //wfs:Operations element
      QDomElement operationsElement = doc.createElement( QStringLiteral( "Operations" )/*wfs:Operations*/ );
      //wfs:Query element
      QDomElement queryElement = doc.createElement( QStringLiteral( "Query" )/*wfs:Query*/ );
      operationsElement.appendChild( queryElement );
      if ( wfstUpdateLayersId.contains( layer->id() ) ||
           wfstInsertLayersId.contains( layer->id() ) ||
           wfstDeleteLayersId.contains( layer->id() ) )
      {
        QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
        QgsVectorDataProvider *provider = vlayer->dataProvider();
        if ( ( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) && wfstInsertLayersId.contains( layer->id() ) )
        {
          //wfs:Insert element
          QDomElement insertElement = doc.createElement( QStringLiteral( "Insert" )/*wfs:Insert*/ );
          operationsElement.appendChild( insertElement );
        }
        if ( ( provider->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) &&
             ( provider->capabilities() & QgsVectorDataProvider::ChangeGeometries ) &&
             wfstUpdateLayersId.contains( layer->id() ) )
        {
          //wfs:Update element
          QDomElement updateElement = doc.createElement( QStringLiteral( "Update" )/*wfs:Update*/ );
          operationsElement.appendChild( updateElement );
        }
        if ( ( provider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) && wfstDeleteLayersId.contains( layer->id() ) )
        {
          //wfs:Delete element
          QDomElement deleteElement = doc.createElement( QStringLiteral( "Delete" )/*wfs:Delete*/ );
          operationsElement.appendChild( deleteElement );
        }
      }

      layerElem.appendChild( operationsElement );

      featureTypeListElement.appendChild( layerElem );
    }

    return featureTypeListElement;
  }
QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( int x, int y, IdentifyMode mode, QList<QgsMapLayer*> layerList, LayerType layerType )
{
  QList<IdentifyResult> results;

  mLastPoint = mCanvas->getCoordinateTransform()->toMapCoordinates( x, y );
  mLastExtent = mCanvas->extent();
  mLastMapUnitsPerPixel = mCanvas->mapUnitsPerPixel();

  if ( mode == DefaultQgsSetting )
  {
    QSettings settings;
    mode = static_cast<IdentifyMode>( settings.value( "/Map/identifyMode", 0 ).toInt() );
  }

  if ( mode == LayerSelection )
  {
    // fill map of layer / identify results
    mLayerIdResults.clear();
    QList<IdentifyResult> idResult = identify( x, y, TopDownAll );
    QList<IdentifyResult>::const_iterator it = idResult.constBegin();
    for ( ; it != idResult.constEnd(); ++it )
    {
      QgsMapLayer *layer = it->mLayer;
      if ( mLayerIdResults.contains( layer ) )
      {
        mLayerIdResults[layer].append( *it );
      }
      else
      {
        mLayerIdResults.insert( layer, QList<IdentifyResult>() << *it );
      }
    }

    //fill selection menu with entries from mmLayerIdResults
    QMenu layerSelectionMenu;
    QMap< QgsMapLayer*, QList<IdentifyResult> >::const_iterator resultIt = mLayerIdResults.constBegin();
    for ( ; resultIt != mLayerIdResults.constEnd(); ++resultIt )
    {
      QAction* action = new QAction( QString( "%1 (%2)" ).arg( resultIt.key()->name() ).arg( resultIt.value().size() ), 0 );
      action->setData( resultIt.key()->id() );
      //add point/line/polygon icon
      QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( resultIt.key() );
      if ( vl )
      {
        switch ( vl->geometryType() )
        {
          case QGis::Point:
            action->setIcon( QgsApplication::getThemeIcon( "/mIconPointLayer.png" ) );
            break;
          case QGis::Line:
            action->setIcon( QgsApplication::getThemeIcon( "/mIconLineLayer.png" ) );
            break;
          case QGis::Polygon:
            action->setIcon( QgsApplication::getThemeIcon( "/mIconPolygonLayer.png" ) );
            break;
          default:
            break;
        }
      }
      else if ( resultIt.key()->type() == QgsMapLayer::RasterLayer )
      {
        action->setIcon( QgsApplication::getThemeIcon( "/mIconRaster.png" ) );
      }
      connect( action, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
      layerSelectionMenu.addAction( action );
    }

    if ( mLayerIdResults.size() > 1 )
    {
      QAction *action = new QAction( tr( "All (%1)" ).arg( idResult.size() ), 0 );
      connect( action, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
      layerSelectionMenu.addAction( action );
    }

    // exec layer selection menu
    QPoint globalPos = mCanvas->mapToGlobal( QPoint( x + 5, y + 5 ) );
    QAction* selectedAction = layerSelectionMenu.exec( globalPos );
    if ( selectedAction )
    {
      if ( selectedAction->data().toString().isEmpty() )
      {
        results = idResult;
      }
      else
      {
        QgsMapLayer* selectedLayer = QgsMapLayerRegistry::instance()->mapLayer( selectedAction->data().toString() );
        QMap< QgsMapLayer*, QList<IdentifyResult> >::const_iterator sIt = mLayerIdResults.find( selectedLayer );
        if ( sIt != mLayerIdResults.constEnd() )
        {
          results = sIt.value();
        }
      }
    }

    deleteRubberBands();
  }
  else if ( mode == ActiveLayer && layerList.isEmpty() )
  {
    QgsMapLayer *layer = mCanvas->currentLayer();

    if ( !layer )
    {
      emit identifyMessage( tr( "No active layer. To identify features, you must choose an active layer." ) );
      return results;
    }

    QApplication::setOverrideCursor( Qt::WaitCursor );

    identifyLayer( &results, layer, mLastPoint, mLastExtent, mLastMapUnitsPerPixel, layerType );
  }
  else
  {
    QApplication::setOverrideCursor( Qt::WaitCursor );

    QStringList noIdentifyLayerIdList = QgsProject::instance()->readListEntry( "Identify", "/disabledLayers" );

    int layerCount;
    if ( layerList.isEmpty() )
      layerCount = mCanvas->layerCount();
    else
      layerCount = layerList.count();


    for ( int i = 0; i < layerCount; i++ )
    {

      QgsMapLayer *layer ;
      if ( layerList.isEmpty() )
        layer = mCanvas->layer( i );
      else
        layer = layerList.value( i );

      emit identifyProgress( i, mCanvas->layerCount() );
      emit identifyMessage( tr( "Identifying on %1..." ).arg( layer->name() ) );

      if ( noIdentifyLayerIdList.contains( layer->id() ) )
        continue;

      if ( identifyLayer( &results, layer,  mLastPoint, mLastExtent, mLastMapUnitsPerPixel, layerType ) )
      {
        if ( mode == TopDownStopAtFirst )
          break;
      }
    }

    emit identifyProgress( mCanvas->layerCount(), mCanvas->layerCount() );
    emit identifyMessage( tr( "Identifying done." ) );
  }

  QApplication::restoreOverrideCursor();

  return results;
}
Beispiel #14
0
  QList< layerDef > getWmtsLayerList( QgsServerInterface *serverIface, const QgsProject *project )
  {
    QList< layerDef > wmtsLayers;
#ifdef HAVE_SERVER_PYTHON_PLUGINS
    QgsAccessControl *accessControl = serverIface->accessControls();
#else
    ( void )serverIface;
#endif

    // WMTS Project configuration
    bool wmtsProject = project->readBoolEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Project" ) );

    // Root Layer name
    QString rootLayerName = QgsServerProjectUtils::wmsRootName( *project );
    if ( rootLayerName.isEmpty() && !project->title().isEmpty() )
    {
      rootLayerName = project->title();
    }

    if ( wmtsProject && !rootLayerName.isEmpty() )
    {
      layerDef pLayer;
      pLayer.id = rootLayerName;

      if ( !project->title().isEmpty() )
      {
        pLayer.title = project->title();
        pLayer.abstract = project->title();
      }

      //transform the project native CRS into WGS84
      QgsRectangle projRect = QgsServerProjectUtils::wmsExtent( *project );
      QgsCoordinateReferenceSystem projCrs = project->crs();
      QgsCoordinateTransform exGeoTransform( projCrs, wgs84, project );
      try
      {
        pLayer.wgs84BoundingRect = exGeoTransform.transformBoundingBox( projRect );
      }
      catch ( const QgsCsException & )
      {
        pLayer.wgs84BoundingRect = QgsRectangle( -180, -90, 180, 90 );
      }

      // Formats
      bool wmtsPngProject = project->readBoolEntry( QStringLiteral( "WMTSPngLayers" ), QStringLiteral( "Project" ) );
      if ( wmtsPngProject )
        pLayer.formats << QStringLiteral( "image/png" );
      bool wmtsJpegProject = project->readBoolEntry( QStringLiteral( "WMTSJpegLayers" ), QStringLiteral( "Project" ) );
      if ( wmtsJpegProject )
        pLayer.formats << QStringLiteral( "image/jpeg" );

      // Project is not queryable in WMS
      //pLayer.queryable = ( nonIdentifiableLayers.count() != project->count() );
      pLayer.queryable = false;

      wmtsLayers.append( pLayer );
    }

    QStringList wmtsGroupNameList = project->readListEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Group" ) );
    if ( !wmtsGroupNameList.isEmpty() )
    {
      QgsLayerTreeGroup *treeRoot = project->layerTreeRoot();

      QStringList wmtsPngGroupNameList = project->readListEntry( QStringLiteral( "WMTSPngLayers" ), QStringLiteral( "Group" ) );
      QStringList wmtsJpegGroupNameList = project->readListEntry( QStringLiteral( "WMTSJpegLayers" ), QStringLiteral( "Group" ) );

      for ( const QString &gName : wmtsGroupNameList )
      {
        QgsLayerTreeGroup *treeGroup = treeRoot->findGroup( gName );
        if ( !treeGroup )
        {
          continue;
        }

        layerDef pLayer;
        pLayer.id = treeGroup->customProperty( QStringLiteral( "wmsShortName" ) ).toString();
        if ( pLayer.id.isEmpty() )
          pLayer.id = gName;

        pLayer.title = treeGroup->customProperty( QStringLiteral( "wmsTitle" ) ).toString();
        if ( pLayer.title.isEmpty() )
          pLayer.title = gName;

        pLayer.abstract = treeGroup->customProperty( QStringLiteral( "wmsAbstract" ) ).toString();

        QgsRectangle wgs84BoundingRect;
        bool queryable = false;
        double maxScale = 0.0;
        double minScale = 0.0;
        for ( QgsLayerTreeLayer *layer : treeGroup->findLayers() )
        {
          QgsMapLayer *l = layer->layer();
          if ( !l )
          {
            continue;
          }
          //transform the layer native CRS into WGS84
          QgsCoordinateReferenceSystem layerCrs = l->crs();
          QgsCoordinateTransform exGeoTransform( layerCrs, wgs84, project );
          try
          {
            wgs84BoundingRect.combineExtentWith( exGeoTransform.transformBoundingBox( l->extent() ) );
          }
          catch ( const QgsCsException & )
          {
            wgs84BoundingRect.combineExtentWith( QgsRectangle( -180, -90, 180, 90 ) );
          }
          if ( !queryable && l->flags().testFlag( QgsMapLayer::Identifiable ) )
          {
            queryable = true;
          }

          if ( l->hasScaleBasedVisibility() )
          {
            double lMaxScale = l->maximumScale();
            if ( lMaxScale > 0.0 && lMaxScale > maxScale )
            {
              maxScale = lMaxScale;
            }
            double lMinScale = l->minimumScale();
            if ( lMinScale > 0.0 && ( minScale == 0.0 || lMinScale < minScale ) )
            {
              minScale = lMinScale;
            }
          }
        }
        pLayer.wgs84BoundingRect = wgs84BoundingRect;
        pLayer.queryable = queryable;
        pLayer.maxScale = maxScale;
        pLayer.minScale = minScale;

        // Formats
        if ( wmtsPngGroupNameList.contains( gName ) )
          pLayer.formats << QStringLiteral( "image/png" );
        if ( wmtsJpegGroupNameList.contains( gName ) )
          pLayer.formats << QStringLiteral( "image/jpeg" );

        wmtsLayers.append( pLayer );
      }
    }

    QStringList wmtsLayerIdList = project->readListEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Layer" ) );
    QStringList wmtsPngLayerIdList = project->readListEntry( QStringLiteral( "WMTSPngLayers" ), QStringLiteral( "Layer" ) );
    QStringList wmtsJpegLayerIdList = project->readListEntry( QStringLiteral( "WMTSJpegLayers" ), QStringLiteral( "Layer" ) );

    for ( const QString &lId : wmtsLayerIdList )
    {
      QgsMapLayer *l = project->mapLayer( lId );
      if ( !l )
      {
        continue;
      }
#ifdef HAVE_SERVER_PYTHON_PLUGINS
      if ( !accessControl->layerReadPermission( l ) )
      {
        continue;
      }
#endif

      layerDef pLayer;
      pLayer.id = l->name();
      if ( !l->shortName().isEmpty() )
        pLayer.id = l->shortName();
      pLayer.id = pLayer.id.replace( ' ', '_' );

      pLayer.title = l->title();
      pLayer.abstract = l->abstract();

      //transform the layer native CRS into WGS84
      QgsCoordinateReferenceSystem layerCrs = l->crs();
      QgsCoordinateTransform exGeoTransform( layerCrs, wgs84, project );
      try
      {
        pLayer.wgs84BoundingRect = exGeoTransform.transformBoundingBox( l->extent() );
      }
      catch ( const QgsCsException & )
      {
        pLayer.wgs84BoundingRect = QgsRectangle( -180, -90, 180, 90 );
      }

      // Formats
      if ( wmtsPngLayerIdList.contains( lId ) )
        pLayer.formats << QStringLiteral( "image/png" );
      if ( wmtsJpegLayerIdList.contains( lId ) )
        pLayer.formats << QStringLiteral( "image/jpeg" );

      pLayer.queryable = ( l->flags().testFlag( QgsMapLayer::Identifiable ) );

      if ( l->hasScaleBasedVisibility() )
      {
        pLayer.maxScale = l->maximumScale();
        pLayer.minScale = l->minimumScale();
      }
      else
      {
        pLayer.maxScale = 0.0;
        pLayer.minScale = 0.0;
      }

      wmtsLayers.append( pLayer );
    }
    return wmtsLayers;
  }
Beispiel #15
0
LayerRenderJobs QgsMapRendererJob::prepareJobs( QPainter* painter, QgsPalLabeling* labelingEngine )
{
  LayerRenderJobs layerJobs;

  // render all layers in the stack, starting at the base
  QListIterator<QString> li( mSettings.layers() );
  li.toBack();

  if ( mCache )
  {
    bool cacheValid = mCache->init( mSettings.visibleExtent(), mSettings.scale() );
    QgsDebugMsg( QString( "CACHE VALID: %1" ).arg( cacheValid ) );
    Q_UNUSED( cacheValid );
  }

  mGeometryCaches.clear();

  while ( li.hasPrevious() )
  {
    QString layerId = li.previous();

    QgsDebugMsg( "Rendering at layer item " + layerId );

    QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer( layerId );

    if ( !ml )
    {
      mErrors.append( Error( layerId, "Layer not found in registry." ) );
      continue;
    }

    QgsDebugMsg( QString( "layer %1:  minscale:%2  maxscale:%3  scaledepvis:%4  extent:%5  blendmode:%6" )
                 .arg( ml->name() )
                 .arg( ml->minimumScale() )
                 .arg( ml->maximumScale() )
                 .arg( ml->hasScaleBasedVisibility() )
                 .arg( ml->extent().toString() )
                 .arg( ml->blendMode() )
               );

    if ( ml->hasScaleBasedVisibility() && ( mSettings.scale() < ml->minimumScale() || mSettings.scale() > ml->maximumScale() ) ) //|| mOverview )
    {
      QgsDebugMsg( "Layer not rendered because it is not within the defined visibility scale range" );
      continue;
    }

    QgsRectangle r1 = mSettings.visibleExtent(), r2;
    const QgsCoordinateTransform* ct = 0;

    if ( mSettings.hasCrsTransformEnabled() )
    {
      ct = mSettings.layerTransfrom( ml );
      if ( ct )
      {
        reprojectToLayerExtent( ct, ml->crs().geographicFlag(), r1, r2 );
      }
      QgsDebugMsg( "extent: " + r1.toString() );
      if ( !r1.isFinite() || !r2.isFinite() )
      {
        mErrors.append( Error( layerId, "There was a problem transforming layer's' extent. Layer skipped." ) );
        continue;
      }
    }

    // Force render of layers that are being edited
    // or if there's a labeling engine that needs the layer to register features
    if ( mCache && ml->type() == QgsMapLayer::VectorLayer )
    {
      QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
      if ( vl->isEditable() || ( labelingEngine && labelingEngine->willUseLayer( vl ) ) )
        mCache->clearCacheImage( ml->id() );
    }

    layerJobs.append( LayerRenderJob() );
    LayerRenderJob& job = layerJobs.last();
    job.cached = false;
    job.img = 0;
    job.blendMode = ml->blendMode();
    job.layerId = ml->id();

    job.context = QgsRenderContext::fromMapSettings( mSettings );
    job.context.setPainter( painter );
    job.context.setLabelingEngine( labelingEngine );
    job.context.setCoordinateTransform( ct );
    job.context.setExtent( r1 );

    // if we can use the cache, let's do it and avoid rendering!
    if ( mCache && !mCache->cacheImage( ml->id() ).isNull() )
    {
      job.cached = true;
      job.img = new QImage( mCache->cacheImage( ml->id() ) );
      job.renderer = 0;
      job.context.setPainter( 0 );
      continue;
    }

    // If we are drawing with an alternative blending mode then we need to render to a separate image
    // before compositing this on the map. This effectively flattens the layer and prevents
    // blending occuring between objects on the layer
    if ( mCache || !painter || needTemporaryImage( ml ) )
    {
      // Flattened image for drawing when a blending mode is set
      QImage * mypFlattenedImage = 0;
      mypFlattenedImage = new QImage( mSettings.outputSize().width(),
                                      mSettings.outputSize().height(),
                                      mSettings.outputImageFormat() );
      if ( mypFlattenedImage->isNull() )
      {
        mErrors.append( Error( layerId, "Insufficient memory for image " + QString::number( mSettings.outputSize().width() ) + "x" + QString::number( mSettings.outputSize().height() ) ) );
        delete mypFlattenedImage;
        layerJobs.removeLast();
        continue;
      }
      mypFlattenedImage->fill( 0 );

      job.img = mypFlattenedImage;
      QPainter* mypPainter = new QPainter( job.img );
      mypPainter->setRenderHint( QPainter::Antialiasing, mSettings.testFlag( QgsMapSettings::Antialiasing ) );
      job.context.setPainter( mypPainter );
    }

    job.renderer = ml->createMapRenderer( job.context );

    if ( mRequestedGeomCacheForLayers.contains( ml->id() ) )
    {
      if ( QgsVectorLayerRenderer* vlr = dynamic_cast<QgsVectorLayerRenderer*>( job.renderer ) )
      {
        vlr->setGeometryCachePointer( &mGeometryCaches[ ml->id()] );
      }
    }

  } // while (li.hasPrevious())

  return layerJobs;
}
Beispiel #16
0
QgsRectangle QgsMapSettings::fullExtent() const
{
  QgsDebugMsg( "called." );
  QgsMapLayerRegistry* registry = QgsMapLayerRegistry::instance();

  // reset the map canvas extent since the extent may now be smaller
  // We can't use a constructor since QgsRectangle normalizes the rectangle upon construction
  QgsRectangle fullExtent;
  fullExtent.setMinimal();

  // iterate through the map layers and test each layers extent
  // against the current min and max values
  QStringList::const_iterator it = mLayers.begin();
  QgsDebugMsg( QString( "Layer count: %1" ).arg( mLayers.count() ) );
  while ( it != mLayers.end() )
  {
    QgsMapLayer * lyr = registry->mapLayer( *it );
    if ( !lyr )
    {
      QgsDebugMsg( QString( "WARNING: layer '%1' not found in map layer registry!" ).arg( *it ) );
    }
    else
    {
      QgsDebugMsg( "Updating extent using " + lyr->name() );
      QgsDebugMsg( "Input extent: " + lyr->extent().toString() );

      if ( lyr->extent().isNull() )
      {
        ++it;
        continue;
      }

      // Layer extents are stored in the coordinate system (CS) of the
      // layer. The extent must be projected to the canvas CS
      QgsRectangle extent = layerExtentToOutputExtent( lyr, lyr->extent() );

      QgsDebugMsg( "Output extent: " + extent.toString() );
      fullExtent.unionRect( extent );

    }
    ++it;
  }

  if ( fullExtent.width() == 0.0 || fullExtent.height() == 0.0 )
  {
    // If all of the features are at the one point, buffer the
    // rectangle a bit. If they are all at zero, do something a bit
    // more crude.

    if ( fullExtent.xMinimum() == 0.0 && fullExtent.xMaximum() == 0.0 &&
         fullExtent.yMinimum() == 0.0 && fullExtent.yMaximum() == 0.0 )
    {
      fullExtent.set( -1.0, -1.0, 1.0, 1.0 );
    }
    else
    {
      const double padFactor = 1e-8;
      double widthPad = fullExtent.xMinimum() * padFactor;
      double heightPad = fullExtent.yMinimum() * padFactor;
      double xmin = fullExtent.xMinimum() - widthPad;
      double xmax = fullExtent.xMaximum() + widthPad;
      double ymin = fullExtent.yMinimum() - heightPad;
      double ymax = fullExtent.yMaximum() + heightPad;
      fullExtent.set( xmin, ymin, xmax, ymax );
    }
  }

  QgsDebugMsg( "Full extent: " + fullExtent.toString() );
  return fullExtent;
}
Beispiel #17
0
void QgsWCSProjectParser::wcsContentMetadata( QDomElement& parentElement, QDomDocument& doc ) const
{
  const QList<QDomElement>& projectLayerElements = mProjectParser.projectLayerElements();
  if ( projectLayerElements.size() < 1 )
  {
    return;
  }

  QStringList wcsLayersId = wcsLayers();

  QMap<QString, QgsMapLayer *> layerMap;

  foreach ( const QDomElement &elem, projectLayerElements )
  {
    QString type = elem.attribute( "type" );
    if ( type == "raster" )
    {
      QgsMapLayer *layer = mProjectParser.createLayerFromElement( elem );
      if ( layer && wcsLayersId.contains( layer->id() ) )
      {
        QgsDebugMsg( QString( "add layer %1 to map" ).arg( layer->id() ) );
        layerMap.insert( layer->id(), layer );

        QDomElement layerElem = doc.createElement( "CoverageOfferingBrief" );
        QDomElement nameElem = doc.createElement( "name" );
        //We use the layer name even though it might not be unique.
        //Because the id sometimes contains user/pw information and the name is more descriptive
        QString typeName = layer->name();
        typeName = typeName.replace( " ", "_" );
        QDomText nameText = doc.createTextNode( typeName );
        nameElem.appendChild( nameText );
        layerElem.appendChild( nameElem );

        QDomElement labelElem = doc.createElement( "label" );
        QString titleName = layer->title();
        if ( titleName.isEmpty() )
        {
          titleName = layer->name();
        }
        QDomText labelText = doc.createTextNode( titleName );
        labelElem.appendChild( labelText );
        layerElem.appendChild( labelElem );

        QDomElement descriptionElem = doc.createElement( "description" );
        QString abstractName = layer->abstract();
        if ( abstractName.isEmpty() )
        {
          abstractName = "";
        }
        QDomText descriptionText = doc.createTextNode( abstractName );
        descriptionElem.appendChild( descriptionText );
        layerElem.appendChild( descriptionElem );

        //lonLatEnvelope
        const QgsCoordinateReferenceSystem& layerCrs = layer->crs();
        QgsCoordinateTransform t( layerCrs, QgsCoordinateReferenceSystem( 4326 ) );
        //transform
        QgsRectangle BBox = t.transformBoundingBox( layer->extent() );
        QDomElement lonLatElem = doc.createElement( "lonLatEnvelope" );
        lonLatElem.setAttribute( "srsName", "urn:ogc:def:crs:OGC:1.3:CRS84" );
        QDomElement lowerPosElem = doc.createElement( "gml:pos" );
        QDomText lowerPosText = doc.createTextNode( QString::number( BBox.xMinimum() ) + " " +  QString::number( BBox.yMinimum() ) );
        lowerPosElem.appendChild( lowerPosText );
        lonLatElem.appendChild( lowerPosElem );
        QDomElement upperPosElem = doc.createElement( "gml:pos" );
        QDomText upperPosText = doc.createTextNode( QString::number( BBox.xMaximum() ) + " " +  QString::number( BBox.yMaximum() ) );
        upperPosElem.appendChild( upperPosText );
        lonLatElem.appendChild( upperPosElem );
        layerElem.appendChild( lonLatElem );

        parentElement.appendChild( layerElem );
      }
    }
  }
  QDomDocument createDescribeFeatureTypeDocument( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
      const QgsServerRequest &request )
  {
    Q_UNUSED( version );

    QDomDocument doc;

    QgsServerRequest::Parameters parameters = request.parameters();
    QgsWfsParameters wfsParameters( parameters );
    QgsWfsParameters::Format oFormat = wfsParameters.outputFormat();

    // test oFormat
    if ( oFormat == QgsWfsParameters::Format::NONE )
      throw QgsBadRequestException( QStringLiteral( "Invalid WFS Parameter" ),
                                    "OUTPUTFORMAT " + wfsParameters.outputFormatAsString() + "is not supported" );

    QgsAccessControl *accessControl = serverIface->accessControls();

    //xsd:schema
    QDomElement schemaElement = doc.createElement( QStringLiteral( "schema" )/*xsd:schema*/ );
    schemaElement.setAttribute( QStringLiteral( "xmlns" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema" ) );
    schemaElement.setAttribute( QStringLiteral( "xmlns:xsd" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema" ) );
    schemaElement.setAttribute( QStringLiteral( "xmlns:ogc" ), OGC_NAMESPACE );
    schemaElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
    schemaElement.setAttribute( QStringLiteral( "xmlns:qgs" ), QGS_NAMESPACE );
    schemaElement.setAttribute( QStringLiteral( "targetNamespace" ), QGS_NAMESPACE );
    schemaElement.setAttribute( QStringLiteral( "elementFormDefault" ), QStringLiteral( "qualified" ) );
    schemaElement.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0" ) );
    doc.appendChild( schemaElement );

    //xsd:import
    QDomElement importElement = doc.createElement( QStringLiteral( "import" )/*xsd:import*/ );
    importElement.setAttribute( QStringLiteral( "namespace" ),  GML_NAMESPACE );
    if ( oFormat == QgsWfsParameters::Format::GML2 )
      importElement.setAttribute( QStringLiteral( "schemaLocation" ), QStringLiteral( "http://schemas.opengis.net/gml/2.1.2/feature.xsd" ) );
    else if ( oFormat == QgsWfsParameters::Format::GML3 )
      importElement.setAttribute( QStringLiteral( "schemaLocation" ), QStringLiteral( "http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" ) );
    schemaElement.appendChild( importElement );

    QStringList typeNameList;
    QDomDocument queryDoc;
    QString errorMsg;
    if ( queryDoc.setContent( parameters.value( QStringLiteral( "REQUEST_BODY" ) ), true, &errorMsg ) )
    {
      //read doc
      QDomElement queryDocElem = queryDoc.documentElement();
      QDomNodeList docChildNodes = queryDocElem.childNodes();
      if ( docChildNodes.size() )
      {
        for ( int i = 0; i < docChildNodes.size(); i++ )
        {
          QDomElement docChildElem = docChildNodes.at( i ).toElement();
          if ( docChildElem.tagName() == QLatin1String( "TypeName" ) )
          {
            QString typeName = docChildElem.text().trimmed();
            if ( typeName.contains( ':' ) )
              typeNameList << typeName.section( ':', 1, 1 );
            else
              typeNameList << typeName;
          }
        }
      }
    }
    else
    {
      QString typeNames = request.parameter( QStringLiteral( "TYPENAME" ) );
      if ( !typeNames.isEmpty() )
      {
        QStringList typeNameSplit = typeNames.split( ',' );
        for ( int i = 0; i < typeNameSplit.size(); ++i )
        {
          QString typeName = typeNameSplit.at( i ).trimmed();
          if ( typeName.contains( ':' ) )
            typeNameList << typeName.section( ':', 1, 1 );
          else
            typeNameList << typeName;
        }
      }
    }

    QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
    for ( int i = 0; i < wfsLayerIds.size(); ++i )
    {
      QgsMapLayer *layer = project->mapLayer( wfsLayerIds.at( i ) );
      if ( layer->type() != QgsMapLayer::LayerType::VectorLayer )
      {
        continue;
      }

      QString name = layer->name();
      if ( !layer->shortName().isEmpty() )
        name = layer->shortName();
      name = name.replace( ' ', '_' );

      if ( !typeNameList.isEmpty() && !typeNameList.contains( name ) )
      {
        continue;
      }

      if ( accessControl && !accessControl->layerReadPermission( layer ) )
      {
        if ( !typeNameList.isEmpty() )
        {
          throw QgsSecurityAccessException( QStringLiteral( "Feature access permission denied" ) );
        }
        else
        {
          continue;
        }
      }

      QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( layer );
      QgsVectorDataProvider *provider = vLayer->dataProvider();
      if ( !provider )
      {
        continue;
      }
      setSchemaLayer( schemaElement, doc, const_cast<QgsVectorLayer *>( vLayer ) );
    }
    return doc;
  }
Beispiel #19
0
  QUrlQuery translateWmtsParamToWmsQueryItem( const QString &request, const QgsWmtsParameters &params,
      const QgsProject *project, QgsServerInterface *serverIface )
  {
#ifndef HAVE_SERVER_PYTHON_PLUGINS
    ( void )serverIface;
#endif

    //defining Layer
    QString layer = params.layer();
    //read Layer
    if ( layer.isEmpty() )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "Layer is mandatory" ) );
    }
    //check layer value
    bool wmtsProject = project->readBoolEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Project" ) );
    QStringList wmtsGroupNameList = project->readListEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Group" ) );
    QStringList wmtsLayerIdList = project->readListEntry( QStringLiteral( "WMTSLayers" ), QStringLiteral( "Layer" ) );
    QStringList wmtsLayerIds;
    if ( wmtsProject )
    {
      // Root Layer name
      QString rootLayerId = QgsServerProjectUtils::wmsRootName( *project );
      if ( rootLayerId.isEmpty() )
      {
        rootLayerId = project->title();
      }
      if ( !rootLayerId.isEmpty() )
      {
        wmtsLayerIds << rootLayerId;
      }
    }
    if ( !wmtsGroupNameList.isEmpty() )
    {
      QgsLayerTreeGroup *treeRoot = project->layerTreeRoot();
      for ( const QString &gName : wmtsGroupNameList )
      {
        QgsLayerTreeGroup *treeGroup = treeRoot->findGroup( gName );
        if ( !treeGroup )
        {
          continue;
        }
        QString groupLayerId = treeGroup->customProperty( QStringLiteral( "wmsShortName" ) ).toString();
        if ( groupLayerId.isEmpty() )
        {
          groupLayerId = gName;
        }
        wmtsLayerIds << groupLayerId;
      }
    }
    if ( !wmtsLayerIdList.isEmpty() )
    {
#ifdef HAVE_SERVER_PYTHON_PLUGINS
      QgsAccessControl *accessControl = serverIface->accessControls();
#endif
      for ( const QString &lId : wmtsLayerIdList )
      {
        QgsMapLayer *l = project->mapLayer( lId );
        if ( !l )
        {
          continue;
        }
#ifdef HAVE_SERVER_PYTHON_PLUGINS
        if ( !accessControl->layerReadPermission( l ) )
        {
          continue;
        }
#endif
        QString layerLayerId = l->shortName();
        if ( layerLayerId.isEmpty() )
        {
          layerLayerId = l->name();
        }
        wmtsLayerIds << layerLayerId;
      }
    }
    if ( !wmtsLayerIds.contains( layer ) )
    {
      QString msg = QObject::tr( "Layer '%1' not found" ).arg( layer );
      throw QgsBadRequestException( QStringLiteral( "LayerNotDefined" ), msg );
    }

    //defining Format
    QString format = params.formatAsString();
    //read Format
    if ( format.isEmpty() )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "Format is mandatory" ) );
    }

    //defining TileMatrixSet ref
    QString tms_ref = params.tileMatrixSet();
    //read TileMatrixSet
    if ( tms_ref.isEmpty() )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is mandatory" ) );
    }

    // verifying TileMatrixSet value
    QList< tileMatrixSetDef > tmsList = getTileMatrixSetList( project, tms_ref );
    if ( tmsList.isEmpty() )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) );
    }
    tileMatrixSetDef tms = tmsList[0];
    if ( tms.ref != tms_ref )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrixSet is unknown" ) );
    }

    //defining TileMatrix idx
    int tm_idx = params.tileMatrixAsInt();
    //read TileMatrix
    if ( tm_idx < 0 || tms.tileMatrixList.count() < tm_idx )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileMatrix is unknown" ) );
    }
    tileMatrixDef tm = tms.tileMatrixList.at( tm_idx );

    //defining TileRow
    int tr = params.tileRowAsInt();
    //read TileRow
    if ( tr < 0 || tm.row <= tr )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileRow is unknown" ) );
    }

    //defining TileCol
    int tc = params.tileColAsInt();
    //read TileCol
    if ( tc < 0 || tm.col <= tc )
    {
      throw QgsRequestNotWellFormedException( QStringLiteral( "TileCol is unknown" ) );
    }

    double res = tm.resolution;
    double minx = tm.left + tc * ( tileSize * res );
    double miny = tm.top - ( tr + 1 ) * ( tileSize * res );
    double maxx = tm.left + ( tc + 1 ) * ( tileSize * res );
    double maxy = tm.top - tr * ( tileSize * res );
    QString bbox;
    if ( tms.hasAxisInverted )
    {
      bbox = qgsDoubleToString( miny, 6 ) + ',' +
             qgsDoubleToString( minx, 6 ) + ',' +
             qgsDoubleToString( maxy, 6 ) + ',' +
             qgsDoubleToString( maxx, 6 );
    }
    else
    {
      bbox = qgsDoubleToString( minx, 6 ) + ',' +
             qgsDoubleToString( miny, 6 ) + ',' +
             qgsDoubleToString( maxx, 6 ) + ',' +
             qgsDoubleToString( maxy, 6 );
    }

    QUrlQuery query;
    if ( !params.value( QStringLiteral( "MAP" ) ).isEmpty() )
    {
      query.addQueryItem( QgsServerParameter::name( QgsServerParameter::MAP ), params.value( QStringLiteral( "MAP" ) ) );
    }
    query.addQueryItem( QgsServerParameter::name( QgsServerParameter::SERVICE ), QStringLiteral( "WMS" ) );
    query.addQueryItem( QgsServerParameter::name( QgsServerParameter::VERSION_SERVICE ), QStringLiteral( "1.3.0" ) );
    query.addQueryItem( QgsServerParameter::name( QgsServerParameter::REQUEST ), request );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::LAYERS ), layer );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::STYLES ), QString() );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::CRS ), tms.ref );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::BBOX ), bbox );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::WIDTH ), QStringLiteral( "256" ) );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::HEIGHT ), QStringLiteral( "256" ) );
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::FORMAT ), format );
    if ( params.format() == QgsWmtsParameters::Format::PNG )
    {
      query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::TRANSPARENT ), QStringLiteral( "true" ) );
    }
    query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::DPI ), QStringLiteral( "96" ) );

    return query;
  }
void QgsOfflineEditing::synchronize()
{
  // open logging db
  sqlite3* db = openLoggingDb();
  if ( db == NULL )
  {
    return;
  }

  emit progressStarted();

  // restore and sync remote layers
  QList<QgsMapLayer*> offlineLayers;
  QMap<QString, QgsMapLayer*> mapLayers = QgsMapLayerRegistry::instance()->mapLayers();
  for ( QMap<QString, QgsMapLayer*>::iterator layer_it = mapLayers.begin() ; layer_it != mapLayers.end(); ++layer_it )
  {
    QgsMapLayer* layer = layer_it.value();
    if ( layer->customProperty( CUSTOM_PROPERTY_IS_OFFLINE_EDITABLE, false ).toBool() )
    {
      offlineLayers << layer;
    }
  }

  for ( int l = 0; l < offlineLayers.count(); l++ )
  {
    QgsMapLayer* layer = offlineLayers[l];

    emit layerProgressUpdated( l + 1, offlineLayers.count() );

    QString remoteSource = layer->customProperty( CUSTOM_PROPERTY_REMOTE_SOURCE, "" ).toString();
    QString remoteProvider = layer->customProperty( CUSTOM_PROPERTY_REMOTE_PROVIDER, "" ).toString();
    QString remoteName = layer->name();
    remoteName.remove( QRegExp( " \\(offline\\)$" ) );

    QgsVectorLayer* remoteLayer = new QgsVectorLayer( remoteSource, remoteName, remoteProvider );
    if ( remoteLayer->isValid() )
    {
      // TODO: only add remote layer if there are log entries?

      QgsVectorLayer* offlineLayer = qobject_cast<QgsVectorLayer*>( layer );

      // copy style
      copySymbology( offlineLayer, remoteLayer );

      // register this layer with the central layers registry
      QgsMapLayerRegistry::instance()->addMapLayers(
        QList<QgsMapLayer *>() << remoteLayer, true );

      // apply layer edit log
      QString qgisLayerId = layer->id();
      QString sql = QString( "SELECT \"id\" FROM 'log_layer_ids' WHERE \"qgis_id\" = '%1'" ).arg( qgisLayerId );
      int layerId = sqlQueryInt( db, sql, -1 );
      if ( layerId != -1 )
      {
        remoteLayer->startEditing();

        // TODO: only get commitNos of this layer?
        int commitNo = getCommitNo( db );
        for ( int i = 0; i < commitNo; i++ )
        {
          // apply commits chronologically
          applyAttributesAdded( remoteLayer, db, layerId, i );
          applyAttributeValueChanges( offlineLayer, remoteLayer, db, layerId, i );
          applyGeometryChanges( remoteLayer, db, layerId, i );
        }

        applyFeaturesAdded( offlineLayer, remoteLayer, db, layerId );
        applyFeaturesRemoved( remoteLayer, db, layerId );

        if ( remoteLayer->commitChanges() )
        {
          // update fid lookup
          updateFidLookup( remoteLayer, db, layerId );

          // clear edit log for this layer
          sql = QString( "DELETE FROM 'log_added_attrs' WHERE \"layer_id\" = %1" ).arg( layerId );
          sqlExec( db, sql );
          sql = QString( "DELETE FROM 'log_added_features' WHERE \"layer_id\" = %1" ).arg( layerId );
          sqlExec( db, sql );
          sql = QString( "DELETE FROM 'log_removed_features' WHERE \"layer_id\" = %1" ).arg( layerId );
          sqlExec( db, sql );
          sql = QString( "DELETE FROM 'log_feature_updates' WHERE \"layer_id\" = %1" ).arg( layerId );
          sqlExec( db, sql );
          sql = QString( "DELETE FROM 'log_geometry_updates' WHERE \"layer_id\" = %1" ).arg( layerId );
          sqlExec( db, sql );

          // reset commitNo
          QString sql = QString( "UPDATE 'log_indices' SET 'last_index' = 0 WHERE \"name\" = 'commit_no'" );
          sqlExec( db, sql );
        }
        else
        {
          showWarning( remoteLayer->commitErrors().join( "\n" ) );
        }
      }

      // remove offline layer
      QgsMapLayerRegistry::instance()->removeMapLayers(
        ( QStringList() << qgisLayerId ) );

      // disable offline project
      QString projectTitle = QgsProject::instance()->title();
      projectTitle.remove( QRegExp( " \\(offline\\)$" ) );
      QgsProject::instance()->title( projectTitle );
      QgsProject::instance()->removeEntry( PROJECT_ENTRY_SCOPE_OFFLINE, PROJECT_ENTRY_KEY_OFFLINE_DB_PATH );
      remoteLayer->reload(); //update with other changes
    }
  }

  emit progressStopped();

  sqlite3_close( db );
}
Beispiel #21
0
void QgsMapRenderer::render( QPainter* painter )
{
  //flag to see if the render context has changed
  //since the last time we rendered. If it hasnt changed we can
  //take some shortcuts with rendering
  bool mySameAsLastFlag = true;

  QgsDebugMsg( "========== Rendering ==========" );

  if ( mExtent.isEmpty() )
  {
    QgsDebugMsg( "empty extent... not rendering" );
    return;
  }

  if ( mSize.width() == 1 && mSize.height() == 1 )
  {
    QgsDebugMsg( "size 1x1... not rendering" );
    return;
  }

  QPaintDevice* thePaintDevice = painter->device();
  if ( !thePaintDevice )
  {
    return;
  }

  // wait
  if ( mDrawing )
  {
    QgsDebugMsg( "already rendering" );
    QCoreApplication::processEvents();
  }

  if ( mDrawing )
  {
    QgsDebugMsg( "still rendering - skipping" );
    return;
  }

  mDrawing = true;

  QgsCoordinateTransform* ct;

#ifdef QGISDEBUG
  QgsDebugMsg( "Starting to render layer stack." );
  QTime renderTime;
  renderTime.start();
#endif

  if ( mOverview )
    mRenderContext.setDrawEditingInformation( !mOverview );

  mRenderContext.setPainter( painter );
  mRenderContext.setCoordinateTransform( 0 );
  //this flag is only for stopping during the current rendering progress,
  //so must be false at every new render operation
  mRenderContext.setRenderingStopped( false );

  //calculate scale factor
  //use the specified dpi and not those from the paint device
  //because sometimes QPainter units are in a local coord sys (e.g. in case of QGraphicsScene)
  double sceneDpi = mScaleCalculator->dpi();
  double scaleFactor = 1.0;
  if ( mOutputUnits == QgsMapRenderer::Millimeters )
  {
    scaleFactor = sceneDpi / 25.4;
  }
  double rasterScaleFactor = ( thePaintDevice->logicalDpiX() + thePaintDevice->logicalDpiY() ) / 2.0 / sceneDpi;
  if ( mRenderContext.rasterScaleFactor() != rasterScaleFactor )
  {
    mRenderContext.setRasterScaleFactor( rasterScaleFactor );
    mySameAsLastFlag = false;
  }
  if ( mRenderContext.scaleFactor() != scaleFactor )
  {
    mRenderContext.setScaleFactor( scaleFactor );
    mySameAsLastFlag = false;
  }
  if ( mRenderContext.rendererScale() != mScale )
  {
    //add map scale to render context
    mRenderContext.setRendererScale( mScale );
    mySameAsLastFlag = false;
  }
  if ( mLastExtent != mExtent )
  {
    mLastExtent = mExtent;
    mySameAsLastFlag = false;
  }

  mRenderContext.setLabelingEngine( mLabelingEngine );
  if ( mLabelingEngine )
    mLabelingEngine->init( this );

  // know we know if this render is just a repeat of the last time, we
  // can clear caches if it has changed
  if ( !mySameAsLastFlag )
  {
    //clear the cache pixmap if we changed resolution / extent
    QSettings mySettings;
    if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
    {
      QgsMapLayerRegistry::instance()->clearAllLayerCaches();
    }
  }

  QgsOverlayObjectPositionManager* overlayManager = overlayManagerFromSettings();
  QList<QgsVectorOverlay*> allOverlayList; //list of all overlays, used to draw them after layers have been rendered

  // render all layers in the stack, starting at the base
  QListIterator<QString> li( mLayerSet );
  li.toBack();

  QgsRectangle r1, r2;

  while ( li.hasPrevious() )
  {
    if ( mRenderContext.renderingStopped() )
    {
      break;
    }

    // Store the painter in case we need to swap it out for the
    // cache painter
    QPainter * mypContextPainter = mRenderContext.painter();

    QString layerId = li.previous();

    QgsDebugMsg( "Rendering at layer item " + layerId );

    // This call is supposed to cause the progress bar to
    // advance. However, it seems that updating the progress bar is
    // incompatible with having a QPainter active (the one that is
    // passed into this function), as Qt produces a number of errors
    // when try to do so. I'm (Gavin) not sure how to fix this, but
    // added these comments and debug statement to help others...
    QgsDebugMsg( "If there is a QPaintEngine error here, it is caused by an emit call" );

    //emit drawingProgress(myRenderCounter++, mLayerSet.size());
    QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer( layerId );

    if ( !ml )
    {
      QgsDebugMsg( "Layer not found in registry!" );
      continue;
    }

    QgsDebugMsg( "Rendering layer " + ml->name() );
    QgsDebugMsg( "  Layer minscale " + QString( "%1" ).arg( ml->minimumScale() ) );
    QgsDebugMsg( "  Layer maxscale " + QString( "%1" ).arg( ml->maximumScale() ) );
    QgsDebugMsg( "  Scale dep. visibility enabled? " + QString( "%1" ).arg( ml->hasScaleBasedVisibility() ) );
    QgsDebugMsg( "  Input extent: " + ml->extent().toString() );

    if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() < mScale && mScale < ml->maximumScale() ) || mOverview )
    {
      connect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );

      //
      // Now do the call to the layer that actually does
      // the rendering work!
      //

      bool split = false;

      if ( hasCrsTransformEnabled() )
      {
        r1 = mExtent;
        split = splitLayersExtent( ml, r1, r2 );
        ct = new QgsCoordinateTransform( ml->crs(), *mDestCRS );
        mRenderContext.setExtent( r1 );
        QgsDebugMsg( "  extent 1: " + r1.toString() );
        QgsDebugMsg( "  extent 2: " + r2.toString() );
        if ( !r1.isFinite() || !r2.isFinite() ) //there was a problem transforming the extent. Skip the layer
        {
          continue;
        }
      }
      else
      {
        ct = NULL;
      }

      mRenderContext.setCoordinateTransform( ct );

      //decide if we have to scale the raster
      //this is necessary in case QGraphicsScene is used
      bool scaleRaster = false;
      QgsMapToPixel rasterMapToPixel;
      QgsMapToPixel bk_mapToPixel;

      if ( ml->type() == QgsMapLayer::RasterLayer && qAbs( rasterScaleFactor - 1.0 ) > 0.000001 )
      {
        scaleRaster = true;
      }


      //create overlay objects for features within the view extent
      if ( ml->type() == QgsMapLayer::VectorLayer && overlayManager )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ( vl )
        {
          QList<QgsVectorOverlay*> thisLayerOverlayList;
          vl->vectorOverlays( thisLayerOverlayList );

          QList<QgsVectorOverlay*>::iterator overlayIt = thisLayerOverlayList.begin();
          for ( ; overlayIt != thisLayerOverlayList.end(); ++overlayIt )
          {
            if (( *overlayIt )->displayFlag() )
            {
              ( *overlayIt )->createOverlayObjects( mRenderContext );
              allOverlayList.push_back( *overlayIt );
            }
          }

          overlayManager->addLayer( vl, thisLayerOverlayList );
        }
      }

      // Force render of layers that are being edited
      // or if there's a labeling engine that needs the layer to register features
      if ( ml->type() == QgsMapLayer::VectorLayer )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ( vl->isEditable() ||
             ( mRenderContext.labelingEngine() && mRenderContext.labelingEngine()->willUseLayer( vl ) ) )
        {
          ml->setCacheImage( 0 );
        }
      }

      QSettings mySettings;
      if ( ! split )//render caching does not yet cater for split extents
      {
        if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
        {
          if ( !mySameAsLastFlag || ml->cacheImage() == 0 )
          {
            QgsDebugMsg( "\n\n\nCaching enabled but layer redraw forced by extent change or empty cache\n\n\n" );
            QImage * mypImage = new QImage( mRenderContext.painter()->device()->width(),
                                            mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 );
            mypImage->fill( 0 );
            ml->setCacheImage( mypImage ); //no need to delete the old one, maplayer does it for you
            QPainter * mypPainter = new QPainter( ml->cacheImage() );
            // Changed to enable anti aliasing by default in QGIS 1.7
            if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
            {
              mypPainter->setRenderHint( QPainter::Antialiasing );
            }
            mRenderContext.setPainter( mypPainter );
          }
          else if ( mySameAsLastFlag )
          {
            //draw from cached image
            QgsDebugMsg( "\n\n\nCaching enabled --- drawing layer from cached image\n\n\n" );
            mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
            disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
            //short circuit as there is nothing else to do...
            continue;
          }
        }
      }

      if ( scaleRaster )
      {
        bk_mapToPixel = mRenderContext.mapToPixel();
        rasterMapToPixel = mRenderContext.mapToPixel();
        rasterMapToPixel.setMapUnitsPerPixel( mRenderContext.mapToPixel().mapUnitsPerPixel() / rasterScaleFactor );
        rasterMapToPixel.setYMaximum( mSize.height() * rasterScaleFactor );
        mRenderContext.setMapToPixel( rasterMapToPixel );
        mRenderContext.painter()->save();
        mRenderContext.painter()->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
      }


      if ( !ml->draw( mRenderContext ) )
      {
        emit drawError( ml );
      }
      else
      {
        QgsDebugMsg( "Layer rendered without issues" );
      }

      if ( split )
      {
        mRenderContext.setExtent( r2 );
        if ( !ml->draw( mRenderContext ) )
        {
          emit drawError( ml );
        }
      }

      if ( scaleRaster )
      {
        mRenderContext.setMapToPixel( bk_mapToPixel );
        mRenderContext.painter()->restore();
      }

      if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
      {
        if ( !split )
        {
          // composite the cached image into our view and then clean up from caching
          // by reinstating the painter as it was swapped out for caching renders
          delete mRenderContext.painter();
          mRenderContext.setPainter( mypContextPainter );
          //draw from cached image that we created further up
          mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
        }
      }
      disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
    }
    else // layer not visible due to scale
    {
Beispiel #22
0
void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
{
  //Lock render method for concurrent threads (e.g. from globe)
  QMutexLocker renderLock( &mRenderMutex );

  //flag to see if the render context has changed
  //since the last time we rendered. If it hasnt changed we can
  //take some shortcuts with rendering
  bool mySameAsLastFlag = true;

  QgsDebugMsg( "========== Rendering ==========" );

  if ( mExtent.isEmpty() )
  {
    QgsDebugMsg( "empty extent... not rendering" );
    return;
  }

  if ( mSize.width() == 1 && mSize.height() == 1 )
  {
    QgsDebugMsg( "size 1x1... not rendering" );
    return;
  }

  QPaintDevice* thePaintDevice = painter->device();
  if ( !thePaintDevice )
  {
    return;
  }

  // wait
  if ( mDrawing )
  {
    QgsDebugMsg( "already rendering" );
    QCoreApplication::processEvents();
  }

  if ( mDrawing )
  {
    QgsDebugMsg( "still rendering - skipping" );
    return;
  }

  mDrawing = true;

  const QgsCoordinateTransform *ct;

#ifdef QGISDEBUG
  QgsDebugMsg( "Starting to render layer stack." );
  QTime renderTime;
  renderTime.start();
#endif

  if ( mOverview )
    mRenderContext.setDrawEditingInformation( !mOverview );

  mRenderContext.setPainter( painter );
  mRenderContext.setCoordinateTransform( 0 );
  //this flag is only for stopping during the current rendering progress,
  //so must be false at every new render operation
  mRenderContext.setRenderingStopped( false );

  // set selection color
  QgsProject* prj = QgsProject::instance();
  int myRed = prj->readNumEntry( "Gui", "/SelectionColorRedPart", 255 );
  int myGreen = prj->readNumEntry( "Gui", "/SelectionColorGreenPart", 255 );
  int myBlue = prj->readNumEntry( "Gui", "/SelectionColorBluePart", 0 );
  int myAlpha = prj->readNumEntry( "Gui", "/SelectionColorAlphaPart", 255 );
  mRenderContext.setSelectionColor( QColor( myRed, myGreen, myBlue, myAlpha ) );

  //calculate scale factor
  //use the specified dpi and not those from the paint device
  //because sometimes QPainter units are in a local coord sys (e.g. in case of QGraphicsScene)
  double sceneDpi = mScaleCalculator->dpi();
  double scaleFactor = 1.0;
  if ( mOutputUnits == QgsMapRenderer::Millimeters )
  {
    if ( forceWidthScale )
    {
      scaleFactor = *forceWidthScale;
    }
    else
    {
      scaleFactor = sceneDpi / 25.4;
    }
  }
  double rasterScaleFactor = ( thePaintDevice->logicalDpiX() + thePaintDevice->logicalDpiY() ) / 2.0 / sceneDpi;
  if ( mRenderContext.rasterScaleFactor() != rasterScaleFactor )
  {
    mRenderContext.setRasterScaleFactor( rasterScaleFactor );
    mySameAsLastFlag = false;
  }
  if ( mRenderContext.scaleFactor() != scaleFactor )
  {
    mRenderContext.setScaleFactor( scaleFactor );
    mySameAsLastFlag = false;
  }
  if ( mRenderContext.rendererScale() != mScale )
  {
    //add map scale to render context
    mRenderContext.setRendererScale( mScale );
    mySameAsLastFlag = false;
  }
  if ( mLastExtent != mExtent )
  {
    mLastExtent = mExtent;
    mySameAsLastFlag = false;
  }

  mRenderContext.setLabelingEngine( mLabelingEngine );
  if ( mLabelingEngine )
    mLabelingEngine->init( this );

  // know we know if this render is just a repeat of the last time, we
  // can clear caches if it has changed
  if ( !mySameAsLastFlag )
  {
    //clear the cache pixmap if we changed resolution / extent
    QSettings mySettings;
    if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
    {
      QgsMapLayerRegistry::instance()->clearAllLayerCaches();
    }
  }

  // render all layers in the stack, starting at the base
  QListIterator<QString> li( mLayerSet );
  li.toBack();

  QgsRectangle r1, r2;

  while ( li.hasPrevious() )
  {
    if ( mRenderContext.renderingStopped() )
    {
      break;
    }

    // Store the painter in case we need to swap it out for the
    // cache painter
    QPainter * mypContextPainter = mRenderContext.painter();
    // Flattened image for drawing when a blending mode is set
    QImage * mypFlattenedImage = 0;

    QString layerId = li.previous();

    QgsDebugMsg( "Rendering at layer item " + layerId );

    // This call is supposed to cause the progress bar to
    // advance. However, it seems that updating the progress bar is
    // incompatible with having a QPainter active (the one that is
    // passed into this function), as Qt produces a number of errors
    // when try to do so. I'm (Gavin) not sure how to fix this, but
    // added these comments and debug statement to help others...
    QgsDebugMsg( "If there is a QPaintEngine error here, it is caused by an emit call" );

    //emit drawingProgress(myRenderCounter++, mLayerSet.size());
    QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer( layerId );

    if ( !ml )
    {
      QgsDebugMsg( "Layer not found in registry!" );
      continue;
    }

    QgsDebugMsg( QString( "layer %1:  minscale:%2  maxscale:%3  scaledepvis:%4  extent:%5  blendmode:%6" )
                 .arg( ml->name() )
                 .arg( ml->minimumScale() )
                 .arg( ml->maximumScale() )
                 .arg( ml->hasScaleBasedVisibility() )
                 .arg( ml->extent().toString() )
                 .arg( ml->blendMode() )
               );

    if ( mRenderContext.useAdvancedEffects() )
    {
      // Set the QPainter composition mode so that this layer is rendered using
      // the desired blending mode
      mypContextPainter->setCompositionMode( ml->blendMode() );
    }

    if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() <= mScale && mScale < ml->maximumScale() ) || mOverview )
    {
      connect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );

      //
      // Now do the call to the layer that actually does
      // the rendering work!
      //

      bool split = false;

      if ( hasCrsTransformEnabled() )
      {
        r1 = mExtent;
        split = splitLayersExtent( ml, r1, r2 );
        ct = transformation( ml );
        mRenderContext.setExtent( r1 );
        QgsDebugMsg( "  extent 1: " + r1.toString() );
        QgsDebugMsg( "  extent 2: " + r2.toString() );
        if ( !r1.isFinite() || !r2.isFinite() ) //there was a problem transforming the extent. Skip the layer
        {
          continue;
        }
      }
      else
      {
        ct = NULL;
      }

      mRenderContext.setCoordinateTransform( ct );

      //decide if we have to scale the raster
      //this is necessary in case QGraphicsScene is used
      bool scaleRaster = false;
      QgsMapToPixel rasterMapToPixel;
      QgsMapToPixel bk_mapToPixel;

      if ( ml->type() == QgsMapLayer::RasterLayer && qAbs( rasterScaleFactor - 1.0 ) > 0.000001 )
      {
        scaleRaster = true;
      }

      // Force render of layers that are being edited
      // or if there's a labeling engine that needs the layer to register features
      if ( ml->type() == QgsMapLayer::VectorLayer )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ( vl->isEditable() ||
             ( mRenderContext.labelingEngine() && mRenderContext.labelingEngine()->willUseLayer( vl ) ) )
        {
          ml->setCacheImage( 0 );
        }
      }

      QSettings mySettings;
      bool useRenderCaching = false;
      if ( ! split )//render caching does not yet cater for split extents
      {
        if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
        {
          useRenderCaching = true;
          if ( !mySameAsLastFlag || ml->cacheImage() == 0 )
          {
            QgsDebugMsg( "Caching enabled but layer redraw forced by extent change or empty cache" );
            QImage * mypImage = new QImage( mRenderContext.painter()->device()->width(),
                                            mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 );
            if ( mypImage->isNull() )
            {
              QgsDebugMsg( "insufficient memory for image " + QString::number( mRenderContext.painter()->device()->width() ) + "x" + QString::number( mRenderContext.painter()->device()->height() ) );
              emit drawError( ml );
              painter->end(); // drawError is not caught by anyone, so we end painting to notify caller
              return;
            }
            mypImage->fill( 0 );
            ml->setCacheImage( mypImage ); //no need to delete the old one, maplayer does it for you
            QPainter * mypPainter = new QPainter( ml->cacheImage() );
            // Changed to enable anti aliasing by default in QGIS 1.7
            if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
            {
              mypPainter->setRenderHint( QPainter::Antialiasing );
            }
            mRenderContext.setPainter( mypPainter );
          }
          else if ( mySameAsLastFlag )
          {
            //draw from cached image
            QgsDebugMsg( "Caching enabled --- drawing layer from cached image" );
            mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
            disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
            //short circuit as there is nothing else to do...
            continue;
          }
        }
      }

      // If we are drawing with an alternative blending mode then we need to render to a separate image
      // before compositing this on the map. This effectively flattens the layer and prevents
      // blending occuring between objects on the layer
      // (this is not required for raster layers or when layer caching is enabled, since that has the same effect)
      bool flattenedLayer = false;
      if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if (( !useRenderCaching )
            && (( vl->blendMode() != QPainter::CompositionMode_SourceOver )
                || ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver )
                || ( vl->layerTransparency() != 0 ) ) )
        {
          flattenedLayer = true;
          mypFlattenedImage = new QImage( mRenderContext.painter()->device()->width(),
                                          mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 );
          if ( mypFlattenedImage->isNull() )
          {
            QgsDebugMsg( "insufficient memory for image " + QString::number( mRenderContext.painter()->device()->width() ) + "x" + QString::number( mRenderContext.painter()->device()->height() ) );
            emit drawError( ml );
            painter->end(); // drawError is not caught by anyone, so we end painting to notify caller
            return;
          }
          mypFlattenedImage->fill( 0 );
          QPainter * mypPainter = new QPainter( mypFlattenedImage );
          if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
          {
            mypPainter->setRenderHint( QPainter::Antialiasing );
          }
          mypPainter->scale( rasterScaleFactor,  rasterScaleFactor );
          mRenderContext.setPainter( mypPainter );
        }
      }

      // Per feature blending mode
      if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver )
        {
          // set the painter to the feature blend mode, so that features drawn
          // on this layer will interact and blend with each other
          mRenderContext.painter()->setCompositionMode( vl->featureBlendMode() );
        }
      }

      if ( scaleRaster )
      {
        bk_mapToPixel = mRenderContext.mapToPixel();
        rasterMapToPixel = mRenderContext.mapToPixel();
        rasterMapToPixel.setMapUnitsPerPixel( mRenderContext.mapToPixel().mapUnitsPerPixel() / rasterScaleFactor );
        rasterMapToPixel.setYMaximum( mSize.height() * rasterScaleFactor );
        mRenderContext.setMapToPixel( rasterMapToPixel );
        mRenderContext.painter()->save();
        mRenderContext.painter()->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
      }

      if ( !ml->draw( mRenderContext ) )
      {
        emit drawError( ml );
      }
      else
      {
        QgsDebugMsg( "Layer rendered without issues" );
      }

      if ( split )
      {
        mRenderContext.setExtent( r2 );
        if ( !ml->draw( mRenderContext ) )
        {
          emit drawError( ml );
        }
      }

      if ( scaleRaster )
      {
        mRenderContext.setMapToPixel( bk_mapToPixel );
        mRenderContext.painter()->restore();
      }

      //apply layer transparency for vector layers
      if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ( vl->layerTransparency() != 0 )
        {
          // a layer transparency has been set, so update the alpha for the flattened layer
          // by combining it with the layer transparency
          QColor transparentFillColor = QColor( 0, 0, 0, 255 - ( 255 * vl->layerTransparency() / 100 ) );
          // use destination in composition mode to merge source's alpha with destination
          mRenderContext.painter()->setCompositionMode( QPainter::CompositionMode_DestinationIn );
          mRenderContext.painter()->fillRect( 0, 0, mRenderContext.painter()->device()->width(),
                                              mRenderContext.painter()->device()->height(), transparentFillColor );
        }
      }

      if ( useRenderCaching )
      {
        // composite the cached image into our view and then clean up from caching
        // by reinstating the painter as it was swapped out for caching renders
        delete mRenderContext.painter();
        mRenderContext.setPainter( mypContextPainter );
        //draw from cached image that we created further up
        if ( ml->cacheImage() )
          mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
      }
      else if ( flattenedLayer )
      {
        // If we flattened this layer for alternate blend modes, composite it now
        delete mRenderContext.painter();
        mRenderContext.setPainter( mypContextPainter );
        mypContextPainter->save();
        mypContextPainter->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
        mypContextPainter->drawImage( 0, 0, *( mypFlattenedImage ) );
        mypContextPainter->restore();
        delete mypFlattenedImage;
        mypFlattenedImage = 0;
      }

      disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
    }
QVariantMap QgsRenameLayerAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
{
  QgsMapLayer *layer = parameterAsLayer( parameters, QStringLiteral( "INPUT" ), context );
  QString name = parameterAsString( parameters, QStringLiteral( "NAME" ), context );

  if ( !layer )
    throw QgsProcessingException( QObject::tr( "Invalid input layer" ) );

  if ( name.isEmpty() )
    throw QgsProcessingException( QObject::tr( "Invalid (empty) layer name" ) );

  bool parameterWasLayerName = parameters.value( QStringLiteral( "INPUT" ) ).toString() == layer->name();

  layer->setName( name );
  QVariantMap results;
  if ( parameterWasLayerName )
    results.insert( QStringLiteral( "OUTPUT" ), name );
  else
    results.insert( QStringLiteral( "OUTPUT" ), parameters.value( QStringLiteral( "INPUT" ) ) );

  return results;
}
Beispiel #24
0
LayerRenderJobs QgsMapRendererJob::prepareJobs( QPainter *painter, QgsLabelingEngine *labelingEngine2 )
{
  LayerRenderJobs layerJobs;

  // render all layers in the stack, starting at the base
  QListIterator<QgsMapLayer *> li( mSettings.layers() );
  li.toBack();

  if ( mCache )
  {
    bool cacheValid = mCache->init( mSettings.visibleExtent(), mSettings.scale() );
    Q_UNUSED( cacheValid );
    QgsDebugMsgLevel( QString( "CACHE VALID: %1" ).arg( cacheValid ), 4 );
  }

  bool requiresLabelRedraw = !( mCache && mCache->hasCacheImage( LABEL_CACHE_ID ) );

  while ( li.hasPrevious() )
  {
    QgsMapLayer *ml = li.previous();

    QgsDebugMsgLevel( QString( "layer %1:  minscale:%2  maxscale:%3  scaledepvis:%4  blendmode:%5" )
                      .arg( ml->name() )
                      .arg( ml->minimumScale() )
                      .arg( ml->maximumScale() )
                      .arg( ml->hasScaleBasedVisibility() )
                      .arg( ml->blendMode() )
                      , 3 );

    if ( !ml->isInScaleRange( mSettings.scale() ) ) //|| mOverview )
    {
      QgsDebugMsgLevel( "Layer not rendered because it is not within the defined visibility scale range", 3 );
      continue;
    }

    QgsRectangle r1 = mSettings.visibleExtent(), r2;
    QgsCoordinateTransform ct;

    ct = mSettings.layerTransform( ml );
    if ( ct.isValid() )
    {
      reprojectToLayerExtent( ml, ct, r1, r2 );
    }
    QgsDebugMsgLevel( "extent: " + r1.toString(), 3 );
    if ( !r1.isFinite() || !r2.isFinite() )
    {
      mErrors.append( Error( ml->id(), tr( "There was a problem transforming the layer's extent. Layer skipped." ) ) );
      continue;
    }

    // Force render of layers that are being edited
    // or if there's a labeling engine that needs the layer to register features
    if ( mCache && ml->type() == QgsMapLayer::VectorLayer )
    {
      QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
      bool requiresLabeling = false;
      requiresLabeling = ( labelingEngine2 && QgsPalLabeling::staticWillUseLayer( vl ) ) && requiresLabelRedraw;
      if ( vl->isEditable() || requiresLabeling )
      {
        mCache->clearCacheImage( ml->id() );
      }
    }

    layerJobs.append( LayerRenderJob() );
    LayerRenderJob &job = layerJobs.last();
    job.cached = false;
    job.img = nullptr;
    job.layer = ml;
    job.renderingTime = -1;

    job.context = QgsRenderContext::fromMapSettings( mSettings );
    job.context.expressionContext().appendScope( QgsExpressionContextUtils::layerScope( ml ) );
    job.context.setPainter( painter );
    job.context.setLabelingEngine( labelingEngine2 );
    job.context.setCoordinateTransform( ct );
    job.context.setExtent( r1 );

    if ( mFeatureFilterProvider )
      job.context.setFeatureFilterProvider( mFeatureFilterProvider );

    QgsMapLayerStyleOverride styleOverride( ml );
    if ( mSettings.layerStyleOverrides().contains( ml->id() ) )
      styleOverride.setOverrideStyle( mSettings.layerStyleOverrides().value( ml->id() ) );

    job.blendMode = ml->blendMode();
    job.opacity = 1.0;
    if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml ) )
    {
      job.opacity = vl->opacity();
    }

    // if we can use the cache, let's do it and avoid rendering!
    if ( mCache && mCache->hasCacheImage( ml->id() ) )
    {
      job.cached = true;
      job.imageInitialized = true;
      job.img = new QImage( mCache->cacheImage( ml->id() ) );
      job.renderer = nullptr;
      job.context.setPainter( nullptr );
      continue;
    }

    // If we are drawing with an alternative blending mode then we need to render to a separate image
    // before compositing this on the map. This effectively flattens the layer and prevents
    // blending occurring between objects on the layer
    if ( mCache || !painter || needTemporaryImage( ml ) )
    {
      // Flattened image for drawing when a blending mode is set
      QImage *mypFlattenedImage = nullptr;
      mypFlattenedImage = new QImage( mSettings.outputSize().width(),
                                      mSettings.outputSize().height(),
                                      mSettings.outputImageFormat() );
      if ( mypFlattenedImage->isNull() )
      {
        mErrors.append( Error( ml->id(), tr( "Insufficient memory for image %1x%2" ).arg( mSettings.outputSize().width() ).arg( mSettings.outputSize().height() ) ) );
        delete mypFlattenedImage;
        layerJobs.removeLast();
        continue;
      }

      job.img = mypFlattenedImage;
      QPainter *mypPainter = new QPainter( job.img );
      mypPainter->setRenderHint( QPainter::Antialiasing, mSettings.testFlag( QgsMapSettings::Antialiasing ) );
      job.context.setPainter( mypPainter );
    }

    QTime layerTime;
    layerTime.start();
    job.renderer = ml->createMapRenderer( job.context );
    job.renderingTime = layerTime.elapsed(); // include job preparation time in layer rendering time
  } // while (li.hasPrevious())

  return layerJobs;
}
QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *parent, Qt::WFlags fl )
    : QDialog( parent, fl )
    , mMapCanvas( mapCanvas )
{
  setupUi( this );
  connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
  connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
  connect( buttonBox->button( QDialogButtonBox::Apply ), SIGNAL( clicked() ), this, SLOT( apply() ) );
  connect( this, SIGNAL( accepted() ), this, SLOT( apply() ) );
  connect( projectionSelector, SIGNAL( sridSelected( QString ) ), this, SLOT( setMapUnitsToCurrentProjection() ) );

  ///////////////////////////////////////////////////////////
  // Properties stored in map canvas's QgsMapRenderer
  // these ones are propagated to QgsProject by a signal

  QgsMapRenderer* myRenderer = mMapCanvas->mapRenderer();
  QGis::UnitType myUnit = myRenderer->mapUnits();
  setMapUnits( myUnit );

  // we need to initialize it, since the on_cbxProjectionEnabled_stateChanged()
  // callback triggered by setChecked() might use it.
  mProjectSrsId = myRenderer->destinationCrs().srsid();

  //see if the user wants on the fly projection enabled
  bool myProjectionEnabled = myRenderer->hasCrsTransformEnabled();
  cbxProjectionEnabled->setChecked( myProjectionEnabled );

  QgsDebugMsg( "Read project CRSID: " + QString::number( mProjectSrsId ) );
  projectionSelector->setSelectedCrsId( mProjectSrsId );
  projectionSelector->setEnabled( myProjectionEnabled );

  ///////////////////////////////////////////////////////////
  // Properties stored in QgsProject

  title( QgsProject::instance()->title() );

  // get the manner in which the number of decimal places in the mouse
  // position display is set (manual or automatic)
  bool automaticPrecision = QgsProject::instance()->readBoolEntry( "PositionPrecision", "/Automatic" );
  if ( automaticPrecision )
  {
    radAutomatic->setChecked( true );
    spinBoxDP->setDisabled( true );
    labelDP->setDisabled( true );
  }
  else
  {
    radManual->setChecked( true );
  }

  cbxAbsolutePath->setCurrentIndex( QgsProject::instance()->readBoolEntry( "Paths", "/Absolute", true ) ? 0 : 1 );

  int dp = QgsProject::instance()->readNumEntry( "PositionPrecision", "/DecimalPlaces" );
  spinBoxDP->setValue( dp );

  QString format = QgsProject::instance()->readEntry( "PositionPrecision", "/DegreeFormat", "D" );
  if ( format == "DM" )
    radDM->setChecked( true );
  else if ( format == "DMS" )
    radDMS->setChecked( true );
  else
    radD->setChecked( true );

  //get the color selections and set the button color accordingly
  int myRedInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorRedPart", 255 );
  int myGreenInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorGreenPart", 255 );
  int myBlueInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorBluePart", 0 );
  int myAlphaInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorAlphaPart", 255 );
  QColor myColor = QColor( myRedInt, myGreenInt, myBlueInt, myAlphaInt );
  pbnSelectionColor->setColor( myColor );

  //get the color for map canvas background and set button color accordingly (default white)
  myRedInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorRedPart", 255 );
  myGreenInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorGreenPart", 255 );
  myBlueInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorBluePart", 255 );
  myColor = QColor( myRedInt, myGreenInt, myBlueInt );
  pbnCanvasColor->setColor( myColor );

  //get project scales
  QStringList myScales = QgsProject::instance()->readListEntry( "Scales", "/ScalesList" );
  if ( !myScales.isEmpty() )
  {
    QStringList::const_iterator scaleIt = myScales.constBegin();
    for ( ; scaleIt != myScales.constEnd(); ++scaleIt )
    {
      QListWidgetItem* newItem = new QListWidgetItem( lstScales );
      newItem->setText( *scaleIt );
      newItem->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable );
      lstScales->addItem( newItem );
    }
  }

  grpProjectScales->setChecked( QgsProject::instance()->readBoolEntry( "Scales", "/useProjectScales" ) );

  QgsMapLayer* currentLayer = 0;

  QStringList noIdentifyLayerIdList = QgsProject::instance()->readListEntry( "Identify", "/disabledLayers" );

  const QMap<QString, QgsMapLayer*> &mapLayers = QgsMapLayerRegistry::instance()->mapLayers();

  if ( mMapCanvas->currentLayer() )
  {
    mLayerSrsId = mMapCanvas->currentLayer()->crs().srsid();
  }
  else if ( mapLayers.size() > 0 )
  {
    mLayerSrsId = mapLayers.begin().value()->crs().srsid();
  }
  else
  {
    mLayerSrsId = mProjectSrsId;
  }

  twIdentifyLayers->setColumnCount( 3 );
  twIdentifyLayers->horizontalHeader()->setVisible( true );
  twIdentifyLayers->setHorizontalHeaderItem( 0, new QTableWidgetItem( tr( "Layer" ) ) );
  twIdentifyLayers->setHorizontalHeaderItem( 1, new QTableWidgetItem( tr( "Type" ) ) );
  twIdentifyLayers->setHorizontalHeaderItem( 2, new QTableWidgetItem( tr( "Identifiable" ) ) );
  twIdentifyLayers->setRowCount( mapLayers.size() );
  twIdentifyLayers->verticalHeader()->setResizeMode( QHeaderView::ResizeToContents );

  int i = 0;
  for ( QMap<QString, QgsMapLayer*>::const_iterator it = mapLayers.constBegin(); it != mapLayers.constEnd(); it++, i++ )
  {
    currentLayer = it.value();

    QTableWidgetItem *twi = new QTableWidgetItem( QString::number( i ) );
    twIdentifyLayers->setVerticalHeaderItem( i, twi );

    twi = new QTableWidgetItem( currentLayer->name() );
    twi->setData( Qt::UserRole, it.key() );
    twi->setFlags( twi->flags() & ~Qt::ItemIsEditable );
    twIdentifyLayers->setItem( i, 0, twi );

    QString type;
    if ( currentLayer->type() == QgsMapLayer::VectorLayer )
    {
      type = tr( "Vector" );
    }
    else if ( currentLayer->type() == QgsMapLayer::RasterLayer )
    {
      QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( currentLayer );

      if ( rl && rl->providerType() == "wms" )
      {
        type = tr( "WMS" );
      }
      else
      {
        type = tr( "Raster" );
      }
    }

    twi = new QTableWidgetItem( type );
    twi->setFlags( twi->flags() & ~Qt::ItemIsEditable );
    twIdentifyLayers->setItem( i, 1, twi );

    QCheckBox *cb = new QCheckBox();
    cb->setChecked( !noIdentifyLayerIdList.contains( currentLayer->id() ) );
    twIdentifyLayers->setCellWidget( i, 2, cb );
  }

  grpOWSServiceCapabilities->setChecked( QgsProject::instance()->readBoolEntry( "WMSServiceCapabilities", "/", false ) );
  mWMSTitle->setText( QgsProject::instance()->readEntry( "WMSServiceTitle", "/" ) );
  mWMSContactOrganization->setText( QgsProject::instance()->readEntry( "WMSContactOrganization", "/", "" ) );
  mWMSContactPerson->setText( QgsProject::instance()->readEntry( "WMSContactPerson", "/", "" ) );
  mWMSContactMail->setText( QgsProject::instance()->readEntry( "WMSContactMail", "/", "" ) );
  mWMSContactPhone->setText( QgsProject::instance()->readEntry( "WMSContactPhone", "/", "" ) );
  mWMSAbstract->setPlainText( QgsProject::instance()->readEntry( "WMSServiceAbstract", "/", "" ) );
  mWMSOnlineResourceLineEdit->setText( QgsProject::instance()->readEntry( "WMSOnlineResource", "/", "" ) );
  mWMSUrlLineEdit->setText( QgsProject::instance()->readEntry( "WMSUrl", "/", "" ) );

  bool ok;
  QStringList values;

  mWMSExtMinX->setValidator( new QDoubleValidator( mWMSExtMinX ) );
  mWMSExtMinY->setValidator( new QDoubleValidator( mWMSExtMinY ) );
  mWMSExtMaxX->setValidator( new QDoubleValidator( mWMSExtMaxX ) );
  mWMSExtMaxY->setValidator( new QDoubleValidator( mWMSExtMaxY ) );

  values = QgsProject::instance()->readListEntry( "WMSExtent", "/", &ok );
  grpWMSExt->setChecked( ok && values.size() == 4 );
  if ( grpWMSExt->isChecked() )
  {
    mWMSExtMinX->setText( values[0] );
    mWMSExtMinY->setText( values[1] );
    mWMSExtMaxX->setText( values[2] );
    mWMSExtMaxY->setText( values[3] );
  }

  values = QgsProject::instance()->readListEntry( "WMSCrsList", "/", &ok );
  grpWMSList->setChecked( ok && values.size() > 0 );
  if ( grpWMSList->isChecked() )
  {
    mWMSList->addItems( values );
  }
  else
  {
    values = QgsProject::instance()->readListEntry( "WMSEpsgList", "/", &ok );
    grpWMSList->setChecked( ok && values.size() > 0 );
    if ( grpWMSList->isChecked() )
    {
      QStringList list;
      foreach ( QString value, values )
      {
        list << QString( "EPSG:%1" ).arg( value );
      }

      mWMSList->addItems( list );
    }
  QDomDocument createDescribeCoverageDocument( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
      const QgsServerRequest &request )
  {
    Q_UNUSED( version );

    QDomDocument doc;

    QgsServerRequest::Parameters parameters = request.parameters();

#ifdef HAVE_SERVER_PYTHON_PLUGINS
    QgsAccessControl *accessControl = serverIface->accessControls();
#endif

    //wcs:WCS_Capabilities element
    QDomElement coveDescElement = doc.createElement( QStringLiteral( "CoverageDescription" )/*wcs:CoverageDescription*/ );
    coveDescElement.setAttribute( QStringLiteral( "xmlns" ), WCS_NAMESPACE );
    coveDescElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
    coveDescElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/describeCoverage.xsd" );
    coveDescElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
    coveDescElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
    coveDescElement.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0.0" ) );
    coveDescElement.setAttribute( QStringLiteral( "updateSequence" ), QStringLiteral( "0" ) );
    doc.appendChild( coveDescElement );

    //defining coverage name
    QString coveNames;
    //read COVERAGE
    QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "COVERAGE" ) );
    if ( cove_name_it != parameters.constEnd() )
    {
      coveNames = cove_name_it.value();
    }
    if ( coveNames.isEmpty() )
    {
      QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "IDENTIFIER" ) );
      if ( cove_name_it != parameters.constEnd() )
      {
        coveNames = cove_name_it.value();
      }
    }

    QStringList coveNameList;
    if ( !coveNames.isEmpty() )
    {
      coveNameList = coveNames.split( ',' );
      for ( int i = 0; i < coveNameList.size(); ++i )
      {
        coveNameList.replace( i, coveNameList.at( i ).trimmed() );
      }
    }

    QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project );
    for ( int i = 0; i < wcsLayersId.size(); ++i )
    {
      QgsMapLayer *layer = project->mapLayer( wcsLayersId.at( i ) );
      if ( !layer )
      {
        continue;
      }
      if ( layer->type() != QgsMapLayer::LayerType::RasterLayer )
      {
        continue;
      }
#ifdef HAVE_SERVER_PYTHON_PLUGINS
      if ( !accessControl->layerReadPermission( layer ) )
      {
        continue;
      }
#endif
      QString name = layer->name();
      if ( !layer->shortName().isEmpty() )
        name = layer->shortName();
      name = name.replace( ' ', '_' );

      if ( coveNameList.size() == 0 || coveNameList.contains( name ) )
      {
        QgsRasterLayer *rLayer = qobject_cast<QgsRasterLayer *>( layer );
        coveDescElement.appendChild( getCoverageOffering( doc, const_cast<QgsRasterLayer *>( rLayer ), project ) );
      }
    }
    return doc;
  }
Beispiel #27
0
void QgsWfsProjectParser::featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const
{
  const QList<QDomElement>& projectLayerElements = mProjectParser->projectLayerElements();
  if ( projectLayerElements.size() < 1 )
  {
    return;
  }

  QStringList wfsLayersId = mProjectParser->wfsLayers();
  QSet<QString> wfstUpdateLayersId = wfstUpdateLayers();
  QSet<QString> wfstInsertLayersId = wfstInsertLayers();
  QSet<QString> wfstDeleteLayersId = wfstDeleteLayers();

  QMap<QString, QgsMapLayer *> layerMap;

  Q_FOREACH ( const QDomElement &elem, projectLayerElements )
  {
    QString type = elem.attribute( "type" );
    if ( type == "vector" )
    {
      QString layerId = mProjectParser->layerId( elem );
      if ( !wfsLayersId.contains( layerId ) )
      {
        continue;
      }
      QgsMapLayer *layer = mProjectParser->createLayerFromElement( elem );
      if ( !layer )
      {
        continue;
      }
#ifdef HAVE_SERVER_PYTHON_PLUGINS
      if ( !mAccessControl->layerReadPermission( layer ) )
      {
        continue;
      }
#endif
      QgsDebugMsg( QString( "add layer %1 to map" ).arg( layer->id() ) );
      layerMap.insert( layer->id(), layer );

      QDomElement layerElem = doc.createElement( "FeatureType" );
      QDomElement nameElem = doc.createElement( "Name" );
      //We use the layer name even though it might not be unique.
      //Because the id sometimes contains user/pw information and the name is more descriptive
      QString typeName = layer->name();
      if ( !layer->shortName().isEmpty() )
        typeName = layer->shortName();
      typeName = typeName.replace( " ", "_" );
      QDomText nameText = doc.createTextNode( typeName );
      nameElem.appendChild( nameText );
      layerElem.appendChild( nameElem );

      QDomElement titleElem = doc.createElement( "Title" );
      QString titleName = layer->title();
      if ( titleName.isEmpty() )
      {
        titleName = layer->name();
      }
      QDomText titleText = doc.createTextNode( titleName );
      titleElem.appendChild( titleText );
      layerElem.appendChild( titleElem );

      QDomElement abstractElem = doc.createElement( "Abstract" );
      QString abstractName = layer->abstract();
      if ( abstractName.isEmpty() )
      {
        abstractName = "";
      }
      QDomText abstractText = doc.createTextNode( abstractName );
      abstractElem.appendChild( abstractText );
      layerElem.appendChild( abstractElem );

      //keyword list
      if ( !layer->keywordList().isEmpty() )
      {
        QDomElement keywordsElem = doc.createElement( "Keywords" );
        QDomText keywordsText = doc.createTextNode( layer->keywordList() );
        keywordsElem.appendChild( keywordsText );
        layerElem.appendChild( keywordsElem );
      }

      //appendExGeographicBoundingBox( layerElem, doc, layer->extent(), layer->crs() );

      QDomElement srsElem = doc.createElement( "SRS" );
      QDomText srsText = doc.createTextNode( layer->crs().authid() );
      srsElem.appendChild( srsText );
      layerElem.appendChild( srsElem );

      //wfs:Operations element
      QDomElement operationsElement = doc.createElement( "Operations"/*wfs:Operations*/ );
      //wfs:Query element
      QDomElement queryElement = doc.createElement( "Query"/*wfs:Query*/ );
      operationsElement.appendChild( queryElement );

      QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer*>( layer );
      QgsVectorDataProvider* provider = vlayer->dataProvider();
      if (( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) && wfstInsertLayersId.contains( layer->id() ) )
      {
        //wfs:Insert element
        QDomElement insertElement = doc.createElement( "Insert"/*wfs:Insert*/ );
        operationsElement.appendChild( insertElement );
      }
      if (( provider->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) &&
          ( provider->capabilities() & QgsVectorDataProvider::ChangeGeometries ) &&
          wfstUpdateLayersId.contains( layer->id() ) )
      {
        //wfs:Update element
        QDomElement updateElement = doc.createElement( "Update"/*wfs:Update*/ );
        operationsElement.appendChild( updateElement );
      }
      if (( provider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) && wfstDeleteLayersId.contains( layer->id() ) )
      {
        //wfs:Delete element
        QDomElement deleteElement = doc.createElement( "Delete"/*wfs:Delete*/ );
        operationsElement.appendChild( deleteElement );
      }

      layerElem.appendChild( operationsElement );

      QgsRectangle layerExtent = layer->extent();
      QDomElement bBoxElement = doc.createElement( "LatLongBoundingBox" );
      bBoxElement.setAttribute( "minx", QString::number( layerExtent.xMinimum() ) );
      bBoxElement.setAttribute( "miny", QString::number( layerExtent.yMinimum() ) );
      bBoxElement.setAttribute( "maxx", QString::number( layerExtent.xMaximum() ) );
      bBoxElement.setAttribute( "maxy", QString::number( layerExtent.yMaximum() ) );
      layerElem.appendChild( bBoxElement );

      // layer metadata URL
      QString metadataUrl = layer->metadataUrl();
      if ( !metadataUrl.isEmpty() )
      {
        QDomElement metaUrlElem = doc.createElement( "MetadataURL" );
        QString metadataUrlType = layer->metadataUrlType();
        metaUrlElem.setAttribute( "type", metadataUrlType );
        QString metadataUrlFormat = layer->metadataUrlFormat();
        if ( metadataUrlFormat == "text/xml" )
        {
          metaUrlElem.setAttribute( "format", "XML" );
        }
        else
        {
          metaUrlElem.setAttribute( "format", "TXT" );
        }
        QDomText metaUrlText = doc.createTextNode( metadataUrl );
        metaUrlElem.appendChild( metaUrlText );
        layerElem.appendChild( metaUrlElem );
      }

      parentElement.appendChild( layerElem );
    }
  }
void QgsMapToolIdentify::canvasReleaseEvent( QMouseEvent *e )
{
  if ( !mCanvas || mCanvas->isDrawing() )
  {
    return;
  }

  results()->clear();

  QSettings settings;
  int identifyMode = settings.value( "/Map/identifyMode", 0 ).toInt();

  bool res = false;

  if ( identifyMode == 0 )
  {
    QgsMapLayer *layer = mCanvas->currentLayer();

    if ( !layer )
    {
      QMessageBox::warning( mCanvas,
                            tr( "No active layer" ),
                            tr( "To identify features, you must choose an active layer by clicking on its name in the legend" ) );
      return;
    }

    QApplication::setOverrideCursor( Qt::WaitCursor );

    res = identifyLayer( layer, e->x(), e->y() );

    QApplication::restoreOverrideCursor();
  }
  else
  {
    connect( this, SIGNAL( identifyProgress( int, int ) ), QgisApp::instance(), SLOT( showProgress( int, int ) ) );
    connect( this, SIGNAL( identifyMessage( QString ) ), QgisApp::instance(), SLOT( showStatusMessage( QString ) ) );

    QApplication::setOverrideCursor( Qt::WaitCursor );

    QStringList noIdentifyLayerIdList = QgsProject::instance()->readListEntry( "Identify", "/disabledLayers" );

    for ( int i = 0; i < mCanvas->layerCount(); i++ )
    {
      QgsMapLayer *layer = mCanvas->layer( i );

      emit identifyProgress( i, mCanvas->layerCount() );
      emit identifyMessage( tr( "Identifying on %1..." ).arg( layer->name() ) );

      if ( noIdentifyLayerIdList.contains( layer->id() ) )
        continue;

      if ( identifyLayer( layer, e->x(), e->y() ) )
      {
        res = true;
        if ( identifyMode == 1 )
          break;
      }
    }

    emit identifyProgress( mCanvas->layerCount(), mCanvas->layerCount() );
    emit identifyMessage( tr( "Identifying done." ) );

    disconnect( this, SIGNAL( identifyProgress( int, int ) ), QgisApp::instance(), SLOT( showProgress( int, int ) ) );
    disconnect( this, SIGNAL( identifyMessage( QString ) ), QgisApp::instance(), SLOT( showStatusMessage( QString ) ) );

    QApplication::restoreOverrideCursor();
  }

  if ( res )
  {
    results()->show();
  }
  else
  {
    QSettings mySettings;
    bool myDockFlag = mySettings.value( "/qgis/dockIdentifyResults", false ).toBool();
    if ( !myDockFlag )
    {
      results()->hide();
    }
    else
    {
      results()->clear();
    }
    QgisApp::instance()->statusBar()->showMessage( tr( "No features at this position found." ) );
  }
}
Beispiel #29
0
QList<QgsMapToolIdentify::IdentifyResult> QgsMapToolIdentify::identify( int x, int y, IdentifyMode mode, const QList<QgsMapLayer*>& layerList, const LayerType& layerType )
{
  QList<IdentifyResult> results;

  mLastPoint = mCanvas->getCoordinateTransform()->toMapCoordinates( x, y );
  mLastExtent = mCanvas->extent();
  mLastMapUnitsPerPixel = mCanvas->mapUnitsPerPixel();

  if ( mode == DefaultQgsSetting )
  {
    QSettings settings;
    mode = static_cast<IdentifyMode>( settings.value( "/Map/identifyMode", 0 ).toInt() );
  }

  if ( mode == LayerSelection )
  {
    QList<IdentifyResult> results = identify( x, y, TopDownAll, layerList, layerType );
    QPoint globalPos = mCanvas->mapToGlobal( QPoint( x + 5, y + 5 ) );
    return mIdentifyMenu->exec( results, globalPos );
  }
  else if ( mode == ActiveLayer && layerList.isEmpty() )
  {
    QgsMapLayer *layer = mCanvas->currentLayer();

    if ( !layer )
    {
      emit identifyMessage( tr( "No active layer. To identify features, you must choose an active layer." ) );
      return results;
    }

    QApplication::setOverrideCursor( Qt::WaitCursor );

    identifyLayer( &results, layer, mLastPoint, mLastExtent, mLastMapUnitsPerPixel, layerType );
  }
  else
  {
    QApplication::setOverrideCursor( Qt::WaitCursor );

    QStringList noIdentifyLayerIdList = QgsProject::instance()->readListEntry( "Identify", "/disabledLayers" );

    int layerCount;
    if ( layerList.isEmpty() )
      layerCount = mCanvas->layerCount();
    else
      layerCount = layerList.count();


    for ( int i = 0; i < layerCount; i++ )
    {

      QgsMapLayer *layer;
      if ( layerList.isEmpty() )
        layer = mCanvas->layer( i );
      else
        layer = layerList.value( i );

      emit identifyProgress( i, mCanvas->layerCount() );
      emit identifyMessage( tr( "Identifying on %1..." ).arg( layer->name() ) );

      if ( noIdentifyLayerIdList.contains( layer->id() ) )
        continue;

      if ( identifyLayer( &results, layer,  mLastPoint, mLastExtent, mLastMapUnitsPerPixel, layerType ) )
      {
        if ( mode == TopDownStopAtFirst )
          break;
      }
    }

    emit identifyProgress( mCanvas->layerCount(), mCanvas->layerCount() );
    emit identifyMessage( tr( "Identifying done." ) );
  }

  QApplication::restoreOverrideCursor();

  return results;
}
Beispiel #30
0
void QgsProjectParser::addLayers( QDomDocument &doc,
                                  QDomElement &parentElem,
                                  const QDomElement &legendElem,
                                  const QMap<QString, QgsMapLayer *> &layerMap,
                                  const QStringList &nonIdentifiableLayers ) const
{
  QDomNodeList legendChildren = legendElem.childNodes();
  for ( int i = 0; i < legendChildren.size(); ++i )
  {
    QDomElement currentChildElem = legendChildren.at( i ).toElement();

    QDomElement layerElem = doc.createElement( "Layer" );

    if ( currentChildElem.tagName() == "legendgroup" )
    {
      layerElem.setAttribute( "queryable", "1" );
      QString name = currentChildElem.attribute( "name" );
      QDomElement nameElem = doc.createElement( "Name" );
      QDomText nameText = doc.createTextNode( name );
      nameElem.appendChild( nameText );
      layerElem.appendChild( nameElem );

      QDomElement titleElem = doc.createElement( "Title" );
      QDomText titleText = doc.createTextNode( name );
      titleElem.appendChild( titleText );
      layerElem.appendChild( titleElem );

      if ( currentChildElem.attribute( "embedded" ) == "1" )
      {
        //add layers from other project files and embed into this group
        QString project = convertToAbsolutePath( currentChildElem.attribute( "project" ) );
        QgsDebugMsg( QString( "Project path: %1" ).arg( project ) );
        QString embeddedGroupName = currentChildElem.attribute( "name" );
        QgsProjectParser* p = dynamic_cast<QgsProjectParser*>( QgsConfigCache::instance()->searchConfiguration( project ) );
        if ( p )
        {
          QStringList pIdDisabled = p->identifyDisabledLayers();

          QDomElement embeddedGroupElem;
          QList<QDomElement> pLegendElems = p->legendGroupElements();
          QList<QDomElement>::const_iterator pLegendIt = pLegendElems.constBegin();
          for ( ; pLegendIt != pLegendElems.constEnd(); ++pLegendIt )
          {
            if ( pLegendIt->attribute( "name" ) == embeddedGroupName )
            {
              embeddedGroupElem = *pLegendIt;
              break;
            }
          }

          QList<QDomElement> pLayerElems = p->projectLayerElements();
          QMap<QString, QgsMapLayer *> pLayerMap;
          QList<QDomElement>::const_iterator pLayerIt = pLayerElems.constBegin();
          for ( ; pLayerIt != pLayerElems.constEnd(); ++pLayerIt )
          {
            pLayerMap.insert( layerId( *pLayerIt ), p->createLayerFromElement( *pLayerIt ) );
          }

          p->addLayers( doc, layerElem, embeddedGroupElem, pLayerMap, pIdDisabled );
        }
      }
      else //normal (not embedded) legend group
      {
        addLayers( doc, layerElem, currentChildElem, layerMap, nonIdentifiableLayers );
      }

      // combine bounding boxes of children (groups/layers)
      combineExtentAndCrsOfGroupChildren( layerElem, doc );
    }
    else if ( currentChildElem.tagName() == "legendlayer" )
    {
      QString id = layerIdFromLegendLayer( currentChildElem );

      if ( !layerMap.contains( id ) )
      {
        QgsDebugMsg( QString( "layer %1 not found in map - layer cache to small?" ).arg( id ) );
        continue;
      }

      QgsMapLayer *currentLayer = layerMap[ id ];
      if ( !currentLayer )
      {
        QgsDebugMsg( QString( "layer %1 not found" ).arg( id ) );
        continue;
      }

      if ( nonIdentifiableLayers.contains( currentLayer->id() ) )
      {
        layerElem.setAttribute( "queryable", "0" );
      }
      else
      {
        layerElem.setAttribute( "queryable", "1" );
      }

      QDomElement nameElem = doc.createElement( "Name" );
      //We use the layer name even though it might not be unique.
      //Because the id sometimes contains user/pw information and the name is more descriptive
      QDomText nameText = doc.createTextNode( currentLayer->name() );
      nameElem.appendChild( nameText );
      layerElem.appendChild( nameElem );

      QDomElement titleElem = doc.createElement( "Title" );
      QDomText titleText = doc.createTextNode( currentLayer->name() );
      titleElem.appendChild( titleText );
      layerElem.appendChild( titleElem );

      //CRS
      QStringList crsList = createCRSListForLayer( currentLayer );
      appendCRSElementsToLayer( layerElem, doc, crsList );

      //Ex_GeographicBoundingBox
      appendLayerBoundingBoxes( layerElem, doc, currentLayer->extent(), currentLayer->crs() );

      //only one default style in project file mode
      QDomElement styleElem = doc.createElement( "Style" );
      QDomElement styleNameElem = doc.createElement( "Name" );
      QDomText styleNameText = doc.createTextNode( "default" );
      styleNameElem.appendChild( styleNameText );
      QDomElement styleTitleElem = doc.createElement( "Title" );
      QDomText styleTitleText = doc.createTextNode( "default" );
      styleTitleElem.appendChild( styleTitleText );
      styleElem.appendChild( styleNameElem );
      styleElem.appendChild( styleTitleElem );
      layerElem.appendChild( styleElem );
    }
    else
    {
      QgsDebugMsg( "unexpected child element" );
      continue;
    }

    parentElem.appendChild( layerElem );
  }
}