Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Better fix for ffd81f4, avoid unnecessary copies of geometry
  • Loading branch information
nyalldawson committed Apr 14, 2015
1 parent cc9f2a6 commit cfe397e
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 10 deletions.
11 changes: 11 additions & 0 deletions python/core/qgspallabeling.sip
Expand Up @@ -754,6 +754,17 @@ class QgsPalLabeling : QgsLabelingEngineInterface
*/
static QgsGeometry* prepareGeometry( QgsGeometry *geometry, const QgsRenderContext &context, const QgsCoordinateTransform *ct, double minSize = 0, QgsGeometry *clipGeometry = 0 ) /Factory/;

/** Checks whether a geometry requires preparation before registration with PAL
* @param geometry geometry to prepare
* @param context render context
* @param ct coordinate transform
* @param clipGeometry geometry to clip features to, if applicable
* @returns true if geometry requires preparation
* @note added in QGIS 2.9
*/
static bool geometryRequiresPreparation( QgsGeometry *geometry, const QgsRenderContext &context, const QgsCoordinateTransform *ct, QgsGeometry *clipGeometry = 0 );


protected:
// update temporary QgsPalLayerSettings with any data defined text style values
void dataDefinedTextStyle( QgsPalLayerSettings& tmpLyr,
Expand Down
64 changes: 54 additions & 10 deletions src/core/qgspallabeling.cpp
Expand Up @@ -1762,11 +1762,19 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, const QgsRenderContext
doClip = true;
}

QScopedPointer<QgsGeometry> preparedGeom( QgsPalLabeling::prepareGeometry( geom, context, ct, minFeatureSize, doClip ? extentGeom : 0 ) );
if ( !preparedGeom.data() )
return;

const GEOSGeometry* geos_geom = preparedGeom.data()->asGeos();
const GEOSGeometry* geos_geom = 0;
QScopedPointer<QgsGeometry> preparedGeom;
if ( QgsPalLabeling::geometryRequiresPreparation( geom, context, ct, doClip ? extentGeom : 0 ) )
{
preparedGeom.reset( QgsPalLabeling::prepareGeometry( geom, context, ct, minFeatureSize, doClip ? extentGeom : 0 ) );
if ( !preparedGeom.data() )
return;
geos_geom = preparedGeom.data()->asGeos();
}
else
{
geos_geom = geom->asGeos();
}

if ( geos_geom == NULL )
return; // invalid geometry
Expand Down Expand Up @@ -3358,6 +3366,33 @@ void QgsPalLabeling::registerFeature( const QString& layerID, QgsFeature& f, con
lyr.registerFeature( f, context, dxfLayer );
}

bool QgsPalLabeling::geometryRequiresPreparation( QgsGeometry* geometry, const QgsRenderContext& context, const QgsCoordinateTransform* ct, QgsGeometry* clipGeometry )
{
if ( !geometry )
{
return false;
}

//requires reprojection
if ( ct )
return true;

//requires fixing
if ( geometry->type() == QGis::Polygon && !geometry->isGeosValid() )
return true;

//requires rotation
const QgsMapToPixel& m2p = context.mapToPixel();
if ( !qgsDoubleNear( m2p.mapRotation(), 0 ) )
return true;

//requires clip
if ( clipGeometry && !clipGeometry->contains( geometry ) )
return true;

return false;
}

QgsGeometry* QgsPalLabeling::prepareGeometry( QgsGeometry* geometry, const QgsRenderContext& context, const QgsCoordinateTransform* ct, double minSize, QgsGeometry* clipGeometry )
{
if ( !geometry )
Expand Down Expand Up @@ -3406,7 +3441,7 @@ QgsGeometry* QgsPalLabeling::prepareGeometry( QgsGeometry* geometry, const QgsRe

// Rotate the geometry if needed, before clipping
const QgsMapToPixel& m2p = context.mapToPixel();
if ( m2p.mapRotation() )
if ( !qgsDoubleNear( m2p.mapRotation(), 0 ) )
{
if ( geom->rotate( m2p.mapRotation(), context.extent().center() ) )
{
Expand Down Expand Up @@ -3500,11 +3535,20 @@ void QgsPalLabeling::registerDiagramFeature( const QString& layerID, QgsFeature&
QgsGeometry* geom = feat.geometry();
QScopedPointer<QgsGeometry> extentGeom( QgsGeometry::fromRect( mMapSettings->visibleExtent() ) );

QScopedPointer<QgsGeometry> preparedGeom( QgsPalLabeling::prepareGeometry( geom, context, layerIt.value().ct, -1, extentGeom.data() ) );
if ( !preparedGeom.data() )
return;
const GEOSGeometry* geos_geom = 0;
QScopedPointer<QgsGeometry> preparedGeom;
if ( QgsPalLabeling::geometryRequiresPreparation( geom, context, layerIt.value().ct, extentGeom.data() ) )
{
preparedGeom.reset( QgsPalLabeling::prepareGeometry( geom, context, layerIt.value().ct, 0, extentGeom.data() ) );
if ( !preparedGeom.data() )
return;
geos_geom = preparedGeom.data()->asGeos();
}
else
{
geos_geom = geom->asGeos();
}

const GEOSGeometry* geos_geom = preparedGeom.data()->asGeos();
if ( geos_geom == 0 )
{
return; // invalid geometry
Expand Down
10 changes: 10 additions & 0 deletions src/core/qgspallabeling.h
Expand Up @@ -823,6 +823,16 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
*/
static QgsGeometry* prepareGeometry( QgsGeometry *geometry, const QgsRenderContext &context, const QgsCoordinateTransform *ct, double minSize = 0, QgsGeometry *clipGeometry = 0 );

/** Checks whether a geometry requires preparation before registration with PAL
* @param geometry geometry to prepare
* @param context render context
* @param ct coordinate transform
* @param clipGeometry geometry to clip features to, if applicable
* @returns true if geometry requires preparation
* @note added in QGIS 2.9
*/
static bool geometryRequiresPreparation( QgsGeometry *geometry, const QgsRenderContext &context, const QgsCoordinateTransform *ct, QgsGeometry *clipGeometry = 0 );

protected:
// update temporary QgsPalLayerSettings with any data defined text style values
void dataDefinedTextStyle( QgsPalLayerSettings& tmpLyr,
Expand Down

0 comments on commit cfe397e

Please sign in to comment.