mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Add SimplifyAlgorithm enum for local simplification
It implements the SimplifyAlgorithm enum for local simplification of geometries. Also the SnapToGrid algorithm is added.
This commit is contained in:
parent
01ece90f51
commit
734b8b4c62
@ -4,6 +4,13 @@ class QgsMapToPixelSimplifier : QgsAbstractGeometrySimplifier
|
||||
#include "qgsmaptopixelgeometrysimplifier.h"
|
||||
%End
|
||||
public:
|
||||
//! Types of simplification algorithms that can be used
|
||||
enum SimplifyAlgorithm
|
||||
{
|
||||
Distance = 0, //!< The simplification uses the distance between points to remove duplicate points
|
||||
SnapToGrid = 1, //!< The simplification uses a grid (similar to ST_SnapToGrid) to remove duplicate points
|
||||
};
|
||||
|
||||
QgsMapToPixelSimplifier( int simplifyFlags, double tolerance );
|
||||
virtual ~QgsMapToPixelSimplifier();
|
||||
|
||||
@ -20,10 +27,16 @@ class QgsMapToPixelSimplifier : QgsAbstractGeometrySimplifier
|
||||
//! Returns the squared 2D-distance of the vector defined by the two points specified
|
||||
static float calculateLengthSquared2D( double x1, double y1, double x2, double y2 );
|
||||
|
||||
//! Returns whether the points belong to the same grid
|
||||
static bool equalSnapToGrid( double x1, double y1, double x2, double y2, double gridOriginX, double gridOriginY, float gridInverseSizeXY );
|
||||
|
||||
public:
|
||||
int simplifyFlags() const;
|
||||
void setSimplifyFlags( int simplifyFlags );
|
||||
|
||||
SimplifyAlgorithm simplifyAlgorithm() const;
|
||||
void setSimplifyAlgorithm( SimplifyAlgorithm simplifyAlgorithm );
|
||||
|
||||
//! Returns a simplified version the specified geometry
|
||||
virtual QgsGeometry* simplify( QgsGeometry* geometry ) const;
|
||||
//! Simplifies the specified geometry
|
||||
@ -42,9 +55,9 @@ class QgsMapToPixelSimplifier : QgsAbstractGeometrySimplifier
|
||||
bool isGeneralizableByMapBoundingBox( const QgsRectangle& envelope ) const;
|
||||
|
||||
//! Simplifies the geometry when is applied the specified map2pixel context
|
||||
static bool simplifyGeometry( QgsGeometry* geometry, int simplifyFlags, double tolerance );
|
||||
static bool simplifyGeometry( QgsGeometry* geometry, int simplifyFlags, double tolerance, SimplifyAlgorithm simplifyAlgorithm = Distance );
|
||||
|
||||
//! Simplifies the WKB-point array when is applied the specified map2pixel context
|
||||
static bool simplifyPoints( QgsWKBTypes::Type wkbType, QgsConstWkbPtr& sourceWkbPtr, QPolygonF& targetPoints, int simplifyFlags, double tolerance );
|
||||
static bool simplifyPoints( QgsWKBTypes::Type wkbType, QgsConstWkbPtr& sourceWkbPtr, QPolygonF& targetPoints, int simplifyFlags, double tolerance, SimplifyAlgorithm simplifyAlgorithm = Distance );
|
||||
|
||||
};
|
||||
|
@ -29,6 +29,18 @@ class QgsVectorSimplifyMethod
|
||||
/** Gets the simplification hints of the vector layer managed */
|
||||
QFlags<QgsVectorSimplifyMethod::SimplifyHint> simplifyHints() const;
|
||||
|
||||
/** Types of local simplification algorithms that can be used */
|
||||
enum SimplifyAlgorithm
|
||||
{
|
||||
Distance = 0, //!< The simplification uses the distance between points to remove duplicate points
|
||||
SnapToGrid = 1, //!< The simplification uses a grid (similar to ST_SnapToGrid) to remove duplicate points
|
||||
};
|
||||
|
||||
/** Sets the local simplification algorithm of the vector layer managed */
|
||||
void setSimplifyAlgorithm( const SimplifyAlgorithm& simplifyAlgorithm );
|
||||
/** Gets the local simplification algorithm of the vector layer managed */
|
||||
SimplifyAlgorithm simplifyAlgorithm() const;
|
||||
|
||||
/** Sets the tolerance of simplification in map units. Represents the maximum distance in map units between two coordinates which can be considered equal */
|
||||
void setTolerance( double tolerance );
|
||||
/** Gets the tolerance of simplification in map units. Represents the maximum distance in map units between two coordinates which can be considered equal */
|
||||
|
@ -613,6 +613,11 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl )
|
||||
doubleSpinBoxMagnifierDefault->setSuffix( "%" );
|
||||
doubleSpinBoxMagnifierDefault->setValue( mSettings->value( "/qgis/magnifier_level", 100 ).toInt() );
|
||||
|
||||
// Default local simplification algorithm
|
||||
mSimplifyAlgorithmComboBox->addItem( tr( "Distance" ), ( int )QgsVectorSimplifyMethod::Distance );
|
||||
mSimplifyAlgorithmComboBox->addItem( tr( "SnapToGrid" ), ( int )QgsVectorSimplifyMethod::SnapToGrid );
|
||||
mSimplifyAlgorithmComboBox->setCurrentIndex( mSimplifyAlgorithmComboBox->findData( mSettings->value( "/qgis/simplifyAlgorithm", 0 ).toInt() ) );
|
||||
|
||||
// Slightly awkard here at the settings value is true to use QImage,
|
||||
// but the checkbox is true to use QPixmap
|
||||
chkAddedVisibility->setChecked( mSettings->value( "/qgis/new_layers_visible", true ).toBool() );
|
||||
@ -1212,6 +1217,7 @@ void QgsOptions::saveOptions()
|
||||
if ( mSimplifyDrawingSpinBox->value() > 1 ) simplifyHints |= QgsVectorSimplifyMethod::AntialiasingSimplification;
|
||||
}
|
||||
mSettings->setValue( "/qgis/simplifyDrawingHints", ( int ) simplifyHints );
|
||||
mSettings->setValue( "/qgis/simplifyAlgorithm", mSimplifyAlgorithmComboBox->itemData( mSimplifyAlgorithmComboBox->currentIndex() ).toInt() );
|
||||
mSettings->setValue( "/qgis/simplifyDrawingTol", mSimplifyDrawingSpinBox->value() );
|
||||
mSettings->setValue( "/qgis/simplifyLocal", !mSimplifyDrawingAtProvider->isChecked() );
|
||||
mSettings->setValue( "/qgis/simplifyMaxScale", 1.0 / mSimplifyMaximumScaleComboBox->scale() );
|
||||
|
@ -439,6 +439,11 @@ void QgsVectorLayerProperties::syncToLayer()
|
||||
mSimplifyDrawingGroupBox->setEnabled( false );
|
||||
}
|
||||
|
||||
// Default local simplification algorithm
|
||||
mSimplifyAlgorithmComboBox->addItem( tr( "Distance" ), ( int )QgsVectorSimplifyMethod::Distance );
|
||||
mSimplifyAlgorithmComboBox->addItem( tr( "SnapToGrid" ), ( int )QgsVectorSimplifyMethod::SnapToGrid );
|
||||
mSimplifyAlgorithmComboBox->setCurrentIndex( mSimplifyAlgorithmComboBox->findData(( int )simplifyMethod.simplifyAlgorithm() ) );
|
||||
|
||||
QStringList myScalesList = PROJECT_SCALES.split( ',' );
|
||||
myScalesList.append( "1:1" );
|
||||
mSimplifyMaximumScaleComboBox->updateScales( myScalesList );
|
||||
@ -625,6 +630,7 @@ void QgsVectorLayerProperties::apply()
|
||||
}
|
||||
QgsVectorSimplifyMethod simplifyMethod = mLayer->simplifyMethod();
|
||||
simplifyMethod.setSimplifyHints( simplifyHints );
|
||||
simplifyMethod.setSimplifyAlgorithm( static_cast< QgsVectorSimplifyMethod::SimplifyAlgorithm >( mSimplifyAlgorithmComboBox->itemData( mSimplifyAlgorithmComboBox->currentIndex() ).toInt() ) );
|
||||
simplifyMethod.setThreshold( mSimplifyDrawingSpinBox->value() );
|
||||
simplifyMethod.setForceLocalOptimization( !mSimplifyDrawingAtProvider->isChecked() );
|
||||
simplifyMethod.setMaximumScale( 1.0 / mSimplifyMaximumScaleComboBox->scale() );
|
||||
|
@ -33,10 +33,11 @@ const QgsConstWkbPtr &QgsConstWkbSimplifierPtr::operator>>( QPolygonF &points )
|
||||
if ( mSimplifyMethod.simplifyHints() != QgsVectorSimplifyMethod::NoSimplification && mSimplifyMethod.forceLocalOptimization() )
|
||||
{
|
||||
int simplifyHints = mSimplifyMethod.simplifyHints() | QgsMapToPixelSimplifier::SimplifyEnvelope;
|
||||
QgsMapToPixelSimplifier::SimplifyAlgorithm simplifyAlgorithm = static_cast< QgsMapToPixelSimplifier::SimplifyAlgorithm >( mSimplifyMethod.simplifyAlgorithm() );
|
||||
|
||||
QgsConstWkbPtr wkbPtr = *this;
|
||||
|
||||
if ( QgsMapToPixelSimplifier::simplifyPoints( mWkbType, wkbPtr, points, simplifyHints, mSimplifyMethod.tolerance() ) )
|
||||
if ( QgsMapToPixelSimplifier::simplifyPoints( mWkbType, wkbPtr, points, simplifyHints, mSimplifyMethod.tolerance(), simplifyAlgorithm ) )
|
||||
{
|
||||
mP = const_cast< unsigned char * >(( const unsigned char * ) wkbPtr );
|
||||
return *this;
|
||||
|
@ -21,9 +21,10 @@
|
||||
#include "qgslogger.h"
|
||||
|
||||
|
||||
QgsMapToPixelSimplifier::QgsMapToPixelSimplifier( int simplifyFlags, double tolerance )
|
||||
QgsMapToPixelSimplifier::QgsMapToPixelSimplifier( int simplifyFlags, double tolerance, SimplifyAlgorithm simplifyAlgorithm )
|
||||
: mSimplifyFlags( simplifyFlags )
|
||||
, mTolerance( tolerance )
|
||||
, mSimplifyAlgorithm( simplifyAlgorithm )
|
||||
{
|
||||
}
|
||||
|
||||
@ -40,7 +41,22 @@ float QgsMapToPixelSimplifier::calculateLengthSquared2D( double x1, double y1, d
|
||||
float vx = static_cast< float >( x2 - x1 );
|
||||
float vy = static_cast< float >( y2 - y1 );
|
||||
|
||||
return vx*vx + vy*vy;
|
||||
return ( vx * vx ) + ( vy * vy );
|
||||
}
|
||||
|
||||
|
||||
//! Returns whether the points belong to the same grid
|
||||
bool QgsMapToPixelSimplifier::equalSnapToGrid( double x1, double y1, double x2, double y2, double gridOriginX, double gridOriginY, float gridInverseSizeXY )
|
||||
{
|
||||
int grid_x1 = qRound(( x1 - gridOriginX ) * gridInverseSizeXY );
|
||||
int grid_x2 = qRound(( x2 - gridOriginX ) * gridInverseSizeXY );
|
||||
if ( grid_x1 != grid_x2 ) return false;
|
||||
|
||||
int grid_y1 = qRound(( y1 - gridOriginY ) * gridInverseSizeXY );
|
||||
int grid_y2 = qRound(( y2 - gridOriginY ) * gridInverseSizeXY );
|
||||
if ( grid_y1 != grid_y2 ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Returns the BBOX of the specified WKB-point stream
|
||||
@ -122,7 +138,9 @@ static bool generalizeWkbGeometryByBoundingBox(
|
||||
|
||||
//! Simplify the WKB-geometry using the specified tolerance
|
||||
bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
int simplifyFlags, QGis::WkbType wkbType,
|
||||
int simplifyFlags,
|
||||
SimplifyAlgorithm simplifyAlgorithm,
|
||||
QGis::WkbType wkbType,
|
||||
QgsConstWkbPtr sourceWkbPtr,
|
||||
QgsWkbPtr targetWkbPtr,
|
||||
int &targetWkbSize,
|
||||
@ -184,8 +202,6 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
targetWkbPtr << numTargetPoints;
|
||||
targetWkbSize += 4;
|
||||
|
||||
map2pixelTol *= map2pixelTol; //-> Use mappixelTol for 'LengthSquare' calculations.
|
||||
|
||||
bool isLongSegment;
|
||||
bool hasLongSegments = false; //-> To avoid replace the simplified geometry by its BBOX when there are 'long' segments.
|
||||
bool badLuck = false;
|
||||
@ -205,27 +221,59 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
}
|
||||
|
||||
// Process each vertex...
|
||||
for ( int i = 0; i < numPoints; ++i )
|
||||
if ( simplifyAlgorithm == SnapToGrid )
|
||||
{
|
||||
sourceWkbPtr >> x >> y;
|
||||
sourceWkbPtr += skipZM;
|
||||
double gridOriginX = envelope.xMinimum();
|
||||
double gridOriginY = envelope.yMinimum();
|
||||
|
||||
isLongSegment = false;
|
||||
// Use a factor for the maximum displacement distance for simplification, similar as GeoServer does
|
||||
float gridInverseSizeXY = map2pixelTol != 0 ? ( float )( 1.0f / ( 0.8 * map2pixelTol ) ) : 0.0f;
|
||||
|
||||
if ( i == 0 ||
|
||||
!isGeneralizable ||
|
||||
( isLongSegment = ( calculateLengthSquared2D( x, y, lastX, lastY ) > map2pixelTol ) ) ||
|
||||
( !isaLinearRing && ( i == 1 || i >= numPoints - 2 ) ) )
|
||||
for ( int i = 0; i < numPoints; ++i )
|
||||
{
|
||||
targetWkbPtr << x << y;
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
numTargetPoints++;
|
||||
sourceWkbPtr >> x >> y;
|
||||
sourceWkbPtr += skipZM;
|
||||
|
||||
hasLongSegments |= isLongSegment;
|
||||
if ( i == 0 ||
|
||||
!isGeneralizable ||
|
||||
!equalSnapToGrid( x, y, lastX, lastY, gridOriginX, gridOriginY, gridInverseSizeXY ) ||
|
||||
( !isaLinearRing && ( i == 1 || i >= numPoints - 2 ) ) )
|
||||
{
|
||||
targetWkbPtr << x << y;
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
numTargetPoints++;
|
||||
}
|
||||
|
||||
r.combineExtentWith( x, y );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
map2pixelTol *= map2pixelTol; //-> Use mappixelTol for 'LengthSquare' calculations.
|
||||
|
||||
r.combineExtentWith( x, y );
|
||||
for ( int i = 0; i < numPoints; ++i )
|
||||
{
|
||||
sourceWkbPtr >> x >> y;
|
||||
sourceWkbPtr += skipZM;
|
||||
|
||||
isLongSegment = false;
|
||||
|
||||
if ( i == 0 ||
|
||||
!isGeneralizable ||
|
||||
( isLongSegment = ( calculateLengthSquared2D( x, y, lastX, lastY ) > map2pixelTol ) ) ||
|
||||
( !isaLinearRing && ( i == 1 || i >= numPoints - 2 ) ) )
|
||||
{
|
||||
targetWkbPtr << x << y;
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
numTargetPoints++;
|
||||
|
||||
hasLongSegments |= isLongSegment;
|
||||
}
|
||||
|
||||
r.combineExtentWith( x, y );
|
||||
}
|
||||
}
|
||||
|
||||
QgsWkbPtr nextPointPtr( targetWkbPtr );
|
||||
@ -296,7 +344,7 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
int sourceWkbSize_i = sizeof( int ) + numPoints_i * QGis::wkbDimensions( wkbType ) * sizeof( double );
|
||||
int targetWkbSize_i = 0;
|
||||
|
||||
result |= simplifyWkbGeometry( simplifyFlags, wkbType, sourceWkbPtr, targetWkbPtr, targetWkbSize_i, envelope_i, map2pixelTol, false, true );
|
||||
result |= simplifyWkbGeometry( simplifyFlags, simplifyAlgorithm, wkbType, sourceWkbPtr, targetWkbPtr, targetWkbSize_i, envelope_i, map2pixelTol, false, true );
|
||||
sourceWkbPtr += sourceWkbSize_i;
|
||||
targetWkbPtr += targetWkbSize_i;
|
||||
|
||||
@ -347,7 +395,7 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
|
||||
sourceWkbPtr2 += wkbSize_i;
|
||||
}
|
||||
}
|
||||
result |= simplifyWkbGeometry( simplifyFlags, QGis::singleType( wkbType ), sourceWkbPtr, targetWkbPtr, targetWkbSize_i, envelope, map2pixelTol, true, false );
|
||||
result |= simplifyWkbGeometry( simplifyFlags, simplifyAlgorithm, QGis::singleType( wkbType ), sourceWkbPtr, targetWkbPtr, targetWkbSize_i, envelope, map2pixelTol, true, false );
|
||||
sourceWkbPtr += sourceWkbSize_i;
|
||||
targetWkbPtr += targetWkbSize_i;
|
||||
|
||||
@ -376,13 +424,13 @@ QgsGeometry* QgsMapToPixelSimplifier::simplify( QgsGeometry* geometry ) const
|
||||
unsigned char* wkb = new unsigned char[ wkbSize ];
|
||||
memcpy( wkb, geometry->asWkb(), wkbSize );
|
||||
g->fromWkb( wkb, wkbSize );
|
||||
simplifyGeometry( g, mSimplifyFlags, mTolerance );
|
||||
simplifyGeometry( g, mSimplifyFlags, mTolerance, mSimplifyAlgorithm );
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
//! Simplifies the geometry (Removing duplicated points) when is applied the specified map2pixel context
|
||||
bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry *geometry, int simplifyFlags, double tolerance )
|
||||
bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry *geometry, int simplifyFlags, double tolerance, SimplifyAlgorithm simplifyAlgorithm )
|
||||
{
|
||||
int finalWkbSize = 0;
|
||||
|
||||
@ -402,7 +450,7 @@ bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry *geometry, int simpl
|
||||
|
||||
try
|
||||
{
|
||||
if ( simplifyWkbGeometry( simplifyFlags, wkbType, wkbPtr, targetWkbPtr, finalWkbSize, envelope, tolerance ) )
|
||||
if ( simplifyWkbGeometry( simplifyFlags, simplifyAlgorithm, wkbType, wkbPtr, targetWkbPtr, finalWkbSize, envelope, tolerance ) )
|
||||
{
|
||||
unsigned char *finalWkb = new unsigned char[finalWkbSize];
|
||||
memcpy( finalWkb, targetWkb, finalWkbSize );
|
||||
@ -423,11 +471,11 @@ bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry *geometry, int simpl
|
||||
//! Simplifies the geometry (Removing duplicated points) when is applied the specified map2pixel context
|
||||
bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry* geometry ) const
|
||||
{
|
||||
return simplifyGeometry( geometry, mSimplifyFlags, mTolerance );
|
||||
return simplifyGeometry( geometry, mSimplifyFlags, mTolerance, mSimplifyAlgorithm );
|
||||
}
|
||||
|
||||
//! Simplifies the WKB-point array (Removing duplicated points) when is applied the specified map2pixel context
|
||||
bool QgsMapToPixelSimplifier::simplifyPoints( QgsWKBTypes::Type wkbType, QgsConstWkbPtr& sourceWkbPtr, QPolygonF& targetPoints, int simplifyFlags, double tolerance )
|
||||
bool QgsMapToPixelSimplifier::simplifyPoints( QgsWKBTypes::Type wkbType, QgsConstWkbPtr& sourceWkbPtr, QPolygonF& targetPoints, int simplifyFlags, double tolerance, SimplifyAlgorithm simplifyAlgorithm )
|
||||
{
|
||||
QgsWKBTypes::Type singleType = QgsWKBTypes::singleType( wkbType );
|
||||
QgsWKBTypes::Type flatType = QgsWKBTypes::flatType( singleType );
|
||||
@ -457,7 +505,7 @@ bool QgsMapToPixelSimplifier::simplifyPoints( QgsWKBTypes::Type wkbType, QgsCons
|
||||
targetWkbPtr << ( char ) QgsApplication::endian() << flatType;
|
||||
targetWkbSize = 5;
|
||||
|
||||
if ( simplifyWkbGeometry( simplifyFlags, QGis::fromNewWkbType( singleType ), sourceWkbPtr, targetWkbPtr, targetWkbSize, envelope, tolerance, false, isaLinearRing ) )
|
||||
if ( simplifyWkbGeometry( simplifyFlags, simplifyAlgorithm, QGis::fromNewWkbType( singleType ), sourceWkbPtr, targetWkbPtr, targetWkbSize, envelope, tolerance, false, isaLinearRing ) )
|
||||
{
|
||||
QgsConstWkbPtr finalWkbPtr( targetWkb, targetWkbSize );
|
||||
finalWkbPtr.readHeader();
|
||||
@ -481,5 +529,5 @@ bool QgsMapToPixelSimplifier::simplifyPoints( QgsWKBTypes::Type wkbType, QgsCons
|
||||
//! Simplifies the specified WKB-point array
|
||||
bool QgsMapToPixelSimplifier::simplifyPoints( QgsWKBTypes::Type wkbType, QgsConstWkbPtr& sourceWkbPtr, QPolygonF& targetPoints ) const
|
||||
{
|
||||
return simplifyPoints( wkbType, sourceWkbPtr, targetPoints, mSimplifyFlags, mTolerance );
|
||||
return simplifyPoints( wkbType, sourceWkbPtr, targetPoints, mSimplifyFlags, mTolerance, mSimplifyAlgorithm );
|
||||
}
|
||||
|
@ -32,7 +32,14 @@
|
||||
class CORE_EXPORT QgsMapToPixelSimplifier : public QgsAbstractGeometrySimplifier
|
||||
{
|
||||
public:
|
||||
QgsMapToPixelSimplifier( int simplifyFlags, double tolerance );
|
||||
//! Types of simplification algorithms that can be used
|
||||
enum SimplifyAlgorithm
|
||||
{
|
||||
Distance = 0, //!< The simplification uses the distance between points to remove duplicate points
|
||||
SnapToGrid = 1, //!< The simplification uses a grid (similar to ST_SnapToGrid) to remove duplicate points
|
||||
};
|
||||
|
||||
QgsMapToPixelSimplifier( int simplifyFlags, double tolerance, SimplifyAlgorithm simplifyAlgorithm = Distance );
|
||||
virtual ~QgsMapToPixelSimplifier();
|
||||
|
||||
//! Applicable simplification flags
|
||||
@ -45,22 +52,31 @@ class CORE_EXPORT QgsMapToPixelSimplifier : public QgsAbstractGeometrySimplifier
|
||||
|
||||
private:
|
||||
//! Simplify the WKB-geometry using the specified tolerance
|
||||
static bool simplifyWkbGeometry( int simplifyFlags, QGis::WkbType wkbType, QgsConstWkbPtr sourceWkbPtr, QgsWkbPtr targetWkbPtr, int &targetWkbSize, const QgsRectangle& envelope, double map2pixelTol, bool writeHeader = true, bool isaLinearRing = false );
|
||||
static bool simplifyWkbGeometry( int simplifyFlags, SimplifyAlgorithm simplifyAlgorithm, QGis::WkbType wkbType, QgsConstWkbPtr sourceWkbPtr, QgsWkbPtr targetWkbPtr, int &targetWkbSize, const QgsRectangle& envelope, double map2pixelTol, bool writeHeader = true, bool isaLinearRing = false );
|
||||
|
||||
protected:
|
||||
//! Current simplification flags
|
||||
int mSimplifyFlags;
|
||||
|
||||
//! Current algorithm
|
||||
SimplifyAlgorithm mSimplifyAlgorithm;
|
||||
|
||||
//! Distance tolerance for the simplification
|
||||
double mTolerance;
|
||||
|
||||
//! Returns the squared 2D-distance of the vector defined by the two points specified
|
||||
static float calculateLengthSquared2D( double x1, double y1, double x2, double y2 );
|
||||
|
||||
//! Returns whether the points belong to the same grid
|
||||
static bool equalSnapToGrid( double x1, double y1, double x2, double y2, double gridOriginX, double gridOriginY, float gridInverseSizeXY );
|
||||
|
||||
public:
|
||||
int simplifyFlags() const { return mSimplifyFlags; }
|
||||
void setSimplifyFlags( int simplifyFlags ) { mSimplifyFlags = simplifyFlags; }
|
||||
|
||||
SimplifyAlgorithm simplifyAlgorithm() const { return mSimplifyAlgorithm; }
|
||||
void setSimplifyAlgorithm( SimplifyAlgorithm simplifyAlgorithm ) { mSimplifyAlgorithm = simplifyAlgorithm; }
|
||||
|
||||
//! Returns a simplified version the specified geometry
|
||||
virtual QgsGeometry* simplify( QgsGeometry* geometry ) const override;
|
||||
//! Simplifies the specified geometry
|
||||
@ -82,10 +98,10 @@ class CORE_EXPORT QgsMapToPixelSimplifier : public QgsAbstractGeometrySimplifier
|
||||
}
|
||||
|
||||
//! Simplifies the geometry when is applied the specified map2pixel context
|
||||
static bool simplifyGeometry( QgsGeometry* geometry, int simplifyFlags, double tolerance );
|
||||
static bool simplifyGeometry( QgsGeometry* geometry, int simplifyFlags, double tolerance, SimplifyAlgorithm simplifyAlgorithm = Distance );
|
||||
|
||||
//! Simplifies the WKB-point array when is applied the specified map2pixel context
|
||||
static bool simplifyPoints( QgsWKBTypes::Type wkbType, QgsConstWkbPtr& sourceWkbPtr, QPolygonF& targetPoints, int simplifyFlags, double tolerance );
|
||||
static bool simplifyPoints( QgsWKBTypes::Type wkbType, QgsConstWkbPtr& sourceWkbPtr, QPolygonF& targetPoints, int simplifyFlags, double tolerance, SimplifyAlgorithm simplifyAlgorithm = Distance );
|
||||
};
|
||||
|
||||
#endif // QGSMAPTOPIXELGEOMETRYSIMPLIFIER_H
|
||||
|
@ -2429,9 +2429,10 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &cont
|
||||
if ( simplifyMethod.simplifyHints() != QgsVectorSimplifyMethod::NoSimplification && simplifyMethod.forceLocalOptimization() )
|
||||
{
|
||||
int simplifyHints = simplifyMethod.simplifyHints() | QgsMapToPixelSimplifier::SimplifyEnvelope;
|
||||
QgsMapToPixelSimplifier::SimplifyAlgorithm simplifyAlgorithm = static_cast< QgsMapToPixelSimplifier::SimplifyAlgorithm >( simplifyMethod.simplifyAlgorithm() );
|
||||
QgsGeometry* g = new QgsGeometry( *geom );
|
||||
|
||||
if ( QgsMapToPixelSimplifier::simplifyGeometry( g, simplifyHints, simplifyMethod.tolerance() ) )
|
||||
if ( QgsMapToPixelSimplifier::simplifyGeometry( g, simplifyHints, simplifyMethod.tolerance(), simplifyAlgorithm ) )
|
||||
{
|
||||
geom = g;
|
||||
scopedClonedGeom.reset( g );
|
||||
@ -3008,9 +3009,10 @@ void QgsPalLayerSettings::registerObstacleFeature( QgsFeature& f, QgsRenderConte
|
||||
if ( simplifyMethod.simplifyHints() != QgsVectorSimplifyMethod::NoSimplification && simplifyMethod.forceLocalOptimization() )
|
||||
{
|
||||
int simplifyHints = simplifyMethod.simplifyHints() | QgsMapToPixelSimplifier::SimplifyEnvelope;
|
||||
QgsMapToPixelSimplifier::SimplifyAlgorithm simplifyAlgorithm = static_cast< QgsMapToPixelSimplifier::SimplifyAlgorithm >( simplifyMethod.simplifyAlgorithm() );
|
||||
QgsGeometry* g = new QgsGeometry( *geom );
|
||||
|
||||
if ( QgsMapToPixelSimplifier::simplifyGeometry( g, simplifyHints, simplifyMethod.tolerance() ) )
|
||||
if ( QgsMapToPixelSimplifier::simplifyGeometry( g, simplifyHints, simplifyMethod.tolerance(), simplifyAlgorithm ) )
|
||||
{
|
||||
geom = g;
|
||||
scopedClonedGeom.reset( g );
|
||||
|
@ -49,7 +49,7 @@ QgsAbstractGeometrySimplifier* QgsSimplifyMethod::createGeometrySimplifier( cons
|
||||
if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
|
||||
{
|
||||
int simplifyFlags = QgsMapToPixelSimplifier::SimplifyGeometry | QgsMapToPixelSimplifier::SimplifyEnvelope;
|
||||
return new QgsMapToPixelSimplifier( simplifyFlags, simplifyMethod.tolerance() );
|
||||
return new QgsMapToPixelSimplifier( simplifyFlags, simplifyMethod.tolerance(), QgsMapToPixelSimplifier::Distance );
|
||||
}
|
||||
else if ( methodType == QgsSimplifyMethod::PreserveTopology )
|
||||
{
|
||||
|
@ -165,6 +165,7 @@ QgsVectorLayer::QgsVectorLayer( const QString& vectorLayerPath,
|
||||
// Default simplify drawing settings
|
||||
QSettings settings;
|
||||
mSimplifyMethod.setSimplifyHints( static_cast< QgsVectorSimplifyMethod::SimplifyHints >( settings.value( "/qgis/simplifyDrawingHints", static_cast< int>( mSimplifyMethod.simplifyHints() ) ).toInt() ) );
|
||||
mSimplifyMethod.setSimplifyAlgorithm( static_cast< QgsVectorSimplifyMethod::SimplifyAlgorithm >( settings.value( "/qgis/simplifyAlgorithm", static_cast< int>( mSimplifyMethod.simplifyAlgorithm() ) ).toInt() ) );
|
||||
mSimplifyMethod.setThreshold( settings.value( "/qgis/simplifyDrawingTol", mSimplifyMethod.threshold() ).toFloat() );
|
||||
mSimplifyMethod.setForceLocalOptimization( settings.value( "/qgis/simplifyLocal", mSimplifyMethod.forceLocalOptimization() ).toBool() );
|
||||
mSimplifyMethod.setMaximumScale( settings.value( "/qgis/simplifyMaxScale", mSimplifyMethod.maximumScale() ).toFloat() );
|
||||
@ -2033,6 +2034,7 @@ bool QgsVectorLayer::readStyle( const QDomNode &node, QString &errorMessage )
|
||||
|
||||
// get the simplification drawing settings
|
||||
mSimplifyMethod.setSimplifyHints( static_cast< QgsVectorSimplifyMethod::SimplifyHints >( e.attribute( "simplifyDrawingHints", "1" ).toInt() ) );
|
||||
mSimplifyMethod.setSimplifyAlgorithm( static_cast< QgsVectorSimplifyMethod::SimplifyAlgorithm >( e.attribute( "simplifyAlgorithm", "0" ).toInt() ) );
|
||||
mSimplifyMethod.setThreshold( e.attribute( "simplifyDrawingTol", "1" ).toFloat() );
|
||||
mSimplifyMethod.setForceLocalOptimization( e.attribute( "simplifyLocal", "1" ).toInt() );
|
||||
mSimplifyMethod.setMaximumScale( e.attribute( "simplifyMaxScale", "1" ).toFloat() );
|
||||
@ -2189,6 +2191,7 @@ bool QgsVectorLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &err
|
||||
|
||||
// save the simplification drawing settings
|
||||
mapLayerNode.setAttribute( "simplifyDrawingHints", QString::number( mSimplifyMethod.simplifyHints() ) );
|
||||
mapLayerNode.setAttribute( "simplifyAlgorithm", QString::number( mSimplifyMethod.simplifyAlgorithm() ) );
|
||||
mapLayerNode.setAttribute( "simplifyDrawingTol", QString::number( mSimplifyMethod.threshold() ) );
|
||||
mapLayerNode.setAttribute( "simplifyLocal", mSimplifyMethod.forceLocalOptimization() ? 1 : 0 );
|
||||
mapLayerNode.setAttribute( "simplifyMaxScale", QString::number( mSimplifyMethod.maximumScale() ) );
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
QgsVectorSimplifyMethod::QgsVectorSimplifyMethod()
|
||||
: mSimplifyHints( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD > 1 ? QgsVectorSimplifyMethod::FullSimplification : QgsVectorSimplifyMethod::GeometrySimplification )
|
||||
, mSimplifyAlgorithm( QgsVectorSimplifyMethod::Distance )
|
||||
, mThreshold( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
|
||||
, mTolerance( 1 )
|
||||
, mLocalOptimization( true )
|
||||
|
@ -42,6 +42,18 @@ class CORE_EXPORT QgsVectorSimplifyMethod
|
||||
/** Gets the simplification hints of the vector layer managed */
|
||||
inline SimplifyHints simplifyHints() const { return mSimplifyHints; }
|
||||
|
||||
/** Types of local simplification algorithms that can be used */
|
||||
enum SimplifyAlgorithm
|
||||
{
|
||||
Distance = 0, //!< The simplification uses the distance between points to remove duplicate points
|
||||
SnapToGrid = 1, //!< The simplification uses a grid (similar to ST_SnapToGrid) to remove duplicate points
|
||||
};
|
||||
|
||||
/** Sets the local simplification algorithm of the vector layer managed */
|
||||
void setSimplifyAlgorithm( const SimplifyAlgorithm& simplifyAlgorithm ) { mSimplifyAlgorithm = simplifyAlgorithm; }
|
||||
/** Gets the local simplification algorithm of the vector layer managed */
|
||||
inline SimplifyAlgorithm simplifyAlgorithm() const { return mSimplifyAlgorithm; }
|
||||
|
||||
/** Sets the tolerance of simplification in map units. Represents the maximum distance in map units between two coordinates which can be considered equal */
|
||||
void setTolerance( double tolerance ) { mTolerance = tolerance; }
|
||||
/** Gets the tolerance of simplification in map units. Represents the maximum distance in map units between two coordinates which can be considered equal */
|
||||
@ -65,6 +77,8 @@ class CORE_EXPORT QgsVectorSimplifyMethod
|
||||
private:
|
||||
/** Simplification hints for fast rendering of features of the vector layer managed */
|
||||
SimplifyHints mSimplifyHints;
|
||||
/** Simplification algorithm */
|
||||
SimplifyAlgorithm mSimplifyAlgorithm;
|
||||
/** Simplification tolerance, it represents the maximum distance between two coordinates which can be considered equal */
|
||||
double mTolerance;
|
||||
/** Simplification threshold */
|
||||
|
@ -1961,14 +1961,30 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="4">
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="mSimplifyAlgorithmLabel">
|
||||
<property name="text">
|
||||
<string>Simplification algorithm: </string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>This algorithm only is applied to simplify on local side</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QComboBox" name="mSimplifyAlgorithmComboBox"/>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="4">
|
||||
<widget class="QCheckBox" name="mSimplifyDrawingAtProvider">
|
||||
<property name="text">
|
||||
<string>Simplify on provider side if possible</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="mSimplifyMaxScaleLabel">
|
||||
<property name="text">
|
||||
<string>Maximum scale at which the layer should be simplified (1:1 always simplifies): </string>
|
||||
@ -1978,7 +1994,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<item row="4" column="2">
|
||||
<widget class="QgsScaleComboBox" name="mSimplifyMaximumScaleComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@ -5296,6 +5312,7 @@
|
||||
<tabstop>spinMapUpdateInterval</tabstop>
|
||||
<tabstop>mSimplifyDrawingGroupBox</tabstop>
|
||||
<tabstop>mSimplifyDrawingSpinBox</tabstop>
|
||||
<tabstop>mSimplifyAlgorithmComboBox</tabstop>
|
||||
<tabstop>mSimplifyDrawingAtProvider</tabstop>
|
||||
<tabstop>mSimplifyMaximumScaleComboBox</tabstop>
|
||||
<tabstop>chkAntiAliasing</tabstop>
|
||||
|
@ -802,14 +802,30 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="4">
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="mSimplifyAlgorithmLabel">
|
||||
<property name="text">
|
||||
<string>Simplification algorithm: </string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>This algorithm only is applied to simplify on local side</string>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QComboBox" name="mSimplifyAlgorithmComboBox"/>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="4">
|
||||
<widget class="QCheckBox" name="mSimplifyDrawingAtProvider">
|
||||
<property name="text">
|
||||
<string>Simplify on provider side if possible</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="mSimplifyMaxScaleLabel">
|
||||
<property name="text">
|
||||
<string>Maximum scale at which the layer should be simplified (1:1 always simplifies): </string>
|
||||
@ -819,7 +835,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<item row="4" column="2">
|
||||
<widget class="QgsScaleComboBox" name="mSimplifyMaximumScaleComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
@ -1745,6 +1761,7 @@
|
||||
<tabstop>scrollArea_19</tabstop>
|
||||
<tabstop>mSimplifyDrawingGroupBox</tabstop>
|
||||
<tabstop>mSimplifyDrawingSpinBox</tabstop>
|
||||
<tabstop>mSimplifyAlgorithmComboBox</tabstop>
|
||||
<tabstop>mSimplifyDrawingAtProvider</tabstop>
|
||||
<tabstop>mSimplifyMaximumScaleComboBox</tabstop>
|
||||
<tabstop>mForceRasterCheckBox</tabstop>
|
||||
|
Loading…
x
Reference in New Issue
Block a user