Skip to content

Commit ae875a0

Browse files
committed
[composer] Make atlas fixed and predefined scales options work correctly with geographic coordinate systems (fix #9839)
1 parent 8f5fe10 commit ae875a0

File tree

1 file changed

+61
-50
lines changed

1 file changed

+61
-50
lines changed

src/core/composer/qgsatlascomposition.cpp

+61-50
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ void QgsAtlasComposition::prepareMap( QgsComposerMap* map )
444444
double xa2 = mTransformedFeatureBounds.xMaximum();
445445
double ya1 = mTransformedFeatureBounds.yMinimum();
446446
double ya2 = mTransformedFeatureBounds.yMaximum();
447-
QgsRectangle new_extent = mTransformedFeatureBounds;
447+
QgsRectangle newExtent = mTransformedFeatureBounds;
448448
QgsRectangle mOrigExtent = map->extent();
449449

450450
//sanity check - only allow fixed scale mode for point layers
@@ -462,85 +462,96 @@ void QgsAtlasComposition::prepareMap( QgsComposerMap* map )
462462
break;
463463
}
464464

465-
if ( map->atlasScalingMode() == QgsComposerMap::Fixed || isPointLayer )
465+
if ( map->atlasScalingMode() == QgsComposerMap::Fixed || map->atlasScalingMode() == QgsComposerMap::Predefined || isPointLayer )
466466
{
467-
// only translate, keep the original scale (i.e. width x height)
468-
469-
double geom_center_x = ( xa1 + xa2 ) / 2.0;
470-
double geom_center_y = ( ya1 + ya2 ) / 2.0;
471-
double xx = geom_center_x - mOrigExtent.width() / 2.0;
472-
double yy = geom_center_y - mOrigExtent.height() / 2.0;
473-
new_extent = QgsRectangle( xx,
474-
yy,
475-
xx + mOrigExtent.width(),
476-
yy + mOrigExtent.height() );
477-
}
478-
else if ( map->atlasScalingMode() == QgsComposerMap::Predefined )
479-
{
480-
// choose one of the predefined scales
481467
QgsScaleCalculator calc;
482468
calc.setMapUnits( composition()->mapSettings().mapUnits() );
483469
calc.setDpi( 25.4 );
484-
double scale = calc.calculate( map->extent(), map->rect().width() );
485-
QgsRectangle extent = map->extent();
470+
double originalScale = calc.calculate( mOrigExtent, map->rect().width() );
471+
double geomCenterX = ( xa1 + xa2 ) / 2.0;
472+
double geomCenterY = ( ya1 + ya2 ) / 2.0;
486473

487-
double n_width = extent.width(), n_height = extent.height();
488-
const QVector<double>& scales = mPredefinedScales;
489-
for ( int i = 0; i < scales.size(); i++ )
474+
if ( map->atlasScalingMode() == QgsComposerMap::Fixed || isPointLayer )
490475
{
491-
double ratio = scales[i] / scale;
492-
n_width = extent.width() * ratio;
493-
n_height = extent.height() * ratio;
494-
if (( n_width >= new_extent.width() ) && ( n_height >= new_extent.height() ) )
476+
// only translate, keep the original scale (i.e. width x height)
477+
double xMin = geomCenterX - mOrigExtent.width() / 2.0;
478+
double yMin = geomCenterY - mOrigExtent.height() / 2.0;
479+
newExtent = QgsRectangle( xMin,
480+
yMin,
481+
xMin + mOrigExtent.width(),
482+
yMin + mOrigExtent.height() );
483+
484+
//scale newExtent to match original scale of map
485+
//this is required for geographic coordinate systems, where the scale varies by extent
486+
double newScale = calc.calculate( newExtent, map->rect().width() );
487+
newExtent.scale( originalScale / newScale );
488+
}
489+
else if ( map->atlasScalingMode() == QgsComposerMap::Predefined )
490+
{
491+
// choose one of the predefined scales
492+
double newWidth = mOrigExtent.width();
493+
double newHeight = mOrigExtent.height();
494+
const QVector<double>& scales = mPredefinedScales;
495+
for ( int i = 0; i < scales.size(); i++ )
495496
{
496-
// this is the smallest extent that embeds the feature, stop here
497-
break;
497+
double ratio = scales[i] / originalScale;
498+
newWidth = mOrigExtent.width() * ratio;
499+
newHeight = mOrigExtent.height() * ratio;
500+
501+
// compute new extent, centered on feature
502+
double xMin = geomCenterX - newWidth / 2.0;
503+
double yMin = geomCenterY - newHeight / 2.0;
504+
newExtent = QgsRectangle( xMin,
505+
yMin,
506+
xMin + newWidth,
507+
yMin + newHeight );
508+
509+
//scale newExtent to match desired map scale
510+
//this is required for geographic coordinate systems, where the scale varies by extent
511+
double newScale = calc.calculate( newExtent, map->rect().width() );
512+
newExtent.scale( scales[i] / newScale );
513+
514+
if (( newExtent.width() >= mTransformedFeatureBounds.width() ) && ( newExtent.height() >= mTransformedFeatureBounds.height() ) )
515+
{
516+
// this is the smallest extent that embeds the feature, stop here
517+
break;
518+
}
498519
}
499520
}
500-
501-
// compute new extent, centered on feature
502-
double geom_center_x = ( xa1 + xa2 ) / 2.0;
503-
double geom_center_y = ( ya1 + ya2 ) / 2.0;
504-
double xx = geom_center_x - n_width / 2.0;
505-
double yy = geom_center_y - n_height / 2.0;
506-
new_extent = QgsRectangle( xx,
507-
yy,
508-
xx + n_width,
509-
yy + n_height );
510521
}
511522
else if ( map->atlasScalingMode() == QgsComposerMap::Auto )
512523
{
513524
// auto scale
514525

515-
double geom_ratio = mTransformedFeatureBounds.width() / mTransformedFeatureBounds.height();
516-
double map_ratio = mOrigExtent.width() / mOrigExtent.height();
526+
double geomRatio = mTransformedFeatureBounds.width() / mTransformedFeatureBounds.height();
527+
double mapRatio = mOrigExtent.width() / mOrigExtent.height();
517528

518529
// geometry height is too big
519-
if ( geom_ratio < map_ratio )
530+
if ( geomRatio < mapRatio )
520531
{
521532
// extent the bbox's width
522-
double adj_width = ( map_ratio * mTransformedFeatureBounds.height() - mTransformedFeatureBounds.width() ) / 2.0;
523-
xa1 -= adj_width;
524-
xa2 += adj_width;
533+
double adjWidth = ( mapRatio * mTransformedFeatureBounds.height() - mTransformedFeatureBounds.width() ) / 2.0;
534+
xa1 -= adjWidth;
535+
xa2 += adjWidth;
525536
}
526537
// geometry width is too big
527-
else if ( geom_ratio > map_ratio )
538+
else if ( geomRatio > mapRatio )
528539
{
529540
// extent the bbox's height
530-
double adj_height = ( mTransformedFeatureBounds.width() / map_ratio - mTransformedFeatureBounds.height() ) / 2.0;
531-
ya1 -= adj_height;
532-
ya2 += adj_height;
541+
double adjHeight = ( mTransformedFeatureBounds.width() / mapRatio - mTransformedFeatureBounds.height() ) / 2.0;
542+
ya1 -= adjHeight;
543+
ya2 += adjHeight;
533544
}
534-
new_extent = QgsRectangle( xa1, ya1, xa2, ya2 );
545+
newExtent = QgsRectangle( xa1, ya1, xa2, ya2 );
535546

536547
if ( map->atlasMargin() > 0.0 )
537548
{
538-
new_extent.scale( 1 + map->atlasMargin() );
549+
newExtent.scale( 1 + map->atlasMargin() );
539550
}
540551
}
541552

542553
// set the new extent (and render)
543-
map->setNewAtlasFeatureExtent( new_extent );
554+
map->setNewAtlasFeatureExtent( newExtent );
544555
}
545556

546557
const QString& QgsAtlasComposition::currentFilename() const

0 commit comments

Comments
 (0)