Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #980 from ahuarte47/Issue_8725-OGR
Feature #8725: Fast rendering of geometries
  • Loading branch information
mhugent committed Dec 17, 2013
2 parents 052b2eb + 9195356 commit 17cd09a
Show file tree
Hide file tree
Showing 40 changed files with 1,814 additions and 56 deletions.
20 changes: 20 additions & 0 deletions i18n/qgis_es.ts
Expand Up @@ -49496,6 +49496,10 @@ Should the existing classes be deleted before classification?</source>
<source>General</source>
<translation>General</translation>
</message>
<message>
<source>Rendering</source>
<translation>Representación</translation>
</message>
<message>
<source>Display name</source>
<translation type="obsolete">Mostrar el nombre</translation>
Expand Down Expand Up @@ -49944,6 +49948,22 @@ Should the existing classes be deleted before classification?</source>
<source>Type</source>
<translation>Tipo</translation>
</message>
<message>
<source>Fast drawing</source>
<translation>Pintado rápido</translation>
</message>
<message>
<source>&lt;b&gt;Note:&lt;/b&gt; This option enables geometry simplification drawing for fast rendering of the layer.</source>
<translation>&lt;b&gt;Nota:&lt;/b&gt; Esta opción activa el pintado simplificado de las geometrías para acelerar la representación de la capa.</translation>
</message>
<message>
<source>Simplification factor (Higher value draws more simplified geometries): </source>
<translation>Factor de simplificación (Cuanto mayor es el valor más se simplifica la geometría): </translation>
</message>
<message>
<source>Higher value draws more simplified geometries</source>
<translation>Cuanto mayor es el valor más se simplifica la geometría</translation>
</message>
</context>
<context>
<name>QgsVectorLayerSaveAsDialog</name>
Expand Down
2 changes: 1 addition & 1 deletion python/core/symbology-ng/qgssymbollayerv2.sip
Expand Up @@ -202,5 +202,5 @@ class QgsFillSymbolLayerV2 : QgsSymbolLayerV2
protected:
QgsFillSymbolLayerV2( bool locked = false );
/**Default method to render polygon*/
void _renderPolygon( QPainter* p, const QPolygonF& points, const QList<QPolygonF>* rings );
void _renderPolygon( QPainter* p, const QPolygonF& points, const QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
};
20 changes: 20 additions & 0 deletions src/app/qgsoptions.cpp
Expand Up @@ -560,6 +560,11 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
chkAntiAliasing->setChecked( settings.value( "/qgis/enable_anti_aliasing", true ).toBool() );
chkUseRenderCaching->setChecked( settings.value( "/qgis/enable_render_caching", false ).toBool() );

// Default simplify drawing configuration
mSimplifyDrawingGroupBox->setChecked( settings.value( "/qgis/simplifyDrawingHints", (int)QgsVectorLayer::DefaultSimplification ).toInt() != QgsVectorLayer::NoSimplification );
mSimplifyDrawingSlider->setValue( (int)(5.0f * (settings.value( "/qgis/simplifyDrawingTol", QGis::DEFAULT_MAPTOPIXEL_THRESHOLD ).toFloat()-1)) );
mSimplifyDrawingPanel->setVisible( mSimplifyDrawingSlider->value()>0 );

// Slightly awkard here at the settings value is true to use QImage,
// but the checkbox is true to use QPixmap
chkUseQPixmap->setChecked( !( settings.value( "/qgis/use_qimage_to_render", true ).toBool() ) );
Expand Down Expand Up @@ -1091,6 +1096,16 @@ void QgsOptions::saveOptions()
bool legendLayersCapitalise = settings.value( "/qgis/capitaliseLayerName", false ).toBool();
settings.setValue( "/qgis/capitaliseLayerName", capitaliseCheckBox->isChecked() );

// Default simplify drawing configuration
int simplifyDrawingHints = QgsVectorLayer::NoSimplification;
if ( mSimplifyDrawingGroupBox->isChecked() )
{
simplifyDrawingHints |= QgsVectorLayer::DefaultSimplification;
if ( mSimplifyDrawingSlider->value() > 0 ) simplifyDrawingHints |= QgsVectorLayer::AntialiasingSimplification;
}
settings.setValue( "/qgis/simplifyDrawingHints", simplifyDrawingHints );
settings.setValue( "/qgis/simplifyDrawingTol", 1.0f + 0.2f*mSimplifyDrawingSlider->value() );

