Skip to content

Commit

Permalink
QgsMapUnitScale fixes:
Browse files Browse the repository at this point in the history
- add docs
- add missing SIP bindings
- remove unnecessary cast from double->float->double
- add unit tests
  • Loading branch information
nyalldawson committed Sep 17, 2015
1 parent a77935f commit f0a2fc1
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 4 deletions.
16 changes: 14 additions & 2 deletions python/core/qgsmapunitscale.sip
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,25 @@ class QgsMapUnitScale
#include <qgsmapunitscale.h>
%End
public:
QgsMapUnitScale();
QgsMapUnitScale( float _minScale, float _maxScale );

/** Constructor for QgsMapUnitScale
* @param minScale minimum allowed scale, or 0.0 if no minimum scale set
* @param maxScale maximum allowed scale, or 0.0 if no maximum scale set
*/
QgsMapUnitScale( double minScale = 0.0, double maxScale = 0.0 );

/** The minimum scale, or 0.0 if unset */
double minScale;
/** The maximum scale, or 0.0 if unset */
double maxScale;

/** Computes a map units per pixel scaling factor, respecting the minimum and maximum scales
* set for the object.
* @param c render context
* @returns map units per pixel, limited between minimum and maximum scales
*/
double computeMapUnitsPerPixel( const QgsRenderContext& c ) const;

bool operator==( const QgsMapUnitScale& other ) const;
bool operator!=( const QgsMapUnitScale& other ) const;
};
22 changes: 20 additions & 2 deletions src/core/qgsmapunitscale.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,35 @@
#include <QtCore>
#include "qgsrendercontext.h"

/**
* \class QgsMapUnitScale
* \brief Struct for storing maximum and minimum scales for measurements in map units
*
* For measurements in map units, a minimum and a maximum scale can be defined.
* Outside this range, the measurements aren't scaled anymore proportionally to
* the map scale.
*/

class CORE_EXPORT QgsMapUnitScale
{
public:
QgsMapUnitScale() : minScale( 0.0 ), maxScale( 0.0 ) {}
QgsMapUnitScale( float _minScale, float _maxScale ) : minScale( _minScale ), maxScale( _maxScale ) {}

/** Constructor for QgsMapUnitScale
* @param minScale minimum allowed scale, or 0.0 if no minimum scale set
* @param maxScale maximum allowed scale, or 0.0 if no maximum scale set
*/
QgsMapUnitScale( double minScale = 0.0, double maxScale = 0.0 ) : minScale( minScale ), maxScale( maxScale ) {}

/** The minimum scale, or 0.0 if unset */
double minScale;
/** The maximum scale, or 0.0 if unset */
double maxScale;

/** Computes a map units per pixel scaling factor, respecting the minimum and maximum scales
* set for the object.
* @param c render context
* @returns map units per pixel, limited between minimum and maximum scales
*/
double computeMapUnitsPerPixel( const QgsRenderContext& c ) const
{
double mup = c.mapToPixel().mapUnitsPerPixel();
Expand Down
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ ADD_PYTHON_TEST(PyQgsFontUtils test_qgsfontutils.py)
ADD_PYTHON_TEST(PyQgsGeometryAvoidIntersections test_qgsgeometry_avoid_intersections.py)
ADD_PYTHON_TEST(PyQgsGeometryTest test_qgsgeometry.py)
ADD_PYTHON_TEST(PyQgsGraduatedSymbolRendererV2 test_qgsgraduatedsymbolrendererv2.py)
ADD_PYTHON_TEST(PyQgsMapUnitScale test_qgsmapunitscale.py)
ADD_PYTHON_TEST(PyQgsMemoryProvider test_provider_memory.py)
ADD_PYTHON_TEST(PyQgsNetworkContentFetcher test_qgsnetworkcontentfetcher.py)
ADD_PYTHON_TEST(PyQgsPalLabelingBase test_qgspallabeling_base.py)
Expand Down
101 changes: 101 additions & 0 deletions tests/src/python/test_qgsmapunitscale.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsMapUnitScale.
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Nyall Dawson'
__date__ = '2015-09'
__copyright__ = 'Copyright 2015, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'

import qgis

from qgis.core import (QgsMapUnitScale, QgsRenderContext, QgsMapSettings, QgsRectangle)
from PyQt4.QtCore import QSize
from utilities import (TestCase, unittest)


class PyQgsMapUnitScale(TestCase):

def testConstructor(self):
#test creating QgsMapUnitScale
c = QgsMapUnitScale()
self.assertEqual(c.minScale, 0)
self.assertEqual(c.maxScale, 0)

c = QgsMapUnitScale(0.0001, 0.005)
self.assertEqual(c.minScale, 0.0001)
self.assertEqual(c.maxScale, 0.005)

def testEquality(self):
#test equality operator

c1 = QgsMapUnitScale(0.0001, 0.005)
c2 = QgsMapUnitScale(0.0001, 0.005)
self.assertEqual(c1, c2)

c2.minScale = 0.0004
self.assertNotEqual(c1, c2)

c2.minScale = 0.0001
c2.maxScale = 0.007
self.assertNotEqual(c1, c2)

c2.maxScale = 0.005
self.assertEqual(c1, c2)

def testMapUnitsPerPixel(self):
#test computeMapUnitsPerPixel

ms = QgsMapSettings()
ms.setExtent(QgsRectangle(0, 0, 100, 100))
ms.setOutputSize(QSize(100, 50))
r = QgsRenderContext.fromMapSettings(ms)

#renderer scale should be about 1:291937841

#start with no min/max scale
c = QgsMapUnitScale()

mup = c.computeMapUnitsPerPixel(r)
self.assertAlmostEqual(mup, 2.0, places=5)

#add a minimum scale less than the renderer scale, so should be no change
c.minScale = 1 / 350000000.0
mup = c.computeMapUnitsPerPixel(r)
self.assertAlmostEqual(mup, 2.0, places=5)

#minimum scale greater than the renderer scale, so should be limited to minScale
c.minScale = 1 / 150000000.0
mup = c.computeMapUnitsPerPixel(r)
self.assertAlmostEqual(mup, 1.0276160, places=5)
c.minScale = 1 / 50000000.0
mup = c.computeMapUnitsPerPixel(r)
self.assertAlmostEqual(mup, 0.3425386, places=5)
c.minScale = 1 / 350000000.0

#add a maximum scale greater than the renderer scale, so should be no change
c.maxScale = 1 / 150000000.0
mup = c.computeMapUnitsPerPixel(r)
self.assertAlmostEqual(mup, 2.0, places=5)

#maximum scale less than the renderer scale, so should be limited to maxScale
c.maxScale = 1 / 350000000.0
mup = c.computeMapUnitsPerPixel(r)
self.assertAlmostEqual(mup, 2.3977706, places=5)
c.maxScale = 1 / 500000000.0
mup = c.computeMapUnitsPerPixel(r)
self.assertAlmostEqual(mup, 3.4253867, places=5)

#test resetting to min/max
c.minScale = 0
c.maxScale = 0
mup = c.computeMapUnitsPerPixel(r)
self.assertAlmostEqual(mup, 2.0, places=5)

if __name__ == '__main__':
unittest.main()

0 comments on commit f0a2fc1

Please sign in to comment.