Skip to content

Commit

Permalink
[feature] data defined control over layout map CRS
Browse files Browse the repository at this point in the history
  • Loading branch information
roya0045 committed Feb 22, 2020
1 parent 199156a commit 13337b2
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 91 deletions.
1 change: 1 addition & 0 deletions python/core/auto_generated/layout/qgslayoutobject.sip.in
Expand Up @@ -163,6 +163,7 @@ A base class for objects which belong to a layout.
ScalebarLineWidth,
//table item
AttributeTableSourceLayer,
MapCrs,
};

enum PropertyValueType
Expand Down
12 changes: 10 additions & 2 deletions src/core/layout/qgslayoutitemmap.cpp
Expand Up @@ -1687,7 +1687,13 @@ void QgsLayoutItemMap::updateBoundingRect()
void QgsLayoutItemMap::refreshDataDefinedProperty( const QgsLayoutObject::DataDefinedProperty property )
{
QgsExpressionContext context = createExpressionContext();

if ( property == QgsLayoutObject::MapCrs || property == QgsLayoutObject::AllProperties )
{
bool ok;
QString crsVar = mDataDefinedProperties.valueAsString( QgsLayoutObject::MapCrs, context, QString(), &ok );
if ( ok && QgsCoordinateReferenceSystem( crsVar ).isValid() )
mCrs = QgsCoordinateReferenceSystem( crsVar );
}
//updates data defined properties and redraws item to match
if ( property == QgsLayoutObject::MapRotation || property == QgsLayoutObject::MapScale ||
property == QgsLayoutObject::MapXMin || property == QgsLayoutObject::MapYMin ||
Expand Down Expand Up @@ -2226,8 +2232,11 @@ void QgsLayoutItemMap::refreshMapExtents( const QgsExpressionContext *context )
QgsExpressionContext scopedContext;
if ( !context )
scopedContext = createExpressionContext();

bool ok = false;
const QgsExpressionContext *evalContext = context ? context : &scopedContext;


//data defined map extents set?
QgsRectangle newExtent = extent();
bool useDdXMin = false;
Expand All @@ -2239,7 +2248,6 @@ void QgsLayoutItemMap::refreshMapExtents( const QgsExpressionContext *context )
double maxXD = 0;
double maxYD = 0;

bool ok = false;
minXD = mDataDefinedProperties.valueAsDouble( QgsLayoutObject::MapXMin, *evalContext, 0.0, &ok );
if ( ok )
{
Expand Down
1 change: 1 addition & 0 deletions src/core/layout/qgslayoutobject.cpp
Expand Up @@ -90,6 +90,7 @@ void QgsLayoutObject::initPropertyDefinitions()
{ QgsLayoutObject::ScalebarLineColor, QgsPropertyDefinition( "dataDefinedScalebarLineColor", QObject::tr( "Line color" ), QgsPropertyDefinition::ColorWithAlpha ) },
{ QgsLayoutObject::ScalebarLineWidth, QgsPropertyDefinition( "dataDefinedScalebarLineWidth", QObject::tr( "Line width" ), QgsPropertyDefinition::StrokeWidth ) },
{ QgsLayoutObject::AttributeTableSourceLayer, QgsPropertyDefinition( "dataDefinedAttributeTableSourceLayer", QObject::tr( "Table source layer" ), QgsPropertyDefinition::String ) },
{ QgsLayoutObject::MapCrs, QgsPropertyDefinition( "dataDefinedCrs", QgsPropertyDefinition::DataTypeString, QObject::tr( "Map CRS" ), QObject::tr( "string representing a CRS, either an authority/id pair (e.g. \"EPSG:4326\"), a proj string prefixes by \"PROJ:\" (e.g. \"PROJ: +proj=...\") or a WKT string prefixed by \"WKT:\" (e.g. \"WKT:GEOGCS[\"WGS 84\"...)" ) ) },
};
}

Expand Down
1 change: 1 addition & 0 deletions src/core/layout/qgslayoutobject.h
Expand Up @@ -191,6 +191,7 @@ class CORE_EXPORT QgsLayoutObject: public QObject, public QgsExpressionContextGe
ScalebarLineWidth, //!< Scalebar line width,
//table item
AttributeTableSourceLayer, //!< Attribute table source layer
MapCrs, //!< Map CRS
};

