Skip to content

Commit

Permalink
Make scalebars auto selected between m/km and ft/miles when newly added
Browse files Browse the repository at this point in the history
Based on current linked map scale and linked map CRS
  • Loading branch information
nyalldawson committed Nov 24, 2017
1 parent 3decab9 commit a615a48
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 1 deletion.
10 changes: 10 additions & 0 deletions python/core/layout/qgslayoutitemscalebar.sip
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,16 @@ class QgsLayoutItemScaleBar: QgsLayoutItem
.. seealso:: applyDefaultSize()
%End

QgsUnitTypes::DistanceUnit guessUnits() const;
%Docstring
Attempts to guess the most reasonable unit choice for the scalebar, given
the current linked map's scale.

This method also considers the linked map's CRS, in order to determine if
metric or imperial units are more appropriate.
:rtype: QgsUnitTypes.DistanceUnit
%End

void applyDefaultSize( QgsUnitTypes::DistanceUnit units = QgsUnitTypes::DistanceMeters );
%Docstring
Applies the default size to the scale bar (scale bar 1/5 of map item width)
Expand Down
2 changes: 1 addition & 1 deletion src/app/layout/qgslayoutapputils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ void QgsLayoutAppUtils::registerGuiForKnownItemTypes()
if ( targetMap )
{
scalebar->setMap( targetMap );
scalebar->applyDefaultSize();
scalebar->applyDefaultSize( scalebar->guessUnits() );
}
} );

Expand Down
42 changes: 42 additions & 0 deletions src/core/layout/qgslayoutitemscalebar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,48 @@ void QgsLayoutItemScaleBar::applyDefaultSettings()
emit changed();
}

QgsUnitTypes::DistanceUnit QgsLayoutItemScaleBar::guessUnits() const
{
if ( !mMap )
return QgsUnitTypes::DistanceMeters;

QgsCoordinateReferenceSystem crs = mMap->crs();
// start with crs units
QgsUnitTypes::DistanceUnit unit = crs.mapUnits();
if ( unit == QgsUnitTypes::DistanceDegrees || unit == QgsUnitTypes::DistanceUnknownUnit )
{
// geographic CRS, use metric units
unit = QgsUnitTypes::DistanceMeters;
}

// try to pick reasonable choice between metric / imperial units
double widthInSelectedUnits = mapWidth();
double initialUnitsPerSegment = widthInSelectedUnits / 10.0; //default scalebar width equals half the map width
switch ( unit )
{
case QgsUnitTypes::DistanceMeters:
{
if ( initialUnitsPerSegment > 1000.0 )
{
unit = QgsUnitTypes::DistanceKilometers;
}
break;
}
case QgsUnitTypes::DistanceFeet:
{
if ( initialUnitsPerSegment > 5419.95 )
{
unit = QgsUnitTypes::DistanceMiles;
}
break;
}
default:
break;
}

return unit;
}

void QgsLayoutItemScaleBar::applyDefaultSize( QgsUnitTypes::DistanceUnit units )
{
mSettings.setUnits( units );
Expand Down
9 changes: 9 additions & 0 deletions src/core/layout/qgslayoutitemscalebar.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,15 @@ class CORE_EXPORT QgsLayoutItemScaleBar: public QgsLayoutItem
*/
void applyDefaultSettings();

/**
* Attempts to guess the most reasonable unit choice for the scalebar, given
* the current linked map's scale.
*
* This method also considers the linked map's CRS, in order to determine if
* metric or imperial units are more appropriate.
*/
QgsUnitTypes::DistanceUnit guessUnits() const;

/**
* Applies the default size to the scale bar (scale bar 1/5 of map item width)
* \see applyDefaultSettings()
Expand Down

0 comments on commit a615a48

Please sign in to comment.