Skip to content
Permalink
Browse files

Allow override WkbPtr and define WkbSimplifierPtr class

This commit simplifies the geometry just before to paint it in the
current QPainter device.

This commit allows to override the '>>' operators of the QgsWkbPtr
class. Also, It defines a new QgsWkbSimplifierPtr class to automatically
simplify the input point stream.
  • Loading branch information
ahuarte47 committed Mar 23, 2016
1 parent c4d7981 commit 51f06edbf78885dd7646e15a7e51bff298ae8ba7
@@ -56,5 +56,5 @@ class QgsClipper
@param wkb pointer to the start of the line wkb
@param clipExtent clipping bounds
@param line out: clipped line coordinates*/
static QgsConstWkbPtr clippedLineWKB( QgsConstWkbPtr wkb, const QgsRectangle& clipExtent, QPolygonF& line );
static QgsConstWkbPtr clippedLineWKB( QgsConstWkbPtr& wkb, const QgsRectangle& clipExtent, QPolygonF& line );
};
@@ -29,6 +29,9 @@ class QgsMapToPixelSimplifier : QgsAbstractGeometrySimplifier
//! Simplifies the specified geometry
virtual bool simplifyGeometry( QgsGeometry* geometry ) const;

//! Simplifies the specified WKB-point array
virtual bool simplifyPoints( QgsWKBTypes::Type wkbType, QgsConstWkbPtr& sourceWkbPtr, QPolygonF& targetPoints ) const;

// MapToPixel simplification helper methods
public:

@@ -41,4 +44,7 @@ class QgsMapToPixelSimplifier : QgsAbstractGeometrySimplifier
//! Simplifies the geometry when is applied the specified map2pixel context
static bool simplifyGeometry( QgsGeometry* geometry, int simplifyFlags, double tolerance );

//! 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 );

};
@@ -403,9 +403,9 @@ class QgsFeatureRendererV2
//! render editing vertex marker for a polygon
void renderVertexMarkerPolygon( QPolygonF& pts, QList<QPolygonF>* rings, QgsRenderContext& context );

static QgsConstWkbPtr _getPoint( QPointF& pt, QgsRenderContext& context, QgsConstWkbPtr wkb );
static QgsConstWkbPtr _getLineString( QPolygonF& pts, QgsRenderContext& context, QgsConstWkbPtr wkb, bool clipToExtent = true );
static QgsConstWkbPtr _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, QgsConstWkbPtr wkb, bool clipToExtent = true );
static QgsConstWkbPtr _getPoint( QPointF& pt, QgsRenderContext& context, QgsConstWkbPtr& wkb );
static QgsConstWkbPtr _getLineString( QPolygonF& pts, QgsRenderContext& context, QgsConstWkbPtr& wkb, bool clipToExtent = true );
static QgsConstWkbPtr _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, QgsConstWkbPtr& wkb, bool clipToExtent = true );

void setScaleMethodToSymbol( QgsSymbolV2* symbol, int scaleMethod );

@@ -228,19 +228,19 @@ class QgsSymbolV2
* Creates a point in screen coordinates from a wkb string in map
* coordinates
*/
static QgsConstWkbPtr _getPoint( QPointF& pt, QgsRenderContext& context, QgsConstWkbPtr wkb );
static QgsConstWkbPtr _getPoint( QPointF& pt, QgsRenderContext& context, QgsConstWkbPtr& wkb );

/**
* Creates a line string in screen coordinates from a wkb string in map
* coordinates
*/
static QgsConstWkbPtr _getLineString( QPolygonF& pts, QgsRenderContext& context, QgsConstWkbPtr wkb, bool clipToExtent = true );
static QgsConstWkbPtr _getLineString( QPolygonF& pts, QgsRenderContext& context, QgsConstWkbPtr& wkb, bool clipToExtent = true );

/**
* Creates a polygon in screen coordinates from a wkb string in map
* coordinates
*/
static QgsConstWkbPtr _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, QgsConstWkbPtr wkb, bool clipToExtent = true );
static QgsConstWkbPtr _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, QgsConstWkbPtr& wkb, bool clipToExtent = true );