// project
settings.setValue( "/qgis/projOpenAtLaunch", mProjectOnLaunchCmbBx->currentIndex() );
settings.setValue( "/qgis/projOpenAtLaunchPath", mProjectOnLaunchLineEdit->text() );
Expand Down Expand Up @@ -2063,3 +2078,8 @@ void QgsOptions::saveDefaultDatumTransformations()
s.endGroup();
}

void QgsOptions::on_mSimplifyDrawingSlider_valueChanged( int value )
{
mSimplifyDrawingPanel->setVisible( value>0 );
}

2 changes: 2 additions & 0 deletions src/app/qgsoptions.h
Expand Up @@ -235,6 +235,8 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption
void on_mRemoveDefaultTransformButton_clicked();
void on_mAddDefaultTransformButton_clicked();

void on_mSimplifyDrawingSlider_valueChanged( int value );

private:
QStringList i18nList();
void initContrastEnhancement( QComboBox *cbox, QString name, QString defaultVal );
Expand Down
20 changes: 20 additions & 0 deletions src/app/qgsvectorlayerproperties.cpp
Expand Up @@ -392,6 +392,11 @@ void QgsVectorLayerProperties::syncToLayer( void )
cbMinimumScale->setScale( 1.0 / layer->minimumScale() );
cbMaximumScale->setScale( 1.0 / layer->maximumScale() );

// get simplify drawing configuration
mSimplifyDrawingGroupBox->setChecked( layer->simplifyDrawingHints() != QgsVectorLayer::NoSimplification );
mSimplifyDrawingSlider->setValue( (int)(5.0f * (layer->simplifyDrawingTol()-1)) );
mSimplifyDrawingPanel->setVisible( mSimplifyDrawingSlider->value()>0 );

// load appropriate symbology page (V1 or V2)
updateSymbologyPage();

Expand Down Expand Up @@ -529,6 +534,16 @@ void QgsVectorLayerProperties::apply()
layer->setMetadataUrlType( mLayerMetadataUrlTypeComboBox->currentText() );
layer->setMetadataUrlFormat( mLayerMetadataUrlFormatComboBox->currentText() );

//layer simplify drawing configuration
int simplifyDrawingHints = QgsVectorLayer::NoSimplification;
if ( mSimplifyDrawingGroupBox->isChecked() )
{
simplifyDrawingHints |= QgsVectorLayer::DefaultSimplification;
if ( mSimplifyDrawingSlider->value() > 0 ) simplifyDrawingHints |= QgsVectorLayer::AntialiasingSimplification;
}
layer->setSimplifyDrawingHints( simplifyDrawingHints );
layer->setSimplifyDrawingTol( 1.0f + 0.2f*mSimplifyDrawingSlider->value() );

// update symbology
emit refreshLegend( layer->id(), QgsLegendItem::DontChange );

Expand Down Expand Up @@ -1067,3 +1082,8 @@ void QgsVectorLayerProperties::on_mMaximumScaleSetCurrentPushButton_clicked()
{
cbMaximumScale->setScale( 1.0 / QgisApp::instance()->mapCanvas()->mapRenderer()->scale() );
}

void QgsVectorLayerProperties::on_mSimplifyDrawingSlider_valueChanged( int value )
{
mSimplifyDrawingPanel->setVisible( value>0 );
}
2 changes: 2 additions & 0 deletions src/app/qgsvectorlayerproperties.h
Expand Up @@ -119,6 +119,8 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
void on_mMinimumScaleSetCurrentPushButton_clicked();
void on_mMaximumScaleSetCurrentPushButton_clicked();

void on_mSimplifyDrawingSlider_valueChanged( int value );

signals:

