예제 #1
0
TEST_F(GlyphColorMapping_test, GlyphMagnitudeColorMappingCreated)
{
    auto poly = genPolyData();
    auto rendered = poly->createRendered();
    auto rendered3D = dynamic_cast<RenderedData3D *>(rendered.get());
    assert(rendered3D);

    auto glyphMappings = rendered3D->glyphMapping().vectors();
    auto vecGlyphMappingIt = std::find_if(glyphMappings.begin(), glyphMappings.end(),
        [] (GlyphMappingData * glyphMappingData)
    {
        assert(glyphMappingData);
        return glyphMappingData->name() == GlyphColorMapping_test::vectorName();
    });
    ASSERT_NE(glyphMappings.end(), vecGlyphMappingIt);

    auto vecGlyphMapping = *vecGlyphMappingIt;
    vecGlyphMapping->setVisible(true);

    auto & colorMapping = rendered3D->colorMapping();

    ASSERT_TRUE(colorMapping.scalarsNames().contains(glyphMagnitudeColorMappingName()));
    colorMapping.setCurrentScalarsByName(glyphMagnitudeColorMappingName(), true);

    auto glyphColorMapping = dynamic_cast<GlyphMagnitudeColorMapping *>(&colorMapping.currentScalars());
    ASSERT_TRUE(glyphColorMapping);
}
예제 #2
0
void RendererImplementationBase3D::onAddContent(AbstractVisualizedData * content, unsigned int subViewIndex)
{
    assert(dynamic_cast<RenderedData *>(content));
    auto renderedData = static_cast<RenderedData *>(content);

    renderedData->colorMapping().colorBarRepresentation().setContext(
        m_renderWindow->GetInteractor(),
        renderer(subViewIndex));

    auto props = vtkSmartPointer<vtkPropCollection>::New();

    auto && renderer = this->renderer(subViewIndex);
    auto && dataProps = m_viewportSetups[subViewIndex].dataProps;

    vtkCollectionSimpleIterator it;
    renderedData->viewProps()->InitTraversal(it);
    while (auto prop = renderedData->viewProps()->GetNextProp(it))
    {
        props->AddItem(prop);
        renderer->AddViewProp(prop);
    }

    assert(!dataProps.contains(renderedData));
    dataProps.insert(renderedData, props);

    addConnectionForContent(content,
        connect(renderedData, &RenderedData::viewPropCollectionChanged,
        [this, renderedData, subViewIndex] () { fetchViewProps(renderedData, subViewIndex); }));

    addConnectionForContent(content,
        connect(renderedData, &RenderedData::visibilityChanged,
        [this, renderedData, subViewIndex] (bool) { dataVisibilityChanged(renderedData, subViewIndex); }));

    dataVisibilityChanged(renderedData, subViewIndex);
}
예제 #3
0
void QgsSingleBandGrayRenderer::toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap &props ) const
{
  QgsStringMap newProps = props;

  // create base structure
  QgsRasterRenderer::toSld( doc, element, props );

  // look for RasterSymbolizer tag
  QDomNodeList elements = element.elementsByTagName( QStringLiteral( "sld:RasterSymbolizer" ) );
  if ( elements.size() == 0 )
    return;

  // there SHOULD be only one
  QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();

  // add Channel Selection tags
  // Need to insert channelSelection in the correct sequence as in SLD standard e.g.
  // after opacity or geometry or as first element after sld:RasterSymbolizer
  QDomElement channelSelectionElem = doc.createElement( QStringLiteral( "sld:ChannelSelection" ) );
  elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral( "sld:Opacity" ) );
  if ( elements.size() != 0 )
  {
    rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
  }
  else
  {
    elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral( "sld:Geometry" ) );
    if ( elements.size() != 0 )
    {
      rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
    }
    else
    {
      rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
    }
  }

  // for gray band
  QDomElement channelElem = doc.createElement( QStringLiteral( "sld:GrayChannel" ) );
  channelSelectionElem.appendChild( channelElem );

  // set band
  QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral( "sld:SourceChannelName" ) );
  sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( grayBand() ) ) );
  channelElem.appendChild( sourceChannelNameElem );

  // set ContrastEnhancement
  if ( contrastEnhancement() )
  {
    QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral( "sld:ContrastEnhancement" ) );
    contrastEnhancement()->toSld( doc, contrastEnhancementElem );

    // do changes to minValue/maxValues depending on stretching algorithm. This is necessary because
    // geoserver do a first stretch on min/max, then apply colo map rules. In some combination is necessary
    // to use real min/max values and in othere the actual edited min/max values
    switch ( contrastEnhancement()->contrastEnhancementAlgorithm() )
    {
      case QgsContrastEnhancement::StretchAndClipToMinimumMaximum:
      case QgsContrastEnhancement::ClipToMinimumMaximum:
      {
        // with this renderer export have to be check against real min/max values of the raster
        QgsRasterBandStats myRasterBandStats = mInput->bandStatistics( grayBand(), QgsRasterBandStats::Min | QgsRasterBandStats::Max );

        // if minimum range differ from the real minimum => set is in exported SLD vendor option
        if ( !qgsDoubleNear( contrastEnhancement()->minimumValue(), myRasterBandStats.minimumValue ) )
        {
          // look for VendorOption tag to look for that with minValue attribute
          QDomNodeList elements = contrastEnhancementElem.elementsByTagName( QStringLiteral( "sld:VendorOption" ) );
          for ( int i = 0; i < elements.size(); ++i )
          {
            QDomElement vendorOption = elements.at( i ).toElement();
            if ( vendorOption.attribute( QStringLiteral( "name" ) ) != QStringLiteral( "minValue" ) )
              continue;

            // remove old value and add the new one
            vendorOption.removeChild( vendorOption.firstChild() );
            vendorOption.appendChild( doc.createTextNode( QString::number( myRasterBandStats.minimumValue ) ) );
          }
        }
        break;
      }
      case QgsContrastEnhancement::UserDefinedEnhancement:
        break;
      case QgsContrastEnhancement::NoEnhancement:
        break;
      case QgsContrastEnhancement::StretchToMinimumMaximum:
        break;
    }

    channelElem.appendChild( contrastEnhancementElem );
  }

  // for each color set a ColorMapEntry tag nested into "sld:ColorMap" tag
  // e.g. <ColorMapEntry color="#EEBE2F" quantity="-300" label="label" opacity="0"/>
  QList< QPair< QString, QColor > > classes;
  legendSymbologyItems( classes );

  // add ColorMap tag
  QDomElement colorMapElem = doc.createElement( QStringLiteral( "sld:ColorMap" ) );
  rasterSymbolizerElem.appendChild( colorMapElem );

  // TODO: add clip intervals basing on real min/max without trigger
  // min/max calculation again that can takes a lot for remote or big images
  //
  // contrast enhancement against a color map can be SLD simulated playing with ColorMapEntryies
  // each ContrastEnhancementAlgorithm need a specific management.
  // set type of ColorMap ramp [ramp, intervals, values]
  // basing on interpolation algorithm of the raster shader
  QList< QPair< QString, QColor > > colorMapping( classes );
  switch ( contrastEnhancement()->contrastEnhancementAlgorithm() )
  {
    case ( QgsContrastEnhancement::StretchAndClipToMinimumMaximum ):
    case ( QgsContrastEnhancement::ClipToMinimumMaximum ):
    {
      QString lowValue = classes[0].first;
      QColor lowColor = classes[0].second;
      lowColor.setAlpha( 0 );
      QString highValue = classes[1].first;
      QColor highColor = classes[1].second;
      highColor.setAlpha( 0 );

      colorMapping.prepend( QPair< QString, QColor >( lowValue, lowColor ) );
      colorMapping.append( QPair< QString, QColor >( highValue, highColor ) );
      break;
    }
    case ( QgsContrastEnhancement::StretchToMinimumMaximum ):
    {
      colorMapping[0].first = QStringLiteral( "0" );
      colorMapping[1].first = QStringLiteral( "255" );
      break;
    }
    case ( QgsContrastEnhancement::UserDefinedEnhancement ):
      break;
    case ( QgsContrastEnhancement::NoEnhancement ):
      break;
  }

  // create tags
  QList< QPair< QString, QColor > >::ConstIterator it;
  for ( it = colorMapping.begin(); it != colorMapping.constEnd() ; ++it )
  {
    // set low level color mapping
    QDomElement lowColorMapEntryElem = doc.createElement( QStringLiteral( "sld:ColorMapEntry" ) );
    colorMapElem.appendChild( lowColorMapEntryElem );
    lowColorMapEntryElem.setAttribute( QStringLiteral( "color" ), it->second.name() );
    lowColorMapEntryElem.setAttribute( QStringLiteral( "quantity" ), it->first );
    if ( it->second.alphaF() == 0.0 )
    {
      lowColorMapEntryElem.setAttribute( QStringLiteral( "opacity" ), QString::number( it->second.alpha() ) );
    }
  }
}