/**
* Retrieve a cloned list of all layers that make up this symbol.
@@ -352,6 +352,7 @@ SET(QGIS_CORE_SRCS
geometry/qgspolygonv2.cpp
geometry/qgswkbptr.cpp
geometry/qgswkbtypes.cpp
geometry/qgswkbsimplifierptr.cpp

${CMAKE_CURRENT_BINARY_DIR}/qgscontexthelp_texts.cpp
${CMAKE_CURRENT_BINARY_DIR}/qgsexpression_texts.cpp
@@ -836,6 +837,7 @@ SET(QGIS_CORE_HDRS
geometry/qgspointv2.h
geometry/qgswkbptr.h
geometry/qgswkbtypes.h
geometry/qgswkbsimplifierptr.h
)

IF (QT_MOBILITY_LOCATION_FOUND OR Qt5Positioning_FOUND)
@@ -32,6 +32,7 @@ QgsConstWkbPtr::QgsConstWkbPtr( const unsigned char *p, int size )
mP = const_cast< unsigned char * >( p );
mEnd = mP + size;
mEndianSwap = false;
mWkbType = QgsWKBTypes::Unknown;
}

QgsWKBTypes::Type QgsConstWkbPtr::readHeader() const
@@ -45,12 +46,40 @@ QgsWKBTypes::Type QgsConstWkbPtr::readHeader() const

int wkbType;
*this >> wkbType;
mWkbType = static_cast<QgsWKBTypes::Type>( wkbType );

return static_cast<QgsWKBTypes::Type>( wkbType );
return mWkbType;
}

void QgsConstWkbPtr::verifyBound( int size ) const
{
if ( !mP || mP + size > mEnd )
throw QgsWkbException( "wkb access out of bounds" );
}

const QgsConstWkbPtr &QgsConstWkbPtr::operator>>( QPointF &point ) const
{
read( point.rx() );
read( point.ry() );
return *this;
}

const QgsConstWkbPtr &QgsConstWkbPtr::operator>>( QPolygonF &points ) const
{
int skipZM = ( QgsWKBTypes::coordDimensions( mWkbType ) - 2 ) * sizeof( double );
Q_ASSERT( skipZM >= 0 );

unsigned int nPoints;
read( nPoints );

points.resize( nPoints );
QPointF* ptr = points.data();

for ( unsigned int i = 0; i < nPoints; ++i, ++ptr )
{
read( ptr->rx() );
read( ptr->ry() );
mP += skipZM;
}
return *this;
}
@@ -19,6 +19,7 @@
#include "qgsapplication.h"
#include "qgis.h"
#include "qgsexception.h"
#include "qpolygon.h"

/** \ingroup core
* * Custom exception class for Wkb related exceptions.
@@ -89,9 +90,11 @@ class CORE_EXPORT QgsWkbPtr

class CORE_EXPORT QgsConstWkbPtr
{
protected:
mutable unsigned char *mP;
unsigned char *mEnd;
mutable bool mEndianSwap;
mutable QgsWKBTypes::Type mWkbType;

void verifyBound( int size ) const;

@@ -114,6 +117,9 @@ class CORE_EXPORT QgsConstWkbPtr
inline const QgsConstWkbPtr &operator>>( unsigned int &v ) const { read( v ); return *this; }
inline const QgsConstWkbPtr &operator>>( char &v ) const { read( v ); return *this; }

virtual const QgsConstWkbPtr &operator>>( QPointF &point ) const;
virtual const QgsConstWkbPtr &operator>>( QPolygonF &points ) const;

inline void operator+=( int n ) { verifyBound( n ); mP += n; }
inline void operator-=( int n ) { mP -= n; }

@@ -0,0 +1,47 @@
/***************************************************************************
qgswkbsimplifierptr.cpp
---------------------
begin : February 2016
copyright : (C) 2016 by Alvaro Huarte
email : http://wiki.osgeo.org/wiki/Alvaro_Huarte
***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#include "qgswkbsimplifierptr.h"
#include "qgsgeometry.h"
#include "qgssimplifymethod.h"
#include "qgsmaptopixelgeometrysimplifier.h"

QgsConstWkbSimplifierPtr::QgsConstWkbSimplifierPtr( const unsigned char *p, int size, const QgsVectorSimplifyMethod &simplifyMethod )
: QgsConstWkbPtr( p, size )
, mSimplifyMethod( simplifyMethod )
{
}

const QgsConstWkbPtr &QgsConstWkbSimplifierPtr::operator>>( QPointF &point ) const
{
return QgsConstWkbPtr::operator>>( point );
}

const QgsConstWkbPtr &QgsConstWkbSimplifierPtr::operator>>( QPolygonF &points ) const
{
if ( mSimplifyMethod.simplifyHints() != QgsVectorSimplifyMethod::NoSimplification && mSimplifyMethod.forceLocalOptimization() )
{
int simplifyHints = mSimplifyMethod.simplifyHints() | QgsMapToPixelSimplifier::SimplifyEnvelope;

QgsConstWkbPtr wkbPtr = *this;

if ( QgsMapToPixelSimplifier::simplifyPoints( mWkbType, wkbPtr, points, simplifyHints, mSimplifyMethod.tolerance() ) )
{
mP = const_cast< unsigned char * >(( const unsigned char * ) wkbPtr );
return *this;
}
}
QgsConstWkbPtr::operator>>( points );
return *this;
}
@@ -0,0 +1,50 @@
/***************************************************************************
qgswkbsimplifierptr.h
---------------------
begin : February 2016
copyright : (C) 2016 by Alvaro Huarte
email : http://wiki.osgeo.org/wiki/Alvaro_Huarte
***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#ifndef QGSWKBSIMPLIFIERPTR_H
#define QGSWKBSIMPLIFIERPTR_H

#include "qgswkbptr.h"
#include "qgsvectorsimplifymethod.h"

class QgsGeometry;

/** \class QgsConstWkbSimplifierPtr
* \note not available in Python bindings
*/