/**
Expand Down
4 changes: 3 additions & 1 deletion src/gui/layout/qgslayoutmapwidget.cpp
Expand Up @@ -38,7 +38,7 @@
#include <QMenu>
#include <QMessageBox>

QgsLayoutMapWidget::QgsLayoutMapWidget(QgsLayoutItemMap *item , QgsMapCanvas *mapCanvas)
QgsLayoutMapWidget::QgsLayoutMapWidget( QgsLayoutItemMap *item, QgsMapCanvas *mapCanvas )
: QgsLayoutItemBaseWidget( nullptr, item )
, mMapItem( item )
, mMapCanvas( mapCanvas )
Expand Down Expand Up @@ -176,6 +176,7 @@ QgsLayoutMapWidget::QgsLayoutMapWidget(QgsLayoutItemMap *item , QgsMapCanvas *ma
registerDataDefinedButton( mAtlasMarginDDBtn, QgsLayoutObject::MapAtlasMargin );
registerDataDefinedButton( mStylePresetsDDBtn, QgsLayoutObject::MapStylePreset );
registerDataDefinedButton( mLayersDDBtn, QgsLayoutObject::MapLayers );
registerDataDefinedButton( mCRSDDBtn, QgsLayoutObject::MapCrs );

updateGuiElements();
loadGridEntries();
Expand Down Expand Up @@ -247,6 +248,7 @@ void QgsLayoutMapWidget::populateDataDefinedButtons()
updateDataDefinedButton( mAtlasMarginDDBtn );
updateDataDefinedButton( mStylePresetsDDBtn );
updateDataDefinedButton( mLayersDDBtn );
updateDataDefinedButton( mCRSDDBtn );
}

void QgsLayoutMapWidget::compositionAtlasToggled( bool atlasEnabled )
Expand Down
187 changes: 99 additions & 88 deletions src/ui/layout/qgslayoutmapwidgetbase.ui
Expand Up @@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>384</width>
<width>564</width>
<height>749</height>
</rect>
</property>
Expand Down Expand Up @@ -87,9 +87,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-583</y>
<width>368</width>
<height>1276</height>
<y>0</y>
<width>545</width>
<height>1113</height>
</rect>
</property>
<property name="sizePolicy">
Expand All @@ -113,59 +113,7 @@
<property name="collapsed" stdset="0">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QgsDoubleSpinBox" name="mMapRotationSpinBox">
<property name="wrapping">
<bool>true</bool>
</property>
<property name="suffix">
<string> °</string>
</property>
<property name="minimum">
<double>-360.000000000000000</double>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QgsPropertyOverrideButton" name="mMapRotationDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="mDrawCanvasItemsCheckBox">
<property name="text">
<string>Draw map canvas items</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLineEdit" name="mScaleLineEdit">
<property name="inputMask">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QgsPropertyOverrideButton" name="mScaleDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
</layout>
</item>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="mScaleLabel">
<property name="text">
Expand All @@ -176,12 +124,68 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QgsProjectionSelectionWidget" name="mCrsSelector" native="true">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
<item row="0" column="1" rowspan="3">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLineEdit" name="mScaleLineEdit">
<property name="inputMask">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QgsPropertyOverrideButton" name="mScaleDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QgsDoubleSpinBox" name="mMapRotationSpinBox">
<property name="wrapping">
<bool>true</bool>
</property>
<property name="suffix">
<string> °</string>
</property>
<property name="minimum">
<double>-360.000000000000000</double>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QgsPropertyOverrideButton" name="mMapRotationDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QgsProjectionSelectionWidget" name="mCrsSelector">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
</item>
<item>
<widget class="QgsPropertyOverrideButton" name="mCRSDDBtn"/>
</item>
</layout>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mMapRotationLabel">
Expand All @@ -197,6 +201,13 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="mDrawCanvasItemsCheckBox">
<property name="text">
<string>Draw map canvas items</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down Expand Up @@ -891,57 +902,57 @@
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>QgsScrollArea</class>
<extends>QScrollArea</extends>
<header>qgsscrollarea.h</header>
<container>1</container>
<class>QgsDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>qgsdoublespinbox.h</header>
</customwidget>
<customwidget>
<class>QgsCollapsibleGroupBoxBasic</class>
<extends>QGroupBox</extends>
<header>qgscollapsiblegroupbox.h</header>
<class>QgsMapLayerComboBox</class>
<extends>QComboBox</extends>
<header>qgsmaplayercombobox.h</header>
</customwidget>
<customwidget>
<class>QgsProjectionSelectionWidget</class>
<extends>QWidget</extends>
<header>qgsprojectionselectionwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>qgsdoublespinbox.h</header>
<class>QgsPropertyOverrideButton</class>
<extends>QToolButton</extends>
<header>qgspropertyoverridebutton.h</header>
</customwidget>
<customwidget>
<class>QgsSpinBox</class>
<extends>QSpinBox</extends>
<header>qgsspinbox.h</header>
</customwidget>
<customwidget>
<class>QgsBlendModeComboBox</class>
<extends>QComboBox</extends>
<header>qgsblendmodecombobox.h</header>
</customwidget>
<customwidget>
<class>QgsSymbolButton</class>
<extends>QToolButton</extends>
<header>qgssymbolbutton.h</header>
</customwidget>
<customwidget>
<class>QgsPropertyOverrideButton</class>
<extends>QToolButton</extends>
<header>qgspropertyoverridebutton.h</header>
<class>QgsScrollArea</class>
<extends>QScrollArea</extends>
<header>qgsscrollarea.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsProjectionSelectionWidget</class>
<extends>QWidget</extends>
<header>qgsprojectionselectionwidget.h</header>
<class>QgsCollapsibleGroupBoxBasic</class>
<extends>QGroupBox</extends>
<header>qgscollapsiblegroupbox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsLayoutItemComboBox</class>
<class>QgsBlendModeComboBox</class>
<extends>QComboBox</extends>
<header>qgslayoutitemcombobox.h</header>
<header>qgsblendmodecombobox.h</header>
</customwidget>
<customwidget>
<class>QgsMapLayerComboBox</class>
<class>QgsLayoutItemComboBox</class>
<extends>QComboBox</extends>
<header location="global">qgsmaplayercombobox.h</header>
<header>qgslayoutitemcombobox.h</header>
</customwidget>
</customwidgets>
<tabstops>
Expand Down
27 changes: 27 additions & 0 deletions tests/src/core/testqgslayoutmap.cpp
Expand Up @@ -56,6 +56,7 @@ class TestQgsLayoutMap : public QObject
void mapPolygonVertices(); // test mapPolygon function with no map rotation
void dataDefinedLayers(); //test data defined layer string
void dataDefinedStyles(); //test data defined styles
void dataDefinedCrs(); //test data defined crs
void rasterized();
void layersToRender();
void mapRotation();
Expand Down Expand Up @@ -458,6 +459,32 @@ void TestQgsLayoutMap::dataDefinedStyles()
QVERIFY( checker.testLayout( mReport, 0, 0 ) );
}

void TestQgsLayoutMap::dataDefinedCrs()
{
QList<QgsMapLayer *> layers = QList<QgsMapLayer *>() << mRasterLayer << mPolysLayer << mPointsLayer << mLinesLayer;

QgsLayout l( QgsProject::instance() );
l.initializeDefaults();

QgsLayoutItemMap *map = new QgsLayoutItemMap( &l );
map->attemptMove( QgsLayoutPoint( 20, 20 ) );
map->attemptResize( QgsLayoutSize( 200, 100 ) );
map->setFrameEnabled( true );
map->setLayers( layers );
l.addLayoutItem( map );

//test epsg variable
map->dataDefinedProperties().setProperty( QgsLayoutObject::MapCrs, QgsProperty::fromValue( QStringLiteral( "EPSG:2192" ) ) );
map->refreshDataDefinedProperty( QgsLayoutObject::MapCrs );
QCOMPARE( map->crs().authid(), QStringLiteral( "EPSG:2192" ) );

//test proj string variable
map->dataDefinedProperties().setProperty( QgsLayoutObject::MapCrs, QgsProperty::fromValue( QStringLiteral( "PROJ4: +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs" ) ) );
map->refreshDataDefinedProperty( QgsLayoutObject::MapCrs );
QCOMPARE( map->crs().toProj(), QStringLiteral( "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs" ) );

}

void TestQgsLayoutMap::rasterized()
{
// test a map which must be rasterized
Expand Down

0 comments on commit 13337b2

Please sign in to comment.