mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-15 00:02:52 -04:00
Add QgsAbstractGeometry::simplifiedTypeRef
Returns a reference to the simplest lossless representation of this geometry, e.g. if the geometry is a multipart geometry type with a single member geometry, a reference to that part will be returned. This method employs the following logic: - For multipart geometries containing a single part only a direct reference to that part will be returned. - For compound curve geometries containing a single curve only a direct reference to that curve will be returned. This method returns a reference only, and does not involve any geometry cloning.
This commit is contained in:
parent
44a2482f36
commit
0d768faa43
@ -719,6 +719,22 @@ Converts the geometry to a specified type.
|
||||
:return: ``True`` if conversion was successful
|
||||
|
||||
.. versionadded:: 2.14
|
||||
%End
|
||||
|
||||
virtual const QgsAbstractGeometry *simplifiedTypeRef() const /HoldGIL/;
|
||||
%Docstring
|
||||
Returns a reference to the simplest lossless representation of this geometry,
|
||||
e.g. if the geometry is a multipart geometry type with a single member geometry,
|
||||
a reference to that part will be returned.
|
||||
|
||||
This method employs the following logic:
|
||||
|
||||
- For multipart geometries containing a single part only a direct reference to that part will be returned.
|
||||
- For compound curve geometries containing a single curve only a direct reference to that curve will be returned.
|
||||
|
||||
This method returns a reference only, and does not involve any geometry cloning.
|
||||
|
||||
.. versionadded:: 3.20
|
||||
%End
|
||||
|
||||
virtual bool isValid( QString &error /Out/, int flags = 0 ) const = 0;
|
||||
|
@ -85,6 +85,8 @@ of the curve.
|
||||
|
||||
virtual bool boundingBoxIntersects( const QgsRectangle &rectangle ) const /HoldGIL/;
|
||||
|
||||
virtual const QgsAbstractGeometry *simplifiedTypeRef() const /HoldGIL/;
|
||||
|
||||
|
||||
int nCurves() const /HoldGIL/;
|
||||
%Docstring
|
||||
|
@ -245,6 +245,8 @@ Returns a geometry without curves. Caller takes ownership
|
||||
|
||||
virtual QgsGeometryCollection *toCurveType() const /Factory/;
|
||||
|
||||
virtual const QgsAbstractGeometry *simplifiedTypeRef() const /HoldGIL/;
|
||||
|
||||
|
||||
virtual bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = 0 );
|
||||
|
||||
|
@ -105,12 +105,14 @@ void QgsBufferedLine3DSymbolHandler::processFeature( const QgsFeature &f, const
|
||||
LineData &out = mSelectedIds.contains( f.id() ) ? outSelected : outNormal;
|
||||
|
||||
QgsGeometry geom = f.geometry();
|
||||
const QgsAbstractGeometry *g = geom.constGet()->simplifiedTypeRef();
|
||||
|
||||
// segmentize curved geometries if necessary
|
||||
if ( QgsWkbTypes::isCurvedType( geom.constGet()->wkbType() ) )
|
||||
geom = QgsGeometry( geom.constGet()->segmentize() );
|
||||
|
||||
const QgsAbstractGeometry *g = geom.constGet();
|
||||
if ( QgsWkbTypes::isCurvedType( g->wkbType() ) )
|
||||
{
|
||||
geom = QgsGeometry( g->segmentize() );
|
||||
g = geom.constGet()->simplifiedTypeRef();
|
||||
}
|
||||
|
||||
// TODO: configurable
|
||||
const int nSegments = 4;
|
||||
@ -375,11 +377,14 @@ void QgsThickLine3DSymbolHandler::processFeature( const QgsFeature &f, const Qgs
|
||||
QgsLineVertexData &out = mSelectedIds.contains( f.id() ) ? outSelected : outNormal;
|
||||
|
||||
QgsGeometry geom = f.geometry();
|
||||
// segmentize curved geometries if necessary
|
||||
if ( QgsWkbTypes::isCurvedType( geom.constGet()->wkbType() ) )
|
||||
geom = QgsGeometry( geom.constGet()->segmentize() );
|
||||
const QgsAbstractGeometry *g = geom.constGet()->simplifiedTypeRef();
|
||||
|
||||
const QgsAbstractGeometry *g = geom.constGet();
|
||||
// segmentize curved geometries if necessary
|
||||
if ( QgsWkbTypes::isCurvedType( g->wkbType() ) )
|
||||
{
|
||||
geom = QgsGeometry( g->segmentize() );
|
||||
g = geom.constGet()->simplifiedTypeRef();
|
||||
}
|
||||
|
||||
if ( const QgsLineString *ls = qgsgeometry_cast<const QgsLineString *>( g ) )
|
||||
{
|
||||
|
@ -163,12 +163,14 @@ void QgsPolygon3DSymbolHandler::processFeature( const QgsFeature &f, const Qgs3D
|
||||
PolygonData &out = mSelectedIds.contains( f.id() ) ? outSelected : outNormal;
|
||||
|
||||
QgsGeometry geom = f.geometry();
|
||||
const QgsAbstractGeometry *g = geom.constGet()->simplifiedTypeRef();
|
||||
|
||||
// segmentize curved geometries if necessary
|
||||
if ( QgsWkbTypes::isCurvedType( geom.constGet()->wkbType() ) )
|
||||
geom = QgsGeometry( geom.constGet()->segmentize() );
|
||||
|
||||
const QgsAbstractGeometry *g = geom.constGet();
|
||||
if ( QgsWkbTypes::isCurvedType( g->wkbType() ) )
|
||||
{
|
||||
geom = QgsGeometry( g->segmentize() );
|
||||
g = geom.constGet()->simplifiedTypeRef();
|
||||
}
|
||||
|
||||
const QgsPropertyCollection &ddp = mSymbol->dataDefinedProperties();
|
||||
bool hasDDHeight = ddp.isActive( QgsAbstract3DSymbol::PropertyHeight );
|
||||
|
@ -280,6 +280,11 @@ bool QgsAbstractGeometry::convertTo( QgsWkbTypes::Type type )
|
||||
return true;
|
||||
}
|
||||
|
||||
const QgsAbstractGeometry *QgsAbstractGeometry::simplifiedTypeRef() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void QgsAbstractGeometry::filterVertices( const std::function<bool ( const QgsPoint & )> & )
|
||||
{
|
||||
// Ideally this would be pure virtual, but SIP has issues with that
|
||||
|
@ -706,6 +706,22 @@ class CORE_EXPORT QgsAbstractGeometry
|
||||
*/
|
||||
virtual bool convertTo( QgsWkbTypes::Type type );
|
||||
|
||||
/**
|
||||
* Returns a reference to the simplest lossless representation of this geometry,
|
||||
* e.g. if the geometry is a multipart geometry type with a single member geometry,
|
||||
* a reference to that part will be returned.
|
||||
*
|
||||
* This method employs the following logic:
|
||||
*
|
||||
* - For multipart geometries containing a single part only a direct reference to that part will be returned.
|
||||
* - For compound curve geometries containing a single curve only a direct reference to that curve will be returned.
|
||||
*
|
||||
* This method returns a reference only, and does not involve any geometry cloning.
|
||||
*
|
||||
* \since QGIS 3.20
|
||||
*/
|
||||
virtual const QgsAbstractGeometry *simplifiedTypeRef() const SIP_HOLDGIL;
|
||||
|
||||
/**
|
||||
* Checks validity of the geometry, and returns TRUE if the geometry is valid.
|
||||
*
|
||||
|
@ -562,6 +562,14 @@ bool QgsCompoundCurve::boundingBoxIntersects( const QgsRectangle &rectangle ) co
|
||||
return QgsAbstractGeometry::boundingBoxIntersects( rectangle );
|
||||
}
|
||||
|
||||
const QgsAbstractGeometry *QgsCompoundCurve::simplifiedTypeRef() const
|
||||
{
|
||||
if ( mCurves.size() == 1 )
|
||||
return mCurves.at( 0 );
|
||||
else
|
||||
return this;
|
||||
}
|
||||
|
||||
const QgsCurve *QgsCompoundCurve::curveAt( int i ) const
|
||||
{
|
||||
if ( i < 0 || i >= mCurves.size() )
|
||||
|
@ -74,6 +74,7 @@ class CORE_EXPORT QgsCompoundCurve: public QgsCurve
|
||||
QgsCompoundCurve *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY;
|
||||
bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
|
||||
bool boundingBoxIntersects( const QgsRectangle &rectangle ) const override SIP_HOLDGIL;
|
||||
const QgsAbstractGeometry *simplifiedTypeRef() const override SIP_HOLDGIL;
|
||||
|
||||
/**
|
||||
* Returns the number of curves in the geometry.
|
||||
|
@ -1020,6 +1020,14 @@ QgsGeometryCollection *QgsGeometryCollection::toCurveType() const
|
||||
return newCollection.release();
|
||||
}
|
||||
|
||||
const QgsAbstractGeometry *QgsGeometryCollection::simplifiedTypeRef() const
|
||||
{
|
||||
if ( mGeometries.size() == 1 )
|
||||
return mGeometries.at( 0 )->simplifiedTypeRef();
|
||||
else
|
||||
return this;
|
||||
}
|
||||
|
||||
bool QgsGeometryCollection::transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback )
|
||||
{
|
||||
if ( !transformer )
|
||||
|
@ -237,6 +237,7 @@ class CORE_EXPORT QgsGeometryCollection: public QgsAbstractGeometry
|
||||
bool dropMValue() override;
|
||||
void swapXy() override;
|
||||
QgsGeometryCollection *toCurveType() const override SIP_FACTORY;
|
||||
const QgsAbstractGeometry *simplifiedTypeRef() const override SIP_HOLDGIL;
|
||||
|
||||
bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
|
||||
|
||||
|
@ -172,6 +172,9 @@ class TestQgsGeometry : public QObject
|
||||
void normalize_data();
|
||||
void normalize();
|
||||
|
||||
void simplifiedTypeRef_data();
|
||||
void simplifiedTypeRef();
|
||||
|
||||
// MK, Disabled 14.11.2014
|
||||
// Too unclear what exactly should be tested and which variations are allowed for the line
|
||||
#if 0
|
||||
@ -17878,6 +17881,36 @@ void TestQgsGeometry::normalize()
|
||||
QCOMPARE( geom.asWkt( 1 ), expected );
|
||||
}
|
||||
|
||||
|
||||
void TestQgsGeometry::simplifiedTypeRef_data()
|
||||
{
|
||||
QTest::addColumn<QString>( "wkt" );
|
||||
QTest::addColumn<QString>( "expected" );
|
||||
|
||||
QTest::newRow( "point empty" ) << QStringLiteral( "POINT EMPTY" ) << QStringLiteral( "Point EMPTY" );
|
||||
QTest::newRow( "point" ) << QStringLiteral( "POINT (1 2)" ) << QStringLiteral( "Point (1 2)" );
|
||||
QTest::newRow( "line empty" ) << QStringLiteral( "LINESTRING EMPTY" ) << QStringLiteral( "LineString EMPTY" );
|
||||
QTest::newRow( "line" ) << QStringLiteral( "LINESTRING (1 1, 1 2, 1 3)" ) << QStringLiteral( "LineString (1 1, 1 2, 1 3)" );
|
||||
QTest::newRow( "circular string" ) << QStringLiteral( "CIRCULARSTRINGZM (1 1 11 21, 1 0 12 22, 0 0 13 23, 0 1 14 24, 1 1 11 21)" ) << QStringLiteral( "CircularStringZM (1 1 11 21, 1 0 12 22, 0 0 13 23, 0 1 14 24, 1 1 11 21)" );
|
||||
QTest::newRow( "compound curve empty" ) << QStringLiteral( "COMPOUNDCURVE EMPTY" ) << QStringLiteral( "CompoundCurve EMPTY" );
|
||||
QTest::newRow( "compound curve one curve" ) << QStringLiteral( "COMPOUNDCURVE ((1 1, 1 2, 2 3))" ) << QStringLiteral( "LineString (1 1, 1 2, 2 3)" );
|
||||
QTest::newRow( "compound curve two curves" ) << QStringLiteral( "COMPOUNDCURVE ((1 1, 1 2, 2 3),(2 3, 4 4))" ) << QStringLiteral( "CompoundCurve ((1 1, 1 2, 2 3),(2 3, 4 4))" );
|
||||
QTest::newRow( "polygon empty" ) << QStringLiteral( "POLYGON EMPTY" ) << QStringLiteral( "Polygon EMPTY" );
|
||||
QTest::newRow( "polygon exterior" ) << QStringLiteral( "POLYGON ((1 1, 0 1, 0 0, 1 0, 1 1))" ) << QStringLiteral( "Polygon ((1 1, 0 1, 0 0, 1 0, 1 1))" );
|
||||
QTest::newRow( "collection empty" ) << QStringLiteral( "GEOMETRYCOLLECTION EMPTY" ) << QStringLiteral( "GeometryCollection EMPTY" );
|
||||
QTest::newRow( "multipoint one point" ) << QStringLiteral( "MULTIPOINT(1 1)" ) << QStringLiteral( "Point (1 1)" );
|
||||
QTest::newRow( "multipoint" ) << QStringLiteral( "MULTIPOINT(1 1, 3 4, 1 3, 2 2)" ) << QStringLiteral( "MultiPoint ((1 1),(3 4),(1 3),(2 2))" );
|
||||
}
|
||||
|
||||
void TestQgsGeometry::simplifiedTypeRef()
|
||||
{
|
||||
QFETCH( QString, wkt );
|
||||
QFETCH( QString, expected );
|
||||
|
||||
QgsGeometry geom = QgsGeometry::fromWkt( wkt );
|
||||
QCOMPARE( geom.constGet()->simplifiedTypeRef()->asWkt( 1 ), expected );
|
||||
}
|
||||
|
||||
// MK, Disabled 14.11.2014
|
||||
// Too unclear what exactly should be tested and which variations are allowed for the line
|
||||
#if 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user