class CORE_EXPORT QgsConstWkbSimplifierPtr : public QgsConstWkbPtr
{
/** Simplification object which holds the information about how to simplify the features for fast rendering */
const QgsVectorSimplifyMethod& mSimplifyMethod;

public:
QgsConstWkbSimplifierPtr( const unsigned char *p, int size, const QgsVectorSimplifyMethod &simplifyMethod );

inline const QgsConstWkbPtr &operator>>( double &v ) const { return QgsConstWkbPtr::operator>>( v ); }
inline const QgsConstWkbPtr &operator>>( float &r ) const { return QgsConstWkbPtr::operator>>( r ); }
inline const QgsConstWkbPtr &operator>>( int &v ) const { return QgsConstWkbPtr::operator>>( v ); }
inline const QgsConstWkbPtr &operator>>( unsigned int &v ) const { return QgsConstWkbPtr::operator>>( v ); }
inline const QgsConstWkbPtr &operator>>( char &v ) const { return QgsConstWkbPtr::operator>>( v ); }

virtual const QgsConstWkbPtr &operator>>( QPointF &point ) const override;
virtual const QgsConstWkbPtr &operator>>( QPolygonF &points ) const override;

inline void operator+=( int n ) { QgsConstWkbPtr::operator+=( n ); }
inline void operator-=( int n ) { QgsConstWkbPtr::operator-=( n ); }

inline operator const unsigned char *() const { return mP; }
};

#endif // QGSWKBSIMPLIFIERPTR_H
@@ -38,7 +38,7 @@ const double QgsClipper::MIN_Y = -16000;

const double QgsClipper::SMALL_NUM = 1e-12;

QgsConstWkbPtr QgsClipper::clippedLineWKB( QgsConstWkbPtr wkbPtr, const QgsRectangle& clipExtent, QPolygonF& line )
QgsConstWkbPtr QgsClipper::clippedLineWKB( QgsConstWkbPtr& wkbPtr, const QgsRectangle& clipExtent, QPolygonF& line )
{
QgsWKBTypes::Type wkbType = wkbPtr.readHeader();

@@ -57,24 +57,31 @@ QgsConstWkbPtr QgsClipper::clippedLineWKB( QgsConstWkbPtr wkbPtr, const QgsRecta
double p1x_c, p1y_c; //clipped end coordinates
double lastClipX = 0.0, lastClipY = 0.0; //last successfully clipped coords

QPolygonF pts;
wkbPtr -= sizeof( unsigned int );
wkbPtr >> pts;
nPoints = pts.size();

line.clear();
line.reserve( nPoints + 1 );

for ( int i = 0; i < nPoints; ++i )
QPointF *ptr = pts.data();

for ( int i = 0; i < nPoints; ++i, ++ptr )
{
if ( i == 0 )
{
wkbPtr >> p1x >> p1y;
wkbPtr += skipZM;
p1x = ptr->rx();
p1y = ptr->ry();
continue;
}
else
{
p0x = p1x;
p0y = p1y;

wkbPtr >> p1x >> p1y;
wkbPtr += skipZM;
p1x = ptr->rx();
p1y = ptr->ry();

p1x_c = p1x;
p1y_c = p1y;
@@ -87,7 +87,7 @@ class CORE_EXPORT QgsClipper
@param wkb pointer to the start of the line wkb
@param clipExtent clipping bounds
@param line out: clipped line coordinates*/
static QgsConstWkbPtr clippedLineWKB( QgsConstWkbPtr wkb, const QgsRectangle& clipExtent, QPolygonF& line );
static QgsConstWkbPtr clippedLineWKB( QgsConstWkbPtr& wkb, const QgsRectangle& clipExtent, QPolygonF& line );

private:

0 comments on commit 51f06ed

Please sign in to comment.
You can’t perform that action at this time.