/** emitted when changes to layer were saved to update legend */
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -74,6 +74,7 @@ SET(QGIS_CORE_SRCS
qgsgeometry.cpp
qgsgeometrycache.cpp
qgsgeometryvalidator.cpp
qgsgeometrysimplifier.cpp
qgsgml.cpp
qgsgmlschema.cpp
qgshttptransaction.cpp
Expand All @@ -85,6 +86,7 @@ SET(QGIS_CORE_SRCS
qgsmaplayerregistry.cpp
qgsmaprenderer.cpp
qgsmaptopixel.cpp
qgsmaptopixelgeometrysimplifier.cpp
qgsmessageoutput.cpp
qgsmimedatautils.cpp
qgsmessagelog.cpp
Expand Down
11 changes: 6 additions & 5 deletions src/core/composer/qgscomposermap.cpp
Expand Up @@ -199,13 +199,14 @@ void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, const
{
theRendererContext->setDrawEditingInformation( false );
theRendererContext->setRenderingStopped( false );
}
theRendererContext->setRenderingPrintComposition( true );

// force vector output (no caching of marker images etc.)
theRendererContext->setForceVectorOutput( true );
// force vector output (no caching of marker images etc.)
theRendererContext->setForceVectorOutput( true );

// make the renderer respect the composition's useAdvancedEffects flag
theRendererContext->setUseAdvancedEffects( mComposition->useAdvancedEffects() );
// make the renderer respect the composition's useAdvancedEffects flag
theRendererContext->setUseAdvancedEffects( mComposition->useAdvancedEffects() );
}

//force composer map scale for scale dependent visibility
double bk_scale = theMapRenderer.scale();
Expand Down
3 changes: 3 additions & 0 deletions src/core/qgis.cpp
Expand Up @@ -73,6 +73,9 @@ const CORE_EXPORT QString GEO_NONE = "NONE";

const double QGis::DEFAULT_IDENTIFY_RADIUS = 0.5;

//! Default threshold between map coordinates and device coordinates for map2pixel simplification
const float QGis::DEFAULT_MAPTOPIXEL_THRESHOLD = 1.0f;

// description strings for units
// Order must match enum indices
const char* QGis::qgisUnitTypes[] =
Expand Down
3 changes: 3 additions & 0 deletions src/core/qgis.h
Expand Up @@ -263,6 +263,9 @@ class CORE_EXPORT QGis

static const double DEFAULT_IDENTIFY_RADIUS;

//! Default threshold between map coordinates and device coordinates for map2pixel simplification
static const float DEFAULT_MAPTOPIXEL_THRESHOLD;

private:
// String representation of unit types (set in qgis.cpp)
static const char *qgisUnitTypes[];
Expand Down
24 changes: 8 additions & 16 deletions src/core/qgsclipper.cpp
Expand Up @@ -45,6 +45,9 @@ const unsigned char* QgsClipper::clippedLineWKB( const unsigned char* wkb, const

bool hasZValue = ( wkbType == QGis::WKBLineString25D );

int sizeOfDoubleX = sizeof(double);
int sizeOfDoubleY = hasZValue ? 2*sizeof(double) : sizeof(double);

double p0x, p0y, p1x = 0.0, p1y = 0.0; //original coordinates
double p1x_c, p1y_c; //clipped end coordinates
double lastClipX = 0.0, lastClipY = 0.0; //last successfully clipped coords
Expand All @@ -56,29 +59,18 @@ const unsigned char* QgsClipper::clippedLineWKB( const unsigned char* wkb, const
{
if ( i == 0 )
{
memcpy( &p1x, wkb, sizeof( double ) );
wkb += sizeof( double );
memcpy( &p1y, wkb, sizeof( double ) );
wkb += sizeof( double );
if ( hasZValue ) // ignore Z value
{
wkb += sizeof( double );
}
memcpy( &p1x, wkb, sizeof( double ) ); wkb += sizeOfDoubleX;
memcpy( &p1y, wkb, sizeof( double ) ); wkb += sizeOfDoubleY;

continue;
}
else
{
p0x = p1x;
p0y = p1y;

memcpy( &p1x, wkb, sizeof( double ) );
wkb += sizeof( double );
memcpy( &p1y, wkb, sizeof( double ) );
wkb += sizeof( double );
if ( hasZValue ) // ignore Z value
{
wkb += sizeof( double );
}
memcpy( &p1x, wkb, sizeof( double ) ); wkb += sizeOfDoubleX;
memcpy( &p1y, wkb, sizeof( double ) ); wkb += sizeOfDoubleY;

p1x_c = p1x; p1y_c = p1y;
if ( clipLineSegment( clipExtent.xMinimum(), clipExtent.xMaximum(), clipExtent.yMinimum(), clipExtent.yMaximum(),
Expand Down
33 changes: 33 additions & 0 deletions src/core/qgsfeaturerequest.cpp
Expand Up @@ -23,6 +23,9 @@ QgsFeatureRequest::QgsFeatureRequest()
: mFilter( FilterNone )
, mFilterExpression( 0 )
, mFlags( 0 )
, mMapCoordTransform( NULL )
, mMapToPixel( NULL )
, mMapToPixelTol( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
{
}

Expand All @@ -31,6 +34,9 @@ QgsFeatureRequest::QgsFeatureRequest( QgsFeatureId fid )
, mFilterFid( fid )
, mFilterExpression( 0 )
, mFlags( 0 )
, mMapCoordTransform( NULL )
, mMapToPixel( NULL )
, mMapToPixelTol( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
{
}

Expand All @@ -39,13 +45,19 @@ QgsFeatureRequest::QgsFeatureRequest( const QgsRectangle& rect )
, mFilterRect( rect )
, mFilterExpression( 0 )
, mFlags( 0 )
, mMapCoordTransform( NULL )
, mMapToPixel( NULL )
, mMapToPixelTol( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
{
}

QgsFeatureRequest::QgsFeatureRequest( const QgsExpression& expr )
: mFilter( FilterExpression )
, mFilterExpression( new QgsExpression( expr.expression() ) )
, mFlags( 0 )
, mMapCoordTransform( NULL )
, mMapToPixel( NULL )
, mMapToPixelTol( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
{
}

Expand All @@ -70,6 +82,9 @@ QgsFeatureRequest& QgsFeatureRequest::operator=( const QgsFeatureRequest & rh )
mFilterExpression = 0;
}
mAttrs = rh.mAttrs;
mMapCoordTransform = rh.mMapCoordTransform;
mMapToPixel = rh.mMapToPixel;
mMapToPixelTol = rh.mMapToPixelTol;
return *this;
}

Expand Down Expand Up @@ -174,3 +189,21 @@ bool QgsFeatureRequest::acceptFeature( const QgsFeature& feature )

return true;
}

QgsFeatureRequest& QgsFeatureRequest::setCoordinateTransform( const QgsCoordinateTransform* ct )
{
mMapCoordTransform = ct;
return *this;
}

QgsFeatureRequest& QgsFeatureRequest::setMapToPixel( const QgsMapToPixel* mtp )
{
mMapToPixel = mtp;
return *this;
}

QgsFeatureRequest& QgsFeatureRequest::setMapToPixelTol( float map2pixelTol )
{
mMapToPixelTol = map2pixelTol;
return *this;
}
23 changes: 22 additions & 1 deletion src/core/qgsfeaturerequest.h
Expand Up @@ -21,6 +21,9 @@
#include "qgsrectangle.h"
#include "qgsexpression.h"

#include "qgscoordinatetransform.h"
#include "qgsmaptopixel.h"

#include <QList>
typedef QList<int> QgsAttributeList;

Expand Down Expand Up @@ -61,7 +64,9 @@ class CORE_EXPORT QgsFeatureRequest
NoFlags = 0,
NoGeometry = 1, //!< Geometry is not required. It may still be returned if e.g. required for a filter condition.
SubsetOfAttributes = 2, //!< Fetch only a subset of attributes (setSubsetOfAttributes sets this flag)
ExactIntersect = 4 //!< Use exact geometry intersection (slower) instead of bounding boxes
ExactIntersect = 4, //!< Use exact geometry intersection (slower) instead of bounding boxes
SimplifyGeometry = 8, //!< The geometries can be simplified using the current map2pixel context state (e.g. for fast rendering...)
SimplifyEnvelope = 16 //!< The geometries can be fully simplified by its BoundingBox (e.g. for fast rendering...)
};
Q_DECLARE_FLAGS( Flags, Flag )

Expand Down Expand Up @@ -135,6 +140,15 @@ class CORE_EXPORT QgsFeatureRequest
// void setFilterNativeExpression(con QString& expr); // using provider's SQL (if supported)
// void setLimit(int limit);

const QgsCoordinateTransform* coordinateTransform() const { return mMapCoordTransform; }
QgsFeatureRequest& setCoordinateTransform( const QgsCoordinateTransform* ct );

const QgsMapToPixel* mapToPixel() const { return mMapToPixel; }
QgsFeatureRequest& setMapToPixel( const QgsMapToPixel* mtp );

float mapToPixelTol() const { return mMapToPixelTol; }
QgsFeatureRequest& setMapToPixelTol( float map2pixelTol );

protected:
FilterType mFilter;
QgsRectangle mFilterRect;
Expand All @@ -143,6 +157,13 @@ class CORE_EXPORT QgsFeatureRequest
QgsExpression* mFilterExpression;
Flags mFlags;
QgsAttributeList mAttrs;

//! For transformation between coordinate systems from current layer to map target. Can be 0 if on-the-fly reprojection is not used
const QgsCoordinateTransform* mMapCoordTransform;
//! For transformation between map coordinates and device coordinates
const QgsMapToPixel* mMapToPixel;
//! Factor tolterance to apply in transformation between map coordinates and device coordinates
float mMapToPixelTol;
};

Q_DECLARE_OPERATORS_FOR_FLAGS( QgsFeatureRequest::Flags )
Expand Down

0 comments on commit 17cd09a

Please sign in to comment.