QgsComposition* QgsConfigParser::createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const
{
  QList<QgsComposerMap*> composerMaps;
  QList<QgsComposerLabel*> composerLabels;

  QgsComposition* c = initComposition( composerTemplate, mapRenderer, composerMaps, composerLabels );
  if ( !c )
  {
    return 0;
  }

  QMap< QString, QString >::const_iterator dpiIt = parameterMap.find( "DPI" );
  if ( dpiIt != parameterMap.constEnd() )
  {
    c->setPrintResolution( dpiIt.value().toInt() );
  }

  //replace composer map parameters
  QList<QgsComposerMap*>::iterator mapIt = composerMaps.begin();
  QgsComposerMap* currentMap = 0;
  for ( ; mapIt != composerMaps.end(); ++mapIt )
  {
    currentMap = *mapIt;
    if ( !currentMap )
    {
      continue;
    }

    QString mapId = "MAP" + QString::number( currentMap->id() );
    QMap< QString, QString >::const_iterator extentIt = parameterMap.find( mapId + ":EXTENT" );
    if ( extentIt == parameterMap.constEnd() ) //map extent is mandatory
    {
      //remove map from composition if not referenced by the request
      c->removeItem( *mapIt ); delete( *mapIt ); continue;
    }

    QStringList coordList = extentIt.value().split( "," );
    if ( coordList.size() < 4 )
    {
      c->removeItem( *mapIt ); delete( *mapIt ); continue; //need at least four coordinates
    }

    bool xMinOk, yMinOk, xMaxOk, yMaxOk;
    double xmin = coordList.at( 0 ).toDouble( &xMinOk );
    double ymin = coordList.at( 1 ).toDouble( &yMinOk );
    double xmax = coordList.at( 2 ).toDouble( &xMaxOk );
    double ymax = coordList.at( 3 ).toDouble( &yMaxOk );
    if ( !xMinOk || !yMinOk || !xMaxOk || !yMaxOk )
    {
      c->removeItem( *mapIt ); delete( *mapIt ); continue;
    }

    //Change x- and y- of extent for WMS 1.3.0 and geographic coordinate systems
    QMap<QString, QString>::const_iterator versionIt = parameterMap.find( "VERSION" );
    if ( versionIt != parameterMap.end() )
    {
      if ( mapRenderer && versionIt.value() == "1.3.0" && mapRenderer->destinationCrs().geographicFlag() )
      {
        //switch coordinates of extent
        double tmp;
        tmp = xmin;
        xmin = ymin; ymin = tmp;
        tmp = xmax;
        xmax = ymax; ymax = tmp;
      }
    }
    currentMap->setNewExtent( QgsRectangle( xmin, ymin, xmax, ymax ) );

    //scale
    QMap< QString, QString >::const_iterator scaleIt = parameterMap.find( mapId + ":SCALE" );
    if ( scaleIt != parameterMap.constEnd() )
    {
      bool scaleOk;
      double scale = scaleIt->toDouble( &scaleOk );
      if ( scaleOk )
      {
        currentMap->setNewScale( scale );
      }
    }

    //rotation
    QMap< QString, QString >::const_iterator rotationIt = parameterMap.find( mapId + ":ROTATION" );
    if ( rotationIt != parameterMap.constEnd() )
    {
      bool rotationOk;
      double rotation = rotationIt->toDouble( &rotationOk );
      if ( rotationOk )
      {
        currentMap->setMapRotation( rotation );
      }
    }

    //layers / styles
    QMap< QString, QString >::const_iterator layersIt = parameterMap.find( mapId + ":LAYERS" );
    QMap< QString, QString >::const_iterator stylesIt = parameterMap.find( mapId + ":STYLES" );
    if ( layersIt != parameterMap.constEnd() )
    {
      QStringList layerSet;
      QStringList wmsLayerList = layersIt->split( "," );
      QStringList wmsStyleList;

      if ( stylesIt != parameterMap.constEnd() )
      {
        wmsStyleList = stylesIt->split( "," );
      }
      for ( int i = 0; i < wmsLayerList.size(); ++i )
      {
        QString styleName;
        if ( wmsStyleList.size() > i )
        {
          styleName = wmsStyleList.at( i );
        }
        QList<QgsMapLayer*> layerList = mapLayerFromStyle( wmsLayerList.at( i ), styleName );
        QList<QgsMapLayer*>::const_iterator mapIdIt = layerList.constBegin();
        for ( ; mapIdIt != layerList.constEnd(); ++mapIdIt )
        {
          if ( *mapIdIt )
          {
            layerSet.push_back(( *mapIdIt )->id() );
          }
        }
      }

      currentMap->setLayerSet( layerSet );
      currentMap->setKeepLayerSet( true );
    }

    //grid space x / y
    QMap< QString, QString >::const_iterator gridSpaceXIt = parameterMap.find( mapId + ":GRID_INTERVAL_X" );
    if ( gridSpaceXIt != parameterMap.constEnd() )
    {
      bool intervalXOk;
      double intervalX = gridSpaceXIt->toDouble( &intervalXOk );
      if ( intervalXOk )
      {
        currentMap->setGridIntervalX( intervalX );
      }
    }
    else
    {
      currentMap->setGridIntervalX( 0 );
    }

    QMap< QString, QString >::const_iterator gridSpaceYIt = parameterMap.find( mapId + ":GRID_INTERVAL_Y" );
    if ( gridSpaceYIt != parameterMap.constEnd() )
    {
      bool intervalYOk;
      double intervalY = gridSpaceYIt->toDouble( &intervalYOk );
      if ( intervalYOk )
      {
        currentMap->setGridIntervalY( intervalY );
      }
    }
    else
    {
      currentMap->setGridIntervalY( 0 );
    }
  }

  //replace label text
  QList<QgsComposerLabel*>::const_iterator labelIt = composerLabels.constBegin();
  QgsComposerLabel* currentLabel = 0;

  for ( ; labelIt != composerLabels.constEnd(); ++labelIt )
  {
    currentLabel = *labelIt;
    QMap< QString, QString >::const_iterator titleIt = parameterMap.find( currentLabel->id().toUpper() );
    if ( titleIt == parameterMap.constEnd() )
    {
      //remove exported labels not referenced in the request
      if ( !currentLabel->id().isEmpty() )
      {
        c->removeItem( currentLabel );
        delete( currentLabel );
      }
      continue;
    }

    if ( !titleIt.key().isEmpty() ) //no label text replacement with empty key
    {
      currentLabel->setText( titleIt.value() );
      currentLabel->adjustSizeToText();
    }
  }

  return c;
}
Beispiel #2
0
QgsComposition* QgsWMSConfigParser::createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const
{
  QList<QgsComposerMap*> composerMaps;
  QList<QgsComposerLegend*> composerLegends;
  QList<QgsComposerLabel*> composerLabels;
  QList<const QgsComposerHtml*> composerHtmls;

  QgsComposition* c = initComposition( composerTemplate, mapRenderer, composerMaps, composerLegends, composerLabels, composerHtmls );
  if ( !c )
  {
    return 0;
  }

  QString dpi = parameterMap.value( "DPI" );
  if ( !dpi.isEmpty() )
  {
    c->setPrintResolution( dpi.toInt() );
  }

  //replace composer map parameters
  Q_FOREACH ( QgsComposerMap* currentMap, composerMaps )
  {
    if ( !currentMap )
    {
      continue;
    }

    QString mapId = "MAP" + QString::number( currentMap->id() );

    QString extent = parameterMap.value( mapId + ":EXTENT" );
    if ( extent.isEmpty() ) //map extent is mandatory
    {
      //remove map from composition if not referenced by the request
      c->removeItem( currentMap ); delete currentMap; continue;
    }

    QStringList coordList = extent.split( "," );
    if ( coordList.size() < 4 )
    {
      c->removeItem( currentMap ); delete currentMap; continue; //need at least four coordinates
    }

    bool xMinOk, yMinOk, xMaxOk, yMaxOk;
    double xmin = coordList.at( 0 ).toDouble( &xMinOk );
    double ymin = coordList.at( 1 ).toDouble( &yMinOk );
    double xmax = coordList.at( 2 ).toDouble( &xMaxOk );
    double ymax = coordList.at( 3 ).toDouble( &yMaxOk );
    if ( !xMinOk || !yMinOk || !xMaxOk || !yMaxOk )
    {
      c->removeItem( currentMap ); delete currentMap; continue;
    }

    QgsRectangle r( xmin, ymin, xmax, ymax );

    //Change x- and y- of extent for WMS 1.3.0 if axis inverted
    QString version = parameterMap.value( "VERSION" );
    if ( version == "1.3.0" && mapRenderer && mapRenderer->destinationCrs().axisInverted() )
    {
      r.invert();
    }
    currentMap->setNewExtent( r );

    //scale
    QString scaleString = parameterMap.value( mapId + ":SCALE" );
    if ( !scaleString.isEmpty() )
    {
      bool scaleOk;
      double scale = scaleString.toDouble( &scaleOk );
      if ( scaleOk )
      {
        currentMap->setNewScale( scale );
      }
    }

    //rotation
    QString rotationString = parameterMap.value( mapId + ":ROTATION" );
    if ( !rotationString.isEmpty() )
    {
      bool rotationOk;
      double rotation = rotationString.toDouble( &rotationOk );
      if ( rotationOk )
      {
        currentMap->setMapRotation( rotation );
      }
    }

    //layers / styles
    QString layers = parameterMap.value( mapId + ":LAYERS" );
    QString styles = parameterMap.value( mapId + ":STYLES" );
    if ( !layers.isEmpty() )
    {
      QStringList layerSet;
      QStringList wmsLayerList = layers.split( ",", QString::SkipEmptyParts );
      QStringList wmsStyleList;

      if ( !styles.isEmpty() )
      {
        wmsStyleList = styles.split( ",", QString::SkipEmptyParts );
      }

      for ( int i = 0; i < wmsLayerList.size(); ++i )
      {
        QString wmsLayer = wmsLayerList.at( i );
        QString styleName;
        if ( wmsStyleList.size() > i )
        {
          styleName = wmsStyleList.at( i );
        }
        
        bool allowCaching = true;
        if ( wmsLayerList.count( wmsLayer ) > 1 )
        {
          allowCaching = false;
        }

        QList<QgsMapLayer*> layerList = mapLayerFromStyle( wmsLayer, styleName, allowCaching );
        int listIndex;
        for ( listIndex = layerList.size() - 1; listIndex >= 0; listIndex-- )
        {
          QgsMapLayer* layer = layerList.at( listIndex );
          if ( layer )
          {
            layerSet.push_back( layer->id() );
          }
        }
      }

      currentMap->setLayerSet( layerSet );
      currentMap->setKeepLayerSet( true );
    }

    //grid space x / y
    currentMap->grid()->setIntervalX( parameterMap.value( mapId + ":GRID_INTERVAL_X" ).toDouble() );
    currentMap->grid()->setIntervalY( parameterMap.value( mapId + ":GRID_INTERVAL_Y" ).toDouble() );
  }
  //update legend
  // if it has an auto-update model
  Q_FOREACH ( QgsComposerLegend* currentLegend, composerLegends )
  {
    if ( !currentLegend )
    {
      continue;
    }

    if ( currentLegend->autoUpdateModel() || currentLegend->legendFilterByMapEnabled() )
    {
      // the legend has an auto-update model or
      // has to be filter by map
      // we will update it with map's layers
      const QgsComposerMap* map = currentLegend->composerMap();
      if ( !map )
      {
        continue;
      }

      // get model and layer tree root of the legend
      QgsLegendModelV2* model = currentLegend->modelV2();
      QgsLayerTreeGroup* root = model->rootGroup();


      // get layerIds find in the layer tree root
      QStringList layerIds = root->findLayerIds();
      // get map layerIds
      QStringList layerSet = map->layerSet();

      // get map scale
      double scale = map->scale();

      // Q_FOREACH layer find in the layer tree
      // remove it if the layer id is not in map layerIds
      Q_FOREACH ( const QString& layerId, layerIds )
      {
        QgsLayerTreeLayer* nodeLayer = root->findLayer( layerId );
        if ( !nodeLayer )
        {
          continue;
        }
        if ( !layerSet.contains( layerId ) )
        {
          qobject_cast<QgsLayerTreeGroup*>( nodeLayer->parent() )->removeChildNode( nodeLayer );
        }
        else
        {
          QgsMapLayer* layer = nodeLayer->layer();
          if ( layer->hasScaleBasedVisibility() )
          {
            if ( layer->minimumScale() > scale )
              qobject_cast<QgsLayerTreeGroup*>( nodeLayer->parent() )->removeChildNode( nodeLayer );
            else if ( layer->maximumScale() < scale )
              qobject_cast<QgsLayerTreeGroup*>( nodeLayer->parent() )->removeChildNode( nodeLayer );
          }
        }
      }
      root->removeChildrenGroupWithoutLayers();
    }
  }