mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-01 00:05:25 -04:00
15344 lines
779 KiB
C++
15344 lines
779 KiB
C++
/***************************************************************************
|
|
testqgsgeometry.cpp
|
|
--------------------------------------
|
|
Date : 20 Jan 2008
|
|
Copyright : (C) 2008 by Tim Sutton
|
|
Email : tim @ linfiniti.com
|
|
***************************************************************************
|
|
* *
|
|
* 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 "qgstest.h"
|
|
#include <QObject>
|
|
#include <QString>
|
|
#include <QStringList>
|
|
#include <QApplication>
|
|
#include <QFileInfo>
|
|
#include <QDir>
|
|
#include <QDesktopServices>
|
|
#include <QVector>
|
|
#include <QPointF>
|
|
#include <QImage>
|
|
#include <QPainter>
|
|
|
|
//qgis includes...
|
|
#include <qgsapplication.h>
|
|
#include "qgscompoundcurve.h"
|
|
#include <qgsgeometry.h>
|
|
#include "qgsgeometryutils.h"
|
|
#include <qgspoint.h>
|
|
#include "qgspoint.h"
|
|
#include "qgslinestring.h"
|
|
#include "qgspolygon.h"
|
|
#include "qgstriangle.h"
|
|
#include "qgscircle.h"
|
|
#include "qgsellipse.h"
|
|
#include "qgsregularpolygon.h"
|
|
#include "qgsmultipoint.h"
|
|
#include "qgsmultilinestring.h"
|
|
#include "qgsmultipolygon.h"
|
|
#include "qgscircularstring.h"
|
|
#include "qgsgeometrycollection.h"
|
|
#include "qgsgeometryfactory.h"
|
|
#include "qgscurvepolygon.h"
|
|
|
|
//qgs unit test utility class
|
|
#include "qgsrenderchecker.h"
|
|
|
|
/**
|
|
* \ingroup UnitTests
|
|
* This is a unit test for the different geometry operations on vector features.
|
|
*/
|
|
class TestQgsGeometry : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
TestQgsGeometry();
|
|
|
|
private slots:
|
|
void initTestCase();// will be called before the first testfunction is executed.
|
|
void cleanupTestCase();// will be called after the last testfunction was executed.
|
|
void init();// will be called before each testfunction is executed.
|
|
void cleanup();// will be called after every testfunction.
|
|
void copy();
|
|
void assignment();
|
|
void asVariant(); //test conversion to and from a QVariant
|
|
void isEmpty();
|
|
void operatorBool();
|
|
|
|
// geometry types
|
|
void point(); //test QgsPointV2
|
|
void lineString(); //test QgsLineString
|
|
void circularString();
|
|
void polygon(); //test QgsPolygonV2
|
|
void curvePolygon();
|
|
void triangle();
|
|
void triangle2();
|
|
void circle();
|
|
void ellipse();
|
|
void regularPolygon();
|
|
void compoundCurve(); //test QgsCompoundCurve
|
|
void multiPoint();
|
|
void multiLineString();
|
|
void multiCurve();
|
|
void multiSurface();
|
|
void multiPolygon();
|
|
void geometryCollection();
|
|
|
|
void fromQgsPointXY();
|
|
void fromQPoint();
|
|
void fromQPolygonF();
|
|
void asQPointF();
|
|
void asQPolygonF();
|
|
|
|
void comparePolylines();
|
|
void comparePolygons();
|
|
|
|
// MK, Disabled 14.11.2014
|
|
// Too unclear what exactly should be tested and which variations are allowed for the line
|
|
#if 0
|
|
void simplifyCheck1();
|
|
#endif
|
|
|
|
void intersectionCheck1();
|
|
void intersectionCheck2();
|
|
void translateCheck1();
|
|
void rotateCheck1();
|
|
void unionCheck1();
|
|
void unionCheck2();
|
|
void differenceCheck1();
|
|
void differenceCheck2();
|
|
void bufferCheck();
|
|
void smoothCheck();
|
|
|
|
void unaryUnion();
|
|
|
|
void dataStream();
|
|
|
|
void exportToGeoJSON();
|
|
|
|
void wkbInOut();
|
|
|
|
void directionNeutralSegmentation();
|
|
void poleOfInaccessibility();
|
|
|
|
void makeValid();
|
|
|
|
void isSimple();
|
|
|
|
void reshapeGeometryLineMerge();
|
|
void createCollectionOfType();
|
|
|
|
void minimalEnclosingCircle( );
|
|
|
|
private:
|
|
//! A helper method to do a render check to see if the geometry op is as expected
|
|
bool renderCheck( const QString &testName, const QString &comment = QString(), int mismatchCount = 0 );
|
|
//! A helper method to dump to qdebug the geometry of a multipolygon
|
|
void dumpMultiPolygon( QgsMultiPolygon &multiPolygon );
|
|
//! A helper method to dump to qdebug the geometry of a polygon
|
|
void dumpPolygon( QgsPolygon &polygon );
|
|
//! A helper method to dump to qdebug the geometry of a polyline
|
|
void dumpPolyline( QgsPolyline &polyline );
|
|
|
|
// Release return with delete []
|
|
unsigned char *hex2bytes( const char *hex, int *size )
|
|
{
|
|
QByteArray ba = QByteArray::fromHex( hex );
|
|
unsigned char *out = new unsigned char[ba.size()];
|
|
memcpy( out, ba.data(), ba.size() );
|
|
*size = ba.size();
|
|
return out;
|
|
}
|
|
|
|
QString bytes2hex( const unsigned char *bytes, int size )
|
|
{
|
|
QByteArray ba( ( const char * )bytes, size );
|
|
QString out = ba.toHex();
|
|
return out;
|
|
}
|
|
|
|
|
|
QString elemToString( const QDomElement &elem ) const;
|
|
|
|
QgsPointXY mPoint1;
|
|
QgsPointXY mPoint2;
|
|
QgsPointXY mPoint3;
|
|
QgsPointXY mPoint4;
|
|
QgsPointXY mPointA;
|
|
QgsPointXY mPointB;
|
|
QgsPointXY mPointC;
|
|
QgsPointXY mPointD;
|
|
QgsPointXY mPointW;
|
|
QgsPointXY mPointX;
|
|
QgsPointXY mPointY;
|
|
QgsPointXY mPointZ;
|
|
QgsPolyline mPolylineA;
|
|
QgsPolyline mPolylineB;
|
|
QgsPolyline mPolylineC;
|
|
QgsGeometry mpPolylineGeometryD;
|
|
QgsPolygon mPolygonA;
|
|
QgsPolygon mPolygonB;
|
|
QgsPolygon mPolygonC;
|
|
QgsGeometry mpPolygonGeometryA;
|
|
QgsGeometry mpPolygonGeometryB;
|
|
QgsGeometry mpPolygonGeometryC;
|
|
QString mWktLine;
|
|
QString mTestDataDir;
|
|
QImage mImage;
|
|
QPainter *mpPainter = nullptr;
|
|
QPen mPen1;
|
|
QPen mPen2;
|
|
QString mReport;
|
|
};
|
|
|
|
TestQgsGeometry::TestQgsGeometry()
|
|
: mpPolylineGeometryD( nullptr )
|
|
, mpPolygonGeometryA( nullptr )
|
|
, mpPolygonGeometryB( nullptr )
|
|
, mpPolygonGeometryC( nullptr )
|
|
{
|
|
|
|
}
|
|
|
|
void TestQgsGeometry::initTestCase()
|
|
{
|
|
// Runs once before any tests are run
|
|
// init QGIS's paths - true means that all path will be inited from prefix
|
|
QgsApplication::init();
|
|
QgsApplication::initQgis();
|
|
QgsApplication::showSettings();
|
|
mReport += QLatin1String( "<h1>Geometry Tests</h1>\n" );
|
|
mReport += QLatin1String( "<p><font color=\"green\">Green = polygonA</font></p>\n" );
|
|
mReport += QLatin1String( "<p><font color=\"red\">Red = polygonB</font></p>\n" );
|
|
mReport += QLatin1String( "<p><font color=\"blue\">Blue = polygonC</font></p>\n" );
|
|
}
|
|
|
|
|
|
void TestQgsGeometry::cleanupTestCase()
|
|
{
|
|
// Runs once after all tests are run
|
|
QString myReportFile = QDir::tempPath() + "/qgistest.html";
|
|
QFile myFile( myReportFile );
|
|
if ( myFile.open( QIODevice::WriteOnly | QIODevice::Append ) )
|
|
{
|
|
QTextStream myQTextStream( &myFile );
|
|
myQTextStream << mReport;
|
|
myFile.close();
|
|
//QDesktopServices::openUrl( "file:///" + myReportFile );
|
|
}
|
|
|
|
QgsApplication::exitQgis();
|
|
}
|
|
|
|
void TestQgsGeometry::init()
|
|
{
|
|
//
|
|
// Reset / reinitialize the geometries before each test is run
|
|
//
|
|
mPoint1 = QgsPointXY( 20.0, 20.0 );
|
|
mPoint2 = QgsPointXY( 80.0, 20.0 );
|
|
mPoint3 = QgsPointXY( 80.0, 80.0 );
|
|
mPoint4 = QgsPointXY( 20.0, 80.0 );
|
|
mPointA = QgsPointXY( 40.0, 40.0 );
|
|
mPointB = QgsPointXY( 100.0, 40.0 );
|
|
mPointC = QgsPointXY( 100.0, 100.0 );
|
|
mPointD = QgsPointXY( 40.0, 100.0 );
|
|
mPointW = QgsPointXY( 200.0, 200.0 );
|
|
mPointX = QgsPointXY( 240.0, 200.0 );
|
|
mPointY = QgsPointXY( 240.0, 240.0 );
|
|
mPointZ = QgsPointXY( 200.0, 240.0 );
|
|
|
|
mWktLine = QStringLiteral( "LINESTRING(117.623198 35.198654, 117.581274 35.198654, 117.078178 35.324427, 116.868555 35.534051, 116.617007 35.869448, 116.491233 35.953297, 116.155836 36.288694, 116.071987 36.372544, 115.443117 36.749865, 114.814247 37.043338, 114.311152 37.169112, 113.388810 37.378735, 113.095337 37.378735, 112.592241 37.378735, 111.753748 37.294886, 111.502201 37.252961, 111.082954 37.127187, 110.747557 37.127187, 110.160612 36.917564, 110.034838 36.833715, 109.741366 36.749865, 109.573667 36.666016, 109.238270 36.498317, 109.070571 36.414468, 108.819023 36.288694, 108.693250 36.246770, 108.483626 36.162920, 107.645134 35.911372, 106.597017 35.869448, 106.051997 35.701749, 105.800449 35.617900, 105.590826 35.575975, 105.297354 35.575975, 104.961956 35.575975, 104.710409 35.534051, 104.458861 35.492126, 103.871916 35.492126, 103.788066 35.492126, 103.326895 35.408277, 102.949574 35.408277, 102.488402 35.450201, 102.069156 35.450201, 101.482211 35.450201, 100.937191 35.659825, 100.308321 35.869448, 100.056773 36.037146, 99.050582 36.079071, 97.667069 35.743674, 97.163973 35.617900, 96.115857 35.534051, 95.612761 35.534051, 94.396947 35.911372, 93.684228 36.288694, 92.929584 36.833715, 92.258790 37.169112, 91.629920 37.504509, 90.414105 37.881831, 90.414105 37.881831, 90.246407 37.923755, 89.491763 37.839906, 89.156366 37.672207, 88.485572 37.504509, 87.814778 37.252961, 87.563230 37.169112, 87.143983 37.043338, 85.970093 36.875639, 85.802395 36.875639, 84.083484 36.959489, 84.041560 37.043338, 82.951519 37.546433, 82.699971 37.630283)" );
|
|
|
|
mPolygonA.clear();
|
|
mPolygonB.clear();
|
|
mPolygonC.clear();
|
|
mPolylineA.clear();
|
|
mPolylineB.clear();
|
|
mPolylineC.clear();
|
|
mPolylineA << mPoint1 << mPoint2 << mPoint3 << mPoint4 << mPoint1;
|
|
mPolygonA << mPolylineA;
|
|
//Polygon B intersects Polygon A
|
|
mPolylineB << mPointA << mPointB << mPointC << mPointD << mPointA;
|
|
mPolygonB << mPolylineB;
|
|
// Polygon C should intersect no other polys
|
|
mPolylineC << mPointW << mPointX << mPointY << mPointZ << mPointW;
|
|
mPolygonC << mPolylineC;
|
|
|
|
mpPolylineGeometryD = QgsGeometry::fromWkt( mWktLine );
|
|
|
|
//polygon: first item of the list is outer ring,
|
|
// inner rings (if any) start from second item
|
|
mpPolygonGeometryA = QgsGeometry::fromPolygon( mPolygonA );
|
|
mpPolygonGeometryB = QgsGeometry::fromPolygon( mPolygonB );
|
|
mpPolygonGeometryC = QgsGeometry::fromPolygon( mPolygonC );
|
|
|
|
mImage = QImage( 250, 250, QImage::Format_RGB32 );
|
|
mImage.fill( qRgb( 152, 219, 249 ) );
|
|
mpPainter = new QPainter( &mImage );
|
|
|
|
// Draw the test shapes first
|
|
mPen1 = QPen();
|
|
mPen1.setWidth( 5 );
|
|
mPen1.setBrush( Qt::green );
|
|
mpPainter->setPen( mPen1 );
|
|
dumpPolygon( mPolygonA );
|
|
mPen1.setBrush( Qt::red );
|
|
mpPainter->setPen( mPen1 );
|
|
dumpPolygon( mPolygonB );
|
|
mPen1.setBrush( Qt::blue );
|
|
mpPainter->setPen( mPen1 );
|
|
dumpPolygon( mPolygonC );
|
|
|
|
mPen2 = QPen();
|
|
mPen2.setWidth( 1 );
|
|
mPen2.setBrush( Qt::black );
|
|
QBrush myBrush( Qt::DiagCrossPattern );
|
|
|
|
|
|
//set the pen to a different color -
|
|
//any test outs will be drawn in pen2
|
|
mpPainter->setPen( mPen2 );
|
|
mpPainter->setBrush( myBrush );
|
|
}
|
|
|
|
void TestQgsGeometry::cleanup()
|
|
{
|
|
// will be called after every testfunction.
|
|
delete mpPainter;
|
|
}
|
|
|
|
void TestQgsGeometry::copy()
|
|
{
|
|
//create a point geometry
|
|
QgsGeometry original( new QgsPoint( 1.0, 2.0 ) );
|
|
QCOMPARE( original.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).x(), 1.0 );
|
|
QCOMPARE( original.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).y(), 2.0 );
|
|
|
|
//implicitly shared copy
|
|
QgsGeometry copy( original );
|
|
QCOMPARE( copy.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).x(), 1.0 );
|
|
QCOMPARE( copy.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).y(), 2.0 );
|
|
|
|
//trigger a detach
|
|
copy.setGeometry( new QgsPoint( 3.0, 4.0 ) );
|
|
QCOMPARE( copy.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).x(), 3.0 );
|
|
QCOMPARE( copy.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).y(), 4.0 );
|
|
|
|
//make sure original was untouched
|
|
QCOMPARE( original.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).x(), 1.0 );
|
|
QCOMPARE( original.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).y(), 2.0 );
|
|
}
|
|
|
|
void TestQgsGeometry::assignment()
|
|
{
|
|
//create a point geometry
|
|
QgsGeometry original( new QgsPoint( 1.0, 2.0 ) );
|
|
QCOMPARE( original.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).x(), 1.0 );
|
|
QCOMPARE( original.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).y(), 2.0 );
|
|
|
|
//assign to implicitly shared copy
|
|
QgsGeometry copy;
|
|
copy = original;
|
|
QCOMPARE( copy.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).x(), 1.0 );
|
|
QCOMPARE( copy.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).y(), 2.0 );
|
|
|
|
//trigger a detach
|
|
copy.setGeometry( new QgsPoint( 3.0, 4.0 ) );
|
|
QCOMPARE( copy.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).x(), 3.0 );
|
|
QCOMPARE( copy.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).y(), 4.0 );
|
|
|
|
//make sure original was untouched
|
|
QCOMPARE( original.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).x(), 1.0 );
|
|
QCOMPARE( original.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).y(), 2.0 );
|
|
}
|
|
|
|
void TestQgsGeometry::asVariant()
|
|
{
|
|
//create a point geometry
|
|
QgsGeometry original( new QgsPoint( 1.0, 2.0 ) );
|
|
QCOMPARE( original.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).x(), 1.0 );
|
|
QCOMPARE( original.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).y(), 2.0 );
|
|
|
|
//convert to and from a QVariant
|
|
QVariant var = QVariant::fromValue( original );
|
|
QVERIFY( var.isValid() );
|
|
|
|
QgsGeometry fromVar = qvariant_cast<QgsGeometry>( var );
|
|
QCOMPARE( fromVar.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).x(), 1.0 );
|
|
QCOMPARE( fromVar.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).y(), 2.0 );
|
|
|
|
//also check copying variant
|
|
QVariant var2 = var;
|
|
QVERIFY( var2.isValid() );
|
|
QgsGeometry fromVar2 = qvariant_cast<QgsGeometry>( var2 );
|
|
QCOMPARE( fromVar2.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).x(), 1.0 );
|
|
QCOMPARE( fromVar2.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).y(), 2.0 );
|
|
|
|
//modify original and check detachment
|
|
original.setGeometry( new QgsPoint( 3.0, 4.0 ) );
|
|
QgsGeometry fromVar3 = qvariant_cast<QgsGeometry>( var );
|
|
QCOMPARE( fromVar3.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).x(), 1.0 );
|
|
QCOMPARE( fromVar3.geometry()->vertexAt( QgsVertexId( 0, 0, 0 ) ).y(), 2.0 );
|
|
}
|
|
|
|
void TestQgsGeometry::isEmpty()
|
|
{
|
|
QgsGeometry geom;
|
|
QVERIFY( geom.isNull() );
|
|
|
|
geom.setGeometry( new QgsPoint( 1.0, 2.0 ) );
|
|
QVERIFY( !geom.isNull() );
|
|
|
|
geom.setGeometry( 0 );
|
|
QVERIFY( geom.isNull() );
|
|
|
|
QgsGeometryCollection collection;
|
|
QVERIFY( collection.isEmpty() );
|
|
}
|
|
|
|
void TestQgsGeometry::operatorBool()
|
|
{
|
|
QgsGeometry geom;
|
|
QVERIFY( !geom );
|
|
|
|
geom.setGeometry( new QgsPoint( 1.0, 2.0 ) );
|
|
QVERIFY( geom );
|
|
|
|
geom.setGeometry( 0 );
|
|
QVERIFY( !geom );
|
|
}
|
|
|
|
void TestQgsGeometry::point()
|
|
{
|
|
//test QgsPointV2
|
|
|
|
//test constructors
|
|
QgsPoint p1( 5.0, 6.0 );
|
|
QCOMPARE( p1.x(), 5.0 );
|
|
QCOMPARE( p1.y(), 6.0 );
|
|
QVERIFY( !p1.isEmpty() );
|
|
QVERIFY( !p1.is3D() );
|
|
QVERIFY( !p1.isMeasure() );
|
|
QCOMPARE( p1.wkbType(), QgsWkbTypes::Point );
|
|
QCOMPARE( p1.wktTypeStr(), QString( "Point" ) );
|
|
|
|
QgsPoint p2( QgsPointXY( 3.0, 4.0 ) );
|
|
QCOMPARE( p2.x(), 3.0 );
|
|
QCOMPARE( p2.y(), 4.0 );
|
|
QVERIFY( !p2.isEmpty() );
|
|
QVERIFY( !p2.is3D() );
|
|
QVERIFY( !p2.isMeasure() );
|
|
QCOMPARE( p2.wkbType(), QgsWkbTypes::Point );
|
|
|
|
QgsPoint p3( QPointF( 7.0, 9.0 ) );
|
|
QCOMPARE( p3.x(), 7.0 );
|
|
QCOMPARE( p3.y(), 9.0 );
|
|
QVERIFY( !p3.isEmpty() );
|
|
QVERIFY( !p3.is3D() );
|
|
QVERIFY( !p3.isMeasure() );
|
|
QCOMPARE( p3.wkbType(), QgsWkbTypes::Point );
|
|
|
|
QgsPoint p4( QgsWkbTypes::Point, 11.0, 13.0 );
|
|
QCOMPARE( p4.x(), 11.0 );
|
|
QCOMPARE( p4.y(), 13.0 );
|
|
QVERIFY( !p4.isEmpty() );
|
|
QVERIFY( !p4.is3D() );
|
|
QVERIFY( !p4.isMeasure() );
|
|
QCOMPARE( p4.wkbType(), QgsWkbTypes::Point );
|
|
|
|
QgsPoint p5( QgsWkbTypes::PointZ, 11.0, 13.0, 15.0 );
|
|
QCOMPARE( p5.x(), 11.0 );
|
|
QCOMPARE( p5.y(), 13.0 );
|
|
QCOMPARE( p5.z(), 15.0 );
|
|
QVERIFY( !p5.isEmpty() );
|
|
QVERIFY( p5.is3D() );
|
|
QVERIFY( !p5.isMeasure() );
|
|
QCOMPARE( p5.wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( p5.wktTypeStr(), QString( "PointZ" ) );
|
|
|
|
QgsPoint p6( QgsWkbTypes::PointM, 11.0, 13.0, 0.0, 17.0 );
|
|
QCOMPARE( p6.x(), 11.0 );
|
|
QCOMPARE( p6.y(), 13.0 );
|
|
QCOMPARE( p6.m(), 17.0 );
|
|
QVERIFY( !p6.isEmpty() );
|
|
QVERIFY( !p6.is3D() );
|
|
QVERIFY( p6.isMeasure() );
|
|
QCOMPARE( p6.wkbType(), QgsWkbTypes::PointM );
|
|
QCOMPARE( p6.wktTypeStr(), QString( "PointM" ) );
|
|
|
|
QgsPoint p7( QgsWkbTypes::PointZM, 11.0, 13.0, 0.0, 17.0 );
|
|
QCOMPARE( p7.x(), 11.0 );
|
|
QCOMPARE( p7.y(), 13.0 );
|
|
QCOMPARE( p7.m(), 17.0 );
|
|
QVERIFY( !p7.isEmpty() );
|
|
QVERIFY( p7.is3D() );
|
|
QVERIFY( p7.isMeasure() );
|
|
QCOMPARE( p7.wkbType(), QgsWkbTypes::PointZM );
|
|
QCOMPARE( p7.wktTypeStr(), QString( "PointZM" ) );
|
|
|
|
QgsPoint noZ( QgsWkbTypes::PointM, 11.0, 13.0, 15.0, 17.0 );
|
|
QCOMPARE( noZ.x(), 11.0 );
|
|
QCOMPARE( noZ.y(), 13.0 );
|
|
QVERIFY( std::isnan( noZ.z() ) );
|
|
QCOMPARE( noZ.m(), 17.0 );
|
|
QCOMPARE( noZ.wkbType(), QgsWkbTypes::PointM );
|
|
|
|
QgsPoint noM( QgsWkbTypes::PointZ, 11.0, 13.0, 17.0, 18.0 );
|
|
QCOMPARE( noM.x(), 11.0 );
|
|
QCOMPARE( noM.y(), 13.0 );
|
|
QVERIFY( std::isnan( noM.m() ) );
|
|
QCOMPARE( noM.z(), 17.0 );
|
|
QCOMPARE( noM.wkbType(), QgsWkbTypes::PointZ );
|
|
|
|
QgsPoint p8( QgsWkbTypes::Point25D, 21.0, 23.0, 25.0 );
|
|
QCOMPARE( p8.x(), 21.0 );
|
|
QCOMPARE( p8.y(), 23.0 );
|
|
QCOMPARE( p8.z(), 25.0 );
|
|
QVERIFY( !p8.isEmpty() );
|
|
QVERIFY( p8.is3D() );
|
|
QVERIFY( !p8.isMeasure() );
|
|
QCOMPARE( p8.wkbType(), QgsWkbTypes::Point25D );
|
|
|
|
QgsPoint pp( QgsWkbTypes::Point );
|
|
QVERIFY( !pp.is3D() );
|
|
QVERIFY( !pp.isMeasure() );
|
|
|
|
QgsPoint ppz( QgsWkbTypes::PointZ );
|
|
QVERIFY( ppz.is3D() );
|
|
QVERIFY( !ppz.isMeasure() );
|
|
|
|
QgsPoint ppm( QgsWkbTypes::PointM );
|
|
QVERIFY( !ppm.is3D() );
|
|
QVERIFY( ppm.isMeasure() );
|
|
|
|
QgsPoint ppzm( QgsWkbTypes::PointZM );
|
|
QVERIFY( ppzm.is3D() );
|
|
QVERIFY( ppzm.isMeasure() );
|
|
|
|
#if 0 //should trigger an assert
|
|
//try creating a point with a nonsense WKB type
|
|
QgsPoint p9( QgsWkbTypes::PolygonZM, 11.0, 13.0, 9.0, 17.0 );
|
|
QCOMPARE( p9.wkbType(), QgsWkbTypes::Unknown );
|
|
#endif
|
|
|
|
//test equality operator
|
|
QVERIFY( QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 1 / 3.0 ) == QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 1 / 3.0 ) );
|
|
QVERIFY( !( QgsPoint( QgsWkbTypes::PointZ, 2 / 3.0, 1 / 3.0 ) == QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 1 / 3.0 ) ) );
|
|
QVERIFY( !( QgsPoint( QgsWkbTypes::Point, 1 / 3.0, 1 / 3.0 ) == QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 1 / 3.0 ) ) );
|
|
QVERIFY( !( QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 2 / 3.0 ) == QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 1 / 3.0 ) ) );
|
|
QVERIFY( QgsPoint( QgsWkbTypes::PointZ, 3.0, 4.0, 1 / 3.0 ) == QgsPoint( QgsWkbTypes::PointZ, 3.0, 4.0, 1 / 3.0 ) );
|
|
QVERIFY( !( QgsPoint( QgsWkbTypes::PointZ, 3.0, 4.0, 1 / 3.0 ) == QgsPoint( QgsWkbTypes::PointZM, 3.0, 4.0, 1 / 3.0 ) ) );
|
|
QVERIFY( !( QgsPoint( QgsWkbTypes::PointZ, 3.0, 4.0, 2 / 3.0 ) == QgsPoint( QgsWkbTypes::PointZ, 3.0, 4.0, 1 / 3.0 ) ) );
|
|
QVERIFY( QgsPoint( QgsWkbTypes::PointM, 3.0, 4.0, 0.0, 1 / 3.0 ) == QgsPoint( QgsWkbTypes::PointM, 3.0, 4.0, 0.0, 1 / 3.0 ) );
|
|
QVERIFY( !( QgsPoint( QgsWkbTypes::PointM, 3.0, 4.0, 0.0, 1 / 3.0 ) == QgsPoint( QgsWkbTypes::PointZ, 3.0, 4.0, 0.0, 1 / 3.0 ) ) );
|
|
QVERIFY( !( QgsPoint( QgsWkbTypes::PointM, 3.0, 4.0, 0.0, 1 / 3.0 ) == QgsPoint( QgsWkbTypes::PointM, 3.0, 4.0, 0.0, 2 / 3.0 ) ) );
|
|
QVERIFY( QgsPoint( QgsWkbTypes::PointZM, 3.0, 4.0, 2 / 3.0, 1 / 3.0 ) == QgsPoint( QgsWkbTypes::PointZM, 3.0, 4.0, 2 / 3.0, 1 / 3.0 ) );
|
|
QVERIFY( QgsPoint( QgsWkbTypes::Point25D, 3.0, 4.0, 2 / 3.0 ) == QgsPoint( QgsWkbTypes::Point25D, 3.0, 4.0, 2 / 3.0 ) );
|
|
QVERIFY( !( QgsPoint( QgsWkbTypes::Point25D, 3.0, 4.0, 2 / 3.0 ) == QgsPoint( QgsWkbTypes::PointZ, 3.0, 4.0, 2 / 3.0 ) ) );
|
|
//test inequality operator
|
|
QVERIFY( !( QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 1 / 3.0 ) != QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 1 / 3.0 ) ) );
|
|
QVERIFY( QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 1 / 3.0 ) != QgsPoint( QgsWkbTypes::PointZ, 2 / 3.0, 1 / 3.0 ) );
|
|
|
|
//test setters and getters
|
|
//x
|
|
QgsPoint p10( QgsWkbTypes::PointZM );
|
|
p10.setX( 5.0 );
|
|
QCOMPARE( p10.x(), 5.0 );
|
|
QCOMPARE( p10.rx(), 5.0 );
|
|
p10.rx() = 9.0;
|
|
QCOMPARE( p10.x(), 9.0 );
|
|
//y
|
|
p10.setY( 7.0 );
|
|
QCOMPARE( p10.y(), 7.0 );
|
|
QCOMPARE( p10.ry(), 7.0 );
|
|
p10.ry() = 3.0;
|
|
QCOMPARE( p10.y(), 3.0 );
|
|
//z
|
|
p10.setZ( 17.0 );
|
|
QCOMPARE( p10.is3D(), true );
|
|
QCOMPARE( p10.z(), 17.0 );
|
|
QCOMPARE( p10.rz(), 17.0 );
|
|
p10.rz() = 13.0;
|
|
QCOMPARE( p10.z(), 13.0 );
|
|
//m
|
|
p10.setM( 27.0 );
|
|
QCOMPARE( p10.m(), 27.0 );
|
|
QCOMPARE( p10.rm(), 27.0 );
|
|
p10.rm() = 23.0;
|
|
QCOMPARE( p10.m(), 23.0 );
|
|
|
|
//other checks
|
|
QCOMPARE( p10.geometryType(), QString( "Point" ) );
|
|
QCOMPARE( p10.dimension(), 0 );
|
|
|
|
//clone
|
|
std::unique_ptr< QgsPoint >clone( p10.clone() );
|
|
QVERIFY( p10 == *clone );
|
|
|
|
//toCurveType
|
|
clone.reset( p10.toCurveType() );
|
|
QVERIFY( p10 == *clone );
|
|
|
|
//assignment
|
|
QgsPoint original( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, -4.0 );
|
|
QgsPoint assigned( 6.0, 7.0 );
|
|
assigned = original;
|
|
QVERIFY( assigned == original );
|
|
|
|
//clear
|
|
QgsPoint p11( 5.0, 6.0 );
|
|
p11.clear();
|
|
QCOMPARE( p11.wkbType(), QgsWkbTypes::Point );
|
|
QCOMPARE( p11.x(), 0.0 );
|
|
QCOMPARE( p11.y(), 0.0 );
|
|
|
|
//toQPointF
|
|
QgsPoint p11a( 5.0, 9.0 );
|
|
QPointF result = p11a.toQPointF();
|
|
QGSCOMPARENEAR( result.x(), 5.0, 4 * DBL_EPSILON );
|
|
QGSCOMPARENEAR( result.y(), 9.0, 4 * DBL_EPSILON );
|
|
|
|
//to/from WKB
|
|
QgsPoint p12( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, -4.0 );
|
|
QByteArray wkb12 = p12.asWkb();
|
|
QgsPoint p13;
|
|
QgsConstWkbPtr wkb12ptr( wkb12 );
|
|
p13.fromWkb( wkb12ptr );
|
|
QVERIFY( p13 == p12 );
|
|
|
|
//bad WKB - check for no crash
|
|
p13 = QgsPoint( 1, 2 );
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !p13.fromWkb( nullPtr ) );
|
|
QCOMPARE( p13.wkbType(), QgsWkbTypes::Point );
|
|
QgsLineString line;
|
|
p13 = QgsPoint( 1, 2 );
|
|
QByteArray wkbLine = line.asWkb();
|
|
QgsConstWkbPtr wkbLinePtr( wkbLine );
|
|
QVERIFY( !p13.fromWkb( wkbLinePtr ) );
|
|
QCOMPARE( p13.wkbType(), QgsWkbTypes::Point );
|
|
|
|
//to/from WKT
|
|
p13 = QgsPoint( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, -4.0 );
|
|
QString wkt = p13.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsPoint p14;
|
|
QVERIFY( p14.fromWkt( wkt ) );
|
|
QVERIFY( p14 == p13 );
|
|
|
|
//bad WKT
|
|
QVERIFY( !p14.fromWkt( "Polygon()" ) );
|
|
QVERIFY( !p14.fromWkt( "Point(1 )" ) );
|
|
|
|
//asGML2
|
|
QgsPoint exportPoint( 1, 2 );
|
|
QgsPoint exportPointFloat( 1 / 3.0, 2 / 3.0 );
|
|
QDomDocument doc( QStringLiteral( "gml" ) );
|
|
QString expectedGML2( QStringLiteral( "<Point xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">1,2</coordinates></Point>" ) );
|
|
QGSCOMPAREGML( elemToString( exportPoint.asGML2( doc ) ), expectedGML2 );
|
|
QString expectedGML2prec3( QStringLiteral( "<Point xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0.333,0.667</coordinates></Point>" ) );
|
|
QGSCOMPAREGML( elemToString( exportPointFloat.asGML2( doc, 3 ) ), expectedGML2prec3 );
|
|
|
|
//asGML3
|
|
QString expectedGML3( QStringLiteral( "<Point xmlns=\"gml\"><pos xmlns=\"gml\" srsDimension=\"2\">1 2</pos></Point>" ) );
|
|
QCOMPARE( elemToString( exportPoint.asGML3( doc ) ), expectedGML3 );
|
|
QString expectedGML3prec3( QStringLiteral( "<Point xmlns=\"gml\"><pos xmlns=\"gml\" srsDimension=\"2\">0.333 0.667</pos></Point>" ) );
|
|
QCOMPARE( elemToString( exportPointFloat.asGML3( doc, 3 ) ), expectedGML3prec3 );
|
|
QgsPoint exportPointZ( 1, 2, 3 );
|
|
QString expectedGML2Z( QStringLiteral( "<Point xmlns=\"gml\"><pos xmlns=\"gml\" srsDimension=\"3\">1 2 3</pos></Point>" ) );
|
|
QGSCOMPAREGML( elemToString( exportPointZ.asGML3( doc, 3 ) ), expectedGML2Z );
|
|
|
|
//asJSON
|
|
QString expectedJson( QStringLiteral( "{\"type\": \"Point\", \"coordinates\": [1, 2]}" ) );
|
|
QCOMPARE( exportPoint.asJSON(), expectedJson );
|
|
QString expectedJsonPrec3( QStringLiteral( "{\"type\": \"Point\", \"coordinates\": [0.333, 0.667]}" ) );
|
|
QCOMPARE( exportPointFloat.asJSON( 3 ), expectedJsonPrec3 );
|
|
|
|
//bounding box
|
|
QgsPoint p15( 1.0, 2.0 );
|
|
QCOMPARE( p15.boundingBox(), QgsRectangle( 1.0, 2.0, 1.0, 2.0 ) );
|
|
//modify points and test that bounding box is updated accordingly
|
|
p15.setX( 3.0 );
|
|
QCOMPARE( p15.boundingBox(), QgsRectangle( 3.0, 2.0, 3.0, 2.0 ) );
|
|
p15.setY( 6.0 );
|
|
QCOMPARE( p15.boundingBox(), QgsRectangle( 3.0, 6.0, 3.0, 6.0 ) );
|
|
p15.rx() = 4.0;
|
|
QCOMPARE( p15.boundingBox(), QgsRectangle( 4.0, 6.0, 4.0, 6.0 ) );
|
|
p15.ry() = 9.0;
|
|
QCOMPARE( p15.boundingBox(), QgsRectangle( 4.0, 9.0, 4.0, 9.0 ) );
|
|
p15.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 11.0, 13.0 ) );
|
|
QCOMPARE( p15.boundingBox(), QgsRectangle( 11.0, 13.0, 11.0, 13.0 ) );
|
|
p15 = QgsPoint( 21.0, 23.0 );
|
|
QCOMPARE( p15.boundingBox(), QgsRectangle( 21.0, 23.0, 21.0, 23.0 ) );
|
|
|
|
//CRS transform
|
|
QgsCoordinateReferenceSystem sourceSrs;
|
|
sourceSrs.createFromSrid( 3994 );
|
|
QgsCoordinateReferenceSystem destSrs;
|
|
destSrs.createFromSrid( 4202 ); // want a transform with ellipsoid change
|
|
QgsCoordinateTransform tr( sourceSrs, destSrs );
|
|
QgsPoint p16( QgsWkbTypes::PointZM, 6374985, -3626584, 1, 2 );
|
|
p16.transform( tr, QgsCoordinateTransform::ForwardTransform );
|
|
QGSCOMPARENEAR( p16.x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( p16.y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( p16.z(), 1.0, 0.001 );
|
|
QCOMPARE( p16.m(), 2.0 );
|
|
p16.transform( tr, QgsCoordinateTransform::ReverseTransform );
|
|
QGSCOMPARENEAR( p16.x(), 6374985, 1 );
|
|
QGSCOMPARENEAR( p16.y(), -3626584, 1 );
|
|
QGSCOMPARENEAR( p16.z(), 1.0, 0.001 );
|
|
QCOMPARE( p16.m(), 2.0 );
|
|
//test with z transform
|
|
p16.transform( tr, QgsCoordinateTransform::ForwardTransform, true );
|
|
QGSCOMPARENEAR( p16.z(), -19.249, 0.001 );
|
|
p16.transform( tr, QgsCoordinateTransform::ReverseTransform, true );
|
|
QGSCOMPARENEAR( p16.z(), 1.0, 0.001 );
|
|
|
|
//QTransform transform
|
|
QTransform qtr = QTransform::fromScale( 2, 3 );
|
|
QgsPoint p17( QgsWkbTypes::PointZM, 10, 20, 30, 40 );
|
|
p17.transform( qtr );
|
|
QVERIFY( p17 == QgsPoint( QgsWkbTypes::PointZM, 20, 60, 30, 40 ) );
|
|
|
|
//coordinateSequence
|
|
QgsPoint p18( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, 4.0 );
|
|
QgsCoordinateSequence coord = p18.coordinateSequence();
|
|
QCOMPARE( coord.count(), 1 );
|
|
QCOMPARE( coord.at( 0 ).count(), 1 );
|
|
QCOMPARE( coord.at( 0 ).at( 0 ).count(), 1 );
|
|
QCOMPARE( coord.at( 0 ).at( 0 ).at( 0 ), p18 );
|
|
|
|
//low level editing
|
|
//insertVertex should have no effect
|
|
QgsPoint p19( QgsWkbTypes::PointZM, 3.0, 4.0, 6.0, 7.0 );
|
|
p19.insertVertex( QgsVertexId( 1, 2, 3 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( p19, QgsPoint( QgsWkbTypes::PointZM, 3.0, 4.0, 6.0, 7.0 ) );
|
|
|
|
//moveVertex
|
|
p19.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, 4.0 ) );
|
|
QCOMPARE( p19, QgsPoint( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, 4.0 ) );
|
|
//invalid vertex id, should not crash
|
|
p19.moveVertex( QgsVertexId( 1, 2, 3 ), QgsPoint( QgsWkbTypes::PointZM, 2.0, 3.0, 1.0, 2.0 ) );
|
|
QCOMPARE( p19, QgsPoint( QgsWkbTypes::PointZM, 2.0, 3.0, 1.0, 2.0 ) );
|
|
//move PointZM using Point
|
|
p19.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( QgsWkbTypes::Point, 11.0, 12.0 ) );
|
|
QCOMPARE( p19, QgsPoint( QgsWkbTypes::PointZM, 11.0, 12.0, 1.0, 2.0 ) );
|
|
//move PointZM using PointZ
|
|
p19.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( QgsWkbTypes::PointZ, 21.0, 22.0, 23.0 ) );
|
|
QCOMPARE( p19, QgsPoint( QgsWkbTypes::PointZM, 21.0, 22.0, 23.0, 2.0 ) );
|
|
//move PointZM using PointM
|
|
p19.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( QgsWkbTypes::PointM, 31.0, 32.0, 0.0, 43.0 ) );
|
|
QCOMPARE( p19, QgsPoint( QgsWkbTypes::PointZM, 31.0, 32.0, 23.0, 43.0 ) );
|
|
//move Point using PointZM (z/m should be ignored)
|
|
QgsPoint p20( 3.0, 4.0 );
|
|
p20.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( QgsWkbTypes::PointZM, 2.0, 3.0, 1.0, 2.0 ) );
|
|
QCOMPARE( p20, QgsPoint( 2.0, 3.0 ) );
|
|
|
|
//deleteVertex - should do nothing, but not crash
|
|
p20.deleteVertex( QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p20, QgsPoint( 2.0, 3.0 ) );
|
|
|
|
// closestSegment
|
|
QgsPoint closest;
|
|
QgsVertexId after;
|
|
// return error - points have no segments
|
|
QVERIFY( p20.closestSegment( QgsPoint( 4.0, 6.0 ), closest, after ) < 0 );
|
|
|
|
//nextVertex
|
|
QgsPoint p21( 3.0, 4.0 );
|
|
QgsPoint p22;
|
|
QgsVertexId v( 0, 0, -1 );
|
|
QVERIFY( p21.nextVertex( v, p22 ) );
|
|
QCOMPARE( p22, p21 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
//no more vertices
|
|
QVERIFY( !p21.nextVertex( v, p22 ) );
|
|
v = QgsVertexId( 0, 1, -1 ); //test that ring number is maintained
|
|
QVERIFY( p21.nextVertex( v, p22 ) );
|
|
QCOMPARE( p22, p21 );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 0 ) );
|
|
v = QgsVertexId( 1, 0, -1 ); //test that part number is maintained
|
|
QVERIFY( p21.nextVertex( v, p22 ) );
|
|
QCOMPARE( p22, p21 );
|
|
QCOMPARE( v, QgsVertexId( 1, 0, 0 ) );
|
|
|
|
//vertexAt - will always be same as point
|
|
QCOMPARE( p21.vertexAt( QgsVertexId() ), p21 );
|
|
QCOMPARE( p21.vertexAt( QgsVertexId( 0, 0, 0 ) ), p21 );
|
|
|
|
//vertexAngle - undefined, but check that it doesn't crash
|
|
( void )p21.vertexAngle( QgsVertexId() );
|
|
|
|
//counts
|
|
QCOMPARE( p20.vertexCount(), 1 );
|
|
QCOMPARE( p20.ringCount(), 1 );
|
|
QCOMPARE( p20.partCount(), 1 );
|
|
|
|
//measures and other abstract geometry methods
|
|
QCOMPARE( p20.length(), 0.0 );
|
|
QCOMPARE( p20.perimeter(), 0.0 );
|
|
QCOMPARE( p20.area(), 0.0 );
|
|
QCOMPARE( p20.centroid(), p20 );
|
|
QVERIFY( !p20.hasCurvedSegments() );
|
|
std::unique_ptr< QgsPoint >segmented( static_cast< QgsPoint *>( p20.segmentize() ) );
|
|
QCOMPARE( *segmented, p20 );
|
|
|
|
//addZValue
|
|
QgsPoint p23( 1.0, 2.0 );
|
|
QVERIFY( p23.addZValue( 5.0 ) );
|
|
QCOMPARE( p23, QgsPoint( QgsWkbTypes::PointZ, 1.0, 2.0, 5.0 ) );
|
|
QVERIFY( !p23.addZValue( 6.0 ) );
|
|
|
|
//addMValue
|
|
QgsPoint p24( 1.0, 2.0 );
|
|
QVERIFY( p24.addMValue( 5.0 ) );
|
|
QCOMPARE( p24, QgsPoint( QgsWkbTypes::PointM, 1.0, 2.0, 0.0, 5.0 ) );
|
|
QVERIFY( !p24.addMValue( 6.0 ) );
|
|
|
|
//dropZ
|
|
QgsPoint p25( QgsWkbTypes::PointZ, 1.0, 2.0, 3.0 );
|
|
QVERIFY( p25.dropZValue() );
|
|
QCOMPARE( p25, QgsPoint( 1.0, 2.0 ) );
|
|
QVERIFY( !p25.dropZValue() );
|
|
QgsPoint p26( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, 4.0 );
|
|
QVERIFY( p26.dropZValue() );
|
|
QCOMPARE( p26, QgsPoint( QgsWkbTypes::PointM, 1.0, 2.0, 0.0, 4.0 ) );
|
|
QVERIFY( !p26.dropZValue() );
|
|
QgsPoint p26a( QgsWkbTypes::Point25D, 1.0, 2.0, 3.0 );
|
|
QVERIFY( p26a.dropZValue() );
|
|
QCOMPARE( p26a, QgsPoint( QgsWkbTypes::Point, 1.0, 2.0 ) );
|
|
QVERIFY( !p26a.dropZValue() );
|
|
|
|
//dropM
|
|
QgsPoint p27( QgsWkbTypes::PointM, 1.0, 2.0, 0.0, 3.0 );
|
|
QVERIFY( p27.dropMValue() );
|
|
QCOMPARE( p27, QgsPoint( 1.0, 2.0 ) );
|
|
QVERIFY( !p27.dropMValue() );
|
|
QgsPoint p28( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, 4.0 );
|
|
QVERIFY( p28.dropMValue() );
|
|
QCOMPARE( p28, QgsPoint( QgsWkbTypes::PointZ, 1.0, 2.0, 3.0, 0.0 ) );
|
|
QVERIFY( !p28.dropMValue() );
|
|
|
|
//convertTo
|
|
QgsPoint p29( 1.0, 2.0 );
|
|
QVERIFY( p29.convertTo( QgsWkbTypes::Point ) );
|
|
QCOMPARE( p29.wkbType(), QgsWkbTypes::Point );
|
|
QVERIFY( p29.convertTo( QgsWkbTypes::PointZ ) );
|
|
QCOMPARE( p29.wkbType(), QgsWkbTypes::PointZ );
|
|
p29.setZ( 5.0 );
|
|
QVERIFY( p29.convertTo( QgsWkbTypes::Point25D ) );
|
|
QCOMPARE( p29.wkbType(), QgsWkbTypes::Point25D );
|
|
QCOMPARE( p29.z(), 5.0 );
|
|
QVERIFY( p29.convertTo( QgsWkbTypes::PointZM ) );
|
|
QCOMPARE( p29.wkbType(), QgsWkbTypes::PointZM );
|
|
QCOMPARE( p29.z(), 5.0 );
|
|
p29.setM( 9.0 );
|
|
QVERIFY( p29.convertTo( QgsWkbTypes::PointM ) );
|
|
QCOMPARE( p29.wkbType(), QgsWkbTypes::PointM );
|
|
QVERIFY( std::isnan( p29.z() ) );
|
|
QCOMPARE( p29.m(), 9.0 );
|
|
QVERIFY( p29.convertTo( QgsWkbTypes::Point ) );
|
|
QCOMPARE( p29.wkbType(), QgsWkbTypes::Point );
|
|
QVERIFY( std::isnan( p29.z() ) );
|
|
QVERIFY( std::isnan( p29.m() ) );
|
|
QVERIFY( !p29.convertTo( QgsWkbTypes::Polygon ) );
|
|
|
|
//boundary
|
|
QgsPoint p30( 1.0, 2.0 );
|
|
QVERIFY( !p30.boundary() );
|
|
|
|
// distance
|
|
QCOMPARE( QgsPoint( 1, 2 ).distance( QgsPoint( 2, 2 ) ), 1.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distance( 2, 2 ), 1.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distance( QgsPoint( 3, 2 ) ), 2.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distance( 3, 2 ), 2.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distance( QgsPoint( 1, 3 ) ), 1.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distance( 1, 3 ), 1.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distance( QgsPoint( 1, 4 ) ), 2.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distance( 1, 4 ), 2.0 );
|
|
QCOMPARE( QgsPoint( 1, -2 ).distance( QgsPoint( 1, -4 ) ), 2.0 );
|
|
QCOMPARE( QgsPoint( 1, -2 ).distance( 1, -4 ), 2.0 );
|
|
|
|
QCOMPARE( QgsPoint( 1, 2 ).distanceSquared( QgsPoint( 2, 2 ) ), 1.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distanceSquared( 2, 2 ), 1.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distanceSquared( QgsPoint( 3, 2 ) ), 4.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distanceSquared( 3, 2 ), 4.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distanceSquared( QgsPoint( 1, 3 ) ), 1.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distanceSquared( 1, 3 ), 1.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distanceSquared( QgsPoint( 1, 4 ) ), 4.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).distanceSquared( 1, 4 ), 4.0 );
|
|
QCOMPARE( QgsPoint( 1, -2 ).distanceSquared( QgsPoint( 1, -4 ) ), 4.0 );
|
|
QCOMPARE( QgsPoint( 1, -2 ).distanceSquared( 1, -4 ), 4.0 );
|
|
|
|
// distance 3D
|
|
QCOMPARE( QgsPoint( 0, 0 ).distanceSquared3D( QgsPoint( 1, 1 ) ), 2.0 );
|
|
QVERIFY( std::isnan( QgsPoint( 0, 0 ).distanceSquared3D( 1, 1, 0 ) ) );
|
|
QVERIFY( std::isnan( QgsPoint( 0, 0 ).distanceSquared3D( QgsPoint( QgsWkbTypes::PointZ, 2, 2, 2, 0 ) ) ) );
|
|
QVERIFY( std::isnan( QgsPoint( 0, 0 ).distanceSquared3D( 2, 2, 2 ) ) );
|
|
QVERIFY( std::isnan( QgsPoint( QgsWkbTypes::PointZ, 2, 2, 2, 0 ).distanceSquared3D( QgsPoint( 1, 1 ) ) ) );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 2, 2, 2, 0 ).distanceSquared3D( 1, 1, 0 ), 6.0 );
|
|
QVERIFY( std::isnan( QgsPoint( QgsWkbTypes::PointZ, -2, -2, -2, 0 ).distanceSquared3D( QgsPoint( 0, 0 ) ) ) );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, -2, -2, -2, 0 ).distanceSquared3D( 0, 0, 0 ), 12.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, -2, -2, -2, 0 ).distanceSquared3D( QgsPoint( QgsWkbTypes::PointZ, 2, 2, 2, 0 ) ), 48.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, -2, -2, -2, 0 ).distanceSquared3D( 2, 2, 2 ), 48.0 );
|
|
|
|
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 1, 2, 0 ).distance3D( QgsPoint( QgsWkbTypes::PointZ, 1, 3, 2, 0 ) ), 2.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 1, 2, 0 ).distance3D( 1, 3, 2 ), 2.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 1, 2, 0 ).distance3D( QgsPoint( QgsWkbTypes::PointZ, 1, 1, 4, 0 ) ), 2.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 1, 2, 0 ).distance3D( 1, 1, 4 ), 2.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 1, -2, 0 ).distance3D( QgsPoint( QgsWkbTypes::PointZ, 1, 1, -4, 0 ) ), 2.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 1, -2, 0 ).distance3D( 1, 1, -4 ), 2.0 );
|
|
|
|
// azimuth
|
|
QCOMPARE( QgsPoint( 1, 2 ).azimuth( QgsPoint( 1, 2 ) ), 0.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).azimuth( QgsPoint( 1, 3 ) ), 0.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).azimuth( QgsPoint( 2, 2 ) ), 90.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).azimuth( QgsPoint( 1, 0 ) ), 180.0 );
|
|
QCOMPARE( QgsPoint( 1, 2 ).azimuth( QgsPoint( 0, 2 ) ), -90.0 );
|
|
|
|
// operators
|
|
QgsPoint p31( 1, 2 );
|
|
QgsPoint p32( 3, 5 );
|
|
QCOMPARE( p32 - p31, QgsVector( 2, 3 ) );
|
|
QCOMPARE( p31 - p32, QgsVector( -2, -3 ) );
|
|
|
|
p31 = QgsPoint( 1, 2 );
|
|
QCOMPARE( p31 + QgsVector( 3, 5 ), QgsPoint( 4, 7 ) );
|
|
p31 += QgsVector( 3, 5 );
|
|
QCOMPARE( p31, QgsPoint( 4, 7 ) );
|
|
|
|
QCOMPARE( p31 - QgsVector( 3, 5 ), QgsPoint( 1, 2 ) );
|
|
p31 -= QgsVector( 3, 5 );
|
|
QCOMPARE( p31, QgsPoint( 1, 2 ) );
|
|
|
|
// test projecting a point
|
|
// 2D
|
|
QgsPoint p33 = QgsPoint( 1, 2 );
|
|
QCOMPARE( p33.project( 1, 0 ), QgsPoint( 1, 3 ) );
|
|
QCOMPARE( p33.project( 1, 0, 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2 ) );
|
|
QCOMPARE( p33.project( 1.5, 90 ), QgsPoint( 2.5, 2 ) );
|
|
QCOMPARE( p33.project( 1.5, 90, 90 ), QgsPoint( 2.5, 2 ) ); // stay QgsWkbTypes::Point
|
|
QCOMPARE( p33.project( 2, 180 ), QgsPoint( 1, 0 ) );
|
|
QCOMPARE( p33.project( 5, 270 ), QgsPoint( -4, 2 ) );
|
|
QCOMPARE( p33.project( 6, 360 ), QgsPoint( 1, 8 ) );
|
|
QCOMPARE( p33.project( 5, 450 ), QgsPoint( 6, 2 ) );
|
|
QCOMPARE( p33.project( 5, 450, 450 ), QgsPoint( 6, 2 ) ); // stay QgsWkbTypes::Point
|
|
QCOMPARE( p33.project( -1, 0 ), QgsPoint( 1, 1 ) );
|
|
QCOMPARE( p33.project( 1.5, -90 ), QgsPoint( -0.5, 2 ) );
|
|
p33.addZValue( 0 );
|
|
QCOMPARE( p33.project( 1, 0, 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 1 ) );
|
|
QCOMPARE( p33.project( 2, 180, 180 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, -2 ) );
|
|
QCOMPARE( p33.project( 5, 270, 270 ), QgsPoint( QgsWkbTypes::PointZ, 6, 2, 0 ) );
|
|
QCOMPARE( p33.project( 6, 360, 360 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 6 ) );
|
|
QCOMPARE( p33.project( -1, 0, 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, -1 ) );
|
|
QCOMPARE( p33.project( 1.5, -90, -90 ), QgsPoint( QgsWkbTypes::PointZ, 2.5, 2, 0 ) );
|
|
|
|
// PointM
|
|
p33.dropZValue();
|
|
p33.addMValue( 5.0 );
|
|
QCOMPARE( p33.project( 1, 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 3, 0, 5 ) );
|
|
QCOMPARE( p33.project( 5, 450, 450 ), QgsPoint( QgsWkbTypes::PointM, 6, 2, 0, 5 ) );
|
|
|
|
p33.addZValue( 0 );
|
|
QCOMPARE( p33.project( 1, 0, 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 1, 5 ) );
|
|
|
|
// 3D
|
|
QgsPoint p34 = QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 );
|
|
QCOMPARE( p34.project( 1, 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 3, 2 ) );
|
|
QCOMPARE( p34.project( 1, 0, 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QCOMPARE( p34.project( 1.5, 90 ), QgsPoint( QgsWkbTypes::PointZ, 2.5, 2, 2 ) );
|
|
QCOMPARE( p34.project( 1.5, 90, 90 ), QgsPoint( QgsWkbTypes::PointZ, 2.5, 2, 2 ) );
|
|
QCOMPARE( p34.project( 2, 180 ), QgsPoint( QgsWkbTypes::PointZ, 1, 0, 2 ) );
|
|
QCOMPARE( p34.project( 2, 180, 180 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 0 ) );
|
|
QCOMPARE( p34.project( 5, 270 ), QgsPoint( QgsWkbTypes::PointZ, -4, 2, 2 ) );
|
|
QCOMPARE( p34.project( 5, 270, 270 ), QgsPoint( QgsWkbTypes::PointZ, 6, 2, 2 ) );
|
|
QCOMPARE( p34.project( 6, 360 ), QgsPoint( QgsWkbTypes::PointZ, 1, 8, 2 ) );
|
|
QCOMPARE( p34.project( 6, 360, 360 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 8 ) );
|
|
QCOMPARE( p34.project( 5, 450 ), QgsPoint( QgsWkbTypes::PointZ, 6, 2, 2 ) );
|
|
QCOMPARE( p34.project( 5, 450, 450 ), QgsPoint( QgsWkbTypes::PointZ, 6, 2, 2 ) );
|
|
QCOMPARE( p34.project( -1, 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 1, 2 ) );
|
|
QCOMPARE( p34.project( -1, 0, 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 1 ) );
|
|
QCOMPARE( p34.project( 1.5, -90 ), QgsPoint( QgsWkbTypes::PointZ, -0.5, 2, 2 ) );
|
|
QCOMPARE( p34.project( 1.5, -90, -90 ), QgsPoint( QgsWkbTypes::PointZ, 2.5, 2, 2 ) );
|
|
// PointM
|
|
p34.addMValue( 5.0 );
|
|
QCOMPARE( p34.project( 1, 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 3, 2, 5 ) );
|
|
QCOMPARE( p34.project( 1, 0, 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 5 ) );
|
|
QCOMPARE( p34.project( 5, 450 ), QgsPoint( QgsWkbTypes::PointZM, 6, 2, 2, 5 ) );
|
|
QCOMPARE( p34.project( 5, 450, 450 ), QgsPoint( QgsWkbTypes::PointZM, 6, 2, 2, 5 ) );
|
|
|
|
// inclination
|
|
QCOMPARE( QgsPoint( 1, 2 ).inclination( QgsPoint( 1, 2 ) ), 90.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 1, 2, 0 ).inclination( QgsPoint( QgsWkbTypes::PointZ, 1, 1, 2, 0 ) ), 90.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 90 ) ), 90.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, -90 ) ), 90.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 0 ) ), 0.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 180 ) ), 180.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, -180 ) ), 180.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 720 ) ), 0.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 45 ) ), 45.0 );
|
|
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 135 ) ), 135.0 );
|
|
|
|
}
|
|
|
|
void TestQgsGeometry::circularString()
|
|
{
|
|
//test constructors
|
|
QgsCircularString l1;
|
|
QVERIFY( l1.isEmpty() );
|
|
QCOMPARE( l1.numPoints(), 0 );
|
|
QCOMPARE( l1.vertexCount(), 0 );
|
|
QCOMPARE( l1.nCoordinates(), 0 );
|
|
QCOMPARE( l1.ringCount(), 0 );
|
|
QCOMPARE( l1.partCount(), 0 );
|
|
QVERIFY( !l1.is3D() );
|
|
QVERIFY( !l1.isMeasure() );
|
|
QCOMPARE( l1.wkbType(), QgsWkbTypes::CircularString );
|
|
QCOMPARE( l1.wktTypeStr(), QString( "CircularString" ) );
|
|
QCOMPARE( l1.geometryType(), QString( "CircularString" ) );
|
|
QCOMPARE( l1.dimension(), 1 );
|
|
QVERIFY( l1.hasCurvedSegments() );
|
|
QCOMPARE( l1.area(), 0.0 );
|
|
QCOMPARE( l1.perimeter(), 0.0 );
|
|
QgsPointSequence pts;
|
|
l1.points( pts );
|
|
QVERIFY( pts.empty() );
|
|
|
|
//setPoints
|
|
QgsCircularString l2;
|
|
l2.setPoints( QgsPointSequence() << QgsPoint( 1.0, 2.0 ) );
|
|
QVERIFY( !l2.isEmpty() );
|
|
QCOMPARE( l2.numPoints(), 1 );
|
|
QCOMPARE( l2.vertexCount(), 1 );
|
|
QCOMPARE( l2.nCoordinates(), 1 );
|
|
QCOMPARE( l2.ringCount(), 1 );
|
|
QCOMPARE( l2.partCount(), 1 );
|
|
QVERIFY( !l2.is3D() );
|
|
QVERIFY( !l2.isMeasure() );
|
|
QCOMPARE( l2.wkbType(), QgsWkbTypes::CircularString );
|
|
QVERIFY( l2.hasCurvedSegments() );
|
|
QCOMPARE( l2.area(), 0.0 );
|
|
QCOMPARE( l2.perimeter(), 0.0 );
|
|
l2.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( 1.0, 2.0 ) );
|
|
|
|
//setting first vertex should set linestring z/m type
|
|
QgsCircularString l3;
|
|
l3.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1.0, 2.0, 3.0 ) );
|
|
QVERIFY( !l3.isEmpty() );
|
|
QVERIFY( l3.is3D() );
|
|
QVERIFY( !l3.isMeasure() );
|
|
QCOMPARE( l3.wkbType(), QgsWkbTypes::CircularStringZ );
|
|
QCOMPARE( l3.wktTypeStr(), QString( "CircularStringZ" ) );
|
|
l3.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1.0, 2.0, 3.0 ) );
|
|
|
|
QgsCircularString l4;
|
|
l4.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1.0, 2.0, 0.0, 3.0 ) );
|
|
QVERIFY( !l4.isEmpty() );
|
|
QVERIFY( !l4.is3D() );
|
|
QVERIFY( l4.isMeasure() );
|
|
QCOMPARE( l4.wkbType(), QgsWkbTypes::CircularStringM );
|
|
QCOMPARE( l4.wktTypeStr(), QString( "CircularStringM" ) );
|
|
l4.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1.0, 2.0, 0.0, 3.0 ) );
|
|
|
|
QgsCircularString l5;
|
|
l5.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, 4.0 ) );
|
|
QVERIFY( !l5.isEmpty() );
|
|
QVERIFY( l5.is3D() );
|
|
QVERIFY( l5.isMeasure() );
|
|
QCOMPARE( l5.wkbType(), QgsWkbTypes::CircularStringZM );
|
|
QCOMPARE( l5.wktTypeStr(), QString( "CircularStringZM" ) );
|
|
l5.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, 4.0 ) );
|
|
|
|
//clear
|
|
l5.clear();
|
|
QVERIFY( l5.isEmpty() );
|
|
QCOMPARE( l5.numPoints(), 0 );
|
|
QCOMPARE( l5.vertexCount(), 0 );
|
|
QCOMPARE( l5.nCoordinates(), 0 );
|
|
QCOMPARE( l5.ringCount(), 0 );
|
|
QCOMPARE( l5.partCount(), 0 );
|
|
QVERIFY( !l5.is3D() );
|
|
QVERIFY( !l5.isMeasure() );
|
|
QCOMPARE( l5.wkbType(), QgsWkbTypes::CircularString );
|
|
|
|
//setPoints
|
|
QgsCircularString l8;
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2, 3 ) << QgsPoint( 3, 4 ) );
|
|
QVERIFY( !l8.isEmpty() );
|
|
QCOMPARE( l8.numPoints(), 3 );
|
|
QCOMPARE( l8.vertexCount(), 3 );
|
|
QCOMPARE( l8.nCoordinates(), 3 );
|
|
QCOMPARE( l8.ringCount(), 1 );
|
|
QCOMPARE( l8.partCount(), 1 );
|
|
QVERIFY( !l8.is3D() );
|
|
QVERIFY( !l8.isMeasure() );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::CircularString );
|
|
QVERIFY( l8.hasCurvedSegments() );
|
|
l8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2, 3 ) << QgsPoint( 3, 4 ) );
|
|
|
|
//setPoints with empty list, should clear linestring
|
|
l8.setPoints( QgsPointSequence() );
|
|
QVERIFY( l8.isEmpty() );
|
|
QCOMPARE( l8.numPoints(), 0 );
|
|
QCOMPARE( l8.vertexCount(), 0 );
|
|
QCOMPARE( l8.nCoordinates(), 0 );
|
|
QCOMPARE( l8.ringCount(), 0 );
|
|
QCOMPARE( l8.partCount(), 0 );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::CircularString );
|
|
l8.points( pts );
|
|
QVERIFY( pts.empty() );
|
|
|
|
//setPoints with z
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 2, 3, 4 ) );
|
|
QCOMPARE( l8.numPoints(), 2 );
|
|
QVERIFY( l8.is3D() );
|
|
QVERIFY( !l8.isMeasure() );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::CircularStringZ );
|
|
l8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 2, 3, 4 ) );
|
|
|
|
//setPoints with m
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 4 ) );
|
|
QCOMPARE( l8.numPoints(), 2 );
|
|
QVERIFY( !l8.is3D() );
|
|
QVERIFY( l8.isMeasure() );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::CircularStringM );
|
|
l8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 4 ) );
|
|
|
|
//setPoints with zm
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 2, 3, 4, 5 ) );
|
|
QCOMPARE( l8.numPoints(), 2 );
|
|
QVERIFY( l8.is3D() );
|
|
QVERIFY( l8.isMeasure() );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::CircularStringZM );
|
|
l8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 2, 3, 4, 5 ) );
|
|
|
|
//setPoints with MIXED dimensionality of points
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 5 ) << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 5 ) );
|
|
QCOMPARE( l8.numPoints(), 2 );
|
|
QVERIFY( l8.is3D() );
|
|
QVERIFY( l8.isMeasure() );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::CircularStringZM );
|
|
l8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 2, 3, 0, 5 ) );
|
|
|
|
//test point
|
|
QCOMPARE( l8.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 5 ) );
|
|
QCOMPARE( l8.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 2, 3, 0, 5 ) );
|
|
|
|
//out of range - just want no crash here
|
|
QgsPoint bad = l8.pointN( -1 );
|
|
bad = l8.pointN( 100 );
|
|
|
|
//test getters/setters
|
|
QgsCircularString l9;
|
|
l9.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 23, 24 ) );
|
|
QCOMPARE( l9.xAt( 0 ), 1.0 );
|
|
QCOMPARE( l9.xAt( 1 ), 11.0 );
|
|
QCOMPARE( l9.xAt( 2 ), 21.0 );
|
|
QCOMPARE( l9.xAt( -1 ), 0.0 ); //out of range
|
|
QCOMPARE( l9.xAt( 11 ), 0.0 ); //out of range
|
|
|
|
l9.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 51.0, 2 ) );
|
|
QCOMPARE( l9.xAt( 0 ), 51.0 );
|
|
l9.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 61.0, 12 ) );
|
|
QCOMPARE( l9.xAt( 1 ), 61.0 );
|
|
l9.moveVertex( QgsVertexId( 0, 0, -1 ), QgsPoint( 71.0, 2 ) ); //out of range
|
|
l9.moveVertex( QgsVertexId( 0, 0, 11 ), QgsPoint( 71.0, 2 ) ); //out of range
|
|
|
|
QCOMPARE( l9.yAt( 0 ), 2.0 );
|
|
QCOMPARE( l9.yAt( 1 ), 12.0 );
|
|
QCOMPARE( l9.yAt( 2 ), 22.0 );
|
|
QCOMPARE( l9.yAt( -1 ), 0.0 ); //out of range
|
|
QCOMPARE( l9.yAt( 11 ), 0.0 ); //out of range
|
|
|
|
l9.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 51.0, 52 ) );
|
|
QCOMPARE( l9.yAt( 0 ), 52.0 );
|
|
l9.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 61.0, 62 ) );
|
|
QCOMPARE( l9.yAt( 1 ), 62.0 );
|
|
|
|
QCOMPARE( l9.pointN( 0 ).z(), 3.0 );
|
|
QCOMPARE( l9.pointN( 1 ).z(), 13.0 );
|
|
QCOMPARE( l9.pointN( 2 ).z(), 23.0 );
|
|
|
|
l9.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 71.0, 2, 53 ) );
|
|
QCOMPARE( l9.pointN( 0 ).z(), 53.0 );
|
|
l9.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 71.0, 2, 63 ) );
|
|
QCOMPARE( l9.pointN( 1 ).z(), 63.0 );
|
|
|
|
QCOMPARE( l9.pointN( 0 ).m(), 4.0 );
|
|
QCOMPARE( l9.pointN( 1 ).m(), 14.0 );
|
|
QCOMPARE( l9.pointN( 2 ).m(), 24.0 );
|
|
|
|
l9.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 71.0, 2, 53, 54 ) );
|
|
QCOMPARE( l9.pointN( 0 ).m(), 54.0 );
|
|
l9.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 71.0, 2, 53, 64 ) );
|
|
QCOMPARE( l9.pointN( 1 ).m(), 64.0 );
|
|
|
|
//check zAt/setZAt with non-3d linestring
|
|
l9.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 21, 22, 0, 24 ) );
|
|
|
|
//basically we just don't want these to crash
|
|
QVERIFY( std::isnan( l9.pointN( 0 ).z() ) );
|
|
QVERIFY( std::isnan( l9.pointN( 1 ).z() ) );
|
|
l9.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 71.0, 2, 53 ) );
|
|
l9.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 71.0, 2, 63 ) );
|
|
|
|
//check mAt/setMAt with non-measure linestring
|
|
l9.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 )
|
|
<< QgsPoint( 21, 22 ) );
|
|
|
|
//basically we just don't want these to crash
|
|
QVERIFY( std::isnan( l9.pointN( 0 ).m() ) );
|
|
QVERIFY( std::isnan( l9.pointN( 1 ).m() ) );
|
|
l9.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 71.0, 2, 0, 53 ) );
|
|
l9.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 71.0, 2, 0, 63 ) );
|
|
|
|
//equality
|
|
QgsCircularString e1;
|
|
QgsCircularString e2;
|
|
QVERIFY( e1 == e2 );
|
|
QVERIFY( !( e1 != e2 ) );
|
|
e1.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) );
|
|
QVERIFY( !( e1 == e2 ) ); //different number of vertices
|
|
QVERIFY( e1 != e2 );
|
|
e2.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) );
|
|
QVERIFY( e1 == e2 );
|
|
QVERIFY( !( e1 != e2 ) );
|
|
e1.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 1 / 3.0, 4 / 3.0 ) );
|
|
e2.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2 / 6.0, 8 / 6.0 ) );
|
|
QVERIFY( e1 == e2 ); //check non-integer equality
|
|
QVERIFY( !( e1 != e2 ) );
|
|
e1.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 1 / 3.0, 4 / 3.0 ) << QgsPoint( 7, 8 ) );
|
|
e2.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2 / 6.0, 8 / 6.0 ) << QgsPoint( 6, 9 ) );
|
|
QVERIFY( !( e1 == e2 ) ); //different coordinates
|
|
QVERIFY( e1 != e2 );
|
|
QgsCircularString e3;
|
|
e3.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 0 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1 / 3.0, 4 / 3.0, 0 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 7, 8, 0 ) );
|
|
QVERIFY( !( e1 == e3 ) ); //different dimension
|
|
QVERIFY( e1 != e3 );
|
|
QgsCircularString e4;
|
|
e4.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1 / 3.0, 4 / 3.0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 7, 8, 4 ) );
|
|
QVERIFY( !( e3 == e4 ) ); //different z coordinates
|
|
QVERIFY( e3 != e4 );
|
|
QgsCircularString e5;
|
|
e5.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 1 / 3.0, 4 / 3.0, 0, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 7, 8, 0, 3 ) );
|
|
QgsCircularString e6;
|
|
e6.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 11 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 1 / 3.0, 4 / 3.0, 0, 12 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 7, 8, 0, 13 ) );
|
|
QVERIFY( !( e5 == e6 ) ); //different m values
|
|
QVERIFY( e5 != e6 );
|
|
|
|
QVERIFY( e6 != QgsLineString() );
|
|
|
|
//isClosed
|
|
QgsCircularString l11;
|
|
QVERIFY( !l11.isClosed() );
|
|
l11.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 2 )
|
|
<< QgsPoint( 11, 22 )
|
|
<< QgsPoint( 1, 22 ) );
|
|
QVERIFY( !l11.isClosed() );
|
|
QCOMPARE( l11.numPoints(), 4 );
|
|
QCOMPARE( l11.area(), 0.0 );
|
|
QCOMPARE( l11.perimeter(), 0.0 );
|
|
|
|
//test that m values aren't considered when testing for closedness
|
|
l11.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 11, 2, 0, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 11, 22, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 6 ) );
|
|
QVERIFY( l11.isClosed() );
|
|
|
|
//polygonf
|
|
QgsCircularString l13;
|
|
l13.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
|
|
QPolygonF poly = l13.asQPolygonF();
|
|
QCOMPARE( poly.count(), 4 );
|
|
QCOMPARE( poly.at( 0 ).x(), 1.0 );
|
|
QCOMPARE( poly.at( 0 ).y(), 2.0 );
|
|
QCOMPARE( poly.at( 1 ).x(), 11.0 );
|
|
QCOMPARE( poly.at( 1 ).y(), 2.0 );
|
|
QCOMPARE( poly.at( 2 ).x(), 11.0 );
|
|
QCOMPARE( poly.at( 2 ).y(), 22.0 );
|
|
QCOMPARE( poly.at( 3 ).x(), 1.0 );
|
|
QCOMPARE( poly.at( 3 ).y(), 22.0 );
|
|
|
|
// clone tests
|
|
QgsCircularString l14;
|
|
l14.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 2 )
|
|
<< QgsPoint( 11, 22 )
|
|
<< QgsPoint( 1, 22 ) );
|
|
std::unique_ptr<QgsCircularString> cloned( l14.clone() );
|
|
QCOMPARE( cloned->numPoints(), 4 );
|
|
QCOMPARE( cloned->vertexCount(), 4 );
|
|
QCOMPARE( cloned->ringCount(), 1 );
|
|
QCOMPARE( cloned->partCount(), 1 );
|
|
QCOMPARE( cloned->wkbType(), QgsWkbTypes::CircularString );
|
|
QVERIFY( !cloned->is3D() );
|
|
QVERIFY( !cloned->isMeasure() );
|
|
QCOMPARE( cloned->pointN( 0 ), l14.pointN( 0 ) );
|
|
QCOMPARE( cloned->pointN( 1 ), l14.pointN( 1 ) );
|
|
QCOMPARE( cloned->pointN( 2 ), l14.pointN( 2 ) );
|
|
QCOMPARE( cloned->pointN( 3 ), l14.pointN( 3 ) );
|
|
|
|
//clone with Z/M
|
|
l14.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
cloned.reset( l14.clone() );
|
|
QCOMPARE( cloned->numPoints(), 4 );
|
|
QCOMPARE( cloned->wkbType(), QgsWkbTypes::CircularStringZM );
|
|
QVERIFY( cloned->is3D() );
|
|
QVERIFY( cloned->isMeasure() );
|
|
QCOMPARE( cloned->pointN( 0 ), l14.pointN( 0 ) );
|
|
QCOMPARE( cloned->pointN( 1 ), l14.pointN( 1 ) );
|
|
QCOMPARE( cloned->pointN( 2 ), l14.pointN( 2 ) );
|
|
QCOMPARE( cloned->pointN( 3 ), l14.pointN( 3 ) );
|
|
|
|
//clone an empty line
|
|
l14.clear();
|
|
cloned.reset( l14.clone() );
|
|
QVERIFY( cloned->isEmpty() );
|
|
QCOMPARE( cloned->numPoints(), 0 );
|
|
QVERIFY( !cloned->is3D() );
|
|
QVERIFY( !cloned->isMeasure() );
|
|
QCOMPARE( cloned->wkbType(), QgsWkbTypes::CircularString );
|
|
|
|
//segmentize tests
|
|
QgsCircularString toSegment;
|
|
toSegment.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 10 ) << QgsPoint( 21, 2 ) );
|
|
std::unique_ptr<QgsLineString> segmentized( static_cast< QgsLineString * >( toSegment.segmentize() ) );
|
|
QCOMPARE( segmentized->numPoints(), 156 );
|
|
QCOMPARE( segmentized->vertexCount(), 156 );
|
|
QCOMPARE( segmentized->ringCount(), 1 );
|
|
QCOMPARE( segmentized->partCount(), 1 );
|
|
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineString );
|
|
QVERIFY( !segmentized->is3D() );
|
|
QVERIFY( !segmentized->isMeasure() );
|
|
QCOMPARE( segmentized->pointN( 0 ), toSegment.pointN( 0 ) );
|
|
QCOMPARE( segmentized->pointN( segmentized->numPoints() - 1 ), toSegment.pointN( toSegment.numPoints() - 1 ) );
|
|
|
|
//segmentize with Z/M
|
|
toSegment.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 10, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 2, 21, 24 ) );
|
|
segmentized.reset( static_cast< QgsLineString * >( toSegment.segmentize() ) );
|
|
QCOMPARE( segmentized->numPoints(), 156 );
|
|
QCOMPARE( segmentized->vertexCount(), 156 );
|
|
QCOMPARE( segmentized->ringCount(), 1 );
|
|
QCOMPARE( segmentized->partCount(), 1 );
|
|
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineStringZM );
|
|
QVERIFY( segmentized->is3D() );
|
|
QVERIFY( segmentized->isMeasure() );
|
|
QCOMPARE( segmentized->pointN( 0 ), toSegment.pointN( 0 ) );
|
|
QCOMPARE( segmentized->pointN( segmentized->numPoints() - 1 ), toSegment.pointN( toSegment.numPoints() - 1 ) );
|
|
|
|
//segmentize an empty line
|
|
toSegment.clear();
|
|
segmentized.reset( static_cast< QgsLineString * >( toSegment.segmentize() ) );
|
|
QVERIFY( segmentized->isEmpty() );
|
|
QCOMPARE( segmentized->numPoints(), 0 );
|
|
QVERIFY( !segmentized->is3D() );
|
|
QVERIFY( !segmentized->isMeasure() );
|
|
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineString );
|
|
|
|
|
|
//to/from WKB
|
|
QgsCircularString l15;
|
|
l15.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
QByteArray wkb15 = l15.asWkb();
|
|
QgsCircularString l16;
|
|
QgsConstWkbPtr wkb15ptr( wkb15 );
|
|
l16.fromWkb( wkb15ptr );
|
|
QCOMPARE( l16.numPoints(), 4 );
|
|
QCOMPARE( l16.vertexCount(), 4 );
|
|
QCOMPARE( l16.nCoordinates(), 4 );
|
|
QCOMPARE( l16.ringCount(), 1 );
|
|
QCOMPARE( l16.partCount(), 1 );
|
|
QCOMPARE( l16.wkbType(), QgsWkbTypes::CircularStringZM );
|
|
QVERIFY( l16.is3D() );
|
|
QVERIFY( l16.isMeasure() );
|
|
QCOMPARE( l16.pointN( 0 ), l15.pointN( 0 ) );
|
|
QCOMPARE( l16.pointN( 1 ), l15.pointN( 1 ) );
|
|
QCOMPARE( l16.pointN( 2 ), l15.pointN( 2 ) );
|
|
QCOMPARE( l16.pointN( 3 ), l15.pointN( 3 ) );
|
|
|
|
//bad WKB - check for no crash
|
|
l16.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !l16.fromWkb( nullPtr ) );
|
|
QCOMPARE( l16.wkbType(), QgsWkbTypes::CircularString );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkb16 = point.asWkb();
|
|
QgsConstWkbPtr wkb16ptr( wkb16 );
|
|
QVERIFY( !l16.fromWkb( wkb16ptr ) );
|
|
QCOMPARE( l16.wkbType(), QgsWkbTypes::CircularString );
|
|
|
|
//to/from WKT
|
|
QgsCircularString l17;
|
|
l17.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
|
|
QString wkt = l17.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsCircularString l18;
|
|
QVERIFY( l18.fromWkt( wkt ) );
|
|
QCOMPARE( l18.numPoints(), 4 );
|
|
QCOMPARE( l18.wkbType(), QgsWkbTypes::CircularStringZM );
|
|
QVERIFY( l18.is3D() );
|
|
QVERIFY( l18.isMeasure() );
|
|
QCOMPARE( l18.pointN( 0 ), l17.pointN( 0 ) );
|
|
QCOMPARE( l18.pointN( 1 ), l17.pointN( 1 ) );
|
|
QCOMPARE( l18.pointN( 2 ), l17.pointN( 2 ) );
|
|
QCOMPARE( l18.pointN( 3 ), l17.pointN( 3 ) );
|
|
|
|
//bad WKT
|
|
QVERIFY( !l18.fromWkt( "Polygon()" ) );
|
|
QVERIFY( l18.isEmpty() );
|
|
QCOMPARE( l18.numPoints(), 0 );
|
|
QVERIFY( !l18.is3D() );
|
|
QVERIFY( !l18.isMeasure() );
|
|
QCOMPARE( l18.wkbType(), QgsWkbTypes::CircularString );
|
|
|
|
//asGML2
|
|
QgsCircularString exportLine;
|
|
exportLine.setPoints( QgsPointSequence() << QgsPoint( 31, 32 )
|
|
<< QgsPoint( 41, 42 )
|
|
<< QgsPoint( 51, 52 ) );
|
|
QgsCircularString exportLineFloat;
|
|
exportLineFloat.setPoints( QgsPointSequence() << QgsPoint( 1 / 3.0, 2 / 3.0 )
|
|
<< QgsPoint( 1 + 1 / 3.0, 1 + 2 / 3.0 )
|
|
<< QgsPoint( 2 + 1 / 3.0, 2 + 2 / 3.0 ) );
|
|
QDomDocument doc( QStringLiteral( "gml" ) );
|
|
QString expectedGML2( QStringLiteral( "<LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">31,32 41,42 51,52</coordinates></LineString>" ) );
|
|
QGSCOMPAREGML( elemToString( exportLine.asGML2( doc ) ), expectedGML2 );
|
|
QString expectedGML2prec3( QStringLiteral( "<LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0.333,0.667 1.333,1.667 2.333,2.667</coordinates></LineString>" ) );
|
|
QGSCOMPAREGML( elemToString( exportLineFloat.asGML2( doc, 3 ) ), expectedGML2prec3 );
|
|
|
|
//asGML3
|
|
QString expectedGML3( QStringLiteral( "<Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">31 32 41 42 51 52</posList></ArcString></segments></Curve>" ) );
|
|
QCOMPARE( elemToString( exportLine.asGML3( doc ) ), expectedGML3 );
|
|
QString expectedGML3prec3( QStringLiteral( "<Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">0.333 0.667 1.333 1.667 2.333 2.667</posList></ArcString></segments></Curve>" ) );
|
|
QCOMPARE( elemToString( exportLineFloat.asGML3( doc, 3 ) ), expectedGML3prec3 );
|
|
|
|
//asJSON
|
|
QString expectedJson( QStringLiteral( "{\"type\": \"LineString\", \"coordinates\": [ [31, 32], [41, 42], [51, 52]]}" ) );
|
|
QCOMPARE( exportLine.asJSON(), expectedJson );
|
|
QString expectedJsonPrec3( QStringLiteral( "{\"type\": \"LineString\", \"coordinates\": [ [0.333, 0.667], [1.333, 1.667], [2.333, 2.667]]}" ) );
|
|
QCOMPARE( exportLineFloat.asJSON( 3 ), expectedJsonPrec3 );
|
|
|
|
//length
|
|
QgsCircularString l19;
|
|
QCOMPARE( l19.length(), 0.0 );
|
|
l19.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
QGSCOMPARENEAR( l19.length(), 26.1433, 0.001 );
|
|
|
|
//startPoint
|
|
QCOMPARE( l19.startPoint(), QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 ) );
|
|
|
|
//endPoint
|
|
QCOMPARE( l19.endPoint(), QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
|
|
//bad start/end points. Test that this doesn't crash.
|
|
l19.clear();
|
|
QCOMPARE( l19.startPoint(), QgsPoint() );
|
|
QCOMPARE( l19.endPoint(), QgsPoint() );
|
|
|
|
//curveToLine - no segmentation required, so should return a clone
|
|
l19.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
segmentized.reset( l19.curveToLine() );
|
|
QCOMPARE( segmentized->numPoints(), 181 );
|
|
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineStringZM );
|
|
QVERIFY( segmentized->is3D() );
|
|
QVERIFY( segmentized->isMeasure() );
|
|
QCOMPARE( segmentized->pointN( 0 ), l19.pointN( 0 ) );
|
|
QCOMPARE( segmentized->pointN( segmentized->numPoints() - 1 ), l19.pointN( l19.numPoints() - 1 ) );
|
|
|
|
// points
|
|
QgsCircularString l20;
|
|
QgsPointSequence points;
|
|
l20.points( points );
|
|
QVERIFY( l20.isEmpty() );
|
|
l20.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
l20.points( points );
|
|
QCOMPARE( points.count(), 3 );
|
|
QCOMPARE( points.at( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 ) );
|
|
QCOMPARE( points.at( 1 ), QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 ) );
|
|
QCOMPARE( points.at( 2 ), QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
|
|
//CRS transform
|
|
QgsCoordinateReferenceSystem sourceSrs;
|
|
sourceSrs.createFromSrid( 3994 );
|
|
QgsCoordinateReferenceSystem destSrs;
|
|
destSrs.createFromSrid( 4202 ); // want a transform with ellipsoid change
|
|
QgsCoordinateTransform tr( sourceSrs, destSrs );
|
|
|
|
// 2d CRS transform
|
|
QgsCircularString l21;
|
|
l21.setPoints( QgsPointSequence() << QgsPoint( 6374985, -3626584 )
|
|
<< QgsPoint( 6474985, -3526584 ) );
|
|
l21.transform( tr, QgsCoordinateTransform::ForwardTransform );
|
|
QGSCOMPARENEAR( l21.pointN( 0 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( l21.pointN( 0 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( l21.pointN( 1 ).x(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( l21.pointN( 1 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( l21.boundingBox().xMinimum(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( l21.boundingBox().yMinimum(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( l21.boundingBox().xMaximum(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( l21.boundingBox().yMaximum(), -38.7999, 0.001 );
|
|
|
|
//3d CRS transform
|
|
QgsCircularString l22;
|
|
l22.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 6374985, -3626584, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 6474985, -3526584, 3, 4 ) );
|
|
l22.transform( tr, QgsCoordinateTransform::ForwardTransform );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).z(), 1.0, 0.001 );
|
|
QCOMPARE( l22.pointN( 0 ).m(), 2.0 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).x(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).z(), 3.0, 0.001 );
|
|
QCOMPARE( l22.pointN( 1 ).m(), 4.0 );
|
|
|
|
//reverse transform
|
|
l22.transform( tr, QgsCoordinateTransform::ReverseTransform );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).x(), 6374985, 0.01 );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).y(), -3626584, 0.01 );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).z(), 1, 0.001 );
|
|
QCOMPARE( l22.pointN( 0 ).m(), 2.0 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).x(), 6474985, 0.01 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).y(), -3526584, 0.01 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).z(), 3, 0.001 );
|
|
QCOMPARE( l22.pointN( 1 ).m(), 4.0 );
|
|
|
|
//z value transform
|
|
l22.transform( tr, QgsCoordinateTransform::ForwardTransform, true );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).z(), -19.249066, 0.001 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).z(), -21.092128, 0.001 );
|
|
l22.transform( tr, QgsCoordinateTransform::ReverseTransform, true );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).z(), 3.0, 0.001 );
|
|
|
|
//QTransform transform
|
|
QTransform qtr = QTransform::fromScale( 2, 3 );
|
|
QgsCircularString l23;
|
|
l23.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
l23.transform( qtr );
|
|
QCOMPARE( l23.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 2, 6, 3, 4 ) );
|
|
QCOMPARE( l23.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 22, 36, 13, 14 ) );
|
|
QCOMPARE( l23.boundingBox(), QgsRectangle( 2, 6, 22, 36 ) );
|
|
|
|
//insert vertex
|
|
//cannot insert vertex in empty line
|
|
QgsCircularString l24;
|
|
QVERIFY( !l24.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QCOMPARE( l24.numPoints(), 0 );
|
|
|
|
//2d line
|
|
l24.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 1, 22 ) );
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 4.0, 7.0 ) ) );
|
|
QCOMPARE( l24.numPoints(), 5 );
|
|
QVERIFY( !l24.is3D() );
|
|
QVERIFY( !l24.isMeasure() );
|
|
QCOMPARE( l24.wkbType(), QgsWkbTypes::CircularString );
|
|
QCOMPARE( l24.pointN( 0 ), QgsPoint( 1.0, 2.0 ) );
|
|
QCOMPARE( l24.pointN( 1 ), QgsPoint( 4.0, 7.0 ) );
|
|
QGSCOMPARENEAR( l24.pointN( 2 ).x(), 7.192236, 0.01 );
|
|
QGSCOMPARENEAR( l24.pointN( 2 ).y(), 9.930870, 0.01 );
|
|
QCOMPARE( l24.pointN( 3 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( l24.pointN( 4 ), QgsPoint( 1.0, 22.0 ) );
|
|
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 8.0, 9.0 ) ) );
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 2 ), QgsPoint( 18.0, 16.0 ) ) );
|
|
QCOMPARE( l24.numPoints(), 9 );
|
|
QCOMPARE( l24.pointN( 0 ), QgsPoint( 1.0, 2.0 ) );
|
|
QGSCOMPARENEAR( l24.pointN( 1 ).x(), 4.363083, 0.01 );
|
|
QGSCOMPARENEAR( l24.pointN( 1 ).y(), 5.636917, 0.01 );
|
|
QCOMPARE( l24.pointN( 2 ), QgsPoint( 8.0, 9.0 ) );
|
|
QCOMPARE( l24.pointN( 3 ), QgsPoint( 18.0, 16.0 ) );
|
|
QGSCOMPARENEAR( l24.pointN( 4 ).x(), 5.876894, 0.01 );
|
|
QGSCOMPARENEAR( l24.pointN( 4 ).y(), 8.246211, 0.01 );
|
|
QCOMPARE( l24.pointN( 5 ), QgsPoint( 4.0, 7.0 ) );
|
|
QGSCOMPARENEAR( l24.pointN( 6 ).x(), 7.192236, 0.01 );
|
|
QGSCOMPARENEAR( l24.pointN( 6 ).y(), 9.930870, 0.01 );
|
|
QCOMPARE( l24.pointN( 7 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( l24.pointN( 8 ), QgsPoint( 1.0, 22.0 ) );
|
|
|
|
//insert vertex at end
|
|
QVERIFY( !l24.insertVertex( QgsVertexId( 0, 0, 9 ), QgsPoint( 31.0, 32.0 ) ) );
|
|
|
|
//insert vertex past end
|
|
QVERIFY( !l24.insertVertex( QgsVertexId( 0, 0, 10 ), QgsPoint( 41.0, 42.0 ) ) );
|
|
QCOMPARE( l24.numPoints(), 9 );
|
|
|
|
//insert vertex before start
|
|
QVERIFY( !l24.insertVertex( QgsVertexId( 0, 0, -18 ), QgsPoint( 41.0, 42.0 ) ) );
|
|
QCOMPARE( l24.numPoints(), 9 );
|
|
|
|
//insert 4d vertex in 4d line
|
|
l24.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) ) );
|
|
QCOMPARE( l24.numPoints(), 5 );
|
|
QCOMPARE( l24.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
|
|
//insert 2d vertex in 4d line
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 101, 102 ) ) );
|
|
QCOMPARE( l24.numPoints(), 7 );
|
|
QCOMPARE( l24.wkbType(), QgsWkbTypes::CircularStringZM );
|
|
QCOMPARE( l24.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 101, 102 ) );
|
|
|
|
//insert 4d vertex in 2d line
|
|
l24.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 1, 22 ) );
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( QgsWkbTypes::PointZM, 2, 4, 103, 104 ) ) );
|
|
QCOMPARE( l24.numPoints(), 5 );
|
|
QCOMPARE( l24.wkbType(), QgsWkbTypes::CircularString );
|
|
QCOMPARE( l24.pointN( 1 ), QgsPoint( QgsWkbTypes::Point, 2, 4 ) );
|
|
|
|
//move vertex
|
|
|
|
//empty line
|
|
QgsCircularString l25;
|
|
QVERIFY( !l25.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( l25.isEmpty() );
|
|
|
|
//valid line
|
|
l25.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) );
|
|
QVERIFY( l25.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( l25.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 16.0, 17.0 ) ) );
|
|
QVERIFY( l25.moveVertex( QgsVertexId( 0, 0, 2 ), QgsPoint( 26.0, 27.0 ) ) );
|
|
QCOMPARE( l25.pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( l25.pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( l25.pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
|
|
//out of range
|
|
QVERIFY( !l25.moveVertex( QgsVertexId( 0, 0, -1 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !l25.moveVertex( QgsVertexId( 0, 0, 10 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QCOMPARE( l25.pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( l25.pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( l25.pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
|
|
//move 4d point in 4d line
|
|
l25.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
QVERIFY( l25.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( QgsWkbTypes::PointZM, 6, 7, 12, 13 ) ) );
|
|
QCOMPARE( l25.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 6, 7, 12, 13 ) );
|
|
|
|
//move 2d point in 4d line, existing z/m should be maintained
|
|
QVERIFY( l25.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 34, 35 ) ) );
|
|
QCOMPARE( l25.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 34, 35, 12, 13 ) );
|
|
|
|
//move 4d point in 2d line
|
|
l25.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) );
|
|
QVERIFY( l25.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( QgsWkbTypes::PointZM, 3, 4, 2, 3 ) ) );
|
|
QCOMPARE( l25.pointN( 0 ), QgsPoint( 3, 4 ) );
|
|
|
|
|
|
//delete vertex
|
|
|
|
//empty line
|
|
QgsCircularString l26;
|
|
QVERIFY( l26.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( l26.isEmpty() );
|
|
|
|
//valid line
|
|
l26.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 31, 32, 6, 7 ) );
|
|
//out of range vertices
|
|
QVERIFY( !l26.deleteVertex( QgsVertexId( 0, 0, -1 ) ) );
|
|
QVERIFY( !l26.deleteVertex( QgsVertexId( 0, 0, 100 ) ) );
|
|
|
|
//valid vertices
|
|
QVERIFY( l26.deleteVertex( QgsVertexId( 0, 0, 1 ) ) );
|
|
QCOMPARE( l26.numPoints(), 2 );
|
|
QCOMPARE( l26.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 ) );
|
|
QCOMPARE( l26.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 31, 32, 6, 7 ) );
|
|
|
|
//removing the next vertex removes all remaining vertices
|
|
QVERIFY( l26.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( l26.numPoints(), 0 );
|
|
QVERIFY( l26.isEmpty() );
|
|
QVERIFY( l26.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( l26.isEmpty() );
|
|
|
|
//reversed
|
|
QgsCircularString l27;
|
|
std::unique_ptr< QgsCircularString > reversed( l27.reversed() );
|
|
QVERIFY( reversed->isEmpty() );
|
|
l27.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
reversed.reset( l27.reversed() );
|
|
QCOMPARE( reversed->numPoints(), 3 );
|
|
QCOMPARE( reversed->wkbType(), QgsWkbTypes::CircularStringZM );
|
|
QVERIFY( reversed->is3D() );
|
|
QVERIFY( reversed->isMeasure() );
|
|
QCOMPARE( reversed->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
QCOMPARE( reversed->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 ) );
|
|
QCOMPARE( reversed->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 ) );
|
|
|
|
//addZValue
|
|
|
|
QgsCircularString l28;
|
|
QCOMPARE( l28.wkbType(), QgsWkbTypes::CircularString );
|
|
QVERIFY( l28.addZValue() );
|
|
QCOMPARE( l28.wkbType(), QgsWkbTypes::CircularStringZ );
|
|
l28.clear();
|
|
QVERIFY( l28.addZValue() );
|
|
QCOMPARE( l28.wkbType(), QgsWkbTypes::CircularStringZ );
|
|
//2d line
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
QVERIFY( l28.addZValue( 2 ) );
|
|
QVERIFY( l28.is3D() );
|
|
QCOMPARE( l28.wkbType(), QgsWkbTypes::CircularStringZ );
|
|
QCOMPARE( l28.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ) );
|
|
QCOMPARE( l28.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZ, 11, 12, 2 ) );
|
|
QVERIFY( !l28.addZValue( 4 ) ); //already has z value, test that existing z is unchanged
|
|
QCOMPARE( l28.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ) );
|
|
QCOMPARE( l28.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZ, 11, 12, 2 ) );
|
|
//linestring with m
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 4 ) );
|
|
QVERIFY( l28.addZValue( 5 ) );
|
|
QVERIFY( l28.is3D() );
|
|
QVERIFY( l28.isMeasure() );
|
|
QCOMPARE( l28.wkbType(), QgsWkbTypes::CircularStringZM );
|
|
QCOMPARE( l28.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 5, 3 ) );
|
|
QCOMPARE( l28.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 5, 4 ) );
|
|
|
|
//addMValue
|
|
|
|
QgsCircularString l29;
|
|
QCOMPARE( l29.wkbType(), QgsWkbTypes::CircularString );
|
|
QVERIFY( l29.addMValue() );
|
|
QCOMPARE( l29.wkbType(), QgsWkbTypes::CircularStringM );
|
|
l29.clear();
|
|
QVERIFY( l29.addMValue() );
|
|
QCOMPARE( l29.wkbType(), QgsWkbTypes::CircularStringM );
|
|
//2d line
|
|
l29.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
QVERIFY( l29.addMValue( 2 ) );
|
|
QVERIFY( !l29.is3D() );
|
|
QVERIFY( l29.isMeasure() );
|
|
QCOMPARE( l29.wkbType(), QgsWkbTypes::CircularStringM );
|
|
QCOMPARE( l29.pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 2 ) );
|
|
QCOMPARE( l29.pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 2 ) );
|
|
QVERIFY( !l29.addMValue( 4 ) ); //already has m value, test that existing m is unchanged
|
|
QCOMPARE( l29.pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 2 ) );
|
|
QCOMPARE( l29.pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 2 ) );
|
|
//linestring with z
|
|
l29.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 4 ) );
|
|
QVERIFY( l29.addMValue( 5 ) );
|
|
QVERIFY( l29.is3D() );
|
|
QVERIFY( l29.isMeasure() );
|
|
QCOMPARE( l29.wkbType(), QgsWkbTypes::CircularStringZM );
|
|
QCOMPARE( l29.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 5 ) );
|
|
QCOMPARE( l29.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 ) );
|
|
|
|
//dropZValue
|
|
QgsCircularString l28d;
|
|
QVERIFY( !l28d.dropZValue() );
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
QVERIFY( !l28d.dropZValue() );
|
|
l28d.addZValue( 1.0 );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::CircularStringZ );
|
|
QVERIFY( l28d.is3D() );
|
|
QVERIFY( l28d.dropZValue() );
|
|
QVERIFY( !l28d.is3D() );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::CircularString );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::Point, 1, 2 ) );
|
|
QCOMPARE( l28d.pointN( 1 ), QgsPoint( QgsWkbTypes::Point, 11, 12 ) );
|
|
QVERIFY( !l28d.dropZValue() ); //already dropped
|
|
//linestring with m
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 3, 4 ) );
|
|
QVERIFY( l28d.dropZValue() );
|
|
QVERIFY( !l28d.is3D() );
|
|
QVERIFY( l28d.isMeasure() );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::CircularStringM );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QCOMPARE( l28d.pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 4 ) );
|
|
|
|
//dropMValue
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
QVERIFY( !l28d.dropMValue() );
|
|
l28d.addMValue( 1.0 );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::CircularStringM );
|
|
QVERIFY( l28d.isMeasure() );
|
|
QVERIFY( l28d.dropMValue() );
|
|
QVERIFY( !l28d.isMeasure() );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::CircularString );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::Point, 1, 2 ) );
|
|
QCOMPARE( l28d.pointN( 1 ), QgsPoint( QgsWkbTypes::Point, 11, 12 ) );
|
|
QVERIFY( !l28d.dropMValue() ); //already dropped
|
|
//linestring with z
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 3, 4 ) );
|
|
QVERIFY( l28d.dropMValue() );
|
|
QVERIFY( !l28d.isMeasure() );
|
|
QVERIFY( l28d.is3D() );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::CircularStringZ );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3, 0 ) );
|
|
QCOMPARE( l28d.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZ, 11, 12, 3, 0 ) );
|
|
|
|
//convertTo
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
QVERIFY( l28d.convertTo( QgsWkbTypes::CircularString ) );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::CircularString );
|
|
QVERIFY( l28d.convertTo( QgsWkbTypes::CircularStringZ ) );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::CircularStringZ );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2 ) );
|
|
|
|
QVERIFY( l28d.convertTo( QgsWkbTypes::CircularStringZM ) );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::CircularStringZM );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2 ) );
|
|
l28d.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 1, 2, 5 ) );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 5.0 ) );
|
|
//l28d.setMAt( 0, 6.0 );
|
|
QVERIFY( l28d.convertTo( QgsWkbTypes::CircularStringM ) );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::CircularStringM );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2 ) );
|
|
l28d.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 1, 2, 0, 6 ) );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0.0, 6.0 ) );
|
|
QVERIFY( l28d.convertTo( QgsWkbTypes::CircularString ) );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::CircularString );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QVERIFY( !l28d.convertTo( QgsWkbTypes::Polygon ) );
|
|
|
|
//isRing
|
|
QgsCircularString l30;
|
|
QVERIFY( !l30.isRing() );
|
|
l30.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 2 ) );
|
|
QVERIFY( !l30.isRing() ); //<4 points
|
|
l30.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 31, 32 ) );
|
|
QVERIFY( !l30.isRing() ); //not closed
|
|
l30.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 1, 2 ) );
|
|
QVERIFY( l30.isRing() );
|
|
|
|
//coordinateSequence
|
|
QgsCircularString l31;
|
|
QgsCoordinateSequence coords = l31.coordinateSequence();
|
|
QCOMPARE( coords.count(), 1 );
|
|
QCOMPARE( coords.at( 0 ).count(), 1 );
|
|
QVERIFY( coords.at( 0 ).at( 0 ).isEmpty() );
|
|
l31.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
coords = l31.coordinateSequence();
|
|
QCOMPARE( coords.count(), 1 );
|
|
QCOMPARE( coords.at( 0 ).count(), 1 );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).count(), 3 );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).at( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 ) );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).at( 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 ) );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).at( 2 ), QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
|
|
//nextVertex
|
|
|
|
QgsCircularString l32;
|
|
QgsVertexId v;
|
|
QgsPoint p;
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
v = QgsVertexId( 0, 0, -2 );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
v = QgsVertexId( 0, 0, 10 );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
//CircularString
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
v = QgsVertexId( 0, 0, 2 ); //out of range
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
v = QgsVertexId( 0, 0, -5 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
v = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( 1, 2 ) );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( 11, 12 ) );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
v = QgsVertexId( 0, 1, 0 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 1 ) ); //test that ring number is maintained
|
|
QCOMPARE( p, QgsPoint( 11, 12 ) );
|
|
v = QgsVertexId( 1, 0, 0 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 1, 0, 1 ) ); //test that part number is maintained
|
|
QCOMPARE( p, QgsPoint( 11, 12 ) );
|
|
|
|
//CircularStringZ
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
v = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
//CircularStringM
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
v = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
//CircularStringZM
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
v = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
|
|
//vertexAt and pointAt
|
|
QgsCircularString l33;
|
|
l33.vertexAt( QgsVertexId( 0, 0, -10 ) ); //out of bounds, check for no crash
|
|
l33.vertexAt( QgsVertexId( 0, 0, 10 ) ); //out of bounds, check for no crash
|
|
QgsVertexId::VertexType type;
|
|
QVERIFY( !l33.pointAt( -10, p, type ) );
|
|
QVERIFY( !l33.pointAt( 10, p, type ) );
|
|
//CircularString
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 22 ) );
|
|
l33.vertexAt( QgsVertexId( 0, 0, -10 ) );
|
|
l33.vertexAt( QgsVertexId( 0, 0, 10 ) ); //out of bounds, check for no crash
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( 11, 12 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( 1, 22 ) );
|
|
QVERIFY( !l33.pointAt( -10, p, type ) );
|
|
QVERIFY( !l33.pointAt( 10, p, type ) );
|
|
QVERIFY( l33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( 1, 2 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( l33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( 11, 12 ) );
|
|
QCOMPARE( type, QgsVertexId::CurveVertex );
|
|
QVERIFY( l33.pointAt( 2, p, type ) );
|
|
QCOMPARE( p, QgsPoint( 1, 22 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
//CircularStringZ
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 22, 23 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( QgsWkbTypes::PointZ, 1, 22, 23 ) );
|
|
QVERIFY( l33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( l33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
QCOMPARE( type, QgsVertexId::CurveVertex );
|
|
QVERIFY( l33.pointAt( 2, p, type ) );
|
|
QCOMPARE( p, QgsPoint( 1, 22, 23 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
//CircularStringM
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) << QgsPoint( QgsWkbTypes::PointM, 1, 22, 0, 24 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( QgsWkbTypes::PointM, 1, 22, 0, 24 ) );
|
|
QVERIFY( l33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( l33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
QCOMPARE( type, QgsVertexId::CurveVertex );
|
|
QVERIFY( l33.pointAt( 2, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 1, 22, 0, 24 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
//CircularStringZM
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 22, 23, 24 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 22, 23, 24 ) );
|
|
QVERIFY( l33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( l33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
QCOMPARE( type, QgsVertexId::CurveVertex );
|
|
QVERIFY( l33.pointAt( 2, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 1, 22, 23, 24 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
|
|
//centroid
|
|
QgsCircularString l34;
|
|
QCOMPARE( l34.centroid(), QgsPoint() );
|
|
l34.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) );
|
|
QCOMPARE( l34.centroid(), QgsPoint( 5, 10 ) );
|
|
l34.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 20, 10 ) << QgsPoint( 2, 9 ) );
|
|
QgsPoint centroid = l34.centroid();
|
|
QGSCOMPARENEAR( centroid.x(), 7.333, 0.001 );
|
|
QGSCOMPARENEAR( centroid.y(), 6.333, 0.001 );
|
|
|
|
//closest segment
|
|
QgsCircularString l35;
|
|
bool leftOf = false;
|
|
p = QgsPoint(); // reset all coords to zero
|
|
( void )l35.closestSegment( QgsPoint( 1, 2 ), p, v ); //empty line, just want no crash
|
|
l35.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) );
|
|
QVERIFY( l35.closestSegment( QgsPoint( 5, 10 ), p, v ) < 0 );
|
|
l35.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 7, 12 ) << QgsPoint( 5, 15 ) );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 4, 11 ), p, v, &leftOf ), 2.0, 0.0001 );
|
|
QCOMPARE( p, QgsPoint( 5, 10 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 8, 11 ), p, v, &leftOf ), 1.583512, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 6.84, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 11.49, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 5.5, 11.5 ), p, v, &leftOf ), 1.288897, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 6.302776, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 10.7, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 7, 16 ), p, v, &leftOf ), 3.068288, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 5.981872, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 14.574621, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 5.5, 13.5 ), p, v, &leftOf ), 1.288897, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 6.302776, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 14.3, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, true );
|
|
// point directly on segment
|
|
QCOMPARE( l35.closestSegment( QgsPoint( 5, 15 ), p, v, &leftOf ), 0.0 );
|
|
QCOMPARE( p, QgsPoint( 5, 15 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
|
|
//clockwise string
|
|
l35.setPoints( QgsPointSequence() << QgsPoint( 5, 15 ) << QgsPoint( 7, 12 ) << QgsPoint( 5, 10 ) );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 4, 11 ), p, v, &leftOf ), 2, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 5, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 10, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 8, 11 ), p, v, &leftOf ), 1.583512, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 6.84, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 11.49, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 5.5, 11.5 ), p, v, &leftOf ), 1.288897, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 6.302776, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 10.7, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 7, 16 ), p, v, &leftOf ), 3.068288, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 5.981872, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 14.574621, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 5.5, 13.5 ), p, v, &leftOf ), 1.288897, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 6.302776, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 14.3, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
// point directly on segment
|
|
QCOMPARE( l35.closestSegment( QgsPoint( 5, 15 ), p, v, &leftOf ), 0.0 );
|
|
QCOMPARE( p, QgsPoint( 5, 15 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
|
|
//sumUpArea
|
|
QgsCircularString l36;
|
|
double area = 1.0; //sumUpArea adds to area, so start with non-zero value
|
|
l36.sumUpArea( area );
|
|
QCOMPARE( area, 1.0 );
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) );
|
|
l36.sumUpArea( area );
|
|
QCOMPARE( area, 1.0 );
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 10, 10 ) );
|
|
l36.sumUpArea( area );
|
|
QCOMPARE( area, 1.0 );
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 2, 0 ) << QgsPoint( 2, 2 ) );
|
|
l36.sumUpArea( area );
|
|
QGSCOMPARENEAR( area, 4.141593, 0.0001 );
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 2, 0 ) << QgsPoint( 2, 2 ) << QgsPoint( 0, 2 ) );
|
|
l36.sumUpArea( area );
|
|
QGSCOMPARENEAR( area, 7.283185, 0.0001 );
|
|
// full circle
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 4, 0 ) << QgsPoint( 0, 0 ) );
|
|
area = 0.0;
|
|
l36.sumUpArea( area );
|
|
QGSCOMPARENEAR( area, 12.566370614359172, 0.0001 );
|
|
|
|
//boundingBox - test that bounding box is updated after every modification to the circular string
|
|
QgsCircularString l37;
|
|
QVERIFY( l37.boundingBox().isNull() );
|
|
l37.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 10, 15 ) );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( 5, 10, 10, 15 ) );
|
|
l37.setPoints( QgsPointSequence() << QgsPoint( -5, -10 ) << QgsPoint( -6, -10 ) << QgsPoint( -5.5, -9 ) );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( -6.125, -10.25, -5, -9 ) );
|
|
QByteArray wkbToAppend = l37.asWkb();
|
|
l37.clear();
|
|
QVERIFY( l37.boundingBox().isNull() );
|
|
QgsConstWkbPtr wkbToAppendPtr( wkbToAppend );
|
|
l37.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 10, 15 ) );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( 5, 10, 10, 15 ) );
|
|
l37.fromWkb( wkbToAppendPtr );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( -6.125, -10.25, -5, -9 ) );
|
|
l37.fromWkt( QStringLiteral( "CircularString( 5 10, 6 10, 5.5 9 )" ) );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( 5, 9, 6.125, 10.25 ) );
|
|
l37.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( -1, 7 ) );
|
|
QgsRectangle r = l37.boundingBox();
|
|
QGSCOMPARENEAR( r.xMinimum(), -3.014, 0.01 );
|
|
QGSCOMPARENEAR( r.xMaximum(), 14.014, 0.01 );
|
|
QGSCOMPARENEAR( r.yMinimum(), -7.0146, 0.01 );
|
|
QGSCOMPARENEAR( r.yMaximum(), 12.4988, 0.01 );
|
|
l37.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( -3, 10 ) );
|
|
r = l37.boundingBox();
|
|
QGSCOMPARENEAR( r.xMinimum(), -10.294, 0.01 );
|
|
QGSCOMPARENEAR( r.xMaximum(), 12.294, 0.01 );
|
|
QGSCOMPARENEAR( r.yMinimum(), 9, 0.01 );
|
|
QGSCOMPARENEAR( r.yMaximum(), 31.856, 0.01 );
|
|
l37.deleteVertex( QgsVertexId( 0, 0, 1 ) );
|
|
r = l37.boundingBox();
|
|
QGSCOMPARENEAR( r.xMinimum(), 5, 0.01 );
|
|
QGSCOMPARENEAR( r.xMaximum(), 6.125, 0.01 );
|
|
QGSCOMPARENEAR( r.yMinimum(), 9, 0.01 );
|
|
QGSCOMPARENEAR( r.yMaximum(), 10.25, 0.01 );
|
|
|
|
//angle
|
|
QgsCircularString l38;
|
|
( void )l38.vertexAngle( QgsVertexId() ); //just want no crash
|
|
( void )l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ); //just want no crash
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) );
|
|
( void )l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ); //just want no crash, any answer is meaningless
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) );
|
|
( void )l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ); //just want no crash, any answer is meaningless
|
|
( void )l38.vertexAngle( QgsVertexId( 0, 0, 1 ) ); //just want no crash, any answer is meaningless
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 2 ) );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 0, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 4.712389, 0.0001 );
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 2 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 3.141593, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 4.712389, 0.0001 );
|
|
( void )l38.vertexAngle( QgsVertexId( 0, 0, 20 ) ); // no crash
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 2 )
|
|
<< QgsPoint( -1, 3 ) << QgsPoint( 0, 4 ) );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 0, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 4.712389, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 3 ) ), 0, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 4 ) ), 1.5708, 0.0001 );
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 4 ) << QgsPoint( -1, 3 ) << QgsPoint( 0, 2 )
|
|
<< QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 4.712389, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 3.141592, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 3 ) ), 3.141592, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 4 ) ), 4.712389, 0.0001 );
|
|
|
|
//closed circular string
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 0, 0 ) );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 0, 0.00001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 3.141592, 0.00001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 0, 0.00001 );
|
|
|
|
//removing a vertex from a 3 point circular string should remove the whole line
|
|
QgsCircularString l39;
|
|
l39.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 2 ) );
|
|
QCOMPARE( l39.numPoints(), 3 );
|
|
l39.deleteVertex( QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( l39.numPoints(), 0 );
|
|
|
|
//boundary
|
|
QgsCircularString boundary1;
|
|
QVERIFY( !boundary1.boundary() );
|
|
boundary1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) );
|
|
QgsAbstractGeometry *boundary = boundary1.boundary();
|
|
QgsMultiPointV2 *mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
delete boundary;
|
|
|
|
// closed string = no boundary
|
|
boundary1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
QVERIFY( !boundary1.boundary() );
|
|
|
|
//boundary with z
|
|
boundary1.setPoints( QList<QgsPoint>() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 10 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 0, 15 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 20 ) );
|
|
boundary = boundary1.boundary();
|
|
mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->geometryN( 0 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->z(), 10.0 );
|
|
QCOMPARE( mpBoundary->geometryN( 1 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->z(), 20.0 );
|
|
delete boundary;
|
|
|
|
// addToPainterPath (note most tests are in test_qgsgeometry.py)
|
|
QgsCircularString path;
|
|
QPainterPath pPath;
|
|
path.addToPainterPath( pPath );
|
|
QVERIFY( pPath.isEmpty() );
|
|
path.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 21, 2, 3 ) );
|
|
path.addToPainterPath( pPath );
|
|
QGSCOMPARENEAR( pPath.currentPosition().x(), 21.0, 0.01 );
|
|
QGSCOMPARENEAR( pPath.currentPosition().y(), 2.0, 0.01 );
|
|
QVERIFY( !pPath.isEmpty() );
|
|
|
|
// even number of points - should still work
|
|
pPath = QPainterPath();
|
|
path.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
path.addToPainterPath( pPath );
|
|
QGSCOMPARENEAR( pPath.currentPosition().x(), 11.0, 0.01 );
|
|
QGSCOMPARENEAR( pPath.currentPosition().y(), 12.0, 0.01 );
|
|
QVERIFY( !pPath.isEmpty() );
|
|
|
|
// toCurveType
|
|
QgsCircularString curveLine1;
|
|
curveLine1.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 22 ) );
|
|
std::unique_ptr< QgsCurve > curveType( curveLine1.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::CircularString );
|
|
QCOMPARE( curveType->numPoints(), 3 );
|
|
QCOMPARE( curveType->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( curveType->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( 11, 12 ) );
|
|
QCOMPARE( curveType->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( 1, 22 ) );
|
|
}
|
|
|
|
|
|
void TestQgsGeometry::lineString()
|
|
{
|
|
//test constructors
|
|
QgsLineString l1;
|
|
QVERIFY( l1.isEmpty() );
|
|
QCOMPARE( l1.numPoints(), 0 );
|
|
QCOMPARE( l1.vertexCount(), 0 );
|
|
QCOMPARE( l1.nCoordinates(), 0 );
|
|
QCOMPARE( l1.ringCount(), 0 );
|
|
QCOMPARE( l1.partCount(), 0 );
|
|
QVERIFY( !l1.is3D() );
|
|
QVERIFY( !l1.isMeasure() );
|
|
QCOMPARE( l1.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( l1.wktTypeStr(), QString( "LineString" ) );
|
|
QCOMPARE( l1.geometryType(), QString( "LineString" ) );
|
|
QCOMPARE( l1.dimension(), 1 );
|
|
QVERIFY( !l1.hasCurvedSegments() );
|
|
QCOMPARE( l1.area(), 0.0 );
|
|
QCOMPARE( l1.perimeter(), 0.0 );
|
|
|
|
// from array
|
|
QVector< double > xx;
|
|
xx << 1 << 2 << 3;
|
|
QVector< double > yy;
|
|
yy << 11 << 12 << 13;
|
|
QgsLineString fromArray( xx, yy );
|
|
QCOMPARE( fromArray.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( fromArray.numPoints(), 3 );
|
|
QCOMPARE( fromArray.xAt( 0 ), 1.0 );
|
|
QCOMPARE( fromArray.yAt( 0 ), 11.0 );
|
|
QCOMPARE( fromArray.xAt( 1 ), 2.0 );
|
|
QCOMPARE( fromArray.yAt( 1 ), 12.0 );
|
|
QCOMPARE( fromArray.xAt( 2 ), 3.0 );
|
|
QCOMPARE( fromArray.yAt( 2 ), 13.0 );
|
|
// unbalanced
|
|
xx = QVector< double >() << 1 << 2;
|
|
yy = QVector< double >() << 11 << 12 << 13;
|
|
QgsLineString fromArray2( xx, yy );
|
|
QCOMPARE( fromArray2.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( fromArray2.numPoints(), 2 );
|
|
QCOMPARE( fromArray2.xAt( 0 ), 1.0 );
|
|
QCOMPARE( fromArray2.yAt( 0 ), 11.0 );
|
|
QCOMPARE( fromArray2.xAt( 1 ), 2.0 );
|
|
QCOMPARE( fromArray2.yAt( 1 ), 12.0 );
|
|
xx = QVector< double >() << 1 << 2 << 3;
|
|
yy = QVector< double >() << 11 << 12;
|
|
QgsLineString fromArray3( xx, yy );
|
|
QCOMPARE( fromArray3.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( fromArray3.numPoints(), 2 );
|
|
QCOMPARE( fromArray3.xAt( 0 ), 1.0 );
|
|
QCOMPARE( fromArray3.yAt( 0 ), 11.0 );
|
|
QCOMPARE( fromArray3.xAt( 1 ), 2.0 );
|
|
QCOMPARE( fromArray3.yAt( 1 ), 12.0 );
|
|
// with z
|
|
QVector< double > zz;
|
|
xx = QVector< double >() << 1 << 2 << 3;
|
|
yy = QVector< double >() << 11 << 12 << 13;
|
|
zz = QVector< double >() << 21 << 22 << 23;
|
|
QgsLineString fromArray4( xx, yy, zz );
|
|
QCOMPARE( fromArray4.wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( fromArray4.numPoints(), 3 );
|
|
QCOMPARE( fromArray4.xAt( 0 ), 1.0 );
|
|
QCOMPARE( fromArray4.yAt( 0 ), 11.0 );
|
|
QCOMPARE( fromArray4.zAt( 0 ), 21.0 );
|
|
QCOMPARE( fromArray4.xAt( 1 ), 2.0 );
|
|
QCOMPARE( fromArray4.yAt( 1 ), 12.0 );
|
|
QCOMPARE( fromArray4.zAt( 1 ), 22.0 );
|
|
QCOMPARE( fromArray4.xAt( 2 ), 3.0 );
|
|
QCOMPARE( fromArray4.yAt( 2 ), 13.0 );
|
|
QCOMPARE( fromArray4.zAt( 2 ), 23.0 );
|
|
// unbalanced -> z ignored
|
|
zz = QVector< double >() << 21 << 22;
|
|
QgsLineString fromArray5( xx, yy, zz );
|
|
QCOMPARE( fromArray5.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( fromArray5.numPoints(), 3 );
|
|
QCOMPARE( fromArray5.xAt( 0 ), 1.0 );
|
|
QCOMPARE( fromArray5.yAt( 0 ), 11.0 );
|
|
QCOMPARE( fromArray5.xAt( 1 ), 2.0 );
|
|
QCOMPARE( fromArray5.yAt( 1 ), 12.0 );
|
|
QCOMPARE( fromArray5.xAt( 2 ), 3.0 );
|
|
QCOMPARE( fromArray5.yAt( 2 ), 13.0 );
|
|
// unbalanced -> z truncated
|
|
zz = QVector< double >() << 21 << 22 << 23 << 24;
|
|
fromArray5 = QgsLineString( xx, yy, zz );
|
|
QCOMPARE( fromArray5.wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( fromArray5.numPoints(), 3 );
|
|
QCOMPARE( fromArray5.xAt( 0 ), 1.0 );
|
|
QCOMPARE( fromArray5.yAt( 0 ), 11.0 );
|
|
QCOMPARE( fromArray5.zAt( 0 ), 21.0 );
|
|
QCOMPARE( fromArray5.xAt( 1 ), 2.0 );
|
|
QCOMPARE( fromArray5.yAt( 1 ), 12.0 );
|
|
QCOMPARE( fromArray5.zAt( 1 ), 22.0 );
|
|
QCOMPARE( fromArray5.xAt( 2 ), 3.0 );
|
|
QCOMPARE( fromArray5.yAt( 2 ), 13.0 );
|
|
QCOMPARE( fromArray5.zAt( 2 ), 23.0 );
|
|
// with m
|
|
QVector< double > mm;
|
|
xx = QVector< double >() << 1 << 2 << 3;
|
|
yy = QVector< double >() << 11 << 12 << 13;
|
|
mm = QVector< double >() << 21 << 22 << 23;
|
|
QgsLineString fromArray6( xx, yy, QVector< double >(), mm );
|
|
QCOMPARE( fromArray6.wkbType(), QgsWkbTypes::LineStringM );
|
|
QCOMPARE( fromArray6.numPoints(), 3 );
|
|
QCOMPARE( fromArray6.xAt( 0 ), 1.0 );
|
|
QCOMPARE( fromArray6.yAt( 0 ), 11.0 );
|
|
QCOMPARE( fromArray6.mAt( 0 ), 21.0 );
|
|
QCOMPARE( fromArray6.xAt( 1 ), 2.0 );
|
|
QCOMPARE( fromArray6.yAt( 1 ), 12.0 );
|
|
QCOMPARE( fromArray6.mAt( 1 ), 22.0 );
|
|
QCOMPARE( fromArray6.xAt( 2 ), 3.0 );
|
|
QCOMPARE( fromArray6.yAt( 2 ), 13.0 );
|
|
QCOMPARE( fromArray6.mAt( 2 ), 23.0 );
|
|
// unbalanced -> m ignored
|
|
mm = QVector< double >() << 21 << 22;
|
|
QgsLineString fromArray7( xx, yy, QVector< double >(), mm );
|
|
QCOMPARE( fromArray7.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( fromArray7.numPoints(), 3 );
|
|
QCOMPARE( fromArray7.xAt( 0 ), 1.0 );
|
|
QCOMPARE( fromArray7.yAt( 0 ), 11.0 );
|
|
QCOMPARE( fromArray7.xAt( 1 ), 2.0 );
|
|
QCOMPARE( fromArray7.yAt( 1 ), 12.0 );
|
|
QCOMPARE( fromArray7.xAt( 2 ), 3.0 );
|
|
QCOMPARE( fromArray7.yAt( 2 ), 13.0 );
|
|
// unbalanced -> m truncated
|
|
mm = QVector< double >() << 21 << 22 << 23 << 24;
|
|
fromArray7 = QgsLineString( xx, yy, QVector< double >(), mm );
|
|
QCOMPARE( fromArray7.wkbType(), QgsWkbTypes::LineStringM );
|
|
QCOMPARE( fromArray7.numPoints(), 3 );
|
|
QCOMPARE( fromArray7.xAt( 0 ), 1.0 );
|
|
QCOMPARE( fromArray7.yAt( 0 ), 11.0 );
|
|
QCOMPARE( fromArray7.mAt( 0 ), 21.0 );
|
|
QCOMPARE( fromArray7.xAt( 1 ), 2.0 );
|
|
QCOMPARE( fromArray7.yAt( 1 ), 12.0 );
|
|
QCOMPARE( fromArray7.mAt( 1 ), 22.0 );
|
|
QCOMPARE( fromArray7.xAt( 2 ), 3.0 );
|
|
QCOMPARE( fromArray7.yAt( 2 ), 13.0 );
|
|
QCOMPARE( fromArray7.mAt( 2 ), 23.0 );
|
|
// zm
|
|
xx = QVector< double >() << 1 << 2 << 3;
|
|
yy = QVector< double >() << 11 << 12 << 13;
|
|
zz = QVector< double >() << 21 << 22 << 23;
|
|
mm = QVector< double >() << 31 << 32 << 33;
|
|
QgsLineString fromArray8( xx, yy, zz, mm );
|
|
QCOMPARE( fromArray8.wkbType(), QgsWkbTypes::LineStringZM );
|
|
QCOMPARE( fromArray8.numPoints(), 3 );
|
|
QCOMPARE( fromArray8.xAt( 0 ), 1.0 );
|
|
QCOMPARE( fromArray8.yAt( 0 ), 11.0 );
|
|
QCOMPARE( fromArray8.zAt( 0 ), 21.0 );
|
|
QCOMPARE( fromArray8.mAt( 0 ), 31.0 );
|
|
QCOMPARE( fromArray8.xAt( 1 ), 2.0 );
|
|
QCOMPARE( fromArray8.yAt( 1 ), 12.0 );
|
|
QCOMPARE( fromArray8.zAt( 1 ), 22.0 );
|
|
QCOMPARE( fromArray8.mAt( 1 ), 32.0 );
|
|
QCOMPARE( fromArray8.xAt( 2 ), 3.0 );
|
|
QCOMPARE( fromArray8.yAt( 2 ), 13.0 );
|
|
QCOMPARE( fromArray8.zAt( 2 ), 23.0 );
|
|
QCOMPARE( fromArray8.mAt( 2 ), 33.0 );
|
|
|
|
// from QList<QgsPointXY>
|
|
QgsLineString fromPtsA = QgsLineString( QVector< QgsPoint >() );
|
|
QVERIFY( fromPtsA.isEmpty() );
|
|
QCOMPARE( fromPtsA.wkbType(), QgsWkbTypes::LineString );
|
|
|
|
fromPtsA = QgsLineString( QVector< QgsPoint >() << QgsPoint( 1, 2, 0, 4, QgsWkbTypes::PointM ) );
|
|
QCOMPARE( fromPtsA.numPoints(), 1 );
|
|
QCOMPARE( fromPtsA.wkbType(), QgsWkbTypes::LineStringM );
|
|
|
|
QList<QgsPointXY> ptsA;
|
|
ptsA << QgsPointXY( 1, 2 ) << QgsPointXY( 11, 12 ) << QgsPointXY( 21, 22 );
|
|
QgsLineString fromPts( ptsA );
|
|
QCOMPARE( fromPts.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( fromPts.numPoints(), 3 );
|
|
QCOMPARE( fromPts.xAt( 0 ), 1.0 );
|
|
QCOMPARE( fromPts.yAt( 0 ), 2.0 );
|
|
QCOMPARE( fromPts.xAt( 1 ), 11.0 );
|
|
QCOMPARE( fromPts.yAt( 1 ), 12.0 );
|
|
QCOMPARE( fromPts.xAt( 2 ), 21.0 );
|
|
QCOMPARE( fromPts.yAt( 2 ), 22.0 );
|
|
|
|
// from QVector<QgsPoint>
|
|
QVector<QgsPoint> ptsVector;
|
|
ptsVector << QgsPoint( 10, 20 ) << QgsPoint( 30, 40 );
|
|
QgsLineString fromVector( ptsVector );
|
|
QCOMPARE( fromVector.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( fromVector.numPoints(), 2 );
|
|
QCOMPARE( fromVector.xAt( 0 ), 10.0 );
|
|
QCOMPARE( fromVector.yAt( 0 ), 20.0 );
|
|
QCOMPARE( fromVector.xAt( 1 ), 30.0 );
|
|
QCOMPARE( fromVector.yAt( 1 ), 40.0 );
|
|
QVector<QgsPoint> ptsVector3D;
|
|
ptsVector3D << QgsPoint( QgsWkbTypes::PointZ, 10, 20, 100 ) << QgsPoint( QgsWkbTypes::PointZ, 30, 40, 200 );
|
|
QgsLineString fromVector3D( ptsVector3D );
|
|
QCOMPARE( fromVector3D.wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( fromVector3D.numPoints(), 2 );
|
|
QCOMPARE( fromVector3D.xAt( 0 ), 10.0 );
|
|
QCOMPARE( fromVector3D.yAt( 0 ), 20.0 );
|
|
QCOMPARE( fromVector3D.zAt( 0 ), 100.0 );
|
|
QCOMPARE( fromVector3D.xAt( 1 ), 30.0 );
|
|
QCOMPARE( fromVector3D.yAt( 1 ), 40.0 );
|
|
QCOMPARE( fromVector3D.zAt( 1 ), 200.0 );
|
|
|
|
//addVertex
|
|
QgsLineString l2;
|
|
l2.addVertex( QgsPoint( 1.0, 2.0 ) );
|
|
QVERIFY( !l2.isEmpty() );
|
|
QCOMPARE( l2.numPoints(), 1 );
|
|
QCOMPARE( l2.vertexCount(), 1 );
|
|
QCOMPARE( l2.nCoordinates(), 1 );
|
|
QCOMPARE( l2.ringCount(), 1 );
|
|
QCOMPARE( l2.partCount(), 1 );
|
|
QVERIFY( !l2.is3D() );
|
|
QVERIFY( !l2.isMeasure() );
|
|
QCOMPARE( l2.wkbType(), QgsWkbTypes::LineString );
|
|
QVERIFY( !l2.hasCurvedSegments() );
|
|
QCOMPARE( l2.area(), 0.0 );
|
|
QCOMPARE( l2.perimeter(), 0.0 );
|
|
|
|
//adding first vertex should set linestring z/m type
|
|
QgsLineString l3;
|
|
l3.addVertex( QgsPoint( QgsWkbTypes::PointZ, 1.0, 2.0, 3.0 ) );
|
|
QVERIFY( !l3.isEmpty() );
|
|
QVERIFY( l3.is3D() );
|
|
QVERIFY( !l3.isMeasure() );
|
|
QCOMPARE( l3.wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( l3.wktTypeStr(), QString( "LineStringZ" ) );
|
|
|
|
QgsLineString l4;
|
|
l4.addVertex( QgsPoint( QgsWkbTypes::PointM, 1.0, 2.0, 0.0, 3.0 ) );
|
|
QVERIFY( !l4.isEmpty() );
|
|
QVERIFY( !l4.is3D() );
|
|
QVERIFY( l4.isMeasure() );
|
|
QCOMPARE( l4.wkbType(), QgsWkbTypes::LineStringM );
|
|
QCOMPARE( l4.wktTypeStr(), QString( "LineStringM" ) );
|
|
|
|
QgsLineString l5;
|
|
l5.addVertex( QgsPoint( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, 4.0 ) );
|
|
QVERIFY( !l5.isEmpty() );
|
|
QVERIFY( l5.is3D() );
|
|
QVERIFY( l5.isMeasure() );
|
|
QCOMPARE( l5.wkbType(), QgsWkbTypes::LineStringZM );
|
|
QCOMPARE( l5.wktTypeStr(), QString( "LineStringZM" ) );
|
|
|
|
QgsLineString l25d;
|
|
l25d.addVertex( QgsPoint( QgsWkbTypes::Point25D, 1.0, 2.0, 3.0 ) );
|
|
QVERIFY( !l25d.isEmpty() );
|
|
QVERIFY( l25d.is3D() );
|
|
QVERIFY( !l25d.isMeasure() );
|
|
QCOMPARE( l25d.wkbType(), QgsWkbTypes::LineString25D );
|
|
QCOMPARE( l25d.wktTypeStr(), QString( "LineStringZ" ) );
|
|
|
|
//adding subsequent vertices should not alter z/m type, regardless of points type
|
|
QgsLineString l6;
|
|
l6.addVertex( QgsPoint( QgsWkbTypes::Point, 1.0, 2.0 ) ); //2d type
|
|
QCOMPARE( l6.wkbType(), QgsWkbTypes::LineString );
|
|
l6.addVertex( QgsPoint( QgsWkbTypes::PointZ, 11.0, 12.0, 13.0 ) ); // add 3d point
|
|
QCOMPARE( l6.numPoints(), 2 );
|
|
QCOMPARE( l6.vertexCount(), 2 );
|
|
QCOMPARE( l6.nCoordinates(), 2 );
|
|
QCOMPARE( l6.ringCount(), 1 );
|
|
QCOMPARE( l6.partCount(), 1 );
|
|
QCOMPARE( l6.wkbType(), QgsWkbTypes::LineString ); //should still be 2d
|
|
QVERIFY( !l6.is3D() );
|
|
QCOMPARE( l6.area(), 0.0 );
|
|
QCOMPARE( l6.perimeter(), 0.0 );
|
|
|
|
QgsLineString l7;
|
|
l7.addVertex( QgsPoint( QgsWkbTypes::PointZ, 1.0, 2.0, 3.0 ) ); //3d type
|
|
QCOMPARE( l7.wkbType(), QgsWkbTypes::LineStringZ );
|
|
l7.addVertex( QgsPoint( QgsWkbTypes::Point, 11.0, 12.0 ) ); //add 2d point
|
|
QCOMPARE( l7.wkbType(), QgsWkbTypes::LineStringZ ); //should still be 3d
|
|
QCOMPARE( l7.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZ, 11.0, 12.0 ) );
|
|
QVERIFY( l7.is3D() );
|
|
QCOMPARE( l7.numPoints(), 2 );
|
|
QCOMPARE( l7.vertexCount(), 2 );
|
|
QCOMPARE( l7.nCoordinates(), 2 );
|
|
QCOMPARE( l7.ringCount(), 1 );
|
|
QCOMPARE( l7.partCount(), 1 );
|
|
|
|
//clear
|
|
l7.clear();
|
|
QVERIFY( l7.isEmpty() );
|
|
QCOMPARE( l7.numPoints(), 0 );
|
|
QCOMPARE( l7.vertexCount(), 0 );
|
|
QCOMPARE( l7.nCoordinates(), 0 );
|
|
QCOMPARE( l7.ringCount(), 0 );
|
|
QCOMPARE( l7.partCount(), 0 );
|
|
QVERIFY( !l7.is3D() );
|
|
QVERIFY( !l7.isMeasure() );
|
|
QCOMPARE( l7.wkbType(), QgsWkbTypes::LineString );
|
|
|
|
//setPoints
|
|
QgsLineString l8;
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2, 3 ) << QgsPoint( 3, 4 ) );
|
|
QVERIFY( !l8.isEmpty() );
|
|
QCOMPARE( l8.numPoints(), 3 );
|
|
QCOMPARE( l8.vertexCount(), 3 );
|
|
QCOMPARE( l8.nCoordinates(), 3 );
|
|
QCOMPARE( l8.ringCount(), 1 );
|
|
QCOMPARE( l8.partCount(), 1 );
|
|
QVERIFY( !l8.is3D() );
|
|
QVERIFY( !l8.isMeasure() );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::LineString );
|
|
QVERIFY( !l8.hasCurvedSegments() );
|
|
QgsPointSequence pts;
|
|
l8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2, 3 ) << QgsPoint( 3, 4 ) );
|
|
|
|
//setPoints with empty list, should clear linestring
|
|
l8.setPoints( QgsPointSequence() );
|
|
QVERIFY( l8.isEmpty() );
|
|
QCOMPARE( l8.numPoints(), 0 );
|
|
QCOMPARE( l8.vertexCount(), 0 );
|
|
QCOMPARE( l8.nCoordinates(), 0 );
|
|
QCOMPARE( l8.ringCount(), 0 );
|
|
QCOMPARE( l8.partCount(), 0 );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::LineString );
|
|
l8.points( pts );
|
|
QVERIFY( pts.isEmpty() );
|
|
|
|
//setPoints with z
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 2, 3, 4 ) );
|
|
QCOMPARE( l8.numPoints(), 2 );
|
|
QVERIFY( l8.is3D() );
|
|
QVERIFY( !l8.isMeasure() );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::LineStringZ );
|
|
l8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 2, 3, 4 ) );
|
|
|
|
//setPoints with 25d
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 1, 2, 4 ) << QgsPoint( QgsWkbTypes::Point25D, 2, 3, 4 ) );
|
|
QCOMPARE( l8.numPoints(), 2 );
|
|
QVERIFY( l8.is3D() );
|
|
QVERIFY( !l8.isMeasure() );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::LineString25D );
|
|
QCOMPARE( l8.pointN( 0 ), QgsPoint( QgsWkbTypes::Point25D, 1, 2, 4 ) );
|
|
l8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 1, 2, 4 ) << QgsPoint( QgsWkbTypes::Point25D, 2, 3, 4 ) );
|
|
|
|
//setPoints with m
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 4 ) );
|
|
QCOMPARE( l8.numPoints(), 2 );
|
|
QVERIFY( !l8.is3D() );
|
|
QVERIFY( l8.isMeasure() );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::LineStringM );
|
|
l8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 4 ) );
|
|
|
|
//setPoints with zm
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 2, 3, 4, 5 ) );
|
|
QCOMPARE( l8.numPoints(), 2 );
|
|
QVERIFY( l8.is3D() );
|
|
QVERIFY( l8.isMeasure() );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::LineStringZM );
|
|
l8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 2, 3, 4, 5 ) );
|
|
|
|
//setPoints with MIXED dimensionality of points
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 5 ) << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 5 ) );
|
|
QCOMPARE( l8.numPoints(), 2 );
|
|
QVERIFY( l8.is3D() );
|
|
QVERIFY( l8.isMeasure() );
|
|
QCOMPARE( l8.wkbType(), QgsWkbTypes::LineStringZM );
|
|
l8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 2, 3, 0, 5 ) );
|
|
|
|
//test point
|
|
QCOMPARE( l8.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 5 ) );
|
|
QCOMPARE( l8.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 2, 3, 0, 5 ) );
|
|
|
|
//out of range - just want no crash here
|
|
QgsPoint bad = l8.pointN( -1 );
|
|
bad = l8.pointN( 100 );
|
|
|
|
//test getters/setters
|
|
QgsLineString l9;
|
|
l9.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 23, 24 ) );
|
|
QCOMPARE( l9.xAt( 0 ), 1.0 );
|
|
QCOMPARE( l9.xAt( 1 ), 11.0 );
|
|
QCOMPARE( l9.xAt( 2 ), 21.0 );
|
|
QCOMPARE( l9.xAt( -1 ), 0.0 ); //out of range
|
|
QCOMPARE( l9.xAt( 11 ), 0.0 ); //out of range
|
|
|
|
l9.setXAt( 0, 51.0 );
|
|
QCOMPARE( l9.xAt( 0 ), 51.0 );
|
|
l9.setXAt( 1, 61.0 );
|
|
QCOMPARE( l9.xAt( 1 ), 61.0 );
|
|
l9.setXAt( -1, 51.0 ); //out of range
|
|
l9.setXAt( 11, 51.0 ); //out of range
|
|
|
|
QCOMPARE( l9.yAt( 0 ), 2.0 );
|
|
QCOMPARE( l9.yAt( 1 ), 12.0 );
|
|
QCOMPARE( l9.yAt( 2 ), 22.0 );
|
|
QCOMPARE( l9.yAt( -1 ), 0.0 ); //out of range
|
|
QCOMPARE( l9.yAt( 11 ), 0.0 ); //out of range
|
|
|
|
l9.setYAt( 0, 52.0 );
|
|
QCOMPARE( l9.yAt( 0 ), 52.0 );
|
|
l9.setYAt( 1, 62.0 );
|
|
QCOMPARE( l9.yAt( 1 ), 62.0 );
|
|
l9.setYAt( -1, 52.0 ); //out of range
|
|
l9.setYAt( 11, 52.0 ); //out of range
|
|
|
|
QCOMPARE( l9.zAt( 0 ), 3.0 );
|
|
QCOMPARE( l9.zAt( 1 ), 13.0 );
|
|
QCOMPARE( l9.zAt( 2 ), 23.0 );
|
|
QVERIFY( std::isnan( l9.zAt( -1 ) ) ); //out of range
|
|
QVERIFY( std::isnan( l9.zAt( 11 ) ) ); //out of range
|
|
|
|
l9.setZAt( 0, 53.0 );
|
|
QCOMPARE( l9.zAt( 0 ), 53.0 );
|
|
l9.setZAt( 1, 63.0 );
|
|
QCOMPARE( l9.zAt( 1 ), 63.0 );
|
|
l9.setZAt( -1, 53.0 ); //out of range
|
|
l9.setZAt( 11, 53.0 ); //out of range
|
|
|
|
QCOMPARE( l9.mAt( 0 ), 4.0 );
|
|
QCOMPARE( l9.mAt( 1 ), 14.0 );
|
|
QCOMPARE( l9.mAt( 2 ), 24.0 );
|
|
QVERIFY( std::isnan( l9.mAt( -1 ) ) ); //out of range
|
|
QVERIFY( std::isnan( l9.mAt( 11 ) ) ); //out of range
|
|
|
|
l9.setMAt( 0, 54.0 );
|
|
QCOMPARE( l9.mAt( 0 ), 54.0 );
|
|
l9.setMAt( 1, 64.0 );
|
|
QCOMPARE( l9.mAt( 1 ), 64.0 );
|
|
l9.setMAt( -1, 54.0 ); //out of range
|
|
l9.setMAt( 11, 54.0 ); //out of range
|
|
|
|
//check zAt/setZAt with non-3d linestring
|
|
l9.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 21, 22, 0, 24 ) );
|
|
|
|
//basically we just don't want these to crash
|
|
QVERIFY( std::isnan( l9.zAt( 0 ) ) );
|
|
QVERIFY( std::isnan( l9.zAt( 1 ) ) );
|
|
l9.setZAt( 0, 53.0 );
|
|
l9.setZAt( 1, 63.0 );
|
|
|
|
//check mAt/setMAt with non-measure linestring
|
|
l9.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 )
|
|
<< QgsPoint( 21, 22 ) );
|
|
|
|
//basically we just don't want these to crash
|
|
QVERIFY( std::isnan( l9.mAt( 0 ) ) );
|
|
QVERIFY( std::isnan( l9.mAt( 1 ) ) );
|
|
l9.setMAt( 0, 53.0 );
|
|
l9.setMAt( 1, 63.0 );
|
|
|
|
//append linestring
|
|
|
|
//append to empty
|
|
QgsLineString l10;
|
|
l10.append( 0 );
|
|
QVERIFY( l10.isEmpty() );
|
|
QCOMPARE( l10.numPoints(), 0 );
|
|
|
|
std::unique_ptr<QgsLineString> toAppend( new QgsLineString() );
|
|
toAppend->setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 )
|
|
<< QgsPoint( 21, 22 ) );
|
|
l10.append( toAppend.get() );
|
|
QVERIFY( !l10.is3D() );
|
|
QVERIFY( !l10.isMeasure() );
|
|
QCOMPARE( l10.numPoints(), 3 );
|
|
QCOMPARE( l10.vertexCount(), 3 );
|
|
QCOMPARE( l10.nCoordinates(), 3 );
|
|
QCOMPARE( l10.ringCount(), 1 );
|
|
QCOMPARE( l10.partCount(), 1 );
|
|
QCOMPARE( l10.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( l10.pointN( 0 ), toAppend->pointN( 0 ) );
|
|
QCOMPARE( l10.pointN( 1 ), toAppend->pointN( 1 ) );
|
|
QCOMPARE( l10.pointN( 2 ), toAppend->pointN( 2 ) );
|
|
|
|
//add more points
|
|
toAppend.reset( new QgsLineString() );
|
|
toAppend->setPoints( QgsPointSequence() << QgsPoint( 31, 32 )
|
|
<< QgsPoint( 41, 42 )
|
|
<< QgsPoint( 51, 52 ) );
|
|
l10.append( toAppend.get() );
|
|
QCOMPARE( l10.numPoints(), 6 );
|
|
QCOMPARE( l10.vertexCount(), 6 );
|
|
QCOMPARE( l10.nCoordinates(), 6 );
|
|
QCOMPARE( l10.ringCount(), 1 );
|
|
QCOMPARE( l10.partCount(), 1 );
|
|
QCOMPARE( l10.pointN( 3 ), toAppend->pointN( 0 ) );
|
|
QCOMPARE( l10.pointN( 4 ), toAppend->pointN( 1 ) );
|
|
QCOMPARE( l10.pointN( 5 ), toAppend->pointN( 2 ) );
|
|
|
|
//check dimensionality is inherited from append line if initially empty
|
|
l10.clear();
|
|
toAppend.reset( new QgsLineString() );
|
|
toAppend->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 31, 32, 33, 34 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 41, 42, 43, 44 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 51, 52, 53, 54 ) );
|
|
l10.append( toAppend.get() );
|
|
QVERIFY( l10.is3D() );
|
|
QVERIFY( l10.isMeasure() );
|
|
QCOMPARE( l10.numPoints(), 3 );
|
|
QCOMPARE( l10.ringCount(), 1 );
|
|
QCOMPARE( l10.partCount(), 1 );
|
|
QCOMPARE( l10.wkbType(), QgsWkbTypes::LineStringZM );
|
|
QCOMPARE( l10.pointN( 0 ), toAppend->pointN( 0 ) );
|
|
QCOMPARE( l10.pointN( 1 ), toAppend->pointN( 1 ) );
|
|
QCOMPARE( l10.pointN( 2 ), toAppend->pointN( 2 ) );
|
|
|
|
//append points with z to non z linestring
|
|
l10.clear();
|
|
l10.addVertex( QgsPoint( 1.0, 2.0 ) );
|
|
QVERIFY( !l10.is3D() );
|
|
QCOMPARE( l10.wkbType(), QgsWkbTypes::LineString );
|
|
toAppend.reset( new QgsLineString() );
|
|
toAppend->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 31, 32, 33, 34 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 41, 42, 43, 44 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 51, 52, 53, 54 ) );
|
|
l10.append( toAppend.get() );
|
|
QCOMPARE( l10.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( l10.pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( l10.pointN( 1 ), QgsPoint( 31, 32 ) );
|
|
QCOMPARE( l10.pointN( 2 ), QgsPoint( 41, 42 ) );
|
|
QCOMPARE( l10.pointN( 3 ), QgsPoint( 51, 52 ) );
|
|
|
|
//append points without z/m to linestring with z & m
|
|
l10.clear();
|
|
l10.addVertex( QgsPoint( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, 4.0 ) );
|
|
QVERIFY( l10.is3D() );
|
|
QVERIFY( l10.isMeasure() );
|
|
QCOMPARE( l10.wkbType(), QgsWkbTypes::LineStringZM );
|
|
toAppend.reset( new QgsLineString() );
|
|
toAppend->setPoints( QgsPointSequence() << QgsPoint( 31, 32 )
|
|
<< QgsPoint( 41, 42 )
|
|
<< QgsPoint( 51, 52 ) );
|
|
l10.append( toAppend.get() );
|
|
QCOMPARE( l10.wkbType(), QgsWkbTypes::LineStringZM );
|
|
QCOMPARE( l10.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
QCOMPARE( l10.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 31, 32 ) );
|
|
QCOMPARE( l10.pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 41, 42 ) );
|
|
QCOMPARE( l10.pointN( 3 ), QgsPoint( QgsWkbTypes::PointZM, 51, 52 ) );
|
|
|
|
//25d append
|
|
l10.clear();
|
|
toAppend.reset( new QgsLineString() );
|
|
toAppend->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 31, 32, 33 )
|
|
<< QgsPoint( QgsWkbTypes::Point25D, 41, 42, 43 ) );
|
|
l10.append( toAppend.get() );
|
|
QVERIFY( l10.is3D() );
|
|
QVERIFY( !l10.isMeasure() );
|
|
QCOMPARE( l10.wkbType(), QgsWkbTypes::LineString25D );
|
|
QCOMPARE( l10.pointN( 0 ), QgsPoint( QgsWkbTypes::Point25D, 31, 32, 33 ) );
|
|
QCOMPARE( l10.pointN( 1 ), QgsPoint( QgsWkbTypes::Point25D, 41, 42, 43 ) );
|
|
l10.clear();
|
|
l10.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 11, 12, 33 ) );
|
|
QCOMPARE( l10.wkbType(), QgsWkbTypes::LineString25D );
|
|
l10.append( toAppend.get() );
|
|
QVERIFY( l10.is3D() );
|
|
QVERIFY( !l10.isMeasure() );
|
|
QCOMPARE( l10.wkbType(), QgsWkbTypes::LineString25D );
|
|
QCOMPARE( l10.pointN( 0 ), QgsPoint( QgsWkbTypes::Point25D, 11, 12, 33 ) );
|
|
QCOMPARE( l10.pointN( 1 ), QgsPoint( QgsWkbTypes::Point25D, 31, 32, 33 ) );
|
|
QCOMPARE( l10.pointN( 2 ), QgsPoint( QgsWkbTypes::Point25D, 41, 42, 43 ) );
|
|
|
|
//append another line the closes the original geometry.
|
|
//Make sure there are not duplicit points except start and end point
|
|
l10.clear();
|
|
toAppend.reset( new QgsLineString() );
|
|
toAppend->setPoints( QgsPointSequence()
|
|
<< QgsPoint( 1, 1 )
|
|
<< QgsPoint( 5, 5 )
|
|
<< QgsPoint( 10, 1 ) );
|
|
l10.append( toAppend.get() );
|
|
QCOMPARE( l10.numPoints(), 3 );
|
|
QCOMPARE( l10.vertexCount(), 3 );
|
|
toAppend.reset( new QgsLineString() );
|
|
toAppend->setPoints( QgsPointSequence()
|
|
<< QgsPoint( 10, 1 )
|
|
<< QgsPoint( 1, 1 ) );
|
|
l10.append( toAppend.get() );
|
|
|
|
QVERIFY( l10.isClosed() );
|
|
QCOMPARE( l10.numPoints(), 4 );
|
|
QCOMPARE( l10.vertexCount(), 4 );
|
|
|
|
//equality
|
|
QgsLineString e1;
|
|
QgsLineString e2;
|
|
QVERIFY( e1 == e2 );
|
|
QVERIFY( !( e1 != e2 ) );
|
|
e1.addVertex( QgsPoint( 1, 2 ) );
|
|
QVERIFY( !( e1 == e2 ) ); //different number of vertices
|
|
QVERIFY( e1 != e2 );
|
|
e2.addVertex( QgsPoint( 1, 2 ) );
|
|
QVERIFY( e1 == e2 );
|
|
QVERIFY( !( e1 != e2 ) );
|
|
e1.addVertex( QgsPoint( 1 / 3.0, 4 / 3.0 ) );
|
|
e2.addVertex( QgsPoint( 2 / 6.0, 8 / 6.0 ) );
|
|
QVERIFY( e1 == e2 ); //check non-integer equality
|
|
QVERIFY( !( e1 != e2 ) );
|
|
e1.addVertex( QgsPoint( 7, 8 ) );
|
|
e2.addVertex( QgsPoint( 6, 9 ) );
|
|
QVERIFY( !( e1 == e2 ) ); //different coordinates
|
|
QVERIFY( e1 != e2 );
|
|
QgsLineString e3;
|
|
e3.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 0 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1 / 3.0, 4 / 3.0, 0 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 7, 8, 0 ) );
|
|
QVERIFY( !( e1 == e3 ) ); //different dimension
|
|
QVERIFY( e1 != e3 );
|
|
QgsLineString e4;
|
|
e4.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1 / 3.0, 4 / 3.0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 7, 8, 4 ) );
|
|
QVERIFY( !( e3 == e4 ) ); //different z coordinates
|
|
QVERIFY( e3 != e4 );
|
|
QgsLineString e5;
|
|
e5.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 1 / 3.0, 4 / 3.0, 0, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 7, 8, 0, 3 ) );
|
|
QgsLineString e6;
|
|
e6.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 11 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 1 / 3.0, 4 / 3.0, 0, 12 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 7, 8, 0, 13 ) );
|
|
QVERIFY( !( e5 == e6 ) ); //different m values
|
|
QVERIFY( e5 != e6 );
|
|
|
|
QVERIFY( e6 != QgsCircularString() );
|
|
|
|
//close/isClosed
|
|
QgsLineString l11;
|
|
QVERIFY( !l11.isClosed() );
|
|
l11.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 2 )
|
|
<< QgsPoint( 11, 22 )
|
|
<< QgsPoint( 1, 22 ) );
|
|
QVERIFY( !l11.isClosed() );
|
|
QCOMPARE( l11.numPoints(), 4 );
|
|
QCOMPARE( l11.area(), 0.0 );
|
|
QCOMPARE( l11.perimeter(), 0.0 );
|
|
l11.close();
|
|
QVERIFY( l11.isClosed() );
|
|
QCOMPARE( l11.numPoints(), 5 );
|
|
QCOMPARE( l11.vertexCount(), 5 );
|
|
QCOMPARE( l11.nCoordinates(), 5 );
|
|
QCOMPARE( l11.ringCount(), 1 );
|
|
QCOMPARE( l11.partCount(), 1 );
|
|
QCOMPARE( l11.pointN( 4 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( l11.area(), 0.0 );
|
|
QCOMPARE( l11.perimeter(), 0.0 );
|
|
//try closing already closed line, should be no change
|
|
l11.close();
|
|
QVERIFY( l11.isClosed() );
|
|
QCOMPARE( l11.numPoints(), 5 );
|
|
QCOMPARE( l11.pointN( 4 ), QgsPoint( 1, 2 ) );
|
|
//test that m values aren't considered when testing for closedness
|
|
l11.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 11, 2, 0, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 11, 22, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 6 ) );
|
|
QVERIFY( l11.isClosed() );
|
|
|
|
//close with z and m
|
|
QgsLineString l12;
|
|
l12.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
l12.close();
|
|
QCOMPARE( l12.pointN( 4 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
|
|
|
|
//polygonf
|
|
QgsLineString l13;
|
|
l13.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
|
|
QPolygonF poly = l13.asQPolygonF();
|
|
QCOMPARE( poly.count(), 4 );
|
|
QCOMPARE( poly.at( 0 ).x(), 1.0 );
|
|
QCOMPARE( poly.at( 0 ).y(), 2.0 );
|
|
QCOMPARE( poly.at( 1 ).x(), 11.0 );
|
|
QCOMPARE( poly.at( 1 ).y(), 2.0 );
|
|
QCOMPARE( poly.at( 2 ).x(), 11.0 );
|
|
QCOMPARE( poly.at( 2 ).y(), 22.0 );
|
|
QCOMPARE( poly.at( 3 ).x(), 1.0 );
|
|
QCOMPARE( poly.at( 3 ).y(), 22.0 );
|
|
|
|
// clone tests. At the same time, check segmentize as the result should
|
|
// be equal to a clone for LineStrings
|
|
QgsLineString l14;
|
|
l14.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 2 )
|
|
<< QgsPoint( 11, 22 )
|
|
<< QgsPoint( 1, 22 ) );
|
|
std::unique_ptr<QgsLineString> cloned( l14.clone() );
|
|
QCOMPARE( cloned->numPoints(), 4 );
|
|
QCOMPARE( cloned->vertexCount(), 4 );
|
|
QCOMPARE( cloned->ringCount(), 1 );
|
|
QCOMPARE( cloned->partCount(), 1 );
|
|
QCOMPARE( cloned->wkbType(), QgsWkbTypes::LineString );
|
|
QVERIFY( !cloned->is3D() );
|
|
QVERIFY( !cloned->isMeasure() );
|
|
QCOMPARE( cloned->pointN( 0 ), l14.pointN( 0 ) );
|
|
QCOMPARE( cloned->pointN( 1 ), l14.pointN( 1 ) );
|
|
QCOMPARE( cloned->pointN( 2 ), l14.pointN( 2 ) );
|
|
QCOMPARE( cloned->pointN( 3 ), l14.pointN( 3 ) );
|
|
std::unique_ptr< QgsLineString > segmentized( static_cast< QgsLineString * >( l14.segmentize() ) );
|
|
QCOMPARE( segmentized->numPoints(), 4 );
|
|
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineString );
|
|
QVERIFY( !segmentized->is3D() );
|
|
QVERIFY( !segmentized->isMeasure() );
|
|
QCOMPARE( segmentized->pointN( 0 ), l14.pointN( 0 ) );
|
|
QCOMPARE( segmentized->pointN( 1 ), l14.pointN( 1 ) );
|
|
QCOMPARE( segmentized->pointN( 2 ), l14.pointN( 2 ) );
|
|
QCOMPARE( segmentized->pointN( 3 ), l14.pointN( 3 ) );
|
|
|
|
//clone with Z/M
|
|
l14.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
cloned.reset( l14.clone() );
|
|
QCOMPARE( cloned->numPoints(), 4 );
|
|
QCOMPARE( cloned->wkbType(), QgsWkbTypes::LineStringZM );
|
|
QVERIFY( cloned->is3D() );
|
|
QVERIFY( cloned->isMeasure() );
|
|
QCOMPARE( cloned->pointN( 0 ), l14.pointN( 0 ) );
|
|
QCOMPARE( cloned->pointN( 1 ), l14.pointN( 1 ) );
|
|
QCOMPARE( cloned->pointN( 2 ), l14.pointN( 2 ) );
|
|
QCOMPARE( cloned->pointN( 3 ), l14.pointN( 3 ) );
|
|
segmentized.reset( static_cast< QgsLineString * >( l14.segmentize() ) );
|
|
QCOMPARE( segmentized->numPoints(), 4 );
|
|
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineStringZM );
|
|
QVERIFY( segmentized->is3D() );
|
|
QVERIFY( segmentized->isMeasure() );
|
|
QCOMPARE( segmentized->pointN( 0 ), l14.pointN( 0 ) );
|
|
QCOMPARE( segmentized->pointN( 1 ), l14.pointN( 1 ) );
|
|
QCOMPARE( segmentized->pointN( 2 ), l14.pointN( 2 ) );
|
|
QCOMPARE( segmentized->pointN( 3 ), l14.pointN( 3 ) );
|
|
|
|
//clone an empty line
|
|
l14.clear();
|
|
cloned.reset( l14.clone() );
|
|
QVERIFY( cloned->isEmpty() );
|
|
QCOMPARE( cloned->numPoints(), 0 );
|
|
QVERIFY( !cloned->is3D() );
|
|
QVERIFY( !cloned->isMeasure() );
|
|
QCOMPARE( cloned->wkbType(), QgsWkbTypes::LineString );
|
|
segmentized.reset( static_cast< QgsLineString * >( l14.segmentize() ) );
|
|
QVERIFY( segmentized->isEmpty() );
|
|
QCOMPARE( segmentized->numPoints(), 0 );
|
|
QVERIFY( !segmentized->is3D() );
|
|
QVERIFY( !segmentized->isMeasure() );
|
|
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineString );
|
|
|
|
//to/from WKB
|
|
QgsLineString l15;
|
|
l15.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
QByteArray wkb15 = l15.asWkb();
|
|
QgsLineString l16;
|
|
QgsConstWkbPtr wkb15ptr( wkb15 );
|
|
l16.fromWkb( wkb15ptr );
|
|
QCOMPARE( l16.numPoints(), 4 );
|
|
QCOMPARE( l16.vertexCount(), 4 );
|
|
QCOMPARE( l16.nCoordinates(), 4 );
|
|
QCOMPARE( l16.ringCount(), 1 );
|
|
QCOMPARE( l16.partCount(), 1 );
|
|
QCOMPARE( l16.wkbType(), QgsWkbTypes::LineStringZM );
|
|
QVERIFY( l16.is3D() );
|
|
QVERIFY( l16.isMeasure() );
|
|
QCOMPARE( l16.pointN( 0 ), l15.pointN( 0 ) );
|
|
QCOMPARE( l16.pointN( 1 ), l15.pointN( 1 ) );
|
|
QCOMPARE( l16.pointN( 2 ), l15.pointN( 2 ) );
|
|
QCOMPARE( l16.pointN( 3 ), l15.pointN( 3 ) );
|
|
|
|
//bad WKB - check for no crash
|
|
l16.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !l16.fromWkb( nullPtr ) );
|
|
QCOMPARE( l16.wkbType(), QgsWkbTypes::LineString );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkb16 = point.asWkb();
|
|
QgsConstWkbPtr wkb16ptr( wkb16 );
|
|
QVERIFY( !l16.fromWkb( wkb16ptr ) );
|
|
QCOMPARE( l16.wkbType(), QgsWkbTypes::LineString );
|
|
|
|
//to/from WKT
|
|
QgsLineString l17;
|
|
l17.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
|
|
QString wkt = l17.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsLineString l18;
|
|
QVERIFY( l18.fromWkt( wkt ) );
|
|
QCOMPARE( l18.numPoints(), 4 );
|
|
QCOMPARE( l18.wkbType(), QgsWkbTypes::LineStringZM );
|
|
QVERIFY( l18.is3D() );
|
|
QVERIFY( l18.isMeasure() );
|
|
QCOMPARE( l18.pointN( 0 ), l17.pointN( 0 ) );
|
|
QCOMPARE( l18.pointN( 1 ), l17.pointN( 1 ) );
|
|
QCOMPARE( l18.pointN( 2 ), l17.pointN( 2 ) );
|
|
QCOMPARE( l18.pointN( 3 ), l17.pointN( 3 ) );
|
|
|
|
//bad WKT
|
|
QVERIFY( !l18.fromWkt( "Polygon()" ) );
|
|
QVERIFY( l18.isEmpty() );
|
|
QCOMPARE( l18.numPoints(), 0 );
|
|
QVERIFY( !l18.is3D() );
|
|
QVERIFY( !l18.isMeasure() );
|
|
QCOMPARE( l18.wkbType(), QgsWkbTypes::LineString );
|
|
|
|
//asGML2
|
|
QgsLineString exportLine;
|
|
exportLine.setPoints( QgsPointSequence() << QgsPoint( 31, 32 )
|
|
<< QgsPoint( 41, 42 )
|
|
<< QgsPoint( 51, 52 ) );
|
|
QgsLineString exportLineFloat;
|
|
exportLineFloat.setPoints( QgsPointSequence() << QgsPoint( 1 / 3.0, 2 / 3.0 )
|
|
<< QgsPoint( 1 + 1 / 3.0, 1 + 2 / 3.0 )
|
|
<< QgsPoint( 2 + 1 / 3.0, 2 + 2 / 3.0 ) );
|
|
QDomDocument doc( QStringLiteral( "gml" ) );
|
|
QString expectedGML2( QStringLiteral( "<LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">31,32 41,42 51,52</coordinates></LineString>" ) );
|
|
QGSCOMPAREGML( elemToString( exportLine.asGML2( doc ) ), expectedGML2 );
|
|
QString expectedGML2prec3( QStringLiteral( "<LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0.333,0.667 1.333,1.667 2.333,2.667</coordinates></LineString>" ) );
|
|
QGSCOMPAREGML( elemToString( exportLineFloat.asGML2( doc, 3 ) ), expectedGML2prec3 );
|
|
|
|
//asGML3
|
|
QString expectedGML3( QStringLiteral( "<LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">31 32 41 42 51 52</posList></LineString>" ) );
|
|
QCOMPARE( elemToString( exportLine.asGML3( doc ) ), expectedGML3 );
|
|
QString expectedGML3prec3( QStringLiteral( "<LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">0.333 0.667 1.333 1.667 2.333 2.667</posList></LineString>" ) );
|
|
QCOMPARE( elemToString( exportLineFloat.asGML3( doc, 3 ) ), expectedGML3prec3 );
|
|
|
|
//asJSON
|
|
QString expectedJson( QStringLiteral( "{\"type\": \"LineString\", \"coordinates\": [ [31, 32], [41, 42], [51, 52]]}" ) );
|
|
QCOMPARE( exportLine.asJSON(), expectedJson );
|
|
QString expectedJsonPrec3( QStringLiteral( "{\"type\": \"LineString\", \"coordinates\": [ [0.333, 0.667], [1.333, 1.667], [2.333, 2.667]]}" ) );
|
|
QCOMPARE( exportLineFloat.asJSON( 3 ), expectedJsonPrec3 );
|
|
|
|
//length
|
|
QgsLineString l19;
|
|
QCOMPARE( l19.length(), 0.0 );
|
|
l19.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
QCOMPARE( l19.length(), 23.0 );
|
|
|
|
//startPoint
|
|
QCOMPARE( l19.startPoint(), QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 ) );
|
|
|
|
//endPoint
|
|
QCOMPARE( l19.endPoint(), QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
|
|
//bad start/end points. Test that this doesn't crash.
|
|
l19.clear();
|
|
QCOMPARE( l19.startPoint(), QgsPoint() );
|
|
QCOMPARE( l19.endPoint(), QgsPoint() );
|
|
|
|
//curveToLine - no segmentation required, so should return a clone
|
|
l19.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
segmentized.reset( l19.curveToLine() );
|
|
QCOMPARE( segmentized->numPoints(), 3 );
|
|
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineStringZM );
|
|
QVERIFY( segmentized->is3D() );
|
|
QVERIFY( segmentized->isMeasure() );
|
|
QCOMPARE( segmentized->pointN( 0 ), l19.pointN( 0 ) );
|
|
QCOMPARE( segmentized->pointN( 1 ), l19.pointN( 1 ) );
|
|
QCOMPARE( segmentized->pointN( 2 ), l19.pointN( 2 ) );
|
|
|
|
// points
|
|
QgsLineString l20;
|
|
QgsPointSequence points;
|
|
l20.points( points );
|
|
QVERIFY( l20.isEmpty() );
|
|
l20.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
l20.points( points );
|
|
QCOMPARE( points.count(), 3 );
|
|
QCOMPARE( points.at( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 ) );
|
|
QCOMPARE( points.at( 1 ), QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 ) );
|
|
QCOMPARE( points.at( 2 ), QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
|
|
//CRS transform
|
|
QgsCoordinateReferenceSystem sourceSrs;
|
|
sourceSrs.createFromSrid( 3994 );
|
|
QgsCoordinateReferenceSystem destSrs;
|
|
destSrs.createFromSrid( 4202 ); // want a transform with ellipsoid change
|
|
QgsCoordinateTransform tr( sourceSrs, destSrs );
|
|
|
|
// 2d CRS transform
|
|
QgsLineString l21;
|
|
l21.setPoints( QgsPointSequence() << QgsPoint( 6374985, -3626584 )
|
|
<< QgsPoint( 6474985, -3526584 ) );
|
|
l21.transform( tr, QgsCoordinateTransform::ForwardTransform );
|
|
QGSCOMPARENEAR( l21.pointN( 0 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( l21.pointN( 0 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( l21.pointN( 1 ).x(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( l21.pointN( 1 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( l21.boundingBox().xMinimum(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( l21.boundingBox().yMinimum(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( l21.boundingBox().xMaximum(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( l21.boundingBox().yMaximum(), -38.7999, 0.001 );
|
|
|
|
//3d CRS transform
|
|
QgsLineString l22;
|
|
l22.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 6374985, -3626584, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 6474985, -3526584, 3, 4 ) );
|
|
l22.transform( tr, QgsCoordinateTransform::ForwardTransform );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).z(), 1.0, 0.001 );
|
|
QCOMPARE( l22.pointN( 0 ).m(), 2.0 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).x(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).z(), 3.0, 0.001 );
|
|
QCOMPARE( l22.pointN( 1 ).m(), 4.0 );
|
|
|
|
//reverse transform
|
|
l22.transform( tr, QgsCoordinateTransform::ReverseTransform );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).x(), 6374985, 0.01 );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).y(), -3626584, 0.01 );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).z(), 1, 0.001 );
|
|
QCOMPARE( l22.pointN( 0 ).m(), 2.0 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).x(), 6474985, 0.01 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).y(), -3526584, 0.01 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).z(), 3, 0.001 );
|
|
QCOMPARE( l22.pointN( 1 ).m(), 4.0 );
|
|
|
|
//z value transform
|
|
l22.transform( tr, QgsCoordinateTransform::ForwardTransform, true );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).z(), -19.249066, 0.001 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).z(), -21.092128, 0.001 );
|
|
l22.transform( tr, QgsCoordinateTransform::ReverseTransform, true );
|
|
QGSCOMPARENEAR( l22.pointN( 0 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( l22.pointN( 1 ).z(), 3.0, 0.001 );
|
|
|
|
//QTransform transform
|
|
QTransform qtr = QTransform::fromScale( 2, 3 );
|
|
QgsLineString l23;
|
|
l23.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
l23.transform( qtr );
|
|
QCOMPARE( l23.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 2, 6, 3, 4 ) );
|
|
QCOMPARE( l23.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 22, 36, 13, 14 ) );
|
|
QCOMPARE( l23.boundingBox(), QgsRectangle( 2, 6, 22, 36 ) );
|
|
|
|
//insert vertex
|
|
|
|
//insert vertex in empty line
|
|
QgsLineString l24;
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QCOMPARE( l24.numPoints(), 1 );
|
|
QVERIFY( !l24.is3D() );
|
|
QVERIFY( !l24.isMeasure() );
|
|
QCOMPARE( l24.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( l24.pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
|
|
//insert 4d vertex in empty line, should set line to 4d
|
|
l24.clear();
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( QgsWkbTypes::PointZM, 6.0, 7.0, 1.0, 2.0 ) ) );
|
|
QCOMPARE( l24.numPoints(), 1 );
|
|
QVERIFY( l24.is3D() );
|
|
QVERIFY( l24.isMeasure() );
|
|
QCOMPARE( l24.wkbType(), QgsWkbTypes::LineStringZM );
|
|
QCOMPARE( l24.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 6.0, 7.0, 1.0, 2.0 ) );
|
|
|
|
//2d line
|
|
l24.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) );
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QCOMPARE( l24.numPoints(), 4 );
|
|
QVERIFY( !l24.is3D() );
|
|
QVERIFY( !l24.isMeasure() );
|
|
QCOMPARE( l24.wkbType(), QgsWkbTypes::LineString );
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 8.0, 9.0 ) ) );
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 2 ), QgsPoint( 18.0, 19.0 ) ) );
|
|
QCOMPARE( l24.pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( l24.pointN( 1 ), QgsPoint( 8.0, 9.0 ) );
|
|
QCOMPARE( l24.pointN( 2 ), QgsPoint( 18.0, 19.0 ) );
|
|
QCOMPARE( l24.pointN( 3 ), QgsPoint( 1.0, 2.0 ) );
|
|
QCOMPARE( l24.pointN( 4 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( l24.pointN( 5 ), QgsPoint( 21.0, 22.0 ) );
|
|
//insert vertex at end
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 6 ), QgsPoint( 31.0, 32.0 ) ) );
|
|
QCOMPARE( l24.pointN( 6 ), QgsPoint( 31.0, 32.0 ) );
|
|
QCOMPARE( l24.numPoints(), 7 );
|
|
|
|
//insert vertex past end
|
|
QVERIFY( !l24.insertVertex( QgsVertexId( 0, 0, 8 ), QgsPoint( 41.0, 42.0 ) ) );
|
|
QCOMPARE( l24.numPoints(), 7 );
|
|
|
|
//insert vertex before start
|
|
QVERIFY( !l24.insertVertex( QgsVertexId( 0, 0, -18 ), QgsPoint( 41.0, 42.0 ) ) );
|
|
QCOMPARE( l24.numPoints(), 7 );
|
|
|
|
//insert 4d vertex in 4d line
|
|
l24.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) ) );
|
|
QCOMPARE( l24.numPoints(), 4 );
|
|
QCOMPARE( l24.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
|
|
//insert 2d vertex in 4d line
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 101, 102 ) ) );
|
|
QCOMPARE( l24.numPoints(), 5 );
|
|
QCOMPARE( l24.wkbType(), QgsWkbTypes::LineStringZM );
|
|
QCOMPARE( l24.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 101, 102 ) );
|
|
|
|
//insert 4d vertex in 2d line
|
|
l24.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) );
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( QgsWkbTypes::PointZM, 101, 102, 103, 104 ) ) );
|
|
QCOMPARE( l24.numPoints(), 4 );
|
|
QCOMPARE( l24.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( l24.pointN( 0 ), QgsPoint( QgsWkbTypes::Point, 101, 102 ) );
|
|
|
|
//insert first vertex as Point25D
|
|
l24.clear();
|
|
QVERIFY( l24.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( QgsWkbTypes::Point25D, 101, 102, 103 ) ) );
|
|
QCOMPARE( l24.wkbType(), QgsWkbTypes::LineString25D );
|
|
QCOMPARE( l24.pointN( 0 ), QgsPoint( QgsWkbTypes::Point25D, 101, 102, 103 ) );
|
|
|
|
//move vertex
|
|
|
|
//empty line
|
|
QgsLineString l25;
|
|
QVERIFY( !l25.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( l25.isEmpty() );
|
|
|
|
//valid line
|
|
l25.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) );
|
|
QVERIFY( l25.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( l25.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 16.0, 17.0 ) ) );
|
|
QVERIFY( l25.moveVertex( QgsVertexId( 0, 0, 2 ), QgsPoint( 26.0, 27.0 ) ) );
|
|
QCOMPARE( l25.pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( l25.pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( l25.pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
|
|
//out of range
|
|
QVERIFY( !l25.moveVertex( QgsVertexId( 0, 0, -1 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !l25.moveVertex( QgsVertexId( 0, 0, 10 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QCOMPARE( l25.pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( l25.pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( l25.pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
|
|
//move 4d point in 4d line
|
|
l25.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
QVERIFY( l25.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( QgsWkbTypes::PointZM, 6, 7, 12, 13 ) ) );
|
|
QCOMPARE( l25.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 6, 7, 12, 13 ) );
|
|
|
|
//move 2d point in 4d line, existing z/m should be maintained
|
|
QVERIFY( l25.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 34, 35 ) ) );
|
|
QCOMPARE( l25.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 34, 35, 12, 13 ) );
|
|
|
|
//move 4d point in 2d line
|
|
l25.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) );
|
|
QVERIFY( l25.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( QgsWkbTypes::PointZM, 3, 4, 2, 3 ) ) );
|
|
QCOMPARE( l25.pointN( 0 ), QgsPoint( 3, 4 ) );
|
|
|
|
|
|
//delete vertex
|
|
|
|
//empty line
|
|
QgsLineString l26;
|
|
QVERIFY( !l26.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( l26.isEmpty() );
|
|
|
|
//valid line
|
|
l26.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
//out of range vertices
|
|
QVERIFY( !l26.deleteVertex( QgsVertexId( 0, 0, -1 ) ) );
|
|
QVERIFY( !l26.deleteVertex( QgsVertexId( 0, 0, 100 ) ) );
|
|
|
|
//valid vertices
|
|
QVERIFY( l26.deleteVertex( QgsVertexId( 0, 0, 1 ) ) );
|
|
QCOMPARE( l26.numPoints(), 2 );
|
|
QCOMPARE( l26.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 ) );
|
|
QCOMPARE( l26.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
//removing the second to last vertex removes both remaining vertices
|
|
QVERIFY( l26.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( l26.numPoints(), 0 );
|
|
QVERIFY( !l26.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( l26.isEmpty() );
|
|
|
|
//reversed
|
|
QgsLineString l27;
|
|
std::unique_ptr< QgsLineString > reversed( l27.reversed() );
|
|
QVERIFY( reversed->isEmpty() );
|
|
l27.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
reversed.reset( l27.reversed() );
|
|
QCOMPARE( reversed->numPoints(), 3 );
|
|
QCOMPARE( reversed->wkbType(), QgsWkbTypes::LineStringZM );
|
|
QVERIFY( reversed->is3D() );
|
|
QVERIFY( reversed->isMeasure() );
|
|
QCOMPARE( reversed->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
QCOMPARE( reversed->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 ) );
|
|
QCOMPARE( reversed->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 ) );
|
|
|
|
//addZValue
|
|
|
|
QgsLineString l28;
|
|
QCOMPARE( l28.wkbType(), QgsWkbTypes::LineString );
|
|
QVERIFY( l28.addZValue() );
|
|
QCOMPARE( l28.wkbType(), QgsWkbTypes::LineStringZ );
|
|
l28.clear();
|
|
QVERIFY( l28.addZValue() );
|
|
QCOMPARE( l28.wkbType(), QgsWkbTypes::LineStringZ );
|
|
//2d line
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
QVERIFY( l28.addZValue( 2 ) );
|
|
QVERIFY( l28.is3D() );
|
|
QCOMPARE( l28.wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( l28.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ) );
|
|
QCOMPARE( l28.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZ, 11, 12, 2 ) );
|
|
QVERIFY( !l28.addZValue( 4 ) ); //already has z value, test that existing z is unchanged
|
|
QCOMPARE( l28.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ) );
|
|
QCOMPARE( l28.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZ, 11, 12, 2 ) );
|
|
//linestring with m
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 4 ) );
|
|
QVERIFY( l28.addZValue( 5 ) );
|
|
QVERIFY( l28.is3D() );
|
|
QVERIFY( l28.isMeasure() );
|
|
QCOMPARE( l28.wkbType(), QgsWkbTypes::LineStringZM );
|
|
QCOMPARE( l28.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 5, 3 ) );
|
|
QCOMPARE( l28.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 5, 4 ) );
|
|
//linestring25d
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::Point25D, 11, 12, 4 ) );
|
|
QCOMPARE( l28.wkbType(), QgsWkbTypes::LineString25D );
|
|
QVERIFY( !l28.addZValue( 5 ) );
|
|
QCOMPARE( l28.wkbType(), QgsWkbTypes::LineString25D );
|
|
QCOMPARE( l28.pointN( 0 ), QgsPoint( QgsWkbTypes::Point25D, 1, 2, 3 ) );
|
|
QCOMPARE( l28.pointN( 1 ), QgsPoint( QgsWkbTypes::Point25D, 11, 12, 4 ) );
|
|
|
|
//addMValue
|
|
|
|
QgsLineString l29;
|
|
QCOMPARE( l29.wkbType(), QgsWkbTypes::LineString );
|
|
QVERIFY( l29.addMValue() );
|
|
QCOMPARE( l29.wkbType(), QgsWkbTypes::LineStringM );
|
|
l29.clear();
|
|
QVERIFY( l29.addMValue() );
|
|
QCOMPARE( l29.wkbType(), QgsWkbTypes::LineStringM );
|
|
//2d line
|
|
l29.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
QVERIFY( l29.addMValue( 2 ) );
|
|
QVERIFY( !l29.is3D() );
|
|
QVERIFY( l29.isMeasure() );
|
|
QCOMPARE( l29.wkbType(), QgsWkbTypes::LineStringM );
|
|
QCOMPARE( l29.pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 2 ) );
|
|
QCOMPARE( l29.pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 2 ) );
|
|
QVERIFY( !l29.addMValue( 4 ) ); //already has m value, test that existing m is unchanged
|
|
QCOMPARE( l29.pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 2 ) );
|
|
QCOMPARE( l29.pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 2 ) );
|
|
//linestring with z
|
|
l29.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 4 ) );
|
|
QVERIFY( l29.addMValue( 5 ) );
|
|
QVERIFY( l29.is3D() );
|
|
QVERIFY( l29.isMeasure() );
|
|
QCOMPARE( l29.wkbType(), QgsWkbTypes::LineStringZM );
|
|
QCOMPARE( l29.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 5 ) );
|
|
QCOMPARE( l29.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 ) );
|
|
//linestring25d, should become LineStringZM
|
|
l29.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::Point25D, 11, 12, 4 ) );
|
|
QCOMPARE( l29.wkbType(), QgsWkbTypes::LineString25D );
|
|
QVERIFY( l29.addMValue( 5 ) );
|
|
QVERIFY( l29.is3D() );
|
|
QVERIFY( l29.isMeasure() );
|
|
QCOMPARE( l29.wkbType(), QgsWkbTypes::LineStringZM );
|
|
QCOMPARE( l29.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 5 ) );
|
|
QCOMPARE( l29.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 ) );
|
|
|
|
|
|
//dropZValue
|
|
QgsLineString l28d;
|
|
QVERIFY( !l28d.dropZValue() );
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
QVERIFY( !l28d.dropZValue() );
|
|
l28d.addZValue( 1.0 );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineStringZ );
|
|
QVERIFY( l28d.is3D() );
|
|
QVERIFY( l28d.dropZValue() );
|
|
QVERIFY( !l28d.is3D() );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::Point, 1, 2 ) );
|
|
QCOMPARE( l28d.pointN( 1 ), QgsPoint( QgsWkbTypes::Point, 11, 12 ) );
|
|
QVERIFY( !l28d.dropZValue() ); //already dropped
|
|
//linestring with m
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 3, 4 ) );
|
|
QVERIFY( l28d.dropZValue() );
|
|
QVERIFY( !l28d.is3D() );
|
|
QVERIFY( l28d.isMeasure() );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineStringM );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QCOMPARE( l28d.pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 4 ) );
|
|
//linestring25d
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::Point25D, 11, 12, 4 ) );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineString25D );
|
|
QVERIFY( l28d.dropZValue() );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::Point, 1, 2 ) );
|
|
QCOMPARE( l28d.pointN( 1 ), QgsPoint( QgsWkbTypes::Point, 11, 12 ) );
|
|
|
|
//dropMValue
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
QVERIFY( !l28d.dropMValue() );
|
|
l28d.addMValue( 1.0 );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineStringM );
|
|
QVERIFY( l28d.isMeasure() );
|
|
QVERIFY( l28d.dropMValue() );
|
|
QVERIFY( !l28d.isMeasure() );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::Point, 1, 2 ) );
|
|
QCOMPARE( l28d.pointN( 1 ), QgsPoint( QgsWkbTypes::Point, 11, 12 ) );
|
|
QVERIFY( !l28d.dropMValue() ); //already dropped
|
|
//linestring with z
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 3, 4 ) );
|
|
QVERIFY( l28d.dropMValue() );
|
|
QVERIFY( !l28d.isMeasure() );
|
|
QVERIFY( l28d.is3D() );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3, 0 ) );
|
|
QCOMPARE( l28d.pointN( 1 ), QgsPoint( QgsWkbTypes::PointZ, 11, 12, 3, 0 ) );
|
|
|
|
//convertTo
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
QVERIFY( l28d.convertTo( QgsWkbTypes::LineString ) );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineString );
|
|
QVERIFY( l28d.convertTo( QgsWkbTypes::LineStringZ ) );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2 ) );
|
|
l28d.setZAt( 0, 5.0 );
|
|
QVERIFY( l28d.convertTo( QgsWkbTypes::LineString25D ) );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineString25D );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::Point25D, 1, 2, 5.0 ) );
|
|
QVERIFY( l28d.convertTo( QgsWkbTypes::LineStringZM ) );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineStringZM );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 5.0 ) );
|
|
l28d.setMAt( 0, 6.0 );
|
|
QVERIFY( l28d.convertTo( QgsWkbTypes::LineStringM ) );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineStringM );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0.0, 6.0 ) );
|
|
QVERIFY( l28d.convertTo( QgsWkbTypes::LineString ) );
|
|
QCOMPARE( l28d.wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( l28d.pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QVERIFY( !l28d.convertTo( QgsWkbTypes::Polygon ) );
|
|
|
|
//isRing
|
|
QgsLineString l30;
|
|
QVERIFY( !l30.isRing() );
|
|
l30.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 2 ) );
|
|
QVERIFY( !l30.isRing() ); //<4 points
|
|
l30.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 31, 32 ) );
|
|
QVERIFY( !l30.isRing() ); //not closed
|
|
l30.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 1, 2 ) );
|
|
QVERIFY( l30.isRing() );
|
|
|
|
//coordinateSequence
|
|
QgsLineString l31;
|
|
QgsCoordinateSequence coords = l31.coordinateSequence();
|
|
QCOMPARE( coords.count(), 1 );
|
|
QCOMPARE( coords.at( 0 ).count(), 1 );
|
|
QVERIFY( coords.at( 0 ).at( 0 ).isEmpty() );
|
|
l31.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
coords = l31.coordinateSequence();
|
|
QCOMPARE( coords.count(), 1 );
|
|
QCOMPARE( coords.at( 0 ).count(), 1 );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).count(), 3 );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).at( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 ) );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).at( 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 ) );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).at( 2 ), QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
|
|
//nextVertex
|
|
|
|
QgsLineString l32;
|
|
QgsVertexId v;
|
|
QgsPoint p;
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
v = QgsVertexId( 0, 0, -2 );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
v = QgsVertexId( 0, 0, 10 );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
//LineString
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
v = QgsVertexId( 0, 0, 2 ); //out of range
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
v = QgsVertexId( 0, 0, -5 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
v = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( 1, 2 ) );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( 11, 12 ) );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
v = QgsVertexId( 0, 1, 0 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 1 ) ); //test that ring number is maintained
|
|
QCOMPARE( p, QgsPoint( 11, 12 ) );
|
|
v = QgsVertexId( 1, 0, 0 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 1, 0, 1 ) ); //test that part number is maintained
|
|
QCOMPARE( p, QgsPoint( 11, 12 ) );
|
|
|
|
//LineStringZ
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
v = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
//LineStringM
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
v = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
//LineStringZM
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
v = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
//LineString25D
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::Point25D, 11, 12, 13 ) );
|
|
v = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::Point25D, 1, 2, 3 ) );
|
|
QVERIFY( l32.nextVertex( v, p ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::Point25D, 11, 12, 13 ) );
|
|
QVERIFY( !l32.nextVertex( v, p ) );
|
|
|
|
//vertexAt and pointAt
|
|
QgsLineString l33;
|
|
l33.vertexAt( QgsVertexId( 0, 0, -10 ) ); //out of bounds, check for no crash
|
|
l33.vertexAt( QgsVertexId( 0, 0, 10 ) ); //out of bounds, check for no crash
|
|
QgsVertexId::VertexType type;
|
|
QVERIFY( !l33.pointAt( -10, p, type ) );
|
|
QVERIFY( !l33.pointAt( 10, p, type ) );
|
|
//LineString
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
l33.vertexAt( QgsVertexId( 0, 0, -10 ) );
|
|
l33.vertexAt( QgsVertexId( 0, 0, 10 ) ); //out of bounds, check for no crash
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( 11, 12 ) );
|
|
QVERIFY( !l33.pointAt( -10, p, type ) );
|
|
QVERIFY( !l33.pointAt( 10, p, type ) );
|
|
QVERIFY( l33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( 1, 2 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( l33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( 11, 12 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
//LineStringZ
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
QVERIFY( l33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( l33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
//LineStringM
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
QVERIFY( l33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( l33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
//LineStringZM
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
QVERIFY( l33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( l33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
//LineString25D
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::Point25D, 11, 12, 13 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::Point25D, 1, 2, 3 ) );
|
|
QCOMPARE( l33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::Point25D, 11, 12, 13 ) );
|
|
QVERIFY( l33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::Point25D, 1, 2, 3 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( l33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::Point25D, 11, 12, 13 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
|
|
//centroid
|
|
QgsLineString l34;
|
|
QCOMPARE( l34.centroid(), QgsPoint() );
|
|
l34.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) );
|
|
QCOMPARE( l34.centroid(), QgsPoint( 5, 10 ) );
|
|
l34.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 20, 10 ) );
|
|
QCOMPARE( l34.centroid(), QgsPoint( 10, 5 ) );
|
|
l34.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 9 ) << QgsPoint( 2, 9 ) << QgsPoint( 2, 0 ) );
|
|
QCOMPARE( l34.centroid(), QgsPoint( 1, 4.95 ) );
|
|
//linestring with 0 length segment
|
|
l34.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 9 ) << QgsPoint( 2, 9 ) << QgsPoint( 2, 9 ) << QgsPoint( 2, 0 ) );
|
|
QCOMPARE( l34.centroid(), QgsPoint( 1, 4.95 ) );
|
|
//linestring with 0 total length segment
|
|
l34.setPoints( QgsPointSequence() << QgsPoint( 5, 4 ) << QgsPoint( 5, 4 ) << QgsPoint( 5, 4 ) );
|
|
QCOMPARE( l34.centroid(), QgsPoint( 5, 4 ) );
|
|
|
|
//closest segment
|
|
QgsLineString l35;
|
|
bool leftOf = false;
|
|
p = QgsPoint(); // reset all coords to zero
|
|
( void )l35.closestSegment( QgsPoint( 1, 2 ), p, v ); //empty line, just want no crash
|
|
l35.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) );
|
|
QVERIFY( l35.closestSegment( QgsPoint( 5, 10 ), p, v ) < 0 );
|
|
l35.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 10, 10 ) );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 4, 11 ), p, v, &leftOf ), 2.0, 4 * DBL_EPSILON );
|
|
QCOMPARE( p, QgsPoint( 5, 10 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 8, 11 ), p, v, &leftOf ), 1.0, 4 * DBL_EPSILON );
|
|
QCOMPARE( p, QgsPoint( 8, 10 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 8, 9 ), p, v, &leftOf ), 1.0, 4 * DBL_EPSILON );
|
|
QCOMPARE( p, QgsPoint( 8, 10 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 11, 9 ), p, v, &leftOf ), 2.0, 4 * DBL_EPSILON );
|
|
QCOMPARE( p, QgsPoint( 10, 10 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
l35.setPoints( QgsPointSequence() << QgsPoint( 5, 10 )
|
|
<< QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 15 ) );
|
|
QGSCOMPARENEAR( l35.closestSegment( QgsPoint( 11, 12 ), p, v, &leftOf ), 1.0, 4 * DBL_EPSILON );
|
|
QCOMPARE( p, QgsPoint( 10, 12 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, false );
|
|
|
|
//sumUpArea
|
|
QgsLineString l36;
|
|
double area = 1.0; //sumUpArea adds to area, so start with non-zero value
|
|
l36.sumUpArea( area );
|
|
QCOMPARE( area, 1.0 );
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) );
|
|
l36.sumUpArea( area );
|
|
QCOMPARE( area, 1.0 );
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 10, 10 ) );
|
|
l36.sumUpArea( area );
|
|
QGSCOMPARENEAR( area, -24, 4 * DBL_EPSILON );
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 2, 0 ) << QgsPoint( 2, 2 ) );
|
|
l36.sumUpArea( area );
|
|
QGSCOMPARENEAR( area, -22, 4 * DBL_EPSILON );
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 2, 0 ) << QgsPoint( 2, 2 ) << QgsPoint( 0, 2 ) );
|
|
l36.sumUpArea( area );
|
|
QGSCOMPARENEAR( area, -18, 4 * DBL_EPSILON );
|
|
|
|
//boundingBox - test that bounding box is updated after every modification to the line string
|
|
QgsLineString l37;
|
|
QVERIFY( l37.boundingBox().isNull() );
|
|
l37.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 10, 15 ) );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( 5, 10, 10, 15 ) );
|
|
l37.setPoints( QgsPointSequence() << QgsPoint( -5, -10 ) << QgsPoint( -6, -10 ) << QgsPoint( -5.5, -9 ) );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( -6, -10, -5, -9 ) );
|
|
//setXAt
|
|
l37.setXAt( 2, -4 );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( -6, -10, -4, -9 ) );
|
|
//setYAt
|
|
l37.setYAt( 1, -15 );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( -6, -15, -4, -9 ) );
|
|
//append
|
|
toAppend.reset( new QgsLineString() );
|
|
toAppend->setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 4, 0 ) );
|
|
l37.append( toAppend.get() );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( -6, -15, 4, 2 ) );
|
|
l37.addVertex( QgsPoint( 6, 3 ) );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( -6, -15, 6, 3 ) );
|
|
l37.clear();
|
|
QVERIFY( l37.boundingBox().isNull() );
|
|
l37.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 10, 15 ) );
|
|
QByteArray wkbToAppend = toAppend->asWkb();
|
|
QgsConstWkbPtr wkbToAppendPtr( wkbToAppend );
|
|
l37.fromWkb( wkbToAppendPtr );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( 1, 0, 4, 2 ) );
|
|
l37.fromWkt( QStringLiteral( "LineString( 1 5, 3 4, 6 3 )" ) );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( 1, 3, 6, 5 ) );
|
|
l37.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( -1, 7 ) );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( -1, 3, 6, 7 ) );
|
|
l37.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( -3, 10 ) );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( -3, 3, 6, 10 ) );
|
|
l37.deleteVertex( QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( l37.boundingBox(), QgsRectangle( 1, 3, 6, 5 ) );
|
|
|
|
//angle
|
|
QgsLineString l38;
|
|
( void )l38.vertexAngle( QgsVertexId() ); //just want no crash
|
|
( void )l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ); //just want no crash
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) );
|
|
( void )l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ); //just want no crash, any answer is meaningless
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 1.5708, 0.0001 );
|
|
( void )l38.vertexAngle( QgsVertexId( 0, 0, 2 ) ); //no crash
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 1 ) );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 0.0, 4 * DBL_EPSILON );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 0.0, 4 * DBL_EPSILON );
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 1, 0 ) << QgsPoint( 0, 0 ) );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 4.71239, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 4.71239, 0.0001 );
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 1 ) << QgsPoint( 0, 0 ) );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 3.1416, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 3.1416, 0.0001 );
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 0.7854, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 0.0, 0.0001 );
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0.5, 0 ) << QgsPoint( 1, 0 )
|
|
<< QgsPoint( 2, 1 ) << QgsPoint( 1, 2 ) << QgsPoint( 0, 2 ) );
|
|
( void )l38.vertexAngle( QgsVertexId( 0, 0, 20 ) );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 1.17809, 0.00001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 3 ) ), 0.0, 0.00001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 4 ) ), 5.10509, 0.00001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 5 ) ), 4.71239, 0.00001 );
|
|
//closed line string
|
|
l38.close();
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 5 ) ), 3.92699, 0.00001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 2.35619, 0.00001 );
|
|
QGSCOMPARENEAR( l38.vertexAngle( QgsVertexId( 0, 0, 6 ) ), 2.35619, 0.00001 );
|
|
|
|
//removing the second to last vertex should remove the whole line
|
|
QgsLineString l39;
|
|
l39.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 1 ) );
|
|
QVERIFY( l39.numPoints() == 2 );
|
|
l39.deleteVertex( QgsVertexId( 0, 0, 1 ) );
|
|
QVERIFY( l39.numPoints() == 0 );
|
|
|
|
//boundary
|
|
QgsLineString boundary1;
|
|
QVERIFY( !boundary1.boundary() );
|
|
boundary1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) );
|
|
QgsAbstractGeometry *boundary = boundary1.boundary();
|
|
QgsMultiPointV2 *mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
delete boundary;
|
|
|
|
// closed string = no boundary
|
|
boundary1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
QVERIFY( !boundary1.boundary() );
|
|
\
|
|
|
|
//boundary with z
|
|
boundary1.setPoints( QList<QgsPoint>() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 10 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 0, 15 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 20 ) );
|
|
boundary = boundary1.boundary();
|
|
mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->geometryN( 0 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->z(), 10.0 );
|
|
QCOMPARE( mpBoundary->geometryN( 1 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->z(), 20.0 );
|
|
delete boundary;
|
|
|
|
//extend
|
|
QgsLineString extend1;
|
|
extend1.extend( 10, 10 ); //test no crash
|
|
extend1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) );
|
|
extend1.extend( 1, 2 );
|
|
QCOMPARE( extend1.pointN( 0 ), QgsPoint( QgsWkbTypes::Point, -1, 0 ) );
|
|
QCOMPARE( extend1.pointN( 1 ), QgsPoint( QgsWkbTypes::Point, 1, 0 ) );
|
|
QCOMPARE( extend1.pointN( 2 ), QgsPoint( QgsWkbTypes::Point, 1, 3 ) );
|
|
|
|
// addToPainterPath (note most tests are in test_qgsgeometry.py)
|
|
QgsLineString path;
|
|
QPainterPath pPath;
|
|
path.addToPainterPath( pPath );
|
|
QVERIFY( pPath.isEmpty() );
|
|
path.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
path.addToPainterPath( pPath );
|
|
QVERIFY( !pPath.isEmpty() );
|
|
|
|
// toCurveType
|
|
QgsLineString curveLine1;
|
|
curveLine1.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
std::unique_ptr< QgsCompoundCurve > curveType( curveLine1.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::CompoundCurve );
|
|
QCOMPARE( curveType->numPoints(), 2 );
|
|
QCOMPARE( curveType->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( curveType->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( 11, 12 ) );
|
|
|
|
}
|
|
void TestQgsGeometry::polygon()
|
|
{
|
|
//test constructor
|
|
QgsPolygonV2 p1;
|
|
QVERIFY( p1.isEmpty() );
|
|
QCOMPARE( p1.numInteriorRings(), 0 );
|
|
QCOMPARE( p1.nCoordinates(), 0 );
|
|
QCOMPARE( p1.ringCount(), 0 );
|
|
QCOMPARE( p1.partCount(), 0 );
|
|
QVERIFY( !p1.is3D() );
|
|
QVERIFY( !p1.isMeasure() );
|
|
QCOMPARE( p1.wkbType(), QgsWkbTypes::Polygon );
|
|
QCOMPARE( p1.wktTypeStr(), QString( "Polygon" ) );
|
|
QCOMPARE( p1.geometryType(), QString( "Polygon" ) );
|
|
QCOMPARE( p1.dimension(), 2 );
|
|
QVERIFY( !p1.hasCurvedSegments() );
|
|
QCOMPARE( p1.area(), 0.0 );
|
|
QCOMPARE( p1.perimeter(), 0.0 );
|
|
QVERIFY( !p1.exteriorRing() );
|
|
QVERIFY( !p1.interiorRing( 0 ) );
|
|
|
|
//set exterior ring
|
|
|
|
//try with no ring
|
|
QgsLineString *ext = 0;
|
|
p1.setExteriorRing( ext );
|
|
QVERIFY( p1.isEmpty() );
|
|
QCOMPARE( p1.numInteriorRings(), 0 );
|
|
QCOMPARE( p1.nCoordinates(), 0 );
|
|
QCOMPARE( p1.ringCount(), 0 );
|
|
QCOMPARE( p1.partCount(), 0 );
|
|
QVERIFY( !p1.exteriorRing() );
|
|
QVERIFY( !p1.interiorRing( 0 ) );
|
|
QCOMPARE( p1.wkbType(), QgsWkbTypes::Polygon );
|
|
|
|
// empty exterior ring
|
|
ext = new QgsLineString();
|
|
p1.setExteriorRing( ext );
|
|
QVERIFY( p1.isEmpty() );
|
|
QCOMPARE( p1.numInteriorRings(), 0 );
|
|
QCOMPARE( p1.nCoordinates(), 0 );
|
|
QCOMPARE( p1.ringCount(), 1 );
|
|
QCOMPARE( p1.partCount(), 1 );
|
|
QVERIFY( p1.exteriorRing() );
|
|
QVERIFY( !p1.interiorRing( 0 ) );
|
|
QCOMPARE( p1.wkbType(), QgsWkbTypes::Polygon );
|
|
|
|
//valid exterior ring
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p1.setExteriorRing( ext );
|
|
QVERIFY( !p1.isEmpty() );
|
|
QCOMPARE( p1.numInteriorRings(), 0 );
|
|
QCOMPARE( p1.nCoordinates(), 5 );
|
|
QCOMPARE( p1.ringCount(), 1 );
|
|
QCOMPARE( p1.partCount(), 1 );
|
|
QVERIFY( !p1.is3D() );
|
|
QVERIFY( !p1.isMeasure() );
|
|
QCOMPARE( p1.wkbType(), QgsWkbTypes::Polygon );
|
|
QCOMPARE( p1.wktTypeStr(), QString( "Polygon" ) );
|
|
QCOMPARE( p1.geometryType(), QString( "Polygon" ) );
|
|
QCOMPARE( p1.dimension(), 2 );
|
|
QVERIFY( !p1.hasCurvedSegments() );
|
|
QCOMPARE( p1.area(), 100.0 );
|
|
QCOMPARE( p1.perimeter(), 40.0 );
|
|
QVERIFY( p1.exteriorRing() );
|
|
QVERIFY( !p1.interiorRing( 0 ) );
|
|
|
|
//retrieve exterior ring and check
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( p1.exteriorRing() ) ), *ext );
|
|
|
|
//test that a non closed exterior ring will be automatically closed
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) );
|
|
QVERIFY( !ext->isClosed() );
|
|
p1.setExteriorRing( ext );
|
|
QVERIFY( !p1.isEmpty() );
|
|
QVERIFY( p1.exteriorRing()->isClosed() );
|
|
QCOMPARE( p1.nCoordinates(), 5 );
|
|
|
|
//initial setting of exterior ring should set z/m type
|
|
QgsPolygonV2 p2;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) );
|
|
p2.setExteriorRing( ext );
|
|
QVERIFY( p2.is3D() );
|
|
QVERIFY( !p2.isMeasure() );
|
|
QCOMPARE( p2.wkbType(), QgsWkbTypes::PolygonZ );
|
|
QCOMPARE( p2.wktTypeStr(), QString( "PolygonZ" ) );
|
|
QCOMPARE( p2.geometryType(), QString( "Polygon" ) );
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( p2.exteriorRing() ) ), *ext );
|
|
QgsPolygonV2 p3;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0, 10, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 10, 10, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 10, 0, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 ) );
|
|
p3.setExteriorRing( ext );
|
|
QVERIFY( !p3.is3D() );
|
|
QVERIFY( p3.isMeasure() );
|
|
QCOMPARE( p3.wkbType(), QgsWkbTypes::PolygonM );
|
|
QCOMPARE( p3.wktTypeStr(), QString( "PolygonM" ) );
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( p3.exteriorRing() ) ), *ext );
|
|
QgsPolygonV2 p4;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 2, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 3, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 5, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 2, 1 ) );
|
|
p4.setExteriorRing( ext );
|
|
QVERIFY( p4.is3D() );
|
|
QVERIFY( p4.isMeasure() );
|
|
QCOMPARE( p4.wkbType(), QgsWkbTypes::PolygonZM );
|
|
QCOMPARE( p4.wktTypeStr(), QString( "PolygonZM" ) );
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( p4.exteriorRing() ) ), *ext );
|
|
QgsPolygonV2 p5;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::Point25D, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::Point25D, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::Point25D, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::Point25D, 0, 0, 1 ) );
|
|
p5.setExteriorRing( ext );
|
|
QVERIFY( p5.is3D() );
|
|
QVERIFY( !p5.isMeasure() );
|
|
QCOMPARE( p5.wkbType(), QgsWkbTypes::Polygon25D );
|
|
QCOMPARE( p5.wktTypeStr(), QString( "PolygonZ" ) );
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( p5.exteriorRing() ) ), *ext );
|
|
|
|
//setting curved exterior ring should be segmentized
|
|
QgsCircularString *circularRing = new QgsCircularString();
|
|
circularRing->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
QVERIFY( circularRing->hasCurvedSegments() );
|
|
p5.setExteriorRing( circularRing );
|
|
QVERIFY( !p5.exteriorRing()->hasCurvedSegments() );
|
|
QCOMPARE( p5.exteriorRing()->wkbType(), QgsWkbTypes::LineString );
|
|
|
|
//addInteriorRing
|
|
QgsPolygonV2 p6;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p6.setExteriorRing( ext );
|
|
//empty ring
|
|
QCOMPARE( p6.numInteriorRings(), 0 );
|
|
QVERIFY( !p6.interiorRing( -1 ) );
|
|
QVERIFY( !p6.interiorRing( 0 ) );
|
|
p6.addInteriorRing( 0 );
|
|
QCOMPARE( p6.numInteriorRings(), 0 );
|
|
QgsLineString *ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( 1, 1 ) << QgsPoint( 1, 9 ) << QgsPoint( 9, 9 )
|
|
<< QgsPoint( 9, 1 ) << QgsPoint( 1, 1 ) );
|
|
p6.addInteriorRing( ring );
|
|
QCOMPARE( p6.numInteriorRings(), 1 );
|
|
QCOMPARE( p6.interiorRing( 0 ), ring );
|
|
QVERIFY( !p6.interiorRing( 1 ) );
|
|
|
|
QgsCoordinateSequence seq = p6.coordinateSequence();
|
|
QCOMPARE( seq, QgsCoordinateSequence() << ( QgsRingSequence() << ( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) )
|
|
<< ( QgsPointSequence() << QgsPoint( 1, 1 ) << QgsPoint( 1, 9 ) << QgsPoint( 9, 9 )
|
|
<< QgsPoint( 9, 1 ) << QgsPoint( 1, 1 ) ) ) );
|
|
QCOMPARE( p6.nCoordinates(), 10 );
|
|
|
|
//add non-closed interior ring, should be closed automatically
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( 0.1, 0.1 ) << QgsPoint( 0.1, 0.9 ) << QgsPoint( 0.9, 0.9 )
|
|
<< QgsPoint( 0.9, 0.1 ) );
|
|
QVERIFY( !ring->isClosed() );
|
|
p6.addInteriorRing( ring );
|
|
QCOMPARE( p6.numInteriorRings(), 2 );
|
|
QVERIFY( p6.interiorRing( 1 )->isClosed() );
|
|
|
|
//try adding an interior ring with z to a 2d polygon, z should be dropped
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.2, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 ) );
|
|
p6.addInteriorRing( ring );
|
|
QCOMPARE( p6.numInteriorRings(), 3 );
|
|
QVERIFY( !p6.is3D() );
|
|
QVERIFY( !p6.isMeasure() );
|
|
QCOMPARE( p6.wkbType(), QgsWkbTypes::Polygon );
|
|
QVERIFY( p6.interiorRing( 2 ) );
|
|
QVERIFY( !p6.interiorRing( 2 )->is3D() );
|
|
QVERIFY( !p6.interiorRing( 2 )->isMeasure() );
|
|
QCOMPARE( p6.interiorRing( 2 )->wkbType(), QgsWkbTypes::LineString );
|
|
|
|
//try adding an interior ring with m to a 2d polygon, m should be dropped
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0.1, 0.1, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0.1, 0.2, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 0.2, 0.2, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0.2, 0.1, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 0.1, 0.1, 0, 1 ) );
|
|
p6.addInteriorRing( ring );
|
|
QCOMPARE( p6.numInteriorRings(), 4 );
|
|
QVERIFY( !p6.is3D() );
|
|
QVERIFY( !p6.isMeasure() );
|
|
QCOMPARE( p6.wkbType(), QgsWkbTypes::Polygon );
|
|
QVERIFY( p6.interiorRing( 3 ) );
|
|
QVERIFY( !p6.interiorRing( 3 )->is3D() );
|
|
QVERIFY( !p6.interiorRing( 3 )->isMeasure() );
|
|
QCOMPARE( p6.interiorRing( 3 )->wkbType(), QgsWkbTypes::LineString );
|
|
|
|
//addInteriorRing without z/m to PolygonZM
|
|
QgsPolygonV2 p6b;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1 ) );
|
|
p6b.setExteriorRing( ext );
|
|
QVERIFY( p6b.is3D() );
|
|
QVERIFY( p6b.isMeasure() );
|
|
QCOMPARE( p6b.wkbType(), QgsWkbTypes::PolygonZM );
|
|
//ring has no z
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 1, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 1, 9 ) << QgsPoint( QgsWkbTypes::PointM, 9, 9 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 9, 1 ) << QgsPoint( QgsWkbTypes::PointM, 1, 1 ) );
|
|
p6b.addInteriorRing( ring );
|
|
QVERIFY( p6b.interiorRing( 0 ) );
|
|
QVERIFY( p6b.interiorRing( 0 )->is3D() );
|
|
QVERIFY( p6b.interiorRing( 0 )->isMeasure() );
|
|
QCOMPARE( p6b.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineStringZM );
|
|
QCOMPARE( p6b.interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 1, 0, 2 ) );
|
|
//ring has no m
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.2, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 ) );
|
|
p6b.addInteriorRing( ring );
|
|
QVERIFY( p6b.interiorRing( 1 ) );
|
|
QVERIFY( p6b.interiorRing( 1 )->is3D() );
|
|
QVERIFY( p6b.interiorRing( 1 )->isMeasure() );
|
|
QCOMPARE( p6b.interiorRing( 1 )->wkbType(), QgsWkbTypes::LineStringZM );
|
|
QCOMPARE( p6b.interiorRing( 1 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 0.1, 0.1, 1, 0 ) );
|
|
//test handling of 25D rings/polygons
|
|
QgsPolygonV2 p6c;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::Point25D, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::Point25D, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::Point25D, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::Point25D, 0, 0, 1 ) );
|
|
p6c.setExteriorRing( ext );
|
|
QVERIFY( p6c.is3D() );
|
|
QVERIFY( !p6c.isMeasure() );
|
|
QCOMPARE( p6c.wkbType(), QgsWkbTypes::Polygon25D );
|
|
//adding a LineStringZ, should become LineString25D
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.2, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 ) );
|
|
QCOMPARE( ring->wkbType(), QgsWkbTypes::LineStringZ );
|
|
p6c.addInteriorRing( ring );
|
|
QVERIFY( p6c.interiorRing( 0 ) );
|
|
QVERIFY( p6c.interiorRing( 0 )->is3D() );
|
|
QVERIFY( !p6c.interiorRing( 0 )->isMeasure() );
|
|
QCOMPARE( p6c.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineString25D );
|
|
QCOMPARE( p6c.interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::Point25D, 0.1, 0.1, 1 ) );
|
|
//add a LineStringM, should become LineString25D
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0.1, 0.1, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0.1, 0.2, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 0.2, 0.2, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0.2, 0.1, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 0.1, 0.1, 0, 1 ) );
|
|
QCOMPARE( ring->wkbType(), QgsWkbTypes::LineStringM );
|
|
p6c.addInteriorRing( ring );
|
|
QVERIFY( p6c.interiorRing( 1 ) );
|
|
QVERIFY( p6c.interiorRing( 1 )->is3D() );
|
|
QVERIFY( !p6c.interiorRing( 1 )->isMeasure() );
|
|
QCOMPARE( p6c.interiorRing( 1 )->wkbType(), QgsWkbTypes::LineString25D );
|
|
QCOMPARE( p6c.interiorRing( 1 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::Point25D, 0.1, 0.1 ) );
|
|
|
|
//add curved ring to polygon
|
|
circularRing = new QgsCircularString();
|
|
circularRing->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
QVERIFY( circularRing->hasCurvedSegments() );
|
|
p6c.addInteriorRing( circularRing );
|
|
QVERIFY( p6c.interiorRing( 2 ) );
|
|
QVERIFY( !p6c.interiorRing( 2 )->hasCurvedSegments() );
|
|
QVERIFY( p6c.interiorRing( 2 )->is3D() );
|
|
QVERIFY( !p6c.interiorRing( 2 )->isMeasure() );
|
|
QCOMPARE( p6c.interiorRing( 2 )->wkbType(), QgsWkbTypes::LineString25D );
|
|
|
|
//set interior rings
|
|
QgsPolygonV2 p7;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p7.setExteriorRing( ext );
|
|
//add a list of rings with mixed types
|
|
QList< QgsCurve * > rings;
|
|
rings << new QgsLineString();
|
|
static_cast< QgsLineString *>( rings[0] )->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.2, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 ) );
|
|
rings << new QgsLineString();
|
|
static_cast< QgsLineString *>( rings[1] )->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0.3, 0.3, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0.3, 0.4, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 0.4, 0.4, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0.4, 0.3, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 0.3, 0.3, 0, 1 ) );
|
|
//throw an empty ring in too
|
|
rings << 0;
|
|
rings << new QgsCircularString();
|
|
static_cast< QgsCircularString *>( rings[3] )->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p7.setInteriorRings( rings );
|
|
QCOMPARE( p7.numInteriorRings(), 3 );
|
|
QVERIFY( p7.interiorRing( 0 ) );
|
|
QVERIFY( !p7.interiorRing( 0 )->is3D() );
|
|
QVERIFY( !p7.interiorRing( 0 )->isMeasure() );
|
|
QCOMPARE( p7.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( p7.interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::Point, 0.1, 0.1 ) );
|
|
QVERIFY( p7.interiorRing( 1 ) );
|
|
QVERIFY( !p7.interiorRing( 1 )->is3D() );
|
|
QVERIFY( !p7.interiorRing( 1 )->isMeasure() );
|
|
QCOMPARE( p7.interiorRing( 1 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( p7.interiorRing( 1 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::Point, 0.3, 0.3 ) );
|
|
QVERIFY( p7.interiorRing( 2 ) );
|
|
QVERIFY( !p7.interiorRing( 2 )->is3D() );
|
|
QVERIFY( !p7.interiorRing( 2 )->isMeasure() );
|
|
QCOMPARE( p7.interiorRing( 2 )->wkbType(), QgsWkbTypes::LineString );
|
|
|
|
//set rings with existing
|
|
rings.clear();
|
|
rings << new QgsLineString();
|
|
static_cast< QgsLineString *>( rings[0] )->setPoints( QgsPointSequence() << QgsPoint( 0.8, 0.8 )
|
|
<< QgsPoint( 0.8, 0.9 ) << QgsPoint( 0.9, 0.9 )
|
|
<< QgsPoint( 0.9, 0.8 ) << QgsPoint( 0.8, 0.8 ) );
|
|
p7.setInteriorRings( rings );
|
|
QCOMPARE( p7.numInteriorRings(), 1 );
|
|
QVERIFY( p7.interiorRing( 0 ) );
|
|
QVERIFY( !p7.interiorRing( 0 )->is3D() );
|
|
QVERIFY( !p7.interiorRing( 0 )->isMeasure() );
|
|
QCOMPARE( p7.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( p7.interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::Point, 0.8, 0.8 ) );
|
|
rings.clear();
|
|
p7.setInteriorRings( rings );
|
|
QCOMPARE( p7.numInteriorRings(), 0 );
|
|
|
|
//change dimensionality of interior rings using setExteriorRing
|
|
QgsPolygonV2 p7a;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 10, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 0, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) );
|
|
p7a.setExteriorRing( ext );
|
|
rings.clear();
|
|
rings << new QgsLineString();
|
|
static_cast< QgsLineString *>( rings[0] )->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.2, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 ) );
|
|
rings << new QgsLineString();
|
|
static_cast< QgsLineString *>( rings[1] )->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0.3, 0.3, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.3, 0.4, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 0.4, 0.4, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.4, 0.3, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0.3, 0.3, 1 ) );
|
|
p7a.setInteriorRings( rings );
|
|
QVERIFY( p7a.is3D() );
|
|
QVERIFY( !p7a.isMeasure() );
|
|
QVERIFY( p7a.interiorRing( 0 )->is3D() );
|
|
QVERIFY( !p7a.interiorRing( 0 )->isMeasure() );
|
|
QVERIFY( p7a.interiorRing( 1 )->is3D() );
|
|
QVERIFY( !p7a.interiorRing( 1 )->isMeasure() );
|
|
//reset exterior ring to 2d
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 )
|
|
<< QgsPoint( 10, 10 ) << QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p7a.setExteriorRing( ext );
|
|
QVERIFY( !p7a.is3D() );
|
|
QVERIFY( !p7a.interiorRing( 0 )->is3D() ); //rings should also be made 2D
|
|
QVERIFY( !p7a.interiorRing( 1 )->is3D() );
|
|
//reset exterior ring to LineStringM
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0, 0 ) << QgsPoint( QgsWkbTypes::PointM, 0, 10 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 10, 10 ) << QgsPoint( QgsWkbTypes::PointM, 10, 0 ) << QgsPoint( QgsWkbTypes::PointM, 0, 0 ) );
|
|
p7a.setExteriorRing( ext );
|
|
QVERIFY( p7a.isMeasure() );
|
|
QVERIFY( p7a.interiorRing( 0 )->isMeasure() ); //rings should also gain measure
|
|
QVERIFY( p7a.interiorRing( 1 )->isMeasure() );
|
|
//25D exterior ring
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 0, 0 ) << QgsPoint( QgsWkbTypes::Point25D, 0, 10 )
|
|
<< QgsPoint( QgsWkbTypes::Point25D, 10, 10 ) << QgsPoint( QgsWkbTypes::Point25D, 10, 0 ) << QgsPoint( QgsWkbTypes::Point25D, 0, 0 ) );
|
|
p7a.setExteriorRing( ext );
|
|
QVERIFY( p7a.is3D() );
|
|
QVERIFY( !p7a.isMeasure() );
|
|
QVERIFY( p7a.interiorRing( 0 )->is3D() ); //rings should also be made 25D
|
|
QVERIFY( !p7a.interiorRing( 0 )->isMeasure() );
|
|
QVERIFY( p7a.interiorRing( 1 )->is3D() );
|
|
QVERIFY( !p7a.interiorRing( 1 )->isMeasure() );
|
|
QCOMPARE( p7a.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineString25D );
|
|
QCOMPARE( p7a.interiorRing( 1 )->wkbType(), QgsWkbTypes::LineString25D );
|
|
|
|
|
|
//removeInteriorRing
|
|
QgsPolygonV2 p8;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p8.setExteriorRing( ext );
|
|
QVERIFY( !p8.removeInteriorRing( -1 ) );
|
|
QVERIFY( !p8.removeInteriorRing( 0 ) );
|
|
rings.clear();
|
|
rings << new QgsLineString();
|
|
static_cast< QgsLineString *>( rings[0] )->setPoints( QgsPointSequence() << QgsPoint( 0.1, 0.1 )
|
|
<< QgsPoint( 0.1, 0.2 ) << QgsPoint( 0.2, 0.2 )
|
|
<< QgsPoint( 0.2, 0.1 ) << QgsPoint( 0.1, 0.1 ) );
|
|
rings << new QgsLineString();
|
|
static_cast< QgsLineString *>( rings[1] )->setPoints( QgsPointSequence() << QgsPoint( 0.3, 0.3 )
|
|
<< QgsPoint( 0.3, 0.4 ) << QgsPoint( 0.4, 0.4 )
|
|
<< QgsPoint( 0.4, 0.3 ) << QgsPoint( 0.3, 0.3 ) );
|
|
rings << new QgsLineString();
|
|
static_cast< QgsLineString *>( rings[2] )->setPoints( QgsPointSequence() << QgsPoint( 0.8, 0.8 )
|
|
<< QgsPoint( 0.8, 0.9 ) << QgsPoint( 0.9, 0.9 )
|
|
<< QgsPoint( 0.9, 0.8 ) << QgsPoint( 0.8, 0.8 ) );
|
|
p8.setInteriorRings( rings );
|
|
QCOMPARE( p8.numInteriorRings(), 3 );
|
|
QVERIFY( p8.removeInteriorRing( 0 ) );
|
|
QCOMPARE( p8.numInteriorRings(), 2 );
|
|
QCOMPARE( p8.interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 0.3, 0.3 ) );
|
|
QCOMPARE( p8.interiorRing( 1 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 0.8, 0.8 ) );
|
|
QVERIFY( p8.removeInteriorRing( 1 ) );
|
|
QCOMPARE( p8.numInteriorRings(), 1 );
|
|
QCOMPARE( p8.interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 0.3, 0.3 ) );
|
|
QVERIFY( p8.removeInteriorRing( 0 ) );
|
|
QCOMPARE( p8.numInteriorRings(), 0 );
|
|
QVERIFY( !p8.removeInteriorRing( 0 ) );
|
|
|
|
//clear
|
|
QgsPolygonV2 p9;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) );
|
|
p9.setExteriorRing( ext );
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1, 9, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 9, 9, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 9, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 1 ) );
|
|
p9.addInteriorRing( ring );
|
|
QCOMPARE( p9.numInteriorRings(), 1 );
|
|
p9.clear();
|
|
QVERIFY( p9.isEmpty() );
|
|
QCOMPARE( p9.numInteriorRings(), 0 );
|
|
QCOMPARE( p9.nCoordinates(), 0 );
|
|
QCOMPARE( p9.ringCount(), 0 );
|
|
QCOMPARE( p9.partCount(), 0 );
|
|
QVERIFY( !p9.is3D() );
|
|
QVERIFY( !p9.isMeasure() );
|
|
QCOMPARE( p9.wkbType(), QgsWkbTypes::Polygon );
|
|
|
|
//equality operator
|
|
QgsPolygonV2 p10;
|
|
QgsPolygonV2 p10b;
|
|
QVERIFY( p10 == p10b );
|
|
QVERIFY( !( p10 != p10b ) );
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p10.setExteriorRing( ext );
|
|
QVERIFY( !( p10 == p10b ) );
|
|
QVERIFY( p10 != p10b );
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p10b.setExteriorRing( ext );
|
|
QVERIFY( p10 == p10b );
|
|
QVERIFY( !( p10 != p10b ) );
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 9 ) << QgsPoint( 9, 9 )
|
|
<< QgsPoint( 9, 0 ) << QgsPoint( 0, 0 ) );
|
|
p10b.setExteriorRing( ext );
|
|
QVERIFY( !( p10 == p10b ) );
|
|
QVERIFY( p10 != p10b );
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 10, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) );
|
|
p10b.setExteriorRing( ext );
|
|
QVERIFY( !( p10 == p10b ) );
|
|
QVERIFY( p10 != p10b );
|
|
p10b.setExteriorRing( p10.exteriorRing()->clone() );
|
|
QVERIFY( p10 == p10b );
|
|
QVERIFY( !( p10 != p10b ) );
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( 1, 1 )
|
|
<< QgsPoint( 1, 9 ) << QgsPoint( 9, 9 )
|
|
<< QgsPoint( 9, 1 ) << QgsPoint( 1, 1 ) );
|
|
p10.addInteriorRing( ring );
|
|
QVERIFY( !( p10 == p10b ) );
|
|
QVERIFY( p10 != p10b );
|
|
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( 2, 1 )
|
|
<< QgsPoint( 2, 9 ) << QgsPoint( 9, 9 )
|
|
<< QgsPoint( 9, 1 ) << QgsPoint( 2, 1 ) );
|
|
p10b.addInteriorRing( ring );
|
|
QVERIFY( !( p10 == p10b ) );
|
|
QVERIFY( p10 != p10b );
|
|
p10b.removeInteriorRing( 0 );
|
|
p10b.addInteriorRing( p10.interiorRing( 0 )->clone() );
|
|
QVERIFY( p10 == p10b );
|
|
QVERIFY( !( p10 != p10b ) );
|
|
|
|
//clone
|
|
|
|
QgsPolygonV2 p11;
|
|
std::unique_ptr< QgsPolygonV2 >cloned( p11.clone() );
|
|
QCOMPARE( p11, *cloned );
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
p11.setExteriorRing( ext );
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
p11.addInteriorRing( ring );
|
|
cloned.reset( p11.clone() );
|
|
QCOMPARE( p11, *cloned );
|
|
|
|
//copy constructor
|
|
QgsPolygonV2 p12;
|
|
QgsPolygonV2 p13( p12 );
|
|
QCOMPARE( p12, p13 );
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
p12.setExteriorRing( ext );
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
p12.addInteriorRing( ring );
|
|
QgsPolygonV2 p14( p12 );
|
|
QCOMPARE( p12, p14 );
|
|
|
|
//assignment operator
|
|
QgsPolygonV2 p15;
|
|
p15 = p13;
|
|
QCOMPARE( p13, p15 );
|
|
p15 = p12;
|
|
QCOMPARE( p12, p15 );
|
|
|
|
//surfaceToPolygon - should be identical given polygon has no curves
|
|
std::unique_ptr< QgsPolygonV2 > surface( p12.surfaceToPolygon() );
|
|
QCOMPARE( *surface, p12 );
|
|
//toPolygon - should be identical given polygon has no curves
|
|
std::unique_ptr< QgsPolygonV2 > toP( p12.toPolygon() );
|
|
QCOMPARE( *toP, p12 );
|
|
|
|
//toCurveType
|
|
std::unique_ptr< QgsCurvePolygon > curveType( p12.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::CurvePolygonZM );
|
|
QCOMPARE( curveType->exteriorRing()->numPoints(), 5 );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 ) );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 ) );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 3 ) ), QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 4 ) ), QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
QCOMPARE( curveType->numInteriorRings(), 1 );
|
|
QCOMPARE( curveType->interiorRing( 0 )->numPoints(), 5 );
|
|
QCOMPARE( curveType->interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 ) );
|
|
QCOMPARE( curveType->interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) );
|
|
QCOMPARE( curveType->interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 ) );
|
|
QCOMPARE( curveType->interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 3 ) ), QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) );
|
|
QCOMPARE( curveType->interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 4 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
|
|
//to/fromWKB
|
|
QgsPolygonV2 p16;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 0, 0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 0, 10 ) << QgsPoint( QgsWkbTypes::Point, 10, 10 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 10, 0 ) << QgsPoint( QgsWkbTypes::Point, 0, 0 ) );
|
|
p16.setExteriorRing( ext );
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 1, 9 ) << QgsPoint( QgsWkbTypes::Point, 9, 9 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 9, 1 ) << QgsPoint( QgsWkbTypes::Point, 1, 1 ) );
|
|
p16.addInteriorRing( ring );
|
|
QByteArray wkb16 = p16.asWkb();
|
|
QgsPolygonV2 p17;
|
|
QgsConstWkbPtr wkb16ptr( wkb16 );
|
|
p17.fromWkb( wkb16ptr );
|
|
QCOMPARE( p16, p17 );
|
|
//PolygonZ
|
|
p16.clear();
|
|
p17.clear();
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) );
|
|
p16.setExteriorRing( ext );
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1, 9, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 9, 9, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 9, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 1 ) );
|
|
p16.addInteriorRing( ring );
|
|
wkb16 = p16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr2( wkb16 );
|
|
p17.fromWkb( wkb16ptr2 );
|
|
QCOMPARE( p16, p17 );
|
|
//PolygonM
|
|
p16.clear();
|
|
p17.clear();
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0, 10, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 10, 10, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 10, 0, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 ) );
|
|
p16.setExteriorRing( ext );
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 1, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 1, 9, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 9, 9, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 9, 1, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 1, 1, 0, 1 ) );
|
|
p16.addInteriorRing( ring );
|
|
wkb16 = p16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr3( wkb16 );
|
|
p17.fromWkb( wkb16ptr3 );
|
|
QCOMPARE( p16, p17 );
|
|
//PolygonZM
|
|
p16.clear();
|
|
p17.clear();
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
p16.setExteriorRing( ext );
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
p16.addInteriorRing( ring );
|
|
wkb16 = p16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr4( wkb16 );
|
|
p17.fromWkb( wkb16ptr4 );
|
|
QCOMPARE( p16, p17 );
|
|
//Polygon25D
|
|
p16.clear();
|
|
p17.clear();
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::Point25D, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::Point25D, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::Point25D, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::Point25D, 0, 0, 1 ) );
|
|
p16.setExteriorRing( ext );
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point25D, 1, 1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::Point25D, 1, 9, 2 ) << QgsPoint( QgsWkbTypes::Point25D, 9, 9, 3 )
|
|
<< QgsPoint( QgsWkbTypes::Point25D, 9, 1, 4 ) << QgsPoint( QgsWkbTypes::Point25D, 1, 1, 1 ) );
|
|
p16.addInteriorRing( ring );
|
|
wkb16 = p16.asWkb();
|
|
p17.clear();
|
|
QgsConstWkbPtr wkb16ptr5( wkb16 );
|
|
p17.fromWkb( wkb16ptr5 );
|
|
QCOMPARE( p16, p17 );
|
|
|
|
//bad WKB - check for no crash
|
|
p17.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !p17.fromWkb( nullPtr ) );
|
|
QCOMPARE( p17.wkbType(), QgsWkbTypes::Polygon );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkbPoint = point.asWkb();
|
|
QgsConstWkbPtr wkbPointPtr( wkbPoint );
|
|
QVERIFY( !p17.fromWkb( wkbPointPtr ) );
|
|
QCOMPARE( p17.wkbType(), QgsWkbTypes::Polygon );
|
|
|
|
//to/from WKT
|
|
QgsPolygonV2 p18;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
p18.setExteriorRing( ext );
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
p18.addInteriorRing( ring );
|
|
|
|
QString wkt = p18.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsPolygonV2 p19;
|
|
QVERIFY( p19.fromWkt( wkt ) );
|
|
QCOMPARE( p18, p19 );
|
|
|
|
//bad WKT
|
|
QVERIFY( !p19.fromWkt( "Point()" ) );
|
|
QVERIFY( p19.isEmpty() );
|
|
QVERIFY( !p19.exteriorRing() );
|
|
QCOMPARE( p19.numInteriorRings(), 0 );
|
|
QVERIFY( !p19.is3D() );
|
|
QVERIFY( !p19.isMeasure() );
|
|
QCOMPARE( p19.wkbType(), QgsWkbTypes::Polygon );
|
|
|
|
//as JSON
|
|
QgsPolygonV2 exportPolygon;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 0, 0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 0, 10 ) << QgsPoint( QgsWkbTypes::Point, 10, 10 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 10, 0 ) << QgsPoint( QgsWkbTypes::Point, 0, 0 ) );
|
|
exportPolygon.setExteriorRing( ext );
|
|
|
|
// GML document for compare
|
|
QDomDocument doc( QStringLiteral( "gml" ) );
|
|
|
|
// as GML2
|
|
QString expectedSimpleGML2( QStringLiteral( "<Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0,0 0,10 10,10 10,0 0,0</coordinates></LinearRing></outerBoundaryIs></Polygon>" ) );
|
|
QGSCOMPAREGML( elemToString( exportPolygon.asGML2( doc ) ), expectedSimpleGML2 );
|
|
|
|
//as GML3
|
|
QString expectedSimpleGML3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><LinearRing xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">0 0 0 10 10 10 10 0 0 0</posList></LinearRing></exterior></Polygon>" ) );
|
|
QCOMPARE( elemToString( exportPolygon.asGML3( doc ) ), expectedSimpleGML3 );
|
|
|
|
// as JSON
|
|
QString expectedSimpleJson( QStringLiteral( "{\"type\": \"Polygon\", \"coordinates\": [[ [0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]] }" ) );
|
|
QCOMPARE( exportPolygon.asJSON(), expectedSimpleJson );
|
|
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 1, 9 ) << QgsPoint( QgsWkbTypes::Point, 9, 9 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 9, 1 ) << QgsPoint( QgsWkbTypes::Point, 1, 1 ) );
|
|
exportPolygon.addInteriorRing( ring );
|
|
|
|
QString expectedJson( QStringLiteral( "{\"type\": \"Polygon\", \"coordinates\": [[ [0, 0], [0, 10], [10, 10], [10, 0], [0, 0]], [ [1, 1], [1, 9], [9, 9], [9, 1], [1, 1]]] }" ) );
|
|
QCOMPARE( exportPolygon.asJSON(), expectedJson );
|
|
|
|
QgsPolygonV2 exportPolygonFloat;
|
|
ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 10 / 9.0, 10 / 9.0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 10 / 9.0, 100 / 9.0 ) << QgsPoint( QgsWkbTypes::Point, 100 / 9.0, 100 / 9.0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 100 / 9.0, 10 / 9.0 ) << QgsPoint( QgsWkbTypes::Point, 10 / 9.0, 10 / 9.0 ) );
|
|
exportPolygonFloat.setExteriorRing( ext );
|
|
ring = new QgsLineString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 2 / 3.0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 4 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 4 / 3.0, 4 / 3.0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 4 / 3.0, 2 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 2 / 3.0 ) );
|
|
exportPolygonFloat.addInteriorRing( ring );
|
|
|
|
QString expectedJsonPrec3( QStringLiteral( "{\"type\": \"Polygon\", \"coordinates\": [[ [1.111, 1.111], [1.111, 11.111], [11.111, 11.111], [11.111, 1.111], [1.111, 1.111]], [ [0.667, 0.667], [0.667, 1.333], [1.333, 1.333], [1.333, 0.667], [0.667, 0.667]]] }" ) );
|
|
QCOMPARE( exportPolygonFloat.asJSON( 3 ), expectedJsonPrec3 );
|
|
|
|
// as GML2
|
|
QString expectedGML2( QStringLiteral( "<Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0,0 0,10 10,10 10,0 0,0</coordinates></LinearRing></outerBoundaryIs>" ) );
|
|
expectedGML2 += QStringLiteral( "<innerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">1,1 1,9 9,9 9,1 1,1</coordinates></LinearRing></innerBoundaryIs></Polygon>" );
|
|
QGSCOMPAREGML( elemToString( exportPolygon.asGML2( doc ) ), expectedGML2 );
|
|
QString expectedGML2prec3( QStringLiteral( "<Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">1.111,1.111 1.111,11.111 11.111,11.111 11.111,1.111 1.111,1.111</coordinates></LinearRing></outerBoundaryIs>" ) );
|
|
expectedGML2prec3 += QStringLiteral( "<innerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0.667,0.667 0.667,1.333 1.333,1.333 1.333,0.667 0.667,0.667</coordinates></LinearRing></innerBoundaryIs></Polygon>" );
|
|
QGSCOMPAREGML( elemToString( exportPolygonFloat.asGML2( doc, 3 ) ), expectedGML2prec3 );
|
|
|
|
//as GML3
|
|
QString expectedGML3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><LinearRing xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">0 0 0 10 10 10 10 0 0 0</posList></LinearRing></exterior>" ) );
|
|
expectedGML3 += QStringLiteral( "<interior xmlns=\"gml\"><LinearRing xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">1 1 1 9 9 9 9 1 1 1</posList></LinearRing></interior></Polygon>" );
|
|
|
|
QCOMPARE( elemToString( exportPolygon.asGML3( doc ) ), expectedGML3 );
|
|
QString expectedGML3prec3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><LinearRing xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">1.111 1.111 1.111 11.111 11.111 11.111 11.111 1.111 1.111 1.111</posList></LinearRing></exterior>" ) );
|
|
expectedGML3prec3 += QStringLiteral( "<interior xmlns=\"gml\"><LinearRing xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">0.667 0.667 0.667 1.333 1.333 1.333 1.333 0.667 0.667 0.667</posList></LinearRing></interior></Polygon>" );
|
|
QCOMPARE( elemToString( exportPolygonFloat.asGML3( doc, 3 ) ), expectedGML3prec3 );
|
|
|
|
//removing the fourth to last vertex removes the whole ring
|
|
QgsPolygonV2 p20;
|
|
QgsLineString *p20ExteriorRing = new QgsLineString();
|
|
p20ExteriorRing->setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
p20.setExteriorRing( p20ExteriorRing );
|
|
QVERIFY( p20.exteriorRing() );
|
|
p20.deleteVertex( QgsVertexId( 0, 0, 2 ) );
|
|
QVERIFY( !p20.exteriorRing() );
|
|
|
|
//boundary
|
|
QgsLineString boundary1;
|
|
boundary1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
QgsPolygonV2 boundaryPolygon;
|
|
QVERIFY( !boundaryPolygon.boundary() );
|
|
|
|
boundaryPolygon.setExteriorRing( boundary1.clone() );
|
|
QgsAbstractGeometry *boundary = boundaryPolygon.boundary();
|
|
QgsLineString *lineBoundary = dynamic_cast< QgsLineString * >( boundary );
|
|
QVERIFY( lineBoundary );
|
|
QCOMPARE( lineBoundary->numPoints(), 4 );
|
|
QCOMPARE( lineBoundary->xAt( 0 ), 0.0 );
|
|
QCOMPARE( lineBoundary->xAt( 1 ), 1.0 );
|
|
QCOMPARE( lineBoundary->xAt( 2 ), 1.0 );
|
|
QCOMPARE( lineBoundary->xAt( 3 ), 0.0 );
|
|
QCOMPARE( lineBoundary->yAt( 0 ), 0.0 );
|
|
QCOMPARE( lineBoundary->yAt( 1 ), 0.0 );
|
|
QCOMPARE( lineBoundary->yAt( 2 ), 1.0 );
|
|
QCOMPARE( lineBoundary->yAt( 3 ), 0.0 );
|
|
delete boundary;
|
|
|
|
// add interior rings
|
|
QgsLineString boundaryRing1;
|
|
boundaryRing1.setPoints( QList<QgsPoint>() << QgsPoint( 0.1, 0.1 ) << QgsPoint( 0.2, 0.1 ) << QgsPoint( 0.2, 0.2 ) << QgsPoint( 0.1, 0.1 ) );
|
|
QgsLineString boundaryRing2;
|
|
boundaryRing2.setPoints( QList<QgsPoint>() << QgsPoint( 0.8, 0.8 ) << QgsPoint( 0.9, 0.8 ) << QgsPoint( 0.9, 0.9 ) << QgsPoint( 0.8, 0.8 ) );
|
|
boundaryPolygon.setInteriorRings( QList< QgsCurve * >() << boundaryRing1.clone() << boundaryRing2.clone() );
|
|
boundary = boundaryPolygon.boundary();
|
|
QgsMultiLineString *multiLineBoundary = dynamic_cast< QgsMultiLineString * >( boundary );
|
|
QVERIFY( multiLineBoundary );
|
|
QCOMPARE( multiLineBoundary->numGeometries(), 3 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->numPoints(), 4 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 0 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 1 ), 1.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 2 ), 1.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 3 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 0 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 1 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 2 ), 1.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 3 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->numPoints(), 4 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->xAt( 0 ), 0.1 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->xAt( 1 ), 0.2 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->xAt( 2 ), 0.2 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->xAt( 3 ), 0.1 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->yAt( 0 ), 0.1 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->yAt( 1 ), 0.1 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->yAt( 2 ), 0.2 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->yAt( 3 ), 0.1 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->numPoints(), 4 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->xAt( 0 ), 0.8 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->xAt( 1 ), 0.9 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->xAt( 2 ), 0.9 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->xAt( 3 ), 0.8 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->yAt( 0 ), 0.8 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->yAt( 1 ), 0.8 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->yAt( 2 ), 0.9 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->yAt( 3 ), 0.8 );
|
|
boundaryPolygon.setInteriorRings( QList< QgsCurve * >() );
|
|
delete boundary;
|
|
|
|
//test boundary with z
|
|
boundary1.setPoints( QList<QgsPoint>() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 10 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 0, 15 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1, 1, 20 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 10 ) );
|
|
boundaryPolygon.setExteriorRing( boundary1.clone() );
|
|
boundary = boundaryPolygon.boundary();
|
|
lineBoundary = dynamic_cast< QgsLineString * >( boundary );
|
|
QVERIFY( lineBoundary );
|
|
QCOMPARE( lineBoundary->numPoints(), 4 );
|
|
QCOMPARE( lineBoundary->wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( lineBoundary->zAt( 0 ), 10.0 );
|
|
QCOMPARE( lineBoundary->zAt( 1 ), 15.0 );
|
|
QCOMPARE( lineBoundary->zAt( 2 ), 20.0 );
|
|
QCOMPARE( lineBoundary->zAt( 3 ), 10.0 );
|
|
delete boundary;
|
|
|
|
// point distance to boundary
|
|
|
|
QgsLineString pd1;
|
|
pd1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 1 ) << QgsPoint( 0, 0 ) );
|
|
QgsPolygonV2 pd;
|
|
// no meaning, but let's not crash
|
|
( void )pd.pointDistanceToBoundary( 0, 0 );
|
|
|
|
pd.setExteriorRing( pd1.clone() );
|
|
QGSCOMPARENEAR( pd.pointDistanceToBoundary( 0, 0.5 ), 0.0, 0.0000000001 );
|
|
QGSCOMPARENEAR( pd.pointDistanceToBoundary( 0.1, 0.5 ), 0.1, 0.0000000001 );
|
|
QGSCOMPARENEAR( pd.pointDistanceToBoundary( -0.1, 0.5 ), -0.1, 0.0000000001 );
|
|
// with a ring
|
|
QgsLineString pdRing1;
|
|
pdRing1.setPoints( QList<QgsPoint>() << QgsPoint( 0.1, 0.1 ) << QgsPoint( 0.2, 0.1 ) << QgsPoint( 0.2, 0.6 ) << QgsPoint( 0.1, 0.6 ) << QgsPoint( 0.1, 0.1 ) );
|
|
pd.setInteriorRings( QList< QgsCurve * >() << pdRing1.clone() );
|
|
QGSCOMPARENEAR( pd.pointDistanceToBoundary( 0, 0.5 ), 0.0, 0.0000000001 );
|
|
QGSCOMPARENEAR( pd.pointDistanceToBoundary( 0.1, 0.5 ), 0.0, 0.0000000001 );
|
|
QGSCOMPARENEAR( pd.pointDistanceToBoundary( 0.01, 0.5 ), 0.01, 0.0000000001 );
|
|
QGSCOMPARENEAR( pd.pointDistanceToBoundary( 0.08, 0.5 ), 0.02, 0.0000000001 );
|
|
QGSCOMPARENEAR( pd.pointDistanceToBoundary( 0.12, 0.5 ), -0.02, 0.0000000001 );
|
|
QGSCOMPARENEAR( pd.pointDistanceToBoundary( -0.1, 0.5 ), -0.1, 0.0000000001 );
|
|
|
|
// remove interior rings
|
|
QgsLineString removeRingsExt;
|
|
removeRingsExt.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
QgsPolygonV2 removeRings1;
|
|
removeRings1.removeInteriorRings();
|
|
|
|
removeRings1.setExteriorRing( boundary1.clone() );
|
|
removeRings1.removeInteriorRings();
|
|
QCOMPARE( removeRings1.numInteriorRings(), 0 );
|
|
|
|
// add interior rings
|
|
QgsLineString removeRingsRing1;
|
|
removeRingsRing1.setPoints( QList<QgsPoint>() << QgsPoint( 0.1, 0.1 ) << QgsPoint( 0.2, 0.1 ) << QgsPoint( 0.2, 0.2 ) << QgsPoint( 0.1, 0.1 ) );
|
|
QgsLineString removeRingsRing2;
|
|
removeRingsRing2.setPoints( QList<QgsPoint>() << QgsPoint( 0.6, 0.8 ) << QgsPoint( 0.9, 0.8 ) << QgsPoint( 0.9, 0.9 ) << QgsPoint( 0.6, 0.8 ) );
|
|
removeRings1.setInteriorRings( QList< QgsCurve * >() << removeRingsRing1.clone() << removeRingsRing2.clone() );
|
|
|
|
// remove ring with size filter
|
|
removeRings1.removeInteriorRings( 0.0075 );
|
|
QCOMPARE( removeRings1.numInteriorRings(), 1 );
|
|
|
|
// remove ring with no size filter
|
|
removeRings1.removeInteriorRings();
|
|
QCOMPARE( removeRings1.numInteriorRings(), 0 );
|
|
|
|
// cast
|
|
QVERIFY( !QgsPolygonV2().cast( nullptr ) );
|
|
QgsPolygonV2 pCast;
|
|
QVERIFY( QgsPolygonV2().cast( &pCast ) );
|
|
QgsPolygonV2 pCast2;
|
|
pCast2.fromWkt( QStringLiteral( "PolygonZ((0 0 0, 0 1 1, 1 0 2, 0 0 0))" ) );
|
|
QVERIFY( QgsPolygonV2().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "PolygonM((0 0 1, 0 1 2, 1 0 3, 0 0 1))" ) );
|
|
QVERIFY( QgsPolygonV2().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "PolygonZM((0 0 0 1, 0 1 1 2, 1 0 2 3, 0 0 0 1))" ) );
|
|
QVERIFY( QgsPolygonV2().cast( &pCast2 ) );
|
|
|
|
//transform
|
|
//CRS transform
|
|
QgsCoordinateReferenceSystem sourceSrs;
|
|
sourceSrs.createFromSrid( 3994 );
|
|
QgsCoordinateReferenceSystem destSrs;
|
|
destSrs.createFromSrid( 4202 ); // want a transform with ellipsoid change
|
|
QgsCoordinateTransform tr( sourceSrs, destSrs );
|
|
|
|
// 2d CRS transform
|
|
QgsPolygonV2 pTransform;
|
|
QgsLineString l21;
|
|
l21.setPoints( QgsPointSequence() << QgsPoint( 6374985, -3626584 )
|
|
<< QgsPoint( 6274985, -3526584 )
|
|
<< QgsPoint( 6474985, -3526584 )
|
|
<< QgsPoint( 6374985, -3626584 ) );
|
|
pTransform.setExteriorRing( l21.clone() );
|
|
pTransform.addInteriorRing( l21.clone() );
|
|
pTransform.transform( tr, QgsCoordinateTransform::ForwardTransform );
|
|
const QgsLineString *extR = static_cast< const QgsLineString * >( pTransform.exteriorRing() );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).x(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).x(), 176.958633, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.exteriorRing()->boundingBox().xMinimum(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.exteriorRing()->boundingBox().yMinimum(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.exteriorRing()->boundingBox().xMaximum(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.exteriorRing()->boundingBox().yMaximum(), -38.7999, 0.001 );
|
|
const QgsLineString *intR = static_cast< const QgsLineString * >( pTransform.interiorRing( 0 ) );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).x(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).x(), 176.958633, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.interiorRing( 0 )->boundingBox().xMinimum(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.interiorRing( 0 )->boundingBox().yMinimum(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.interiorRing( 0 )->boundingBox().xMaximum(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.interiorRing( 0 )->boundingBox().yMaximum(), -38.7999, 0.001 );
|
|
|
|
//3d CRS transform
|
|
QgsLineString l22;
|
|
l22.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 6374985, -3626584, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 6274985, -3526584, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 6474985, -3526584, 5, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 6374985, -3626584, 1, 2 ) );
|
|
pTransform.clear();
|
|
pTransform.setExteriorRing( l22.clone() );
|
|
pTransform.addInteriorRing( l22.clone() );
|
|
pTransform.transform( tr, QgsCoordinateTransform::ForwardTransform );
|
|
extR = static_cast< const QgsLineString * >( pTransform.exteriorRing() );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).x(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).x(), 176.958633, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).z(), 5.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).m(), 6.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.exteriorRing()->boundingBox().xMinimum(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.exteriorRing()->boundingBox().yMinimum(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.exteriorRing()->boundingBox().xMaximum(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.exteriorRing()->boundingBox().yMaximum(), -38.7999, 0.001 );
|
|
intR = static_cast< const QgsLineString * >( pTransform.interiorRing( 0 ) );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).x(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).x(), 176.958633, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).z(), 5.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).m(), 6.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.interiorRing( 0 )->boundingBox().xMinimum(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.interiorRing( 0 )->boundingBox().yMinimum(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.interiorRing( 0 )->boundingBox().xMaximum(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.interiorRing( 0 )->boundingBox().yMaximum(), -38.7999, 0.001 );
|
|
|
|
//reverse transform
|
|
pTransform.transform( tr, QgsCoordinateTransform::ReverseTransform );
|
|
extR = static_cast< const QgsLineString * >( pTransform.exteriorRing() );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).x(), 6374984, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).y(), -3626584, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).x(), 6274984, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).y(), -3526584, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).x(), 6474984, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).y(), -3526584, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).z(), 5.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).m(), 6.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).x(), 6374984, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).y(), -3626584, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( pTransform.exteriorRing()->boundingBox().xMinimum(), 6274984, 100 );
|
|
QGSCOMPARENEAR( pTransform.exteriorRing()->boundingBox().yMinimum(), -3626584, 100 );
|
|
QGSCOMPARENEAR( pTransform.exteriorRing()->boundingBox().xMaximum(), 6474984, 100 );
|
|
QGSCOMPARENEAR( pTransform.exteriorRing()->boundingBox().yMaximum(), -3526584, 100 );
|
|
intR = static_cast< const QgsLineString * >( pTransform.interiorRing( 0 ) );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).x(), 6374984, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).y(), -3626584, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).x(), 6274984, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).y(), -3526584, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).x(), 6474984, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).y(), -3526584, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).z(), 5.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).m(), 6.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).x(), 6374984, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).y(), -3626584, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().xMinimum(), 6274984, 100 );
|
|
QGSCOMPARENEAR( intR->boundingBox().yMinimum(), -3626584, 100 );
|
|
QGSCOMPARENEAR( intR->boundingBox().xMaximum(), 6474984, 100 );
|
|
QGSCOMPARENEAR( intR->boundingBox().yMaximum(), -3526584, 100 );
|
|
|
|
//z value transform
|
|
pTransform.transform( tr, QgsCoordinateTransform::ForwardTransform, true );
|
|
extR = static_cast< const QgsLineString * >( pTransform.exteriorRing() );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).z(), -19.249066, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).z(), -19.148357, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).z(), -19.092128, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).z(), -19.249066, 0.001 );
|
|
intR = static_cast< const QgsLineString * >( pTransform.interiorRing( 0 ) );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).z(), -19.249066, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).z(), -19.148357, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).z(), -19.092128, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).z(), -19.249066, 0.001 );
|
|
pTransform.transform( tr, QgsCoordinateTransform::ReverseTransform, true );
|
|
extR = static_cast< const QgsLineString * >( pTransform.exteriorRing() );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).z(), 1, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).z(), 3, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).z(), 5, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).z(), 1, 0.001 );
|
|
intR = static_cast< const QgsLineString * >( pTransform.interiorRing( 0 ) );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).z(), 1, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).z(), 3, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).z(), 5, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).z(), 1, 0.001 );
|
|
|
|
//QTransform transform
|
|
QTransform qtr = QTransform::fromScale( 2, 3 );
|
|
QgsLineString l23;
|
|
l23.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 12, 23, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
QgsPolygonV2 pTransform2;
|
|
pTransform2.setExteriorRing( l23.clone() );
|
|
pTransform2.addInteriorRing( l23.clone() );
|
|
pTransform2.transform( qtr );
|
|
|
|
extR = static_cast< const QgsLineString * >( pTransform2.exteriorRing() );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).x(), 2, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).y(), 6, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).x(), 22, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).y(), 36, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).z(), 13.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).m(), 14.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).x(), 2, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).y(), 36, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).z(), 23.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).m(), 24.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).x(), 2, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).y(), 6, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( pTransform2.exteriorRing()->boundingBox().xMinimum(), 2, 0.001 );
|
|
QGSCOMPARENEAR( pTransform2.exteriorRing()->boundingBox().yMinimum(), 6, 0.001 );
|
|
QGSCOMPARENEAR( pTransform2.exteriorRing()->boundingBox().xMaximum(), 22, 0.001 );
|
|
QGSCOMPARENEAR( pTransform2.exteriorRing()->boundingBox().yMaximum(), 36, 0.001 );
|
|
intR = static_cast< const QgsLineString * >( pTransform2.interiorRing( 0 ) );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).x(), 2, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).y(), 6, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).x(), 22, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).y(), 36, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).z(), 13.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).m(), 14.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).x(), 2, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).y(), 36, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).z(), 23.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).m(), 24.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).x(), 2, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).y(), 6, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().xMinimum(), 2, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().yMinimum(), 6, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().xMaximum(), 22, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().yMaximum(), 36, 0.001 );
|
|
|
|
// closestSegment
|
|
QgsPoint pt;
|
|
QgsVertexId v;
|
|
bool leftOf = false;
|
|
QgsPolygonV2 empty;
|
|
( void )empty.closestSegment( QgsPoint( 1, 2 ), pt, v ); // empty polygon, just want no crash
|
|
|
|
QgsPolygonV2 p21;
|
|
QgsLineString p21ls;
|
|
p21ls.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 7, 12 ) << QgsPoint( 5, 15 ) << QgsPoint( 5, 10 ) );
|
|
p21.setExteriorRing( p21ls.clone() );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 4, 11 ), pt, v, &leftOf ), 1.0, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 11, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 8, 11 ), pt, v, &leftOf ), 2.0, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 7, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 12, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 6, 11.5 ), pt, v, &leftOf ), 0.125000, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 6.25, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 11.25, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 7, 16 ), pt, v, &leftOf ), 4.923077, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5.153846, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 14.769231, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 5.5, 13.5 ), pt, v, &leftOf ), 0.173077, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5.846154, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 13.730769, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, true );
|
|
// point directly on segment
|
|
QCOMPARE( p21.closestSegment( QgsPoint( 5, 15 ), pt, v, &leftOf ), 0.0 );
|
|
QCOMPARE( pt, QgsPoint( 5, 15 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
// with interior ring
|
|
p21ls.setPoints( QgsPointSequence() << QgsPoint( 6, 11.5 ) << QgsPoint( 6.5, 12 ) << QgsPoint( 6, 13 ) << QgsPoint( 6, 11.5 ) );
|
|
p21.addInteriorRing( p21ls.clone() );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 4, 11 ), pt, v, &leftOf ), 1.0, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 11, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 8, 11 ), pt, v, &leftOf ), 2.0, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 7, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 12, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 6, 11.4 ), pt, v, &leftOf ), 0.01, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 6.0, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 11.5, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 7, 16 ), pt, v, &leftOf ), 4.923077, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5.153846, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 14.769231, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 5.5, 13.5 ), pt, v, &leftOf ), 0.173077, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5.846154, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 13.730769, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, true );
|
|
// point directly on segment
|
|
QCOMPARE( p21.closestSegment( QgsPoint( 6, 13 ), pt, v, &leftOf ), 0.0 );
|
|
QCOMPARE( pt, QgsPoint( 6, 13 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 2 ) );
|
|
|
|
//nextVertex
|
|
QgsPolygonV2 p22;
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 0, -2 );
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 0, 10 );
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
QgsLineString lp22;
|
|
lp22.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 12 ) << QgsPoint( 1, 2 ) );
|
|
p22.setExteriorRing( lp22.clone() );
|
|
v = QgsVertexId( 0, 0, 4 ); //out of range
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 0, -5 );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( pt, QgsPoint( 1, 2 ) );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( pt, QgsPoint( 11, 12 ) );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( pt, QgsPoint( 1, 12 ) );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( pt, QgsPoint( 1, 2 ) );
|
|
v = QgsVertexId( 0, 1, 0 );
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 1, 0, 0 );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 1, 0, 1 ) ); //test that part number is maintained
|
|
QCOMPARE( pt, QgsPoint( 11, 12 ) );
|
|
// add interior ring
|
|
lp22.setPoints( QgsPointSequence() << QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 11, 22 ) << QgsPoint( 11, 12 ) );
|
|
p22.addInteriorRing( lp22.clone() );
|
|
v = QgsVertexId( 0, 1, 4 ); //out of range
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 1, -5 );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 1, -1 );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 0 ) );
|
|
QCOMPARE( pt, QgsPoint( 11, 12 ) );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 1 ) );
|
|
QCOMPARE( pt, QgsPoint( 21, 22 ) );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 2 ) );
|
|
QCOMPARE( pt, QgsPoint( 11, 22 ) );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 3 ) );
|
|
QCOMPARE( pt, QgsPoint( 11, 12 ) );
|
|
v = QgsVertexId( 0, 2, 0 );
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 1, 1, 0 );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 1, 1, 1 ) ); //test that part number is maintained
|
|
QCOMPARE( pt, QgsPoint( 21, 22 ) );
|
|
|
|
// dropZValue
|
|
QgsPolygonV2 p23;
|
|
p23.dropZValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::Polygon );
|
|
QgsLineString lp23;
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 12 ) << QgsPoint( 1, 2 ) );
|
|
p23.setExteriorRing( lp23.clone() );
|
|
p23.addInteriorRing( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::Polygon );
|
|
p23.dropZValue(); // not z
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::Polygon );
|
|
QCOMPARE( p23.exteriorRing()->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.exteriorRing() )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( p23.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
// with z
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2, 3 ) << QgsPoint( 11, 12, 13 ) << QgsPoint( 1, 12, 23 ) << QgsPoint( 1, 2, 3 ) );
|
|
p23.clear();
|
|
p23.setExteriorRing( lp23.clone() );
|
|
p23.addInteriorRing( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::PolygonZ );
|
|
p23.dropZValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::Polygon );
|
|
QCOMPARE( p23.exteriorRing()->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.exteriorRing() )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( p23.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
// with zm
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2, 3, 4 ) << QgsPoint( 11, 12, 13, 14 ) << QgsPoint( 1, 12, 23, 24 ) << QgsPoint( 1, 2, 3, 4 ) );
|
|
p23.clear();
|
|
p23.setExteriorRing( lp23.clone() );
|
|
p23.addInteriorRing( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::PolygonZM );
|
|
p23.dropZValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::PolygonM );
|
|
QCOMPARE( p23.exteriorRing()->wkbType(), QgsWkbTypes::LineStringM );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QCOMPARE( p23.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineStringM );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
|
|
// dropMValue
|
|
p23.clear();
|
|
p23.dropMValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::Polygon );
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 12 ) << QgsPoint( 1, 2 ) );
|
|
p23.setExteriorRing( lp23.clone() );
|
|
p23.addInteriorRing( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::Polygon );
|
|
p23.dropMValue(); // not zm
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::Polygon );
|
|
QCOMPARE( p23.exteriorRing()->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.exteriorRing() )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( p23.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
// with m
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 13 ) << QgsPoint( QgsWkbTypes::PointM, 1, 12, 0, 23 ) << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) );
|
|
p23.clear();
|
|
p23.setExteriorRing( lp23.clone() );
|
|
p23.addInteriorRing( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::PolygonM );
|
|
p23.dropMValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::Polygon );
|
|
QCOMPARE( p23.exteriorRing()->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.exteriorRing() )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( p23.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
// with zm
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2, 3, 4 ) << QgsPoint( 11, 12, 13, 14 ) << QgsPoint( 1, 12, 23, 24 ) << QgsPoint( 1, 2, 3, 4 ) );
|
|
p23.clear();
|
|
p23.setExteriorRing( lp23.clone() );
|
|
p23.addInteriorRing( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::PolygonZM );
|
|
p23.dropMValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::PolygonZ );
|
|
QCOMPARE( p23.exteriorRing()->wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QCOMPARE( p23.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
|
|
//vertexAngle
|
|
QgsPolygonV2 p24;
|
|
( void )p24.vertexAngle( QgsVertexId() ); //just want no crash
|
|
( void )p24.vertexAngle( QgsVertexId( 0, 0, 0 ) ); //just want no crash
|
|
( void )p24.vertexAngle( QgsVertexId( 0, 1, 0 ) ); //just want no crash
|
|
QgsLineString l38;
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0.5, 0 ) << QgsPoint( 1, 0 )
|
|
<< QgsPoint( 2, 1 ) << QgsPoint( 1, 2 ) << QgsPoint( 0, 2 ) << QgsPoint( 0, 0 ) );
|
|
p24.setExteriorRing( l38.clone() );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 2.35619, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 1.17809, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 3 ) ), 0.0, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 4 ) ), 5.10509, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 5 ) ), 3.92699, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 6 ) ), 2.35619, 0.00001 );
|
|
p24.addInteriorRing( l38.clone() );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 1, 0 ) ), 2.35619, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 1, 1 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 1, 2 ) ), 1.17809, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 1, 3 ) ), 0.0, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 1, 4 ) ), 5.10509, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 1, 5 ) ), 3.92699, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 1, 6 ) ), 2.35619, 0.00001 );
|
|
|
|
//insert vertex
|
|
|
|
//insert vertex in empty polygon
|
|
QgsPolygonV2 p25;
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 1, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 1, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( p25.isEmpty() );
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0.5, 0 ) << QgsPoint( 1, 0 )
|
|
<< QgsPoint( 2, 1 ) << QgsPoint( 1, 2 ) << QgsPoint( 0, 2 ) << QgsPoint( 0, 0 ) );
|
|
p25.setExteriorRing( l38.clone() );
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 0.3, 0 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 8 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 0 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 1 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 2 ), QgsPoint( 0.5, 0 ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 0, -1 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 0, 100 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 1, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
// first vertex
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 0, 0.1 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 9 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 0 ), QgsPoint( 0, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 2 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 3 ), QgsPoint( 0.5, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 7 ), QgsPoint( 0, 2 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 8 ), QgsPoint( 0, 0.1 ) );
|
|
// last vertex
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 0, 9 ), QgsPoint( 0.1, 0.1 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 10 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 0 ), QgsPoint( 0.1, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 2 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 3 ), QgsPoint( 0.5, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 8 ), QgsPoint( 0, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 9 ), QgsPoint( 0.1, 0.1 ) );
|
|
// with interior ring
|
|
p25.addInteriorRing( l38.clone() );
|
|
QCOMPARE( p25.nCoordinates(), 17 );
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 1, 1 ), QgsPoint( 0.3, 0 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 18 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 0.5, 0 ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 1, -1 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 1, 100 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 2, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
// first vertex in interior ring
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 1, 0 ), QgsPoint( 0, 0.1 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 19 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 0, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 3 ), QgsPoint( 0.5, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 7 ), QgsPoint( 0, 2 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 8 ), QgsPoint( 0, 0.1 ) );
|
|
// last vertex in interior ring
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 1, 9 ), QgsPoint( 0.1, 0.1 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 20 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 0.1, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 3 ), QgsPoint( 0.5, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 8 ), QgsPoint( 0, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 9 ), QgsPoint( 0.1, 0.1 ) );
|
|
|
|
//move vertex
|
|
|
|
//empty polygon
|
|
QgsPolygonV2 p26;
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( p26.isEmpty() );
|
|
|
|
//valid polygon
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 1, 2 ) );
|
|
p26.setExteriorRing( l38.clone() );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 16.0, 17.0 ) ) );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 0, 2 ), QgsPoint( 26.0, 27.0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 3 ), QgsPoint( 6.0, 7.0 ) );
|
|
|
|
//out of range
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 0, -1 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 0, 10 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 1, 0 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 3 ), QgsPoint( 6.0, 7.0 ) );
|
|
|
|
// with interior ring
|
|
p26.addInteriorRing( l38.clone() );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 1, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 1, 1 ), QgsPoint( 16.0, 17.0 ) ) );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 1, 2 ), QgsPoint( 26.0, 27.0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.interiorRing( 0 ) )->pointN( 3 ), QgsPoint( 6.0, 7.0 ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 1, -1 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 1, 10 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 2, 0 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
|
|
//delete vertex
|
|
|
|
//empty polygon
|
|
QgsPolygonV2 p27;
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 1, 0 ) ) );
|
|
QVERIFY( p27.isEmpty() );
|
|
|
|
//valid polygon
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 5, 2 ) << QgsPoint( 6, 2 ) << QgsPoint( 7, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 1, 2 ) );
|
|
|
|
p27.setExteriorRing( l38.clone() );
|
|
//out of range vertices
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 0, -1 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 0, 100 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 1, 1 ) ) );
|
|
|
|
//valid vertices
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 1 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 0 ), QgsPoint( 1.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 1 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 2 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 3 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 5 ), QgsPoint( 1.0, 2.0 ) );
|
|
|
|
// delete first vertex
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 0 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 1 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 2 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 3 ), QgsPoint( 21.0, 22.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 4 ), QgsPoint( 6.0, 2.0 ) );
|
|
|
|
// delete last vertex
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 4 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 0 ), QgsPoint( 21.0, 22.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 1 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 2 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 3 ), QgsPoint( 21.0, 22.0 ) );
|
|
|
|
// delete another vertex - should remove ring
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 1 ) ) );
|
|
QVERIFY( !p27.exteriorRing() );
|
|
|
|
// with interior ring
|
|
p27.setExteriorRing( l38.clone() );
|
|
p27.addInteriorRing( l38.clone() );
|
|
|
|
//out of range vertices
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 1, -1 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 1, 100 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 2, 1 ) ) );
|
|
|
|
//valid vertices
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 1, 1 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 1.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 3 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 5 ), QgsPoint( 1.0, 2.0 ) );
|
|
|
|
// delete first vertex
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 1, 0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 3 ), QgsPoint( 21.0, 22.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 4 ), QgsPoint( 6.0, 2.0 ) );
|
|
|
|
// delete last vertex
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 1, 4 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 21.0, 22.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 3 ), QgsPoint( 21.0, 22.0 ) );
|
|
|
|
// delete another vertex - should remove ring
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 1, 1 ) ) );
|
|
QCOMPARE( p27.numInteriorRings(), 0 );
|
|
QVERIFY( p27.exteriorRing() );
|
|
|
|
// test that interior ring is "promoted" when exterior is removed
|
|
p27.addInteriorRing( l38.clone() );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( p27.numInteriorRings(), 1 );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( p27.numInteriorRings(), 1 );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( p27.numInteriorRings(), 1 );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( p27.numInteriorRings(), 0 );
|
|
QVERIFY( p27.exteriorRing() );
|
|
|
|
}
|
|
|
|
void TestQgsGeometry::triangle()
|
|
{
|
|
//test constructor
|
|
QgsTriangle t1;
|
|
QVERIFY( t1.isEmpty() );
|
|
QCOMPARE( t1.numInteriorRings(), 0 );
|
|
QCOMPARE( t1.nCoordinates(), 0 );
|
|
QCOMPARE( t1.ringCount(), 0 );
|
|
QCOMPARE( t1.partCount(), 0 );
|
|
QVERIFY( !t1.is3D() );
|
|
QVERIFY( !t1.isMeasure() );
|
|
QCOMPARE( t1.wkbType(), QgsWkbTypes::Triangle );
|
|
QCOMPARE( t1.wktTypeStr(), QString( "Triangle" ) );
|
|
QCOMPARE( t1.geometryType(), QString( "Triangle" ) );
|
|
QCOMPARE( t1.dimension(), 2 );
|
|
QVERIFY( !t1.hasCurvedSegments() );
|
|
QCOMPARE( t1.area(), 0.0 );
|
|
QCOMPARE( t1.perimeter(), 0.0 );
|
|
QVERIFY( !t1.exteriorRing() );
|
|
QVERIFY( !t1.interiorRing( 0 ) );
|
|
|
|
// invalid triangles
|
|
QgsTriangle invalid( QgsPointXY( 0, 0 ), QgsPointXY( 0, 0 ), QgsPointXY( 10, 10 ) );
|
|
QVERIFY( invalid.isEmpty() );
|
|
invalid = QgsTriangle( QPointF( 0, 0 ), QPointF( 0, 0 ), QPointF( 10, 10 ) );
|
|
QVERIFY( invalid.isEmpty() );
|
|
//set exterior ring
|
|
|
|
//try with no ring
|
|
std::unique_ptr< QgsLineString > ext;
|
|
t1.setExteriorRing( nullptr );
|
|
QVERIFY( t1.isEmpty() );
|
|
QCOMPARE( t1.numInteriorRings(), 0 );
|
|
QCOMPARE( t1.nCoordinates(), 0 );
|
|
QCOMPARE( t1.ringCount(), 0 );
|
|
QCOMPARE( t1.partCount(), 0 );
|
|
QVERIFY( !t1.exteriorRing() );
|
|
QVERIFY( !t1.interiorRing( 0 ) );
|
|
QCOMPARE( t1.wkbType(), QgsWkbTypes::Triangle );
|
|
|
|
//valid exterior ring
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 0, 0 ) );
|
|
QVERIFY( ext->isClosed() );
|
|
t1.setExteriorRing( ext->clone() );
|
|
QVERIFY( !t1.isEmpty() );
|
|
QCOMPARE( t1.numInteriorRings(), 0 );
|
|
QCOMPARE( t1.nCoordinates(), 4 );
|
|
QCOMPARE( t1.ringCount(), 1 );
|
|
QCOMPARE( t1.partCount(), 1 );
|
|
QVERIFY( !t1.is3D() );
|
|
QVERIFY( !t1.isMeasure() );
|
|
QCOMPARE( t1.wkbType(), QgsWkbTypes::Triangle );
|
|
QCOMPARE( t1.wktTypeStr(), QString( "Triangle" ) );
|
|
QCOMPARE( t1.geometryType(), QString( "Triangle" ) );
|
|
QCOMPARE( t1.dimension(), 2 );
|
|
QVERIFY( !t1.hasCurvedSegments() );
|
|
QCOMPARE( t1.area(), 50.0 );
|
|
QGSCOMPARENEAR( t1.perimeter(), 34.1421, 0.001 );
|
|
QVERIFY( t1.exteriorRing() );
|
|
QVERIFY( !t1.interiorRing( 0 ) );
|
|
|
|
//retrieve exterior ring and check
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( t1.exteriorRing() ) ), *ext );
|
|
|
|
//set new ExteriorRing
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 10 ) << QgsPoint( 5, 5 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 0, 10 ) );
|
|
QVERIFY( ext->isClosed() );
|
|
t1.setExteriorRing( ext->clone() );
|
|
QVERIFY( !t1.isEmpty() );
|
|
QCOMPARE( t1.numInteriorRings(), 0 );
|
|
QCOMPARE( t1.nCoordinates(), 4 );
|
|
QCOMPARE( t1.ringCount(), 1 );
|
|
QCOMPARE( t1.partCount(), 1 );
|
|
QVERIFY( !t1.is3D() );
|
|
QVERIFY( !t1.isMeasure() );
|
|
QCOMPARE( t1.wkbType(), QgsWkbTypes::Triangle );
|
|
QCOMPARE( t1.wktTypeStr(), QString( "Triangle" ) );
|
|
QCOMPARE( t1.geometryType(), QString( "Triangle" ) );
|
|
QCOMPARE( t1.dimension(), 2 );
|
|
QVERIFY( !t1.hasCurvedSegments() );
|
|
QCOMPARE( t1.area(), 25.0 );
|
|
QGSCOMPARENEAR( t1.perimeter(), 24.1421, 0.001 );
|
|
QVERIFY( t1.exteriorRing() );
|
|
QVERIFY( !t1.interiorRing( 0 ) );
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( t1.exteriorRing() ) ), *ext );
|
|
|
|
//test that a non closed exterior ring will be automatically closed
|
|
QgsTriangle t2;
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 ) );
|
|
QVERIFY( !ext->isClosed() );
|
|
t2.setExteriorRing( ext.release() );
|
|
QVERIFY( !t2.isEmpty() );
|
|
QVERIFY( t2.exteriorRing()->isClosed() );
|
|
QCOMPARE( t2.nCoordinates(), 4 );
|
|
|
|
// invalid number of points
|
|
ext.reset( new QgsLineString() );
|
|
t2.clear();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) );
|
|
t2.setExteriorRing( ext.release() );
|
|
QVERIFY( t2.isEmpty() );
|
|
|
|
ext.reset( new QgsLineString() );
|
|
t2.clear();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 ) << QgsPoint( 5, 10 ) << QgsPoint( 8, 10 ) );
|
|
t2.setExteriorRing( ext.release() );
|
|
QVERIFY( t2.isEmpty() );
|
|
|
|
// invalid exterior ring
|
|
ext.reset( new QgsLineString() );
|
|
t2.clear();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 ) << QgsPoint( 5, 10 ) );
|
|
t2.setExteriorRing( ext.release() );
|
|
QVERIFY( t2.isEmpty() );
|
|
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 0, 0 ) );
|
|
t2.setExteriorRing( ext.release() );
|
|
QVERIFY( t2.isEmpty() );
|
|
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 0, 0 ) );
|
|
t2.setExteriorRing( ext.release() );
|
|
QVERIFY( t2.isEmpty() );
|
|
|
|
// circular ring
|
|
QgsCircularString *circularRing = new QgsCircularString();
|
|
t2.clear();
|
|
circularRing->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 ) );
|
|
QVERIFY( circularRing->hasCurvedSegments() );
|
|
t2.setExteriorRing( circularRing );
|
|
QVERIFY( t2.isEmpty() );
|
|
|
|
//constructor with 3 points
|
|
// double points
|
|
QgsTriangle t3( QgsPoint( 0, 0 ), QgsPoint( 0, 0 ), QgsPoint( 10, 10 ) );
|
|
QVERIFY( t3.isEmpty() );
|
|
QCOMPARE( t3.numInteriorRings(), 0 );
|
|
QCOMPARE( t3.nCoordinates(), 0 );
|
|
QCOMPARE( t3.ringCount(), 0 );
|
|
QCOMPARE( t3.partCount(), 0 );
|
|
QVERIFY( !t3.is3D() );
|
|
QVERIFY( !t3.isMeasure() );
|
|
QCOMPARE( t3.wkbType(), QgsWkbTypes::Triangle );
|
|
QCOMPARE( t3.wktTypeStr(), QString( "Triangle" ) );
|
|
QCOMPARE( t3.geometryType(), QString( "Triangle" ) );
|
|
QCOMPARE( t3.dimension(), 2 );
|
|
QVERIFY( !t3.hasCurvedSegments() );
|
|
QCOMPARE( t3.area(), 0.0 );
|
|
QCOMPARE( t3.perimeter(), 0.0 );
|
|
QVERIFY( !t3.exteriorRing() );
|
|
QVERIFY( !t3.interiorRing( 0 ) );
|
|
|
|
// colinear
|
|
t3 = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 0, 10 ) );
|
|
QVERIFY( t3.isEmpty() );
|
|
QCOMPARE( t3.numInteriorRings(), 0 );
|
|
QCOMPARE( t3.nCoordinates(), 0 );
|
|
QCOMPARE( t3.ringCount(), 0 );
|
|
QCOMPARE( t3.partCount(), 0 );
|
|
QVERIFY( !t3.is3D() );
|
|
QVERIFY( !t3.isMeasure() );
|
|
QCOMPARE( t3.wkbType(), QgsWkbTypes::Triangle );
|
|
QCOMPARE( t3.wktTypeStr(), QString( "Triangle" ) );
|
|
QCOMPARE( t3.geometryType(), QString( "Triangle" ) );
|
|
QCOMPARE( t3.dimension(), 2 );
|
|
QVERIFY( !t3.hasCurvedSegments() );
|
|
QCOMPARE( t3.area(), 0.0 );
|
|
QCOMPARE( t3.perimeter(), 0.0 );
|
|
QVERIFY( !t3.exteriorRing() );
|
|
QVERIFY( !t3.interiorRing( 0 ) );
|
|
|
|
t3 = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 10 ), QgsPoint( 10, 10 ) );
|
|
QVERIFY( !t3.isEmpty() );
|
|
QCOMPARE( t3.numInteriorRings(), 0 );
|
|
QCOMPARE( t3.nCoordinates(), 4 );
|
|
QCOMPARE( t3.ringCount(), 1 );
|
|
QCOMPARE( t3.partCount(), 1 );
|
|
QVERIFY( !t3.is3D() );
|
|
QVERIFY( !t3.isMeasure() );
|
|
QCOMPARE( t3.wkbType(), QgsWkbTypes::Triangle );
|
|
QCOMPARE( t3.wktTypeStr(), QString( "Triangle" ) );
|
|
QCOMPARE( t3.geometryType(), QString( "Triangle" ) );
|
|
QCOMPARE( t3.dimension(), 2 );
|
|
QVERIFY( !t3.hasCurvedSegments() );
|
|
QCOMPARE( t3.area(), 50.0 );
|
|
QGSCOMPARENEAR( t3.perimeter(), 34.1421, 0.001 );
|
|
QVERIFY( t3.exteriorRing() );
|
|
QVERIFY( !t3.interiorRing( 0 ) );
|
|
|
|
// equality
|
|
QVERIFY( QgsTriangle() == QgsTriangle() ); // empty
|
|
QVERIFY( QgsTriangle() == QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 0, 10 ) ) ); // empty
|
|
QVERIFY( QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 0, 10 ) ) == QgsTriangle() ); // empty
|
|
QVERIFY( QgsTriangle() != QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 5, 5 ), QgsPoint( 0, 10 ) ) );
|
|
QVERIFY( QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 5, 5 ), QgsPoint( 0, 10 ) ) != QgsTriangle() );
|
|
QVERIFY( QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 5, 5 ), QgsPoint( 0, 10 ) ) != QgsTriangle( QgsPoint( 0, 10 ), QgsPoint( 5, 5 ), QgsPoint( 0, 0 ) ) );
|
|
|
|
// clone
|
|
QgsTriangle *t4 = t3.clone();
|
|
QCOMPARE( t3, *t4 );
|
|
delete t4;
|
|
|
|
// constructor from QgsPointXY and QPointF
|
|
QgsTriangle t_qgspoint = QgsTriangle( QgsPointXY( 0, 0 ), QgsPointXY( 0, 10 ), QgsPointXY( 10, 10 ) );
|
|
QVERIFY( t3 == t_qgspoint );
|
|
QgsTriangle t_pointf = QgsTriangle( QPointF( 0, 0 ), QPointF( 0, 10 ), QPointF( 10, 10 ) );
|
|
QVERIFY( t3 == t_pointf );
|
|
|
|
// fromWkt
|
|
QgsTriangle t5;
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 ) );
|
|
t5.setExteriorRing( ext.release() );
|
|
QString wkt = t5.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsTriangle t6;
|
|
QVERIFY( t6.fromWkt( wkt ) );
|
|
QCOMPARE( t5, t6 );
|
|
|
|
// conversion
|
|
QgsPolygonV2 p1;
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 ) );
|
|
p1.setExteriorRing( ext.release() );
|
|
//toPolygon
|
|
std::unique_ptr< QgsPolygonV2 > poly( t5.toPolygon() );
|
|
QCOMPARE( *poly, p1 );
|
|
//surfaceToPolygon
|
|
std::unique_ptr< QgsPolygonV2 > surface( t5.surfaceToPolygon() );
|
|
QCOMPARE( *surface, p1 );
|
|
|
|
//bad WKT
|
|
QVERIFY( !t6.fromWkt( "Point()" ) );
|
|
QVERIFY( t6.isEmpty() );
|
|
QVERIFY( !t6.exteriorRing() );
|
|
QCOMPARE( t6.numInteriorRings(), 0 );
|
|
QVERIFY( !t6.is3D() );
|
|
QVERIFY( !t6.isMeasure() );
|
|
QCOMPARE( t6.wkbType(), QgsWkbTypes::Triangle );
|
|
|
|
// WKB
|
|
QByteArray wkb = t5.asWkb();
|
|
t6.clear();
|
|
QgsConstWkbPtr wkb16ptr5( wkb );
|
|
t6.fromWkb( wkb16ptr5 );
|
|
QCOMPARE( t5.wkbType(), QgsWkbTypes::TriangleZM );
|
|
QCOMPARE( t5, t6 );
|
|
|
|
//bad WKB - check for no crash
|
|
t6.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !t6.fromWkb( nullPtr ) );
|
|
QCOMPARE( t6.wkbType(), QgsWkbTypes::Triangle );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkbPoint = point.asWkb();
|
|
QgsConstWkbPtr wkbPointPtr( wkbPoint );
|
|
QVERIFY( !t6.fromWkb( wkbPointPtr ) );
|
|
QCOMPARE( t6.wkbType(), QgsWkbTypes::Triangle );
|
|
|
|
// lengths and angles
|
|
QgsTriangle t7( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) );
|
|
|
|
QVector<double> a_tested, a_t7 = t7.angles();
|
|
a_tested.append( M_PI / 4.0 );
|
|
a_tested.append( M_PI / 2.0 );
|
|
a_tested.append( M_PI / 4.0 );
|
|
QGSCOMPARENEAR( a_tested.at( 0 ), a_t7.at( 0 ), 0.0001 );
|
|
QGSCOMPARENEAR( a_tested.at( 1 ), a_t7.at( 1 ), 0.0001 );
|
|
QGSCOMPARENEAR( a_tested.at( 2 ), a_t7.at( 2 ), 0.0001 );
|
|
|
|
QVector<double> l_tested, l_t7 = t7.lengths();
|
|
l_tested.append( 5 );
|
|
l_tested.append( 5 );
|
|
l_tested.append( std::sqrt( 5 * 5 + 5 * 5 ) );
|
|
QGSCOMPARENEAR( l_tested.at( 0 ), l_t7.at( 0 ), 0.0001 );
|
|
QGSCOMPARENEAR( l_tested.at( 1 ), l_t7.at( 1 ), 0.0001 );
|
|
QGSCOMPARENEAR( l_tested.at( 2 ), l_t7.at( 2 ), 0.0001 );
|
|
|
|
// type of triangle
|
|
QVERIFY( t7.isRight() );
|
|
QVERIFY( t7.isIsocele() );
|
|
QVERIFY( !t7.isScalene() );
|
|
QVERIFY( !t7.isEquilateral() );
|
|
|
|
QgsTriangle t8( QgsPoint( 7.2825, 4.2368 ), QgsPoint( 13.0058, 3.3218 ), QgsPoint( 9.2145, 6.5242 ) );
|
|
// angles in radians 58.8978;31.1036;89.9985
|
|
// length 5.79598;4.96279;2.99413
|
|
QVERIFY( t8.isRight() );
|
|
QVERIFY( !t8.isIsocele() );
|
|
QVERIFY( t8.isScalene() );
|
|
QVERIFY( !t8.isEquilateral() );
|
|
|
|
QgsTriangle t9( QgsPoint( 10, 10 ), QgsPoint( 16, 10 ), QgsPoint( 13, 15.1962 ) );
|
|
QVERIFY( !t9.isRight() );
|
|
QVERIFY( t9.isIsocele() );
|
|
QVERIFY( !t9.isScalene() );
|
|
QVERIFY( t9.isEquilateral() );
|
|
|
|
// vertex
|
|
QCOMPARE( t9.vertexAt( -1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( t9.vertexAt( 0 ), QgsPoint( 10, 10 ) );
|
|
QCOMPARE( t9.vertexAt( 1 ), QgsPoint( 16, 10 ) );
|
|
QCOMPARE( t9.vertexAt( 2 ), QgsPoint( 13, 15.1962 ) );
|
|
QCOMPARE( t9.vertexAt( 3 ), QgsPoint( 10, 10 ) );
|
|
QCOMPARE( t9.vertexAt( 4 ), QgsPoint( 0, 0 ) );
|
|
|
|
// altitudes
|
|
QgsTriangle t10( QgsPoint( 20, 2 ), QgsPoint( 16, 6 ), QgsPoint( 26, 2 ) );
|
|
QVector<QgsLineString> alt = t10.altitudes();
|
|
QGSCOMPARENEARPOINT( alt.at( 0 ).pointN( 1 ), QgsPoint( 20.8276, 4.0690 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( alt.at( 1 ).pointN( 1 ), QgsPoint( 16, 2 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( alt.at( 2 ).pointN( 1 ), QgsPoint( 23, -1 ), 0.0001 );
|
|
|
|
// orthocenter
|
|
QCOMPARE( QgsPoint( 16, -8 ), t10.orthocenter() );
|
|
QCOMPARE( QgsPoint( 0, 5 ), t7.orthocenter() );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 13, 11.7321 ), t9.orthocenter(), 0.0001 );
|
|
|
|
// circumscribed circle
|
|
QCOMPARE( QgsPoint( 2.5, 2.5 ), t7.circumscribedCenter() );
|
|
QGSCOMPARENEAR( 3.5355, t7.circumscribedRadius(), 0.0001 );
|
|
QCOMPARE( QgsPoint( 23, 9 ), t10.circumscribedCenter() );
|
|
QGSCOMPARENEAR( 7.6158, t10.circumscribedRadius(), 0.0001 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 13, 11.7321 ), t9.circumscribedCenter(), 0.0001 );
|
|
QGSCOMPARENEAR( 3.4641, t9.circumscribedRadius(), 0.0001 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 13, 11.7321 ), t9.circumscribedCircle().center(), 0.0001 );
|
|
QGSCOMPARENEAR( 3.4641, t9.circumscribedCircle().radius(), 0.0001 );
|
|
|
|
// inscribed circle
|
|
QGSCOMPARENEARPOINT( QgsPoint( 1.4645, 3.5355 ), t7.inscribedCenter(), 0.001 );
|
|
QGSCOMPARENEAR( 1.4645, t7.inscribedRadius(), 0.0001 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 20.4433, 3.0701 ), t10.inscribedCenter(), 0.001 );
|
|
QGSCOMPARENEAR( 1.0701, t10.inscribedRadius(), 0.0001 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 13, 11.7321 ), t9.inscribedCenter(), 0.0001 );
|
|
QGSCOMPARENEAR( 1.7321, t9.inscribedRadius(), 0.0001 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 13, 11.7321 ), t9.inscribedCircle().center(), 0.0001 );
|
|
QGSCOMPARENEAR( 1.7321, t9.inscribedCircle().radius(), 0.0001 );
|
|
|
|
// medians
|
|
QVector<QgsLineString> med = t7.medians();
|
|
QCOMPARE( med.at( 0 ).pointN( 0 ), t7.vertexAt( 0 ) );
|
|
QGSCOMPARENEARPOINT( med.at( 0 ).pointN( 1 ), QgsPoint( 2.5, 5 ), 0.0001 );
|
|
QCOMPARE( med.at( 1 ).pointN( 0 ), t7.vertexAt( 1 ) );
|
|
QGSCOMPARENEARPOINT( med.at( 1 ).pointN( 1 ), QgsPoint( 2.5, 2.5 ), 0.0001 );
|
|
QCOMPARE( med.at( 2 ).pointN( 0 ), t7.vertexAt( 2 ) );
|
|
QGSCOMPARENEARPOINT( med.at( 2 ).pointN( 1 ), QgsPoint( 0, 2.5 ), 0.0001 );
|
|
med.clear();
|
|
|
|
med = t10.medians();
|
|
QCOMPARE( med.at( 0 ).pointN( 0 ), t10.vertexAt( 0 ) );
|
|
QGSCOMPARENEARPOINT( med.at( 0 ).pointN( 1 ), QgsPoint( 21, 4 ), 0.0001 );
|
|
QCOMPARE( med.at( 1 ).pointN( 0 ), t10.vertexAt( 1 ) );
|
|
QGSCOMPARENEARPOINT( med.at( 1 ).pointN( 1 ), QgsPoint( 23, 2 ), 0.0001 );
|
|
QCOMPARE( med.at( 2 ).pointN( 0 ), t10.vertexAt( 2 ) );
|
|
QGSCOMPARENEARPOINT( med.at( 2 ).pointN( 1 ), QgsPoint( 18, 4 ), 0.0001 );
|
|
med.clear();
|
|
alt.clear();
|
|
|
|
med = t9.medians();
|
|
alt = t9.altitudes();
|
|
QGSCOMPARENEARPOINT( med.at( 0 ).pointN( 0 ), alt.at( 0 ).pointN( 0 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( med.at( 0 ).pointN( 1 ), alt.at( 0 ).pointN( 1 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( med.at( 1 ).pointN( 0 ), alt.at( 1 ).pointN( 0 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( med.at( 1 ).pointN( 1 ), alt.at( 1 ).pointN( 1 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( med.at( 2 ).pointN( 0 ), alt.at( 2 ).pointN( 0 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( med.at( 2 ).pointN( 1 ), alt.at( 2 ).pointN( 1 ), 0.0001 );
|
|
|
|
// medial
|
|
QCOMPARE( t7.medial(), QgsTriangle( QgsPoint( 0, 2.5 ), QgsPoint( 2.5, 5 ), QgsPoint( 2.5, 2.5 ) ) );
|
|
QCOMPARE( t9.medial(), QgsTriangle( QgsGeometryUtils::midpoint( t9.vertexAt( 0 ), t9.vertexAt( 1 ) ),
|
|
QgsGeometryUtils::midpoint( t9.vertexAt( 1 ), t9.vertexAt( 2 ) ),
|
|
QgsGeometryUtils::midpoint( t9.vertexAt( 2 ), t9.vertexAt( 0 ) ) ) );
|
|
|
|
// bisectors
|
|
QVector<QgsLineString> bis = t7.bisectors();
|
|
QCOMPARE( bis.at( 0 ).pointN( 0 ), t7.vertexAt( 0 ) );
|
|
QGSCOMPARENEARPOINT( bis.at( 0 ).pointN( 1 ), QgsPoint( 2.0711, 5 ), 0.0001 );
|
|
QCOMPARE( bis.at( 1 ).pointN( 0 ), t7.vertexAt( 1 ) );
|
|
QGSCOMPARENEARPOINT( bis.at( 1 ).pointN( 1 ), QgsPoint( 2.5, 2.5 ), 0.0001 );
|
|
QCOMPARE( bis.at( 2 ).pointN( 0 ), t7.vertexAt( 2 ) );
|
|
QGSCOMPARENEARPOINT( bis.at( 2 ).pointN( 1 ), QgsPoint( 0, 2.9289 ), 0.0001 );
|
|
|
|
// "deleted" method
|
|
ext.reset( new QgsLineString() );
|
|
QgsTriangle t11( QgsPoint( 0, 0 ), QgsPoint( 100, 100 ), QgsPoint( 0, 200 ) );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 5, 5 )
|
|
<< QgsPoint( 50, 50 ) << QgsPoint( 0, 25 )
|
|
<< QgsPoint( 5, 5 ) );
|
|
t11.addInteriorRing( ext.release() );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 100 100, 0 200, 0 0))" ) );
|
|
|
|
/* QList<QgsCurve *> lc;
|
|
lc.append(ext);
|
|
t11.setInteriorRings( lc );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 100 100, 0 200, 0 0))" ) );*/
|
|
|
|
QgsVertexId id( 0, 0, 1 );
|
|
QVERIFY( !t11.deleteVertex( id ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 100 100, 0 200, 0 0))" ) );
|
|
QVERIFY( !t11.insertVertex( id, QgsPoint( 5, 5 ) ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 100 100, 0 200, 0 0))" ) );
|
|
|
|
//move vertex
|
|
QgsPoint pt1( 5, 5 );
|
|
// invalid part
|
|
id.part = -1;
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
id.part = 1;
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
// invalid ring
|
|
id.part = 0;
|
|
id.ring = -1;
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
id.ring = 1;
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
id.ring = 0;
|
|
id.vertex = -1;
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
id.vertex = 5;
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
|
|
// valid vertex
|
|
id.vertex = 0;
|
|
QVERIFY( t11.moveVertex( id, pt1 ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((5 5, 100 100, 0 200, 5 5))" ) );
|
|
pt1 = QgsPoint();
|
|
QVERIFY( t11.moveVertex( id, pt1 ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 100 100, 0 200, 0 0))" ) );
|
|
id.vertex = 4;
|
|
pt1 = QgsPoint( 5, 5 );
|
|
QVERIFY( t11.moveVertex( id, pt1 ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((5 5, 100 100, 0 200, 5 5))" ) );
|
|
pt1 = QgsPoint();
|
|
QVERIFY( t11.moveVertex( id, pt1 ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 100 100, 0 200, 0 0))" ) );
|
|
id.vertex = 1;
|
|
pt1 = QgsPoint( 5, 5 );
|
|
QVERIFY( t11.moveVertex( id, pt1 ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 5 5, 0 200, 0 0))" ) );
|
|
// colinear
|
|
pt1 = QgsPoint( 0, 100 );
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
// duplicate point
|
|
pt1 = QgsPoint( 0, 0 );
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
|
|
//toCurveType
|
|
QgsTriangle t12( QgsPoint( 7, 4 ), QgsPoint( 13, 3 ), QgsPoint( 9, 6 ) );
|
|
std::unique_ptr< QgsCurvePolygon > curveType( t12.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::CurvePolygon );
|
|
QCOMPARE( curveType->exteriorRing()->numPoints(), 4 );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 7, 4 ) );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( 13, 3 ) );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( 9, 6 ) );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 3 ) ), QgsPoint( 7, 4 ) );
|
|
QCOMPARE( curveType->numInteriorRings(), 0 );
|
|
|
|
// boundary
|
|
QVERIFY( !QgsTriangle().boundary() );
|
|
std::unique_ptr< QgsCurve > boundary( QgsTriangle( QgsPoint( 7, 4 ), QgsPoint( 13, 3 ), QgsPoint( 9, 6 ) ).boundary() );
|
|
QCOMPARE( boundary->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( boundary->numPoints(), 4 );
|
|
QCOMPARE( boundary->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 7, 4 ) );
|
|
QCOMPARE( boundary->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( 13, 3 ) );
|
|
QCOMPARE( boundary->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( 9, 6 ) );
|
|
QCOMPARE( boundary->vertexAt( QgsVertexId( 0, 0, 3 ) ), QgsPoint( 7, 4 ) );
|
|
|
|
// cast
|
|
QgsTriangle pCast;
|
|
QVERIFY( QgsPolygonV2().cast( &pCast ) );
|
|
QgsTriangle pCast2( QgsPoint( 7, 4 ), QgsPoint( 13, 3 ), QgsPoint( 9, 6 ) );;
|
|
QVERIFY( QgsPolygonV2().cast( &pCast2 ) );
|
|
}
|
|
|
|
void TestQgsGeometry::ellipse()
|
|
{
|
|
//test constructors
|
|
QgsEllipse elp1;
|
|
QVERIFY( elp1.center() == QgsPoint() );
|
|
QCOMPARE( elp1.semiMajorAxis(), 0.0 );
|
|
QCOMPARE( elp1.semiMinorAxis(), 0.0 );
|
|
QCOMPARE( elp1.azimuth(), 90.0 );
|
|
QVERIFY( elp1.isEmpty() );
|
|
|
|
QgsEllipse elp2( QgsPoint( 5, 10 ), 3, 2 );
|
|
QVERIFY( elp2.center() == QgsPoint( 5, 10 ) );
|
|
QCOMPARE( elp2.semiMajorAxis(), 3.0 );
|
|
QCOMPARE( elp2.semiMinorAxis(), 2.0 );
|
|
QCOMPARE( elp2.azimuth(), 90.0 );
|
|
QVERIFY( !elp2.isEmpty() );
|
|
|
|
QgsEllipse elp3( QgsPoint( 5, 10 ), 3, 2, 45 );
|
|
QVERIFY( elp3.center() == QgsPoint( 5, 10 ) );
|
|
QCOMPARE( elp3.semiMajorAxis(), 3.0 );
|
|
QCOMPARE( elp3.semiMinorAxis(), 2.0 );
|
|
QCOMPARE( elp3.azimuth(), 45.0 );
|
|
QVERIFY( !elp3.isEmpty() );
|
|
|
|
QgsEllipse elp4( QgsPoint( 5, 10 ), 2, 3, 45 );
|
|
QVERIFY( elp4.center() == QgsPoint( 5, 10 ) );
|
|
QCOMPARE( elp4.semiMajorAxis(), 3.0 );
|
|
QCOMPARE( elp4.semiMinorAxis(), 2.0 );
|
|
QCOMPARE( elp4.azimuth(), 135.0 );
|
|
QVERIFY( !elp4.isEmpty() );
|
|
|
|
//test toString
|
|
QCOMPARE( elp1.toString(), QString( "Empty" ) );
|
|
QCOMPARE( elp2.toString(), QString( "Ellipse (Center: Point (5 10), Semi-Major Axis: 3, Semi-Minor Axis: 2, Azimuth: 90)" ) );
|
|
QCOMPARE( elp3.toString(), QString( "Ellipse (Center: Point (5 10), Semi-Major Axis: 3, Semi-Minor Axis: 2, Azimuth: 45)" ) );
|
|
QCOMPARE( elp4.toString(), QString( "Ellipse (Center: Point (5 10), Semi-Major Axis: 3, Semi-Minor Axis: 2, Azimuth: 135)" ) );
|
|
|
|
//test equality operator
|
|
QVERIFY( QgsEllipse() == QgsEllipse( QgsPoint(), 0, 0, 90 ) );
|
|
QVERIFY( !( QgsEllipse() == QgsEllipse( QgsPoint(), 0, 0, 0.0005 ) ) );
|
|
QVERIFY( elp2 == QgsEllipse( QgsPoint( 5, 10 ), 2, 3, 0 ) );
|
|
QVERIFY( elp2 != elp3 );
|
|
QVERIFY( elp3 != elp4 );
|
|
QVERIFY( elp4 == QgsEllipse( QgsPoint( 5, 10 ), 3, 2, 90 + 45 ) );
|
|
|
|
//test setter and getter
|
|
elp1.setAzimuth( 45 );
|
|
QCOMPARE( elp1.azimuth(), 45.0 );
|
|
|
|
elp1.setSemiMajorAxis( 50 );
|
|
QCOMPARE( elp1.semiMajorAxis(), 50.0 );
|
|
|
|
// axis_b > axis_a
|
|
elp1.setSemiMinorAxis( 70 );
|
|
QCOMPARE( elp1.semiMajorAxis(), 70.0 );
|
|
QCOMPARE( elp1.semiMinorAxis(), 50.0 );
|
|
// axis_b < axis_a
|
|
elp1.setSemiMinorAxis( 3 );
|
|
QCOMPARE( elp1.semiMinorAxis(), 3.0 );
|
|
QCOMPARE( elp1.semiMajorAxis(), 70.0 );
|
|
|
|
elp1.setSemiMajorAxis( 2 );
|
|
QCOMPARE( elp1.semiMinorAxis(), 2.0 );
|
|
QCOMPARE( elp1.semiMajorAxis(), 3.0 );
|
|
|
|
elp1.setCenter( QgsPoint( 5, 10 ) );
|
|
QVERIFY( elp1.center() == QgsPoint( 5, 10 ) );
|
|
QVERIFY( elp1.rcenter() == QgsPoint( 5, 10 ) );
|
|
elp1.rcenter() = QgsPoint( 25, 310 );
|
|
QVERIFY( elp1.center() == QgsPoint( 25, 310 ) );
|
|
|
|
//test "alt" constructors
|
|
// fromExtent
|
|
QgsEllipse elp_alt = QgsEllipse( QgsPoint( 2.5, 5 ), 2.5, 5 );
|
|
QVERIFY( QgsEllipse().fromExtent( QgsPoint( 0, 0 ), QgsPoint( 5, 10 ) ) == elp_alt );
|
|
QVERIFY( QgsEllipse().fromExtent( QgsPoint( 5, 10 ), QgsPoint( 0, 0 ) ) == elp_alt );
|
|
QVERIFY( QgsEllipse().fromExtent( QgsPoint( 5, 0 ), QgsPoint( 0, 10 ) ) == elp_alt );
|
|
QVERIFY( QgsEllipse().fromExtent( QgsPoint( -5, 0 ), QgsPoint( 0, 10 ) ) != elp_alt );
|
|
// fromCenterPoint
|
|
QVERIFY( QgsEllipse().fromCenterPoint( QgsPoint( 2.5, 5 ), QgsPoint( 5, 10 ) ) == elp_alt );
|
|
QVERIFY( QgsEllipse().fromCenterPoint( QgsPoint( 2.5, 5 ), QgsPoint( -0, 0 ) ) == elp_alt );
|
|
QVERIFY( QgsEllipse().fromCenterPoint( QgsPoint( 2.5, 5 ), QgsPoint( 0, -10 ) ) != elp_alt );
|
|
// fromCenter2Points
|
|
QVERIFY( QgsEllipse().fromCenter2Points( QgsPoint( 2.5, 5 ), QgsPoint( 2.5, 0 ), QgsPoint( 7.5, 5 ) ) ==
|
|
QgsEllipse( QgsPoint( 2.5, 5 ), 5, 5, 180 ) );
|
|
QVERIFY( QgsEllipse().fromCenter2Points( QgsPoint( 2.5, 5 ), QgsPoint( 2.5, 7.5 ), QgsPoint( 7.5, 5 ) ) != elp_alt ); //same ellipse with different azimuth
|
|
QVERIFY( QgsEllipse().fromCenter2Points( QgsPoint( 2.5, 5 ), QgsPoint( 2.5, 2.5 ), QgsPoint( 7.5, 5 ) ) != elp_alt ); //same ellipse with different azimuth
|
|
QVERIFY( QgsEllipse().fromCenter2Points( QgsPoint( 2.5, 5 ), QgsPoint( 2.5, 0 ), QgsPoint( 5, 5 ) ) == elp_alt );
|
|
QVERIFY( QgsEllipse().fromCenter2Points( QgsPoint( 5, 10 ), QgsPoint( 5, 10 ).project( 3, 45 ), QgsPoint( 5, 10 ).project( 2, 90 + 45 ) ) ==
|
|
QgsEllipse( QgsPoint( 5, 10 ), 3, 2, 45 ) );
|
|
|
|
// fromFoci
|
|
// horizontal
|
|
QgsEllipse elp_hor = QgsEllipse().fromFoci( QgsPoint( -4, 0 ), QgsPoint( 4, 0 ), QgsPoint( 0, 4 ) );
|
|
QVERIFY( QgsEllipse( QgsPoint( 0, 0 ), std::sqrt( 32.0 ), std::sqrt( 16.0 ), 90.0 ) == elp_hor );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 4, 0 ), elp_hor.foci().at( 0 ), 1e-8 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( -4, 0 ), elp_hor.foci().at( 1 ), 1e-8 );
|
|
elp_hor = QgsEllipse().fromFoci( QgsPoint( 4, 0 ), QgsPoint( -4, 0 ), QgsPoint( 0, 4 ) );
|
|
QVERIFY( QgsEllipse( QgsPoint( 0, 0 ), std::sqrt( 32.0 ), std::sqrt( 16.0 ), 270.0 ) == elp_hor );
|
|
QGSCOMPARENEARPOINT( QgsPoint( -4, 0 ), elp_hor.foci().at( 0 ), 1e-8 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 4, 0 ), elp_hor.foci().at( 1 ), 1e-8 );
|
|
|
|
// vertical
|
|
QgsEllipse elp_ver = QgsEllipse().fromFoci( QgsPoint( 45, -15 ), QgsPoint( 45, 10 ), QgsPoint( 55, 0 ) );
|
|
QVERIFY( QgsEllipse( QgsPoint( 45, -2.5 ), 16.084946, 10.123017725, 0.0 ) == elp_ver );
|
|
elp_ver = QgsEllipse().fromFoci( QgsPoint( 45, 10 ), QgsPoint( 45, -15 ), QgsPoint( 55, 0 ) );
|
|
QVERIFY( QgsEllipse( QgsPoint( 45, -2.5 ), 16.084946, 10.123017725, 180.0 ) == elp_ver );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 45, -15 ), elp_ver.foci().at( 0 ), 1e-8 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 45, 10 ), elp_ver.foci().at( 1 ), 1e-8 );
|
|
// oriented
|
|
// first quadrant
|
|
QgsEllipse elp_ori = QgsEllipse().fromFoci( QgsPoint( 10, 10 ), QgsPoint( 25, 20 ), QgsPoint( 15, 20 ) );
|
|
QVERIFY( QgsEllipse( QgsPoint( 17.5, 15.0 ), 10.5901699437, 5.55892970251, 90.0 - 33.690067526 ) == elp_ori );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 25, 20 ), elp_ori.foci().at( 0 ), 1e-8 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 10, 10 ), elp_ori.foci().at( 1 ), 1e-8 );
|
|
// second quadrant
|
|
elp_ori = QgsEllipse().fromFoci( QgsPoint( 10, 10 ), QgsPoint( 5, 20 ), QgsPoint( 15, 20 ) );
|
|
QVERIFY( QgsEllipse( QgsPoint( 7.5, 15.0 ), 10.5901699437, 8.99453719974, 360 - 26.56505117 ) == elp_ori );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 5, 20 ), elp_ori.foci().at( 0 ), 1e-8 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 10, 10 ), elp_ori.foci().at( 1 ), 1e-8 );
|
|
// third quadrant
|
|
elp_ori = QgsEllipse().fromFoci( QgsPoint( 10, 10 ), QgsPoint( 5, -5 ), QgsPoint( 15, 20 ) );
|
|
QVERIFY( QgsEllipse( QgsPoint( 7.5, 2.5 ), 19.0530819616, 17.3355107289893, 198.434948822922 ) == elp_ori );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 10, 10 ), elp_ori.foci().at( 1 ), 1e-8 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 5, -5 ), elp_ori.foci().at( 0 ), 1e-8 );
|
|
// fourth quadrant
|
|
elp_ori = QgsEllipse().fromFoci( QgsPoint( 10, 10 ), QgsPoint( 25, -5 ), QgsPoint( 15, 20 ) );
|
|
QVERIFY( QgsEllipse( QgsPoint( 17.5, 2.5 ), 19.0530819616, 15.82782146, 135 ) == elp_ori );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 25, -5 ), elp_ori.foci().at( 0 ), 1e-8 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 10, 10 ), elp_ori.foci().at( 1 ), 1e-8 );
|
|
|
|
// test quadrant
|
|
QgsEllipse elpq( QgsPoint( 5, 10 ), 3, 2, 45 );
|
|
QVector<QgsPoint> q = elpq.quadrant();
|
|
QGSCOMPARENEARPOINT( q.at( 0 ), QgsPoint( 7.1213, 12.1213 ), 0.001 );
|
|
QGSCOMPARENEARPOINT( q.at( 3 ), QgsPoint( 3.5858, 11.4142 ), 0.001 );
|
|
QGSCOMPARENEARPOINT( q.at( 2 ), QgsPoint( 2.8787, 7.8787 ), 0.001 );
|
|
QGSCOMPARENEARPOINT( q.at( 1 ), QgsPoint( 6.4142, 8.5858 ), 0.001 );
|
|
|
|
elpq = QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 90 );
|
|
q.clear();
|
|
q = elpq.quadrant();
|
|
QCOMPARE( q.at( 3 ), QgsPoint( 0, 2 ) );
|
|
QCOMPARE( q.at( 0 ), QgsPoint( 5, 0 ) );
|
|
QCOMPARE( q.at( 1 ), QgsPoint( 0, -2 ) );
|
|
QCOMPARE( q.at( 2 ), QgsPoint( -5, 0 ) );
|
|
|
|
elpq = QgsEllipse( QgsPoint( QgsWkbTypes::PointZM, 0, 0, 123, 321 ), 5, 2, 0 );
|
|
q.clear();
|
|
q = elpq.quadrant();
|
|
QCOMPARE( q.at( 0 ), QgsPoint( QgsWkbTypes::PointZM, 0, 5, 123, 321 ) );
|
|
QCOMPARE( q.at( 3 ), QgsPoint( QgsWkbTypes::PointZM, -2, 0, 123, 321 ) );
|
|
QCOMPARE( q.at( 2 ), QgsPoint( QgsWkbTypes::PointZM, 0, -5, 123, 321 ) );
|
|
QCOMPARE( q.at( 1 ), QgsPoint( QgsWkbTypes::PointZM, 2, 0, 123, 321 ) );
|
|
|
|
elpq = QgsEllipse( QgsPoint( 0, 0 ), 2.5, 2, 315 );
|
|
q.clear();
|
|
q = elpq.quadrant();
|
|
QGSCOMPARENEARPOINT( q.at( 1 ), QgsPoint( 1.4142, 1.4142 ), 0.001 );
|
|
QGSCOMPARENEARPOINT( q.at( 2 ), QgsPoint( 1.7678, -1.7678 ), 0.001 );
|
|
QGSCOMPARENEARPOINT( q.at( 3 ), QgsPoint( -1.4142, -1.4142 ), 0.001 );
|
|
QGSCOMPARENEARPOINT( q.at( 0 ), QgsPoint( -1.7678, 1.7678 ), 0.001 );
|
|
|
|
elpq = QgsEllipse( QgsPoint( 0, 0 ), 5, 2.5, 45 );
|
|
q.clear();
|
|
q = elpq.quadrant();
|
|
QGSCOMPARENEARPOINT( q.at( 3 ), QgsPoint( -1.7678, 1.7678 ), 0.001 );
|
|
QGSCOMPARENEARPOINT( q.at( 0 ), QgsPoint( 3.5355, 3.5355 ), 0.001 );
|
|
QGSCOMPARENEARPOINT( q.at( 1 ), QgsPoint( 1.7678, -1.7678 ), 0.001 );
|
|
QGSCOMPARENEARPOINT( q.at( 2 ), QgsPoint( -3.5355, -3.5355 ), 0.001 );
|
|
|
|
//test conversion
|
|
// points
|
|
QgsPointSequence pts;
|
|
pts = QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 0 ).points( 4 );
|
|
q = QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 0 ).quadrant();
|
|
QCOMPARE( pts.length(), 4 );
|
|
QGSCOMPARENEARPOINT( q.at( 0 ), pts.at( 0 ), 2 );
|
|
QGSCOMPARENEARPOINT( q.at( 1 ), pts.at( 1 ), 2 );
|
|
QGSCOMPARENEARPOINT( q.at( 2 ), pts.at( 2 ), 2 );
|
|
QGSCOMPARENEARPOINT( q.at( 3 ), pts.at( 3 ), 2 );
|
|
|
|
QVERIFY( QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 0 ).points( 2 ).isEmpty() ); // segments too low
|
|
|
|
// linestring
|
|
std::unique_ptr< QgsLineString > l( new QgsLineString() );
|
|
|
|
l.reset( QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 0 ).toLineString( 2 ) );
|
|
QVERIFY( l->isEmpty() ); // segments too low
|
|
|
|
l.reset( QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 0 ).toLineString( 4 ) );
|
|
QCOMPARE( l->numPoints(), 4 );
|
|
QgsPointSequence pts_l;
|
|
l->points( pts_l );
|
|
QCOMPARE( pts, pts_l );
|
|
|
|
// polygon
|
|
std::unique_ptr< QgsPolygonV2 > p1( new QgsPolygonV2() );
|
|
|
|
p1.reset( QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 0 ).toPolygon( 2 ) );
|
|
QVERIFY( p1->isEmpty() ); // segments too low
|
|
|
|
p1.reset( QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 0 ).toPolygon( 4 ) );
|
|
q = QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 0 ).quadrant();
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 0 ) ), q.at( 0 ) );
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 1 ) ), q.at( 1 ) );
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 2 ) ), q.at( 2 ) );
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 3 ) ), q.at( 3 ) );
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 4 ) ), q.at( 0 ) );
|
|
QCOMPARE( 0, p1->numInteriorRings() );
|
|
QCOMPARE( 5, p1->exteriorRing()->numPoints() );
|
|
|
|
p1.reset( QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 90 ).toPolygon( 4 ) );
|
|
q = QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 90 ).quadrant();
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 0 ) ), q.at( 0 ) );
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 1 ) ), q.at( 1 ) );
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 2 ) ), q.at( 2 ) );
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 3 ) ), q.at( 3 ) );
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 4 ) ), q.at( 0 ) );
|
|
QCOMPARE( 0, p1->numInteriorRings() );
|
|
QCOMPARE( 5, p1->exteriorRing()->numPoints() );
|
|
|
|
p1.reset( elpq.toPolygon( 4 ) );
|
|
q = elpq.quadrant();
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 0 ) ), q.at( 0 ) );
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 1 ) ), q.at( 1 ) );
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 2 ) ), q.at( 2 ) );
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 3 ) ), q.at( 3 ) );
|
|
QCOMPARE( p1->vertexAt( QgsVertexId( 0, 0, 4 ) ), q.at( 0 ) );
|
|
QCOMPARE( 0, p1->numInteriorRings() );
|
|
QCOMPARE( 5, p1->exteriorRing()->numPoints() );
|
|
|
|
// oriented bounding box
|
|
std::unique_ptr< QgsPolygonV2 > ombb( QgsEllipse().orientedBoundingBox() );
|
|
QVERIFY( ombb->isEmpty() );
|
|
|
|
elpq = QgsEllipse( QgsPoint( 0, 0 ), 5, 2 );
|
|
ombb.reset( new QgsPolygonV2() );
|
|
QgsLineString *ext = new QgsLineString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 5, 2 ) << QgsPoint( 5, -2 ) << QgsPoint( -5, -2 ) << QgsPoint( -5, 2 ) );
|
|
ombb->setExteriorRing( ext );
|
|
std::unique_ptr< QgsPolygonV2 >ombb2( elpq.orientedBoundingBox() );
|
|
QCOMPARE( ombb->asWkt( 2 ), ombb2->asWkt( 2 ) );
|
|
|
|
elpq = QgsEllipse( QgsPoint( 0, 0 ), 5, 2.5, 45 );
|
|
ombb.reset( elpq.orientedBoundingBox() );
|
|
QGSCOMPARENEARPOINT( ombb->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 1.7678, 5.3033 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( ombb->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( 5.3033, 1.7678 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( ombb->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( -1.7678, -5.3033 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( ombb->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 3 ) ), QgsPoint( -5.3033, -1.7678 ), 0.0001 );
|
|
|
|
elpq = QgsEllipse( QgsPoint( 0, 0 ), 5, 2.5, 315 );
|
|
ombb.reset( elpq.orientedBoundingBox() );
|
|
QGSCOMPARENEARPOINT( ombb->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( -5.3033, 1.7678 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( ombb->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( -1.7678, 5.3033 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( ombb->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( 5.3033, -1.7678 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( ombb->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 3 ) ), QgsPoint( 1.7678, -5.3033 ), 0.0001 );
|
|
|
|
// bounding box
|
|
QCOMPARE( QgsEllipse().boundingBox(), QgsRectangle() );
|
|
ombb.reset( QgsEllipse( QgsPoint( 0, 0 ), 5, 2 ).orientedBoundingBox() );
|
|
QCOMPARE( QgsEllipse( QgsPoint( 0, 0 ), 5, 2 ).boundingBox(), ombb->boundingBox() );
|
|
QCOMPARE( QgsEllipse( QgsPoint( 0, 0 ), 5, 5 ).boundingBox(), QgsRectangle( QgsPointXY( -5, -5 ), QgsPointXY( 5, 5 ) ) );
|
|
QCOMPARE( QgsEllipse( QgsPoint( 0, 0 ), 5, 5, 60 ).boundingBox(), QgsRectangle( QgsPointXY( -5, -5 ), QgsPointXY( 5, 5 ) ) );
|
|
QCOMPARE( QgsEllipse( QgsPoint( 0, 0 ), 13, 9, 45 ).boundingBox().toString( 4 ).toStdString(), QgsRectangle( QgsPointXY( -11.1803, -11.1803 ), QgsPointXY( 11.1803, 11.1803 ) ).toString( 4 ).toStdString() );
|
|
QCOMPARE( QgsEllipse( QgsPoint( 0, 0 ), 13, 9, 60 ).boundingBox().toString( 4 ).toStdString(), QgsRectangle( QgsPointXY( -12.12436, -10.14889 ), QgsPointXY( 12.12436, 10.14889 ) ).toString( 4 ).toStdString() );
|
|
QCOMPARE( QgsEllipse( QgsPoint( 0, 0 ), 13, 9, 60 + 90 ).boundingBox().toString( 4 ).toStdString(), QgsRectangle( QgsPointXY( -10.14889, -12.12436 ), QgsPointXY( 10.14889, 12.12436 ) ).toString( 4 ).toStdString() );
|
|
QCOMPARE( QgsEllipse( QgsPoint( 0, 0 ), 13, 9, 300 ).boundingBox().toString( 4 ).toStdString(), QgsRectangle( QgsPointXY( -12.12436, -10.14889 ), QgsPointXY( 12.12436, 10.14889 ) ).toString( 4 ).toStdString() );
|
|
QCOMPARE( QgsEllipse( QgsPoint( 0, 0 ), 13, 9, 300 - 90 ).boundingBox().toString( 4 ).toStdString(), QgsRectangle( QgsPointXY( -10.14889, -12.12436 ), QgsPointXY( 10.14889, 12.12436 ) ).toString( 4 ).toStdString() );
|
|
|
|
// focus
|
|
QCOMPARE( QgsEllipse().fromFoci( QgsPoint( -4, 0 ), QgsPoint( 4, 0 ), QgsPoint( 0, 4 ) ).focusDistance(), 4.0 );
|
|
QGSCOMPARENEAR( QgsEllipse().fromFoci( QgsPoint( 10, 10 ), QgsPoint( 25, 20 ), QgsPoint( 15, 20 ) ).focusDistance(), 9.01388, 0.0001 );
|
|
|
|
// eccentricity
|
|
QCOMPARE( QgsEllipse().fromFoci( QgsPoint( -4, 0 ), QgsPoint( 4, 0 ), QgsPoint( 0, 4 ) ).eccentricity(), 0.7071067811865475 );
|
|
QCOMPARE( QgsEllipse( QgsPoint( 0, 0 ), 3, 3 ).eccentricity(), 0.0 );
|
|
QVERIFY( std::isnan( QgsEllipse().eccentricity() ) );
|
|
|
|
// area
|
|
QGSCOMPARENEAR( 31.4159, QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 0 ).area(), 0.0001 );
|
|
// perimeter
|
|
p1.reset( QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 45 ).toPolygon( 10000 ) );
|
|
QGSCOMPARENEAR( QgsEllipse( QgsPoint( 0, 0 ), 5, 2, 45 ).perimeter(), p1->perimeter(), 0.001 );
|
|
|
|
}
|
|
|
|
void TestQgsGeometry::circle()
|
|
{
|
|
//test constructors
|
|
QgsCircle circ1;
|
|
QVERIFY( circ1.center() == QgsPoint() );
|
|
QCOMPARE( circ1.radius(), 0.0 );
|
|
QCOMPARE( circ1.azimuth(), 0.0 );
|
|
QVERIFY( circ1.isEmpty() );
|
|
|
|
QgsCircle circ2( QgsPoint( 5, 10 ), 3 );
|
|
QVERIFY( circ2.center() == QgsPoint( 5, 10 ) );
|
|
QCOMPARE( circ2.radius(), 3.0 );
|
|
QCOMPARE( circ2.azimuth(), 0.0 );
|
|
QVERIFY( !circ2.isEmpty() );
|
|
|
|
QgsCircle circ3( QgsPoint( 5, 10 ), 3, 45 );
|
|
QVERIFY( circ3.center() == QgsPoint( 5, 10 ) );
|
|
QCOMPARE( circ3.radius(), 3.0 );
|
|
QCOMPARE( circ3.azimuth(), 45.0 );
|
|
QVERIFY( !circ3.isEmpty() );
|
|
|
|
//test toString
|
|
QCOMPARE( circ1.toString(), QString( "Empty" ) );
|
|
QCOMPARE( circ2.toString(), QString( "Circle (Center: Point (5 10), Radius: 3, Azimuth: 0)" ) );
|
|
QCOMPARE( circ3.toString(), QString( "Circle (Center: Point (5 10), Radius: 3, Azimuth: 45)" ) );
|
|
|
|
//test equality operator
|
|
QVERIFY( QgsCircle() == QgsCircle( QgsPoint(), 0, 0 ) );
|
|
QVERIFY( !( QgsCircle() == QgsCircle( QgsPoint(), 0, 0.0005 ) ) );
|
|
QVERIFY( circ2 == QgsCircle( QgsPoint( 5, 10 ), 3, 0 ) );
|
|
QVERIFY( circ2 != circ3 );
|
|
|
|
//test setter and getter
|
|
circ1.setAzimuth( 45 );
|
|
QCOMPARE( circ1.azimuth(), 45.0 );
|
|
|
|
circ1.setRadius( 50 );
|
|
QCOMPARE( circ1.radius(), 50.0 );
|
|
QCOMPARE( circ1.semiMajorAxis(), 50.0 );
|
|
QCOMPARE( circ1.semiMinorAxis(), 50.0 );
|
|
|
|
circ1.setSemiMajorAxis( 250 );
|
|
QCOMPARE( circ1.radius(), 250.0 );
|
|
QCOMPARE( circ1.semiMajorAxis(), 250.0 );
|
|
QCOMPARE( circ1.semiMinorAxis(), 250.0 );
|
|
|
|
circ1.setSemiMinorAxis( 8250 );
|
|
QCOMPARE( circ1.radius(), 8250.0 );
|
|
QCOMPARE( circ1.semiMajorAxis(), 8250.0 );
|
|
QCOMPARE( circ1.semiMinorAxis(), 8250.0 );
|
|
|
|
circ1.setCenter( QgsPoint( 5, 10 ) );
|
|
QVERIFY( circ1.center() == QgsPoint( 5, 10 ) );
|
|
QVERIFY( circ1.rcenter() == QgsPoint( 5, 10 ) );
|
|
circ1.rcenter() = QgsPoint( 25, 310 );
|
|
QVERIFY( circ1.center() == QgsPoint( 25, 310 ) );
|
|
|
|
//test "alt" constructors
|
|
// by2Points
|
|
QVERIFY( QgsCircle().from2Points( QgsPoint( -5, 0 ), QgsPoint( 5, 0 ) ) == QgsCircle( QgsPoint( 0, 0 ), 5, 90 ) );
|
|
QVERIFY( QgsCircle().from2Points( QgsPoint( 0, -5 ), QgsPoint( 0, 5 ) ) == QgsCircle( QgsPoint( 0, 0 ), 5, 0 ) );
|
|
// byExtent
|
|
QVERIFY( QgsCircle().fromExtent( QgsPoint( -5, -5 ), QgsPoint( 5, 5 ) ) == QgsCircle( QgsPoint( 0, 0 ), 5, 0 ) );
|
|
QVERIFY( QgsCircle().fromExtent( QgsPoint( -7.5, -2.5 ), QgsPoint( 2.5, 200.5 ) ) == QgsCircle() );
|
|
// by3Points
|
|
QVERIFY( QgsCircle().from3Points( QgsPoint( -5, 0 ), QgsPoint( 5, 0 ), QgsPoint( 0, 5 ) ) == QgsCircle( QgsPoint( 0, 0 ), 5 ) );
|
|
QVERIFY( QgsCircle().from3Points( QgsPoint( 5, 0 ), QgsPoint( 6, 0 ), QgsPoint( 7, 0 ) ) == QgsCircle() );
|
|
// byCenterDiameter
|
|
QVERIFY( QgsCircle().fromCenterDiameter( QgsPoint( 0, 0 ), 10 ) == QgsCircle( QgsPoint( 0, 0 ), 5, 0 ) );
|
|
QVERIFY( QgsCircle().fromCenterDiameter( QgsPoint( 2, 100 ), -10 ) == QgsCircle( QgsPoint( 2, 100 ), 5, 0 ) );
|
|
QVERIFY( QgsCircle().fromCenterDiameter( QgsPoint( 2, 100 ), -10, 45 ) == QgsCircle( QgsPoint( 2, 100 ), 5, 45 ) );
|
|
// byCenterPoint
|
|
QVERIFY( QgsCircle().fromCenterPoint( QgsPoint( 0, 0 ), QgsPoint( 5, 0 ) ) == QgsCircle( QgsPoint( 0, 0 ), 5, 90 ) );
|
|
QVERIFY( QgsCircle().fromCenterPoint( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ) ) == QgsCircle( QgsPoint( 0, 0 ), 5, 0 ) );
|
|
QVERIFY( QgsCircle().fromCenterPoint( QgsPoint( 0, 0 ), QgsPoint( 5 * std::cos( 45 * M_PI / 180.0 ), 5 * std::sin( 45 * M_PI / 180.0 ) ) ) == QgsCircle( QgsPoint( 0, 0 ), 5, 45 ) );
|
|
// by3Tangents
|
|
// Tangents from triangle tri1( 0,0 ; 0,5 ), tri2( 0,0 ; 5,0 ), tri3( 5,0 ; 0,5 )
|
|
QgsCircle circ_tgt = QgsCircle().from3Tangents( QgsPoint( 0, 0 ), QgsPoint( 0, 1 ), QgsPoint( 2, 0 ), QgsPoint( 3, 0 ), QgsPoint( 5, 0 ), QgsPoint( 0, 5 ) );
|
|
QGSCOMPARENEARPOINT( circ_tgt.center(), QgsPoint( 1.4645, 1.4645 ), 0.0001 );
|
|
QGSCOMPARENEAR( circ_tgt.radius(), 1.4645, 0.0001 );
|
|
// minimalCircleFrom3points
|
|
QgsCircle minCircle3Points = QgsCircle().minimalCircleFrom3Points( QgsPoint( 0, 5 ), QgsPoint( 0, -5 ), QgsPoint( 1, 2 ) );
|
|
QGSCOMPARENEARPOINT( minCircle3Points.center(), QgsPoint( 0, 0 ), 0.0001 );
|
|
QGSCOMPARENEAR( minCircle3Points.radius(), 5.0, 0.0001 );
|
|
minCircle3Points = QgsCircle().minimalCircleFrom3Points( QgsPoint( 0, 5 ), QgsPoint( 5, 0 ), QgsPoint( -5, 0 ) );
|
|
QGSCOMPARENEARPOINT( minCircle3Points.center(), QgsPoint( 0, 0 ), 0.0001 );
|
|
QGSCOMPARENEAR( minCircle3Points.radius(), 5.0, 0.0001 );
|
|
|
|
|
|
|
|
// test quadrant
|
|
QVector<QgsPoint> quad = QgsCircle( QgsPoint( 0, 0 ), 5 ).northQuadrant();
|
|
QVERIFY( quad.at( 0 ) == QgsPoint( 0, 5 ) );
|
|
QVERIFY( quad.at( 1 ) == QgsPoint( 5, 0 ) );
|
|
QVERIFY( quad.at( 2 ) == QgsPoint( 0, -5 ) );
|
|
QVERIFY( quad.at( 3 ) == QgsPoint( -5, 0 ) );
|
|
|
|
quad = QgsCircle( QgsPoint( 0, 0 ), 5, 123 ).northQuadrant();
|
|
QVERIFY( quad.at( 0 ) == QgsPoint( 0, 5 ) );
|
|
QVERIFY( quad.at( 1 ) == QgsPoint( 5, 0 ) );
|
|
QVERIFY( quad.at( 2 ) == QgsPoint( 0, -5 ) );
|
|
QVERIFY( quad.at( 3 ) == QgsPoint( -5, 0 ) );
|
|
|
|
quad = QgsCircle( QgsPoint( 0, 0 ), 5, 456 ).northQuadrant();
|
|
QVERIFY( quad.at( 0 ) == QgsPoint( 0, 5 ) );
|
|
QVERIFY( quad.at( 1 ) == QgsPoint( 5, 0 ) );
|
|
QVERIFY( quad.at( 2 ) == QgsPoint( 0, -5 ) );
|
|
QVERIFY( quad.at( 3 ) == QgsPoint( -5, 0 ) );
|
|
|
|
quad = QgsCircle( QgsPoint( 0, 0 ), 5, -789l ).northQuadrant();
|
|
QVERIFY( quad.at( 0 ) == QgsPoint( 0, 5 ) );
|
|
QVERIFY( quad.at( 1 ) == QgsPoint( 5, 0 ) );
|
|
QVERIFY( quad.at( 2 ) == QgsPoint( 0, -5 ) );
|
|
QVERIFY( quad.at( 3 ) == QgsPoint( -5, 0 ) );
|
|
|
|
|
|
//test conversion
|
|
QgsPointSequence ptsPol;
|
|
std::unique_ptr< QgsPolygonV2 > pol( new QgsPolygonV2() );
|
|
// polygon
|
|
pol.reset( QgsCircle( QgsPoint( 0, 0 ), 5 ).toPolygon( 4 ) );
|
|
QCOMPARE( pol->numInteriorRings(), 0 );
|
|
QCOMPARE( pol->exteriorRing()->numPoints(), 5 );
|
|
|
|
pol->exteriorRing()->points( ptsPol );
|
|
QCOMPARE( ptsPol.length(), 5 );
|
|
QVERIFY( ptsPol.at( 0 ) == QgsPoint( 0, 5 ) );
|
|
QVERIFY( ptsPol.at( 1 ) == QgsPoint( 5, 0 ) );
|
|
QVERIFY( ptsPol.at( 2 ) == QgsPoint( 0, -5 ) );
|
|
QVERIFY( ptsPol.at( 3 ) == QgsPoint( -5, 0 ) );
|
|
QVERIFY( ptsPol.at( 4 ) == QgsPoint( 0, 5 ) );
|
|
|
|
// oriented
|
|
//45
|
|
double val = 5 * std::sin( M_PI / 4 );
|
|
pol.reset( QgsCircle( QgsPoint( 0, 0 ), 5, 45 ).toPolygon( 4 ) );
|
|
QCOMPARE( pol->numInteriorRings(), 0 );
|
|
QCOMPARE( pol->exteriorRing()->numPoints(), 5 );
|
|
pol->exteriorRing()->points( ptsPol );
|
|
QCOMPARE( ptsPol.length(), 5 );
|
|
QVERIFY( ptsPol.at( 0 ) == QgsPoint( val, val ) );
|
|
QVERIFY( ptsPol.at( 1 ) == QgsPoint( val, -val ) );
|
|
QVERIFY( ptsPol.at( 2 ) == QgsPoint( -val, -val ) );
|
|
QVERIFY( ptsPol.at( 3 ) == QgsPoint( -val, val ) );
|
|
QVERIFY( ptsPol.at( 4 ) == QgsPoint( val, val ) );
|
|
//135
|
|
pol.reset( QgsCircle( QgsPoint( 0, 0 ), 5, 135 ).toPolygon( 4 ) );
|
|
QCOMPARE( pol->numInteriorRings(), 0 );
|
|
QCOMPARE( pol->exteriorRing()->numPoints(), 5 );
|
|
pol->exteriorRing()->points( ptsPol );
|
|
QCOMPARE( ptsPol.length(), 5 );
|
|
QVERIFY( ptsPol.at( 0 ) == QgsPoint( val, -val ) );
|
|
QVERIFY( ptsPol.at( 1 ) == QgsPoint( -val, -val ) );
|
|
QVERIFY( ptsPol.at( 2 ) == QgsPoint( -val, val ) );
|
|
QVERIFY( ptsPol.at( 3 ) == QgsPoint( val, val ) );
|
|
QVERIFY( ptsPol.at( 4 ) == QgsPoint( val, -val ) );
|
|
//225
|
|
pol.reset( QgsCircle( QgsPoint( 0, 0 ), 5, 225 ).toPolygon( 4 ) );
|
|
QCOMPARE( pol->numInteriorRings(), 0 );
|
|
QCOMPARE( pol->exteriorRing()->numPoints(), 5 );
|
|
pol->exteriorRing()->points( ptsPol );
|
|
QCOMPARE( ptsPol.length(), 5 );
|
|
QVERIFY( ptsPol.at( 0 ) == QgsPoint( -val, -val ) );
|
|
QVERIFY( ptsPol.at( 1 ) == QgsPoint( -val, val ) );
|
|
QVERIFY( ptsPol.at( 2 ) == QgsPoint( val, val ) );
|
|
QVERIFY( ptsPol.at( 3 ) == QgsPoint( val, -val ) );
|
|
QVERIFY( ptsPol.at( 4 ) == QgsPoint( -val, -val ) );
|
|
//315
|
|
pol.reset( QgsCircle( QgsPoint( 0, 0 ), 5, 315 ).toPolygon( 4 ) );
|
|
QCOMPARE( pol->numInteriorRings(), 0 );
|
|
QCOMPARE( pol->exteriorRing()->numPoints(), 5 );
|
|
pol->exteriorRing()->points( ptsPol );
|
|
QCOMPARE( ptsPol.length(), 5 );
|
|
QVERIFY( ptsPol.at( 0 ) == QgsPoint( -val, val ) );
|
|
QVERIFY( ptsPol.at( 1 ) == QgsPoint( val, val ) );
|
|
QVERIFY( ptsPol.at( 2 ) == QgsPoint( val, -val ) );
|
|
QVERIFY( ptsPol.at( 3 ) == QgsPoint( -val, -val ) );
|
|
QVERIFY( ptsPol.at( 4 ) == QgsPoint( -val, val ) );
|
|
|
|
// circular arc
|
|
std::unique_ptr< QgsCircularString > cs( QgsCircle( QgsPoint( 0, 0 ), 5 ).toCircularString() );
|
|
QCOMPARE( cs->asWkt( 2 ), QString( "CircularString (0 5, 5 0, 0 -5, -5 0, 0 5)" ) );
|
|
cs.reset( QgsCircle( QgsPoint( 0, 0 ), 5 ).toCircularString( true ) );
|
|
QCOMPARE( cs->asWkt( 2 ), QString( "CircularString (0 5, 5 0, 0 -5, -5 -0, 0 5)" ) );
|
|
cs.reset( QgsCircle( QgsPoint( 0, 0 ), 5, 315 ).toCircularString() );
|
|
QCOMPARE( cs->asWkt( 2 ), QString( "CircularString (0 5, 5 0, 0 -5, -5 0, 0 5)" ) );
|
|
cs.reset( QgsCircle( QgsPoint( 0, 0 ), 5, 315 ).toCircularString( true ) );
|
|
QCOMPARE( cs->asWkt( 2 ), QString( "CircularString (-3.54 3.54, 3.54 3.54, 3.54 -3.54, -3.54 -3.54, -3.54 3.54)" ) );
|
|
|
|
// bounding box
|
|
QVERIFY( QgsRectangle( QgsPointXY( -2.5, -2.5 ), QgsPointXY( 2.5, 2.5 ) ) == QgsCircle( QgsPoint( 0, 0 ), 2.5, 0 ).boundingBox() );
|
|
QVERIFY( QgsRectangle( QgsPointXY( -2.5, -2.5 ), QgsPointXY( 2.5, 2.5 ) ) == QgsCircle( QgsPoint( 0, 0 ), 2.5, 45 ).boundingBox() );
|
|
|
|
// area
|
|
QGSCOMPARENEAR( 314.1593, QgsCircle( QgsPoint( 0, 0 ), 10 ).area(), 0.0001 );
|
|
// perimeter
|
|
QGSCOMPARENEAR( 31.4159, QgsCircle( QgsPoint( 0, 0 ), 5 ).perimeter(), 0.0001 );
|
|
|
|
// contains
|
|
QgsPoint pc;
|
|
pc = QgsPoint( 1, 1 );
|
|
QVERIFY( QgsCircle( QgsPoint( 0, 0 ), 5 ).contains( pc ) );
|
|
pc = QgsPoint( 0, 5 );
|
|
QVERIFY( QgsCircle( QgsPoint( 0, 0 ), 5 ).contains( pc ) );
|
|
pc = QgsPoint( 6, 1 );
|
|
QVERIFY( !QgsCircle( QgsPoint( 0, 0 ), 5 ).contains( pc ) );
|
|
}
|
|
|
|
void TestQgsGeometry::regularPolygon()
|
|
{
|
|
// constructors
|
|
QgsRegularPolygon rp1 = QgsRegularPolygon();
|
|
QCOMPARE( rp1.center(), QgsPoint() );
|
|
QCOMPARE( rp1.firstVertex(), QgsPoint() );
|
|
QCOMPARE( rp1.numberSides(), static_cast< unsigned int >( 0 ) );
|
|
QCOMPARE( rp1.radius(), 0.0 );
|
|
QVERIFY( rp1.isEmpty() );
|
|
|
|
QgsRegularPolygon rp2;
|
|
QgsRegularPolygon( QgsPoint(), 5, 0, 2, QgsRegularPolygon::InscribedCircle );
|
|
QVERIFY( rp2.isEmpty() );
|
|
QgsRegularPolygon( QgsPoint(), 5, 0, 5, static_cast< QgsRegularPolygon::ConstructionOption >( 4 ) );
|
|
QVERIFY( rp2.isEmpty() );
|
|
|
|
rp2 = QgsRegularPolygon( QgsPoint(), 5, 0, 5, QgsRegularPolygon::InscribedCircle );
|
|
QVERIFY( !rp2.isEmpty() );
|
|
QCOMPARE( rp2.center(), QgsPoint() );
|
|
QCOMPARE( rp2.firstVertex(), QgsPoint( 0, 5 ) );
|
|
QCOMPARE( rp2.numberSides(), static_cast< unsigned int>( 5 ) );
|
|
QCOMPARE( rp2.radius(), 5.0 );
|
|
QGSCOMPARENEAR( rp2.apothem(), 4.0451, 10E-4 );
|
|
QVERIFY( rp2 == QgsRegularPolygon( QgsPoint(), -5, 0, 5, QgsRegularPolygon::InscribedCircle ) );
|
|
|
|
QgsRegularPolygon rp3 = QgsRegularPolygon( QgsPoint(), rp2.apothem(), 36.0, 5, QgsRegularPolygon::CircumscribedCircle );
|
|
QVERIFY( rp2 == rp3 );
|
|
QVERIFY( rp2 == QgsRegularPolygon( QgsPoint(), -rp2.apothem(), 36.0, 5, QgsRegularPolygon::CircumscribedCircle ) );
|
|
QVERIFY( rp1 != rp3 );
|
|
QVERIFY( rp1 != QgsRegularPolygon( QgsPoint( 5, 5 ), rp2.apothem(), 36.0, 5, QgsRegularPolygon::CircumscribedCircle ) );
|
|
QVERIFY( rp1 != QgsRegularPolygon( QgsPoint( 0, 0 ), 5, 36.0, 5, QgsRegularPolygon::CircumscribedCircle ) );
|
|
QVERIFY( rp1 != QgsRegularPolygon( QgsPoint( 0, 0 ), 5, 36.0, 5, QgsRegularPolygon::InscribedCircle ) );
|
|
|
|
QgsRegularPolygon rp4 = QgsRegularPolygon( QgsPoint(), QgsPoint( 0, 5 ), 2, QgsRegularPolygon::InscribedCircle );
|
|
QVERIFY( rp4.isEmpty() );
|
|
rp4 = QgsRegularPolygon( QgsPoint(), QgsPoint( 0, 5 ), 5, static_cast< QgsRegularPolygon::ConstructionOption >( 4 ) );
|
|
QVERIFY( rp4.isEmpty() );
|
|
rp4 = QgsRegularPolygon( QgsPoint(), QgsPoint( 0, 5 ), 5, QgsRegularPolygon::InscribedCircle );
|
|
QVERIFY( rp4 == rp2 );
|
|
|
|
QgsRegularPolygon rp5 = QgsRegularPolygon( QgsPoint(), QgsPoint( 0, 0 ).project( rp2.apothem(), 36.0 ), 2, QgsRegularPolygon::CircumscribedCircle );
|
|
QVERIFY( rp5.isEmpty() );
|
|
rp5 = QgsRegularPolygon( QgsPoint(), QgsPoint( 0, 0 ).project( rp2.apothem(), 36.0 ), 5, static_cast< QgsRegularPolygon::ConstructionOption >( 4 ) );
|
|
QVERIFY( rp5.isEmpty() );
|
|
rp5 = QgsRegularPolygon( QgsPoint(), QgsPoint( 0, 0 ).project( rp2.apothem(), 36.0 ), 5, QgsRegularPolygon::CircumscribedCircle );
|
|
QVERIFY( rp5 == rp2 );
|
|
|
|
QgsRegularPolygon rp6 = QgsRegularPolygon( QgsPoint( 0, 5 ), QgsPoint( 0, 0 ).project( 5.0, 72 ), 5 );
|
|
QVERIFY( rp6 == rp2 );
|
|
|
|
|
|
// setters and getters
|
|
QgsRegularPolygon rp7 = QgsRegularPolygon();
|
|
|
|
rp7.setCenter( QgsPoint( 5, 5 ) );
|
|
QVERIFY( rp7.isEmpty() );
|
|
QCOMPARE( rp7.center(), QgsPoint( 5, 5 ) );
|
|
|
|
rp7.setNumberSides( 2 );
|
|
QVERIFY( rp7.isEmpty() );
|
|
QCOMPARE( rp7.numberSides(), static_cast< unsigned int >( 0 ) );
|
|
rp7.setNumberSides( 5 );
|
|
QVERIFY( rp7.isEmpty() );
|
|
QCOMPARE( rp7.numberSides(), static_cast< unsigned int >( 5 ) );
|
|
rp7.setNumberSides( 2 );
|
|
QVERIFY( rp7.isEmpty() );
|
|
QCOMPARE( rp7.numberSides(), static_cast< unsigned int >( 5 ) );
|
|
rp7.setNumberSides( 3 );
|
|
QVERIFY( rp7.isEmpty() );
|
|
QCOMPARE( rp7.numberSides(), static_cast< unsigned int >( 3 ) );
|
|
|
|
rp7.setRadius( -6 );
|
|
QVERIFY( !rp7.isEmpty() );
|
|
QCOMPARE( rp7.radius(), 6.0 );
|
|
QCOMPARE( rp7.firstVertex(), rp7.center().project( 6, 0 ) );
|
|
|
|
rp7.setFirstVertex( QgsPoint( 4, 4 ) );
|
|
QCOMPARE( rp7.firstVertex(), QgsPoint( 4, 4 ) );
|
|
QCOMPARE( rp7.radius(), rp7.center().distance3D( QgsPoint( 4, 4 ) ) );
|
|
|
|
rp7 = QgsRegularPolygon( QgsPoint(), QgsPoint( 0, 5 ), 5, QgsRegularPolygon::InscribedCircle );
|
|
rp7.setCenter( QgsPoint( 5, 5 ) );
|
|
QCOMPARE( rp7.radius(), 5.0 );
|
|
QCOMPARE( rp7.firstVertex(), QgsPoint( 5, 10 ) );
|
|
rp7.setNumberSides( 3 );
|
|
QCOMPARE( rp7.radius(), 5.0 );
|
|
QCOMPARE( rp7.firstVertex(), QgsPoint( 5, 10 ) );
|
|
rp7.setNumberSides( 2 );
|
|
QCOMPARE( rp7.radius(), 5.0 );
|
|
QCOMPARE( rp7.firstVertex(), QgsPoint( 5, 10 ) );
|
|
|
|
// measures
|
|
QGSCOMPARENEAR( rp1.length(), 0.0, 10e-4 );
|
|
QGSCOMPARENEAR( rp1.area(), 0.0, 10e-4 );
|
|
QGSCOMPARENEAR( rp1.perimeter(), 0.0, 10e-4 );
|
|
QGSCOMPARENEAR( rp2.length(), 5.8779, 10e-4 );
|
|
QGSCOMPARENEAR( rp2.area(), 59.4410, 10e-4 );
|
|
QGSCOMPARENEAR( rp2.perimeter(), 29.3893, 10e-4 );
|
|
QCOMPARE( rp2.interiorAngle(), 108.0 );
|
|
QCOMPARE( rp2.centralAngle(), 72.0 );
|
|
QgsRegularPolygon rp8 = QgsRegularPolygon( QgsPoint( 0, 0 ), QgsPoint( 5, 0 ), 5 );
|
|
QGSCOMPARENEAR( rp8.area(), 43.0119, 10e-4 );
|
|
QCOMPARE( rp8.perimeter(), 25.0 );
|
|
QCOMPARE( rp8.length(), 5.0 );
|
|
QCOMPARE( rp8.interiorAngle(), 108.0 );
|
|
QCOMPARE( rp8.centralAngle(), 72.0 );
|
|
rp8.setNumberSides( 4 );
|
|
QCOMPARE( rp8.interiorAngle(), 90.0 );
|
|
QCOMPARE( rp8.centralAngle(), 90.0 );
|
|
rp8.setNumberSides( 3 );
|
|
QCOMPARE( rp8.interiorAngle(), 60.0 );
|
|
QCOMPARE( rp8.centralAngle(), 120.0 );
|
|
|
|
//points
|
|
rp8 = QgsRegularPolygon(); // empty
|
|
QgsPointSequence points = rp8.points();
|
|
QVERIFY( points.isEmpty() );
|
|
rp8 = QgsRegularPolygon( QgsPoint(), QgsPoint( 0, 5 ), 3, QgsRegularPolygon::InscribedCircle );
|
|
points = rp8.points();
|
|
QCOMPARE( points.count(), 3 );
|
|
QCOMPARE( points.at( 0 ), QgsPoint( 0, 5 ) );
|
|
QGSCOMPARENEAR( points.at( 1 ).x(), 4.33, 0.01 );
|
|
QGSCOMPARENEAR( points.at( 1 ).y(), -2.4999, 0.01 );
|
|
QGSCOMPARENEAR( points.at( 2 ).x(), -4.33, 0.01 );
|
|
QGSCOMPARENEAR( points.at( 2 ).y(), -2.4999, 0.01 );
|
|
|
|
//test conversions
|
|
// circle
|
|
QVERIFY( QgsCircle( QgsPoint( 0, 0 ), 5 ) == rp2.circumscribedCircle() );
|
|
QVERIFY( rp2.inscribedCircle() == QgsRegularPolygon( QgsPoint( 0, 0 ), rp2.apothem(), 36.0, 5, QgsRegularPolygon::InscribedCircle ).circumscribedCircle() );
|
|
|
|
// triangle
|
|
QCOMPARE( QgsTriangle(), rp2.toTriangle() );
|
|
QCOMPARE( QgsTriangle(), QgsRegularPolygon().toTriangle() );
|
|
QgsRegularPolygon rp9 = QgsRegularPolygon( QgsPoint( 0, 0 ), 5, 0, 3, QgsRegularPolygon::InscribedCircle );
|
|
|
|
QVERIFY( QgsCircle( QgsPoint( 0, 0 ), 5 ) == rp9.toTriangle().circumscribedCircle() );
|
|
|
|
QgsRegularPolygon rp10 = QgsRegularPolygon( QgsPoint( 0, 0 ), QgsPoint( 0, 4 ), 4 );
|
|
QList<QgsTriangle> rp10_tri = rp10.triangulate();
|
|
QCOMPARE( rp10_tri.length(), static_cast< int >( rp10.numberSides() ) );
|
|
QVERIFY( rp10_tri.at( 0 ) == QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 4 ), rp10.center() ) );
|
|
QVERIFY( rp10_tri.at( 1 ) == QgsTriangle( QgsPoint( 0, 4 ), QgsPoint( 4, 4 ), rp10.center() ) );
|
|
QVERIFY( rp10_tri.at( 2 ) == QgsTriangle( QgsPoint( 4, 4 ), QgsPoint( 4, 0 ), rp10.center() ) );
|
|
QVERIFY( rp10_tri.at( 3 ) == QgsTriangle( QgsPoint( 4, 0 ), QgsPoint( 0, 0 ), rp10.center() ) );
|
|
|
|
QVERIFY( QgsRegularPolygon().triangulate().isEmpty() );
|
|
|
|
// polygon
|
|
std::unique_ptr< QgsPolygonV2 > toP( QgsRegularPolygon().toPolygon() );
|
|
QVERIFY( toP->isEmpty() );
|
|
|
|
QgsPointSequence ptsPol;
|
|
std::unique_ptr< QgsPolygonV2 > pol( new QgsPolygonV2() );
|
|
pol.reset( rp10.toPolygon() );
|
|
QCOMPARE( pol->numInteriorRings(), 0 );
|
|
QCOMPARE( pol->exteriorRing()->numPoints(), 5 );
|
|
|
|
pol->exteriorRing()->points( ptsPol );
|
|
QCOMPARE( ptsPol.length(), 5 );
|
|
QVERIFY( ptsPol.at( 0 ) == QgsPoint( 0, 0 ) );
|
|
QVERIFY( ptsPol.at( 1 ) == QgsPoint( 0, 4 ) );
|
|
QVERIFY( ptsPol.at( 2 ) == QgsPoint( 4, 4 ) );
|
|
QVERIFY( ptsPol.at( 3 ) == QgsPoint( 4, 0 ) );
|
|
QVERIFY( ptsPol.at( 4 ) == QgsPoint( 0, 0 ) );
|
|
ptsPol.pop_back();
|
|
|
|
std::unique_ptr< QgsLineString > l( QgsRegularPolygon( QgsPoint(), QgsPoint( 0, 5 ), 1, QgsRegularPolygon::InscribedCircle ).toLineString() );
|
|
QVERIFY( l->isEmpty() );
|
|
l.reset( rp10.toLineString() );
|
|
QCOMPARE( l->numPoints(), 4 );
|
|
QgsPointSequence pts_l;
|
|
l->points( pts_l );
|
|
QCOMPARE( ptsPol, pts_l );
|
|
|
|
//test toString
|
|
QCOMPARE( rp1.toString(), QString( "Empty" ) );
|
|
QCOMPARE( rp2.toString(), QString( "RegularPolygon (Center: Point (0 0), First Vertex: Point (0 5), Radius: 5, Azimuth: 0)" ) );
|
|
|
|
}
|
|
|
|
|
|
void TestQgsGeometry::curvePolygon()
|
|
{
|
|
//test constructor
|
|
QgsCurvePolygon p1;
|
|
QVERIFY( p1.isEmpty() );
|
|
QCOMPARE( p1.numInteriorRings(), 0 );
|
|
QCOMPARE( p1.nCoordinates(), 0 );
|
|
QCOMPARE( p1.ringCount(), 0 );
|
|
QCOMPARE( p1.partCount(), 0 );
|
|
QVERIFY( !p1.is3D() );
|
|
QVERIFY( !p1.isMeasure() );
|
|
QCOMPARE( p1.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
QCOMPARE( p1.wktTypeStr(), QString( "CurvePolygon" ) );
|
|
QCOMPARE( p1.geometryType(), QString( "CurvePolygon" ) );
|
|
QCOMPARE( p1.dimension(), 2 );
|
|
QVERIFY( !p1.hasCurvedSegments() );
|
|
QCOMPARE( p1.area(), 0.0 );
|
|
QCOMPARE( p1.perimeter(), 0.0 );
|
|
QVERIFY( !p1.exteriorRing() );
|
|
QVERIFY( !p1.interiorRing( 0 ) );
|
|
|
|
//set exterior ring
|
|
|
|
//try with no ring
|
|
QgsCircularString *ext = nullptr;
|
|
p1.setExteriorRing( ext );
|
|
QVERIFY( p1.isEmpty() );
|
|
QCOMPARE( p1.numInteriorRings(), 0 );
|
|
QCOMPARE( p1.nCoordinates(), 0 );
|
|
QCOMPARE( p1.ringCount(), 0 );
|
|
QCOMPARE( p1.partCount(), 0 );
|
|
QVERIFY( !p1.exteriorRing() );
|
|
QVERIFY( !p1.interiorRing( 0 ) );
|
|
QCOMPARE( p1.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
|
|
// empty exterior ring
|
|
ext = new QgsCircularString();
|
|
p1.setExteriorRing( ext );
|
|
QVERIFY( p1.isEmpty() );
|
|
QCOMPARE( p1.numInteriorRings(), 0 );
|
|
QCOMPARE( p1.nCoordinates(), 0 );
|
|
QCOMPARE( p1.ringCount(), 1 );
|
|
QCOMPARE( p1.partCount(), 1 );
|
|
QVERIFY( p1.exteriorRing() );
|
|
QVERIFY( !p1.interiorRing( 0 ) );
|
|
QCOMPARE( p1.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
|
|
//valid exterior ring
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p1.setExteriorRing( ext );
|
|
QVERIFY( !p1.isEmpty() );
|
|
QCOMPARE( p1.numInteriorRings(), 0 );
|
|
QCOMPARE( p1.nCoordinates(), 5 );
|
|
QCOMPARE( p1.ringCount(), 1 );
|
|
QCOMPARE( p1.partCount(), 1 );
|
|
QVERIFY( !p1.is3D() );
|
|
QVERIFY( !p1.isMeasure() );
|
|
QCOMPARE( p1.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
QCOMPARE( p1.wktTypeStr(), QString( "CurvePolygon" ) );
|
|
QCOMPARE( p1.geometryType(), QString( "CurvePolygon" ) );
|
|
QCOMPARE( p1.dimension(), 2 );
|
|
QVERIFY( p1.hasCurvedSegments() );
|
|
QGSCOMPARENEAR( p1.area(), 157.08, 0.01 );
|
|
QGSCOMPARENEAR( p1.perimeter(), 44.4288, 0.01 );
|
|
QVERIFY( p1.exteriorRing() );
|
|
QVERIFY( !p1.interiorRing( 0 ) );
|
|
|
|
//retrieve exterior ring and check
|
|
QCOMPARE( *( static_cast< const QgsCircularString * >( p1.exteriorRing() ) ), *ext );
|
|
|
|
//initial setting of exterior ring should set z/m type
|
|
QgsCurvePolygon p2;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) );
|
|
p2.setExteriorRing( ext );
|
|
QVERIFY( p2.is3D() );
|
|
QVERIFY( !p2.isMeasure() );
|
|
QCOMPARE( p2.wkbType(), QgsWkbTypes::CurvePolygonZ );
|
|
QCOMPARE( p2.wktTypeStr(), QString( "CurvePolygonZ" ) );
|
|
QCOMPARE( p2.geometryType(), QString( "CurvePolygon" ) );
|
|
QCOMPARE( *( static_cast< const QgsCircularString * >( p2.exteriorRing() ) ), *ext );
|
|
QgsCurvePolygon p3;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0, 10, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 10, 10, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 10, 0, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 ) );
|
|
p3.setExteriorRing( ext );
|
|
QVERIFY( !p3.is3D() );
|
|
QVERIFY( p3.isMeasure() );
|
|
QCOMPARE( p3.wkbType(), QgsWkbTypes::CurvePolygonM );
|
|
QCOMPARE( p3.wktTypeStr(), QString( "CurvePolygonM" ) );
|
|
QCOMPARE( *( static_cast< const QgsCircularString * >( p3.exteriorRing() ) ), *ext );
|
|
QgsCurvePolygon p4;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 2, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 3, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 5, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 2, 1 ) );
|
|
p4.setExteriorRing( ext );
|
|
QVERIFY( p4.is3D() );
|
|
QVERIFY( p4.isMeasure() );
|
|
QCOMPARE( p4.wkbType(), QgsWkbTypes::CurvePolygonZM );
|
|
QCOMPARE( p4.wktTypeStr(), QString( "CurvePolygonZM" ) );
|
|
QCOMPARE( *( static_cast< const QgsCircularString * >( p4.exteriorRing() ) ), *ext );
|
|
|
|
//addInteriorRing
|
|
QgsCurvePolygon p6;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p6.setExteriorRing( ext );
|
|
//empty ring
|
|
QCOMPARE( p6.numInteriorRings(), 0 );
|
|
QVERIFY( !p6.interiorRing( -1 ) );
|
|
QVERIFY( !p6.interiorRing( 0 ) );
|
|
p6.addInteriorRing( 0 );
|
|
QCOMPARE( p6.numInteriorRings(), 0 );
|
|
QgsCircularString *ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( 1, 1 ) << QgsPoint( 1, 9 ) << QgsPoint( 9, 9 )
|
|
<< QgsPoint( 9, 1 ) << QgsPoint( 1, 1 ) );
|
|
p6.addInteriorRing( ring );
|
|
QCOMPARE( p6.numInteriorRings(), 1 );
|
|
QCOMPARE( p6.interiorRing( 0 ), ring );
|
|
QVERIFY( !p6.interiorRing( 1 ) );
|
|
|
|
QgsCoordinateSequence seq = p6.coordinateSequence();
|
|
QCOMPARE( seq, QgsCoordinateSequence() << ( QgsRingSequence() << ( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) )
|
|
<< ( QgsPointSequence() << QgsPoint( 1, 1 ) << QgsPoint( 1, 9 ) << QgsPoint( 9, 9 )
|
|
<< QgsPoint( 9, 1 ) << QgsPoint( 1, 1 ) ) ) );
|
|
QCOMPARE( p6.nCoordinates(), 10 );
|
|
|
|
//try adding an interior ring with z to a 2d polygon, z should be dropped
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.2, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 ) );
|
|
p6.addInteriorRing( ring );
|
|
QCOMPARE( p6.numInteriorRings(), 2 );
|
|
QVERIFY( !p6.is3D() );
|
|
QVERIFY( !p6.isMeasure() );
|
|
QCOMPARE( p6.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
QVERIFY( p6.interiorRing( 1 ) );
|
|
QVERIFY( !p6.interiorRing( 1 )->is3D() );
|
|
QVERIFY( !p6.interiorRing( 1 )->isMeasure() );
|
|
QCOMPARE( p6.interiorRing( 1 )->wkbType(), QgsWkbTypes::CircularString );
|
|
|
|
//try adding an interior ring with m to a 2d polygon, m should be dropped
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0.1, 0.1, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0.1, 0.2, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 0.2, 0.2, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0.2, 0.1, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 0.1, 0.1, 0, 1 ) );
|
|
p6.addInteriorRing( ring );
|
|
QCOMPARE( p6.numInteriorRings(), 3 );
|
|
QVERIFY( !p6.is3D() );
|
|
QVERIFY( !p6.isMeasure() );
|
|
QCOMPARE( p6.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
QVERIFY( p6.interiorRing( 2 ) );
|
|
QVERIFY( !p6.interiorRing( 2 )->is3D() );
|
|
QVERIFY( !p6.interiorRing( 2 )->isMeasure() );
|
|
QCOMPARE( p6.interiorRing( 2 )->wkbType(), QgsWkbTypes::CircularString );
|
|
|
|
|
|
//addInteriorRing without z/m to PolygonZM
|
|
QgsCurvePolygon p6b;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1 ) );
|
|
p6b.setExteriorRing( ext );
|
|
QVERIFY( p6b.is3D() );
|
|
QVERIFY( p6b.isMeasure() );
|
|
QCOMPARE( p6b.wkbType(), QgsWkbTypes::CurvePolygonZM );
|
|
//ring has no z
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 1, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 1, 9 ) << QgsPoint( QgsWkbTypes::PointM, 9, 9 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 9, 1 ) << QgsPoint( QgsWkbTypes::PointM, 1, 1 ) );
|
|
p6b.addInteriorRing( ring );
|
|
QVERIFY( p6b.interiorRing( 0 ) );
|
|
QVERIFY( p6b.interiorRing( 0 )->is3D() );
|
|
QVERIFY( p6b.interiorRing( 0 )->isMeasure() );
|
|
QCOMPARE( p6b.interiorRing( 0 )->wkbType(), QgsWkbTypes::CircularStringZM );
|
|
QCOMPARE( p6b.interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 1, 0, 2 ) );
|
|
//ring has no m
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.2, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 ) );
|
|
p6b.addInteriorRing( ring );
|
|
QVERIFY( p6b.interiorRing( 1 ) );
|
|
QVERIFY( p6b.interiorRing( 1 )->is3D() );
|
|
QVERIFY( p6b.interiorRing( 1 )->isMeasure() );
|
|
QCOMPARE( p6b.interiorRing( 1 )->wkbType(), QgsWkbTypes::CircularStringZM );
|
|
QCOMPARE( p6b.interiorRing( 1 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 0.1, 0.1, 1, 0 ) );
|
|
|
|
//set interior rings
|
|
QgsCurvePolygon p7;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p7.setExteriorRing( ext );
|
|
//add a list of rings with mixed types
|
|
QList< QgsCurve * > rings;
|
|
rings << new QgsCircularString();
|
|
static_cast< QgsCircularString *>( rings[0] )->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.2, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 ) );
|
|
rings << new QgsCircularString();
|
|
static_cast< QgsCircularString *>( rings[1] )->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0.3, 0.3, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0.3, 0.4, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 0.4, 0.4, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0.4, 0.3, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 0.3, 0.3, 0, 1 ) );
|
|
//throw an empty ring in too
|
|
rings << 0;
|
|
rings << new QgsCircularString();
|
|
static_cast< QgsCircularString *>( rings[3] )->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p7.setInteriorRings( rings );
|
|
QCOMPARE( p7.numInteriorRings(), 3 );
|
|
QVERIFY( p7.interiorRing( 0 ) );
|
|
QVERIFY( !p7.interiorRing( 0 )->is3D() );
|
|
QVERIFY( !p7.interiorRing( 0 )->isMeasure() );
|
|
QCOMPARE( p7.interiorRing( 0 )->wkbType(), QgsWkbTypes::CircularString );
|
|
QCOMPARE( p7.interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::Point, 0.1, 0.1 ) );
|
|
QVERIFY( p7.interiorRing( 1 ) );
|
|
QVERIFY( !p7.interiorRing( 1 )->is3D() );
|
|
QVERIFY( !p7.interiorRing( 1 )->isMeasure() );
|
|
QCOMPARE( p7.interiorRing( 1 )->wkbType(), QgsWkbTypes::CircularString );
|
|
QCOMPARE( p7.interiorRing( 1 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::Point, 0.3, 0.3 ) );
|
|
QVERIFY( p7.interiorRing( 2 ) );
|
|
QVERIFY( !p7.interiorRing( 2 )->is3D() );
|
|
QVERIFY( !p7.interiorRing( 2 )->isMeasure() );
|
|
QCOMPARE( p7.interiorRing( 2 )->wkbType(), QgsWkbTypes::CircularString );
|
|
|
|
//set rings with existing
|
|
rings.clear();
|
|
rings << new QgsCircularString();
|
|
static_cast< QgsCircularString *>( rings[0] )->setPoints( QgsPointSequence() << QgsPoint( 0.8, 0.8 )
|
|
<< QgsPoint( 0.8, 0.9 ) << QgsPoint( 0.9, 0.9 )
|
|
<< QgsPoint( 0.9, 0.8 ) << QgsPoint( 0.8, 0.8 ) );
|
|
p7.setInteriorRings( rings );
|
|
QCOMPARE( p7.numInteriorRings(), 1 );
|
|
QVERIFY( p7.interiorRing( 0 ) );
|
|
QVERIFY( !p7.interiorRing( 0 )->is3D() );
|
|
QVERIFY( !p7.interiorRing( 0 )->isMeasure() );
|
|
QCOMPARE( p7.interiorRing( 0 )->wkbType(), QgsWkbTypes::CircularString );
|
|
QCOMPARE( p7.interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::Point, 0.8, 0.8 ) );
|
|
rings.clear();
|
|
p7.setInteriorRings( rings );
|
|
QCOMPARE( p7.numInteriorRings(), 0 );
|
|
|
|
//change dimensionality of interior rings using setExteriorRing
|
|
QgsCurvePolygon p7a;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 10, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 0, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) );
|
|
p7a.setExteriorRing( ext );
|
|
rings.clear();
|
|
rings << new QgsCircularString();
|
|
static_cast< QgsCircularString *>( rings[0] )->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.2, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.2, 0.1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0.1, 0.1, 1 ) );
|
|
rings << new QgsCircularString();
|
|
static_cast< QgsCircularString *>( rings[1] )->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0.3, 0.3, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.3, 0.4, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 0.4, 0.4, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0.4, 0.3, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0.3, 0.3, 1 ) );
|
|
p7a.setInteriorRings( rings );
|
|
QVERIFY( p7a.is3D() );
|
|
QVERIFY( !p7a.isMeasure() );
|
|
QVERIFY( p7a.interiorRing( 0 )->is3D() );
|
|
QVERIFY( !p7a.interiorRing( 0 )->isMeasure() );
|
|
QVERIFY( p7a.interiorRing( 1 )->is3D() );
|
|
QVERIFY( !p7a.interiorRing( 1 )->isMeasure() );
|
|
//reset exterior ring to 2d
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 )
|
|
<< QgsPoint( 10, 10 ) << QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p7a.setExteriorRing( ext );
|
|
QVERIFY( !p7a.is3D() );
|
|
QVERIFY( !p7a.interiorRing( 0 )->is3D() ); //rings should also be made 2D
|
|
QVERIFY( !p7a.interiorRing( 1 )->is3D() );
|
|
//reset exterior ring to LineStringM
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0, 0 ) << QgsPoint( QgsWkbTypes::PointM, 0, 10 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 10, 10 ) << QgsPoint( QgsWkbTypes::PointM, 10, 0 ) << QgsPoint( QgsWkbTypes::PointM, 0, 0 ) );
|
|
p7a.setExteriorRing( ext );
|
|
QVERIFY( p7a.isMeasure() );
|
|
QVERIFY( p7a.interiorRing( 0 )->isMeasure() ); //rings should also gain measure
|
|
QVERIFY( p7a.interiorRing( 1 )->isMeasure() );
|
|
|
|
//removeInteriorRing
|
|
QgsCurvePolygon p8;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p8.setExteriorRing( ext );
|
|
QVERIFY( !p8.removeInteriorRing( -1 ) );
|
|
QVERIFY( !p8.removeInteriorRing( 0 ) );
|
|
rings.clear();
|
|
rings << new QgsCircularString();
|
|
static_cast< QgsCircularString *>( rings[0] )->setPoints( QgsPointSequence() << QgsPoint( 0.1, 0.1 )
|
|
<< QgsPoint( 0.1, 0.2 ) << QgsPoint( 0.2, 0.2 )
|
|
<< QgsPoint( 0.2, 0.1 ) << QgsPoint( 0.1, 0.1 ) );
|
|
rings << new QgsCircularString();
|
|
static_cast< QgsCircularString *>( rings[1] )->setPoints( QgsPointSequence() << QgsPoint( 0.3, 0.3 )
|
|
<< QgsPoint( 0.3, 0.4 ) << QgsPoint( 0.4, 0.4 )
|
|
<< QgsPoint( 0.4, 0.3 ) << QgsPoint( 0.3, 0.3 ) );
|
|
rings << new QgsCircularString();
|
|
static_cast< QgsCircularString *>( rings[2] )->setPoints( QgsPointSequence() << QgsPoint( 0.8, 0.8 )
|
|
<< QgsPoint( 0.8, 0.9 ) << QgsPoint( 0.9, 0.9 )
|
|
<< QgsPoint( 0.9, 0.8 ) << QgsPoint( 0.8, 0.8 ) );
|
|
p8.setInteriorRings( rings );
|
|
QCOMPARE( p8.numInteriorRings(), 3 );
|
|
QVERIFY( p8.removeInteriorRing( 0 ) );
|
|
QCOMPARE( p8.numInteriorRings(), 2 );
|
|
QCOMPARE( p8.interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 0.3, 0.3 ) );
|
|
QCOMPARE( p8.interiorRing( 1 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 0.8, 0.8 ) );
|
|
QVERIFY( p8.removeInteriorRing( 1 ) );
|
|
QCOMPARE( p8.numInteriorRings(), 1 );
|
|
QCOMPARE( p8.interiorRing( 0 )->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 0.3, 0.3 ) );
|
|
QVERIFY( p8.removeInteriorRing( 0 ) );
|
|
QCOMPARE( p8.numInteriorRings(), 0 );
|
|
QVERIFY( !p8.removeInteriorRing( 0 ) );
|
|
|
|
//clear
|
|
QgsCurvePolygon p9;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) );
|
|
p9.setExteriorRing( ext );
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1, 9, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 9, 9, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 9, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 1 ) );
|
|
p9.addInteriorRing( ring );
|
|
QCOMPARE( p9.numInteriorRings(), 1 );
|
|
p9.clear();
|
|
QVERIFY( p9.isEmpty() );
|
|
QCOMPARE( p9.numInteriorRings(), 0 );
|
|
QCOMPARE( p9.nCoordinates(), 0 );
|
|
QCOMPARE( p9.ringCount(), 0 );
|
|
QCOMPARE( p9.partCount(), 0 );
|
|
QVERIFY( !p9.is3D() );
|
|
QVERIFY( !p9.isMeasure() );
|
|
QCOMPARE( p9.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
|
|
//equality operator
|
|
QgsCurvePolygon p10;
|
|
QgsCurvePolygon p10b;
|
|
QVERIFY( p10 == p10b );
|
|
QVERIFY( !( p10 != p10b ) );
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p10.setExteriorRing( ext );
|
|
QVERIFY( !( p10 == p10b ) );
|
|
QVERIFY( p10 != p10b );
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
p10b.setExteriorRing( ext );
|
|
QVERIFY( p10 == p10b );
|
|
QVERIFY( !( p10 != p10b ) );
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 9 ) << QgsPoint( 9, 9 )
|
|
<< QgsPoint( 9, 0 ) << QgsPoint( 0, 0 ) );
|
|
p10b.setExteriorRing( ext );
|
|
QVERIFY( !( p10 == p10b ) );
|
|
QVERIFY( p10 != p10b );
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 10, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) );
|
|
p10b.setExteriorRing( ext );
|
|
QVERIFY( !( p10 == p10b ) );
|
|
QVERIFY( p10 != p10b );
|
|
p10b.setExteriorRing( p10.exteriorRing()->clone() );
|
|
QVERIFY( p10 == p10b );
|
|
QVERIFY( !( p10 != p10b ) );
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( 1, 1 )
|
|
<< QgsPoint( 1, 9 ) << QgsPoint( 9, 9 )
|
|
<< QgsPoint( 9, 1 ) << QgsPoint( 1, 1 ) );
|
|
p10.addInteriorRing( ring );
|
|
QVERIFY( !( p10 == p10b ) );
|
|
QVERIFY( p10 != p10b );
|
|
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( 2, 1 )
|
|
<< QgsPoint( 2, 9 ) << QgsPoint( 9, 9 )
|
|
<< QgsPoint( 9, 1 ) << QgsPoint( 2, 1 ) );
|
|
p10b.addInteriorRing( ring );
|
|
QVERIFY( !( p10 == p10b ) );
|
|
QVERIFY( p10 != p10b );
|
|
p10b.removeInteriorRing( 0 );
|
|
p10b.addInteriorRing( p10.interiorRing( 0 )->clone() );
|
|
QVERIFY( p10 == p10b );
|
|
QVERIFY( !( p10 != p10b ) );
|
|
|
|
//clone
|
|
|
|
QgsCurvePolygon p11;
|
|
std::unique_ptr< QgsCurvePolygon >cloned( p11.clone() );
|
|
QCOMPARE( p11, *cloned );
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
p11.setExteriorRing( ext );
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
p11.addInteriorRing( ring );
|
|
cloned.reset( p11.clone() );
|
|
QCOMPARE( p11, *cloned );
|
|
|
|
//copy constructor
|
|
QgsCurvePolygon p12;
|
|
QgsCurvePolygon p13( p12 );
|
|
QCOMPARE( p12, p13 );
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
p12.setExteriorRing( ext );
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
p12.addInteriorRing( ring );
|
|
QgsCurvePolygon p14( p12 );
|
|
QCOMPARE( p12, p14 );
|
|
|
|
//assignment operator
|
|
QgsCurvePolygon p15;
|
|
p15 = p13;
|
|
QCOMPARE( p13, p15 );
|
|
p15 = p12;
|
|
QCOMPARE( p12, p15 );
|
|
|
|
// bounding box
|
|
QgsCurvePolygon boundingBoxPoly;
|
|
QgsRectangle bBox = boundingBoxPoly.boundingBox(); //no crash!
|
|
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0, 1 ) << QgsPoint( 1, 10, 2 ) << QgsPoint( 0, 18, 3 )
|
|
<< QgsPoint( -1, 4, 4 ) << QgsPoint( 0, 0, 1 ) );
|
|
boundingBoxPoly.setExteriorRing( ext );
|
|
bBox = boundingBoxPoly.boundingBox();
|
|
QGSCOMPARENEAR( bBox.xMinimum(), -1.435273, 0.001 );
|
|
QGSCOMPARENEAR( bBox.xMaximum(), 1.012344, 0.001 );
|
|
QGSCOMPARENEAR( bBox.yMinimum(), 0.000000, 0.001 );
|
|
QGSCOMPARENEAR( bBox.yMaximum(), 18, 0.001 );
|
|
|
|
//surfaceToPolygon
|
|
QgsCurvePolygon p12a;
|
|
std::unique_ptr< QgsPolygonV2 > surface( p12a.surfaceToPolygon() );
|
|
QVERIFY( surface->isEmpty() );
|
|
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 3 ) << QgsPoint( 2, 4 )
|
|
<< QgsPoint( -1, 5 ) << QgsPoint( 0, 6 ) );
|
|
p12a.setExteriorRing( ext );
|
|
surface.reset( p12a.surfaceToPolygon() );
|
|
QCOMPARE( surface->wkbType(), QgsWkbTypes::Polygon );
|
|
QCOMPARE( surface->exteriorRing()->nCoordinates(), 290 );
|
|
QCOMPARE( surface->exteriorRing()->nCoordinates(), 290 ); // nCoordinates is cached, so check twice
|
|
QVERIFY( surface->exteriorRing()->isClosed() );
|
|
// too many vertices to actually check the result, let's just make sure the bounding boxes are similar
|
|
QgsRectangle r1 = ext->boundingBox();
|
|
QgsRectangle r2 = surface->exteriorRing()->boundingBox();
|
|
QGSCOMPARENEAR( r1.xMinimum(), r2.xMinimum(), 0.0001 );
|
|
QGSCOMPARENEAR( r1.xMaximum(), r2.xMaximum(), 0.0001 );
|
|
QGSCOMPARENEAR( r1.yMinimum(), r2.yMinimum(), 0.0001 );
|
|
QGSCOMPARENEAR( r1.yMaximum(), r2.yMaximum(), 0.0001 );
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
p12a.addInteriorRing( ring );
|
|
surface.reset( p12a.surfaceToPolygon() );
|
|
QCOMPARE( surface->wkbType(), QgsWkbTypes::Polygon );
|
|
QCOMPARE( surface->exteriorRing()->nCoordinates(), 290 );
|
|
QCOMPARE( surface->exteriorRing()->nCoordinates(), 290 ); // nCoordinates is cached, so check twice
|
|
QVERIFY( surface->exteriorRing()->isClosed() );
|
|
QCOMPARE( surface->numInteriorRings(), 1 );
|
|
// too many vertices to actually check the result, let's just make sure the bounding boxes are similar
|
|
r1 = ring->boundingBox();
|
|
r2 = surface->interiorRing( 0 )->boundingBox();
|
|
QGSCOMPARENEAR( r1.xMinimum(), r2.xMinimum(), 0.0001 );
|
|
QGSCOMPARENEAR( r1.xMaximum(), r2.xMaximum(), 0.0001 );
|
|
QGSCOMPARENEAR( r1.yMinimum(), r2.yMinimum(), 0.0001 );
|
|
QGSCOMPARENEAR( r1.yMaximum(), r2.yMaximum(), 0.0001 );
|
|
|
|
//toPolygon
|
|
p12a = QgsCurvePolygon();
|
|
surface.reset( p12a.toPolygon() );
|
|
QVERIFY( surface->isEmpty() );
|
|
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 10 ) << QgsPoint( 0, 18 )
|
|
<< QgsPoint( -1, 4 ) << QgsPoint( 0, 0 ) );
|
|
p12a.setExteriorRing( ext );
|
|
surface.reset( p12a.toPolygon() );
|
|
QCOMPARE( surface->wkbType(), QgsWkbTypes::Polygon );
|
|
QCOMPARE( surface->exteriorRing()->nCoordinates(), 64 );
|
|
QCOMPARE( surface->exteriorRing()->nCoordinates(), 64 ); // ncoordinates is cached, so check twice
|
|
QVERIFY( surface->exteriorRing()->isClosed() );
|
|
// too many vertices to actually check the result, let's just make sure the bounding boxes are similar
|
|
r1 = ext->boundingBox();
|
|
r2 = surface->exteriorRing()->boundingBox();
|
|
QGSCOMPARENEAR( r1.xMinimum(), r2.xMinimum(), 0.01 );
|
|
QGSCOMPARENEAR( r1.xMaximum(), r2.xMaximum(), 0.01 );
|
|
QGSCOMPARENEAR( r1.yMinimum(), r2.yMinimum(), 0.01 );
|
|
QGSCOMPARENEAR( r1.yMaximum(), r2.yMaximum(), 0.01 );
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
p12a.addInteriorRing( ring );
|
|
surface.reset( p12a.toPolygon() );
|
|
QCOMPARE( surface->wkbType(), QgsWkbTypes::Polygon );
|
|
QCOMPARE( surface->exteriorRing()->nCoordinates(), 64 );
|
|
QCOMPARE( surface->exteriorRing()->nCoordinates(), 64 ); //ncoordinates is cached, so check twice
|
|
QVERIFY( surface->exteriorRing()->isClosed() );
|
|
QCOMPARE( surface->numInteriorRings(), 1 );
|
|
// too many vertices to actually check the result, let's just make sure the bounding boxes are similar
|
|
r1 = ring->boundingBox();
|
|
r2 = surface->interiorRing( 0 )->boundingBox();
|
|
QGSCOMPARENEAR( r1.xMinimum(), r2.xMinimum(), 0.0001 );
|
|
QGSCOMPARENEAR( r1.xMaximum(), r2.xMaximum(), 0.0001 );
|
|
QGSCOMPARENEAR( r1.yMinimum(), r2.yMinimum(), 0.0001 );
|
|
QGSCOMPARENEAR( r1.yMaximum(), r2.yMaximum(), 0.0001 );
|
|
|
|
//toCurveType - should be identical since it's already a curve
|
|
std::unique_ptr< QgsCurvePolygon > curveType( p12a.toCurveType() );
|
|
QCOMPARE( *curveType, p12a );
|
|
|
|
//to/fromWKB
|
|
QgsCurvePolygon p16;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 2, 0 )
|
|
<< QgsPoint( 1, 0.5 ) << QgsPoint( 0, 0 ) );
|
|
p16.setExteriorRing( ext );
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0.1, 0 ) << QgsPoint( 0.2, 0 )
|
|
<< QgsPoint( 0.1, 0.05 ) << QgsPoint( 0, 0 ) );
|
|
p16.addInteriorRing( ring );
|
|
QByteArray wkb16 = p16.asWkb();
|
|
QgsCurvePolygon p17;
|
|
QgsConstWkbPtr wkb16ptr( wkb16 );
|
|
p17.fromWkb( wkb16ptr );
|
|
QCOMPARE( p16, p17 );
|
|
//CurvePolygonZ
|
|
p16.clear();
|
|
p17.clear();
|
|
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0, 1 ) << QgsPoint( 1, 0, 2 ) << QgsPoint( 2, 0, 3 )
|
|
<< QgsPoint( 1, 0.5, 4 ) << QgsPoint( 0, 0, 1 ) );
|
|
p16.setExteriorRing( ext );
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( 0, 0, 1 ) << QgsPoint( 0.1, 0, 2 ) << QgsPoint( 0.2, 0, 3 )
|
|
<< QgsPoint( 0.1, 0.05, 4 ) << QgsPoint( 0, 0, 1 ) );
|
|
p16.addInteriorRing( ring );
|
|
wkb16 = p16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr2( wkb16 );
|
|
p17.fromWkb( wkb16ptr2 );
|
|
QCOMPARE( p16, p17 );
|
|
|
|
// compound curve
|
|
QgsCompoundCurve *cCurve = new QgsCompoundCurve();
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0, 1 ) << QgsPoint( 1, 0, 2 ) << QgsPoint( 2, 0, 3 )
|
|
<< QgsPoint( 1, 0.5, 4 ) << QgsPoint( 0, 0, 1 ) );
|
|
cCurve->addCurve( ext );
|
|
p16.addInteriorRing( cCurve );
|
|
wkb16 = p16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr3( wkb16 );
|
|
p17.fromWkb( wkb16ptr3 );
|
|
QCOMPARE( p16, p17 );
|
|
|
|
//CurvePolygonM
|
|
p16.clear();
|
|
p17.clear();
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 ) << QgsPoint( QgsWkbTypes::PointM, 1, 0, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 2, 0, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 1, 0.5, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 ) );
|
|
p16.setExteriorRing( ext );
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 ) << QgsPoint( QgsWkbTypes::PointM, 0.1, 0, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 0.2, 0, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0.1, 0.05, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 ) );
|
|
p16.addInteriorRing( ring );
|
|
wkb16 = p16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr8( wkb16 );
|
|
p17.fromWkb( wkb16ptr8 );
|
|
QCOMPARE( p16, p17 );
|
|
|
|
//CurvePolygonZM
|
|
p16.clear();
|
|
p17.clear();
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 0, 11, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 2, 0, 12, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 0.5, 13, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) );
|
|
p16.setExteriorRing( ext );
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 0.1, 0, 11, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 0.2, 0, 12, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0.1, 0.05, 13, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) );
|
|
p16.addInteriorRing( ring );
|
|
wkb16 = p16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr4( wkb16 );
|
|
p17.fromWkb( wkb16ptr4 );
|
|
QCOMPARE( p16, p17 );
|
|
|
|
//bad WKB - check for no crash
|
|
p17.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !p17.fromWkb( nullPtr ) );
|
|
QCOMPARE( p17.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkbPoint = point.asWkb();
|
|
QgsConstWkbPtr wkbPointPtr( wkbPoint );
|
|
QVERIFY( !p17.fromWkb( wkbPointPtr ) );
|
|
QCOMPARE( p17.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
|
|
//to/from WKT
|
|
QgsCurvePolygon p18;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 0, 11, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 2, 0, 12, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 0.5, 13, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) );
|
|
p18.setExteriorRing( ext );
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 0.1, 0, 11, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 0.2, 0, 12, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0.1, 0.05, 13, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) );
|
|
p18.addInteriorRing( ring );
|
|
|
|
QString wkt = p18.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsCurvePolygon p19;
|
|
QVERIFY( p19.fromWkt( wkt ) );
|
|
QCOMPARE( p18, p19 );
|
|
|
|
//bad WKT
|
|
QVERIFY( !p19.fromWkt( "Point()" ) );
|
|
QVERIFY( p19.isEmpty() );
|
|
QVERIFY( !p19.exteriorRing() );
|
|
QCOMPARE( p19.numInteriorRings(), 0 );
|
|
QVERIFY( !p19.is3D() );
|
|
QVERIFY( !p19.isMeasure() );
|
|
QCOMPARE( p19.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
|
|
|
|
//as JSON
|
|
QgsCurvePolygon exportPolygon;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 0, 11, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 2, 0, 12, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 0.5, 13, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) );
|
|
exportPolygon.setExteriorRing( ext );
|
|
|
|
|
|
// GML document for compare
|
|
QDomDocument doc( QStringLiteral( "gml" ) );
|
|
|
|
// as GML2
|
|
QString expectedSimpleGML2( QStringLiteral( "<Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0,0 1,0 2,0 2,0 2,0 2,0.1 1.9,0.1 1.9,0.1 1.9,0.1 1.9,0.1 1.9,0.1 1.9,0.1 1.9,0.2 1.8,0.2 1.8,0.2 1.8,0.2 1.8,0.2 1.8,0.2 1.8,0.2 1.7,0.3 1.7,0.3 1.7,0.3 1.7,0.3 1.7,0.3 1.6,0.3 1.6,0.3 1.6,0.3 1.6,0.4 1.6,0.4 1.6,0.4 1.5,0.4 1.5,0.4 1.5,0.4 1.5,0.4 1.5,0.4 1.4,0.4 1.4,0.4 1.4,0.4 1.4,0.4 1.4,0.4 1.3,0.5 1.3,0.5 1.3,0.5 1.3,0.5 1.2,0.5 1.2,0.5 1.2,0.5 1.2,0.5 1.2,0.5 1.1,0.5 1.1,0.5 1.1,0.5 1.1,0.5 1.1,0.5 1,0.5 1,0.5 1,0.5 1,0.5 0.9,0.5 0.9,0.5 0.9,0.5 0.9,0.5 0.9,0.5 0.8,0.5 0.8,0.5 0.8,0.5 0.8,0.5 0.8,0.5 0.7,0.5 0.7,0.5 0.7,0.5 0.7,0.5 0.6,0.4 0.6,0.4 0.6,0.4 0.6,0.4 0.6,0.4 0.5,0.4 0.5,0.4 0.5,0.4 0.5,0.4 0.5,0.4 0.4,0.4 0.4,0.4 0.4,0.4 0.4,0.3 0.4,0.3 0.4,0.3 0.3,0.3 0.3,0.3 0.3,0.3 0.3,0.3 0.3,0.3 0.2,0.2 0.2,0.2 0.2,0.2 0.2,0.2 0.2,0.2 0.2,0.2 0.1,0.2 0.1,0.1 0.1,0.1 0.1,0.1 0.1,0.1 0.1,0.1 0.1,0.1 0,0.1 0,0 0,0 0,0</coordinates></LinearRing></outerBoundaryIs></Polygon>" ) );
|
|
QString res = elemToString( exportPolygon.asGML2( doc, 1 ) );
|
|
QGSCOMPAREGML( res, expectedSimpleGML2 );
|
|
|
|
//as GML3
|
|
QString expectedSimpleGML3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 1 0 11 2 0 12 1 0.5 13 0 0 10</posList></ArcString></segments></Curve></exterior></Polygon>" ) );
|
|
res = elemToString( exportPolygon.asGML3( doc, 2 ) );
|
|
QCOMPARE( elemToString( exportPolygon.asGML3( doc ) ), expectedSimpleGML3 );
|
|
|
|
// as JSON
|
|
QString expectedSimpleJson( QStringLiteral( "{\"type\": \"Polygon\", \"coordinates\": [[ [0, 0], [1, 0], [2, 0], [2, 0], [2, 0], [2, 0.1], [1.9, 0.1], [1.9, 0.1], [1.9, 0.1], [1.9, 0.1], [1.9, 0.1], [1.9, 0.1], [1.9, 0.2], [1.8, 0.2], [1.8, 0.2], [1.8, 0.2], [1.8, 0.2], [1.8, 0.2], [1.8, 0.2], [1.7, 0.3], [1.7, 0.3], [1.7, 0.3], [1.7, 0.3], [1.7, 0.3], [1.6, 0.3], [1.6, 0.3], [1.6, 0.3], [1.6, 0.4], [1.6, 0.4], [1.6, 0.4], [1.5, 0.4], [1.5, 0.4], [1.5, 0.4], [1.5, 0.4], [1.5, 0.4], [1.4, 0.4], [1.4, 0.4], [1.4, 0.4], [1.4, 0.4], [1.4, 0.4], [1.3, 0.5], [1.3, 0.5], [1.3, 0.5], [1.3, 0.5], [1.2, 0.5], [1.2, 0.5], [1.2, 0.5], [1.2, 0.5], [1.2, 0.5], [1.1, 0.5], [1.1, 0.5], [1.1, 0.5], [1.1, 0.5], [1.1, 0.5], [1, 0.5], [1, 0.5], [1, 0.5], [1, 0.5], [0.9, 0.5], [0.9, 0.5], [0.9, 0.5], [0.9, 0.5], [0.9, 0.5], [0.8, 0.5], [0.8, 0.5], [0.8, 0.5], [0.8, 0.5], [0.8, 0.5], [0.7, 0.5], [0.7, 0.5], [0.7, 0.5], [0.7, 0.5], [0.6, 0.4], [0.6, 0.4], [0.6, 0.4], [0.6, 0.4], [0.6, 0.4], [0.5, 0.4], [0.5, 0.4], [0.5, 0.4], [0.5, 0.4], [0.5, 0.4], [0.4, 0.4], [0.4, 0.4], [0.4, 0.4], [0.4, 0.3], [0.4, 0.3], [0.4, 0.3], [0.3, 0.3], [0.3, 0.3], [0.3, 0.3], [0.3, 0.3], [0.3, 0.3], [0.2, 0.2], [0.2, 0.2], [0.2, 0.2], [0.2, 0.2], [0.2, 0.2], [0.2, 0.2], [0.1, 0.2], [0.1, 0.1], [0.1, 0.1], [0.1, 0.1], [0.1, 0.1], [0.1, 0.1], [0.1, 0.1], [0, 0.1], [0, 0], [0, 0], [0, 0]]] }" ) );
|
|
res = exportPolygon.asJSON( 1 );
|
|
QCOMPARE( res, expectedSimpleJson );
|
|
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 0.1, 0, 11, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 0.2, 0, 12, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0.1, 0.05, 13, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) );
|
|
exportPolygon.addInteriorRing( ring );
|
|
|
|
QString expectedJson( QStringLiteral( "{\"type\": \"Polygon\", \"coordinates\": [[ [0, 0], [1, 0], [2, 0], [2, 0], [2, 0], [2, 0.1], [1.9, 0.1], [1.9, 0.1], [1.9, 0.1], [1.9, 0.1], [1.9, 0.1], [1.9, 0.1], [1.9, 0.2], [1.8, 0.2], [1.8, 0.2], [1.8, 0.2], [1.8, 0.2], [1.8, 0.2], [1.8, 0.2], [1.7, 0.3], [1.7, 0.3], [1.7, 0.3], [1.7, 0.3], [1.7, 0.3], [1.6, 0.3], [1.6, 0.3], [1.6, 0.3], [1.6, 0.4], [1.6, 0.4], [1.6, 0.4], [1.5, 0.4], [1.5, 0.4], [1.5, 0.4], [1.5, 0.4], [1.5, 0.4], [1.4, 0.4], [1.4, 0.4], [1.4, 0.4], [1.4, 0.4], [1.4, 0.4], [1.3, 0.5], [1.3, 0.5], [1.3, 0.5], [1.3, 0.5], [1.2, 0.5], [1.2, 0.5], [1.2, 0.5], [1.2, 0.5], [1.2, 0.5], [1.1, 0.5], [1.1, 0.5], [1.1, 0.5], [1.1, 0.5], [1.1, 0.5], [1, 0.5], [1, 0.5], [1, 0.5], [1, 0.5], [0.9, 0.5], [0.9, 0.5], [0.9, 0.5], [0.9, 0.5], [0.9, 0.5], [0.8, 0.5], [0.8, 0.5], [0.8, 0.5], [0.8, 0.5], [0.8, 0.5], [0.7, 0.5], [0.7, 0.5], [0.7, 0.5], [0.7, 0.5], [0.6, 0.4], [0.6, 0.4], [0.6, 0.4], [0.6, 0.4], [0.6, 0.4], [0.5, 0.4], [0.5, 0.4], [0.5, 0.4], [0.5, 0.4], [0.5, 0.4], [0.4, 0.4], [0.4, 0.4], [0.4, 0.4], [0.4, 0.3], [0.4, 0.3], [0.4, 0.3], [0.3, 0.3], [0.3, 0.3], [0.3, 0.3], [0.3, 0.3], [0.3, 0.3], [0.2, 0.2], [0.2, 0.2], [0.2, 0.2], [0.2, 0.2], [0.2, 0.2], [0.2, 0.2], [0.1, 0.2], [0.1, 0.1], [0.1, 0.1], [0.1, 0.1], [0.1, 0.1], [0.1, 0.1], [0.1, 0.1], [0, 0.1], [0, 0], [0, 0], [0, 0]], [ [0, 0], [0.1, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.2, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0.1, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]] }" ) );
|
|
res = exportPolygon.asJSON( 1 );
|
|
QCOMPARE( res, expectedJson );
|
|
|
|
|
|
QgsCurvePolygon exportPolygonFloat;
|
|
ext = new QgsCircularString();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 1 / 3.0, 0, 11, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 2 / 3.0, 0, 12, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1 / 3.0, 0.5, 13, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) );
|
|
exportPolygonFloat.setExteriorRing( ext );
|
|
ring = new QgsCircularString();
|
|
ring->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 0.1 / 3.0, 0, 11, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 0.2 / 3.0, 0, 12, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0.1 / 3.0, 0.05 / 3.0, 13, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 10, 1 ) );
|
|
exportPolygonFloat.addInteriorRing( ring );
|
|
|
|
QString expectedJsonPrec3( QStringLiteral( "{\"type\": \"Polygon\", \"coordinates\": [[ [0, 0], [0.333, 0], [0.667, 0], [0.669, 0.006], [0.671, 0.012], [0.673, 0.018], [0.676, 0.024], [0.677, 0.029], [0.679, 0.035], [0.681, 0.042], [0.683, 0.048], [0.684, 0.054], [0.686, 0.06], [0.687, 0.066], [0.688, 0.072], [0.689, 0.078], [0.69, 0.084], [0.691, 0.091], [0.692, 0.097], [0.693, 0.103], [0.693, 0.109], [0.694, 0.116], [0.694, 0.122], [0.694, 0.128], [0.694, 0.135], [0.694, 0.141], [0.694, 0.147], [0.694, 0.153], [0.694, 0.16], [0.693, 0.166], [0.693, 0.172], [0.692, 0.178], [0.692, 0.185], [0.691, 0.191], [0.69, 0.197], [0.689, 0.203], [0.687, 0.209], [0.686, 0.216], [0.685, 0.222], [0.683, 0.228], [0.682, 0.234], [0.68, 0.24], [0.678, 0.246], [0.676, 0.252], [0.674, 0.258], [0.672, 0.264], [0.67, 0.27], [0.668, 0.275], [0.665, 0.281], [0.663, 0.287], [0.66, 0.293], [0.657, 0.298], [0.654, 0.304], [0.652, 0.31], [0.649, 0.315], [0.645, 0.321], [0.642, 0.326], [0.639, 0.331], [0.636, 0.337], [0.632, 0.342], [0.628, 0.347], [0.625, 0.352], [0.621, 0.357], [0.617, 0.362], [0.613, 0.367], [0.609, 0.372], [0.605, 0.377], [0.601, 0.381], [0.597, 0.386], [0.592, 0.39], [0.588, 0.395], [0.584, 0.399], [0.579, 0.404], [0.574, 0.408], [0.57, 0.412], [0.565, 0.416], [0.56, 0.42], [0.555, 0.424], [0.55, 0.428], [0.545, 0.431], [0.54, 0.435], [0.535, 0.439], [0.529, 0.442], [0.524, 0.445], [0.519, 0.449], [0.513, 0.452], [0.508, 0.455], [0.502, 0.458], [0.497, 0.461], [0.491, 0.464], [0.485, 0.466], [0.48, 0.469], [0.474, 0.471], [0.468, 0.474], [0.462, 0.476], [0.456, 0.478], [0.451, 0.48], [0.445, 0.482], [0.439, 0.484], [0.433, 0.486], [0.426, 0.488], [0.42, 0.489], [0.414, 0.491], [0.408, 0.492], [0.402, 0.493], [0.396, 0.495], [0.39, 0.496], [0.383, 0.497], [0.377, 0.497], [0.371, 0.498], [0.365, 0.499], [0.358, 0.499], [0.352, 0.5], [0.346, 0.5], [0.34, 0.5], [0.333, 0.5], [0.327, 0.5], [0.321, 0.5], [0.314, 0.5], [0.308, 0.499], [0.302, 0.499], [0.296, 0.498], [0.289, 0.497], [0.283, 0.497], [0.277, 0.496], [0.271, 0.495], [0.265, 0.493], [0.259, 0.492], [0.252, 0.491], [0.246, 0.489], [0.24, 0.488], [0.234, 0.486], [0.228, 0.484], [0.222, 0.482], [0.216, 0.48], [0.21, 0.478], [0.204, 0.476], [0.198, 0.474], [0.193, 0.471], [0.187, 0.469], [0.181, 0.466], [0.176, 0.464], [0.17, 0.461], [0.164, 0.458], [0.159, 0.455], [0.153, 0.452], [0.148, 0.449], [0.143, 0.445], [0.137, 0.442], [0.132, 0.439], [0.127, 0.435], [0.122, 0.431], [0.117, 0.428], [0.112, 0.424], [0.107, 0.42], [0.102, 0.416], [0.097, 0.412], [0.092, 0.408], [0.088, 0.404], [0.083, 0.399], [0.079, 0.395], [0.074, 0.39], [0.07, 0.386], [0.066, 0.381], [0.061, 0.377], [0.057, 0.372], [0.053, 0.367], [0.049, 0.362], [0.046, 0.357], [0.042, 0.352], [0.038, 0.347], [0.035, 0.342], [0.031, 0.337], [0.028, 0.331], [0.024, 0.326], [0.021, 0.321], [0.018, 0.315], [0.015, 0.31], [0.012, 0.304], [0.009, 0.298], [0.007, 0.293], [0.004, 0.287], [0.001, 0.281], [-0.001, 0.275], [-0.003, 0.27], [-0.005, 0.264], [-0.008, 0.258], [-0.01, 0.252], [-0.012, 0.246], [-0.013, 0.24], [-0.015, 0.234], [-0.017, 0.228], [-0.018, 0.222], [-0.02, 0.216], [-0.021, 0.209], [-0.022, 0.203], [-0.023, 0.197], [-0.024, 0.191], [-0.025, 0.185], [-0.026, 0.178], [-0.026, 0.172], [-0.027, 0.166], [-0.027, 0.16], [-0.027, 0.153], [-0.028, 0.147], [-0.028, 0.141], [-0.028, 0.135], [-0.028, 0.128], [-0.027, 0.122], [-0.027, 0.116], [-0.027, 0.109], [-0.026, 0.103], [-0.025, 0.097], [-0.025, 0.091], [-0.024, 0.084], [-0.023, 0.078], [-0.022, 0.072], [-0.02, 0.066], [-0.019, 0.06], [-0.018, 0.054], [-0.016, 0.048], [-0.014, 0.042], [-0.013, 0.035], [-0.011, 0.029], [-0.009, 0.024], [-0.007, 0.018], [-0.005, 0.012], [-0.002, 0.006], [0, 0]], [ [0, 0], [0.033, 0], [0.067, 0], [0.066, 0.001], [0.066, 0.001], [0.065, 0.002], [0.065, 0.002], [0.064, 0.003], [0.064, 0.003], [0.063, 0.004], [0.063, 0.004], [0.062, 0.005], [0.062, 0.005], [0.061, 0.006], [0.061, 0.006], [0.06, 0.007], [0.06, 0.007], [0.059, 0.008], [0.059, 0.008], [0.058, 0.009], [0.057, 0.009], [0.057, 0.009], [0.056, 0.01], [0.056, 0.01], [0.055, 0.011], [0.054, 0.011], [0.054, 0.011], [0.053, 0.012], [0.052, 0.012], [0.052, 0.012], [0.051, 0.013], [0.051, 0.013], [0.05, 0.013], [0.049, 0.014], [0.049, 0.014], [0.048, 0.014], [0.047, 0.014], [0.046, 0.015], [0.046, 0.015], [0.045, 0.015], [0.044, 0.015], [0.044, 0.015], [0.043, 0.016], [0.042, 0.016], [0.042, 0.016], [0.041, 0.016], [0.04, 0.016], [0.039, 0.016], [0.039, 0.016], [0.038, 0.016], [0.037, 0.016], [0.037, 0.017], [0.036, 0.017], [0.035, 0.017], [0.034, 0.017], [0.034, 0.017], [0.033, 0.017], [0.032, 0.017], [0.032, 0.017], [0.031, 0.017], [0.03, 0.017], [0.029, 0.016], [0.029, 0.016], [0.028, 0.016], [0.027, 0.016], [0.027, 0.016], [0.026, 0.016], [0.025, 0.016], [0.024, 0.016], [0.024, 0.016], [0.023, 0.015], [0.022, 0.015], [0.022, 0.015], [0.021, 0.015], [0.02, 0.015], [0.02, 0.014], [0.019, 0.014], [0.018, 0.014], [0.017, 0.014], [0.017, 0.013], [0.016, 0.013], [0.016, 0.013], [0.015, 0.012], [0.014, 0.012], [0.014, 0.012], [0.013, 0.011], [0.012, 0.011], [0.012, 0.011], [0.011, 0.01], [0.01, 0.01], [0.01, 0.009], [0.009, 0.009], [0.009, 0.009], [0.008, 0.008], [0.008, 0.008], [0.007, 0.007], [0.006, 0.007], [0.006, 0.006], [0.005, 0.006], [0.005, 0.005], [0.004, 0.005], [0.004, 0.004], [0.003, 0.004], [0.003, 0.003], [0.002, 0.003], [0.002, 0.002], [0.001, 0.002], [0.001, 0.001], [0, 0.001], [0, 0]]] }" ) );
|
|
res = exportPolygonFloat.asJSON( 3 );
|
|
QCOMPARE( exportPolygonFloat.asJSON( 3 ), expectedJsonPrec3 );
|
|
|
|
// as GML2
|
|
QString expectedGML2( QStringLiteral( "<Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0,0 1,0 2,0 1.98685,0.01722 1.97341,0.03421 1.95967,0.05096 1.94564,0.06747 1.93133,0.08374 1.91674,0.09976 1.90188,0.11552 1.88674,0.13102 1.87134,0.14625 1.85567,0.16122 1.83975,0.17592 1.82358,0.19033 1.80716,0.20446 1.79049,0.21831 1.77359,0.23186 1.75646,0.24512 1.7391,0.25809 1.72151,0.27074 1.70371,0.2831 1.6857,0.29514 1.66748,0.30687 1.64907,0.31828 1.63045,0.32936 1.61165,0.34013 1.59267,0.35057 1.5735,0.36067 1.55417,0.37045 1.53466,0.37988 1.515,0.38898 1.49518,0.39773 1.47522,0.40614 1.45511,0.41421 1.43486,0.42192 1.41448,0.42928 1.39398,0.43629 1.37336,0.44294 1.35263,0.44923 1.33179,0.45516 1.31086,0.46073 1.28983,0.46594 1.26871,0.47078 1.24751,0.47525 1.22624,0.47936 1.2049,0.48309 1.18349,0.48646 1.16204,0.48945 1.14053,0.49208 1.11898,0.49432 1.0974,0.4962 1.07578,0.4977 1.05415,0.49883 1.0325,0.49958 1.01083,0.49995 0.98917,0.49995 0.9675,0.49958 0.94585,0.49883 0.92422,0.4977 0.9026,0.4962 0.88102,0.49432 0.85947,0.49208 0.83796,0.48945 0.81651,0.48646 0.7951,0.48309 0.77376,0.47936 0.75249,0.47525 0.73129,0.47078 0.71017,0.46594 0.68914,0.46073 0.66821,0.45516 0.64737,0.44923 0.62664,0.44294 0.60602,0.43629 0.58552,0.42928 0.56514,0.42192 0.54489,0.41421 0.52478,0.40614 0.50482,0.39773 0.485,0.38898 0.46534,0.37988 0.44583,0.37045 0.4265,0.36067 0.40733,0.35057 0.38835,0.34013 0.36955,0.32936 0.35093,0.31828 0.33252,0.30687 0.3143,0.29514 0.29629,0.2831 0.27849,0.27074 0.2609,0.25809 0.24354,0.24512 0.22641,0.23186 0.20951,0.21831 0.19284,0.20446 0.17642,0.19033 0.16025,0.17592 0.14433,0.16122 0.12866,0.14625 0.11326,0.13102 0.09812,0.11552 0.08326,0.09976 0.06867,0.08374 0.05436,0.06747 0.04033,0.05096 0.02659,0.03421 0.01315,0.01722 0,0</coordinates></LinearRing></outerBoundaryIs><innerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0,0 0.1,0 0.2,0 0.19869,0.00172 0.19734,0.00342 0.19597,0.0051 0.19456,0.00675 0.19313,0.00837 0.19167,0.00998 0.19019,0.01155 0.18867,0.0131 0.18713,0.01463 0.18557,0.01612 0.18398,0.01759 0.18236,0.01903 0.18072,0.02045 0.17905,0.02183 0.17736,0.02319 0.17565,0.02451 0.17391,0.02581 0.17215,0.02707 0.17037,0.02831 0.16857,0.02951 0.16675,0.03069 0.16491,0.03183 0.16305,0.03294 0.16117,0.03401 0.15927,0.03506 0.15735,0.03607 0.15542,0.03704 0.15347,0.03799 0.1515,0.0389 0.14952,0.03977 0.14752,0.04061 0.14551,0.04142 0.14349,0.04219 0.14145,0.04293 0.1394,0.04363 0.13734,0.04429 0.13526,0.04492 0.13318,0.04552 0.13109,0.04607 0.12898,0.04659 0.12687,0.04708 0.12475,0.04753 0.12262,0.04794 0.12049,0.04831 0.11835,0.04865 0.1162,0.04895 0.11405,0.04921 0.1119,0.04943 0.10974,0.04962 0.10758,0.04977 0.10541,0.04988 0.10325,0.04996 0.10108,0.05 0.09892,0.05 0.09675,0.04996 0.09459,0.04988 0.09242,0.04977 0.09026,0.04962 0.0881,0.04943 0.08595,0.04921 0.0838,0.04895 0.08165,0.04865 0.07951,0.04831 0.07738,0.04794 0.07525,0.04753 0.07313,0.04708 0.07102,0.04659 0.06891,0.04607 0.06682,0.04552 0.06474,0.04492 0.06266,0.04429 0.0606,0.04363 0.05855,0.04293 0.05651,0.04219 0.05449,0.04142 0.05248,0.04061 0.05048,0.03977 0.0485,0.0389 0.04653,0.03799 0.04458,0.03704 0.04265,0.03607 0.04073,0.03506 0.03883,0.03401 0.03695,0.03294 0.03509,0.03183 0.03325,0.03069 0.03143,0.02951 0.02963,0.02831 0.02785,0.02707 0.02609,0.02581 0.02435,0.02451 0.02264,0.02319 0.02095,0.02183 0.01928,0.02045 0.01764,0.01903 0.01602,0.01759 0.01443,0.01612 0.01287,0.01463 0.01133,0.0131 0.00981,0.01155 0.00833,0.00998 0.00687,0.00837 0.00544,0.00675 0.00403,0.0051 0.00266,0.00342 0.00131,0.00172 0,0</coordinates></LinearRing></innerBoundaryIs></Polygon>" ) );
|
|
res = elemToString( exportPolygon.asGML2( doc, 5 ) );
|
|
QGSCOMPAREGML( res, expectedGML2 );
|
|
|
|
QString expectedGML2prec2( QStringLiteral( "<Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0,0 1,0 2,0 1.99,0.02 1.97,0.03 1.96,0.05 1.95,0.07 1.93,0.08 1.92,0.1 1.9,0.12 1.89,0.13 1.87,0.15 1.86,0.16 1.84,0.18 1.82,0.19 1.81,0.2 1.79,0.22 1.77,0.23 1.76,0.25 1.74,0.26 1.72,0.27 1.7,0.28 1.69,0.3 1.67,0.31 1.65,0.32 1.63,0.33 1.61,0.34 1.59,0.35 1.57,0.36 1.55,0.37 1.53,0.38 1.52,0.39 1.5,0.4 1.48,0.41 1.46,0.41 1.43,0.42 1.41,0.43 1.39,0.44 1.37,0.44 1.35,0.45 1.33,0.46 1.31,0.46 1.29,0.47 1.27,0.47 1.25,0.48 1.23,0.48 1.2,0.48 1.18,0.49 1.16,0.49 1.14,0.49 1.12,0.49 1.1,0.5 1.08,0.5 1.05,0.5 1.03,0.5 1.01,0.5 0.99,0.5 0.97,0.5 0.95,0.5 0.92,0.5 0.9,0.5 0.88,0.49 0.86,0.49 0.84,0.49 0.82,0.49 0.8,0.48 0.77,0.48 0.75,0.48 0.73,0.47 0.71,0.47 0.69,0.46 0.67,0.46 0.65,0.45 0.63,0.44 0.61,0.44 0.59,0.43 0.57,0.42 0.54,0.41 0.52,0.41 0.5,0.4 0.48,0.39 0.47,0.38 0.45,0.37 0.43,0.36 0.41,0.35 0.39,0.34 0.37,0.33 0.35,0.32 0.33,0.31 0.31,0.3 0.3,0.28 0.28,0.27 0.26,0.26 0.24,0.25 0.23,0.23 0.21,0.22 0.19,0.2 0.18,0.19 0.16,0.18 0.14,0.16 0.13,0.15 0.11,0.13 0.1,0.12 0.08,0.1 0.07,0.08 0.05,0.07 0.04,0.05 0.03,0.03 0.01,0.02 0,0</coordinates></LinearRing></outerBoundaryIs><innerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0,0 0.1,0 0.2,0 0.2,0 0.2,0 0.2,0.01 0.19,0.01 0.19,0.01 0.19,0.01 0.19,0.01 0.19,0.01 0.19,0.01 0.19,0.02 0.18,0.02 0.18,0.02 0.18,0.02 0.18,0.02 0.18,0.02 0.18,0.02 0.17,0.03 0.17,0.03 0.17,0.03 0.17,0.03 0.17,0.03 0.16,0.03 0.16,0.03 0.16,0.03 0.16,0.04 0.16,0.04 0.16,0.04 0.15,0.04 0.15,0.04 0.15,0.04 0.15,0.04 0.15,0.04 0.14,0.04 0.14,0.04 0.14,0.04 0.14,0.04 0.14,0.04 0.13,0.05 0.13,0.05 0.13,0.05 0.13,0.05 0.12,0.05 0.12,0.05 0.12,0.05 0.12,0.05 0.12,0.05 0.11,0.05 0.11,0.05 0.11,0.05 0.11,0.05 0.11,0.05 0.1,0.05 0.1,0.05 0.1,0.05 0.1,0.05 0.09,0.05 0.09,0.05 0.09,0.05 0.09,0.05 0.09,0.05 0.08,0.05 0.08,0.05 0.08,0.05 0.08,0.05 0.08,0.05 0.07,0.05 0.07,0.05 0.07,0.05 0.07,0.05 0.06,0.04 0.06,0.04 0.06,0.04 0.06,0.04 0.06,0.04 0.05,0.04 0.05,0.04 0.05,0.04 0.05,0.04 0.05,0.04 0.04,0.04 0.04,0.04 0.04,0.04 0.04,0.03 0.04,0.03 0.04,0.03 0.03,0.03 0.03,0.03 0.03,0.03 0.03,0.03 0.03,0.03 0.02,0.02 0.02,0.02 0.02,0.02 0.02,0.02 0.02,0.02 0.02,0.02 0.01,0.02 0.01,0.01 0.01,0.01 0.01,0.01 0.01,0.01 0.01,0.01 0.01,0.01 0,0.01 0,0 0,0 0,0</coordinates></LinearRing></innerBoundaryIs></Polygon>" ) );
|
|
res = elemToString( exportPolygon.asGML2( doc, 2 ) );
|
|
QGSCOMPAREGML( res, expectedGML2prec2 );
|
|
|
|
//as GML3
|
|
QString expectedGML3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 1 0 11 2 0 12 1 0.5 13 0 0 10</posList></ArcString></segments></Curve></exterior><interior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 0.10000000000000001 0 11 0.20000000000000001 0 12 0.10000000000000001 0.05 13 0 0 10</posList></ArcString></segments></Curve></interior></Polygon>" ) );
|
|
res = elemToString( exportPolygon.asGML3( doc ) );
|
|
QCOMPARE( res, expectedGML3 );
|
|
|
|
QString expectedGML3prec3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 1 0 11 2 0 12 1 0.5 13 0 0 10</posList></ArcString></segments></Curve></exterior><interior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 0.1 0 11 0.2 0 12 0.1 0.05 13 0 0 10</posList></ArcString></segments></Curve></interior></Polygon>" ) );
|
|
res = elemToString( exportPolygon.asGML3( doc, 3 ) );
|
|
QCOMPARE( res, expectedGML3prec3 );
|
|
|
|
//removing the fourth to last vertex removes the whole ring
|
|
QgsCurvePolygon p20;
|
|
QgsCircularString *p20ExteriorRing = new QgsCircularString();
|
|
p20ExteriorRing->setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
p20.setExteriorRing( p20ExteriorRing );
|
|
QVERIFY( p20.exteriorRing() );
|
|
p20.deleteVertex( QgsVertexId( 0, 0, 2 ) );
|
|
QVERIFY( !p20.exteriorRing() );
|
|
|
|
//boundary
|
|
QgsCircularString boundary1;
|
|
boundary1.setPoints( QgsPointSequence() << QgsPoint( 0, 0, 1 ) << QgsPoint( 1, 0, 2 ) << QgsPoint( 2, 0, 3 )
|
|
<< QgsPoint( 1, 0.5, 4 ) << QgsPoint( 0, 0, 1 ) );
|
|
QgsCurvePolygon boundaryPolygon;
|
|
QVERIFY( !boundaryPolygon.boundary() );
|
|
|
|
boundaryPolygon.setExteriorRing( boundary1.clone() );
|
|
QgsAbstractGeometry *boundary = boundaryPolygon.boundary();
|
|
QgsCircularString *lineBoundary = dynamic_cast< QgsCircularString * >( boundary );
|
|
QVERIFY( lineBoundary );
|
|
QCOMPARE( lineBoundary->numPoints(), 5 );
|
|
QCOMPARE( lineBoundary->xAt( 0 ), 0.0 );
|
|
QCOMPARE( lineBoundary->xAt( 1 ), 1.0 );
|
|
QCOMPARE( lineBoundary->xAt( 2 ), 2.0 );
|
|
QCOMPARE( lineBoundary->xAt( 3 ), 1.0 );
|
|
QCOMPARE( lineBoundary->xAt( 4 ), 0.0 );
|
|
QCOMPARE( lineBoundary->yAt( 0 ), 0.0 );
|
|
QCOMPARE( lineBoundary->yAt( 1 ), 0.0 );
|
|
QCOMPARE( lineBoundary->yAt( 2 ), 0.0 );
|
|
QCOMPARE( lineBoundary->yAt( 3 ), 0.5 );
|
|
QCOMPARE( lineBoundary->yAt( 4 ), 0.0 );
|
|
delete boundary;
|
|
|
|
// add interior rings
|
|
QgsCircularString boundaryRing1;
|
|
boundaryRing1.setPoints( QList<QgsPoint>() << QgsPoint( 0.1, 0.1 ) << QgsPoint( 0.2, 0.1 ) << QgsPoint( 0.2, 0.2 ) );
|
|
QgsCircularString boundaryRing2;
|
|
boundaryRing2.setPoints( QList<QgsPoint>() << QgsPoint( 0.8, 0.8 ) << QgsPoint( 0.9, 0.8 ) << QgsPoint( 0.9, 0.9 ) );
|
|
boundaryPolygon.setInteriorRings( QList< QgsCurve * >() << boundaryRing1.clone() << boundaryRing2.clone() );
|
|
boundary = boundaryPolygon.boundary();
|
|
QgsMultiCurve *multiLineBoundary = dynamic_cast< QgsMultiCurve * >( boundary );
|
|
QVERIFY( multiLineBoundary );
|
|
QCOMPARE( multiLineBoundary->numGeometries(), 3 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 0 ) )->numPoints(), 5 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 0 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 1 ), 1.0 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 2 ), 2.0 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 3 ), 1.0 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 4 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 0 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 1 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 2 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 3 ), 0.5 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 4 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 1 ) )->numPoints(), 3 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 1 ) )->xAt( 0 ), 0.1 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 1 ) )->xAt( 1 ), 0.2 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 1 ) )->xAt( 2 ), 0.2 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 1 ) )->yAt( 0 ), 0.1 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 1 ) )->yAt( 1 ), 0.1 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 1 ) )->yAt( 2 ), 0.2 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 2 ) )->numPoints(), 3 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 2 ) )->xAt( 0 ), 0.8 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 2 ) )->xAt( 1 ), 0.9 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 2 ) )->xAt( 2 ), 0.9 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 2 ) )->yAt( 0 ), 0.8 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 2 ) )->yAt( 1 ), 0.8 );
|
|
QCOMPARE( dynamic_cast< QgsCircularString * >( multiLineBoundary->geometryN( 2 ) )->yAt( 2 ), 0.9 );
|
|
boundaryPolygon.setInteriorRings( QList< QgsCurve * >() );
|
|
delete boundary;
|
|
|
|
//test boundary with z
|
|
boundary1.setPoints( QList<QgsPoint>() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 10 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 0, 15 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1, 1, 20 ) );
|
|
boundaryPolygon.setExteriorRing( boundary1.clone() );
|
|
boundary = boundaryPolygon.boundary();
|
|
lineBoundary = dynamic_cast< QgsCircularString * >( boundary );
|
|
QVERIFY( lineBoundary );
|
|
QCOMPARE( lineBoundary->numPoints(), 3 );
|
|
QCOMPARE( lineBoundary->wkbType(), QgsWkbTypes::CircularStringZ );
|
|
QCOMPARE( lineBoundary->pointN( 0 ).z(), 10.0 );
|
|
QCOMPARE( lineBoundary->pointN( 1 ).z(), 15.0 );
|
|
QCOMPARE( lineBoundary->pointN( 2 ).z(), 20.0 );
|
|
delete boundary;
|
|
|
|
// remove interior rings
|
|
QgsCircularString removeRingsExt;
|
|
removeRingsExt.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
QgsCurvePolygon removeRings1;
|
|
removeRings1.removeInteriorRings();
|
|
|
|
removeRings1.setExteriorRing( boundary1.clone() );
|
|
removeRings1.removeInteriorRings();
|
|
QCOMPARE( removeRings1.numInteriorRings(), 0 );
|
|
|
|
// add interior rings
|
|
QgsCircularString removeRingsRing1;
|
|
removeRingsRing1.setPoints( QgsPointSequence() << QgsPoint( 0, 0, 1 ) << QgsPoint( 0.1, 1, 2 ) << QgsPoint( 0, 2, 3 )
|
|
<< QgsPoint( -0.1, 1.2, 4 ) << QgsPoint( 0, 0, 1 ) );
|
|
QgsCircularString removeRingsRing2;
|
|
removeRingsRing2.setPoints( QgsPointSequence() << QgsPoint( 0, 0, 1 ) << QgsPoint( 0.01, 0.1, 2 ) << QgsPoint( 0, 0.2, 3 )
|
|
<< QgsPoint( -0.01, 0.12, 4 ) << QgsPoint( 0, 0, 1 ) );
|
|
removeRings1.setInteriorRings( QList< QgsCurve * >() << removeRingsRing1.clone() << removeRingsRing2.clone() );
|
|
|
|
// remove ring with size filter
|
|
removeRings1.removeInteriorRings( 0.05 );
|
|
QCOMPARE( removeRings1.numInteriorRings(), 1 );
|
|
|
|
// remove ring with no size filter
|
|
removeRings1.removeInteriorRings();
|
|
QCOMPARE( removeRings1.numInteriorRings(), 0 );
|
|
|
|
// cast
|
|
QVERIFY( !QgsCurvePolygon().cast( nullptr ) );
|
|
QgsCurvePolygon pCast;
|
|
QVERIFY( QgsCurvePolygon().cast( &pCast ) );
|
|
QgsCurvePolygon pCast2;
|
|
pCast2.fromWkt( QStringLiteral( "CurvePolygonZ((0 0 0, 0 1 1, 1 0 2, 0 0 0))" ) );
|
|
QVERIFY( QgsCurvePolygon().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "CurvePolygonM((0 0 1, 0 1 2, 1 0 3, 0 0 1))" ) );
|
|
QVERIFY( QgsCurvePolygon().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "CurvePolygonZM((0 0 0 1, 0 1 1 2, 1 0 2 3, 0 0 0 1))" ) );
|
|
QVERIFY( QgsCurvePolygon().cast( &pCast2 ) );
|
|
|
|
// draw - most tests are in test_qgsgeometry.py
|
|
QgsCurvePolygon empty;
|
|
QPainter p;
|
|
empty.draw( p ); //no crash!
|
|
|
|
|
|
// closestSegment
|
|
QgsPoint pt;
|
|
QgsVertexId v;
|
|
bool leftOf = false;
|
|
( void )empty.closestSegment( QgsPoint( 1, 2 ), pt, v ); // empty curve, just want no crash
|
|
|
|
QgsCurvePolygon cp12;
|
|
QgsLineString cp12ls;
|
|
cp12ls.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 7, 12 ) << QgsPoint( 5, 15 ) << QgsPoint( 5, 10 ) );
|
|
cp12.setExteriorRing( cp12ls.clone() );
|
|
QGSCOMPARENEAR( cp12.closestSegment( QgsPoint( 4, 11 ), pt, v, &leftOf ), 1.0, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 11, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( cp12.closestSegment( QgsPoint( 8, 11 ), pt, v, &leftOf ), 2.0, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 7, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 12, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( cp12.closestSegment( QgsPoint( 6, 11.5 ), pt, v, &leftOf ), 0.125000, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 6.25, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 11.25, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( cp12.closestSegment( QgsPoint( 7, 16 ), pt, v, &leftOf ), 4.923077, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5.153846, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 14.769231, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( cp12.closestSegment( QgsPoint( 5.5, 13.5 ), pt, v, &leftOf ), 0.173077, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5.846154, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 13.730769, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, true );
|
|
// point directly on segment
|
|
QCOMPARE( cp12.closestSegment( QgsPoint( 5, 15 ), pt, v, &leftOf ), 0.0 );
|
|
QCOMPARE( pt, QgsPoint( 5, 15 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
|
|
// with interior ring
|
|
cp12ls.setPoints( QgsPointSequence() << QgsPoint( 6, 11.5 ) << QgsPoint( 6.5, 12 ) << QgsPoint( 6, 13 ) << QgsPoint( 6, 11.5 ) );
|
|
cp12.addInteriorRing( cp12ls.clone() );
|
|
QGSCOMPARENEAR( cp12.closestSegment( QgsPoint( 4, 11 ), pt, v, &leftOf ), 1.0, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 11, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( cp12.closestSegment( QgsPoint( 8, 11 ), pt, v, &leftOf ), 2.0, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 7, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 12, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( cp12.closestSegment( QgsPoint( 6, 11.4 ), pt, v, &leftOf ), 0.01, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 6.0, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 11.5, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( cp12.closestSegment( QgsPoint( 7, 16 ), pt, v, &leftOf ), 4.923077, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5.153846, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 14.769231, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( cp12.closestSegment( QgsPoint( 5.5, 13.5 ), pt, v, &leftOf ), 0.173077, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5.846154, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 13.730769, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, true );
|
|
// point directly on segment
|
|
QCOMPARE( cp12.closestSegment( QgsPoint( 6, 13 ), pt, v, &leftOf ), 0.0 );
|
|
QCOMPARE( pt, QgsPoint( 6, 13 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 2 ) );
|
|
|
|
//nextVertex
|
|
QgsCurvePolygon cp13;
|
|
QVERIFY( !cp13.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 0, -2 );
|
|
QVERIFY( !cp13.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 0, 10 );
|
|
QVERIFY( !cp13.nextVertex( v, pt ) );
|
|
QgsLineString lp22;
|
|
lp22.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 12 ) << QgsPoint( 1, 2 ) );
|
|
cp13.setExteriorRing( lp22.clone() );
|
|
v = QgsVertexId( 0, 0, 4 ); //out of range
|
|
QVERIFY( !cp13.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 0, -5 );
|
|
QVERIFY( cp13.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( cp13.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( pt, QgsPoint( 1, 2 ) );
|
|
QVERIFY( cp13.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( pt, QgsPoint( 11, 12 ) );
|
|
QVERIFY( cp13.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( pt, QgsPoint( 1, 12 ) );
|
|
QVERIFY( cp13.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( pt, QgsPoint( 1, 2 ) );
|
|
v = QgsVertexId( 0, 1, 0 );
|
|
QVERIFY( !cp13.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 1, 0, 0 );
|
|
QVERIFY( cp13.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 1, 0, 1 ) ); //test that part number is maintained
|
|
QCOMPARE( pt, QgsPoint( 11, 12 ) );
|
|
// add interior ring
|
|
lp22.setPoints( QgsPointSequence() << QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 11, 22 ) << QgsPoint( 11, 12 ) );
|
|
cp13.addInteriorRing( lp22.clone() );
|
|
v = QgsVertexId( 0, 1, 4 ); //out of range
|
|
QVERIFY( !cp13.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 1, -5 );
|
|
QVERIFY( cp13.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 1, -1 );
|
|
QVERIFY( cp13.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 0 ) );
|
|
QCOMPARE( pt, QgsPoint( 11, 12 ) );
|
|
QVERIFY( cp13.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 1 ) );
|
|
QCOMPARE( pt, QgsPoint( 21, 22 ) );
|
|
QVERIFY( cp13.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 2 ) );
|
|
QCOMPARE( pt, QgsPoint( 11, 22 ) );
|
|
QVERIFY( cp13.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 1, 3 ) );
|
|
QCOMPARE( pt, QgsPoint( 11, 12 ) );
|
|
v = QgsVertexId( 0, 2, 0 );
|
|
QVERIFY( !cp13.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 1, 1, 0 );
|
|
QVERIFY( cp13.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 1, 1, 1 ) ); //test that part number is maintained
|
|
QCOMPARE( pt, QgsPoint( 21, 22 ) );
|
|
|
|
// dropZValue
|
|
QgsCurvePolygon p23;
|
|
p23.dropZValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
QgsLineString lp23;
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 12 ) << QgsPoint( 1, 2 ) );
|
|
p23.setExteriorRing( lp23.clone() );
|
|
p23.addInteriorRing( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
p23.dropZValue(); // not z
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
QCOMPARE( p23.exteriorRing()->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.exteriorRing() )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( p23.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
// with z
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2, 3 ) << QgsPoint( 11, 12, 13 ) << QgsPoint( 1, 12, 23 ) << QgsPoint( 1, 2, 3 ) );
|
|
p23.clear();
|
|
p23.setExteriorRing( lp23.clone() );
|
|
p23.addInteriorRing( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygonZ );
|
|
p23.dropZValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
QCOMPARE( p23.exteriorRing()->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.exteriorRing() )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( p23.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
// with zm
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2, 3, 4 ) << QgsPoint( 11, 12, 13, 14 ) << QgsPoint( 1, 12, 23, 24 ) << QgsPoint( 1, 2, 3, 4 ) );
|
|
p23.clear();
|
|
p23.setExteriorRing( lp23.clone() );
|
|
p23.addInteriorRing( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygonZM );
|
|
p23.dropZValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygonM );
|
|
QCOMPARE( p23.exteriorRing()->wkbType(), QgsWkbTypes::LineStringM );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QCOMPARE( p23.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineStringM );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
|
|
// dropMValue
|
|
p23.clear();
|
|
p23.dropMValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 12 ) << QgsPoint( 1, 2 ) );
|
|
p23.setExteriorRing( lp23.clone() );
|
|
p23.addInteriorRing( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
p23.dropMValue(); // not zm
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
QCOMPARE( p23.exteriorRing()->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.exteriorRing() )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( p23.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
// with m
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 13 ) << QgsPoint( QgsWkbTypes::PointM, 1, 12, 0, 23 ) << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) );
|
|
p23.clear();
|
|
p23.setExteriorRing( lp23.clone() );
|
|
p23.addInteriorRing( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygonM );
|
|
p23.dropMValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygon );
|
|
QCOMPARE( p23.exteriorRing()->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.exteriorRing() )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( p23.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
// with zm
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2, 3, 4 ) << QgsPoint( 11, 12, 13, 14 ) << QgsPoint( 1, 12, 23, 24 ) << QgsPoint( 1, 2, 3, 4 ) );
|
|
p23.clear();
|
|
p23.setExteriorRing( lp23.clone() );
|
|
p23.addInteriorRing( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygonZM );
|
|
p23.dropMValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::CurvePolygonZ );
|
|
QCOMPARE( p23.exteriorRing()->wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QCOMPARE( p23.interiorRing( 0 )->wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
|
|
|
|
// hasCurvedSegments
|
|
QgsCurvePolygon p24;
|
|
QVERIFY( !p24.hasCurvedSegments() );
|
|
QgsLineString lp24;
|
|
lp24.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 12 ) << QgsPoint( 1, 2 ) );
|
|
p24.setExteriorRing( lp23.clone() );
|
|
QVERIFY( !p24.hasCurvedSegments() );
|
|
QgsCircularString cs24;
|
|
cs24.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 12 ) << QgsPoint( 1, 2 ) );
|
|
p24.addInteriorRing( cs24.clone() );
|
|
QVERIFY( p24.hasCurvedSegments() );
|
|
|
|
//vertexAngle
|
|
QgsCurvePolygon p25;
|
|
( void )p25.vertexAngle( QgsVertexId() ); //just want no crash
|
|
( void )p25.vertexAngle( QgsVertexId( 0, 0, 0 ) ); //just want no crash
|
|
( void )p25.vertexAngle( QgsVertexId( 0, 1, 0 ) ); //just want no crash
|
|
QgsLineString l38;
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0.5, 0 ) << QgsPoint( 1, 0 )
|
|
<< QgsPoint( 2, 1 ) << QgsPoint( 1, 2 ) << QgsPoint( 0, 2 ) << QgsPoint( 0, 0 ) );
|
|
p25.setExteriorRing( l38.clone() );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 2.35619, 0.00001 );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 1.17809, 0.00001 );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 0, 3 ) ), 0.0, 0.00001 );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 0, 4 ) ), 5.10509, 0.00001 );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 0, 5 ) ), 3.92699, 0.00001 );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 0, 6 ) ), 2.35619, 0.00001 );
|
|
p25.addInteriorRing( l38.clone() );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 1, 0 ) ), 2.35619, 0.00001 );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 1, 1 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 1, 2 ) ), 1.17809, 0.00001 );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 1, 3 ) ), 0.0, 0.00001 );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 1, 4 ) ), 5.10509, 0.00001 );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 1, 5 ) ), 3.92699, 0.00001 );
|
|
QGSCOMPARENEAR( p25.vertexAngle( QgsVertexId( 0, 1, 6 ) ), 2.35619, 0.00001 );
|
|
|
|
|
|
//insert vertex
|
|
|
|
//insert vertex in empty polygon
|
|
p25.clear();
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 1, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 1, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( p25.isEmpty() );
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0.5, 0 ) << QgsPoint( 1, 0 )
|
|
<< QgsPoint( 2, 1 ) << QgsPoint( 1, 2 ) << QgsPoint( 0, 2 ) << QgsPoint( 0, 0 ) );
|
|
p25.setExteriorRing( l38.clone() );
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 0.3, 0 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 8 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 0 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 1 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 2 ), QgsPoint( 0.5, 0 ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 0, -1 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 0, 100 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 1, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
// first vertex
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 0, 0.1 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 9 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 0 ), QgsPoint( 0, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 2 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 3 ), QgsPoint( 0.5, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 7 ), QgsPoint( 0, 2 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 8 ), QgsPoint( 0, 0.1 ) );
|
|
// last vertex
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 0, 9 ), QgsPoint( 0.1, 0.1 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 10 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 0 ), QgsPoint( 0.1, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 2 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 3 ), QgsPoint( 0.5, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 8 ), QgsPoint( 0, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.exteriorRing() )->pointN( 9 ), QgsPoint( 0.1, 0.1 ) );
|
|
// with interior ring
|
|
p25.addInteriorRing( l38.clone() );
|
|
QCOMPARE( p25.nCoordinates(), 17 );
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 1, 1 ), QgsPoint( 0.3, 0 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 18 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 0.5, 0 ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 1, -1 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 1, 100 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 2, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
// first vertex in interior ring
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 1, 0 ), QgsPoint( 0, 0.1 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 19 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 0, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 3 ), QgsPoint( 0.5, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 7 ), QgsPoint( 0, 2 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 8 ), QgsPoint( 0, 0.1 ) );
|
|
// last vertex in interior ring
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 1, 9 ), QgsPoint( 0.1, 0.1 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 20 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 0.1, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 3 ), QgsPoint( 0.5, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 8 ), QgsPoint( 0, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.interiorRing( 0 ) )->pointN( 9 ), QgsPoint( 0.1, 0.1 ) );
|
|
|
|
//move vertex
|
|
|
|
//empty polygon
|
|
QgsCurvePolygon p26;
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( p26.isEmpty() );
|
|
|
|
//valid polygon
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 1, 2 ) );
|
|
p26.setExteriorRing( l38.clone() );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 16.0, 17.0 ) ) );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 0, 2 ), QgsPoint( 26.0, 27.0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 3 ), QgsPoint( 6.0, 7.0 ) );
|
|
|
|
//out of range
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 0, -1 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 0, 10 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 1, 0 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.exteriorRing() )->pointN( 3 ), QgsPoint( 6.0, 7.0 ) );
|
|
|
|
// with interior ring
|
|
p26.addInteriorRing( l38.clone() );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 1, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 1, 1 ), QgsPoint( 16.0, 17.0 ) ) );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 1, 2 ), QgsPoint( 26.0, 27.0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.interiorRing( 0 ) )->pointN( 3 ), QgsPoint( 6.0, 7.0 ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 1, -1 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 1, 10 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 2, 0 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
|
|
//delete vertex
|
|
|
|
//empty polygon
|
|
QgsCurvePolygon p27;
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 1, 0 ) ) );
|
|
QVERIFY( p27.isEmpty() );
|
|
|
|
//valid polygon
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 5, 2 ) << QgsPoint( 6, 2 ) << QgsPoint( 7, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 1, 2 ) );
|
|
|
|
p27.setExteriorRing( l38.clone() );
|
|
//out of range vertices
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 0, -1 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 0, 100 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 1, 1 ) ) );
|
|
|
|
//valid vertices
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 1 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 0 ), QgsPoint( 1.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 1 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 2 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 3 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 5 ), QgsPoint( 1.0, 2.0 ) );
|
|
|
|
// delete first vertex
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 0 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 1 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 2 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 3 ), QgsPoint( 21.0, 22.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 4 ), QgsPoint( 6.0, 2.0 ) );
|
|
|
|
// delete last vertex
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 4 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 0 ), QgsPoint( 21.0, 22.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 1 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 2 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.exteriorRing() )->pointN( 3 ), QgsPoint( 21.0, 22.0 ) );
|
|
|
|
// delete another vertex - should remove ring
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 1 ) ) );
|
|
QVERIFY( !p27.exteriorRing() );
|
|
|
|
// with interior ring
|
|
p27.setExteriorRing( l38.clone() );
|
|
p27.addInteriorRing( l38.clone() );
|
|
|
|
//out of range vertices
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 1, -1 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 1, 100 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 2, 1 ) ) );
|
|
|
|
//valid vertices
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 1, 1 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 1.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 3 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 5 ), QgsPoint( 1.0, 2.0 ) );
|
|
|
|
// delete first vertex
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 1, 0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 3 ), QgsPoint( 21.0, 22.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 4 ), QgsPoint( 6.0, 2.0 ) );
|
|
|
|
// delete last vertex
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 1, 4 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 0 ), QgsPoint( 21.0, 22.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 1 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 2 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.interiorRing( 0 ) )->pointN( 3 ), QgsPoint( 21.0, 22.0 ) );
|
|
|
|
// delete another vertex - should remove ring
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 1, 1 ) ) );
|
|
QCOMPARE( p27.numInteriorRings(), 0 );
|
|
QVERIFY( p27.exteriorRing() );
|
|
|
|
// test that interior ring is "promoted" when exterior is removed
|
|
p27.addInteriorRing( l38.clone() );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( p27.numInteriorRings(), 1 );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( p27.numInteriorRings(), 1 );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( p27.numInteriorRings(), 1 );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( p27.numInteriorRings(), 0 );
|
|
QVERIFY( p27.exteriorRing() );
|
|
}
|
|
|
|
void TestQgsGeometry::compoundCurve()
|
|
{
|
|
//test constructors
|
|
QgsCompoundCurve l1;
|
|
QVERIFY( l1.isEmpty() );
|
|
QCOMPARE( l1.numPoints(), 0 );
|
|
QCOMPARE( l1.vertexCount(), 0 );
|
|
QCOMPARE( l1.nCoordinates(), 0 );
|
|
QCOMPARE( l1.ringCount(), 0 );
|
|
QCOMPARE( l1.partCount(), 0 );
|
|
QVERIFY( !l1.is3D() );
|
|
QVERIFY( !l1.isMeasure() );
|
|
QCOMPARE( l1.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
QCOMPARE( l1.wktTypeStr(), QString( "CompoundCurve" ) );
|
|
QCOMPARE( l1.geometryType(), QString( "CompoundCurve" ) );
|
|
QCOMPARE( l1.dimension(), 1 );
|
|
QVERIFY( !l1.hasCurvedSegments() );
|
|
QCOMPARE( l1.area(), 0.0 );
|
|
QCOMPARE( l1.perimeter(), 0.0 );
|
|
QgsPointSequence pts;
|
|
l1.points( pts );
|
|
QVERIFY( pts.empty() );
|
|
|
|
// empty, test some methods to make sure they don't crash
|
|
QCOMPARE( l1.nCurves(), 0 );
|
|
QVERIFY( !l1.curveAt( -1 ) );
|
|
QVERIFY( !l1.curveAt( 0 ) );
|
|
QVERIFY( !l1.curveAt( 100 ) );
|
|
l1.removeCurve( -1 );
|
|
l1.removeCurve( 0 );
|
|
l1.removeCurve( 100 );
|
|
|
|
//addCurve
|
|
QgsCompoundCurve c1;
|
|
//try to add null curve
|
|
c1.addCurve( nullptr );
|
|
QCOMPARE( c1.nCurves(), 0 );
|
|
QVERIFY( !c1.curveAt( 0 ) );
|
|
|
|
QgsCircularString l2;
|
|
l2.setPoints( QgsPointSequence() << QgsPoint( 1.0, 2.0 ) );
|
|
c1.addCurve( l2.clone() );
|
|
QVERIFY( !c1.isEmpty() );
|
|
QCOMPARE( c1.numPoints(), 1 );
|
|
QCOMPARE( c1.vertexCount(), 1 );
|
|
QCOMPARE( c1.nCoordinates(), 1 );
|
|
QCOMPARE( c1.ringCount(), 1 );
|
|
QCOMPARE( c1.partCount(), 1 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
QVERIFY( c1.hasCurvedSegments() );
|
|
QCOMPARE( c1.area(), 0.0 );
|
|
QCOMPARE( c1.perimeter(), 0.0 );
|
|
c1.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( 1.0, 2.0 ) );
|
|
|
|
//adding first curve should set linestring z/m type
|
|
QgsCircularString l3;
|
|
l3.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1.0, 2.0, 3.0 ) );
|
|
QgsCompoundCurve c2;
|
|
c2.addCurve( l3.clone() );
|
|
QVERIFY( !c2.isEmpty() );
|
|
QVERIFY( c2.is3D() );
|
|
QVERIFY( !c2.isMeasure() );
|
|
QCOMPARE( c2.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
QCOMPARE( c2.wktTypeStr(), QString( "CompoundCurveZ" ) );
|
|
c2.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1.0, 2.0, 3.0 ) );
|
|
|
|
QgsCircularString l4;
|
|
l4.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1.0, 2.0, 0.0, 3.0 ) );
|
|
QgsCompoundCurve c4;
|
|
c4.addCurve( l4.clone() );
|
|
QVERIFY( !c4.isEmpty() );
|
|
QVERIFY( !c4.is3D() );
|
|
QVERIFY( c4.isMeasure() );
|
|
QCOMPARE( c4.wkbType(), QgsWkbTypes::CompoundCurveM );
|
|
QCOMPARE( c4.wktTypeStr(), QString( "CompoundCurveM" ) );
|
|
c4.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1.0, 2.0, 0.0, 3.0 ) );
|
|
|
|
QgsCircularString l5;
|
|
l5.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, 4.0 ) );
|
|
QgsCompoundCurve c5;
|
|
c5.addCurve( l5.clone() );
|
|
QVERIFY( !c5.isEmpty() );
|
|
QVERIFY( c5.is3D() );
|
|
QVERIFY( c5.isMeasure() );
|
|
QCOMPARE( c5.wkbType(), QgsWkbTypes::CompoundCurveZM );
|
|
QCOMPARE( c5.wktTypeStr(), QString( "CompoundCurveZM" ) );
|
|
c5.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, 4.0 ) );
|
|
|
|
//clear
|
|
c5.clear();
|
|
QVERIFY( c5.isEmpty() );
|
|
QCOMPARE( c5.nCurves(), 0 );
|
|
QCOMPARE( c5.numPoints(), 0 );
|
|
QCOMPARE( c5.vertexCount(), 0 );
|
|
QCOMPARE( c5.nCoordinates(), 0 );
|
|
QCOMPARE( c5.ringCount(), 0 );
|
|
QCOMPARE( c5.partCount(), 0 );
|
|
QVERIFY( !c5.is3D() );
|
|
QVERIFY( !c5.isMeasure() );
|
|
QCOMPARE( c5.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
|
|
//addCurve
|
|
QgsCircularString l8;
|
|
QgsCompoundCurve c8;
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2, 3 ) << QgsPoint( 3, 4 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QVERIFY( !c8.isEmpty() );
|
|
QCOMPARE( c8.numPoints(), 3 );
|
|
QCOMPARE( c8.vertexCount(), 3 );
|
|
QCOMPARE( c8.nCoordinates(), 3 );
|
|
QCOMPARE( c8.ringCount(), 1 );
|
|
QCOMPARE( c8.partCount(), 1 );
|
|
QCOMPARE( c8.nCurves(), 1 );
|
|
QVERIFY( !c8.is3D() );
|
|
QVERIFY( !c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
QVERIFY( c8.hasCurvedSegments() );
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2, 3 ) << QgsPoint( 3, 4 ) );
|
|
QCOMPARE( *dynamic_cast< const QgsCircularString *>( c8.curveAt( 0 ) ), l8 );
|
|
QVERIFY( ! c8.curveAt( -1 ) );
|
|
QVERIFY( ! c8.curveAt( 1 ) );
|
|
|
|
QgsCircularString l8a;
|
|
l8a.setPoints( QgsPointSequence() << QgsPoint( 3, 4 ) << QgsPoint( 4, 5 ) << QgsPoint( 3, 6 ) );
|
|
c8.addCurve( l8a.clone() );
|
|
QCOMPARE( c8.numPoints(), 5 );
|
|
QCOMPARE( c8.vertexCount(), 5 );
|
|
QCOMPARE( c8.nCoordinates(), 5 );
|
|
QCOMPARE( c8.ringCount(), 1 );
|
|
QCOMPARE( c8.partCount(), 1 );
|
|
QCOMPARE( c8.nCurves(), 2 );
|
|
pts.clear();
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2, 3 ) << QgsPoint( 3, 4 )
|
|
<< QgsPoint( 4, 5 ) << QgsPoint( 3, 6 ) );
|
|
QCOMPARE( *dynamic_cast< const QgsCircularString *>( c8.curveAt( 0 ) ), l8 );
|
|
QCOMPARE( *dynamic_cast< const QgsCircularString *>( c8.curveAt( 1 ) ), l8a );
|
|
QVERIFY( ! c8.curveAt( -1 ) );
|
|
QVERIFY( ! c8.curveAt( 2 ) );
|
|
|
|
QgsLineString l8b;
|
|
l8b.setPoints( QgsPointSequence() << QgsPoint( 3, 6 ) << QgsPoint( 4, 6 ) );
|
|
c8.addCurve( l8b.clone() );
|
|
QCOMPARE( c8.numPoints(), 6 );
|
|
QCOMPARE( c8.vertexCount(), 6 );
|
|
QCOMPARE( c8.nCoordinates(), 6 );
|
|
QCOMPARE( c8.ringCount(), 1 );
|
|
QCOMPARE( c8.partCount(), 1 );
|
|
QCOMPARE( c8.nCurves(), 3 );
|
|
pts.clear();
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2, 3 ) << QgsPoint( 3, 4 )
|
|
<< QgsPoint( 4, 5 ) << QgsPoint( 3, 6 )
|
|
<< QgsPoint( 4, 6 ) );
|
|
QCOMPARE( *dynamic_cast< const QgsCircularString *>( c8.curveAt( 0 ) ), l8 );
|
|
QCOMPARE( *dynamic_cast< const QgsCircularString *>( c8.curveAt( 1 ) ), l8a );
|
|
QCOMPARE( *dynamic_cast< const QgsLineString *>( c8.curveAt( 2 ) ), l8b );
|
|
QVERIFY( ! c8.curveAt( -1 ) );
|
|
QVERIFY( ! c8.curveAt( 3 ) );
|
|
|
|
//removeCurve
|
|
c8.removeCurve( -1 );
|
|
c8.removeCurve( 3 );
|
|
QCOMPARE( c8.nCurves(), 3 );
|
|
QCOMPARE( *dynamic_cast< const QgsCircularString *>( c8.curveAt( 0 ) ), l8 );
|
|
QCOMPARE( *dynamic_cast< const QgsCircularString *>( c8.curveAt( 1 ) ), l8a );
|
|
QCOMPARE( *dynamic_cast< const QgsLineString *>( c8.curveAt( 2 ) ), l8b );
|
|
c8.removeCurve( 1 );
|
|
QCOMPARE( c8.nCurves(), 2 );
|
|
QCOMPARE( *dynamic_cast< const QgsCircularString *>( c8.curveAt( 0 ) ), l8 );
|
|
QCOMPARE( *dynamic_cast< const QgsLineString *>( c8.curveAt( 1 ) ), l8b );
|
|
c8.removeCurve( 0 );
|
|
QCOMPARE( c8.nCurves(), 1 );
|
|
QCOMPARE( *dynamic_cast< const QgsLineString *>( c8.curveAt( 0 ) ), l8b );
|
|
c8.removeCurve( 0 );
|
|
QCOMPARE( c8.nCurves(), 0 );
|
|
QVERIFY( c8.isEmpty() );
|
|
|
|
//addCurve with z
|
|
c8.clear();
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 2, 3, 4 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QCOMPARE( c8.numPoints(), 2 );
|
|
QVERIFY( c8.is3D() );
|
|
QVERIFY( !c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
pts.clear();
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 2, 3, 4 ) );
|
|
|
|
//addCurve with m
|
|
c8.clear();
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 4 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QCOMPARE( c8.numPoints(), 2 );
|
|
QVERIFY( !c8.is3D() );
|
|
QVERIFY( c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurveM );
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 4 ) );
|
|
|
|
//addCurve with zm
|
|
c8.clear();
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 2, 3, 4, 5 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QCOMPARE( c8.numPoints(), 2 );
|
|
QVERIFY( c8.is3D() );
|
|
QVERIFY( c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurveZM );
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 2, 3, 4, 5 ) );
|
|
|
|
//addCurve with z to non z compound curve
|
|
c8.clear();
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 1, 2 ) << QgsPoint( QgsWkbTypes::Point, 2, 3 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 3, 3, 5 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QVERIFY( !c8.is3D() );
|
|
QVERIFY( !c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 1, 2 ) << QgsPoint( QgsWkbTypes::Point, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 3, 3 ) );
|
|
c8.removeCurve( 1 );
|
|
|
|
//addCurve with m to non m compound curve
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 3, 3, 0, 5 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QVERIFY( !c8.is3D() );
|
|
QVERIFY( !c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 1, 2 ) << QgsPoint( QgsWkbTypes::Point, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 3, 3 ) );
|
|
c8.removeCurve( 1 );
|
|
|
|
//addCurve with zm to non m compound curve
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 2, 3, 6, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 3, 1, 5 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QVERIFY( !c8.is3D() );
|
|
QVERIFY( !c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 1, 2 ) << QgsPoint( QgsWkbTypes::Point, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 3, 3 ) );
|
|
c8.removeCurve( 1 );
|
|
|
|
//addCurve with no z to z compound curve
|
|
c8.clear();
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 2, 3, 5 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 2, 3 ) << QgsPoint( QgsWkbTypes::Point, 3, 4 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QVERIFY( c8.is3D() );
|
|
QVERIFY( !c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 2, 3, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 3, 4, 0 ) );
|
|
c8.removeCurve( 1 );
|
|
|
|
//add curve with m, no z to z compound curve
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 8 ) << QgsPoint( QgsWkbTypes::PointM, 3, 4, 0, 9 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QVERIFY( c8.is3D() );
|
|
QVERIFY( !c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 2, 3, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 3, 4, 0 ) );
|
|
c8.removeCurve( 1 );
|
|
|
|
//add curve with zm to z compound curve
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 2, 3, 6, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 4, 7, 9 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QVERIFY( c8.is3D() );
|
|
QVERIFY( !c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 2, 3, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 3, 4, 7 ) );
|
|
c8.removeCurve( 1 );
|
|
|
|
//addCurve with no m to m compound curve
|
|
c8.clear();
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 5 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurveM );
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 2, 3 ) << QgsPoint( QgsWkbTypes::Point, 3, 4 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QVERIFY( !c8.is3D() );
|
|
QVERIFY( c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurveM );
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 3, 4, 0, 0 ) );
|
|
c8.removeCurve( 1 );
|
|
|
|
//add curve with z, no m to m compound curve
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 2, 3, 8 ) << QgsPoint( QgsWkbTypes::PointZ, 3, 4, 9 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QVERIFY( !c8.is3D() );
|
|
QVERIFY( c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurveM );
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 3, 4, 0, 0 ) );
|
|
c8.removeCurve( 1 );
|
|
|
|
//add curve with zm to m compound curve
|
|
l8.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 2, 3, 6, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 4, 7, 9 ) );
|
|
c8.addCurve( l8.clone() );
|
|
QVERIFY( !c8.is3D() );
|
|
QVERIFY( c8.isMeasure() );
|
|
QCOMPARE( c8.wkbType(), QgsWkbTypes::CompoundCurveM );
|
|
c8.points( pts );
|
|
QCOMPARE( pts, QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 2, 3, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 3, 4, 0, 9 ) );
|
|
c8.removeCurve( 1 );
|
|
|
|
//test getters/setters
|
|
QgsCompoundCurve c9;
|
|
|
|
// no crash!
|
|
( void )c9.xAt( -1 );
|
|
( void )c9.xAt( 1 );
|
|
( void )c9.yAt( -1 );
|
|
( void )c9.yAt( 1 );
|
|
|
|
QgsCircularString l9;
|
|
l9.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 23, 24 ) );
|
|
c9.addCurve( l9.clone() );
|
|
QCOMPARE( c9.xAt( 0 ), 1.0 );
|
|
QCOMPARE( c9.xAt( 1 ), 11.0 );
|
|
QCOMPARE( c9.xAt( 2 ), 21.0 );
|
|
( void ) c9.xAt( -1 ); //out of range
|
|
( void ) c9.xAt( 11 ); //out of range
|
|
QCOMPARE( c9.yAt( 0 ), 2.0 );
|
|
QCOMPARE( c9.yAt( 1 ), 12.0 );
|
|
QCOMPARE( c9.yAt( 2 ), 22.0 );
|
|
( void ) c9.yAt( -1 ); //out of range
|
|
( void ) c9.yAt( 11 ); //out of range
|
|
|
|
QgsLineString l9a;
|
|
l9a.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 21, 22, 23, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 31, 22, 13, 14 ) );
|
|
c9.addCurve( l9a.clone() );
|
|
QCOMPARE( c9.xAt( 0 ), 1.0 );
|
|
QCOMPARE( c9.xAt( 1 ), 11.0 );
|
|
QCOMPARE( c9.xAt( 2 ), 21.0 );
|
|
QCOMPARE( c9.xAt( 3 ), 31.0 );
|
|
QCOMPARE( c9.xAt( 4 ), 0.0 );
|
|
( void ) c9.xAt( -1 ); //out of range
|
|
( void ) c9.xAt( 11 ); //out of range
|
|
QCOMPARE( c9.yAt( 0 ), 2.0 );
|
|
QCOMPARE( c9.yAt( 1 ), 12.0 );
|
|
QCOMPARE( c9.yAt( 2 ), 22.0 );
|
|
QCOMPARE( c9.yAt( 3 ), 22.0 );
|
|
QCOMPARE( c9.yAt( 4 ), 0.0 );
|
|
( void ) c9.yAt( -1 ); //out of range
|
|
( void ) c9.yAt( 11 ); //out of range
|
|
|
|
c9.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 51.0, 52.0 ) );
|
|
QCOMPARE( c9.xAt( 0 ), 51.0 );
|
|
QCOMPARE( c9.yAt( 0 ), 52.0 );
|
|
c9.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 61.0, 62 ) );
|
|
QCOMPARE( c9.xAt( 1 ), 61.0 );
|
|
QCOMPARE( c9.yAt( 1 ), 62.0 );
|
|
c9.moveVertex( QgsVertexId( 0, 0, -1 ), QgsPoint( 71.0, 2 ) ); //out of range
|
|
c9.moveVertex( QgsVertexId( 0, 0, 11 ), QgsPoint( 71.0, 2 ) ); //out of range
|
|
|
|
QgsPoint p;
|
|
QgsVertexId::VertexType type;
|
|
QVERIFY( !c9.pointAt( -1, p, type ) );
|
|
QVERIFY( !c9.pointAt( 11, p, type ) );
|
|
QVERIFY( c9.pointAt( 0, p, type ) );
|
|
QCOMPARE( p.z(), 3.0 );
|
|
QCOMPARE( p.m(), 4.0 );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( c9.pointAt( 1, p, type ) );
|
|
QCOMPARE( p.z(), 13.0 );
|
|
QCOMPARE( p.m(), 14.0 );
|
|
QCOMPARE( type, QgsVertexId::CurveVertex );
|
|
QVERIFY( c9.pointAt( 2, p, type ) );
|
|
QCOMPARE( p.z(), 23.0 );
|
|
QCOMPARE( p.m(), 24.0 );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( c9.pointAt( 3, p, type ) );
|
|
QCOMPARE( p.z(), 13.0 );
|
|
QCOMPARE( p.m(), 14.0 );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
|
|
//equality
|
|
QgsCompoundCurve e1;
|
|
QgsCompoundCurve e2;
|
|
QVERIFY( e1 == e2 );
|
|
QVERIFY( !( e1 != e2 ) );
|
|
QgsLineString le1;
|
|
QgsLineString le2;
|
|
le1.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) );
|
|
e1.addCurve( le1.clone() );
|
|
QVERIFY( !( e1 == e2 ) ); //different number of curves
|
|
QVERIFY( e1 != e2 );
|
|
e2.addCurve( le1.clone() );
|
|
QVERIFY( e1 == e2 );
|
|
QVERIFY( !( e1 != e2 ) );
|
|
le1.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 1 / 3.0, 4 / 3.0 ) );
|
|
e1.addCurve( le1.clone() );
|
|
QVERIFY( !( e1 == e2 ) ); //different number of curves
|
|
QVERIFY( e1 != e2 );
|
|
le2.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2 / 6.0, 8 / 6.0 ) );
|
|
e2.addCurve( le2.clone() );
|
|
QVERIFY( e1 == e2 ); //check non-integer equality
|
|
QVERIFY( !( e1 != e2 ) );
|
|
le1.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 1 / 3.0, 4 / 3.0 ) << QgsPoint( 7, 8 ) );
|
|
e1.addCurve( le1.clone() );
|
|
le2.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 2 / 6.0, 8 / 6.0 ) << QgsPoint( 6, 9 ) );
|
|
e2.addCurve( le2.clone() );
|
|
QVERIFY( !( e1 == e2 ) ); //different coordinates
|
|
QVERIFY( e1 != e2 );
|
|
|
|
// different dimensions
|
|
QgsCompoundCurve e3;
|
|
e1.clear();
|
|
e1.addCurve( le1.clone() );
|
|
QgsLineString le3;
|
|
le3.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 0 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1 / 3.0, 4 / 3.0, 0 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 7, 8, 0 ) );
|
|
e3.addCurve( le3.clone() );
|
|
QVERIFY( !( e1 == e3 ) ); //different dimension
|
|
QVERIFY( e1 != e3 );
|
|
QgsCompoundCurve e4;
|
|
QgsLineString le4;
|
|
le4.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1 / 3.0, 4 / 3.0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 7, 8, 4 ) );
|
|
e4.addCurve( le4.clone() );
|
|
QVERIFY( !( e3 == e4 ) ); //different z coordinates
|
|
QVERIFY( e3 != e4 );
|
|
QgsCompoundCurve e5;
|
|
QgsLineString le5;
|
|
le5.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 1 / 3.0, 4 / 3.0, 0, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 7, 8, 0, 3 ) );
|
|
e5.addCurve( le5.clone() );
|
|
QgsCompoundCurve e6;
|
|
QgsLineString le6;
|
|
le6.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 11 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 1 / 3.0, 4 / 3.0, 0, 12 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 7, 8, 0, 13 ) );
|
|
e6.addCurve( le6.clone() );
|
|
QVERIFY( !( e5 == e6 ) ); //different m values
|
|
QVERIFY( e5 != e6 );
|
|
|
|
QVERIFY( e6 != QgsLineString() );
|
|
|
|
// assignment operator
|
|
e5.addCurve( le5.clone() );
|
|
QVERIFY( e5 != e6 );
|
|
e6 = e5;
|
|
QCOMPARE( e5, e6 );
|
|
|
|
//isClosed
|
|
QgsCompoundCurve c11;
|
|
QgsCircularString l11;
|
|
QVERIFY( !c11.isClosed() );
|
|
l11.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 2 )
|
|
<< QgsPoint( 11, 22 )
|
|
<< QgsPoint( 1, 22 ) );
|
|
c11.addCurve( l11.clone() );
|
|
QVERIFY( !c11.isClosed() );
|
|
QgsLineString ls11;
|
|
ls11.setPoints( QgsPointSequence() << QgsPoint( 1, 22 )
|
|
<< QgsPoint( 1, 2 ) );
|
|
c11.addCurve( ls11.clone() );
|
|
QVERIFY( c11.isClosed() );
|
|
|
|
//test that m values aren't considered when testing for closedness
|
|
c11.clear();
|
|
l11.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 11, 2, 0, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 11, 22, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 6 ) );
|
|
c11.addCurve( l11.clone() );
|
|
QVERIFY( c11.isClosed() );
|
|
|
|
//polygonf
|
|
QgsCircularString lc13;
|
|
QgsCompoundCurve c13;
|
|
lc13.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
c13.addCurve( lc13.clone() );
|
|
QgsLineString ls13;
|
|
ls13.setPoints( QgsPointSequence() << QgsPoint( 1, 22 ) << QgsPoint( 23, 22 ) );
|
|
c13.addCurve( ls13.clone() );
|
|
QPolygonF poly = c13.asQPolygonF();
|
|
QCOMPARE( poly.count(), 5 );
|
|
QCOMPARE( poly.at( 0 ).x(), 1.0 );
|
|
QCOMPARE( poly.at( 0 ).y(), 2.0 );
|
|
QCOMPARE( poly.at( 1 ).x(), 11.0 );
|
|
QCOMPARE( poly.at( 1 ).y(), 2.0 );
|
|
QCOMPARE( poly.at( 2 ).x(), 11.0 );
|
|
QCOMPARE( poly.at( 2 ).y(), 22.0 );
|
|
QCOMPARE( poly.at( 3 ).x(), 1.0 );
|
|
QCOMPARE( poly.at( 3 ).y(), 22.0 );
|
|
QCOMPARE( poly.at( 4 ).x(), 23.0 );
|
|
QCOMPARE( poly.at( 4 ).y(), 22.0 );
|
|
|
|
// clone tests
|
|
QgsCircularString lc14;
|
|
lc14.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 2 )
|
|
<< QgsPoint( 11, 22 )
|
|
<< QgsPoint( 1, 22 ) );
|
|
QgsCompoundCurve c14;
|
|
c14.addCurve( lc14.clone() );
|
|
QgsLineString ls14;
|
|
ls14.setPoints( QgsPointSequence() << QgsPoint( 1, 22 ) << QgsPoint( 23, 22 ) );
|
|
c14.addCurve( ls14.clone() );
|
|
std::unique_ptr<QgsCompoundCurve> cloned( c14.clone() );
|
|
QCOMPARE( *cloned, c14 );
|
|
|
|
//clone with Z/M
|
|
lc14.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
ls14.setPoints( QgsPointSequence() << QgsPoint( 1, 22, 31, 34 ) << QgsPoint( 23, 22, 42, 43 ) );
|
|
c14.clear();
|
|
c14.addCurve( lc14.clone() );
|
|
c14.addCurve( ls14.clone() );
|
|
cloned.reset( c14.clone() );
|
|
QCOMPARE( *cloned, c14 );
|
|
|
|
//clone an empty line
|
|
c14.clear();
|
|
cloned.reset( c14.clone() );
|
|
QVERIFY( cloned->isEmpty() );
|
|
QCOMPARE( cloned->numPoints(), 0 );
|
|
QVERIFY( !cloned->is3D() );
|
|
QVERIFY( !cloned->isMeasure() );
|
|
QCOMPARE( cloned->wkbType(), QgsWkbTypes::CompoundCurve );
|
|
|
|
//segmentize tests
|
|
QgsCompoundCurve toSegment;
|
|
QgsCircularString lcSegment;
|
|
lcSegment.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 10 ) << QgsPoint( 21, 2 ) );
|
|
toSegment.addCurve( lcSegment.clone() );
|
|
std::unique_ptr<QgsLineString> segmentized( static_cast< QgsLineString * >( toSegment.segmentize() ) );
|
|
QCOMPARE( segmentized->numPoints(), 156 );
|
|
QCOMPARE( segmentized->vertexCount(), 156 );
|
|
QCOMPARE( segmentized->ringCount(), 1 );
|
|
QCOMPARE( segmentized->partCount(), 1 );
|
|
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineString );
|
|
QVERIFY( !segmentized->is3D() );
|
|
QVERIFY( !segmentized->isMeasure() );
|
|
|
|
QCOMPARE( segmentized->pointN( 0 ), lcSegment.pointN( 0 ) );
|
|
QCOMPARE( segmentized->pointN( segmentized->numPoints() - 1 ), lcSegment.pointN( toSegment.numPoints() - 1 ) );
|
|
|
|
//segmentize with Z/M
|
|
lcSegment.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 10, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 2, 21, 24 ) );
|
|
toSegment.clear();
|
|
toSegment.addCurve( lcSegment.clone() );
|
|
segmentized.reset( static_cast< QgsLineString * >( toSegment.segmentize() ) );
|
|
QCOMPARE( segmentized->numPoints(), 156 );
|
|
QCOMPARE( segmentized->vertexCount(), 156 );
|
|
QCOMPARE( segmentized->ringCount(), 1 );
|
|
QCOMPARE( segmentized->partCount(), 1 );
|
|
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineStringZM );
|
|
QVERIFY( segmentized->is3D() );
|
|
QVERIFY( segmentized->isMeasure() );
|
|
QCOMPARE( segmentized->pointN( 0 ), lcSegment.pointN( 0 ) );
|
|
QCOMPARE( segmentized->pointN( segmentized->numPoints() - 1 ), lcSegment.pointN( toSegment.numPoints() - 1 ) );
|
|
|
|
//segmentize an empty line
|
|
toSegment.clear();
|
|
segmentized.reset( static_cast< QgsLineString * >( toSegment.segmentize() ) );
|
|
QVERIFY( segmentized->isEmpty() );
|
|
QCOMPARE( segmentized->numPoints(), 0 );
|
|
QVERIFY( !segmentized->is3D() );
|
|
QVERIFY( !segmentized->isMeasure() );
|
|
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineString );
|
|
|
|
//to/from WKB
|
|
QgsCompoundCurve c15;
|
|
QgsCircularString l15;
|
|
l15.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
c15.addCurve( l15.clone() );
|
|
QByteArray wkb15 = c15.asWkb();
|
|
QgsCompoundCurve c16;
|
|
QgsConstWkbPtr wkb15ptr( wkb15 );
|
|
c16.fromWkb( wkb15ptr );
|
|
QCOMPARE( c16.numPoints(), 4 );
|
|
QCOMPARE( c16.vertexCount(), 4 );
|
|
QCOMPARE( c16.nCoordinates(), 4 );
|
|
QCOMPARE( c16.ringCount(), 1 );
|
|
QCOMPARE( c16.partCount(), 1 );
|
|
QCOMPARE( c16.wkbType(), QgsWkbTypes::CompoundCurveZM );
|
|
QVERIFY( c16.is3D() );
|
|
QVERIFY( c16.isMeasure() );
|
|
QCOMPARE( c16.nCurves(), 1 );
|
|
QCOMPARE( dynamic_cast< const QgsCircularString *>( c16.curveAt( 0 ) )->pointN( 0 ), l15.pointN( 0 ) );
|
|
QCOMPARE( dynamic_cast< const QgsCircularString *>( c16.curveAt( 0 ) )->pointN( 1 ), l15.pointN( 1 ) );
|
|
QCOMPARE( dynamic_cast< const QgsCircularString *>( c16.curveAt( 0 ) )->pointN( 2 ), l15.pointN( 2 ) );
|
|
QCOMPARE( dynamic_cast< const QgsCircularString *>( c16.curveAt( 0 ) )->pointN( 3 ), l15.pointN( 3 ) );
|
|
|
|
//bad WKB - check for no crash
|
|
c16.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !c16.fromWkb( nullPtr ) );
|
|
QCOMPARE( c16.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkb16 = point.asWkb();
|
|
QgsConstWkbPtr wkb16ptr( wkb16 );
|
|
QVERIFY( !c16.fromWkb( wkb16ptr ) );
|
|
QCOMPARE( c16.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
|
|
//to/from WKT
|
|
QgsCompoundCurve c17;
|
|
QgsCircularString l17;
|
|
l17.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 2, 11, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 22, 21, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 22, 31, 34 ) );
|
|
c17.addCurve( l17.clone() );
|
|
|
|
QString wkt = c17.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsCompoundCurve c18;
|
|
QVERIFY( c18.fromWkt( wkt ) );
|
|
QCOMPARE( c18.numPoints(), 4 );
|
|
QCOMPARE( c18.wkbType(), QgsWkbTypes::CompoundCurveZM );
|
|
QVERIFY( c18.is3D() );
|
|
QVERIFY( c18.isMeasure() );
|
|
QCOMPARE( dynamic_cast< const QgsCircularString *>( c18.curveAt( 0 ) )->pointN( 0 ), l17.pointN( 0 ) );
|
|
QCOMPARE( dynamic_cast< const QgsCircularString *>( c18.curveAt( 0 ) )->pointN( 1 ), l17.pointN( 1 ) );
|
|
QCOMPARE( dynamic_cast< const QgsCircularString *>( c18.curveAt( 0 ) )->pointN( 2 ), l17.pointN( 2 ) );
|
|
QCOMPARE( dynamic_cast< const QgsCircularString *>( c18.curveAt( 0 ) )->pointN( 3 ), l17.pointN( 3 ) );
|
|
|
|
//bad WKT
|
|
QVERIFY( !c18.fromWkt( "Polygon()" ) );
|
|
QVERIFY( c18.isEmpty() );
|
|
QCOMPARE( c18.numPoints(), 0 );
|
|
QVERIFY( !c18.is3D() );
|
|
QVERIFY( !c18.isMeasure() );
|
|
QCOMPARE( c18.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
QVERIFY( !c18.fromWkt( "CompoundCurve(LineString(0 0, 1 1),Point( 2 2 ))" ) );
|
|
|
|
//asGML2
|
|
QgsCompoundCurve exportCurve;
|
|
QgsCircularString exportLine;
|
|
exportLine.setPoints( QgsPointSequence() << QgsPoint( 31, 32 )
|
|
<< QgsPoint( 41, 42 )
|
|
<< QgsPoint( 51, 52 ) );
|
|
exportCurve.addCurve( exportLine.clone() );
|
|
QgsLineString exportLineString;
|
|
exportLineString.setPoints( QgsPointSequence() << QgsPoint( 51, 52 )
|
|
<< QgsPoint( 61, 62 ) );
|
|
exportCurve.addCurve( exportLineString.clone() );
|
|
|
|
QgsCircularString exportLineFloat;
|
|
exportLineFloat.setPoints( QgsPointSequence() << QgsPoint( 1 / 3.0, 2 / 3.0 )
|
|
<< QgsPoint( 1 + 1 / 3.0, 1 + 2 / 3.0 )
|
|
<< QgsPoint( 2 + 1 / 3.0, 2 + 2 / 3.0 ) );
|
|
QgsCompoundCurve exportCurveFloat;
|
|
exportCurveFloat.addCurve( exportLineFloat.clone() );
|
|
QgsLineString exportLineStringFloat;
|
|
exportLineStringFloat.setPoints( QgsPointSequence() << QgsPoint( 2 + 1 / 3.0, 2 + 2 / 3.0 )
|
|
<< QgsPoint( 3 + 1 / 3.0, 3 + 2 / 3.0 ) );
|
|
exportCurveFloat.addCurve( exportLineStringFloat.clone() );
|
|
|
|
QDomDocument doc( QStringLiteral( "gml" ) );
|
|
QString expectedGML2( QStringLiteral( "<LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">31,32 41,42 51,52 61,62</coordinates></LineString>" ) );
|
|
QString result = elemToString( exportCurve.asGML2( doc ) );
|
|
QGSCOMPAREGML( result, expectedGML2 );
|
|
QString expectedGML2prec3( QStringLiteral( "<LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0.333,0.667 1.333,1.667 2.333,2.667 3.333,3.667</coordinates></LineString>" ) );
|
|
result = elemToString( exportCurveFloat.asGML2( doc, 3 ) );
|
|
QGSCOMPAREGML( result, expectedGML2prec3 );
|
|
|
|
|
|
//asGML3
|
|
QString expectedGML3( QStringLiteral( "<CompositeCurve xmlns=\"gml\"><curveMember xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">31 32 41 42 51 52</posList></ArcString></segments></Curve></curveMember><curveMember xmlns=\"gml\"><LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">51 52 61 62</posList></LineString></curveMember></CompositeCurve>" ) );
|
|
result = elemToString( exportCurve.asGML3( doc ) );
|
|
QCOMPARE( result, expectedGML3 );
|
|
QString expectedGML3prec3( QStringLiteral( "<CompositeCurve xmlns=\"gml\"><curveMember xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">0.333 0.667 1.333 1.667 2.333 2.667</posList></ArcString></segments></Curve></curveMember><curveMember xmlns=\"gml\"><LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">2.333 2.667 3.333 3.667</posList></LineString></curveMember></CompositeCurve>" ) );
|
|
result = elemToString( exportCurveFloat.asGML3( doc, 3 ) );
|
|
QCOMPARE( result, expectedGML3prec3 );
|
|
|
|
//asJSON
|
|
QString expectedJson( QStringLiteral( "{\"type\": \"LineString\", \"coordinates\": [ [31, 32], [41, 42], [51, 52], [61, 62]]}" ) );
|
|
result = exportCurve.asJSON();
|
|
QCOMPARE( result, expectedJson );
|
|
QString expectedJsonPrec3( QStringLiteral( "{\"type\": \"LineString\", \"coordinates\": [ [0.333, 0.667], [1.333, 1.667], [2.333, 2.667], [3.333, 3.667]]}" ) );
|
|
result = exportCurveFloat.asJSON( 3 );
|
|
QCOMPARE( result, expectedJsonPrec3 );
|
|
|
|
//length
|
|
QgsCompoundCurve c19;
|
|
QCOMPARE( c19.length(), 0.0 );
|
|
QgsCircularString l19;
|
|
l19.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
c19.addCurve( l19.clone() );
|
|
QgsLineString l19a;
|
|
l19a.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 25, 10, 6, 7 ) );
|
|
c19.addCurve( l19a.clone() );
|
|
QGSCOMPARENEAR( c19.length(), 36.1433, 0.001 );
|
|
|
|
//startPoint
|
|
QCOMPARE( c19.startPoint(), QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 ) );
|
|
|
|
//endPoint
|
|
QCOMPARE( c19.endPoint(), QgsPoint( QgsWkbTypes::PointZM, 25, 10, 6, 7 ) );
|
|
|
|
//bad start/end points. Test that this doesn't crash.
|
|
c19.clear();
|
|
QCOMPARE( c19.startPoint(), QgsPoint() );
|
|
QCOMPARE( c19.endPoint(), QgsPoint() );
|
|
|
|
//curveToLine
|
|
c19.clear();
|
|
l19.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
c19.addCurve( l19.clone() );
|
|
l19a.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 25, 10, 6, 7 ) );
|
|
c19.addCurve( l19a.clone() );
|
|
segmentized.reset( c19.curveToLine() );
|
|
QCOMPARE( segmentized->numPoints(), 182 );
|
|
QCOMPARE( segmentized->wkbType(), QgsWkbTypes::LineStringZM );
|
|
QVERIFY( segmentized->is3D() );
|
|
QVERIFY( segmentized->isMeasure() );
|
|
QCOMPARE( segmentized->pointN( 0 ), l19.pointN( 0 ) );
|
|
QCOMPARE( segmentized->pointN( segmentized->numPoints() - 1 ), l19a.pointN( l19a.numPoints() - 1 ) );
|
|
|
|
// points
|
|
QgsCompoundCurve c20;
|
|
QgsCircularString l20;
|
|
QgsPointSequence points;
|
|
c20.points( points );
|
|
QVERIFY( points.isEmpty() );
|
|
l20.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
c20.addCurve( l20.clone() );
|
|
QgsLineString ls20;
|
|
ls20.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 25, 10, 6, 7 ) );
|
|
c20.addCurve( ls20.clone() );
|
|
c20.points( points );
|
|
QCOMPARE( points.count(), 4 );
|
|
QCOMPARE( points.at( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 ) );
|
|
QCOMPARE( points.at( 1 ), QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 ) );
|
|
QCOMPARE( points.at( 2 ), QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
QCOMPARE( points.at( 3 ), QgsPoint( QgsWkbTypes::PointZM, 25, 10, 6, 7 ) );
|
|
|
|
//CRS transform
|
|
QgsCoordinateReferenceSystem sourceSrs;
|
|
sourceSrs.createFromSrid( 3994 );
|
|
QgsCoordinateReferenceSystem destSrs;
|
|
destSrs.createFromSrid( 4202 ); // want a transform with ellipsoid change
|
|
QgsCoordinateTransform tr( sourceSrs, destSrs );
|
|
|
|
// 2d CRS transform
|
|
QgsCompoundCurve c21;
|
|
QgsCircularString l21;
|
|
l21.setPoints( QgsPointSequence() << QgsPoint( 6374985, -3626584 )
|
|
<< QgsPoint( 6474985, -3526584 ) );
|
|
c21.addCurve( l21.clone() );
|
|
QgsLineString ls21;
|
|
ls21.setPoints( QgsPointSequence() << QgsPoint( 6474985, -3526584 )
|
|
<< QgsPoint( 6504985, -3526584 ) );
|
|
c21.addCurve( ls21.clone() );
|
|
c21.transform( tr, QgsCoordinateTransform::ForwardTransform );
|
|
QGSCOMPARENEAR( c21.xAt( 0 ), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( c21.yAt( 0 ), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( c21.xAt( 1 ), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( c21.yAt( 1 ), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( c21.xAt( 2 ), 177.315211, 0.001 );
|
|
QGSCOMPARENEAR( c21.yAt( 2 ), -38.799974, 0.001 );
|
|
QGSCOMPARENEAR( c21.boundingBox().xMinimum(), 175.770033, 0.001 );
|
|
QGSCOMPARENEAR( c21.boundingBox().yMinimum(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( c21.boundingBox().xMaximum(), 177.315211, 0.001 );
|
|
QGSCOMPARENEAR( c21.boundingBox().yMaximum(), -38.7999, 0.001 );
|
|
|
|
//3d CRS transform
|
|
QgsCompoundCurve c22;
|
|
l21.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 6374985, -3626584, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 6474985, -3526584, 3, 4 ) );
|
|
c22.addCurve( l21.clone() );
|
|
ls21.setPoints( QgsPointSequence() << QgsPoint( 6474985, -3526584, 3, 4 )
|
|
<< QgsPoint( 6504985, -3526584, 5, 6 ) );
|
|
c22.addCurve( ls21.clone() );
|
|
c22.transform( tr, QgsCoordinateTransform::ForwardTransform );
|
|
QgsPoint pt;
|
|
QgsVertexId::VertexType v;
|
|
c22.pointAt( 0, pt, v );
|
|
QGSCOMPARENEAR( pt.x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( pt.y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( pt.z(), 1.0, 0.001 );
|
|
QCOMPARE( pt.m(), 2.0 );
|
|
c22.pointAt( 1, pt, v );
|
|
QGSCOMPARENEAR( pt.x(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( pt.y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( pt.z(), 3.0, 0.001 );
|
|
QCOMPARE( pt.m(), 4.0 );
|
|
c22.pointAt( 2, pt, v );
|
|
QGSCOMPARENEAR( pt.x(), 177.315211, 0.001 );
|
|
QGSCOMPARENEAR( pt.y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( pt.z(), 5.0, 0.001 );
|
|
QCOMPARE( pt.m(), 6.0 );
|
|
|
|
//reverse transform
|
|
c22.transform( tr, QgsCoordinateTransform::ReverseTransform );
|
|
c22.pointAt( 0, pt, v );
|
|
QGSCOMPARENEAR( pt.x(), 6374985, 100 );
|
|
QGSCOMPARENEAR( pt.y(), -3626584, 100 );
|
|
QGSCOMPARENEAR( pt.z(), 1.0, 0.001 );
|
|
QCOMPARE( pt.m(), 2.0 );
|
|
c22.pointAt( 1, pt, v );
|
|
QGSCOMPARENEAR( pt.x(), 6474985, 100 );
|
|
QGSCOMPARENEAR( pt.y(), -3526584, 100 );
|
|
QGSCOMPARENEAR( pt.z(), 3.0, 0.001 );
|
|
QCOMPARE( pt.m(), 4.0 );
|
|
c22.pointAt( 2, pt, v );
|
|
QGSCOMPARENEAR( pt.x(), 6504985, 100 );
|
|
QGSCOMPARENEAR( pt.y(), -3526584, 100 );
|
|
QGSCOMPARENEAR( pt.z(), 5.0, 0.001 );
|
|
QCOMPARE( pt.m(), 6.0 );
|
|
|
|
//z value transform
|
|
c22.transform( tr, QgsCoordinateTransform::ForwardTransform, true );
|
|
c22.pointAt( 0, pt, v );
|
|
QGSCOMPARENEAR( pt.z(), -19.249066, 0.001 );
|
|
c22.pointAt( 1, pt, v );
|
|
QGSCOMPARENEAR( pt.z(), -21.092128, 0.001 );
|
|
c22.pointAt( 2, pt, v );
|
|
QGSCOMPARENEAR( pt.z(), -19.370485, 0.001 );
|
|
|
|
c22.transform( tr, QgsCoordinateTransform::ReverseTransform, true );
|
|
c22.pointAt( 0, pt, v );
|
|
QGSCOMPARENEAR( pt.z(), 1, 0.001 );
|
|
c22.pointAt( 1, pt, v );
|
|
QGSCOMPARENEAR( pt.z(), 3, 0.001 );
|
|
c22.pointAt( 2, pt, v );
|
|
QGSCOMPARENEAR( pt.z(), 5, 0.001 );
|
|
|
|
//QTransform transform
|
|
QTransform qtr = QTransform::fromScale( 2, 3 );
|
|
QgsCompoundCurve c23;
|
|
QgsCircularString l23;
|
|
l23.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
c23.addCurve( l23.clone() );
|
|
QgsLineString ls23;
|
|
ls23.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) << QgsPoint( QgsWkbTypes::PointZM, 21, 13, 13, 14 ) );
|
|
c23.addCurve( ls23.clone() );
|
|
c23.transform( qtr );
|
|
c23.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 2, 6, 3, 4 ) );
|
|
c23.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 22, 36, 13, 14 ) );
|
|
c23.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 42, 39, 13, 14 ) );
|
|
QCOMPARE( c23.boundingBox(), QgsRectangle( 2, 6, 42, 39 ) );
|
|
|
|
//insert vertex
|
|
//cannot insert vertex in empty line
|
|
QgsCompoundCurve c24;
|
|
QVERIFY( !c24.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QCOMPARE( c24.numPoints(), 0 );
|
|
|
|
//2d line
|
|
QgsCircularString l24;
|
|
l24.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 1, 22 ) );
|
|
c24.addCurve( l24.clone() );
|
|
QVERIFY( c24.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 4.0, 7.0 ) ) );
|
|
QCOMPARE( c24.numPoints(), 5 );
|
|
QVERIFY( !c24.is3D() );
|
|
QVERIFY( !c24.isMeasure() );
|
|
QCOMPARE( c24.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
c24.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 1.0, 2.0 ) );
|
|
c24.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 4.0, 7.0 ) );
|
|
c24.pointAt( 2, pt, v );
|
|
QGSCOMPARENEAR( pt.x(), 7.192236, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 9.930870, 0.01 );
|
|
c24.pointAt( 3, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 11.0, 12.0 ) );
|
|
c24.pointAt( 4, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 1.0, 22.0 ) );
|
|
|
|
QVERIFY( c24.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 8.0, 9.0 ) ) );
|
|
QVERIFY( c24.insertVertex( QgsVertexId( 0, 0, 2 ), QgsPoint( 18.0, 16.0 ) ) );
|
|
QCOMPARE( c24.numPoints(), 9 );
|
|
c24.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 1.0, 2.0 ) );
|
|
c24.pointAt( 1, pt, v );
|
|
QGSCOMPARENEAR( pt.x(), 4.363083, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 5.636917, 0.01 );
|
|
c24.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 8.0, 9.0 ) );
|
|
c24.pointAt( 3, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 18.0, 16.0 ) );
|
|
c24.pointAt( 4, pt, v );
|
|
QGSCOMPARENEAR( pt.x(), 5.876894, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 8.246211, 0.01 );
|
|
c24.pointAt( 5, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 4.0, 7.0 ) );
|
|
c24.pointAt( 6, pt, v );
|
|
QGSCOMPARENEAR( pt.x(), 7.192236, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 9.930870, 0.01 );
|
|
c24.pointAt( 7, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 11.0, 12.0 ) );
|
|
c24.pointAt( 8, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 1.0, 22.0 ) );
|
|
|
|
//insert vertex at end
|
|
QVERIFY( !c24.insertVertex( QgsVertexId( 0, 0, 9 ), QgsPoint( 31.0, 32.0 ) ) );
|
|
|
|
//insert vertex past end
|
|
QVERIFY( !c24.insertVertex( QgsVertexId( 0, 0, 10 ), QgsPoint( 41.0, 42.0 ) ) );
|
|
QCOMPARE( c24.numPoints(), 9 );
|
|
|
|
//insert vertex before start
|
|
QVERIFY( !c24.insertVertex( QgsVertexId( 0, 0, -18 ), QgsPoint( 41.0, 42.0 ) ) );
|
|
QCOMPARE( c24.numPoints(), 9 );
|
|
|
|
//insert 4d vertex in 4d line
|
|
c24.clear();
|
|
l24.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
c24.addCurve( l24.clone( ) );
|
|
QVERIFY( c24.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) ) );
|
|
QCOMPARE( c24.numPoints(), 5 );
|
|
c24.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
|
|
//insert 2d vertex in 4d line
|
|
QVERIFY( c24.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 101, 102 ) ) );
|
|
QCOMPARE( c24.numPoints(), 7 );
|
|
QCOMPARE( c24.wkbType(), QgsWkbTypes::CompoundCurveZM );
|
|
c24.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 101, 102 ) );
|
|
|
|
//insert 4d vertex in 2d line
|
|
c24.clear();
|
|
l24.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 1, 22 ) );
|
|
c24.addCurve( l24.clone() );
|
|
QVERIFY( c24.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( QgsWkbTypes::PointZM, 2, 4, 103, 104 ) ) );
|
|
QCOMPARE( c24.numPoints(), 5 );
|
|
QCOMPARE( c24.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
c24.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::Point, 2, 4 ) );
|
|
|
|
// invalid
|
|
QVERIFY( !c24.insertVertex( QgsVertexId( 0, 1, 0 ), QgsPoint( 1, 2 ) ) );
|
|
|
|
//move vertex
|
|
|
|
//empty line
|
|
QgsCompoundCurve c25;
|
|
QgsCircularString l25;
|
|
QVERIFY( !c25.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( c25.isEmpty() );
|
|
|
|
//valid line
|
|
l25.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) );
|
|
c25.addCurve( l25.clone() );
|
|
QVERIFY( c25.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( c25.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 16.0, 17.0 ) ) );
|
|
QVERIFY( c25.moveVertex( QgsVertexId( 0, 0, 2 ), QgsPoint( 26.0, 27.0 ) ) );
|
|
c25.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 6.0, 7.0 ) );
|
|
c25.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 16.0, 17.0 ) );
|
|
c25.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 26.0, 27.0 ) );
|
|
|
|
//out of range
|
|
QVERIFY( !c25.moveVertex( QgsVertexId( 0, 0, -1 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !c25.moveVertex( QgsVertexId( 0, 0, 10 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !c25.moveVertex( QgsVertexId( 0, 1, 10 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
c25.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 6.0, 7.0 ) );
|
|
c25.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 16.0, 17.0 ) );
|
|
c25.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 26.0, 27.0 ) );
|
|
|
|
//move 4d point in 4d line
|
|
l25.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 10, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 15, 10, 6, 7 ) );
|
|
c25.clear();
|
|
c25.addCurve( l25.clone() );
|
|
QVERIFY( c25.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( QgsWkbTypes::PointZM, 6, 7, 12, 13 ) ) );
|
|
c25.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 6, 7, 12, 13 ) );
|
|
|
|
//move 2d point in 4d line, existing z/m should be maintained
|
|
QVERIFY( c25.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 34, 35 ) ) );
|
|
c25.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 34, 35, 12, 13 ) );
|
|
|
|
//move 4d point in 2d line
|
|
l25.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) );
|
|
c25.clear();
|
|
c25.addCurve( l25.clone() );
|
|
QVERIFY( c25.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( QgsWkbTypes::PointZM, 3, 4, 2, 3 ) ) );
|
|
c25.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 3, 4 ) );
|
|
|
|
//delete vertex
|
|
|
|
//empty line
|
|
QgsCompoundCurve c26;
|
|
QgsCircularString l26;
|
|
QVERIFY( !c26.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( c26.isEmpty() );
|
|
|
|
//valid line
|
|
l26.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 31, 32, 6, 7 ) );
|
|
c26.addCurve( l26.clone() );
|
|
//out of range vertices
|
|
QVERIFY( !c26.deleteVertex( QgsVertexId( 0, 0, -1 ) ) );
|
|
QVERIFY( !c26.deleteVertex( QgsVertexId( 0, 0, 100 ) ) );
|
|
|
|
//valid vertices
|
|
QVERIFY( c26.deleteVertex( QgsVertexId( 0, 0, 1 ) ) );
|
|
QCOMPARE( c26.numPoints(), 2 );
|
|
c26.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 ) );
|
|
c26.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 31, 32, 6, 7 ) );
|
|
|
|
//removing the next vertex removes all remaining vertices
|
|
QVERIFY( c26.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( c26.numPoints(), 0 );
|
|
QVERIFY( c26.isEmpty() );
|
|
|
|
// two lines
|
|
QgsLineString ls26;
|
|
c26.clear();
|
|
ls26.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 ) );
|
|
c26.addCurve( ls26.clone() );
|
|
ls26.setPoints( QgsPointSequence()
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 32, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 31, 42, 4, 5 ) );
|
|
c26.addCurve( ls26.clone() );
|
|
QVERIFY( c26.deleteVertex( QgsVertexId( 0, 0, 1 ) ) );
|
|
QCOMPARE( c26.nCurves(), 1 );
|
|
const QgsLineString *ls26r = dynamic_cast< const QgsLineString * >( c26.curveAt( 0 ) );
|
|
QCOMPARE( ls26r->numPoints(), 2 );
|
|
QCOMPARE( ls26r->startPoint(), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 ) );
|
|
QCOMPARE( ls26r->endPoint(), QgsPoint( QgsWkbTypes::PointZM, 31, 42, 4, 5 ) );
|
|
|
|
c26.clear();
|
|
ls26.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 32, 4, 5 ) );
|
|
c26.addCurve( ls26.clone() );
|
|
ls26.setPoints( QgsPointSequence()
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 32, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 31, 42, 4, 5 ) );
|
|
c26.addCurve( ls26.clone() );
|
|
QVERIFY( c26.deleteVertex( QgsVertexId( 0, 0, 2 ) ) );
|
|
QCOMPARE( c26.nCurves(), 1 );
|
|
ls26r = dynamic_cast< const QgsLineString * >( c26.curveAt( 0 ) );
|
|
QCOMPARE( ls26r->numPoints(), 2 );
|
|
QCOMPARE( ls26r->startPoint(), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 ) );
|
|
QCOMPARE( ls26r->endPoint(), QgsPoint( QgsWkbTypes::PointZM, 31, 42, 4, 5 ) );
|
|
|
|
//reversed
|
|
QgsCompoundCurve c27;
|
|
QgsCircularString l27;
|
|
std::unique_ptr< QgsCompoundCurve > reversed( c27.reversed() );
|
|
QVERIFY( reversed->isEmpty() );
|
|
l27.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
c27.addCurve( l27.clone() );
|
|
QgsLineString ls27;
|
|
ls27.setPoints( QgsPointSequence()
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 23, 32, 7, 8 ) );
|
|
c27.addCurve( ls27.clone() );
|
|
|
|
reversed.reset( c27.reversed() );
|
|
QCOMPARE( reversed->numPoints(), 4 );
|
|
QVERIFY( dynamic_cast< const QgsLineString * >( reversed->curveAt( 0 ) ) );
|
|
QVERIFY( dynamic_cast< const QgsCircularString * >( reversed->curveAt( 1 ) ) );
|
|
QCOMPARE( reversed->wkbType(), QgsWkbTypes::CompoundCurveZM );
|
|
QVERIFY( reversed->is3D() );
|
|
QVERIFY( reversed->isMeasure() );
|
|
reversed->pointAt( 0, pt, v );
|
|
reversed->pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
reversed->pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 ) );
|
|
reversed->pointAt( 3, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 ) );
|
|
|
|
//addZValue
|
|
QgsCompoundCurve c28;
|
|
QgsCircularString l28;
|
|
QCOMPARE( c28.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
QVERIFY( c28.addZValue() );
|
|
QCOMPARE( c28.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
c28.clear();
|
|
//2d line
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
c28.addCurve( l28.clone() );
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( 11, 12 ) << QgsPoint( 3, 4 ) );
|
|
c28.addCurve( l28.clone() );
|
|
QVERIFY( c28.addZValue( 2 ) );
|
|
QVERIFY( c28.is3D() );
|
|
QCOMPARE( c28.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
c28.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ) );
|
|
c28.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZ, 11, 12, 2 ) );
|
|
c28.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZ, 3, 4, 2 ) );
|
|
|
|
QVERIFY( !c28.addZValue( 4 ) ); //already has z value, test that existing z is unchanged
|
|
c28.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ) );
|
|
c28.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZ, 11, 12, 2 ) );
|
|
c28.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZ, 3, 4, 2 ) );
|
|
|
|
//linestring with m
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 4 ) );
|
|
c28.clear();
|
|
c28.addCurve( l28.clone() );
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 21, 32, 0, 4 ) );
|
|
c28.addCurve( l28.clone() );
|
|
QVERIFY( c28.addZValue( 5 ) );
|
|
QVERIFY( c28.is3D() );
|
|
QVERIFY( c28.isMeasure() );
|
|
QCOMPARE( c28.wkbType(), QgsWkbTypes::CompoundCurveZM );
|
|
c28.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 1, 2, 5, 3 ) );
|
|
c28.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 11, 12, 5, 4 ) );
|
|
c28.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 21, 32, 5, 4 ) );
|
|
|
|
//addMValue
|
|
c28.clear();
|
|
//2d line
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
c28.addCurve( l28.clone() );
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( 11, 12 ) << QgsPoint( 3, 4 ) );
|
|
c28.addCurve( l28.clone() );
|
|
QVERIFY( c28.addMValue( 2 ) );
|
|
QVERIFY( c28.isMeasure() );
|
|
QCOMPARE( c28.wkbType(), QgsWkbTypes::CompoundCurveM );
|
|
c28.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 2 ) );
|
|
c28.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 2 ) );
|
|
c28.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointM, 3, 4, 0, 2 ) );
|
|
|
|
QVERIFY( !c28.addMValue( 4 ) ); //already has z value, test that existing z is unchanged
|
|
c28.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 2 ) );
|
|
c28.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 2 ) );
|
|
c28.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointM, 3, 4, 0, 2 ) );
|
|
|
|
//linestring with z
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 4 ) );
|
|
c28.clear();
|
|
c28.addCurve( l28.clone() );
|
|
l28.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 21, 32, 4 ) );
|
|
c28.addCurve( l28.clone() );
|
|
QVERIFY( c28.addMValue( 5 ) );
|
|
QVERIFY( c28.is3D() );
|
|
QVERIFY( c28.isMeasure() );
|
|
QCOMPARE( c28.wkbType(), QgsWkbTypes::CompoundCurveZM );
|
|
c28.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 5 ) );
|
|
c28.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 ) );
|
|
c28.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 21, 32, 4, 5 ) );
|
|
|
|
//dropZValue
|
|
QgsCompoundCurve c28d;
|
|
QgsCircularString l28d;
|
|
QVERIFY( !c28d.dropZValue() );
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
c28d.addCurve( l28d.clone() );
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) );
|
|
c28d.addCurve( l28d.clone() );
|
|
QVERIFY( !c28d.dropZValue() );
|
|
c28d.addZValue( 1.0 );
|
|
QCOMPARE( c28d.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
QVERIFY( c28d.is3D() );
|
|
QVERIFY( c28d.dropZValue() );
|
|
QVERIFY( !c28d.is3D() );
|
|
QCOMPARE( c28d.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
c28d.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::Point, 1, 2 ) );
|
|
c28d.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::Point, 11, 12 ) );
|
|
c28d.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::Point, 21, 22 ) );
|
|
|
|
QVERIFY( !c28d.dropZValue() ); //already dropped
|
|
//linestring with m
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 3, 4 ) );
|
|
c28d.clear();
|
|
c28d.addCurve( l28d.clone() );
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 21, 22, 3, 4 ) );
|
|
c28d.addCurve( l28d.clone() );
|
|
QVERIFY( c28d.dropZValue() );
|
|
QVERIFY( !c28d.is3D() );
|
|
QVERIFY( c28d.isMeasure() );
|
|
QCOMPARE( c28d.wkbType(), QgsWkbTypes::CompoundCurveM );
|
|
c28d.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
c28d.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 4 ) );
|
|
c28d.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointM, 21, 22, 0, 4 ) );
|
|
|
|
//dropMValue
|
|
c28d.clear();
|
|
QVERIFY( !c28d.dropMValue() );
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
c28d.addCurve( l28d.clone() );
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) );
|
|
c28d.addCurve( l28d.clone() );
|
|
QVERIFY( !c28d.dropMValue() );
|
|
c28d.addMValue( 1.0 );
|
|
QCOMPARE( c28d.wkbType(), QgsWkbTypes::CompoundCurveM );
|
|
QVERIFY( c28d.isMeasure() );
|
|
QVERIFY( c28d.dropMValue() );
|
|
QVERIFY( !c28d.isMeasure() );
|
|
QCOMPARE( c28d.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
c28d.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::Point, 1, 2 ) );
|
|
c28d.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::Point, 11, 12 ) );
|
|
c28d.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::Point, 21, 22 ) );
|
|
|
|
QVERIFY( !c28d.dropMValue() ); //already dropped
|
|
//linestring with z
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 3, 4 ) );
|
|
c28d.clear();
|
|
c28d.addCurve( l28d.clone() );
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 21, 22, 3, 4 ) );
|
|
c28d.addCurve( l28d.clone() );
|
|
QVERIFY( c28d.dropMValue() );
|
|
QVERIFY( !c28d.isMeasure() );
|
|
QVERIFY( c28d.is3D() );
|
|
QCOMPARE( c28d.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
c28d.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
c28d.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZ, 11, 12, 3 ) );
|
|
c28d.pointAt( 2, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZ, 21, 22, 3 ) );
|
|
|
|
//convertTo
|
|
l28d.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
c28d.clear();
|
|
c28d.addCurve( l28d.clone() );
|
|
QVERIFY( c28d.convertTo( QgsWkbTypes::CompoundCurve ) );
|
|
QCOMPARE( c28d.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
QVERIFY( c28d.convertTo( QgsWkbTypes::CompoundCurveZ ) );
|
|
QCOMPARE( c28d.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
c28d.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZ, 1, 2 ) );
|
|
|
|
QVERIFY( c28d.convertTo( QgsWkbTypes::CompoundCurveZM ) );
|
|
QCOMPARE( c28d.wkbType(), QgsWkbTypes::CompoundCurveZM );
|
|
c28d.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 1, 2 ) );
|
|
c28d.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 1, 2, 5 ) );
|
|
c28d.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZM, 1, 2, 5.0 ) );
|
|
QVERIFY( c28d.convertTo( QgsWkbTypes::CompoundCurveM ) );
|
|
QCOMPARE( c28d.wkbType(), QgsWkbTypes::CompoundCurveM );
|
|
c28d.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointM, 1, 2 ) );
|
|
c28d.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 1, 2, 0, 6 ) );
|
|
c28d.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointM, 1, 2, 0.0, 6.0 ) );
|
|
QVERIFY( c28d.convertTo( QgsWkbTypes::CompoundCurve ) );
|
|
QCOMPARE( c28d.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
c28d.pointAt( 0, pt, v );
|
|
QCOMPARE( pt, QgsPoint( 1, 2 ) );
|
|
QVERIFY( !c28d.convertTo( QgsWkbTypes::Polygon ) );
|
|
|
|
//isRing
|
|
QgsCircularString l30;
|
|
QgsCompoundCurve c30;
|
|
QVERIFY( !c30.isRing() );
|
|
l30.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 2 ) );
|
|
c30.addCurve( l30.clone() );
|
|
QVERIFY( !c30.isRing() ); //<4 points
|
|
l30.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 31, 32 ) );
|
|
c30.clear();
|
|
c30.addCurve( l30.clone() );
|
|
QVERIFY( !c30.isRing() ); //not closed
|
|
l30.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 1, 2 ) );
|
|
c30.clear();
|
|
c30.addCurve( l30.clone() );
|
|
QVERIFY( c30.isRing() );
|
|
l30.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
c30.clear();
|
|
c30.addCurve( l30.clone() );
|
|
QVERIFY( !c30.isRing() );
|
|
l30.setPoints( QgsPointSequence() << QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) );
|
|
c30.addCurve( l30.clone() );
|
|
QVERIFY( !c30.isRing() );
|
|
l30.setPoints( QgsPointSequence() << QgsPoint( 21, 22 ) << QgsPoint( 1, 2 ) );
|
|
c30.addCurve( l30.clone() );
|
|
QVERIFY( c30.isRing() );
|
|
|
|
//coordinateSequence
|
|
QgsCompoundCurve c31;
|
|
QgsCircularString l31;
|
|
QgsCoordinateSequence coords = c31.coordinateSequence();
|
|
QCOMPARE( coords.count(), 1 );
|
|
QCOMPARE( coords.at( 0 ).count(), 1 );
|
|
QVERIFY( coords.at( 0 ).at( 0 ).isEmpty() );
|
|
l31.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
c31.addCurve( l31.clone() );
|
|
QgsLineString ls31;
|
|
ls31.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) <<
|
|
QgsPoint( QgsWkbTypes::PointZM, 31, 32, 16, 17 ) );
|
|
c31.addCurve( ls31.clone() );
|
|
coords = c31.coordinateSequence();
|
|
QCOMPARE( coords.count(), 1 );
|
|
QCOMPARE( coords.at( 0 ).count(), 1 );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).count(), 4 );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).at( 0 ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 2, 3 ) );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).at( 1 ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 4, 5 ) );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).at( 2 ), QgsPoint( QgsWkbTypes::PointZM, 21, 22, 6, 7 ) );
|
|
QCOMPARE( coords.at( 0 ).at( 0 ).at( 3 ), QgsPoint( QgsWkbTypes::PointZM, 31, 32, 16, 17 ) );
|
|
|
|
//nextVertex
|
|
QgsCompoundCurve c32;
|
|
QgsCircularString l32;
|
|
QgsVertexId vId;
|
|
QVERIFY( !c32.nextVertex( vId, p ) );
|
|
vId = QgsVertexId( 0, 0, -2 );
|
|
QVERIFY( !c32.nextVertex( vId, p ) );
|
|
vId = QgsVertexId( 0, 0, 10 );
|
|
QVERIFY( !c32.nextVertex( vId, p ) );
|
|
//CircularString
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) );
|
|
c32.addCurve( l32.clone() );
|
|
vId = QgsVertexId( 0, 0, 2 ); //out of range
|
|
QVERIFY( !c32.nextVertex( vId, p ) );
|
|
vId = QgsVertexId( 0, 0, -5 );
|
|
QVERIFY( c32.nextVertex( vId, p ) );
|
|
vId = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( c32.nextVertex( vId, p ) );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( 1, 2 ) );
|
|
QVERIFY( c32.nextVertex( vId, p ) );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( 11, 12 ) );
|
|
QVERIFY( !c32.nextVertex( vId, p ) );
|
|
vId = QgsVertexId( 0, 1, 0 );
|
|
QVERIFY( c32.nextVertex( vId, p ) );
|
|
QCOMPARE( vId, QgsVertexId( 0, 1, 1 ) ); //test that ring number is maintained
|
|
QCOMPARE( p, QgsPoint( 11, 12 ) );
|
|
vId = QgsVertexId( 1, 0, 0 );
|
|
QVERIFY( c32.nextVertex( vId, p ) );
|
|
QCOMPARE( vId, QgsVertexId( 1, 0, 1 ) ); //test that part number is maintained
|
|
QCOMPARE( p, QgsPoint( 11, 12 ) );
|
|
QgsLineString ls32;
|
|
ls32.setPoints( QgsPointSequence() << QgsPoint( 11, 12 ) << QgsPoint( 13, 14 ) );
|
|
c32.addCurve( ls32.clone() );
|
|
vId = QgsVertexId( 0, 0, 1 );
|
|
QVERIFY( c32.nextVertex( vId, p ) );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( p, QgsPoint( 13, 14 ) );
|
|
QVERIFY( !c32.nextVertex( vId, p ) );
|
|
|
|
//CircularStringZ
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
c32.clear();
|
|
c32.addCurve( l32.clone() );
|
|
vId = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( c32.nextVertex( vId, p ) );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QVERIFY( c32.nextVertex( vId, p ) );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
QVERIFY( !c32.nextVertex( vId, p ) );
|
|
//CircularStringM
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
c32.clear();
|
|
c32.addCurve( l32.clone() );
|
|
vId = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( c32.nextVertex( vId, p ) );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QVERIFY( c32.nextVertex( vId, p ) );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
QVERIFY( !c32.nextVertex( vId, p ) );
|
|
//CircularStringZM
|
|
l32.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
c32.clear();
|
|
c32.addCurve( l32.clone() );
|
|
vId = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( c32.nextVertex( vId, p ) );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
QVERIFY( c32.nextVertex( vId, p ) );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
QVERIFY( !c32.nextVertex( vId, p ) );
|
|
|
|
//vertexAt and pointAt
|
|
QgsCompoundCurve c33;
|
|
QgsCircularString l33;
|
|
c33.vertexAt( QgsVertexId( 0, 0, -10 ) ); //out of bounds, check for no crash
|
|
c33.vertexAt( QgsVertexId( 0, 0, 10 ) ); //out of bounds, check for no crash
|
|
QVERIFY( !c33.pointAt( -10, p, type ) );
|
|
QVERIFY( !c33.pointAt( 10, p, type ) );
|
|
//CircularString
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 22 ) );
|
|
c33.addCurve( l33.clone() );
|
|
c33.vertexAt( QgsVertexId( 0, 0, -10 ) );
|
|
c33.vertexAt( QgsVertexId( 0, 0, 10 ) ); //out of bounds, check for no crash
|
|
QCOMPARE( c33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( c33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( 11, 12 ) );
|
|
QCOMPARE( c33.vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( 1, 22 ) );
|
|
QVERIFY( !c33.pointAt( -10, p, type ) );
|
|
QVERIFY( !c33.pointAt( 10, p, type ) );
|
|
QVERIFY( c33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( 1, 2 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( c33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( 11, 12 ) );
|
|
QCOMPARE( type, QgsVertexId::CurveVertex );
|
|
QVERIFY( c33.pointAt( 2, p, type ) );
|
|
QCOMPARE( p, QgsPoint( 1, 22 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QgsLineString ls33;
|
|
ls33.setPoints( QgsPointSequence() << QgsPoint( 1, 22 ) << QgsPoint( 3, 34 ) );
|
|
c33.addCurve( ls33.clone() );
|
|
QVERIFY( c33.pointAt( 3, p, type ) );
|
|
QCOMPARE( p, QgsPoint( 3, 34 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
|
|
c33.clear();
|
|
//CircularStringZ
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 22, 23 ) );
|
|
c33.addCurve( l33.clone() );
|
|
QCOMPARE( c33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QCOMPARE( c33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
QCOMPARE( c33.vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( QgsWkbTypes::PointZ, 1, 22, 23 ) );
|
|
QVERIFY( c33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( c33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
QCOMPARE( type, QgsVertexId::CurveVertex );
|
|
QVERIFY( c33.pointAt( 2, p, type ) );
|
|
QCOMPARE( p, QgsPoint( 1, 22, 23 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
|
|
//CircularStringM
|
|
c33.clear();
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) << QgsPoint( QgsWkbTypes::PointM, 1, 22, 0, 24 ) );
|
|
c33.addCurve( l33.clone() );
|
|
QCOMPARE( c33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QCOMPARE( c33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
QCOMPARE( c33.vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( QgsWkbTypes::PointM, 1, 22, 0, 24 ) );
|
|
QVERIFY( c33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( c33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 14 ) );
|
|
QCOMPARE( type, QgsVertexId::CurveVertex );
|
|
QVERIFY( c33.pointAt( 2, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointM, 1, 22, 0, 24 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
//CircularStringZM
|
|
l33.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 22, 23, 24 ) );
|
|
c33.clear();
|
|
c33.addCurve( l33.clone() );
|
|
QCOMPARE( c33.vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
QCOMPARE( c33.vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
QCOMPARE( c33.vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 22, 23, 24 ) );
|
|
QVERIFY( c33.pointAt( 0, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
QVERIFY( c33.pointAt( 1, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 ) );
|
|
QCOMPARE( type, QgsVertexId::CurveVertex );
|
|
QVERIFY( c33.pointAt( 2, p, type ) );
|
|
QCOMPARE( p, QgsPoint( QgsWkbTypes::PointZM, 1, 22, 23, 24 ) );
|
|
QCOMPARE( type, QgsVertexId::SegmentVertex );
|
|
|
|
//centroid
|
|
QgsCircularString l34;
|
|
QgsCompoundCurve c34;
|
|
QCOMPARE( c34.centroid(), QgsPoint() );
|
|
l34.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) );
|
|
c34.addCurve( l34.clone() );
|
|
QCOMPARE( c34.centroid(), QgsPoint( 5, 10 ) );
|
|
l34.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 20, 10 ) << QgsPoint( 2, 9 ) );
|
|
c34.clear();
|
|
c34.addCurve( l34.clone() );
|
|
QgsPoint centroid = c34.centroid();
|
|
QGSCOMPARENEAR( centroid.x(), 7.333, 0.001 );
|
|
QGSCOMPARENEAR( centroid.y(), 6.333, 0.001 );
|
|
l34.setPoints( QgsPointSequence() << QgsPoint( 2, 9 ) << QgsPoint( 12, 9 ) << QgsPoint( 15, 19 ) );
|
|
c34.addCurve( l34.clone() );
|
|
centroid = c34.centroid();
|
|
QGSCOMPARENEAR( centroid.x(), 9.756646, 0.001 );
|
|
QGSCOMPARENEAR( centroid.y(), 8.229039, 0.001 );
|
|
|
|
//closest segment
|
|
QgsCompoundCurve c35;
|
|
QgsCircularString l35;
|
|
bool leftOf = false;
|
|
p = QgsPoint(); // reset all coords to zero
|
|
( void )c35.closestSegment( QgsPoint( 1, 2 ), p, vId ); //empty line, just want no crash
|
|
l35.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) );
|
|
c35.addCurve( l35.clone() );
|
|
QVERIFY( c35.closestSegment( QgsPoint( 5, 10 ), p, vId ) < 0 );
|
|
l35.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 7, 12 ) << QgsPoint( 5, 15 ) );
|
|
c35.clear();
|
|
c35.addCurve( l35.clone() );
|
|
QGSCOMPARENEAR( c35.closestSegment( QgsPoint( 4, 11 ), p, vId, &leftOf ), 2.0, 0.0001 );
|
|
QCOMPARE( p, QgsPoint( 5, 10 ) );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( c35.closestSegment( QgsPoint( 8, 11 ), p, vId, &leftOf ), 1.583512, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 6.84, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 11.49, 0.01 );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( c35.closestSegment( QgsPoint( 5.5, 11.5 ), p, vId, &leftOf ), 1.288897, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 6.302776, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 10.7, 0.01 );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( c35.closestSegment( QgsPoint( 7, 16 ), p, vId, &leftOf ), 3.068288, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 5.981872, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 14.574621, 0.01 );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( c35.closestSegment( QgsPoint( 5.5, 13.5 ), p, vId, &leftOf ), 1.288897, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 6.302776, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 14.3, 0.01 );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, true );
|
|
// point directly on segment
|
|
QCOMPARE( c35.closestSegment( QgsPoint( 5, 15 ), p, vId, &leftOf ), 0.0 );
|
|
QCOMPARE( p, QgsPoint( 5, 15 ) );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 2 ) );
|
|
|
|
QgsLineString ls35;
|
|
ls35.setPoints( QgsPointSequence() << QgsPoint( 5, 15 ) << QgsPoint( 5, 20 ) );
|
|
c35.addCurve( ls35.clone() );
|
|
QGSCOMPARENEAR( c35.closestSegment( QgsPoint( 5.5, 16.5 ), p, vId, &leftOf ), 0.25, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 5.0, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 16.5, 0.01 );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( c35.closestSegment( QgsPoint( 4.5, 16.5 ), p, vId, &leftOf ), 0.25, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 5.0, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 16.5, 0.01 );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( c35.closestSegment( QgsPoint( 4.5, 21.5 ), p, vId, &leftOf ), 2.500000, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 5.0, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 20.0, 0.01 );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( c35.closestSegment( QgsPoint( 5.5, 21.5 ), p, vId, &leftOf ), 2.500000, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 5.0, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 20.0, 0.01 );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( c35.closestSegment( QgsPoint( 5, 20 ), p, vId, &leftOf ), 0.0000, 0.0001 );
|
|
QGSCOMPARENEAR( p.x(), 5.0, 0.01 );
|
|
QGSCOMPARENEAR( p.y(), 20.0, 0.01 );
|
|
QCOMPARE( vId, QgsVertexId( 0, 0, 3 ) );
|
|
|
|
//sumUpArea
|
|
QgsCompoundCurve c36;
|
|
QgsCircularString l36;
|
|
double area = 1.0; //sumUpArea adds to area, so start with non-zero value
|
|
c36.sumUpArea( area );
|
|
QCOMPARE( area, 1.0 );
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) );
|
|
c36.addCurve( l36.clone() );
|
|
c36.sumUpArea( area );
|
|
QCOMPARE( area, 1.0 );
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 10, 10 ) );
|
|
c36.clear();
|
|
c36.addCurve( l36.clone() );
|
|
c36.sumUpArea( area );
|
|
QCOMPARE( area, 1.0 );
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 2, 0 ) << QgsPoint( 2, 2 ) );
|
|
c36.clear();
|
|
c36.addCurve( l36.clone() );
|
|
c36.sumUpArea( area );
|
|
QGSCOMPARENEAR( area, 4.141593, 0.0001 );
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 2, 0 ) << QgsPoint( 2, 2 ) << QgsPoint( 0, 2 ) );
|
|
c36.clear();
|
|
c36.addCurve( l36.clone() );
|
|
c36.sumUpArea( area );
|
|
QGSCOMPARENEAR( area, 7.283185, 0.0001 );
|
|
// full circle
|
|
l36.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 4, 0 ) << QgsPoint( 0, 0 ) );
|
|
c36.clear();
|
|
c36.addCurve( l36.clone() );
|
|
area = 0.0;
|
|
c36.sumUpArea( area );
|
|
QGSCOMPARENEAR( area, 12.566370614359172, 0.0001 );
|
|
|
|
//boundingBox - test that bounding box is updated after every modification to the circular string
|
|
QgsCompoundCurve c37;
|
|
QgsCircularString l37;
|
|
QVERIFY( c37.boundingBox().isNull() );
|
|
l37.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 10, 15 ) );
|
|
c37.addCurve( l37.clone() );
|
|
QCOMPARE( c37.boundingBox(), QgsRectangle( 5, 10, 10, 15 ) );
|
|
l37.setPoints( QgsPointSequence() << QgsPoint( -5, -10 ) << QgsPoint( -6, -10 ) << QgsPoint( -5.5, -9 ) );
|
|
c37.clear();
|
|
c37.addCurve( l37.clone() );
|
|
QCOMPARE( c37.boundingBox(), QgsRectangle( -6.125, -10.25, -5, -9 ) );
|
|
QByteArray wkbToAppend = c37.asWkb();
|
|
c37.clear();
|
|
QVERIFY( c37.boundingBox().isNull() );
|
|
QgsConstWkbPtr wkbToAppendPtr( wkbToAppend );
|
|
l37.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 10, 15 ) );
|
|
c37.clear();
|
|
c37.addCurve( l37.clone() );
|
|
QCOMPARE( c37.boundingBox(), QgsRectangle( 5, 10, 10, 15 ) );
|
|
c37.fromWkb( wkbToAppendPtr );
|
|
QCOMPARE( c37.boundingBox(), QgsRectangle( -6.125, -10.25, -5, -9 ) );
|
|
c37.fromWkt( QStringLiteral( "CompoundCurve(CircularString( 5 10, 6 10, 5.5 9 ))" ) );
|
|
QCOMPARE( c37.boundingBox(), QgsRectangle( 5, 9, 6.125, 10.25 ) );
|
|
c37.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( -1, 7 ) );
|
|
QgsRectangle r = c37.boundingBox();
|
|
QGSCOMPARENEAR( r.xMinimum(), -3.014, 0.01 );
|
|
QGSCOMPARENEAR( r.xMaximum(), 14.014, 0.01 );
|
|
QGSCOMPARENEAR( r.yMinimum(), -7.0146, 0.01 );
|
|
QGSCOMPARENEAR( r.yMaximum(), 12.4988, 0.01 );
|
|
c37.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( -3, 10 ) );
|
|
r = c37.boundingBox();
|
|
QGSCOMPARENEAR( r.xMinimum(), -10.294, 0.01 );
|
|
QGSCOMPARENEAR( r.xMaximum(), 12.294, 0.01 );
|
|
QGSCOMPARENEAR( r.yMinimum(), 9, 0.01 );
|
|
QGSCOMPARENEAR( r.yMaximum(), 31.856, 0.01 );
|
|
c37.deleteVertex( QgsVertexId( 0, 0, 1 ) );
|
|
r = c37.boundingBox();
|
|
QGSCOMPARENEAR( r.xMinimum(), 5, 0.01 );
|
|
QGSCOMPARENEAR( r.xMaximum(), 6.125, 0.01 );
|
|
QGSCOMPARENEAR( r.yMinimum(), 9, 0.01 );
|
|
QGSCOMPARENEAR( r.yMaximum(), 10.25, 0.01 );
|
|
|
|
//angle
|
|
QgsCompoundCurve c38;
|
|
QgsCircularString l38;
|
|
( void )c38.vertexAngle( QgsVertexId() ); //just want no crash
|
|
( void )c38.vertexAngle( QgsVertexId( 0, 0, 0 ) ); //just want no crash
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) );
|
|
c38.addCurve( l38.clone() );
|
|
( void )c38.vertexAngle( QgsVertexId( 0, 0, 0 ) ); //just want no crash, any answer is meaningless
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) );
|
|
c38.clear();
|
|
c38.addCurve( l38.clone() );
|
|
( void )c38.vertexAngle( QgsVertexId( 0, 0, 0 ) ); //just want no crash, any answer is meaningless
|
|
( void )c38.vertexAngle( QgsVertexId( 0, 0, 1 ) ); //just want no crash, any answer is meaningless
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 2 ) );
|
|
c38.clear();
|
|
c38.addCurve( l38.clone() );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 0, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 4.712389, 0.0001 );
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 2 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
c38.clear();
|
|
c38.addCurve( l38.clone() );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 3.141593, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 4.712389, 0.0001 );
|
|
( void )c38.vertexAngle( QgsVertexId( 0, 0, 20 ) ); // no crash
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 2 )
|
|
<< QgsPoint( -1, 3 ) << QgsPoint( 0, 4 ) );
|
|
c38.clear();
|
|
c38.addCurve( l38.clone() );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 0, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 4.712389, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 3 ) ), 0, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 4 ) ), 1.5708, 0.0001 );
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 4 ) << QgsPoint( -1, 3 ) << QgsPoint( 0, 2 )
|
|
<< QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
c38.clear();
|
|
c38.addCurve( l38.clone() );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 4.712389, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 3.141592, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 3 ) ), 3.141592, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 4 ) ), 4.712389, 0.0001 );
|
|
|
|
// with second curve
|
|
QgsLineString ls38;
|
|
ls38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, -1 ) );
|
|
c38.addCurve( ls38.clone() );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 4 ) ), 3.926991, 0.0001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 5 ) ), 3.141593, 0.0001 );
|
|
|
|
//closed circular string
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 0, 0 ) );
|
|
c38.clear();
|
|
c38.addCurve( l38.clone() );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 0, 0.00001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 3.141592, 0.00001 );
|
|
QGSCOMPARENEAR( c38.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 0, 0.00001 );
|
|
|
|
//removing a vertex from a 3 point comound curveshould remove the whole line
|
|
QgsCircularString l39;
|
|
QgsCompoundCurve c39;
|
|
l39.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 2 ) );
|
|
c39.addCurve( l39.clone() );
|
|
QCOMPARE( c39.numPoints(), 3 );
|
|
c39.deleteVertex( QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( c39.numPoints(), 0 );
|
|
|
|
//boundary
|
|
QgsCompoundCurve cBoundary1;
|
|
QgsCircularString boundary1;
|
|
QVERIFY( !cBoundary1.boundary() );
|
|
boundary1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) );
|
|
cBoundary1.addCurve( boundary1.clone() );
|
|
QgsAbstractGeometry *boundary = cBoundary1.boundary();
|
|
QgsMultiPointV2 *mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
delete boundary;
|
|
|
|
// closed string = no boundary
|
|
boundary1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
cBoundary1.clear();
|
|
cBoundary1.addCurve( boundary1.clone() );
|
|
QVERIFY( !cBoundary1.boundary() );
|
|
|
|
//boundary with z
|
|
boundary1.setPoints( QList<QgsPoint>() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 10 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 0, 15 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 20 ) );
|
|
cBoundary1.clear();
|
|
cBoundary1.addCurve( boundary1.clone() );
|
|
boundary = cBoundary1.boundary();
|
|
mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->geometryN( 0 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->z(), 10.0 );
|
|
QCOMPARE( mpBoundary->geometryN( 1 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->z(), 20.0 );
|
|
delete boundary;
|
|
|
|
// addToPainterPath (note most tests are in test_qgsgeometry.py)
|
|
QgsCompoundCurve ccPath;
|
|
QgsCircularString path;
|
|
QPainterPath pPath;
|
|
ccPath.addToPainterPath( pPath );
|
|
QVERIFY( pPath.isEmpty() );
|
|
path.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 21, 2, 3 ) );
|
|
ccPath.addCurve( path.clone() );
|
|
ccPath.addToPainterPath( pPath );
|
|
QGSCOMPARENEAR( pPath.currentPosition().x(), 21.0, 0.01 );
|
|
QGSCOMPARENEAR( pPath.currentPosition().y(), 2.0, 0.01 );
|
|
QVERIFY( !pPath.isEmpty() );
|
|
QgsLineString lsPath;
|
|
lsPath.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 21, 2, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 31, 12, 3 ) );
|
|
ccPath.addCurve( lsPath.clone() );
|
|
pPath = QPainterPath();
|
|
ccPath.addToPainterPath( pPath );
|
|
QGSCOMPARENEAR( pPath.currentPosition().x(), 31.0, 0.01 );
|
|
QGSCOMPARENEAR( pPath.currentPosition().y(), 12.0, 0.01 );
|
|
|
|
// even number of points - should still work
|
|
pPath = QPainterPath();
|
|
path.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZ, 11, 12, 13 ) );
|
|
ccPath.clear();
|
|
ccPath.addCurve( path.clone() );
|
|
ccPath.addToPainterPath( pPath );
|
|
QGSCOMPARENEAR( pPath.currentPosition().x(), 11.0, 0.01 );
|
|
QGSCOMPARENEAR( pPath.currentPosition().y(), 12.0, 0.01 );
|
|
QVERIFY( !pPath.isEmpty() );
|
|
|
|
// toCurveType
|
|
QgsCircularString curveLine1;
|
|
QgsCompoundCurve cc1;
|
|
curveLine1.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 22 ) );
|
|
cc1.addCurve( curveLine1.clone() );
|
|
std::unique_ptr< QgsCurve > curveType( cc1.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::CompoundCurve );
|
|
QCOMPARE( curveType->numPoints(), 3 );
|
|
QCOMPARE( curveType->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( curveType->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( 11, 12 ) );
|
|
QCOMPARE( curveType->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( 1, 22 ) );
|
|
QgsLineString ccls1;
|
|
ccls1.setPoints( QgsPointSequence() << QgsPoint( 1, 22 ) << QgsPoint( 1, 25 ) );
|
|
cc1.addCurve( ccls1.clone() );
|
|
curveType.reset( cc1.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::CompoundCurve );
|
|
QCOMPARE( curveType->numPoints(), 4 );
|
|
QCOMPARE( curveType->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( curveType->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( 11, 12 ) );
|
|
QCOMPARE( curveType->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( 1, 22 ) );
|
|
QCOMPARE( curveType->vertexAt( QgsVertexId( 0, 0, 3 ) ), QgsPoint( 1, 25 ) );
|
|
|
|
//test that area of a compound curve ring is equal to a closed linestring with the same vertices
|
|
QgsCompoundCurve cc;
|
|
QgsLineString *ll1 = new QgsLineString();
|
|
ll1->setPoints( QgsPointSequence() << QgsPoint( 1, 1 ) << QgsPoint( 0, 2 ) );
|
|
cc.addCurve( ll1 );
|
|
QgsLineString *ll2 = new QgsLineString();
|
|
ll2->setPoints( QgsPointSequence() << QgsPoint( 0, 2 ) << QgsPoint( -1, 0 ) << QgsPoint( 0, -1 ) );
|
|
cc.addCurve( ll2 );
|
|
QgsLineString *ll3 = new QgsLineString();
|
|
ll3->setPoints( QgsPointSequence() << QgsPoint( 0, -1 ) << QgsPoint( 1, 1 ) );
|
|
cc.addCurve( ll3 );
|
|
|
|
double ccArea = 0.0;
|
|
cc.sumUpArea( ccArea );
|
|
|
|
QgsLineString ls;
|
|
ls.setPoints( QgsPointSequence() << QgsPoint( 1, 1 ) << QgsPoint( 0, 2 ) << QgsPoint( -1, 0 ) << QgsPoint( 0, -1 )
|
|
<< QgsPoint( 1, 1 ) );
|
|
double lsArea = 0.0;
|
|
ls.sumUpArea( lsArea );
|
|
QGSCOMPARENEAR( ccArea, lsArea, 4 * DBL_EPSILON );
|
|
|
|
|
|
//addVertex
|
|
QgsCompoundCurve ac1;
|
|
ac1.addVertex( QgsPoint( 1.0, 2.0 ) );
|
|
QVERIFY( !ac1.isEmpty() );
|
|
QCOMPARE( ac1.numPoints(), 1 );
|
|
QCOMPARE( ac1.vertexCount(), 1 );
|
|
QCOMPARE( ac1.nCoordinates(), 1 );
|
|
QCOMPARE( ac1.ringCount(), 1 );
|
|
QCOMPARE( ac1.partCount(), 1 );
|
|
QVERIFY( !ac1.is3D() );
|
|
QVERIFY( !ac1.isMeasure() );
|
|
QCOMPARE( ac1.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
QVERIFY( !ac1.hasCurvedSegments() );
|
|
QCOMPARE( ac1.area(), 0.0 );
|
|
QCOMPARE( ac1.perimeter(), 0.0 );
|
|
|
|
//adding first vertex should set linestring z/m type
|
|
QgsCompoundCurve ac2;
|
|
ac2.addVertex( QgsPoint( QgsWkbTypes::PointZ, 1.0, 2.0, 3.0 ) );
|
|
QVERIFY( !ac2.isEmpty() );
|
|
QVERIFY( ac2.is3D() );
|
|
QVERIFY( !ac2.isMeasure() );
|
|
QCOMPARE( ac2.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
QCOMPARE( ac2.wktTypeStr(), QString( "CompoundCurveZ" ) );
|
|
|
|
QgsCompoundCurve ac3;
|
|
ac3.addVertex( QgsPoint( QgsWkbTypes::PointM, 1.0, 2.0, 0.0, 3.0 ) );
|
|
QVERIFY( !ac3.isEmpty() );
|
|
QVERIFY( !ac3.is3D() );
|
|
QVERIFY( ac3.isMeasure() );
|
|
QCOMPARE( ac3.wkbType(), QgsWkbTypes::CompoundCurveM );
|
|
QCOMPARE( ac3.wktTypeStr(), QString( "CompoundCurveM" ) );
|
|
|
|
QgsCompoundCurve ac4;
|
|
ac4.addVertex( QgsPoint( QgsWkbTypes::PointZM, 1.0, 2.0, 3.0, 4.0 ) );
|
|
QVERIFY( !ac4.isEmpty() );
|
|
QVERIFY( ac4.is3D() );
|
|
QVERIFY( ac4.isMeasure() );
|
|
QCOMPARE( ac4.wkbType(), QgsWkbTypes::CompoundCurveZM );
|
|
QCOMPARE( ac4.wktTypeStr(), QString( "CompoundCurveZM" ) );
|
|
|
|
//adding subsequent vertices should not alter z/m type, regardless of points type
|
|
QgsCompoundCurve ac5;
|
|
ac5.addVertex( QgsPoint( QgsWkbTypes::Point, 1.0, 2.0 ) ); //2d type
|
|
QCOMPARE( ac5.wkbType(), QgsWkbTypes::CompoundCurve );
|
|
ac5.addVertex( QgsPoint( QgsWkbTypes::PointZ, 11.0, 12.0, 13.0 ) ); // add 3d point
|
|
QCOMPARE( ac5.numPoints(), 2 );
|
|
QCOMPARE( ac5.vertexCount(), 2 );
|
|
QCOMPARE( ac5.nCoordinates(), 2 );
|
|
QCOMPARE( ac5.ringCount(), 1 );
|
|
QCOMPARE( ac5.partCount(), 1 );
|
|
QCOMPARE( ac5.wkbType(), QgsWkbTypes::CompoundCurve ); //should still be 2d
|
|
QVERIFY( !ac5.is3D() );
|
|
QCOMPARE( ac5.area(), 0.0 );
|
|
QCOMPARE( ac5.perimeter(), 0.0 );
|
|
|
|
QgsCompoundCurve ac6;
|
|
ac6.addVertex( QgsPoint( QgsWkbTypes::PointZ, 1.0, 2.0, 3.0 ) ); //3d type
|
|
QCOMPARE( ac6.wkbType(), QgsWkbTypes::CompoundCurveZ );
|
|
ac6.addVertex( QgsPoint( QgsWkbTypes::Point, 11.0, 12.0 ) ); //add 2d point
|
|
QCOMPARE( ac6.wkbType(), QgsWkbTypes::CompoundCurveZ ); //should still be 3d
|
|
ac6.pointAt( 1, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::PointZ, 11.0, 12.0 ) );
|
|
QVERIFY( ac6.is3D() );
|
|
QCOMPARE( ac6.numPoints(), 2 );
|
|
QCOMPARE( ac6.vertexCount(), 2 );
|
|
QCOMPARE( ac6.nCoordinates(), 2 );
|
|
QCOMPARE( ac6.ringCount(), 1 );
|
|
QCOMPARE( ac6.partCount(), 1 );
|
|
|
|
//close
|
|
QgsLineString closeC1;
|
|
QgsCompoundCurve closeCc1;
|
|
closeCc1.close();
|
|
QVERIFY( closeCc1.isEmpty() );
|
|
closeC1.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 22 ) );
|
|
closeCc1.addCurve( closeC1.clone() );
|
|
QCOMPARE( closeCc1.numPoints(), 3 );
|
|
QVERIFY( !closeCc1.isClosed() );
|
|
closeCc1.close();
|
|
QCOMPARE( closeCc1.numPoints(), 4 );
|
|
QVERIFY( closeCc1.isClosed() );
|
|
closeCc1.pointAt( 3, pt, v );
|
|
QCOMPARE( pt, QgsPoint( QgsWkbTypes::Point, 1, 2 ) );
|
|
closeCc1.close();
|
|
QCOMPARE( closeCc1.numPoints(), 4 );
|
|
QVERIFY( closeCc1.isClosed() );
|
|
|
|
}
|
|
|
|
void TestQgsGeometry::multiPoint()
|
|
{
|
|
//test constructor
|
|
QgsMultiPointV2 c1;
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiPoint );
|
|
QCOMPARE( c1.wktTypeStr(), QString( "MultiPoint" ) );
|
|
QCOMPARE( c1.geometryType(), QString( "MultiPoint" ) );
|
|
QCOMPARE( c1.dimension(), 0 );
|
|
QVERIFY( !c1.hasCurvedSegments() );
|
|
QCOMPARE( c1.area(), 0.0 );
|
|
QCOMPARE( c1.perimeter(), 0.0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
QCOMPARE( c1.vertexCount( 0, 0 ), 0 );
|
|
QCOMPARE( c1.vertexCount( 0, 1 ), 0 );
|
|
QCOMPARE( c1.vertexCount( 1, 0 ), 0 );
|
|
|
|
//addGeometry
|
|
|
|
//try with nullptr
|
|
c1.addGeometry( nullptr );
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiPoint );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
|
|
// not a point
|
|
QVERIFY( !c1.addGeometry( new QgsLineString() ) );
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiPoint );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
|
|
//valid geometry
|
|
QgsPoint part( 1, 10 );
|
|
c1.addGeometry( part.clone() );
|
|
QVERIFY( !c1.isEmpty() );
|
|
QCOMPARE( c1.numGeometries(), 1 );
|
|
QCOMPARE( c1.nCoordinates(), 1 );
|
|
QCOMPARE( c1.ringCount(), 1 );
|
|
QCOMPARE( c1.partCount(), 1 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiPoint );
|
|
QCOMPARE( c1.wktTypeStr(), QString( "MultiPoint" ) );
|
|
QCOMPARE( c1.geometryType(), QString( "MultiPoint" ) );
|
|
QCOMPARE( c1.dimension(), 0 );
|
|
QVERIFY( !c1.hasCurvedSegments() );
|
|
QCOMPARE( c1.area(), 0.0 );
|
|
QCOMPARE( c1.perimeter(), 0.0 );
|
|
QVERIFY( c1.geometryN( 0 ) );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c1.geometryN( 0 ) ), part );
|
|
QVERIFY( !c1.geometryN( 100 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
QCOMPARE( c1.vertexCount( 0, 0 ), 1 );
|
|
QCOMPARE( c1.vertexCount( 1, 0 ), 0 );
|
|
|
|
//initial adding of geometry should set z/m type
|
|
part = QgsPoint( QgsWkbTypes::PointZ, 10, 11, 1 );
|
|
QgsMultiPointV2 c2;
|
|
c2.addGeometry( part.clone() );
|
|
QVERIFY( c2.is3D() );
|
|
QVERIFY( !c2.isMeasure() );
|
|
QCOMPARE( c2.wkbType(), QgsWkbTypes::MultiPointZ );
|
|
QCOMPARE( c2.wktTypeStr(), QString( "MultiPointZ" ) );
|
|
QCOMPARE( c2.geometryType(), QString( "MultiPoint" ) );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c2.geometryN( 0 ) ) ), part );
|
|
QgsMultiPointV2 c3;
|
|
part = QgsPoint( QgsWkbTypes::PointM, 10, 10, 0, 3 );
|
|
c3.addGeometry( part.clone() );
|
|
QVERIFY( !c3.is3D() );
|
|
QVERIFY( c3.isMeasure() );
|
|
QCOMPARE( c3.wkbType(), QgsWkbTypes::MultiPointM );
|
|
QCOMPARE( c3.wktTypeStr(), QString( "MultiPointM" ) );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c3.geometryN( 0 ) ) ), part );
|
|
QgsMultiPointV2 c4;
|
|
part = QgsPoint( QgsWkbTypes::PointZM, 10, 10, 5, 3 );
|
|
c4.addGeometry( part.clone() );
|
|
QVERIFY( c4.is3D() );
|
|
QVERIFY( c4.isMeasure() );
|
|
QCOMPARE( c4.wkbType(), QgsWkbTypes::MultiPointZM );
|
|
QCOMPARE( c4.wktTypeStr(), QString( "MultiPointZM" ) );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c4.geometryN( 0 ) ) ), part );
|
|
|
|
//add another part
|
|
QgsMultiPointV2 c6;
|
|
part = QgsPoint( 10, 11 );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 1 );
|
|
part = QgsPoint( 9, 1 );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 1 );
|
|
QCOMPARE( c6.numGeometries(), 2 );
|
|
QVERIFY( c6.geometryN( 0 ) );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c6.geometryN( 1 ) ), part );
|
|
|
|
QgsCoordinateSequence seq = c6.coordinateSequence();
|
|
QCOMPARE( seq, QgsCoordinateSequence() << ( QgsRingSequence() << ( QgsPointSequence() << QgsPoint( 10, 11 ) ) )
|
|
<< ( QgsRingSequence() << ( QgsPointSequence() << QgsPoint( 9, 1 ) ) ) );
|
|
QCOMPARE( c6.nCoordinates(), 2 );
|
|
|
|
//adding subsequent points should not alter z/m type, regardless of points type
|
|
c6.clear();
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPoint );
|
|
c6.addGeometry( new QgsPoint( QgsWkbTypes::PointZ, 1.0, 2.0, 3 ) );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPoint );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 1 );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 1 );
|
|
QCOMPARE( c6.vertexCount( 2, 0 ), 0 );
|
|
QCOMPARE( c6.vertexCount( -1, 0 ), 0 );
|
|
QCOMPARE( c6.nCoordinates(), 2 );
|
|
QCOMPARE( c6.ringCount(), 1 );
|
|
QCOMPARE( c6.partCount(), 2 );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPoint ); //should still be 2d
|
|
QVERIFY( !c6.is3D() );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c6.geometryN( 1 ) ) ), QgsPoint( 1, 2 ) );
|
|
c6.addGeometry( new QgsPoint( QgsWkbTypes::PointM, 11.0, 12.0, 0, 3 ) );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPoint );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 1 );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 1 );
|
|
QCOMPARE( c6.vertexCount( 2, 0 ), 1 );
|
|
QCOMPARE( c6.nCoordinates(), 3 );
|
|
QCOMPARE( c6.ringCount(), 1 );
|
|
QCOMPARE( c6.partCount(), 3 );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPoint ); //should still be 2d
|
|
QVERIFY( !c6.is3D() );
|
|
QVERIFY( !c6.isMeasure() );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c6.geometryN( 2 ) ) ), QgsPoint( 11, 12 ) );
|
|
|
|
c6.clear();
|
|
c6.addGeometry( new QgsPoint( QgsWkbTypes::PointZ, 1.0, 2.0, 3 ) );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPointZ );
|
|
c6.addGeometry( new QgsPoint( QgsWkbTypes::Point, 11.0, 12.0 ) );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPointZ );
|
|
QVERIFY( c6.is3D() );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c6.geometryN( 0 ) ) ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c6.geometryN( 1 ) ) ), QgsPoint( QgsWkbTypes::PointZ, 11, 12, 0 ) );
|
|
c6.addGeometry( new QgsPoint( QgsWkbTypes::PointM, 21.0, 22.0, 0, 3 ) );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPointZ );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( !c6.isMeasure() );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c6.geometryN( 2 ) ) ), QgsPoint( QgsWkbTypes::PointZ, 21, 22, 0 ) );
|
|
|
|
c6.clear();
|
|
c6.addGeometry( new QgsPoint( QgsWkbTypes::PointM, 1.0, 2.0, 0, 3 ) );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPointM );
|
|
c6.addGeometry( new QgsPoint( QgsWkbTypes::Point, 11.0, 12.0 ) );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPointM );
|
|
QVERIFY( c6.isMeasure() );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c6.geometryN( 0 ) ) ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c6.geometryN( 1 ) ) ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 0 ) );
|
|
c6.addGeometry( new QgsPoint( QgsWkbTypes::PointZ, 21.0, 22.0, 3 ) );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPointM );
|
|
QVERIFY( !c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c6.geometryN( 2 ) ) ), QgsPoint( QgsWkbTypes::PointM, 21, 22, 0, 0 ) );
|
|
|
|
c6.clear();
|
|
c6.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 1.0, 2.0, 4, 3 ) );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPointZM );
|
|
c6.addGeometry( new QgsPoint( QgsWkbTypes::Point, 11.0, 12.0 ) );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPointZM );
|
|
QVERIFY( c6.isMeasure() );
|
|
QVERIFY( c6.is3D() );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c6.geometryN( 0 ) ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 4, 3 ) );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c6.geometryN( 1 ) ) ), QgsPoint( QgsWkbTypes::PointZM, 11, 12, 0, 0 ) );
|
|
c6.addGeometry( new QgsPoint( QgsWkbTypes::PointZ, 21.0, 22.0, 3 ) );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPointZM );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c6.geometryN( 2 ) ) ), QgsPoint( QgsWkbTypes::PointZM, 21, 22, 3, 0 ) );
|
|
c6.addGeometry( new QgsPoint( QgsWkbTypes::PointM, 31.0, 32.0, 0, 4 ) );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPointZM );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
QCOMPARE( *( static_cast< const QgsPoint * >( c6.geometryN( 3 ) ) ), QgsPoint( QgsWkbTypes::PointZM, 31, 32, 0, 4 ) );
|
|
|
|
//clear
|
|
QgsMultiPointV2 c7;
|
|
c7.addGeometry( new QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 ) );
|
|
c7.addGeometry( new QgsPoint( QgsWkbTypes::PointZ, 11, 12, 3 ) );
|
|
QCOMPARE( c7.numGeometries(), 2 );
|
|
c7.clear();
|
|
QVERIFY( c7.isEmpty() );
|
|
QCOMPARE( c7.numGeometries(), 0 );
|
|
QCOMPARE( c7.nCoordinates(), 0 );
|
|
QCOMPARE( c7.ringCount(), 0 );
|
|
QCOMPARE( c7.partCount(), 0 );
|
|
QVERIFY( !c7.is3D() );
|
|
QVERIFY( !c7.isMeasure() );
|
|
QCOMPARE( c7.wkbType(), QgsWkbTypes::MultiPoint );
|
|
|
|
//clone
|
|
QgsMultiPointV2 c11;
|
|
std::unique_ptr< QgsMultiPointV2 >cloned( c11.clone() );
|
|
QVERIFY( cloned->isEmpty() );
|
|
c11.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 ) );
|
|
c11.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
cloned.reset( c11.clone() );
|
|
QCOMPARE( cloned->numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( cloned->geometryN( 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 ) );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( cloned->geometryN( 1 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
|
|
//copy constructor
|
|
QgsMultiPointV2 c12;
|
|
QgsMultiPointV2 c13( c12 );
|
|
QVERIFY( c13.isEmpty() );
|
|
c12.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) );
|
|
c12.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 20, 10, 14, 18 ) );
|
|
QgsMultiPointV2 c14( c12 );
|
|
QCOMPARE( c14.numGeometries(), 2 );
|
|
QCOMPARE( c14.wkbType(), QgsWkbTypes::MultiPointZM );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c14.geometryN( 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c14.geometryN( 1 ) ), QgsPoint( QgsWkbTypes::PointZM, 20, 10, 14, 18 ) );
|
|
|
|
//assignment operator
|
|
QgsMultiPointV2 c15;
|
|
c15 = c13;
|
|
QCOMPARE( c15.numGeometries(), 0 );
|
|
c15 = c14;
|
|
QCOMPARE( c15.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c15.geometryN( 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c15.geometryN( 1 ) ), QgsPoint( QgsWkbTypes::PointZM, 20, 10, 14, 18 ) );
|
|
|
|
//toCurveType
|
|
std::unique_ptr< QgsMultiPointV2 > curveType( c12.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::MultiPointZM );
|
|
QCOMPARE( curveType->numGeometries(), 2 );
|
|
const QgsPoint *curve = static_cast< const QgsPoint * >( curveType->geometryN( 0 ) );
|
|
QCOMPARE( *curve, QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) );
|
|
curve = static_cast< const QgsPoint * >( curveType->geometryN( 1 ) );
|
|
QCOMPARE( *curve, QgsPoint( QgsWkbTypes::PointZM, 20, 10, 14, 18 ) );
|
|
|
|
//to/fromWKB
|
|
QgsMultiPointV2 c16;
|
|
c16.addGeometry( new QgsPoint( QgsWkbTypes::Point, 10, 11 ) );
|
|
c16.addGeometry( new QgsPoint( QgsWkbTypes::Point, 20, 21 ) );
|
|
QByteArray wkb16 = c16.asWkb();
|
|
QgsMultiPointV2 c17;
|
|
QgsConstWkbPtr wkb16ptr( wkb16 );
|
|
c17.fromWkb( wkb16ptr );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c17.geometryN( 0 ) ), QgsPoint( QgsWkbTypes::Point, 10, 11 ) );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c17.geometryN( 1 ) ), QgsPoint( QgsWkbTypes::Point, 20, 21 ) );
|
|
|
|
//parts with Z
|
|
c16.clear();
|
|
c17.clear();
|
|
c16.addGeometry( new QgsPoint( QgsWkbTypes::PointZ, 10, 0, 4 ) );
|
|
c16.addGeometry( new QgsPoint( QgsWkbTypes::PointZ, 9, 1, 4 ) );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr2( wkb16 );
|
|
c17.fromWkb( wkb16ptr2 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiPointZ );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c17.geometryN( 0 ) ), QgsPoint( QgsWkbTypes::PointZ, 10, 0, 4 ) );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c17.geometryN( 1 ) ), QgsPoint( QgsWkbTypes::PointZ, 9, 1, 4 ) );
|
|
|
|
//parts with m
|
|
c16.clear();
|
|
c17.clear();
|
|
c16.addGeometry( new QgsPoint( QgsWkbTypes::PointM, 10, 0, 0, 4 ) );
|
|
c16.addGeometry( new QgsPoint( QgsWkbTypes::PointM, 9, 1, 0, 4 ) );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr3( wkb16 );
|
|
c17.fromWkb( wkb16ptr3 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiPointM );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c17.geometryN( 0 ) ), QgsPoint( QgsWkbTypes::PointM, 10, 0, 0, 4 ) );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c17.geometryN( 1 ) ), QgsPoint( QgsWkbTypes::PointM, 9, 1, 0, 4 ) );
|
|
|
|
// parts with ZM
|
|
c16.clear();
|
|
c17.clear();
|
|
c16.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 10, 0, 70, 4 ) );
|
|
c16.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 9, 1, 3, 4 ) );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr4( wkb16 );
|
|
c17.fromWkb( wkb16ptr4 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiPointZM );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c17.geometryN( 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 10, 0, 70, 4 ) );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c17.geometryN( 1 ) ), QgsPoint( QgsWkbTypes::PointZM, 9, 1, 3, 4 ) );
|
|
|
|
//bad WKB - check for no crash
|
|
c17.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !c17.fromWkb( nullPtr ) );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiPoint );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkbPoint = point.asWkb();
|
|
QgsConstWkbPtr wkbPointPtr( wkbPoint );
|
|
QVERIFY( !c17.fromWkb( wkbPointPtr ) );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiPoint );
|
|
|
|
//to/from WKT
|
|
QgsMultiPointV2 c18;
|
|
c18.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) );
|
|
c18.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) );
|
|
|
|
QString wkt = c18.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsMultiPointV2 c19;
|
|
QVERIFY( c19.fromWkt( wkt ) );
|
|
QCOMPARE( c19.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c19.geometryN( 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) );
|
|
QCOMPARE( *static_cast< const QgsPoint * >( c19.geometryN( 1 ) ), QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) );
|
|
|
|
//bad WKT
|
|
QgsMultiPointV2 c20;
|
|
QVERIFY( !c20.fromWkt( "Point()" ) );
|
|
QVERIFY( c20.isEmpty() );
|
|
QCOMPARE( c20.numGeometries(), 0 );
|
|
QCOMPARE( c20.wkbType(), QgsWkbTypes::MultiPoint );
|
|
|
|
//as JSON
|
|
QgsMultiPointV2 exportC;
|
|
exportC.addGeometry( new QgsPoint( QgsWkbTypes::Point, 0, 10 ) );
|
|
exportC.addGeometry( new QgsPoint( QgsWkbTypes::Point, 10, 0 ) );
|
|
|
|
// GML document for compare
|
|
QDomDocument doc( "gml" );
|
|
|
|
// as GML2
|
|
QString expectedSimpleGML2( QStringLiteral( "<MultiPoint xmlns=\"gml\"><pointMember xmlns=\"gml\"><Point xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0,10</coordinates></Point></pointMember><pointMember xmlns=\"gml\"><Point xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">10,0</coordinates></Point></pointMember></MultiPoint>" ) );
|
|
QString res = elemToString( exportC.asGML2( doc ) );
|
|
QGSCOMPAREGML( res, expectedSimpleGML2 );
|
|
|
|
//as GML3
|
|
QString expectedSimpleGML3( QStringLiteral( "<MultiPoint xmlns=\"gml\"><pointMember xmlns=\"gml\"><Point xmlns=\"gml\"><pos xmlns=\"gml\" srsDimension=\"2\">0 10</pos></Point></pointMember><pointMember xmlns=\"gml\"><Point xmlns=\"gml\"><pos xmlns=\"gml\" srsDimension=\"2\">10 0</pos></Point></pointMember></MultiPoint>" ) );
|
|
res = elemToString( exportC.asGML3( doc ) );
|
|
QCOMPARE( res, expectedSimpleGML3 );
|
|
|
|
// as JSON
|
|
QString expectedSimpleJson( "{\"type\": \"MultiPoint\", \"coordinates\": [ [0, 10], [10, 0]] }" );
|
|
res = exportC.asJSON();
|
|
QCOMPARE( res, expectedSimpleJson );
|
|
|
|
QgsMultiPointV2 exportFloat;
|
|
exportFloat.addGeometry( new QgsPoint( QgsWkbTypes::Point, 10 / 9.0, 100 / 9.0 ) );
|
|
exportFloat.addGeometry( new QgsPoint( QgsWkbTypes::Point, 4 / 3.0, 2 / 3.0 ) );
|
|
|
|
QString expectedJsonPrec3( QStringLiteral( "{\"type\": \"MultiPoint\", \"coordinates\": [ [1.111, 11.111], [1.333, 0.667]] }" ) );
|
|
res = exportFloat.asJSON( 3 );
|
|
QCOMPARE( res, expectedJsonPrec3 );
|
|
|
|
// as GML2
|
|
QString expectedGML2prec3( QStringLiteral( "<MultiPoint xmlns=\"gml\"><pointMember xmlns=\"gml\"><Point xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">1.111,11.111</coordinates></Point></pointMember><pointMember xmlns=\"gml\"><Point xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">1.333,0.667</coordinates></Point></pointMember></MultiPoint>" ) );
|
|
res = elemToString( exportFloat.asGML2( doc, 3 ) );
|
|
QGSCOMPAREGML( res, expectedGML2prec3 );
|
|
|
|
//as GML3
|
|
QString expectedGML3prec3( QStringLiteral( "<MultiPoint xmlns=\"gml\"><pointMember xmlns=\"gml\"><Point xmlns=\"gml\"><pos xmlns=\"gml\" srsDimension=\"2\">1.111 11.111</pos></Point></pointMember><pointMember xmlns=\"gml\"><Point xmlns=\"gml\"><pos xmlns=\"gml\" srsDimension=\"2\">1.333 0.667</pos></Point></pointMember></MultiPoint>" ) );
|
|
res = elemToString( exportFloat.asGML3( doc, 3 ) );
|
|
QCOMPARE( res, expectedGML3prec3 );
|
|
|
|
// insert geometry
|
|
QgsMultiPointV2 rc;
|
|
rc.clear();
|
|
rc.insertGeometry( nullptr, 0 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
rc.insertGeometry( nullptr, -1 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
rc.insertGeometry( nullptr, 100 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
|
|
rc.insertGeometry( new QgsLineString(), 0 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
|
|
// cast
|
|
QVERIFY( !QgsMultiPointV2().cast( nullptr ) );
|
|
QgsMultiPointV2 pCast;
|
|
QVERIFY( QgsMultiPointV2().cast( &pCast ) );
|
|
QgsMultiPointV2 pCast2;
|
|
pCast2.fromWkt( QStringLiteral( "MultiPointZ(PointZ(0 1 1))" ) );
|
|
QVERIFY( QgsMultiPointV2().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "MultiPointM(PointM(0 1 1))" ) );
|
|
QVERIFY( QgsMultiPointV2().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "MultiPointZM(PointZM(0 1 1 2))" ) );
|
|
QVERIFY( QgsMultiPointV2().cast( &pCast2 ) );
|
|
|
|
//boundary
|
|
|
|
//multipoints have no boundary defined
|
|
QgsMultiPointV2 boundaryMP;
|
|
QVERIFY( !boundaryMP.boundary() );
|
|
// add some points and retest, should still be undefined
|
|
boundaryMP.addGeometry( new QgsPoint( 0, 0 ) );
|
|
boundaryMP.addGeometry( new QgsPoint( 1, 1 ) );
|
|
QVERIFY( !boundaryMP.boundary() );
|
|
|
|
// closestSegment
|
|
QgsPoint closest;
|
|
QgsVertexId after;
|
|
// return error - points have no segments
|
|
QVERIFY( boundaryMP.closestSegment( QgsPoint( 0.5, 0.5 ), closest, after ) < 0 );
|
|
}
|
|
|
|
void TestQgsGeometry::multiLineString()
|
|
{
|
|
//test constructor
|
|
QgsMultiLineString c1;
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiLineString );
|
|
QCOMPARE( c1.wktTypeStr(), QString( "MultiLineString" ) );
|
|
QCOMPARE( c1.geometryType(), QString( "MultiLineString" ) );
|
|
QCOMPARE( c1.dimension(), 0 );
|
|
QVERIFY( !c1.hasCurvedSegments() );
|
|
QCOMPARE( c1.area(), 0.0 );
|
|
QCOMPARE( c1.perimeter(), 0.0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
QCOMPARE( c1.vertexCount( 0, 0 ), 0 );
|
|
QCOMPARE( c1.vertexCount( 0, 1 ), 0 );
|
|
QCOMPARE( c1.vertexCount( 1, 0 ), 0 );
|
|
|
|
//addGeometry
|
|
|
|
//try with nullptr
|
|
c1.addGeometry( nullptr );
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiLineString );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
|
|
// not a linestring
|
|
QVERIFY( !c1.addGeometry( new QgsPoint() ) );
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiLineString );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
|
|
//valid geometry
|
|
QgsLineString part;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 1, 10 ) << QgsPoint( 2, 11 ) );
|
|
c1.addGeometry( part.clone() );
|
|
QVERIFY( !c1.isEmpty() );
|
|
QCOMPARE( c1.numGeometries(), 1 );
|
|
QCOMPARE( c1.nCoordinates(), 2 );
|
|
QCOMPARE( c1.ringCount(), 1 );
|
|
QCOMPARE( c1.partCount(), 1 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiLineString );
|
|
QCOMPARE( c1.wktTypeStr(), QString( "MultiLineString" ) );
|
|
QCOMPARE( c1.geometryType(), QString( "MultiLineString" ) );
|
|
QCOMPARE( c1.dimension(), 1 );
|
|
QVERIFY( !c1.hasCurvedSegments() );
|
|
QCOMPARE( c1.area(), 0.0 );
|
|
QCOMPARE( c1.perimeter(), 0.0 );
|
|
QVERIFY( c1.geometryN( 0 ) );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c1.geometryN( 0 ) ), part );
|
|
QVERIFY( !c1.geometryN( 100 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
QCOMPARE( c1.vertexCount( 0, 0 ), 2 );
|
|
QCOMPARE( c1.vertexCount( 1, 0 ), 0 );
|
|
|
|
//initial adding of geometry should set z/m type
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 10, 11, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 20, 21, 2 ) );
|
|
QgsMultiLineString c2;
|
|
c2.addGeometry( part.clone() );
|
|
QVERIFY( c2.is3D() );
|
|
QVERIFY( !c2.isMeasure() );
|
|
QCOMPARE( c2.wkbType(), QgsWkbTypes::MultiLineStringZ );
|
|
QCOMPARE( c2.wktTypeStr(), QString( "MultiLineStringZ" ) );
|
|
QCOMPARE( c2.geometryType(), QString( "MultiLineString" ) );
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( c2.geometryN( 0 ) ) ), part );
|
|
QgsMultiLineString c3;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 10, 11, 0, 1 ) << QgsPoint( QgsWkbTypes::PointM, 20, 21, 0, 2 ) );
|
|
c3.addGeometry( part.clone() );
|
|
QVERIFY( !c3.is3D() );
|
|
QVERIFY( c3.isMeasure() );
|
|
QCOMPARE( c3.wkbType(), QgsWkbTypes::MultiLineStringM );
|
|
QCOMPARE( c3.wktTypeStr(), QString( "MultiLineStringM" ) );
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( c3.geometryN( 0 ) ) ), part );
|
|
QgsMultiLineString c4;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 10, 11, 2, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 20, 21, 3, 2 ) );
|
|
c4.addGeometry( part.clone() );
|
|
QVERIFY( c4.is3D() );
|
|
QVERIFY( c4.isMeasure() );
|
|
QCOMPARE( c4.wkbType(), QgsWkbTypes::MultiLineStringZM );
|
|
QCOMPARE( c4.wktTypeStr(), QString( "MultiLineStringZM" ) );
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( c4.geometryN( 0 ) ) ), part );
|
|
|
|
//add another part
|
|
QgsMultiLineString c6;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 1, 10 ) << QgsPoint( 2, 11 ) );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 2 );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 9, 12 ) << QgsPoint( 3, 13 ) );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 2 );
|
|
QCOMPARE( c6.numGeometries(), 2 );
|
|
QVERIFY( c6.geometryN( 0 ) );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c6.geometryN( 1 ) ), part );
|
|
|
|
//adding subsequent points should not alter z/m type, regardless of points type
|
|
c6.clear();
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineString );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 1, 10, 2 ) << QgsPoint( 2, 11, 3 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineString );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 2 );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 2 );
|
|
QCOMPARE( c6.vertexCount( 2, 0 ), 0 );
|
|
QCOMPARE( c6.vertexCount( -1, 0 ), 0 );
|
|
QCOMPARE( c6.nCoordinates(), 4 );
|
|
QCOMPARE( c6.ringCount(), 1 );
|
|
QCOMPARE( c6.partCount(), 2 );
|
|
QVERIFY( !c6.is3D() );
|
|
const QgsLineString *ls = static_cast< const QgsLineString * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( 9, 12 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( 3, 13 ) );
|
|
ls = static_cast< const QgsLineString * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( 1, 10 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( 2, 11 ) );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 21, 30, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 32, 41, 0, 3 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineString );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 2 );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 2 );
|
|
QCOMPARE( c6.vertexCount( 2, 0 ), 2 );
|
|
QCOMPARE( c6.nCoordinates(), 6 );
|
|
QCOMPARE( c6.ringCount(), 1 );
|
|
QCOMPARE( c6.partCount(), 3 );
|
|
QVERIFY( !c6.is3D() );
|
|
QVERIFY( !c6.isMeasure() );
|
|
ls = static_cast< const QgsLineString * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( 21, 30 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( 32, 41 ) );
|
|
|
|
c6.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 1, 10, 2 ) << QgsPoint( 2, 11, 3 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineStringZ );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 2, 20 ) << QgsPoint( 3, 31 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineStringZ );
|
|
QVERIFY( c6.is3D() );
|
|
ls = static_cast< const QgsLineString * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( 1, 10, 2 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( 2, 11, 3 ) );
|
|
ls = static_cast< const QgsLineString * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( 2, 20, 0 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( 3, 31, 0 ) );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 6, 61, 0, 5 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineStringZ );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( !c6.isMeasure() );
|
|
ls = static_cast< const QgsLineString * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( 5, 50, 0 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( 6, 61, 0 ) );
|
|
|
|
c6.clear();
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineString );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 6, 61, 0, 5 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineStringM );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 2, 20 ) << QgsPoint( 3, 31 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineStringM );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsLineString * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 6, 61, 0, 5 ) );
|
|
ls = static_cast< const QgsLineString * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 2, 20, 0, 0 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 3, 31, 0, 0 ) );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 11, 12, 13 ) << QgsPoint( 14, 15, 16 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineStringM );
|
|
QVERIFY( !c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsLineString * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 0 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 14, 15, 0, 0 ) );
|
|
|
|
c6.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 6, 61, 3, 5 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineStringZM );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineStringZM );
|
|
QVERIFY( c6.isMeasure() );
|
|
QVERIFY( c6.is3D() );
|
|
ls = static_cast< const QgsLineString * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 6, 61, 3, 5 ) );
|
|
ls = static_cast< const QgsLineString * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 7, 17, 0, 0 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 3, 13, 0, 0 ) );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 77, 87, 7 ) << QgsPoint( QgsWkbTypes::PointZ, 83, 83, 8 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineStringZM );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsLineString * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 77, 87, 7, 0 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 83, 83, 8, 0 ) );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 177, 187, 0, 9 ) << QgsPoint( QgsWkbTypes::PointM, 183, 183, 0, 11 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiLineStringZM );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsLineString * >( c6.geometryN( 3 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 177, 187, 0, 9 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 183, 183, 0, 11 ) );
|
|
|
|
//clear
|
|
QgsMultiLineString c7;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 6, 61, 3, 5 ) ) ;
|
|
c7.addGeometry( part.clone() );
|
|
c7.addGeometry( part.clone() );
|
|
QCOMPARE( c7.numGeometries(), 2 );
|
|
c7.clear();
|
|
QVERIFY( c7.isEmpty() );
|
|
QCOMPARE( c7.numGeometries(), 0 );
|
|
QCOMPARE( c7.nCoordinates(), 0 );
|
|
QCOMPARE( c7.ringCount(), 0 );
|
|
QCOMPARE( c7.partCount(), 0 );
|
|
QVERIFY( !c7.is3D() );
|
|
QVERIFY( !c7.isMeasure() );
|
|
QCOMPARE( c7.wkbType(), QgsWkbTypes::MultiLineString );
|
|
|
|
//clone
|
|
QgsMultiLineString c11;
|
|
std::unique_ptr< QgsMultiLineString >cloned( c11.clone() );
|
|
QVERIFY( cloned->isEmpty() );
|
|
c11.addGeometry( part.clone() );
|
|
c11.addGeometry( part.clone() );
|
|
cloned.reset( c11.clone() );
|
|
QCOMPARE( cloned->numGeometries(), 2 );
|
|
ls = static_cast< const QgsLineString * >( cloned->geometryN( 0 ) );
|
|
QCOMPARE( *ls, part );
|
|
ls = static_cast< const QgsLineString * >( cloned->geometryN( 1 ) );
|
|
QCOMPARE( *ls, part );
|
|
|
|
//copy constructor
|
|
QgsMultiLineString c12;
|
|
QgsMultiLineString c13( c12 );
|
|
QVERIFY( c13.isEmpty() );
|
|
c12.addGeometry( part.clone() );
|
|
c12.addGeometry( part.clone() );
|
|
QgsMultiLineString c14( c12 );
|
|
QCOMPARE( c14.numGeometries(), 2 );
|
|
QCOMPARE( c14.wkbType(), QgsWkbTypes::MultiLineStringZM );
|
|
ls = static_cast< const QgsLineString * >( c14.geometryN( 0 ) );
|
|
QCOMPARE( *ls, part );
|
|
ls = static_cast< const QgsLineString * >( c14.geometryN( 1 ) );
|
|
QCOMPARE( *ls, part );
|
|
|
|
//assignment operator
|
|
QgsMultiLineString c15;
|
|
c15 = c13;
|
|
QCOMPARE( c15.numGeometries(), 0 );
|
|
c15 = c14;
|
|
QCOMPARE( c15.numGeometries(), 2 );
|
|
ls = static_cast< const QgsLineString * >( c15.geometryN( 0 ) );
|
|
QCOMPARE( *ls, part );
|
|
ls = static_cast< const QgsLineString * >( c15.geometryN( 1 ) );
|
|
QCOMPARE( *ls, part );
|
|
|
|
//toCurveType
|
|
std::unique_ptr< QgsMultiCurve > curveType( c12.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::MultiCurveZM );
|
|
QCOMPARE( curveType->numGeometries(), 2 );
|
|
const QgsCompoundCurve *curve = static_cast< const QgsCompoundCurve * >( curveType->geometryN( 0 ) );
|
|
QCOMPARE( curve->asWkt(), QStringLiteral( "CompoundCurveZM ((5 50 1 4, 6 61 3 5))" ) );
|
|
curve = static_cast< const QgsCompoundCurve * >( curveType->geometryN( 1 ) );
|
|
QCOMPARE( curve->asWkt(), QStringLiteral( "CompoundCurveZM ((5 50 1 4, 6 61 3 5))" ) );
|
|
|
|
//to/fromWKB
|
|
QgsMultiLineString c16;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27, 37 ) << QgsPoint( QgsWkbTypes::Point, 43, 43 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
QByteArray wkb16 = c16.asWkb();
|
|
QgsMultiLineString c17;
|
|
QgsConstWkbPtr wkb16ptr( wkb16 );
|
|
c17.fromWkb( wkb16ptr );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 0 ) ), *static_cast< const QgsLineString * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 1 ) ), *static_cast< const QgsLineString * >( c16.geometryN( 1 ) ) );
|
|
|
|
//parts with Z
|
|
c16.clear();
|
|
c17.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 7, 17, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 3, 13, 4 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 27, 37, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 43, 43, 5 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr2( wkb16 );
|
|
c17.fromWkb( wkb16ptr2 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiLineStringZ );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 0 ) ), *static_cast< const QgsLineString * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 1 ) ), *static_cast< const QgsLineString * >( c16.geometryN( 1 ) ) );
|
|
|
|
//parts with m
|
|
c16.clear();
|
|
c17.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 7, 17, 0, 1 ) << QgsPoint( QgsWkbTypes::PointM, 3, 13, 0, 4 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 27, 37, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 43, 43, 0, 5 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr3( wkb16 );
|
|
c17.fromWkb( wkb16ptr3 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiLineStringM );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 0 ) ), *static_cast< const QgsLineString * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 1 ) ), *static_cast< const QgsLineString * >( c16.geometryN( 1 ) ) );
|
|
|
|
// parts with ZM
|
|
c16.clear();
|
|
c17.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 13, 1, 4 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 43, 43, 11, 5 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr4( wkb16 );
|
|
c17.fromWkb( wkb16ptr4 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiLineStringZM );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 0 ) ), *static_cast< const QgsLineString * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 1 ) ), *static_cast< const QgsLineString * >( c16.geometryN( 1 ) ) );
|
|
|
|
//bad WKB - check for no crash
|
|
c17.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !c17.fromWkb( nullPtr ) );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiLineString );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkbPoint = point.asWkb();
|
|
QgsConstWkbPtr wkbPointPtr( wkbPoint );
|
|
QVERIFY( !c17.fromWkb( wkbPointPtr ) );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiLineString );
|
|
|
|
//to/from WKT
|
|
QgsMultiLineString c18;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 13, 1, 4 ) ) ;
|
|
c18.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 43, 43, 11, 5 ) ) ;
|
|
c18.addGeometry( part.clone() );
|
|
|
|
QString wkt = c18.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsMultiLineString c19;
|
|
QVERIFY( c19.fromWkt( wkt ) );
|
|
QCOMPARE( c19.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c19.geometryN( 0 ) ), *static_cast< const QgsLineString * >( c18.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c19.geometryN( 1 ) ), *static_cast< const QgsLineString * >( c18.geometryN( 1 ) ) );
|
|
|
|
//bad WKT
|
|
QgsMultiLineString c20;
|
|
QVERIFY( !c20.fromWkt( "Point()" ) );
|
|
QVERIFY( c20.isEmpty() );
|
|
QCOMPARE( c20.numGeometries(), 0 );
|
|
QCOMPARE( c20.wkbType(), QgsWkbTypes::MultiLineString );
|
|
|
|
//as JSON
|
|
QgsMultiLineString exportC;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 ) ) ;
|
|
exportC.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27, 37 ) << QgsPoint( QgsWkbTypes::Point, 43, 43 ) ) ;
|
|
exportC.addGeometry( part.clone() );
|
|
|
|
// GML document for compare
|
|
QDomDocument doc( "gml" );
|
|
|
|
// as GML2
|
|
QString expectedSimpleGML2( QStringLiteral( "<MultiLineString xmlns=\"gml\"><lineStringMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">7,17 3,13</coordinates></LineString></lineStringMember><lineStringMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">27,37 43,43</coordinates></LineString></lineStringMember></MultiLineString>" ) );
|
|
QString res = elemToString( exportC.asGML2( doc ) );
|
|
QGSCOMPAREGML( res, expectedSimpleGML2 );
|
|
|
|
//as GML3
|
|
QString expectedSimpleGML3( QStringLiteral( "<MultiCurve xmlns=\"gml\"><curveMember xmlns=\"gml\"><LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">7 17 3 13</posList></LineString></curveMember><curveMember xmlns=\"gml\"><LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">27 37 43 43</posList></LineString></curveMember></MultiCurve>" ) );
|
|
res = elemToString( exportC.asGML3( doc ) );
|
|
QCOMPARE( res, expectedSimpleGML3 );
|
|
|
|
// as JSON
|
|
QString expectedSimpleJson( "{\"type\": \"MultiLineString\", \"coordinates\": [[ [7, 17], [3, 13]], [ [27, 37], [43, 43]]] }" );
|
|
res = exportC.asJSON();
|
|
QCOMPARE( res, expectedSimpleJson );
|
|
|
|
QgsMultiLineString exportFloat;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7 / 3.0, 17 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 3 / 5.0, 13 / 3.0 ) ) ;
|
|
exportFloat.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27 / 3.0, 37 / 9.0 ) << QgsPoint( QgsWkbTypes::Point, 43 / 41.0, 43 / 42.0 ) ) ;
|
|
exportFloat.addGeometry( part.clone() );
|
|
|
|
QString expectedJsonPrec3( QStringLiteral( "{\"type\": \"MultiLineString\", \"coordinates\": [[ [2.333, 5.667], [0.6, 4.333]], [ [9, 4.111], [1.049, 1.024]]] }" ) );
|
|
res = exportFloat.asJSON( 3 );
|
|
QCOMPARE( res, expectedJsonPrec3 );
|
|
|
|
// as GML2
|
|
QString expectedGML2prec3( QStringLiteral( "<MultiLineString xmlns=\"gml\"><lineStringMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">2.333,5.667 0.6,4.333</coordinates></LineString></lineStringMember><lineStringMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">9,4.111 1.049,1.024</coordinates></LineString></lineStringMember></MultiLineString>" ) );
|
|
res = elemToString( exportFloat.asGML2( doc, 3 ) );
|
|
QGSCOMPAREGML( res, expectedGML2prec3 );
|
|
|
|
//as GML3
|
|
QString expectedGML3prec3( QStringLiteral( "<MultiCurve xmlns=\"gml\"><curveMember xmlns=\"gml\"><LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">2.333 5.667 0.6 4.333</posList></LineString></curveMember><curveMember xmlns=\"gml\"><LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">9 4.111 1.049 1.024</posList></LineString></curveMember></MultiCurve>" ) );
|
|
res = elemToString( exportFloat.asGML3( doc, 3 ) );
|
|
QCOMPARE( res, expectedGML3prec3 );
|
|
|
|
// insert geometry
|
|
QgsMultiLineString rc;
|
|
rc.clear();
|
|
rc.insertGeometry( nullptr, 0 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
rc.insertGeometry( nullptr, -1 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
rc.insertGeometry( nullptr, 100 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
|
|
rc.insertGeometry( new QgsPoint(), 0 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
|
|
rc.insertGeometry( part.clone(), 0 );
|
|
QVERIFY( !rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 1 );
|
|
|
|
// cast
|
|
QVERIFY( !QgsMultiLineString().cast( nullptr ) );
|
|
QgsMultiLineString pCast;
|
|
QVERIFY( QgsMultiLineString().cast( &pCast ) );
|
|
QgsMultiLineString pCast2;
|
|
pCast2.fromWkt( QStringLiteral( "MultiLineStringZ()" ) );
|
|
QVERIFY( QgsMultiLineString().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "MultiLineStringM()" ) );
|
|
QVERIFY( QgsMultiLineString().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "MultiLineStringZM()" ) );
|
|
QVERIFY( QgsMultiLineString().cast( &pCast2 ) );
|
|
|
|
//boundary
|
|
QgsMultiLineString multiLine1;
|
|
QVERIFY( !multiLine1.boundary() );
|
|
QgsLineString boundaryLine1;
|
|
boundaryLine1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) );
|
|
multiLine1.addGeometry( boundaryLine1.clone() );
|
|
QgsAbstractGeometry *boundary = multiLine1.boundary();
|
|
QgsMultiPointV2 *mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->numGeometries(), 2 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
delete boundary;
|
|
// add another linestring
|
|
QgsLineString boundaryLine2;
|
|
boundaryLine2.setPoints( QList<QgsPoint>() << QgsPoint( 10, 10 ) << QgsPoint( 11, 10 ) << QgsPoint( 11, 11 ) );
|
|
multiLine1.addGeometry( boundaryLine2.clone() );
|
|
boundary = multiLine1.boundary();
|
|
mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->numGeometries(), 4 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->x(), 10.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->y(), 10.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->x(), 11.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->y(), 11.0 );
|
|
delete boundary;
|
|
|
|
// add a closed string = no boundary
|
|
QgsLineString boundaryLine3;
|
|
boundaryLine3.setPoints( QList<QgsPoint>() << QgsPoint( 20, 20 ) << QgsPoint( 21, 20 ) << QgsPoint( 21, 21 ) << QgsPoint( 20, 20 ) );
|
|
multiLine1.addGeometry( boundaryLine3.clone() );
|
|
boundary = multiLine1.boundary();
|
|
mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->numGeometries(), 4 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->x(), 10.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->y(), 10.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->x(), 11.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->y(), 11.0 );
|
|
delete boundary;
|
|
|
|
//boundary with z
|
|
QgsLineString boundaryLine4;
|
|
boundaryLine4.setPoints( QList<QgsPoint>() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 10 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 0, 15 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 20 ) );
|
|
QgsLineString boundaryLine5;
|
|
boundaryLine5.setPoints( QList<QgsPoint>() << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 100 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 20, 150 ) << QgsPoint( QgsWkbTypes::PointZ, 20, 20, 200 ) );
|
|
QgsMultiLineString multiLine2;
|
|
multiLine2.addGeometry( boundaryLine4.clone() );
|
|
multiLine2.addGeometry( boundaryLine5.clone() );
|
|
|
|
boundary = multiLine2.boundary();
|
|
mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->numGeometries(), 4 );
|
|
QCOMPARE( mpBoundary->geometryN( 0 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->z(), 10.0 );
|
|
QCOMPARE( mpBoundary->geometryN( 1 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->z(), 20.0 );
|
|
QCOMPARE( mpBoundary->geometryN( 2 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->x(), 10.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->y(), 10.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->z(), 100.0 );
|
|
QCOMPARE( mpBoundary->geometryN( 3 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->x(), 20.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->y(), 20.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->z(), 200.0 );
|
|
delete boundary;
|
|
}
|
|
|
|
void TestQgsGeometry::multiCurve()
|
|
{
|
|
//test constructor
|
|
QgsMultiCurve c1;
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiCurve );
|
|
QCOMPARE( c1.wktTypeStr(), QString( "MultiCurve" ) );
|
|
QCOMPARE( c1.geometryType(), QString( "MultiCurve" ) );
|
|
QCOMPARE( c1.dimension(), 0 );
|
|
QVERIFY( !c1.hasCurvedSegments() );
|
|
QCOMPARE( c1.area(), 0.0 );
|
|
QCOMPARE( c1.perimeter(), 0.0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
QCOMPARE( c1.vertexCount( 0, 0 ), 0 );
|
|
QCOMPARE( c1.vertexCount( 0, 1 ), 0 );
|
|
QCOMPARE( c1.vertexCount( 1, 0 ), 0 );
|
|
|
|
//addGeometry
|
|
//try with nullptr
|
|
c1.addGeometry( nullptr );
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiCurve );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
|
|
// not a curve
|
|
QVERIFY( !c1.addGeometry( new QgsPoint() ) );
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiCurve );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
|
|
//valid geometry
|
|
QgsCircularString part;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 1, 10 ) << QgsPoint( 2, 11 ) << QgsPoint( 1, 12 ) );
|
|
c1.addGeometry( part.clone() );
|
|
QVERIFY( !c1.isEmpty() );
|
|
QCOMPARE( c1.numGeometries(), 1 );
|
|
QCOMPARE( c1.nCoordinates(), 3 );
|
|
QCOMPARE( c1.ringCount(), 1 );
|
|
QCOMPARE( c1.partCount(), 1 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiCurve );
|
|
QCOMPARE( c1.wktTypeStr(), QString( "MultiCurve" ) );
|
|
QCOMPARE( c1.geometryType(), QString( "MultiCurve" ) );
|
|
QCOMPARE( c1.dimension(), 1 );
|
|
QVERIFY( c1.hasCurvedSegments() );
|
|
QCOMPARE( c1.area(), 0.0 );
|
|
QCOMPARE( c1.perimeter(), 0.0 );
|
|
QVERIFY( c1.geometryN( 0 ) );
|
|
QCOMPARE( *static_cast< const QgsCircularString * >( c1.geometryN( 0 ) ), part );
|
|
QVERIFY( !c1.geometryN( 100 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
QCOMPARE( c1.vertexCount( 0, 0 ), 3 );
|
|
QCOMPARE( c1.vertexCount( 1, 0 ), 0 );
|
|
|
|
//initial adding of geometry should set z/m type
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 10, 11, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 20, 21, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 31, 3 ) );
|
|
QgsMultiCurve c2;
|
|
c2.addGeometry( part.clone() );
|
|
QVERIFY( c2.is3D() );
|
|
QVERIFY( !c2.isMeasure() );
|
|
QCOMPARE( c2.wkbType(), QgsWkbTypes::MultiCurveZ );
|
|
QCOMPARE( c2.wktTypeStr(), QString( "MultiCurveZ" ) );
|
|
QCOMPARE( c2.geometryType(), QString( "MultiCurve" ) );
|
|
QCOMPARE( *( static_cast< const QgsCircularString * >( c2.geometryN( 0 ) ) ), part );
|
|
QgsMultiCurve c3;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 10, 11, 0, 1 ) << QgsPoint( QgsWkbTypes::PointM, 20, 21, 0, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 10, 31, 0, 3 ) );
|
|
c3.addGeometry( part.clone() );
|
|
QVERIFY( !c3.is3D() );
|
|
QVERIFY( c3.isMeasure() );
|
|
QCOMPARE( c3.wkbType(), QgsWkbTypes::MultiCurveM );
|
|
QCOMPARE( c3.wktTypeStr(), QString( "MultiCurveM" ) );
|
|
QCOMPARE( *( static_cast< const QgsCircularString * >( c3.geometryN( 0 ) ) ), part );
|
|
QgsMultiCurve c4;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 10, 11, 2, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 20, 21, 3, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 31, 4, 5 ) );
|
|
c4.addGeometry( part.clone() );
|
|
QVERIFY( c4.is3D() );
|
|
QVERIFY( c4.isMeasure() );
|
|
QCOMPARE( c4.wkbType(), QgsWkbTypes::MultiCurveZM );
|
|
QCOMPARE( c4.wktTypeStr(), QString( "MultiCurveZM" ) );
|
|
QCOMPARE( *( static_cast< const QgsCircularString * >( c4.geometryN( 0 ) ) ), part );
|
|
|
|
//add another part
|
|
QgsMultiCurve c6;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 1, 10 ) << QgsPoint( 2, 11 ) << QgsPoint( 1, 20 ) );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 3 );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 9, 12 ) << QgsPoint( 3, 13 ) << QgsPoint( 9, 20 ) );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 3 );
|
|
QCOMPARE( c6.numGeometries(), 2 );
|
|
QVERIFY( c6.geometryN( 0 ) );
|
|
QCOMPARE( *static_cast< const QgsCircularString * >( c6.geometryN( 1 ) ), part );
|
|
|
|
//adding subsequent points should not alter z/m type, regardless of parts type
|
|
c6.clear();
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurve );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 1, 10, 2 ) << QgsPoint( 2, 11, 3 ) << QgsPoint( 1, 20, 4 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurve );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 3 );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 3 );
|
|
QCOMPARE( c6.vertexCount( 2, 0 ), 0 );
|
|
QCOMPARE( c6.vertexCount( -1, 0 ), 0 );
|
|
QCOMPARE( c6.nCoordinates(), 6 );
|
|
QCOMPARE( c6.ringCount(), 1 );
|
|
QCOMPARE( c6.partCount(), 2 );
|
|
QVERIFY( !c6.is3D() );
|
|
const QgsCircularString *ls = static_cast< const QgsCircularString * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( 9, 12 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( 3, 13 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( 9, 20 ) );
|
|
ls = static_cast< const QgsCircularString * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( 1, 10 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( 2, 11 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( 1, 20 ) );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 21, 30, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 32, 41, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 21, 51, 0, 4 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurve );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 3 );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 3 );
|
|
QCOMPARE( c6.vertexCount( 2, 0 ), 3 );
|
|
QCOMPARE( c6.nCoordinates(), 9 );
|
|
QCOMPARE( c6.ringCount(), 1 );
|
|
QCOMPARE( c6.partCount(), 3 );
|
|
QVERIFY( !c6.is3D() );
|
|
QVERIFY( !c6.isMeasure() );
|
|
ls = static_cast< const QgsCircularString * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( 21, 30 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( 32, 41 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( 21, 51 ) );
|
|
|
|
c6.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 1, 10, 2 ) << QgsPoint( 2, 11, 3 ) << QgsPoint( 1, 21, 4 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurveZ );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 2, 20 ) << QgsPoint( 3, 31 ) << QgsPoint( 2, 41 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurveZ );
|
|
QVERIFY( c6.is3D() );
|
|
ls = static_cast< const QgsCircularString * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( 1, 10, 2 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( 2, 11, 3 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( 1, 21, 4 ) );
|
|
ls = static_cast< const QgsCircularString * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( 2, 20, 0 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( 3, 31, 0 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( 2, 41, 0 ) );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 6, 61, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 5, 71, 0, 6 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurveZ );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( !c6.isMeasure() );
|
|
ls = static_cast< const QgsCircularString * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( 5, 50, 0 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( 6, 61, 0 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( 5, 71, 0 ) );
|
|
|
|
c6.clear();
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurve );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 6, 61, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 5, 71, 0, 5 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurveM );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 2, 20 ) << QgsPoint( 3, 31 ) << QgsPoint( 2, 41 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurveM );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsCircularString * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 6, 61, 0, 5 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( QgsWkbTypes::PointM, 5, 71, 0, 5 ) );
|
|
ls = static_cast< const QgsCircularString * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 2, 20, 0, 0 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 3, 31, 0, 0 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( QgsWkbTypes::PointM, 2, 41, 0, 0 ) );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 11, 12, 13 ) << QgsPoint( 14, 15, 16 ) << QgsPoint( 11, 25, 17 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurveM );
|
|
QVERIFY( !c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsCircularString * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 0 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 14, 15, 0, 0 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( QgsWkbTypes::PointM, 11, 25, 0, 0 ) );
|
|
|
|
c6.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 6, 61, 3, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 5, 71, 4, 6 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurveZM );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 7, 11 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurveZM );
|
|
QVERIFY( c6.isMeasure() );
|
|
QVERIFY( c6.is3D() );
|
|
ls = static_cast< const QgsCircularString * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 6, 61, 3, 5 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 5, 71, 4, 6 ) );
|
|
ls = static_cast< const QgsCircularString * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 7, 17, 0, 0 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 3, 13, 0, 0 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 7, 11, 0, 0 ) );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 77, 87, 7 ) << QgsPoint( QgsWkbTypes::PointZ, 83, 83, 8 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 77, 81, 9 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurveZM );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsCircularString * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 77, 87, 7, 0 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 83, 83, 8, 0 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 77, 81, 9, 0 ) );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 177, 187, 0, 9 ) << QgsPoint( QgsWkbTypes::PointM, 183, 183, 0, 11 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 177, 181, 0, 13 ) ) ;
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiCurveZM );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsCircularString * >( c6.geometryN( 3 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 177, 187, 0, 9 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 183, 183, 0, 11 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 177, 181, 0, 13 ) );
|
|
|
|
//clear
|
|
QgsMultiCurve c7;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 6, 61, 3, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 5, 71, 4, 6 ) ) ;
|
|
c7.addGeometry( part.clone() );
|
|
c7.addGeometry( part.clone() );
|
|
QCOMPARE( c7.numGeometries(), 2 );
|
|
c7.clear();
|
|
QVERIFY( c7.isEmpty() );
|
|
QCOMPARE( c7.numGeometries(), 0 );
|
|
QCOMPARE( c7.nCoordinates(), 0 );
|
|
QCOMPARE( c7.ringCount(), 0 );
|
|
QCOMPARE( c7.partCount(), 0 );
|
|
QVERIFY( !c7.is3D() );
|
|
QVERIFY( !c7.isMeasure() );
|
|
QCOMPARE( c7.wkbType(), QgsWkbTypes::MultiCurve );
|
|
|
|
//clone
|
|
QgsMultiCurve c11;
|
|
std::unique_ptr< QgsMultiCurve >cloned( c11.clone() );
|
|
QVERIFY( cloned->isEmpty() );
|
|
c11.addGeometry( part.clone() );
|
|
c11.addGeometry( part.clone() );
|
|
cloned.reset( c11.clone() );
|
|
QCOMPARE( cloned->numGeometries(), 2 );
|
|
ls = static_cast< const QgsCircularString * >( cloned->geometryN( 0 ) );
|
|
QCOMPARE( *ls, part );
|
|
ls = static_cast< const QgsCircularString * >( cloned->geometryN( 1 ) );
|
|
QCOMPARE( *ls, part );
|
|
|
|
//copy constructor
|
|
QgsMultiCurve c12;
|
|
QgsMultiCurve c13( c12 );
|
|
QVERIFY( c13.isEmpty() );
|
|
c12.addGeometry( part.clone() );
|
|
c12.addGeometry( part.clone() );
|
|
QgsMultiCurve c14( c12 );
|
|
QCOMPARE( c14.numGeometries(), 2 );
|
|
QCOMPARE( c14.wkbType(), QgsWkbTypes::MultiCurveZM );
|
|
ls = static_cast< const QgsCircularString * >( c14.geometryN( 0 ) );
|
|
QCOMPARE( *ls, part );
|
|
ls = static_cast< const QgsCircularString * >( c14.geometryN( 1 ) );
|
|
QCOMPARE( *ls, part );
|
|
|
|
//assignment operator
|
|
QgsMultiCurve c15;
|
|
c15 = c13;
|
|
QCOMPARE( c15.numGeometries(), 0 );
|
|
c15 = c14;
|
|
QCOMPARE( c15.numGeometries(), 2 );
|
|
ls = static_cast< const QgsCircularString * >( c15.geometryN( 0 ) );
|
|
QCOMPARE( *ls, part );
|
|
ls = static_cast< const QgsCircularString * >( c15.geometryN( 1 ) );
|
|
QCOMPARE( *ls, part );
|
|
|
|
//toCurveType
|
|
std::unique_ptr< QgsMultiCurve > curveType( c12.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::MultiCurveZM );
|
|
QCOMPARE( curveType->numGeometries(), 2 );
|
|
const QgsCircularString *curve = static_cast< const QgsCircularString * >( curveType->geometryN( 0 ) );
|
|
QCOMPARE( *curve, *static_cast< const QgsCircularString * >( c12.geometryN( 0 ) ) );
|
|
curve = static_cast< const QgsCircularString * >( curveType->geometryN( 1 ) );
|
|
QCOMPARE( *curve, *static_cast< const QgsCircularString * >( c12.geometryN( 1 ) ) );
|
|
|
|
//to/fromWKB
|
|
QgsMultiCurve c16;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 ) << QgsPoint( QgsWkbTypes::Point, 7, 11 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27, 37 ) << QgsPoint( QgsWkbTypes::Point, 43, 43 ) << QgsPoint( QgsWkbTypes::Point, 27, 54 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
QByteArray wkb16 = c16.asWkb();
|
|
QgsMultiCurve c17;
|
|
QgsConstWkbPtr wkb16ptr( wkb16 );
|
|
c17.fromWkb( wkb16ptr );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsCircularString * >( c17.geometryN( 0 ) ), *static_cast< const QgsCircularString * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsCircularString * >( c17.geometryN( 1 ) ), *static_cast< const QgsCircularString * >( c16.geometryN( 1 ) ) );
|
|
|
|
//parts with Z
|
|
c16.clear();
|
|
c17.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 7, 17, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 3, 13, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 7, 11, 3 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 27, 37, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 43, 43, 5 ) << QgsPoint( QgsWkbTypes::PointZ, 27, 53, 6 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr2( wkb16 );
|
|
c17.fromWkb( wkb16ptr2 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiCurveZ );
|
|
QCOMPARE( *static_cast< const QgsCircularString * >( c17.geometryN( 0 ) ), *static_cast< const QgsCircularString * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsCircularString * >( c17.geometryN( 1 ) ), *static_cast< const QgsCircularString * >( c16.geometryN( 1 ) ) );
|
|
|
|
//parts with m
|
|
c16.clear();
|
|
c17.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 7, 17, 0, 1 ) << QgsPoint( QgsWkbTypes::PointM, 3, 13, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 7, 11, 0, 5 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 27, 37, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 43, 43, 0, 5 ) << QgsPoint( QgsWkbTypes::PointM, 27, 53, 0, 7 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr3( wkb16 );
|
|
c17.fromWkb( wkb16ptr3 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiCurveM );
|
|
QCOMPARE( *static_cast< const QgsCircularString * >( c17.geometryN( 0 ) ), *static_cast< const QgsCircularString * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsCircularString * >( c17.geometryN( 1 ) ), *static_cast< const QgsCircularString * >( c16.geometryN( 1 ) ) );
|
|
|
|
// parts with ZM
|
|
c16.clear();
|
|
c17.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 13, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 7, 11, 2, 5 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 43, 43, 11, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 27, 47, 12, 15 ) ) ;
|
|
c16.addGeometry( part.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr4( wkb16 );
|
|
c17.fromWkb( wkb16ptr4 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiCurveZM );
|
|
QCOMPARE( *static_cast< const QgsCircularString * >( c17.geometryN( 0 ) ), *static_cast< const QgsCircularString * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsCircularString * >( c17.geometryN( 1 ) ), *static_cast< const QgsCircularString * >( c16.geometryN( 1 ) ) );
|
|
|
|
//bad WKB - check for no crash
|
|
c17.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !c17.fromWkb( nullPtr ) );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiCurve );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkbPoint = point.asWkb();
|
|
QgsConstWkbPtr wkbPointPtr( wkbPoint );
|
|
QVERIFY( !c17.fromWkb( wkbPointPtr ) );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiCurve );
|
|
|
|
//to/from WKT
|
|
QgsMultiCurve c18;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 13, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 7, 11, 2, 8 ) ) ;
|
|
c18.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 43, 43, 11, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 27, 53, 21, 52 ) ) ;
|
|
c18.addGeometry( part.clone() );
|
|
|
|
QString wkt = c18.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsMultiCurve c19;
|
|
QVERIFY( c19.fromWkt( wkt ) );
|
|
QCOMPARE( c19.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsCircularString * >( c19.geometryN( 0 ) ), *static_cast< const QgsCircularString * >( c18.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsCircularString * >( c19.geometryN( 1 ) ), *static_cast< const QgsCircularString * >( c18.geometryN( 1 ) ) );
|
|
|
|
//bad WKT
|
|
QgsMultiCurve c20;
|
|
QVERIFY( !c20.fromWkt( "Point()" ) );
|
|
QVERIFY( c20.isEmpty() );
|
|
QCOMPARE( c20.numGeometries(), 0 );
|
|
QCOMPARE( c20.wkbType(), QgsWkbTypes::MultiCurve );
|
|
|
|
//as JSON
|
|
QgsMultiCurve exportC;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 ) << QgsPoint( QgsWkbTypes::Point, 7, 11 ) ) ;
|
|
exportC.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27, 37 ) << QgsPoint( QgsWkbTypes::Point, 43, 43 ) << QgsPoint( QgsWkbTypes::Point, 27, 47 ) ) ;
|
|
exportC.addGeometry( part.clone() );
|
|
|
|
// GML document for compare
|
|
QDomDocument doc( "gml" );
|
|
|
|
// as GML2
|
|
QString expectedSimpleGML2( QStringLiteral( "<MultiLineString xmlns=\"gml\"><lineStringMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">7,17 6.9,17 6.9,17 6.8,17 6.8,17.1 6.7,17.1 6.7,17.1 6.6,17.1 6.6,17.1 6.5,17.1 6.5,17.1 6.4,17.1 6.4,17.1 6.3,17.1 6.2,17.2 6.2,17.2 6.1,17.2 6.1,17.2 6,17.2 6,17.2 5.9,17.2 5.9,17.2 5.8,17.2 5.7,17.2 5.7,17.1 5.6,17.1 5.6,17.1 5.5,17.1 5.5,17.1 5.4,17.1 5.4,17.1 5.3,17.1 5.3,17.1 5.2,17.1 5.2,17 5.1,17 5,17 5,17 4.9,17 4.9,17 4.8,16.9 4.8,16.9 4.7,16.9 4.7,16.9 4.6,16.9 4.6,16.8 4.5,16.8 4.5,16.8 4.4,16.8 4.4,16.7 4.3,16.7 4.3,16.7 4.3,16.6 4.2,16.6 4.2,16.6 4.1,16.5 4.1,16.5 4,16.5 4,16.4 3.9,16.4 3.9,16.4 3.9,16.3 3.8,16.3 3.8,16.3 3.7,16.2 3.7,16.2 3.7,16.1 3.6,16.1 3.6,16.1 3.6,16 3.5,16 3.5,15.9 3.5,15.9 3.4,15.8 3.4,15.8 3.4,15.7 3.3,15.7 3.3,15.7 3.3,15.6 3.2,15.6 3.2,15.5 3.2,15.5 3.2,15.4 3.1,15.4 3.1,15.3 3.1,15.3 3.1,15.2 3.1,15.2 3,15.1 3,15.1 3,15 3,15 3,14.9 3,14.8 2.9,14.8 2.9,14.7 2.9,14.7 2.9,14.6 2.9,14.6 2.9,14.5 2.9,14.5 2.9,14.4 2.9,14.4 2.9,14.3 2.8,14.2 2.8,14.2 2.8,14.1 2.8,14.1 2.8,14 2.8,14 2.8,13.9 2.8,13.9 2.8,13.8 2.8,13.8 2.9,13.7 2.9,13.6 2.9,13.6 2.9,13.5 2.9,13.5 2.9,13.4 2.9,13.4 2.9,13.3 2.9,13.3 2.9,13.2 3,13.2 3,13.1 3,13 3,13 3,12.9 3,12.9 3.1,12.8 3.1,12.8 3.1,12.7 3.1,12.7 3.1,12.6 3.2,12.6 3.2,12.5 3.2,12.5 3.2,12.4 3.3,12.4 3.3,12.3 3.3,12.3 3.4,12.3 3.4,12.2 3.4,12.2 3.5,12.1 3.5,12.1 3.5,12 3.6,12 3.6,11.9 3.6,11.9 3.7,11.9 3.7,11.8 3.7,11.8 3.8,11.7 3.8,11.7 3.9,11.7 3.9,11.6 3.9,11.6 4,11.6 4,11.5 4.1,11.5 4.1,11.5 4.2,11.4 4.2,11.4 4.3,11.4 4.3,11.3 4.3,11.3 4.4,11.3 4.4,11.2 4.5,11.2 4.5,11.2 4.6,11.2 4.6,11.1 4.7,11.1 4.7,11.1 4.8,11.1 4.8,11.1 4.9,11 4.9,11 5,11 5,11 5.1,11 5.2,11 5.2,10.9 5.3,10.9 5.3,10.9 5.4,10.9 5.4,10.9 5.5,10.9 5.5,10.9 5.6,10.9 5.6,10.9 5.7,10.9 5.7,10.8 5.8,10.8 5.9,10.8 5.9,10.8 6,10.8 6,10.8 6.1,10.8 6.1,10.8 6.2,10.8 6.2,10.8 6.3,10.9 6.4,10.9 6.4,10.9 6.5,10.9 6.5,10.9 6.6,10.9 6.6,10.9 6.7,10.9 6.7,10.9 6.8,10.9 6.8,11 6.9,11 6.9,11 7,11</coordinates></LineString></lineStringMember><lineStringMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">27,37 27.1,36.9 27.2,36.8 27.3,36.6 27.4,36.5 27.5,36.4 27.6,36.3 27.7,36.2 27.8,36 27.9,35.9 28,35.8 28.1,35.7 28.2,35.6 28.3,35.5 28.4,35.4 28.5,35.3 28.7,35.2 28.8,35.1 28.9,35 29,34.9 29.1,34.8 29.3,34.7 29.4,34.6 29.5,34.6 29.7,34.5 29.8,34.4 29.9,34.3 30.1,34.3 30.2,34.2 30.3,34.1 30.5,34 30.6,34 30.7,33.9 30.9,33.9 31,33.8 31.2,33.7 31.3,33.7 31.5,33.6 31.6,33.6 31.8,33.6 31.9,33.5 32.1,33.5 32.2,33.4 32.4,33.4 32.5,33.4 32.7,33.3 32.8,33.3 33,33.3 33.1,33.3 33.3,33.2 33.4,33.2 33.6,33.2 33.7,33.2 33.9,33.2 34,33.2 34.2,33.2 34.3,33.2 34.5,33.2 34.6,33.2 34.8,33.2 34.9,33.2 35.1,33.2 35.3,33.3 35.4,33.3 35.6,33.3 35.7,33.3 35.9,33.3 36,33.4 36.2,33.4 36.3,33.4 36.5,33.5 36.6,33.5 36.8,33.6 36.9,33.6 37.1,33.7 37.2,33.7 37.3,33.8 37.5,33.8 37.6,33.9 37.8,33.9 37.9,34 38,34.1 38.2,34.1 38.3,34.2 38.5,34.3 38.6,34.3 38.7,34.4 38.9,34.5 39,34.6 39.1,34.7 39.2,34.7 39.4,34.8 39.5,34.9 39.6,35 39.7,35.1 39.9,35.2 40,35.3 40.1,35.4 40.2,35.5 40.3,35.6 40.4,35.7 40.5,35.8 40.6,35.9 40.7,36.1 40.8,36.2 40.9,36.3 41,36.4 41.1,36.5 41.2,36.6 41.3,36.8 41.4,36.9 41.5,37 41.6,37.1 41.7,37.3 41.8,37.4 41.8,37.5 41.9,37.7 42,37.8 42.1,37.9 42.1,38.1 42.2,38.2 42.3,38.3 42.3,38.5 42.4,38.6 42.4,38.8 42.5,38.9 42.6,39.1 42.6,39.2 42.6,39.4 42.7,39.5 42.7,39.6 42.8,39.8 42.8,39.9 42.8,40.1 42.9,40.2 42.9,40.4 42.9,40.5 43,40.7 43,40.9 43,41 43,41.2 43,41.3 43,41.5 43,41.6 43.1,41.8 43.1,41.9 43.1,42.1 43.1,42.2 43,42.4 43,42.5 43,42.7 43,42.8 43,43 43,43.1 43,43.3 42.9,43.5 42.9,43.6 42.9,43.8 42.8,43.9 42.8,44.1 42.8,44.2 42.7,44.4 42.7,44.5 42.6,44.6 42.6,44.8 42.6,44.9 42.5,45.1 42.4,45.2 42.4,45.4 42.3,45.5 42.3,45.7 42.2,45.8 42.1,45.9 42.1,46.1 42,46.2 41.9,46.3 41.8,46.5 41.8,46.6 41.7,46.7 41.6,46.9 41.5,47 41.4,47.1 41.3,47.2 41.2,47.4 41.1,47.5 41,47.6 40.9,47.7 40.8,47.8 40.7,47.9 40.6,48.1 40.5,48.2 40.4,48.3 40.3,48.4 40.2,48.5 40.1,48.6 40,48.7 39.9,48.8 39.7,48.9 39.6,49 39.5,49.1 39.4,49.2 39.2,49.3 39.1,49.3 39,49.4 38.9,49.5 38.7,49.6 38.6,49.7 38.5,49.7 38.3,49.8 38.2,49.9 38,49.9 37.9,50 37.8,50.1 37.6,50.1 37.5,50.2 37.3,50.2 37.2,50.3 37.1,50.3 36.9,50.4 36.8,50.4 36.6,50.5 36.5,50.5 36.3,50.6 36.2,50.6 36,50.6 35.9,50.7 35.7,50.7 35.6,50.7 35.4,50.7 35.3,50.7 35.1,50.8 34.9,50.8 34.8,50.8 34.6,50.8 34.5,50.8 34.3,50.8 34.2,50.8 34,50.8 33.9,50.8 33.7,50.8 33.6,50.8 33.4,50.8 33.3,50.8 33.1,50.7 33,50.7 32.8,50.7 32.7,50.7 32.5,50.6 32.4,50.6 32.2,50.6 32.1,50.5 31.9,50.5 31.8,50.4 31.6,50.4 31.5,50.4 31.3,50.3 31.2,50.3 31,50.2 30.9,50.1 30.7,50.1 30.6,50 30.5,50 30.3,49.9 30.2,49.8 30.1,49.7 29.9,49.7 29.8,49.6 29.7,49.5 29.5,49.4 29.4,49.4 29.3,49.3 29.1,49.2 29,49.1 28.9,49 28.8,48.9 28.7,48.8 28.5,48.7 28.4,48.6 28.3,48.5 28.2,48.4 28.1,48.3 28,48.2 27.9,48.1 27.8,48 27.7,47.8 27.6,47.7 27.5,47.6 27.4,47.5 27.3,47.4 27.2,47.2 27.1,47.1 27,47</coordinates></LineString></lineStringMember></MultiLineString>" ) );
|
|
QString res = elemToString( exportC.asGML2( doc, 1 ) );
|
|
QGSCOMPAREGML( res, expectedSimpleGML2 );
|
|
|
|
//as GML3
|
|
QString expectedSimpleGML3( QStringLiteral( "<MultiCurve xmlns=\"gml\"><curveMember xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">7 17 3 13 7 11</posList></ArcString></segments></Curve></curveMember><curveMember xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">27 37 43 43 27 47</posList></ArcString></segments></Curve></curveMember></MultiCurve>" ) );
|
|
res = elemToString( exportC.asGML3( doc ) );
|
|
QCOMPARE( res, expectedSimpleGML3 );
|
|
|
|
// as JSON
|
|
QString expectedSimpleJson( "{\"type\": \"MultiLineString\", \"coordinates\": [[ [7, 17], [6.9, 17], [6.9, 17], [6.8, 17], [6.8, 17.1], [6.7, 17.1], [6.7, 17.1], [6.6, 17.1], [6.6, 17.1], [6.5, 17.1], [6.5, 17.1], [6.4, 17.1], [6.4, 17.1], [6.3, 17.1], [6.2, 17.2], [6.2, 17.2], [6.1, 17.2], [6.1, 17.2], [6, 17.2], [6, 17.2], [5.9, 17.2], [5.9, 17.2], [5.8, 17.2], [5.7, 17.2], [5.7, 17.1], [5.6, 17.1], [5.6, 17.1], [5.5, 17.1], [5.5, 17.1], [5.4, 17.1], [5.4, 17.1], [5.3, 17.1], [5.3, 17.1], [5.2, 17.1], [5.2, 17], [5.1, 17], [5, 17], [5, 17], [4.9, 17], [4.9, 17], [4.8, 16.9], [4.8, 16.9], [4.7, 16.9], [4.7, 16.9], [4.6, 16.9], [4.6, 16.8], [4.5, 16.8], [4.5, 16.8], [4.4, 16.8], [4.4, 16.7], [4.3, 16.7], [4.3, 16.7], [4.3, 16.6], [4.2, 16.6], [4.2, 16.6], [4.1, 16.5], [4.1, 16.5], [4, 16.5], [4, 16.4], [3.9, 16.4], [3.9, 16.4], [3.9, 16.3], [3.8, 16.3], [3.8, 16.3], [3.7, 16.2], [3.7, 16.2], [3.7, 16.1], [3.6, 16.1], [3.6, 16.1], [3.6, 16], [3.5, 16], [3.5, 15.9], [3.5, 15.9], [3.4, 15.8], [3.4, 15.8], [3.4, 15.7], [3.3, 15.7], [3.3, 15.7], [3.3, 15.6], [3.2, 15.6], [3.2, 15.5], [3.2, 15.5], [3.2, 15.4], [3.1, 15.4], [3.1, 15.3], [3.1, 15.3], [3.1, 15.2], [3.1, 15.2], [3, 15.1], [3, 15.1], [3, 15], [3, 15], [3, 14.9], [3, 14.8], [2.9, 14.8], [2.9, 14.7], [2.9, 14.7], [2.9, 14.6], [2.9, 14.6], [2.9, 14.5], [2.9, 14.5], [2.9, 14.4], [2.9, 14.4], [2.9, 14.3], [2.8, 14.2], [2.8, 14.2], [2.8, 14.1], [2.8, 14.1], [2.8, 14], [2.8, 14], [2.8, 13.9], [2.8, 13.9], [2.8, 13.8], [2.8, 13.8], [2.9, 13.7], [2.9, 13.6], [2.9, 13.6], [2.9, 13.5], [2.9, 13.5], [2.9, 13.4], [2.9, 13.4], [2.9, 13.3], [2.9, 13.3], [2.9, 13.2], [3, 13.2], [3, 13.1], [3, 13], [3, 13], [3, 12.9], [3, 12.9], [3.1, 12.8], [3.1, 12.8], [3.1, 12.7], [3.1, 12.7], [3.1, 12.6], [3.2, 12.6], [3.2, 12.5], [3.2, 12.5], [3.2, 12.4], [3.3, 12.4], [3.3, 12.3], [3.3, 12.3], [3.4, 12.3], [3.4, 12.2], [3.4, 12.2], [3.5, 12.1], [3.5, 12.1], [3.5, 12], [3.6, 12], [3.6, 11.9], [3.6, 11.9], [3.7, 11.9], [3.7, 11.8], [3.7, 11.8], [3.8, 11.7], [3.8, 11.7], [3.9, 11.7], [3.9, 11.6], [3.9, 11.6], [4, 11.6], [4, 11.5], [4.1, 11.5], [4.1, 11.5], [4.2, 11.4], [4.2, 11.4], [4.3, 11.4], [4.3, 11.3], [4.3, 11.3], [4.4, 11.3], [4.4, 11.2], [4.5, 11.2], [4.5, 11.2], [4.6, 11.2], [4.6, 11.1], [4.7, 11.1], [4.7, 11.1], [4.8, 11.1], [4.8, 11.1], [4.9, 11], [4.9, 11], [5, 11], [5, 11], [5.1, 11], [5.2, 11], [5.2, 10.9], [5.3, 10.9], [5.3, 10.9], [5.4, 10.9], [5.4, 10.9], [5.5, 10.9], [5.5, 10.9], [5.6, 10.9], [5.6, 10.9], [5.7, 10.9], [5.7, 10.8], [5.8, 10.8], [5.9, 10.8], [5.9, 10.8], [6, 10.8], [6, 10.8], [6.1, 10.8], [6.1, 10.8], [6.2, 10.8], [6.2, 10.8], [6.3, 10.9], [6.4, 10.9], [6.4, 10.9], [6.5, 10.9], [6.5, 10.9], [6.6, 10.9], [6.6, 10.9], [6.7, 10.9], [6.7, 10.9], [6.8, 10.9], [6.8, 11], [6.9, 11], [6.9, 11], [7, 11]], [ [27, 37], [27.1, 36.9], [27.2, 36.8], [27.3, 36.6], [27.4, 36.5], [27.5, 36.4], [27.6, 36.3], [27.7, 36.2], [27.8, 36], [27.9, 35.9], [28, 35.8], [28.1, 35.7], [28.2, 35.6], [28.3, 35.5], [28.4, 35.4], [28.5, 35.3], [28.7, 35.2], [28.8, 35.1], [28.9, 35], [29, 34.9], [29.1, 34.8], [29.3, 34.7], [29.4, 34.6], [29.5, 34.6], [29.7, 34.5], [29.8, 34.4], [29.9, 34.3], [30.1, 34.3], [30.2, 34.2], [30.3, 34.1], [30.5, 34], [30.6, 34], [30.7, 33.9], [30.9, 33.9], [31, 33.8], [31.2, 33.7], [31.3, 33.7], [31.5, 33.6], [31.6, 33.6], [31.8, 33.6], [31.9, 33.5], [32.1, 33.5], [32.2, 33.4], [32.4, 33.4], [32.5, 33.4], [32.7, 33.3], [32.8, 33.3], [33, 33.3], [33.1, 33.3], [33.3, 33.2], [33.4, 33.2], [33.6, 33.2], [33.7, 33.2], [33.9, 33.2], [34, 33.2], [34.2, 33.2], [34.3, 33.2], [34.5, 33.2], [34.6, 33.2], [34.8, 33.2], [34.9, 33.2], [35.1, 33.2], [35.3, 33.3], [35.4, 33.3], [35.6, 33.3], [35.7, 33.3], [35.9, 33.3], [36, 33.4], [36.2, 33.4], [36.3, 33.4], [36.5, 33.5], [36.6, 33.5], [36.8, 33.6], [36.9, 33.6], [37.1, 33.7], [37.2, 33.7], [37.3, 33.8], [37.5, 33.8], [37.6, 33.9], [37.8, 33.9], [37.9, 34], [38, 34.1], [38.2, 34.1], [38.3, 34.2], [38.5, 34.3], [38.6, 34.3], [38.7, 34.4], [38.9, 34.5], [39, 34.6], [39.1, 34.7], [39.2, 34.7], [39.4, 34.8], [39.5, 34.9], [39.6, 35], [39.7, 35.1], [39.9, 35.2], [40, 35.3], [40.1, 35.4], [40.2, 35.5], [40.3, 35.6], [40.4, 35.7], [40.5, 35.8], [40.6, 35.9], [40.7, 36.1], [40.8, 36.2], [40.9, 36.3], [41, 36.4], [41.1, 36.5], [41.2, 36.6], [41.3, 36.8], [41.4, 36.9], [41.5, 37], [41.6, 37.1], [41.7, 37.3], [41.8, 37.4], [41.8, 37.5], [41.9, 37.7], [42, 37.8], [42.1, 37.9], [42.1, 38.1], [42.2, 38.2], [42.3, 38.3], [42.3, 38.5], [42.4, 38.6], [42.4, 38.8], [42.5, 38.9], [42.6, 39.1], [42.6, 39.2], [42.6, 39.4], [42.7, 39.5], [42.7, 39.6], [42.8, 39.8], [42.8, 39.9], [42.8, 40.1], [42.9, 40.2], [42.9, 40.4], [42.9, 40.5], [43, 40.7], [43, 40.9], [43, 41], [43, 41.2], [43, 41.3], [43, 41.5], [43, 41.6], [43.1, 41.8], [43.1, 41.9], [43.1, 42.1], [43.1, 42.2], [43, 42.4], [43, 42.5], [43, 42.7], [43, 42.8], [43, 43], [43, 43.1], [43, 43.3], [42.9, 43.5], [42.9, 43.6], [42.9, 43.8], [42.8, 43.9], [42.8, 44.1], [42.8, 44.2], [42.7, 44.4], [42.7, 44.5], [42.6, 44.6], [42.6, 44.8], [42.6, 44.9], [42.5, 45.1], [42.4, 45.2], [42.4, 45.4], [42.3, 45.5], [42.3, 45.7], [42.2, 45.8], [42.1, 45.9], [42.1, 46.1], [42, 46.2], [41.9, 46.3], [41.8, 46.5], [41.8, 46.6], [41.7, 46.7], [41.6, 46.9], [41.5, 47], [41.4, 47.1], [41.3, 47.2], [41.2, 47.4], [41.1, 47.5], [41, 47.6], [40.9, 47.7], [40.8, 47.8], [40.7, 47.9], [40.6, 48.1], [40.5, 48.2], [40.4, 48.3], [40.3, 48.4], [40.2, 48.5], [40.1, 48.6], [40, 48.7], [39.9, 48.8], [39.7, 48.9], [39.6, 49], [39.5, 49.1], [39.4, 49.2], [39.2, 49.3], [39.1, 49.3], [39, 49.4], [38.9, 49.5], [38.7, 49.6], [38.6, 49.7], [38.5, 49.7], [38.3, 49.8], [38.2, 49.9], [38, 49.9], [37.9, 50], [37.8, 50.1], [37.6, 50.1], [37.5, 50.2], [37.3, 50.2], [37.2, 50.3], [37.1, 50.3], [36.9, 50.4], [36.8, 50.4], [36.6, 50.5], [36.5, 50.5], [36.3, 50.6], [36.2, 50.6], [36, 50.6], [35.9, 50.7], [35.7, 50.7], [35.6, 50.7], [35.4, 50.7], [35.3, 50.7], [35.1, 50.8], [34.9, 50.8], [34.8, 50.8], [34.6, 50.8], [34.5, 50.8], [34.3, 50.8], [34.2, 50.8], [34, 50.8], [33.9, 50.8], [33.7, 50.8], [33.6, 50.8], [33.4, 50.8], [33.3, 50.8], [33.1, 50.7], [33, 50.7], [32.8, 50.7], [32.7, 50.7], [32.5, 50.6], [32.4, 50.6], [32.2, 50.6], [32.1, 50.5], [31.9, 50.5], [31.8, 50.4], [31.6, 50.4], [31.5, 50.4], [31.3, 50.3], [31.2, 50.3], [31, 50.2], [30.9, 50.1], [30.7, 50.1], [30.6, 50], [30.5, 50], [30.3, 49.9], [30.2, 49.8], [30.1, 49.7], [29.9, 49.7], [29.8, 49.6], [29.7, 49.5], [29.5, 49.4], [29.4, 49.4], [29.3, 49.3], [29.1, 49.2], [29, 49.1], [28.9, 49], [28.8, 48.9], [28.7, 48.8], [28.5, 48.7], [28.4, 48.6], [28.3, 48.5], [28.2, 48.4], [28.1, 48.3], [28, 48.2], [27.9, 48.1], [27.8, 48], [27.7, 47.8], [27.6, 47.7], [27.5, 47.6], [27.4, 47.5], [27.3, 47.4], [27.2, 47.2], [27.1, 47.1], [27, 47]]] }" );
|
|
res = exportC.asJSON( 1 );
|
|
QCOMPARE( res, expectedSimpleJson );
|
|
|
|
QgsMultiCurve exportFloat;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7 / 3.0, 17 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 3 / 5.0, 13 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 7 / 3.0, 11 / 3.0 ) ) ;
|
|
exportFloat.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27 / 3.0, 37 / 9.0 ) << QgsPoint( QgsWkbTypes::Point, 43 / 41.0, 43 / 42.0 ) << QgsPoint( QgsWkbTypes::Point, 27 / 3.0, 1 / 3.0 ) ) ;
|
|
exportFloat.addGeometry( part.clone() );
|
|
|
|
QString expectedJsonPrec3( QStringLiteral( "{\"type\": \"MultiLineString\", \"coordinates\": [[ [2.333, 5.667], [2.316, 5.677], [2.298, 5.687], [2.28, 5.697], [2.262, 5.707], [2.244, 5.716], [2.226, 5.725], [2.207, 5.734], [2.188, 5.742], [2.17, 5.75], [2.151, 5.757], [2.131, 5.765], [2.112, 5.772], [2.093, 5.778], [2.074, 5.785], [2.054, 5.79], [2.034, 5.796], [2.015, 5.801], [1.995, 5.806], [1.975, 5.811], [1.955, 5.815], [1.935, 5.819], [1.915, 5.822], [1.894, 5.826], [1.874, 5.828], [1.854, 5.831], [1.834, 5.833], [1.813, 5.835], [1.793, 5.836], [1.773, 5.837], [1.752, 5.838], [1.732, 5.838], [1.711, 5.838], [1.691, 5.838], [1.67, 5.837], [1.65, 5.836], [1.63, 5.834], [1.609, 5.833], [1.589, 5.83], [1.569, 5.828], [1.548, 5.825], [1.528, 5.822], [1.508, 5.818], [1.488, 5.814], [1.468, 5.81], [1.448, 5.805], [1.428, 5.801], [1.409, 5.795], [1.389, 5.79], [1.37, 5.784], [1.35, 5.777], [1.331, 5.771], [1.312, 5.764], [1.293, 5.756], [1.274, 5.749], [1.255, 5.741], [1.236, 5.732], [1.218, 5.724], [1.199, 5.715], [1.181, 5.705], [1.163, 5.696], [1.145, 5.686], [1.128, 5.676], [1.11, 5.665], [1.093, 5.654], [1.076, 5.643], [1.059, 5.632], [1.042, 5.62], [1.025, 5.608], [1.009, 5.596], [0.993, 5.583], [0.977, 5.57], [0.962, 5.557], [0.946, 5.543], [0.931, 5.53], [0.916, 5.516], [0.901, 5.502], [0.887, 5.487], [0.873, 5.473], [0.859, 5.458], [0.845, 5.442], [0.832, 5.427], [0.819, 5.411], [0.806, 5.395], [0.793, 5.379], [0.781, 5.363], [0.769, 5.346], [0.757, 5.33], [0.746, 5.313], [0.735, 5.296], [0.724, 5.278], [0.713, 5.261], [0.703, 5.243], [0.693, 5.225], [0.684, 5.207], [0.674, 5.189], [0.666, 5.171], [0.657, 5.152], [0.649, 5.133], [0.641, 5.115], [0.633, 5.096], [0.626, 5.077], [0.619, 5.057], [0.612, 5.038], [0.606, 5.019], [0.6, 4.999], [0.594, 4.979], [0.589, 4.96], [0.584, 4.94], [0.579, 4.92], [0.575, 4.9], [0.571, 4.88], [0.568, 4.86], [0.564, 4.84], [0.562, 4.819], [0.559, 4.799], [0.557, 4.779], [0.555, 4.759], [0.554, 4.738], [0.553, 4.718], [0.552, 4.697], [0.552, 4.677], [0.552, 4.656], [0.552, 4.636], [0.553, 4.616], [0.554, 4.595], [0.555, 4.575], [0.557, 4.554], [0.559, 4.534], [0.562, 4.514], [0.564, 4.494], [0.568, 4.473], [0.571, 4.453], [0.575, 4.433], [0.579, 4.413], [0.584, 4.393], [0.589, 4.374], [0.594, 4.354], [0.6, 4.334], [0.606, 4.315], [0.612, 4.295], [0.619, 4.276], [0.626, 4.257], [0.633, 4.238], [0.641, 4.219], [0.649, 4.2], [0.657, 4.181], [0.666, 4.163], [0.674, 4.144], [0.684, 4.126], [0.693, 4.108], [0.703, 4.09], [0.713, 4.073], [0.724, 4.055], [0.735, 4.038], [0.746, 4.021], [0.757, 4.004], [0.769, 3.987], [0.781, 3.97], [0.793, 3.954], [0.806, 3.938], [0.819, 3.922], [0.832, 3.906], [0.845, 3.891], [0.859, 3.876], [0.873, 3.861], [0.887, 3.846], [0.901, 3.832], [0.916, 3.817], [0.931, 3.804], [0.946, 3.79], [0.962, 3.776], [0.977, 3.763], [0.993, 3.75], [1.009, 3.738], [1.025, 3.726], [1.042, 3.713], [1.059, 3.702], [1.076, 3.69], [1.093, 3.679], [1.11, 3.668], [1.128, 3.658], [1.145, 3.648], [1.163, 3.638], [1.181, 3.628], [1.199, 3.619], [1.218, 3.61], [1.236, 3.601], [1.255, 3.593], [1.274, 3.585], [1.293, 3.577], [1.312, 3.57], [1.331, 3.563], [1.35, 3.556], [1.37, 3.55], [1.389, 3.544], [1.409, 3.538], [1.428, 3.533], [1.448, 3.528], [1.468, 3.523], [1.488, 3.519], [1.508, 3.515], [1.528, 3.511], [1.548, 3.508], [1.569, 3.505], [1.589, 3.503], [1.609, 3.501], [1.63, 3.499], [1.65, 3.497], [1.67, 3.496], [1.691, 3.496], [1.711, 3.495], [1.732, 3.495], [1.752, 3.496], [1.773, 3.496], [1.793, 3.497], [1.813, 3.499], [1.834, 3.5], [1.854, 3.503], [1.874, 3.505], [1.894, 3.508], [1.915, 3.511], [1.935, 3.514], [1.955, 3.518], [1.975, 3.523], [1.995, 3.527], [2.015, 3.532], [2.034, 3.537], [2.054, 3.543], [2.074, 3.549], [2.093, 3.555], [2.112, 3.562], [2.131, 3.569], [2.151, 3.576], [2.17, 3.584], [2.188, 3.592], [2.207, 3.6], [2.226, 3.608], [2.244, 3.617], [2.262, 3.627], [2.28, 3.636], [2.298, 3.646], [2.316, 3.656], [2.333, 3.667]], [ [9, 4.111], [8.966, 4.178], [8.932, 4.244], [8.896, 4.309], [8.859, 4.374], [8.821, 4.438], [8.782, 4.502], [8.742, 4.565], [8.7, 4.627], [8.658, 4.688], [8.614, 4.749], [8.57, 4.809], [8.524, 4.868], [8.477, 4.926], [8.43, 4.983], [8.381, 5.04], [8.331, 5.096], [8.281, 5.151], [8.229, 5.205], [8.177, 5.258], [8.124, 5.31], [8.069, 5.361], [8.014, 5.411], [7.958, 5.461], [7.901, 5.509], [7.844, 5.556], [7.785, 5.603], [7.726, 5.648], [7.666, 5.692], [7.605, 5.735], [7.543, 5.777], [7.481, 5.818], [7.418, 5.858], [7.354, 5.897], [7.29, 5.935], [7.225, 5.971], [7.159, 6.007], [7.093, 6.041], [7.026, 6.074], [6.958, 6.106], [6.89, 6.137], [6.822, 6.167], [6.753, 6.195], [6.683, 6.222], [6.613, 6.248], [6.543, 6.273], [6.472, 6.296], [6.401, 6.319], [6.329, 6.34], [6.257, 6.36], [6.185, 6.378], [6.112, 6.395], [6.04, 6.411], [5.966, 6.426], [5.893, 6.44], [5.819, 6.452], [5.746, 6.463], [5.672, 6.472], [5.597, 6.48], [5.523, 6.487], [5.449, 6.493], [5.374, 6.498], [5.3, 6.501], [5.225, 6.503], [5.15, 6.503], [5.076, 6.502], [5.001, 6.5], [4.927, 6.497], [4.852, 6.492], [4.778, 6.486], [4.704, 6.479], [4.629, 6.47], [4.555, 6.46], [4.482, 6.449], [4.408, 6.437], [4.335, 6.423], [4.262, 6.408], [4.189, 6.392], [4.116, 6.374], [4.044, 6.355], [3.972, 6.335], [3.901, 6.314], [3.83, 6.292], [3.759, 6.268], [3.688, 6.243], [3.619, 6.217], [3.549, 6.189], [3.48, 6.16], [3.412, 6.131], [3.344, 6.1], [3.277, 6.067], [3.21, 6.034], [3.144, 5.999], [3.078, 5.964], [3.013, 5.927], [2.949, 5.889], [2.886, 5.85], [2.823, 5.81], [2.761, 5.768], [2.699, 5.726], [2.638, 5.683], [2.578, 5.638], [2.519, 5.593], [2.461, 5.546], [2.403, 5.499], [2.347, 5.45], [2.291, 5.401], [2.236, 5.35], [2.182, 5.299], [2.129, 5.246], [2.076, 5.193], [2.025, 5.139], [1.975, 5.084], [1.925, 5.028], [1.877, 4.971], [1.829, 4.914], [1.783, 4.855], [1.738, 4.796], [1.693, 4.736], [1.65, 4.675], [1.608, 4.614], [1.567, 4.551], [1.527, 4.488], [1.488, 4.425], [1.45, 4.36], [1.413, 4.295], [1.378, 4.23], [1.343, 4.164], [1.31, 4.097], [1.278, 4.029], [1.247, 3.961], [1.217, 3.893], [1.189, 3.824], [1.161, 3.755], [1.135, 3.685], [1.11, 3.614], [1.087, 3.544], [1.064, 3.472], [1.043, 3.401], [1.023, 3.329], [1.004, 3.257], [0.987, 3.184], [0.971, 3.111], [0.956, 3.038], [0.942, 2.965], [0.93, 2.891], [0.919, 2.817], [0.909, 2.743], [0.901, 2.669], [0.894, 2.595], [0.888, 2.52], [0.883, 2.446], [0.88, 2.371], [0.878, 2.297], [0.878, 2.222], [0.878, 2.148], [0.88, 2.073], [0.883, 1.998], [0.888, 1.924], [0.894, 1.85], [0.901, 1.775], [0.909, 1.701], [0.919, 1.627], [0.93, 1.553], [0.942, 1.48], [0.956, 1.406], [0.971, 1.333], [0.987, 1.26], [1.004, 1.188], [1.023, 1.116], [1.043, 1.044], [1.064, 0.972], [1.087, 0.901], [1.11, 0.83], [1.135, 0.76], [1.161, 0.69], [1.189, 0.62], [1.217, 0.551], [1.247, 0.483], [1.278, 0.415], [1.31, 0.348], [1.343, 0.281], [1.378, 0.215], [1.413, 0.149], [1.45, 0.084], [1.488, 0.02], [1.527, -0.044], [1.567, -0.107], [1.608, -0.169], [1.65, -0.231], [1.693, -0.291], [1.738, -0.351], [1.783, -0.411], [1.829, -0.469], [1.877, -0.527], [1.925, -0.584], [1.975, -0.639], [2.025, -0.694], [2.076, -0.749], [2.129, -0.802], [2.182, -0.854], [2.236, -0.906], [2.291, -0.956], [2.347, -1.006], [2.403, -1.054], [2.461, -1.102], [2.519, -1.148], [2.578, -1.194], [2.638, -1.238], [2.699, -1.282], [2.761, -1.324], [2.823, -1.365], [2.886, -1.405], [2.949, -1.444], [3.013, -1.482], [3.078, -1.519], [3.144, -1.555], [3.21, -1.589], [3.277, -1.623], [3.344, -1.655], [3.412, -1.686], [3.48, -1.716], [3.549, -1.745], [3.619, -1.772], [3.688, -1.798], [3.759, -1.823], [3.83, -1.847], [3.901, -1.87], [3.972, -1.891], [4.044, -1.911], [4.116, -1.93], [4.189, -1.947], [4.262, -1.964], [4.335, -1.979], [4.408, -1.992], [4.482, -2.005], [4.555, -2.016], [4.629, -2.026], [4.704, -2.034], [4.778, -2.042], [4.852, -2.048], [4.927, -2.052], [5.001, -2.056], [5.076, -2.058], [5.15, -2.059], [5.225, -2.058], [5.3, -2.056], [5.374, -2.053], [5.449, -2.049], [5.523, -2.043], [5.597, -2.036], [5.672, -2.028], [5.746, -2.018], [5.819, -2.007], [5.893, -1.995], [5.966, -1.982], [6.04, -1.967], [6.112, -1.951], [6.185, -1.934], [6.257, -1.915], [6.329, -1.895], [6.401, -1.874], [6.472, -1.852], [6.543, -1.829], [6.613, -1.804], [6.683, -1.778], [6.753, -1.751], [6.822, -1.722], [6.89, -1.693], [6.958, -1.662], [7.026, -1.63], [7.093, -1.597], [7.159, -1.562], [7.225, -1.527], [7.29, -1.49], [7.354, -1.453], [7.418, -1.414], [7.481, -1.374], [7.543, -1.333], [7.605, -1.291], [7.666, -1.248], [7.726, -1.203], [7.785, -1.158], [7.844, -1.112], [7.901, -1.065], [7.958, -1.016], [8.014, -0.967], [8.069, -0.917], [8.124, -0.865], [8.177, -0.813], [8.229, -0.76], [8.281, -0.706], [8.331, -0.651], [8.381, -0.596], [8.43, -0.539], [8.477, -0.482], [8.524, -0.423], [8.57, -0.364], [8.614, -0.304], [8.658, -0.244], [8.7, -0.182], [8.742, -0.12], [8.782, -0.057], [8.821, 0.006], [8.859, 0.07], [8.896, 0.135], [8.932, 0.201], [8.966, 0.267], [9, 0.333]]] }" ) );
|
|
res = exportFloat.asJSON( 3 );
|
|
QCOMPARE( res, expectedJsonPrec3 );
|
|
|
|
// as GML2
|
|
QString expectedGML2prec3( QStringLiteral( "<MultiLineString xmlns=\"gml\"><lineStringMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">2.333,5.667 2.316,5.677 2.298,5.687 2.28,5.697 2.262,5.707 2.244,5.716 2.226,5.725 2.207,5.734 2.188,5.742 2.17,5.75 2.151,5.757 2.131,5.765 2.112,5.772 2.093,5.778 2.074,5.785 2.054,5.79 2.034,5.796 2.015,5.801 1.995,5.806 1.975,5.811 1.955,5.815 1.935,5.819 1.915,5.822 1.894,5.826 1.874,5.828 1.854,5.831 1.834,5.833 1.813,5.835 1.793,5.836 1.773,5.837 1.752,5.838 1.732,5.838 1.711,5.838 1.691,5.838 1.67,5.837 1.65,5.836 1.63,5.834 1.609,5.833 1.589,5.83 1.569,5.828 1.548,5.825 1.528,5.822 1.508,5.818 1.488,5.814 1.468,5.81 1.448,5.805 1.428,5.801 1.409,5.795 1.389,5.79 1.37,5.784 1.35,5.777 1.331,5.771 1.312,5.764 1.293,5.756 1.274,5.749 1.255,5.741 1.236,5.732 1.218,5.724 1.199,5.715 1.181,5.705 1.163,5.696 1.145,5.686 1.128,5.676 1.11,5.665 1.093,5.654 1.076,5.643 1.059,5.632 1.042,5.62 1.025,5.608 1.009,5.596 0.993,5.583 0.977,5.57 0.962,5.557 0.946,5.543 0.931,5.53 0.916,5.516 0.901,5.502 0.887,5.487 0.873,5.473 0.859,5.458 0.845,5.442 0.832,5.427 0.819,5.411 0.806,5.395 0.793,5.379 0.781,5.363 0.769,5.346 0.757,5.33 0.746,5.313 0.735,5.296 0.724,5.278 0.713,5.261 0.703,5.243 0.693,5.225 0.684,5.207 0.674,5.189 0.666,5.171 0.657,5.152 0.649,5.133 0.641,5.115 0.633,5.096 0.626,5.077 0.619,5.057 0.612,5.038 0.606,5.019 0.6,4.999 0.594,4.979 0.589,4.96 0.584,4.94 0.579,4.92 0.575,4.9 0.571,4.88 0.568,4.86 0.564,4.84 0.562,4.819 0.559,4.799 0.557,4.779 0.555,4.759 0.554,4.738 0.553,4.718 0.552,4.697 0.552,4.677 0.552,4.656 0.552,4.636 0.553,4.616 0.554,4.595 0.555,4.575 0.557,4.554 0.559,4.534 0.562,4.514 0.564,4.494 0.568,4.473 0.571,4.453 0.575,4.433 0.579,4.413 0.584,4.393 0.589,4.374 0.594,4.354 0.6,4.334 0.606,4.315 0.612,4.295 0.619,4.276 0.626,4.257 0.633,4.238 0.641,4.219 0.649,4.2 0.657,4.181 0.666,4.163 0.674,4.144 0.684,4.126 0.693,4.108 0.703,4.09 0.713,4.073 0.724,4.055 0.735,4.038 0.746,4.021 0.757,4.004 0.769,3.987 0.781,3.97 0.793,3.954 0.806,3.938 0.819,3.922 0.832,3.906 0.845,3.891 0.859,3.876 0.873,3.861 0.887,3.846 0.901,3.832 0.916,3.817 0.931,3.804 0.946,3.79 0.962,3.776 0.977,3.763 0.993,3.75 1.009,3.738 1.025,3.726 1.042,3.713 1.059,3.702 1.076,3.69 1.093,3.679 1.11,3.668 1.128,3.658 1.145,3.648 1.163,3.638 1.181,3.628 1.199,3.619 1.218,3.61 1.236,3.601 1.255,3.593 1.274,3.585 1.293,3.577 1.312,3.57 1.331,3.563 1.35,3.556 1.37,3.55 1.389,3.544 1.409,3.538 1.428,3.533 1.448,3.528 1.468,3.523 1.488,3.519 1.508,3.515 1.528,3.511 1.548,3.508 1.569,3.505 1.589,3.503 1.609,3.501 1.63,3.499 1.65,3.497 1.67,3.496 1.691,3.496 1.711,3.495 1.732,3.495 1.752,3.496 1.773,3.496 1.793,3.497 1.813,3.499 1.834,3.5 1.854,3.503 1.874,3.505 1.894,3.508 1.915,3.511 1.935,3.514 1.955,3.518 1.975,3.523 1.995,3.527 2.015,3.532 2.034,3.537 2.054,3.543 2.074,3.549 2.093,3.555 2.112,3.562 2.131,3.569 2.151,3.576 2.17,3.584 2.188,3.592 2.207,3.6 2.226,3.608 2.244,3.617 2.262,3.627 2.28,3.636 2.298,3.646 2.316,3.656 2.333,3.667</coordinates></LineString></lineStringMember><lineStringMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">9,4.111 8.966,4.178 8.932,4.244 8.896,4.309 8.859,4.374 8.821,4.438 8.782,4.502 8.742,4.565 8.7,4.627 8.658,4.688 8.614,4.749 8.57,4.809 8.524,4.868 8.477,4.926 8.43,4.983 8.381,5.04 8.331,5.096 8.281,5.151 8.229,5.205 8.177,5.258 8.124,5.31 8.069,5.361 8.014,5.411 7.958,5.461 7.901,5.509 7.844,5.556 7.785,5.603 7.726,5.648 7.666,5.692 7.605,5.735 7.543,5.777 7.481,5.818 7.418,5.858 7.354,5.897 7.29,5.935 7.225,5.971 7.159,6.007 7.093,6.041 7.026,6.074 6.958,6.106 6.89,6.137 6.822,6.167 6.753,6.195 6.683,6.222 6.613,6.248 6.543,6.273 6.472,6.296 6.401,6.319 6.329,6.34 6.257,6.36 6.185,6.378 6.112,6.395 6.04,6.411 5.966,6.426 5.893,6.44 5.819,6.452 5.746,6.463 5.672,6.472 5.597,6.48 5.523,6.487 5.449,6.493 5.374,6.498 5.3,6.501 5.225,6.503 5.15,6.503 5.076,6.502 5.001,6.5 4.927,6.497 4.852,6.492 4.778,6.486 4.704,6.479 4.629,6.47 4.555,6.46 4.482,6.449 4.408,6.437 4.335,6.423 4.262,6.408 4.189,6.392 4.116,6.374 4.044,6.355 3.972,6.335 3.901,6.314 3.83,6.292 3.759,6.268 3.688,6.243 3.619,6.217 3.549,6.189 3.48,6.16 3.412,6.131 3.344,6.1 3.277,6.067 3.21,6.034 3.144,5.999 3.078,5.964 3.013,5.927 2.949,5.889 2.886,5.85 2.823,5.81 2.761,5.768 2.699,5.726 2.638,5.683 2.578,5.638 2.519,5.593 2.461,5.546 2.403,5.499 2.347,5.45 2.291,5.401 2.236,5.35 2.182,5.299 2.129,5.246 2.076,5.193 2.025,5.139 1.975,5.084 1.925,5.028 1.877,4.971 1.829,4.914 1.783,4.855 1.738,4.796 1.693,4.736 1.65,4.675 1.608,4.614 1.567,4.551 1.527,4.488 1.488,4.425 1.45,4.36 1.413,4.295 1.378,4.23 1.343,4.164 1.31,4.097 1.278,4.029 1.247,3.961 1.217,3.893 1.189,3.824 1.161,3.755 1.135,3.685 1.11,3.614 1.087,3.544 1.064,3.472 1.043,3.401 1.023,3.329 1.004,3.257 0.987,3.184 0.971,3.111 0.956,3.038 0.942,2.965 0.93,2.891 0.919,2.817 0.909,2.743 0.901,2.669 0.894,2.595 0.888,2.52 0.883,2.446 0.88,2.371 0.878,2.297 0.878,2.222 0.878,2.148 0.88,2.073 0.883,1.998 0.888,1.924 0.894,1.85 0.901,1.775 0.909,1.701 0.919,1.627 0.93,1.553 0.942,1.48 0.956,1.406 0.971,1.333 0.987,1.26 1.004,1.188 1.023,1.116 1.043,1.044 1.064,0.972 1.087,0.901 1.11,0.83 1.135,0.76 1.161,0.69 1.189,0.62 1.217,0.551 1.247,0.483 1.278,0.415 1.31,0.348 1.343,0.281 1.378,0.215 1.413,0.149 1.45,0.084 1.488,0.02 1.527,-0.044 1.567,-0.107 1.608,-0.169 1.65,-0.231 1.693,-0.291 1.738,-0.351 1.783,-0.411 1.829,-0.469 1.877,-0.527 1.925,-0.584 1.975,-0.639 2.025,-0.694 2.076,-0.749 2.129,-0.802 2.182,-0.854 2.236,-0.906 2.291,-0.956 2.347,-1.006 2.403,-1.054 2.461,-1.102 2.519,-1.148 2.578,-1.194 2.638,-1.238 2.699,-1.282 2.761,-1.324 2.823,-1.365 2.886,-1.405 2.949,-1.444 3.013,-1.482 3.078,-1.519 3.144,-1.555 3.21,-1.589 3.277,-1.623 3.344,-1.655 3.412,-1.686 3.48,-1.716 3.549,-1.745 3.619,-1.772 3.688,-1.798 3.759,-1.823 3.83,-1.847 3.901,-1.87 3.972,-1.891 4.044,-1.911 4.116,-1.93 4.189,-1.947 4.262,-1.964 4.335,-1.979 4.408,-1.992 4.482,-2.005 4.555,-2.016 4.629,-2.026 4.704,-2.034 4.778,-2.042 4.852,-2.048 4.927,-2.052 5.001,-2.056 5.076,-2.058 5.15,-2.059 5.225,-2.058 5.3,-2.056 5.374,-2.053 5.449,-2.049 5.523,-2.043 5.597,-2.036 5.672,-2.028 5.746,-2.018 5.819,-2.007 5.893,-1.995 5.966,-1.982 6.04,-1.967 6.112,-1.951 6.185,-1.934 6.257,-1.915 6.329,-1.895 6.401,-1.874 6.472,-1.852 6.543,-1.829 6.613,-1.804 6.683,-1.778 6.753,-1.751 6.822,-1.722 6.89,-1.693 6.958,-1.662 7.026,-1.63 7.093,-1.597 7.159,-1.562 7.225,-1.527 7.29,-1.49 7.354,-1.453 7.418,-1.414 7.481,-1.374 7.543,-1.333 7.605,-1.291 7.666,-1.248 7.726,-1.203 7.785,-1.158 7.844,-1.112 7.901,-1.065 7.958,-1.016 8.014,-0.967 8.069,-0.917 8.124,-0.865 8.177,-0.813 8.229,-0.76 8.281,-0.706 8.331,-0.651 8.381,-0.596 8.43,-0.539 8.477,-0.482 8.524,-0.423 8.57,-0.364 8.614,-0.304 8.658,-0.244 8.7,-0.182 8.742,-0.12 8.782,-0.057 8.821,0.006 8.859,0.07 8.896,0.135 8.932,0.201 8.966,0.267 9,0.333</coordinates></LineString></lineStringMember></MultiLineString>" ) );
|
|
res = elemToString( exportFloat.asGML2( doc, 3 ) );
|
|
QGSCOMPAREGML( res, expectedGML2prec3 );
|
|
|
|
//as GML3
|
|
QString expectedGML3prec3( QStringLiteral( "<MultiCurve xmlns=\"gml\"><curveMember xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">2.333 5.667 0.6 4.333 2.333 3.667</posList></ArcString></segments></Curve></curveMember><curveMember xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">9 4.111 1.049 1.024 9 0.333</posList></ArcString></segments></Curve></curveMember></MultiCurve>" ) );
|
|
res = elemToString( exportFloat.asGML3( doc, 3 ) );
|
|
QCOMPARE( res, expectedGML3prec3 );
|
|
|
|
// insert geometry
|
|
QgsMultiCurve rc;
|
|
rc.clear();
|
|
rc.insertGeometry( nullptr, 0 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
rc.insertGeometry( nullptr, -1 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
rc.insertGeometry( nullptr, 100 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
|
|
rc.insertGeometry( new QgsPoint(), 0 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
|
|
rc.insertGeometry( part.clone(), 0 );
|
|
QVERIFY( !rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 1 );
|
|
|
|
// cast
|
|
QVERIFY( !QgsMultiCurve().cast( nullptr ) );
|
|
QgsMultiCurve pCast;
|
|
QVERIFY( QgsMultiCurve().cast( &pCast ) );
|
|
QgsMultiCurve pCast2;
|
|
pCast2.fromWkt( QStringLiteral( "MultiCurveZ()" ) );
|
|
QVERIFY( QgsMultiCurve().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "MultiCurveM()" ) );
|
|
QVERIFY( QgsMultiCurve().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "MultiCurveZM()" ) );
|
|
QVERIFY( QgsMultiCurve().cast( &pCast2 ) );
|
|
|
|
//boundary
|
|
QgsMultiCurve multiLine1;
|
|
QVERIFY( !multiLine1.boundary() );
|
|
QgsCircularString boundaryLine1;
|
|
boundaryLine1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) );
|
|
multiLine1.addGeometry( boundaryLine1.clone() );
|
|
QgsAbstractGeometry *boundary = multiLine1.boundary();
|
|
QgsMultiPointV2 *mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->numGeometries(), 2 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
delete boundary;
|
|
// add another QgsCircularString
|
|
QgsCircularString boundaryLine2;
|
|
boundaryLine2.setPoints( QList<QgsPoint>() << QgsPoint( 10, 10 ) << QgsPoint( 11, 10 ) << QgsPoint( 11, 11 ) );
|
|
multiLine1.addGeometry( boundaryLine2.clone() );
|
|
boundary = multiLine1.boundary();
|
|
mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->numGeometries(), 4 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->x(), 10.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->y(), 10.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->x(), 11.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->y(), 11.0 );
|
|
delete boundary;
|
|
|
|
// add a closed string = no boundary
|
|
QgsCircularString boundaryLine3;
|
|
boundaryLine3.setPoints( QList<QgsPoint>() << QgsPoint( 20, 20 ) << QgsPoint( 21, 20 ) << QgsPoint( 20, 20 ) );
|
|
multiLine1.addGeometry( boundaryLine3.clone() );
|
|
boundary = multiLine1.boundary();
|
|
mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->numGeometries(), 4 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->x(), 10.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->y(), 10.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->x(), 11.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->y(), 11.0 );
|
|
delete boundary;
|
|
|
|
//boundary with z
|
|
QgsCircularString boundaryLine4;
|
|
boundaryLine4.setPoints( QList<QgsPoint>() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 10 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 0, 15 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 20 ) );
|
|
QgsCircularString boundaryLine5;
|
|
boundaryLine5.setPoints( QList<QgsPoint>() << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 100 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 20, 150 ) << QgsPoint( QgsWkbTypes::PointZ, 20, 20, 200 ) );
|
|
QgsMultiCurve multiLine2;
|
|
multiLine2.addGeometry( boundaryLine4.clone() );
|
|
multiLine2.addGeometry( boundaryLine5.clone() );
|
|
|
|
boundary = multiLine2.boundary();
|
|
mpBoundary = dynamic_cast< QgsMultiPointV2 * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->numGeometries(), 4 );
|
|
QCOMPARE( mpBoundary->geometryN( 0 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->x(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->y(), 0.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 0 ) )->z(), 10.0 );
|
|
QCOMPARE( mpBoundary->geometryN( 1 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->x(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->y(), 1.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 1 ) )->z(), 20.0 );
|
|
QCOMPARE( mpBoundary->geometryN( 2 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->x(), 10.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->y(), 10.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 2 ) )->z(), 100.0 );
|
|
QCOMPARE( mpBoundary->geometryN( 3 )->wkbType(), QgsWkbTypes::PointZ );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->x(), 20.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->y(), 20.0 );
|
|
QCOMPARE( static_cast< QgsPoint *>( mpBoundary->geometryN( 3 ) )->z(), 200.0 );
|
|
delete boundary;
|
|
|
|
//reversed
|
|
QgsMultiCurve cR;
|
|
std::unique_ptr< QgsMultiCurve > reversed( cR.reversed() );
|
|
QVERIFY( reversed->isEmpty() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 13, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 7, 11, 2, 8 ) ) ;
|
|
cR.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 43, 43, 11, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 27, 53, 21, 52 ) ) ;
|
|
cR.addGeometry( part.clone() );
|
|
reversed.reset( cR.reversed() );
|
|
QVERIFY( !reversed->isEmpty() );
|
|
ls = static_cast< const QgsCircularString * >( reversed->geometryN( 0 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 7, 11, 2, 8 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 3, 13, 1, 4 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) );
|
|
ls = static_cast< const QgsCircularString * >( reversed->geometryN( 1 ) );
|
|
QCOMPARE( ls->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 27, 53, 21, 52 ) );
|
|
QCOMPARE( ls->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 43, 43, 11, 5 ) );
|
|
QCOMPARE( ls->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) );
|
|
}
|
|
|
|
void TestQgsGeometry::multiSurface()
|
|
{
|
|
//test constructor
|
|
QgsMultiSurface c1;
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiSurface );
|
|
QCOMPARE( c1.wktTypeStr(), QString( "MultiSurface" ) );
|
|
QCOMPARE( c1.geometryType(), QString( "MultiSurface" ) );
|
|
QCOMPARE( c1.dimension(), 0 );
|
|
QVERIFY( !c1.hasCurvedSegments() );
|
|
QCOMPARE( c1.area(), 0.0 );
|
|
QCOMPARE( c1.perimeter(), 0.0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
QCOMPARE( c1.vertexCount( 0, 0 ), 0 );
|
|
QCOMPARE( c1.vertexCount( 0, 1 ), 0 );
|
|
QCOMPARE( c1.vertexCount( 1, 0 ), 0 );
|
|
|
|
//addGeometry
|
|
//try with nullptr
|
|
c1.addGeometry( nullptr );
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiSurface );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
|
|
// not a surface
|
|
QVERIFY( !c1.addGeometry( new QgsPoint() ) );
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiSurface );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
|
|
//valid geometry
|
|
QgsCurvePolygon part;
|
|
QgsCircularString ring;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 1, 10 ) << QgsPoint( 2, 11 ) << QgsPoint( 1, 10 ) );
|
|
part.setExteriorRing( ring.clone() );
|
|
c1.addGeometry( part.clone() );
|
|
QVERIFY( !c1.isEmpty() );
|
|
QCOMPARE( c1.numGeometries(), 1 );
|
|
QCOMPARE( c1.nCoordinates(), 3 );
|
|
QCOMPARE( c1.ringCount(), 1 );
|
|
QCOMPARE( c1.partCount(), 1 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiSurface );
|
|
QCOMPARE( c1.wktTypeStr(), QString( "MultiSurface" ) );
|
|
QCOMPARE( c1.geometryType(), QString( "MultiSurface" ) );
|
|
QCOMPARE( c1.dimension(), 2 );
|
|
QVERIFY( c1.hasCurvedSegments() );
|
|
QVERIFY( c1.geometryN( 0 ) );
|
|
QCOMPARE( *static_cast< const QgsCurvePolygon * >( c1.geometryN( 0 ) ), part );
|
|
QVERIFY( !c1.geometryN( 100 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
QCOMPARE( c1.vertexCount( 0, 0 ), 3 );
|
|
QCOMPARE( c1.vertexCount( 1, 0 ), 0 );
|
|
|
|
//initial adding of geometry should set z/m type
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 10, 11, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 20, 21, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 11, 1 ) );
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
QgsMultiSurface c2;
|
|
c2.addGeometry( part.clone() );
|
|
QVERIFY( c2.is3D() );
|
|
QVERIFY( !c2.isMeasure() );
|
|
QCOMPARE( c2.wkbType(), QgsWkbTypes::MultiSurfaceZ );
|
|
QCOMPARE( c2.wktTypeStr(), QString( "MultiSurfaceZ" ) );
|
|
QCOMPARE( c2.geometryType(), QString( "MultiSurface" ) );
|
|
QCOMPARE( *( static_cast< const QgsCurvePolygon * >( c2.geometryN( 0 ) ) ), part );
|
|
QgsMultiSurface c3;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 10, 11, 0, 1 ) << QgsPoint( QgsWkbTypes::PointM, 20, 21, 0, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 10, 11, 0, 1 ) );
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c3.addGeometry( part.clone() );
|
|
QVERIFY( !c3.is3D() );
|
|
QVERIFY( c3.isMeasure() );
|
|
QCOMPARE( c3.wkbType(), QgsWkbTypes::MultiSurfaceM );
|
|
QCOMPARE( c3.wktTypeStr(), QString( "MultiSurfaceM" ) );
|
|
QCOMPARE( *( static_cast< const QgsCurvePolygon * >( c3.geometryN( 0 ) ) ), part );
|
|
QgsMultiSurface c4;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 10, 11, 2, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 20, 21, 3, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 11, 2, 1 ) );
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c4.addGeometry( part.clone() );
|
|
QVERIFY( c4.is3D() );
|
|
QVERIFY( c4.isMeasure() );
|
|
QCOMPARE( c4.wkbType(), QgsWkbTypes::MultiSurfaceZM );
|
|
QCOMPARE( c4.wktTypeStr(), QString( "MultiSurfaceZM" ) );
|
|
QCOMPARE( *( static_cast< const QgsCurvePolygon * >( c4.geometryN( 0 ) ) ), part );
|
|
|
|
//add another part
|
|
QgsMultiSurface c6;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 1, 10 ) << QgsPoint( 2, 11 ) << QgsPoint( 1, 10 ) );
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 3 );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 9, 12 ) << QgsPoint( 3, 13 ) << QgsPoint( 9, 12 ) );
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 3 );
|
|
QCOMPARE( c6.numGeometries(), 2 );
|
|
QVERIFY( c6.geometryN( 0 ) );
|
|
QCOMPARE( *static_cast< const QgsCurvePolygon * >( c6.geometryN( 1 ) ), part );
|
|
|
|
//adding subsequent points should not alter z/m type, regardless of parts type
|
|
c6.clear();
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurface );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 1, 10, 2 ) << QgsPoint( 2, 11, 3 ) << QgsPoint( 1, 10, 2 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurface );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 3 );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 3 );
|
|
QCOMPARE( c6.vertexCount( 2, 0 ), 0 );
|
|
QCOMPARE( c6.vertexCount( -1, 0 ), 0 );
|
|
QCOMPARE( c6.nCoordinates(), 6 );
|
|
QCOMPARE( c6.ringCount(), 1 );
|
|
QCOMPARE( c6.partCount(), 2 );
|
|
QVERIFY( !c6.is3D() );
|
|
const QgsCurvePolygon *ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( 9, 12 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( 3, 13 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( 9, 12 ) );
|
|
ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( 1, 10 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( 2, 11 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( 1, 10 ) );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 21, 30, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 32, 41, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 21, 30, 0, 2 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurface );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 3 );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 3 );
|
|
QCOMPARE( c6.vertexCount( 2, 0 ), 3 );
|
|
QCOMPARE( c6.nCoordinates(), 9 );
|
|
QCOMPARE( c6.ringCount(), 1 );
|
|
QCOMPARE( c6.partCount(), 3 );
|
|
QVERIFY( !c6.is3D() );
|
|
QVERIFY( !c6.isMeasure() );
|
|
ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( 21, 30 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( 32, 41 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( 21, 30 ) );
|
|
|
|
c6.clear();
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 1, 10, 2 ) << QgsPoint( 2, 11, 3 ) << QgsPoint( 1, 10, 2 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurfaceZ );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 2, 20 ) << QgsPoint( 3, 31 ) << QgsPoint( 2, 20 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurfaceZ );
|
|
QVERIFY( c6.is3D() );
|
|
ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( 1, 10, 2 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( 2, 11, 3 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( 1, 10, 2 ) );
|
|
ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( 2, 20, 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( 3, 31, 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( 2, 20, 0 ) );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 6, 61, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurfaceZ );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( !c6.isMeasure() );
|
|
ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( 5, 50, 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( 6, 61, 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( 5, 50, 0 ) );
|
|
|
|
c6.clear();
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurface );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 6, 61, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurfaceM );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 2, 20 ) << QgsPoint( 3, 31 ) << QgsPoint( 2, 20 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurfaceM );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 6, 61, 0, 5 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) );
|
|
ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 2, 20, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 3, 31, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointM, 2, 20, 0, 0 ) );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 11, 12, 13 ) << QgsPoint( 14, 15, 16 ) << QgsPoint( 11, 12, 13 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurfaceM );
|
|
QVERIFY( !c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 14, 15, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 0 ) );
|
|
|
|
c6.clear();
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 6, 61, 3, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurfaceZM );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 7, 17 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurfaceZM );
|
|
QVERIFY( c6.isMeasure() );
|
|
QVERIFY( c6.is3D() );
|
|
ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 6, 61, 3, 5 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) );
|
|
ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 7, 17, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 3, 13, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 7, 17, 0, 0 ) );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 77, 87, 7 ) << QgsPoint( QgsWkbTypes::PointZ, 83, 83, 8 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 77, 87, 7 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurfaceZM );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 77, 87, 7, 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 83, 83, 8, 0 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 77, 87, 7, 0 ) );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 177, 187, 0, 9 ) << QgsPoint( QgsWkbTypes::PointM, 183, 183, 0, 11 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 177, 187, 0, 9 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiSurfaceZM );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsCurvePolygon * >( c6.geometryN( 3 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 177, 187, 0, 9 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 183, 183, 0, 11 ) );
|
|
QCOMPARE( static_cast< const QgsCircularString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 177, 187, 0, 9 ) );
|
|
|
|
//clear
|
|
QgsMultiSurface c7;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 6, 61, 3, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 5, 71, 4, 6 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c7.addGeometry( part.clone() );
|
|
c7.addGeometry( part.clone() );
|
|
QCOMPARE( c7.numGeometries(), 2 );
|
|
c7.clear();
|
|
QVERIFY( c7.isEmpty() );
|
|
QCOMPARE( c7.numGeometries(), 0 );
|
|
QCOMPARE( c7.nCoordinates(), 0 );
|
|
QCOMPARE( c7.ringCount(), 0 );
|
|
QCOMPARE( c7.partCount(), 0 );
|
|
QVERIFY( !c7.is3D() );
|
|
QVERIFY( !c7.isMeasure() );
|
|
QCOMPARE( c7.wkbType(), QgsWkbTypes::MultiSurface );
|
|
|
|
//clone
|
|
QgsMultiSurface c11;
|
|
std::unique_ptr< QgsMultiSurface >cloned( c11.clone() );
|
|
QVERIFY( cloned->isEmpty() );
|
|
c11.addGeometry( part.clone() );
|
|
c11.addGeometry( part.clone() );
|
|
cloned.reset( c11.clone() );
|
|
QCOMPARE( cloned->numGeometries(), 2 );
|
|
ls = static_cast< const QgsCurvePolygon * >( cloned->geometryN( 0 ) );
|
|
QCOMPARE( *ls, part );
|
|
ls = static_cast< const QgsCurvePolygon * >( cloned->geometryN( 1 ) );
|
|
QCOMPARE( *ls, part );
|
|
|
|
//copy constructor
|
|
QgsMultiSurface c12;
|
|
QgsMultiSurface c13( c12 );
|
|
QVERIFY( c13.isEmpty() );
|
|
c12.addGeometry( part.clone() );
|
|
c12.addGeometry( part.clone() );
|
|
QgsMultiSurface c14( c12 );
|
|
QCOMPARE( c14.numGeometries(), 2 );
|
|
QCOMPARE( c14.wkbType(), QgsWkbTypes::MultiSurfaceZM );
|
|
ls = static_cast< const QgsCurvePolygon * >( c14.geometryN( 0 ) );
|
|
QCOMPARE( *ls, part );
|
|
ls = static_cast< const QgsCurvePolygon * >( c14.geometryN( 1 ) );
|
|
QCOMPARE( *ls, part );
|
|
|
|
//assignment operator
|
|
QgsMultiSurface c15;
|
|
c15 = c13;
|
|
QCOMPARE( c15.numGeometries(), 0 );
|
|
c15 = c14;
|
|
QCOMPARE( c15.numGeometries(), 2 );
|
|
ls = static_cast< const QgsCurvePolygon * >( c15.geometryN( 0 ) );
|
|
QCOMPARE( *ls, part );
|
|
ls = static_cast< const QgsCurvePolygon * >( c15.geometryN( 1 ) );
|
|
QCOMPARE( *ls, part );
|
|
|
|
//toCurveType
|
|
std::unique_ptr< QgsMultiSurface > curveType( c12.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::MultiSurfaceZM );
|
|
QCOMPARE( curveType->numGeometries(), 2 );
|
|
const QgsCurvePolygon *curve = static_cast< const QgsCurvePolygon * >( curveType->geometryN( 0 ) );
|
|
QCOMPARE( *curve, *static_cast< const QgsCurvePolygon * >( c12.geometryN( 0 ) ) );
|
|
curve = static_cast< const QgsCurvePolygon * >( curveType->geometryN( 1 ) );
|
|
QCOMPARE( *curve, *static_cast< const QgsCurvePolygon * >( c12.geometryN( 1 ) ) );
|
|
|
|
//to/fromWKB
|
|
QgsMultiSurface c16;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 ) << QgsPoint( QgsWkbTypes::Point, 7, 17 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27, 37 ) << QgsPoint( QgsWkbTypes::Point, 43, 43 ) << QgsPoint( QgsWkbTypes::Point, 27, 37 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
QByteArray wkb16 = c16.asWkb();
|
|
QgsMultiSurface c17;
|
|
QgsConstWkbPtr wkb16ptr( wkb16 );
|
|
c17.fromWkb( wkb16ptr );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsCurvePolygon * >( c17.geometryN( 0 ) ), *static_cast< const QgsCurvePolygon * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsCurvePolygon * >( c17.geometryN( 1 ) ), *static_cast< const QgsCurvePolygon * >( c16.geometryN( 1 ) ) );
|
|
|
|
//parts with Z
|
|
c16.clear();
|
|
c17.clear();
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 7, 17, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 3, 13, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 7, 17, 1 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 27, 37, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 43, 43, 5 ) << QgsPoint( QgsWkbTypes::PointZ, 27, 37, 2 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr2( wkb16 );
|
|
c17.fromWkb( wkb16ptr2 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiSurfaceZ );
|
|
QCOMPARE( *static_cast< const QgsCurvePolygon * >( c17.geometryN( 0 ) ), *static_cast< const QgsCurvePolygon * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsCurvePolygon * >( c17.geometryN( 1 ) ), *static_cast< const QgsCurvePolygon * >( c16.geometryN( 1 ) ) );
|
|
|
|
//parts with m
|
|
c16.clear();
|
|
c17.clear();
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 7, 17, 0, 1 ) << QgsPoint( QgsWkbTypes::PointM, 3, 13, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 7, 17, 0, 1 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 27, 37, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 43, 43, 0, 5 ) << QgsPoint( QgsWkbTypes::PointM, 27, 37, 0, 2 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr3( wkb16 );
|
|
c17.fromWkb( wkb16ptr3 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiSurfaceM );
|
|
QCOMPARE( *static_cast< const QgsCurvePolygon * >( c17.geometryN( 0 ) ), *static_cast< const QgsCurvePolygon * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsCurvePolygon * >( c17.geometryN( 1 ) ), *static_cast< const QgsCurvePolygon * >( c16.geometryN( 1 ) ) );
|
|
|
|
// parts with ZM
|
|
c16.clear();
|
|
c17.clear();
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 13, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 43, 43, 11, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr4( wkb16 );
|
|
c17.fromWkb( wkb16ptr4 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiSurfaceZM );
|
|
QCOMPARE( *static_cast< const QgsCurvePolygon * >( c17.geometryN( 0 ) ), *static_cast< const QgsCurvePolygon * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsCurvePolygon * >( c17.geometryN( 1 ) ), *static_cast< const QgsCurvePolygon * >( c16.geometryN( 1 ) ) );
|
|
|
|
//bad WKB - check for no crash
|
|
c17.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !c17.fromWkb( nullPtr ) );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiSurface );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkbPoint = point.asWkb();
|
|
QgsConstWkbPtr wkbPointPtr( wkbPoint );
|
|
QVERIFY( !c17.fromWkb( wkbPointPtr ) );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiSurface );
|
|
|
|
//to/from WKT
|
|
QgsMultiSurface c18;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 13, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 7, 11, 2, 8 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c18.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 43, 43, 11, 5 ) << QgsPoint( QgsWkbTypes::PointZM, 27, 53, 21, 52 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c18.addGeometry( part.clone() );
|
|
|
|
QString wkt = c18.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsMultiSurface c19;
|
|
QVERIFY( c19.fromWkt( wkt ) );
|
|
QCOMPARE( c19.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsCurvePolygon * >( c19.geometryN( 0 ) ), *static_cast< const QgsCurvePolygon * >( c18.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsCurvePolygon * >( c19.geometryN( 1 ) ), *static_cast< const QgsCurvePolygon * >( c18.geometryN( 1 ) ) );
|
|
|
|
//bad WKT
|
|
QgsMultiSurface c20;
|
|
QVERIFY( !c20.fromWkt( "Point()" ) );
|
|
QVERIFY( c20.isEmpty() );
|
|
QCOMPARE( c20.numGeometries(), 0 );
|
|
QCOMPARE( c20.wkbType(), QgsWkbTypes::MultiSurface );
|
|
|
|
//as JSON
|
|
QgsMultiSurface exportC;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 ) << QgsPoint( QgsWkbTypes::Point, 7, 17 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
exportC.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27, 37 ) << QgsPoint( QgsWkbTypes::Point, 43, 43 ) << QgsPoint( QgsWkbTypes::Point, 27, 37 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
exportC.addGeometry( part.clone() );
|
|
|
|
// GML document for compare
|
|
QDomDocument doc( "gml" );
|
|
|
|
// as GML2
|
|
QString expectedSimpleGML2( QStringLiteral( "<MultiPolygon xmlns=\"gml\"><polygonMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">7,17 7,17</coordinates></LinearRing></outerBoundaryIs></Polygon></polygonMember><polygonMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">27,37 27,37</coordinates></LinearRing></outerBoundaryIs></Polygon></polygonMember></MultiPolygon>" ) );
|
|
QString res = elemToString( exportC.asGML2( doc, 1 ) );
|
|
QGSCOMPAREGML( res, expectedSimpleGML2 );
|
|
|
|
//as GML3
|
|
QString expectedSimpleGML3( QStringLiteral( "<MultiSurface xmlns=\"gml\"><surfaceMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">7 17 3 13 7 17</posList></ArcString></segments></Curve></exterior></Polygon></surfaceMember><surfaceMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">27 37 43 43 27 37</posList></ArcString></segments></Curve></exterior></Polygon></surfaceMember></MultiSurface>" ) );
|
|
res = elemToString( exportC.asGML3( doc ) );
|
|
QCOMPARE( res, expectedSimpleGML3 );
|
|
|
|
// as JSON
|
|
QString expectedSimpleJson( "{\"type\": \"MultiPolygon\", \"coordinates\": [[[ [7, 17], [7, 17]]], [[ [27, 37], [27, 37]]]] }" );
|
|
res = exportC.asJSON( 1 );
|
|
QCOMPARE( res, expectedSimpleJson );
|
|
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 17, 27 ) << QgsPoint( QgsWkbTypes::Point, 18, 28 ) << QgsPoint( QgsWkbTypes::Point, 17, 27 ) ) ;
|
|
part.addInteriorRing( ring.clone() );
|
|
exportC.addGeometry( part.clone() );
|
|
|
|
QString expectedJsonWithRings( "{\"type\": \"MultiPolygon\", \"coordinates\": [[[ [7, 17], [7, 17]]], [[ [27, 37], [27, 37]]], [[ [27, 37], [27, 37]], [ [17, 27], [17, 27]]]] }" );
|
|
res = exportC.asJSON( 1 );
|
|
QCOMPARE( res, expectedJsonWithRings );
|
|
|
|
QgsMultiSurface exportFloat;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7 / 3.0, 17 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 3 / 5.0, 13 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 7 / 3.0, 17 / 3.0 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
exportFloat.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27 / 3.0, 37 / 9.0 ) << QgsPoint( QgsWkbTypes::Point, 43 / 41.0, 43 / 42.0 ) << QgsPoint( QgsWkbTypes::Point, 27 / 3.0, 37 / 9.0 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
exportFloat.addGeometry( part.clone() );
|
|
|
|
QString expectedJsonPrec3( QStringLiteral( "{\"type\": \"MultiPolygon\", \"coordinates\": [[[ [2.333, 5.667], [2.333, 5.667]]], [[ [9, 4.111], [9, 4.111]]]] }" ) );
|
|
res = exportFloat.asJSON( 3 );
|
|
QCOMPARE( res, expectedJsonPrec3 );
|
|
|
|
// as GML2
|
|
QString expectedGML2prec3( QStringLiteral( "<MultiPolygon xmlns=\"gml\"><polygonMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">2.333,5.667 2.333,5.667</coordinates></LinearRing></outerBoundaryIs></Polygon></polygonMember><polygonMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">9,4.111 9,4.111</coordinates></LinearRing></outerBoundaryIs></Polygon></polygonMember></MultiPolygon>" ) );
|
|
res = elemToString( exportFloat.asGML2( doc, 3 ) );
|
|
QGSCOMPAREGML( res, expectedGML2prec3 );
|
|
|
|
//as GML3
|
|
QString expectedGML3prec3( QStringLiteral( "<MultiSurface xmlns=\"gml\"><surfaceMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">2.333 5.667 0.6 4.333 2.333 5.667</posList></ArcString></segments></Curve></exterior></Polygon></surfaceMember><surfaceMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">9 4.111 1.049 1.024 9 4.111</posList></ArcString></segments></Curve></exterior></Polygon></surfaceMember></MultiSurface>" ) );
|
|
res = elemToString( exportFloat.asGML3( doc, 3 ) );
|
|
QCOMPARE( res, expectedGML3prec3 );
|
|
|
|
// insert geometry
|
|
QgsMultiSurface rc;
|
|
rc.clear();
|
|
rc.insertGeometry( nullptr, 0 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
rc.insertGeometry( nullptr, -1 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
rc.insertGeometry( nullptr, 100 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
|
|
rc.insertGeometry( new QgsPoint(), 0 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
|
|
rc.insertGeometry( part.clone(), 0 );
|
|
QVERIFY( !rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 1 );
|
|
|
|
// cast
|
|
QVERIFY( !QgsMultiSurface().cast( nullptr ) );
|
|
QgsMultiSurface pCast;
|
|
QVERIFY( QgsMultiSurface().cast( &pCast ) );
|
|
QgsMultiSurface pCast2;
|
|
pCast2.fromWkt( QStringLiteral( "MultiSurfaceZ()" ) );
|
|
QVERIFY( QgsMultiSurface().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "MultiSurfaceM()" ) );
|
|
QVERIFY( QgsMultiSurface().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "MultiSurfaceZM()" ) );
|
|
QVERIFY( QgsMultiSurface().cast( &pCast2 ) );
|
|
|
|
//boundary
|
|
QgsMultiSurface multiSurface;
|
|
QVERIFY( !multiSurface.boundary() );
|
|
QgsCircularString boundaryLine1;
|
|
boundaryLine1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 0, 0 ) );
|
|
part.clear();
|
|
part.setExteriorRing( boundaryLine1.clone() );
|
|
multiSurface.addGeometry( part.clone() );
|
|
QgsAbstractGeometry *boundary = multiSurface.boundary();
|
|
QgsMultiCurve *mpBoundary = dynamic_cast< QgsMultiCurve * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->numGeometries(), 1 );
|
|
QCOMPARE( *static_cast< const QgsCurve *>( mpBoundary->geometryN( 0 ) ), *part.exteriorRing() );
|
|
delete boundary;
|
|
// add another QgsCircularString
|
|
QgsCircularString boundaryLine2;
|
|
boundaryLine2.setPoints( QList<QgsPoint>() << QgsPoint( 10, 10 ) << QgsPoint( 11, 10 ) << QgsPoint( 10, 10 ) );
|
|
QgsCurvePolygon part2;
|
|
part2.setExteriorRing( boundaryLine2.clone() );
|
|
multiSurface.addGeometry( part2.clone() );
|
|
boundary = multiSurface.boundary();
|
|
mpBoundary = dynamic_cast< QgsMultiCurve * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsCurve *>( mpBoundary->geometryN( 0 ) ), *part.exteriorRing() );
|
|
QCOMPARE( *static_cast< const QgsCurve *>( mpBoundary->geometryN( 1 ) ), *part2.exteriorRing() );
|
|
delete boundary;
|
|
|
|
//boundary with z
|
|
QgsCircularString boundaryLine4;
|
|
boundaryLine4.setPoints( QList<QgsPoint>() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 10 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 0, 15 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 10 ) );
|
|
part.clear();
|
|
part.setExteriorRing( boundaryLine4.clone() );
|
|
QgsCircularString boundaryLine5;
|
|
boundaryLine5.setPoints( QList<QgsPoint>() << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 100 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 20, 150 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 100 ) );
|
|
part2.clear();
|
|
part2.setExteriorRing( boundaryLine5.clone() );
|
|
QgsMultiSurface multiSurface2;
|
|
multiSurface2.addGeometry( part.clone() );
|
|
multiSurface2.addGeometry( part2.clone() );
|
|
|
|
boundary = multiSurface2.boundary();
|
|
mpBoundary = dynamic_cast< QgsMultiCurve * >( boundary );
|
|
QVERIFY( mpBoundary );
|
|
QCOMPARE( mpBoundary->numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsCurve *>( mpBoundary->geometryN( 0 ) ), *part.exteriorRing() );
|
|
QCOMPARE( *static_cast< const QgsCurve *>( mpBoundary->geometryN( 1 ) ), *part2.exteriorRing() );
|
|
delete boundary;
|
|
}
|
|
|
|
void TestQgsGeometry::multiPolygon()
|
|
{
|
|
//test constructor
|
|
QgsMultiPolygonV2 c1;
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiPolygon );
|
|
QCOMPARE( c1.wktTypeStr(), QString( "MultiPolygon" ) );
|
|
QCOMPARE( c1.geometryType(), QString( "MultiPolygon" ) );
|
|
QCOMPARE( c1.dimension(), 0 );
|
|
QVERIFY( !c1.hasCurvedSegments() );
|
|
QCOMPARE( c1.area(), 0.0 );
|
|
QCOMPARE( c1.perimeter(), 0.0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
QCOMPARE( c1.vertexCount( 0, 0 ), 0 );
|
|
QCOMPARE( c1.vertexCount( 0, 1 ), 0 );
|
|
QCOMPARE( c1.vertexCount( 1, 0 ), 0 );
|
|
|
|
//addGeometry
|
|
//try with nullptr
|
|
c1.addGeometry( nullptr );
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiPolygon );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
|
|
// not a surface
|
|
QVERIFY( !c1.addGeometry( new QgsPoint() ) );
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiPolygon );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
|
|
//valid geometry
|
|
QgsPolygonV2 part;
|
|
QgsLineString ring;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 1, 10 ) << QgsPoint( 2, 11 ) << QgsPoint( 2, 21 ) << QgsPoint( 1, 10 ) );
|
|
part.setExteriorRing( ring.clone() );
|
|
c1.addGeometry( part.clone() );
|
|
QVERIFY( !c1.isEmpty() );
|
|
QCOMPARE( c1.numGeometries(), 1 );
|
|
QCOMPARE( c1.nCoordinates(), 4 );
|
|
QCOMPARE( c1.ringCount(), 1 );
|
|
QCOMPARE( c1.partCount(), 1 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::MultiPolygon );
|
|
QCOMPARE( c1.wktTypeStr(), QString( "MultiPolygon" ) );
|
|
QCOMPARE( c1.geometryType(), QString( "MultiPolygon" ) );
|
|
QCOMPARE( c1.dimension(), 2 );
|
|
QVERIFY( !c1.hasCurvedSegments() );
|
|
QVERIFY( c1.geometryN( 0 ) );
|
|
QCOMPARE( *static_cast< const QgsPolygonV2 * >( c1.geometryN( 0 ) ), part );
|
|
QVERIFY( !c1.geometryN( 100 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
QCOMPARE( c1.vertexCount( 0, 0 ), 4 );
|
|
QCOMPARE( c1.vertexCount( 1, 0 ), 0 );
|
|
|
|
//initial adding of geometry should set z/m type
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 10, 11, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 20, 21, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 30, 31, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 11, 1 ) );
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
QgsMultiPolygonV2 c2;
|
|
c2.addGeometry( part.clone() );
|
|
QVERIFY( c2.is3D() );
|
|
QVERIFY( !c2.isMeasure() );
|
|
QCOMPARE( c2.wkbType(), QgsWkbTypes::MultiPolygonZ );
|
|
QCOMPARE( c2.wktTypeStr(), QString( "MultiPolygonZ" ) );
|
|
QCOMPARE( c2.geometryType(), QString( "MultiPolygon" ) );
|
|
QCOMPARE( *( static_cast< const QgsPolygonV2 * >( c2.geometryN( 0 ) ) ), part );
|
|
QgsMultiPolygonV2 c3;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 10, 11, 0, 1 ) << QgsPoint( QgsWkbTypes::PointM, 20, 21, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 30, 31, 0, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 10, 11, 0, 1 ) );
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c3.addGeometry( part.clone() );
|
|
QVERIFY( !c3.is3D() );
|
|
QVERIFY( c3.isMeasure() );
|
|
QCOMPARE( c3.wkbType(), QgsWkbTypes::MultiPolygonM );
|
|
QCOMPARE( c3.wktTypeStr(), QString( "MultiPolygonM" ) );
|
|
QCOMPARE( *( static_cast< const QgsPolygonV2 * >( c3.geometryN( 0 ) ) ), part );
|
|
QgsMultiPolygonV2 c4;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 10, 11, 2, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 20, 21, 3, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 30, 31, 3, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 11, 2, 1 ) );
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c4.addGeometry( part.clone() );
|
|
QVERIFY( c4.is3D() );
|
|
QVERIFY( c4.isMeasure() );
|
|
QCOMPARE( c4.wkbType(), QgsWkbTypes::MultiPolygonZM );
|
|
QCOMPARE( c4.wktTypeStr(), QString( "MultiPolygonZM" ) );
|
|
QCOMPARE( *( static_cast< const QgsPolygonV2 * >( c4.geometryN( 0 ) ) ), part );
|
|
|
|
//add another part
|
|
QgsMultiPolygonV2 c6;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 1, 10 ) << QgsPoint( 2, 11 ) << QgsPoint( 10, 21 ) << QgsPoint( 1, 10 ) );
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 4 );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 9, 12 ) << QgsPoint( 3, 13 ) << QgsPoint( 4, 17 ) << QgsPoint( 9, 12 ) );
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 4 );
|
|
QCOMPARE( c6.numGeometries(), 2 );
|
|
QVERIFY( c6.geometryN( 0 ) );
|
|
QCOMPARE( *static_cast< const QgsPolygonV2 * >( c6.geometryN( 1 ) ), part );
|
|
|
|
//adding subsequent points should not alter z/m type, regardless of parts type
|
|
c6.clear();
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygon );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 1, 10, 2 ) << QgsPoint( 2, 11, 3 ) << QgsPoint( 10, 13, 3 ) << QgsPoint( 1, 10, 2 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygon );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 4 );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 4 );
|
|
QCOMPARE( c6.vertexCount( 2, 0 ), 0 );
|
|
QCOMPARE( c6.vertexCount( -1, 0 ), 0 );
|
|
QCOMPARE( c6.nCoordinates(), 8 );
|
|
QCOMPARE( c6.ringCount(), 1 );
|
|
QCOMPARE( c6.partCount(), 2 );
|
|
QVERIFY( !c6.is3D() );
|
|
const QgsPolygonV2 *ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( 9, 12 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( 3, 13 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( 4, 17 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( 9, 12 ) );
|
|
ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( 1, 10 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( 2, 11 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( 10, 13 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( 1, 10 ) );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 21, 30, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 32, 41, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 42, 61, 0, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 21, 30, 0, 2 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygon );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 4 );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 4 );
|
|
QCOMPARE( c6.vertexCount( 2, 0 ), 4 );
|
|
QCOMPARE( c6.nCoordinates(), 12 );
|
|
QCOMPARE( c6.ringCount(), 1 );
|
|
QCOMPARE( c6.partCount(), 3 );
|
|
QVERIFY( !c6.is3D() );
|
|
QVERIFY( !c6.isMeasure() );
|
|
ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( 21, 30 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( 32, 41 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( 42, 61 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( 21, 30 ) );
|
|
|
|
c6.clear();
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 1, 10, 2 ) << QgsPoint( 2, 11, 3 ) << QgsPoint( 9, 15, 3 ) << QgsPoint( 1, 10, 2 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygonZ );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 2, 20 ) << QgsPoint( 3, 31 ) << QgsPoint( 7, 34 ) << QgsPoint( 2, 20 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygonZ );
|
|
QVERIFY( c6.is3D() );
|
|
ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( 1, 10, 2 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( 2, 11, 3 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( 9, 15, 3 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( 1, 10, 2 ) );
|
|
ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( 2, 20, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( 3, 31, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( 7, 34, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( 2, 20, 0 ) );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 6, 61, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 9, 65, 0, 7 ) << QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygonZ );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( !c6.isMeasure() );
|
|
ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( 5, 50, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( 6, 61, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( 9, 65, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( 5, 50, 0 ) );
|
|
|
|
c6.clear();
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygon );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 6, 61, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 9, 76, 0, 8 ) << QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygonM );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 2, 20 ) << QgsPoint( 3, 31 ) << QgsPoint( 7, 39 ) << QgsPoint( 2, 20 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygonM );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 6, 61, 0, 5 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointM, 9, 76, 0, 8 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( QgsWkbTypes::PointM, 5, 50, 0, 4 ) );
|
|
ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 2, 20, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 3, 31, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointM, 7, 39, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( QgsWkbTypes::PointM, 2, 20, 0, 0 ) );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( 11, 12, 13 ) << QgsPoint( 14, 15, 16 ) << QgsPoint( 24, 21, 5 ) << QgsPoint( 11, 12, 13 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygonM );
|
|
QVERIFY( !c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointM, 14, 15, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointM, 24, 21, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 0 ) );
|
|
|
|
c6.clear();
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 6, 61, 3, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 71, 4, 9 ) << QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygonZM );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 13, 27 ) << QgsPoint( QgsWkbTypes::Point, 7, 17 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygonZM );
|
|
QVERIFY( c6.isMeasure() );
|
|
QVERIFY( c6.is3D() );
|
|
ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 6, 61, 3, 5 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 9, 71, 4, 9 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) );
|
|
ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 7, 17, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 3, 13, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 13, 27, 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( QgsWkbTypes::PointZM, 7, 17, 0, 0 ) );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 77, 87, 7 ) << QgsPoint( QgsWkbTypes::PointZ, 83, 83, 8 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 93, 85, 10 ) << QgsPoint( QgsWkbTypes::PointZ, 77, 87, 7 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygonZM );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 2 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 77, 87, 7, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 83, 83, 8, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 93, 85, 10, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( QgsWkbTypes::PointZM, 77, 87, 7, 0 ) );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 177, 187, 0, 9 ) << QgsPoint( QgsWkbTypes::PointM, 183, 183, 0, 11 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 185, 193, 0, 13 ) << QgsPoint( QgsWkbTypes::PointM, 177, 187, 0, 9 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.wkbType(), QgsWkbTypes::MultiPolygonZM );
|
|
QVERIFY( c6.is3D() );
|
|
QVERIFY( c6.isMeasure() );
|
|
ls = static_cast< const QgsPolygonV2 * >( c6.geometryN( 3 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZM, 177, 187, 0, 9 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 1 ), QgsPoint( QgsWkbTypes::PointZM, 183, 183, 0, 11 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 2 ), QgsPoint( QgsWkbTypes::PointZM, 185, 193, 0, 13 ) );
|
|
QCOMPARE( static_cast< const QgsLineString *>( ls->exteriorRing() )->pointN( 3 ), QgsPoint( QgsWkbTypes::PointZM, 177, 187, 0, 9 ) );
|
|
|
|
//clear
|
|
QgsMultiPolygonV2 c7;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 5, 50, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 6, 61, 3, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 71, 4, 15 ) << QgsPoint( QgsWkbTypes::PointZM, 5, 71, 4, 6 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c7.addGeometry( part.clone() );
|
|
c7.addGeometry( part.clone() );
|
|
QCOMPARE( c7.numGeometries(), 2 );
|
|
c7.clear();
|
|
QVERIFY( c7.isEmpty() );
|
|
QCOMPARE( c7.numGeometries(), 0 );
|
|
QCOMPARE( c7.nCoordinates(), 0 );
|
|
QCOMPARE( c7.ringCount(), 0 );
|
|
QCOMPARE( c7.partCount(), 0 );
|
|
QVERIFY( !c7.is3D() );
|
|
QVERIFY( !c7.isMeasure() );
|
|
QCOMPARE( c7.wkbType(), QgsWkbTypes::MultiPolygon );
|
|
|
|
//clone
|
|
QgsMultiPolygonV2 c11;
|
|
std::unique_ptr< QgsMultiPolygonV2 >cloned( c11.clone() );
|
|
QVERIFY( cloned->isEmpty() );
|
|
c11.addGeometry( part.clone() );
|
|
c11.addGeometry( part.clone() );
|
|
cloned.reset( c11.clone() );
|
|
QCOMPARE( cloned->numGeometries(), 2 );
|
|
ls = static_cast< const QgsPolygonV2 * >( cloned->geometryN( 0 ) );
|
|
QCOMPARE( *ls, part );
|
|
ls = static_cast< const QgsPolygonV2 * >( cloned->geometryN( 1 ) );
|
|
QCOMPARE( *ls, part );
|
|
|
|
//copy constructor
|
|
QgsMultiPolygonV2 c12;
|
|
QgsMultiPolygonV2 c13( c12 );
|
|
QVERIFY( c13.isEmpty() );
|
|
c12.addGeometry( part.clone() );
|
|
c12.addGeometry( part.clone() );
|
|
QgsMultiPolygonV2 c14( c12 );
|
|
QCOMPARE( c14.numGeometries(), 2 );
|
|
QCOMPARE( c14.wkbType(), QgsWkbTypes::MultiPolygonZM );
|
|
ls = static_cast< const QgsPolygonV2 * >( c14.geometryN( 0 ) );
|
|
QCOMPARE( *ls, part );
|
|
ls = static_cast< const QgsPolygonV2 * >( c14.geometryN( 1 ) );
|
|
QCOMPARE( *ls, part );
|
|
|
|
//assignment operator
|
|
QgsMultiPolygonV2 c15;
|
|
c15 = c13;
|
|
QCOMPARE( c15.numGeometries(), 0 );
|
|
c15 = c14;
|
|
QCOMPARE( c15.numGeometries(), 2 );
|
|
ls = static_cast< const QgsPolygonV2 * >( c15.geometryN( 0 ) );
|
|
QCOMPARE( *ls, part );
|
|
ls = static_cast< const QgsPolygonV2 * >( c15.geometryN( 1 ) );
|
|
QCOMPARE( *ls, part );
|
|
|
|
//toCurveType
|
|
std::unique_ptr< QgsMultiSurface > curveType( c12.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::MultiSurfaceZM );
|
|
QCOMPARE( curveType->numGeometries(), 2 );
|
|
const QgsPolygonV2 *curve = static_cast< const QgsPolygonV2 * >( curveType->geometryN( 0 ) );
|
|
QCOMPARE( *curve, *static_cast< const QgsPolygonV2 * >( c12.geometryN( 0 ) ) );
|
|
curve = static_cast< const QgsPolygonV2 * >( curveType->geometryN( 1 ) );
|
|
QCOMPARE( *curve, *static_cast< const QgsPolygonV2 * >( c12.geometryN( 1 ) ) );
|
|
|
|
//to/fromWKB
|
|
QgsMultiPolygonV2 c16;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 ) << QgsPoint( QgsWkbTypes::Point, 9, 27 ) << QgsPoint( QgsWkbTypes::Point, 7, 17 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27, 37 ) << QgsPoint( QgsWkbTypes::Point, 43, 43 ) << QgsPoint( QgsWkbTypes::Point, 29, 39 ) << QgsPoint( QgsWkbTypes::Point, 27, 37 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
QByteArray wkb16 = c16.asWkb();
|
|
QgsMultiPolygonV2 c17;
|
|
QgsConstWkbPtr wkb16ptr( wkb16 );
|
|
c17.fromWkb( wkb16ptr );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsPolygonV2 * >( c17.geometryN( 0 ) ), *static_cast< const QgsPolygonV2 * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsPolygonV2 * >( c17.geometryN( 1 ) ), *static_cast< const QgsPolygonV2 * >( c16.geometryN( 1 ) ) );
|
|
|
|
//parts with Z
|
|
c16.clear();
|
|
c17.clear();
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 7, 17, 1 ) << QgsPoint( QgsWkbTypes::PointZ, 3, 13, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 9, 27, 5 ) << QgsPoint( QgsWkbTypes::PointZ, 7, 17, 1 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 27, 37, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 43, 43, 5 ) << QgsPoint( QgsWkbTypes::PointZ, 87, 54, 7 ) << QgsPoint( QgsWkbTypes::PointZ, 27, 37, 2 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr2( wkb16 );
|
|
c17.fromWkb( wkb16ptr2 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiPolygonZ );
|
|
QCOMPARE( *static_cast< const QgsPolygonV2 * >( c17.geometryN( 0 ) ), *static_cast< const QgsPolygonV2 * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsPolygonV2 * >( c17.geometryN( 1 ) ), *static_cast< const QgsPolygonV2 * >( c16.geometryN( 1 ) ) );
|
|
|
|
//parts with m
|
|
c16.clear();
|
|
c17.clear();
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 7, 17, 0, 1 ) << QgsPoint( QgsWkbTypes::PointM, 3, 13, 0, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 9, 21, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 7, 17, 0, 1 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 27, 37, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 43, 43, 0, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 37, 31, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 27, 37, 0, 2 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr3( wkb16 );
|
|
c17.fromWkb( wkb16ptr3 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiPolygonM );
|
|
QCOMPARE( *static_cast< const QgsPolygonV2 * >( c17.geometryN( 0 ) ), *static_cast< const QgsPolygonV2 * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsPolygonV2 * >( c17.geometryN( 1 ) ), *static_cast< const QgsPolygonV2 * >( c16.geometryN( 1 ) ) );
|
|
|
|
// parts with ZM
|
|
c16.clear();
|
|
c17.clear();
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 13, 1, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 19, 13, 5, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 43, 43, 11, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c16.addGeometry( part.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr4( wkb16 );
|
|
c17.fromWkb( wkb16ptr4 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiPolygonZM );
|
|
QCOMPARE( *static_cast< const QgsPolygonV2 * >( c17.geometryN( 0 ) ), *static_cast< const QgsPolygonV2 * >( c16.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsPolygonV2 * >( c17.geometryN( 1 ) ), *static_cast< const QgsPolygonV2 * >( c16.geometryN( 1 ) ) );
|
|
|
|
//bad WKB - check for no crash
|
|
c17.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !c17.fromWkb( nullPtr ) );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiPolygon );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkbPoint = point.asWkb();
|
|
QgsConstWkbPtr wkbPointPtr( wkbPoint );
|
|
QVERIFY( !c17.fromWkb( wkbPointPtr ) );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::MultiPolygon );
|
|
|
|
//to/from WKT
|
|
QgsMultiPolygonV2 c18;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 7, 17, 4, 1 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 13, 1, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 13, 19, 3, 10 ) << QgsPoint( QgsWkbTypes::PointZM, 7, 11, 2, 8 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c18.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 27, 37, 6, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 43, 43, 11, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 17, 49, 31, 53 ) << QgsPoint( QgsWkbTypes::PointZM, 27, 53, 21, 52 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
c18.addGeometry( part.clone() );
|
|
|
|
QString wkt = c18.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsMultiPolygonV2 c19;
|
|
QVERIFY( c19.fromWkt( wkt ) );
|
|
QCOMPARE( c19.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsPolygonV2 * >( c19.geometryN( 0 ) ), *static_cast< const QgsPolygonV2 * >( c18.geometryN( 0 ) ) );
|
|
QCOMPARE( *static_cast< const QgsPolygonV2 * >( c19.geometryN( 1 ) ), *static_cast< const QgsPolygonV2 * >( c18.geometryN( 1 ) ) );
|
|
|
|
//bad WKT
|
|
QgsMultiPolygonV2 c20;
|
|
QVERIFY( !c20.fromWkt( "Point()" ) );
|
|
QVERIFY( c20.isEmpty() );
|
|
QCOMPARE( c20.numGeometries(), 0 );
|
|
QCOMPARE( c20.wkbType(), QgsWkbTypes::MultiPolygon );
|
|
|
|
//as JSON
|
|
QgsMultiPolygonV2 exportC;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7, 17 ) << QgsPoint( QgsWkbTypes::Point, 3, 13 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 7, 21 ) << QgsPoint( QgsWkbTypes::Point, 7, 17 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
exportC.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27, 37 ) << QgsPoint( QgsWkbTypes::Point, 43, 43 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 41, 39 ) << QgsPoint( QgsWkbTypes::Point, 27, 37 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
exportC.addGeometry( part.clone() );
|
|
|
|
// GML document for compare
|
|
QDomDocument doc( "gml" );
|
|
|
|
// as GML2
|
|
QString expectedSimpleGML2( QStringLiteral( "<MultiPolygon xmlns=\"gml\"><polygonMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">7,17 3,13 7,21 7,17</coordinates></LinearRing></outerBoundaryIs></Polygon></polygonMember><polygonMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">27,37 43,43 41,39 27,37</coordinates></LinearRing></outerBoundaryIs></Polygon></polygonMember></MultiPolygon>" ) );
|
|
QString res = elemToString( exportC.asGML2( doc, 1 ) );
|
|
QGSCOMPAREGML( res, expectedSimpleGML2 );
|
|
|
|
//as GML3
|
|
QString expectedSimpleGML3( QStringLiteral( "<MultiPolygon xmlns=\"gml\"><polygonMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><LinearRing xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">7 17 3 13 7 21 7 17</posList></LinearRing></exterior></Polygon></polygonMember><polygonMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><LinearRing xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">27 37 43 43 41 39 27 37</posList></LinearRing></exterior></Polygon></polygonMember></MultiPolygon>" ) );
|
|
res = elemToString( exportC.asGML3( doc ) );
|
|
QCOMPARE( res, expectedSimpleGML3 );
|
|
|
|
// as JSON
|
|
QString expectedSimpleJson( "{\"type\": \"MultiPolygon\", \"coordinates\": [[[ [7, 17], [3, 13], [7, 21], [7, 17]]], [[ [27, 37], [43, 43], [41, 39], [27, 37]]]] }" );
|
|
res = exportC.asJSON( 1 );
|
|
QCOMPARE( res, expectedSimpleJson );
|
|
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 17, 27 ) << QgsPoint( QgsWkbTypes::Point, 18, 28 ) << QgsPoint( QgsWkbTypes::Point, 19, 37 ) << QgsPoint( QgsWkbTypes::Point, 17, 27 ) ) ;
|
|
part.addInteriorRing( ring.clone() );
|
|
exportC.addGeometry( part.clone() );
|
|
|
|
QString expectedJsonWithRings( "{\"type\": \"MultiPolygon\", \"coordinates\": [[[ [7, 17], [3, 13], [7, 21], [7, 17]]], [[ [27, 37], [43, 43], [41, 39], [27, 37]]], [[ [27, 37], [43, 43], [41, 39], [27, 37]], [ [17, 27], [18, 28], [19, 37], [17, 27]]]] }" );
|
|
res = exportC.asJSON( 1 );
|
|
QCOMPARE( res, expectedJsonWithRings );
|
|
|
|
QgsMultiPolygonV2 exportFloat;
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 7 / 3.0, 17 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 3 / 5.0, 13 / 3.0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 8 / 3.0, 27 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 7 / 3.0, 17 / 3.0 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
exportFloat.addGeometry( part.clone() );
|
|
ring.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 27 / 3.0, 37 / 9.0 ) << QgsPoint( QgsWkbTypes::Point, 43 / 41.0, 43 / 42.0 ) << QgsPoint( QgsWkbTypes::Point, 27 / 3.0, 37 / 9.0 ) ) ;
|
|
part.clear();
|
|
part.setExteriorRing( ring.clone() );
|
|
exportFloat.addGeometry( part.clone() );
|
|
|
|
QString expectedJsonPrec3( QStringLiteral( "{\"type\": \"MultiPolygon\", \"coordinates\": [[[ [2.333, 5.667], [0.6, 4.333], [2.667, 9], [2.333, 5.667]]], [[ [9, 4.111], [1.049, 1.024], [9, 4.111]]]] }" ) );
|
|
res = exportFloat.asJSON( 3 );
|
|
QCOMPARE( res, expectedJsonPrec3 );
|
|
|
|
// as GML2
|
|
QString expectedGML2prec3( QStringLiteral( "<MultiPolygon xmlns=\"gml\"><polygonMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">2.333,5.667 0.6,4.333 2.667,9 2.333,5.667</coordinates></LinearRing></outerBoundaryIs></Polygon></polygonMember><polygonMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><outerBoundaryIs xmlns=\"gml\"><LinearRing xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">9,4.111 1.049,1.024 9,4.111</coordinates></LinearRing></outerBoundaryIs></Polygon></polygonMember></MultiPolygon>" ) );
|
|
res = elemToString( exportFloat.asGML2( doc, 3 ) );
|
|
QGSCOMPAREGML( res, expectedGML2prec3 );
|
|
|
|
//as GML3
|
|
QString expectedGML3prec3( QStringLiteral( "<MultiPolygon xmlns=\"gml\"><polygonMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><LinearRing xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">2.333 5.667 0.6 4.333 2.667 9 2.333 5.667</posList></LinearRing></exterior></Polygon></polygonMember><polygonMember xmlns=\"gml\"><Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><LinearRing xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">9 4.111 1.049 1.024 9 4.111</posList></LinearRing></exterior></Polygon></polygonMember></MultiPolygon>" ) );
|
|
res = elemToString( exportFloat.asGML3( doc, 3 ) );
|
|
QCOMPARE( res, expectedGML3prec3 );
|
|
|
|
// insert geometry
|
|
QgsMultiPolygonV2 rc;
|
|
rc.clear();
|
|
rc.insertGeometry( nullptr, 0 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
rc.insertGeometry( nullptr, -1 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
rc.insertGeometry( nullptr, 100 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
|
|
rc.insertGeometry( new QgsPoint(), 0 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
|
|
rc.insertGeometry( part.clone(), 0 );
|
|
QVERIFY( !rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 1 );
|
|
|
|
// cast
|
|
QVERIFY( !QgsMultiPolygonV2().cast( nullptr ) );
|
|
QgsMultiPolygonV2 pCast;
|
|
QVERIFY( QgsMultiPolygonV2().cast( &pCast ) );
|
|
QgsMultiPolygonV2 pCast2;
|
|
pCast2.fromWkt( QStringLiteral( "MultiPolygonZ()" ) );
|
|
QVERIFY( QgsMultiPolygonV2().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "MultiPolygonM()" ) );
|
|
QVERIFY( QgsMultiPolygonV2().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "MultiPolygonZM()" ) );
|
|
QVERIFY( QgsMultiPolygonV2().cast( &pCast2 ) );
|
|
|
|
|
|
//boundary
|
|
QgsMultiPolygonV2 multiPolygon1;
|
|
QVERIFY( !multiPolygon1.boundary() );
|
|
|
|
QgsLineString ring1;
|
|
ring1.setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) << QgsPoint( 1, 1 ) << QgsPoint( 0, 0 ) );
|
|
QgsPolygonV2 polygon1;
|
|
polygon1.setExteriorRing( ring1.clone() );
|
|
multiPolygon1.addGeometry( polygon1.clone() );
|
|
|
|
std::unique_ptr< QgsAbstractGeometry > boundary( multiPolygon1.boundary() );
|
|
QgsMultiLineString *lineBoundary = dynamic_cast< QgsMultiLineString * >( boundary.get() );
|
|
QVERIFY( lineBoundary );
|
|
QCOMPARE( lineBoundary->numGeometries(), 1 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( lineBoundary->geometryN( 0 ) )->numPoints(), 4 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( lineBoundary->geometryN( 0 ) )->xAt( 0 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( lineBoundary->geometryN( 0 ) )->xAt( 1 ), 1.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( lineBoundary->geometryN( 0 ) )->xAt( 2 ), 1.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( lineBoundary->geometryN( 0 ) )->xAt( 3 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( lineBoundary->geometryN( 0 ) )->yAt( 0 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( lineBoundary->geometryN( 0 ) )->yAt( 1 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( lineBoundary->geometryN( 0 ) )->yAt( 2 ), 1.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( lineBoundary->geometryN( 0 ) )->yAt( 3 ), 0.0 );
|
|
|
|
// add polygon with interior rings
|
|
QgsLineString ring2;
|
|
ring2.setPoints( QList<QgsPoint>() << QgsPoint( 10, 10 ) << QgsPoint( 11, 10 ) << QgsPoint( 11, 11 ) << QgsPoint( 10, 10 ) );
|
|
QgsPolygonV2 polygon2;
|
|
polygon2.setExteriorRing( ring2.clone() );
|
|
QgsLineString boundaryRing1;
|
|
boundaryRing1.setPoints( QList<QgsPoint>() << QgsPoint( 10.1, 10.1 ) << QgsPoint( 10.2, 10.1 ) << QgsPoint( 10.2, 10.2 ) << QgsPoint( 10.1, 10.1 ) );
|
|
QgsLineString boundaryRing2;
|
|
boundaryRing2.setPoints( QList<QgsPoint>() << QgsPoint( 10.8, 10.8 ) << QgsPoint( 10.9, 10.8 ) << QgsPoint( 10.9, 10.9 ) << QgsPoint( 10.8, 10.8 ) );
|
|
polygon2.setInteriorRings( QList< QgsCurve * >() << boundaryRing1.clone() << boundaryRing2.clone() );
|
|
multiPolygon1.addGeometry( polygon2.clone() );
|
|
|
|
boundary.reset( multiPolygon1.boundary() );
|
|
QgsMultiLineString *multiLineBoundary( static_cast< QgsMultiLineString * >( boundary.get() ) );
|
|
QVERIFY( multiLineBoundary );
|
|
QCOMPARE( multiLineBoundary->numGeometries(), 4 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->numPoints(), 4 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 0 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 1 ), 1.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 2 ), 1.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->xAt( 3 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 0 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 1 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 2 ), 1.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 0 ) )->yAt( 3 ), 0.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->numPoints(), 4 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->xAt( 0 ), 10.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->xAt( 1 ), 11.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->xAt( 2 ), 11.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->xAt( 3 ), 10.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->yAt( 0 ), 10.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->yAt( 1 ), 10.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->yAt( 2 ), 11.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 1 ) )->yAt( 3 ), 10.0 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->numPoints(), 4 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->xAt( 0 ), 10.1 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->xAt( 1 ), 10.2 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->xAt( 2 ), 10.2 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->xAt( 3 ), 10.1 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->yAt( 0 ), 10.1 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->yAt( 1 ), 10.1 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->yAt( 2 ), 10.2 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 2 ) )->yAt( 3 ), 10.1 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 3 ) )->numPoints(), 4 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 3 ) )->xAt( 0 ), 10.8 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 3 ) )->xAt( 1 ), 10.9 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 3 ) )->xAt( 2 ), 10.9 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 3 ) )->xAt( 3 ), 10.8 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 3 ) )->yAt( 0 ), 10.8 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 3 ) )->yAt( 1 ), 10.8 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 3 ) )->yAt( 2 ), 10.9 );
|
|
QCOMPARE( dynamic_cast< QgsLineString * >( multiLineBoundary->geometryN( 3 ) )->yAt( 3 ), 10.8 );
|
|
}
|
|
|
|
void TestQgsGeometry::geometryCollection()
|
|
{
|
|
//test constructor
|
|
QgsGeometryCollection c1;
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QCOMPARE( c1.wktTypeStr(), QString( "GeometryCollection" ) );
|
|
QCOMPARE( c1.geometryType(), QString( "GeometryCollection" ) );
|
|
QCOMPARE( c1.dimension(), 0 );
|
|
QVERIFY( !c1.hasCurvedSegments() );
|
|
QCOMPARE( c1.area(), 0.0 );
|
|
QCOMPARE( c1.perimeter(), 0.0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
QCOMPARE( c1.vertexCount( 0, 0 ), 0 );
|
|
QCOMPARE( c1.vertexCount( 0, 1 ), 0 );
|
|
QCOMPARE( c1.vertexCount( 1, 0 ), 0 );
|
|
|
|
//addGeometry
|
|
|
|
//try with nullptr
|
|
c1.addGeometry( nullptr );
|
|
QVERIFY( c1.isEmpty() );
|
|
QCOMPARE( c1.nCoordinates(), 0 );
|
|
QCOMPARE( c1.ringCount(), 0 );
|
|
QCOMPARE( c1.partCount(), 0 );
|
|
QCOMPARE( c1.numGeometries(), 0 );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QVERIFY( !c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
|
|
//valid geometry
|
|
QgsLineString part;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
c1.addGeometry( part.clone() );
|
|
QVERIFY( !c1.isEmpty() );
|
|
QCOMPARE( c1.numGeometries(), 1 );
|
|
QCOMPARE( c1.nCoordinates(), 5 );
|
|
QCOMPARE( c1.ringCount(), 1 );
|
|
QCOMPARE( c1.partCount(), 1 );
|
|
QVERIFY( !c1.is3D() );
|
|
QVERIFY( !c1.isMeasure() );
|
|
QCOMPARE( c1.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QCOMPARE( c1.wktTypeStr(), QString( "GeometryCollection" ) );
|
|
QCOMPARE( c1.geometryType(), QString( "GeometryCollection" ) );
|
|
QCOMPARE( c1.dimension(), 1 );
|
|
QVERIFY( !c1.hasCurvedSegments() );
|
|
QCOMPARE( c1.area(), 0.0 );
|
|
QCOMPARE( c1.perimeter(), 0.0 );
|
|
QVERIFY( c1.geometryN( 0 ) );
|
|
QVERIFY( !c1.geometryN( 100 ) );
|
|
QVERIFY( !c1.geometryN( -1 ) );
|
|
QCOMPARE( c1.vertexCount( 0, 0 ), 5 );
|
|
QCOMPARE( c1.vertexCount( 1, 0 ), 0 );
|
|
|
|
//retrieve geometry and check
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( c1.geometryN( 0 ) ) ), part );
|
|
|
|
//initial adding of geometry should set z/m type
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) );
|
|
QgsGeometryCollection c2;
|
|
c2.addGeometry( part.clone() );
|
|
//QVERIFY( c2.is3D() ); //no meaning for collections?
|
|
//QVERIFY( !c2.isMeasure() ); //no meaning for collections?
|
|
QCOMPARE( c2.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QCOMPARE( c2.wktTypeStr(), QString( "GeometryCollection" ) );
|
|
QCOMPARE( c2.geometryType(), QString( "GeometryCollection" ) );
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( c2.geometryN( 0 ) ) ), part );
|
|
QgsGeometryCollection c3;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0, 10, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 10, 10, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 10, 0, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 ) );
|
|
c3.addGeometry( part.clone() );
|
|
//QVERIFY( !c3.is3D() ); //no meaning for collections?
|
|
//QVERIFY( c3.isMeasure() ); //no meaning for collections?
|
|
QCOMPARE( c3.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QCOMPARE( c3.wktTypeStr(), QString( "GeometryCollection" ) );
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( c3.geometryN( 0 ) ) ), part );
|
|
QgsGeometryCollection c4;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 2, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 3, 2 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 5, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 2, 1 ) );
|
|
c4.addGeometry( part.clone() );
|
|
//QVERIFY( c4.is3D() ); //no meaning for collections?
|
|
//QVERIFY( c4.isMeasure() ); //no meaning for collections?
|
|
QCOMPARE( c4.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QCOMPARE( c4.wktTypeStr(), QString( "GeometryCollection" ) );
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( c4.geometryN( 0 ) ) ), part );
|
|
|
|
//add another part
|
|
QgsGeometryCollection c6;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.vertexCount( 0, 0 ), 5 );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( 1, 1 ) << QgsPoint( 1, 9 ) << QgsPoint( 9, 9 )
|
|
<< QgsPoint( 9, 1 ) << QgsPoint( 1, 1 ) );
|
|
c6.addGeometry( part.clone() );
|
|
QCOMPARE( c6.vertexCount( 1, 0 ), 5 );
|
|
QCOMPARE( c6.numGeometries(), 2 );
|
|
QVERIFY( c6.geometryN( 0 ) );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c6.geometryN( 1 ) ), part );
|
|
|
|
QgsCoordinateSequence seq = c6.coordinateSequence();
|
|
QCOMPARE( seq, QgsCoordinateSequence() << ( QgsRingSequence() << ( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 10, 0 ) << QgsPoint( 0, 0 ) ) )
|
|
<< ( QgsRingSequence() << ( QgsPointSequence() << QgsPoint( 1, 1 ) << QgsPoint( 1, 9 ) << QgsPoint( 9, 9 )
|
|
<< QgsPoint( 9, 1 ) << QgsPoint( 1, 1 ) ) ) );
|
|
QCOMPARE( c6.nCoordinates(), 10 );
|
|
|
|
//clear
|
|
QgsGeometryCollection c7;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) );
|
|
c7.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1, 9, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 9, 9, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 9, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 1 ) );
|
|
c7.addGeometry( part.clone() );
|
|
QCOMPARE( c7.numGeometries(), 2 );
|
|
c7.clear();
|
|
QVERIFY( c7.isEmpty() );
|
|
QCOMPARE( c7.numGeometries(), 0 );
|
|
QCOMPARE( c7.nCoordinates(), 0 );
|
|
QCOMPARE( c7.ringCount(), 0 );
|
|
QCOMPARE( c7.partCount(), 0 );
|
|
QVERIFY( !c7.is3D() );
|
|
QVERIFY( !c7.isMeasure() );
|
|
QCOMPARE( c7.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
|
|
//clone
|
|
QgsGeometryCollection c11;
|
|
std::unique_ptr< QgsGeometryCollection >cloned( c11.clone() );
|
|
QVERIFY( cloned->isEmpty() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
c11.addGeometry( part.clone() );
|
|
QgsLineString part2;
|
|
part2.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
c11.addGeometry( part2.clone() );
|
|
cloned.reset( c11.clone() );
|
|
QCOMPARE( cloned->numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( cloned->geometryN( 0 ) ), part );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( cloned->geometryN( 1 ) ), part2 );
|
|
|
|
//copy constructor
|
|
QgsGeometryCollection c12;
|
|
QgsGeometryCollection c13( c12 );
|
|
QVERIFY( c13.isEmpty() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
c12.addGeometry( part.clone() );
|
|
part2.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
c12.addGeometry( part2.clone() );
|
|
QgsGeometryCollection c14( c12 );
|
|
QCOMPARE( c14.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c14.geometryN( 0 ) ), part );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c14.geometryN( 1 ) ), part2 );
|
|
|
|
//assignment operator
|
|
QgsGeometryCollection c15;
|
|
c15 = c13;
|
|
QCOMPARE( c15.numGeometries(), 0 );
|
|
c15 = c14;
|
|
QCOMPARE( c15.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c15.geometryN( 0 ) ), part );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c15.geometryN( 1 ) ), part2 );
|
|
|
|
//toCurveType
|
|
std::unique_ptr< QgsGeometryCollection > curveType( c12.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QCOMPARE( curveType->numGeometries(), 2 );
|
|
const QgsCompoundCurve *curve = static_cast< const QgsCompoundCurve * >( curveType->geometryN( 0 ) );
|
|
QCOMPARE( curve->numPoints(), 5 );
|
|
QCOMPARE( curve->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 ) );
|
|
QCOMPARE( curve->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) );
|
|
QCOMPARE( curve->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 ) );
|
|
QCOMPARE( curve->vertexAt( QgsVertexId( 0, 0, 3 ) ), QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) );
|
|
QCOMPARE( curve->vertexAt( QgsVertexId( 0, 0, 4 ) ), QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
curve = static_cast< const QgsCompoundCurve * >( curveType->geometryN( 1 ) );
|
|
QCOMPARE( curve->numPoints(), 5 );
|
|
QCOMPARE( curve->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 ) );
|
|
QCOMPARE( curve->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) );
|
|
QCOMPARE( curve->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 ) );
|
|
QCOMPARE( curve->vertexAt( QgsVertexId( 0, 0, 3 ) ), QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) );
|
|
QCOMPARE( curve->vertexAt( QgsVertexId( 0, 0, 4 ) ), QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
|
|
//to/fromWKB
|
|
QgsGeometryCollection c16;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 0, 0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 0, 10 ) << QgsPoint( QgsWkbTypes::Point, 10, 10 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 10, 0 ) << QgsPoint( QgsWkbTypes::Point, 0, 0 ) );
|
|
c16.addGeometry( part.clone() );
|
|
part2.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 1, 9 ) << QgsPoint( QgsWkbTypes::Point, 9, 9 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 9, 1 ) << QgsPoint( QgsWkbTypes::Point, 1, 1 ) );
|
|
c16.addGeometry( part2.clone() );
|
|
QByteArray wkb16 = c16.asWkb();
|
|
QgsGeometryCollection c17;
|
|
QgsConstWkbPtr wkb16ptr( wkb16 );
|
|
c17.fromWkb( wkb16ptr );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 0 ) ), part );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 1 ) ), part2 );
|
|
|
|
//parts with Z
|
|
c16.clear();
|
|
c17.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 0, 10, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 10, 0, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 0, 0, 1 ) );
|
|
c16.addGeometry( part.clone() );
|
|
part2.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 1, 9, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 9, 9, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointZ, 9, 1, 4 ) << QgsPoint( QgsWkbTypes::PointZ, 1, 1, 1 ) );
|
|
c16.addGeometry( part2.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr2( wkb16 );
|
|
c17.fromWkb( wkb16ptr2 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 0 ) ), part );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 1 ) ), part2 );
|
|
|
|
|
|
//parts with m
|
|
c16.clear();
|
|
c17.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 0, 10, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 10, 10, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 10, 0, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 1 ) );
|
|
c16.addGeometry( part.clone() );
|
|
part2.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 1, 0, 1 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 1, 9, 0, 2 ) << QgsPoint( QgsWkbTypes::PointM, 9, 9, 0, 3 )
|
|
<< QgsPoint( QgsWkbTypes::PointM, 9, 1, 0, 4 ) << QgsPoint( QgsWkbTypes::PointM, 1, 1, 0, 1 ) );
|
|
c16.addGeometry( part2.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr3( wkb16 );
|
|
c17.fromWkb( wkb16ptr3 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 0 ) ), part );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 1 ) ), part2 );
|
|
|
|
// parts with ZM
|
|
c16.clear();
|
|
c17.clear();
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
c16.addGeometry( part.clone() );
|
|
part2.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
c16.addGeometry( part2.clone() );
|
|
wkb16 = c16.asWkb();
|
|
QgsConstWkbPtr wkb16ptr4( wkb16 );
|
|
c17.fromWkb( wkb16ptr4 );
|
|
QCOMPARE( c17.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 0 ) ), part );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c17.geometryN( 1 ) ), part2 );
|
|
|
|
|
|
//bad WKB - check for no crash
|
|
c17.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !c17.fromWkb( nullPtr ) );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkbPoint = point.asWkb();
|
|
QgsConstWkbPtr wkbPointPtr( wkbPoint );
|
|
QVERIFY( !c17.fromWkb( wkbPointPtr ) );
|
|
QCOMPARE( c17.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
|
|
//to/from WKT
|
|
QgsGeometryCollection c18;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
c18.addGeometry( part.clone() );
|
|
part2.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
c18.addGeometry( part2.clone() );
|
|
|
|
QString wkt = c18.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsGeometryCollection c19;
|
|
QVERIFY( c19.fromWkt( wkt ) );
|
|
QCOMPARE( c19.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c19.geometryN( 0 ) ), part );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( c19.geometryN( 1 ) ), part2 );
|
|
|
|
//bad WKT
|
|
QgsGeometryCollection c20;
|
|
QVERIFY( !c20.fromWkt( "Point()" ) );
|
|
QVERIFY( c20.isEmpty() );
|
|
QCOMPARE( c20.numGeometries(), 0 );
|
|
QCOMPARE( c20.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
|
|
//as JSON
|
|
QgsGeometryCollection exportC;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 0, 0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 0, 10 ) << QgsPoint( QgsWkbTypes::Point, 10, 10 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 10, 0 ) << QgsPoint( QgsWkbTypes::Point, 0, 0 ) );
|
|
exportC.addGeometry( part.clone() );
|
|
|
|
// GML document for compare
|
|
QDomDocument doc( "gml" );
|
|
|
|
|
|
// as GML2
|
|
QString expectedSimpleGML2( QStringLiteral( "<MultiGeometry xmlns=\"gml\"><geometryMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0,0 0,10 10,10 10,0 0,0</coordinates></LineString></geometryMember></MultiGeometry>" ) );
|
|
QString res = elemToString( exportC.asGML2( doc ) );
|
|
QGSCOMPAREGML( res, expectedSimpleGML2 );
|
|
|
|
//as GML3
|
|
QString expectedSimpleGML3( QStringLiteral( "<MultiGeometry xmlns=\"gml\"><geometryMember xmlns=\"gml\"><LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">0 0 0 10 10 10 10 0 0 0</posList></LineString></geometryMember></MultiGeometry>" ) );
|
|
res = elemToString( exportC.asGML3( doc ) );
|
|
QCOMPARE( res, expectedSimpleGML3 );
|
|
|
|
// as JSON
|
|
QString expectedSimpleJson( "{\"type\": \"GeometryCollection\", \"geometries\": [{\"type\": \"LineString\", \"coordinates\": [ [0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]}] }" );
|
|
res = exportC.asJSON();
|
|
QCOMPARE( res, expectedSimpleJson );
|
|
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 1, 1 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 1, 9 ) << QgsPoint( QgsWkbTypes::Point, 9, 9 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 9, 1 ) << QgsPoint( QgsWkbTypes::Point, 1, 1 ) );
|
|
exportC.addGeometry( part.clone() );
|
|
|
|
QString expectedJson( QStringLiteral( "{\"type\": \"GeometryCollection\", \"geometries\": [{\"type\": \"LineString\", \"coordinates\": [ [0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]}, {\"type\": \"LineString\", \"coordinates\": [ [1, 1], [1, 9], [9, 9], [9, 1], [1, 1]]}] }" ) );
|
|
res = exportC.asJSON();
|
|
QCOMPARE( res, expectedJson );
|
|
|
|
QgsGeometryCollection exportFloat;
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 10 / 9.0, 10 / 9.0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 10 / 9.0, 100 / 9.0 ) << QgsPoint( QgsWkbTypes::Point, 100 / 9.0, 100 / 9.0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 100 / 9.0, 10 / 9.0 ) << QgsPoint( QgsWkbTypes::Point, 10 / 9.0, 10 / 9.0 ) );
|
|
exportFloat.addGeometry( part.clone() );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 2 / 3.0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 4 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 4 / 3.0, 4 / 3.0 )
|
|
<< QgsPoint( QgsWkbTypes::Point, 4 / 3.0, 2 / 3.0 ) << QgsPoint( QgsWkbTypes::Point, 2 / 3.0, 2 / 3.0 ) );
|
|
exportFloat.addGeometry( part.clone() );
|
|
|
|
QString expectedJsonPrec3( QStringLiteral( "{\"type\": \"GeometryCollection\", \"geometries\": [{\"type\": \"LineString\", \"coordinates\": [ [1.111, 1.111], [1.111, 11.111], [11.111, 11.111], [11.111, 1.111], [1.111, 1.111]]}, {\"type\": \"LineString\", \"coordinates\": [ [0.667, 0.667], [0.667, 1.333], [1.333, 1.333], [1.333, 0.667], [0.667, 0.667]]}] }" ) );
|
|
res = exportFloat.asJSON( 3 );
|
|
QCOMPARE( res, expectedJsonPrec3 );
|
|
|
|
// as GML2
|
|
QString expectedGML2( QStringLiteral( "<MultiGeometry xmlns=\"gml\"><geometryMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0,0 0,10 10,10 10,0 0,0</coordinates></LineString></geometryMember><geometryMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">1,1 1,9 9,9 9,1 1,1</coordinates></LineString></geometryMember></MultiGeometry>" ) );
|
|
res = elemToString( exportC.asGML2( doc ) );
|
|
QGSCOMPAREGML( res, expectedGML2 );
|
|
QString expectedGML2prec3( QStringLiteral( "<MultiGeometry xmlns=\"gml\"><geometryMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">1.111,1.111 1.111,11.111 11.111,11.111 11.111,1.111 1.111,1.111</coordinates></LineString></geometryMember><geometryMember xmlns=\"gml\"><LineString xmlns=\"gml\"><coordinates xmlns=\"gml\" cs=\",\" ts=\" \">0.667,0.667 0.667,1.333 1.333,1.333 1.333,0.667 0.667,0.667</coordinates></LineString></geometryMember></MultiGeometry>" ) );
|
|
res = elemToString( exportFloat.asGML2( doc, 3 ) );
|
|
QGSCOMPAREGML( res, expectedGML2prec3 );
|
|
|
|
//as GML3
|
|
QString expectedGML3( QStringLiteral( "<MultiGeometry xmlns=\"gml\"><geometryMember xmlns=\"gml\"><LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">0 0 0 10 10 10 10 0 0 0</posList></LineString></geometryMember><geometryMember xmlns=\"gml\"><LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">1 1 1 9 9 9 9 1 1 1</posList></LineString></geometryMember></MultiGeometry>" ) );
|
|
res = elemToString( exportC.asGML3( doc ) );
|
|
QCOMPARE( res, expectedGML3 );
|
|
QString expectedGML3prec3( QStringLiteral( "<MultiGeometry xmlns=\"gml\"><geometryMember xmlns=\"gml\"><LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">1.111 1.111 1.111 11.111 11.111 11.111 11.111 1.111 1.111 1.111</posList></LineString></geometryMember><geometryMember xmlns=\"gml\"><LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">0.667 0.667 0.667 1.333 1.333 1.333 1.333 0.667 0.667 0.667</posList></LineString></geometryMember></MultiGeometry>" ) );
|
|
res = elemToString( exportFloat.asGML3( doc, 3 ) );
|
|
QCOMPARE( res, expectedGML3prec3 );
|
|
|
|
// remove geometry
|
|
QgsGeometryCollection rc;
|
|
// no crash!
|
|
rc.removeGeometry( -1 );
|
|
rc.removeGeometry( 0 );
|
|
rc.removeGeometry( 100 );
|
|
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 9 ) );
|
|
rc.addGeometry( part.clone() );
|
|
part2.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 9, 2, 3 ) << QgsPoint( QgsWkbTypes::PointZM, 9, 9, 3, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) << QgsPoint( QgsWkbTypes::PointZM, 1, 1, 1, 7 ) );
|
|
rc.addGeometry( part2.clone() );
|
|
// no crash
|
|
rc.removeGeometry( -1 );
|
|
rc.removeGeometry( 100 );
|
|
|
|
rc.removeGeometry( 0 );
|
|
QCOMPARE( rc.numGeometries(), 1 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( rc.geometryN( 0 ) ), part2 );
|
|
|
|
rc.addGeometry( part.clone() );
|
|
rc.removeGeometry( 1 );
|
|
QCOMPARE( rc.numGeometries(), 1 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( rc.geometryN( 0 ) ), part2 );
|
|
rc.removeGeometry( 0 );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
|
|
|
|
// insert geometry
|
|
rc.clear();
|
|
rc.insertGeometry( nullptr, 0 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
rc.insertGeometry( nullptr, -1 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
rc.insertGeometry( nullptr, 100 );
|
|
QVERIFY( rc.isEmpty() );
|
|
QCOMPARE( rc.numGeometries(), 0 );
|
|
|
|
rc.insertGeometry( part.clone(), 0 );
|
|
QCOMPARE( rc.numGeometries(), 1 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( rc.geometryN( 0 ) ), part );
|
|
rc.insertGeometry( part2.clone(), 0 );
|
|
QCOMPARE( rc.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( rc.geometryN( 0 ) ), part2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( rc.geometryN( 1 ) ), part );
|
|
rc.removeGeometry( 0 );
|
|
rc.insertGeometry( part2.clone(), 1 );
|
|
QCOMPARE( rc.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( rc.geometryN( 0 ) ), part );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( rc.geometryN( 1 ) ), part2 );
|
|
rc.removeGeometry( 1 );
|
|
rc.insertGeometry( part2.clone(), 2 );
|
|
QCOMPARE( rc.numGeometries(), 2 );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( rc.geometryN( 0 ) ), part );
|
|
QCOMPARE( *static_cast< const QgsLineString * >( rc.geometryN( 1 ) ), part2 );
|
|
|
|
// cast
|
|
QVERIFY( !QgsGeometryCollection().cast( nullptr ) );
|
|
QgsGeometryCollection pCast;
|
|
QVERIFY( QgsGeometryCollection().cast( &pCast ) );
|
|
QgsGeometryCollection pCast2;
|
|
pCast2.fromWkt( QStringLiteral( "GeometryCollectionZ(PolygonZ((0 0 0, 0 1 1, 1 0 2, 0 0 0)))" ) );
|
|
QVERIFY( QgsGeometryCollection().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "GeometryCollectionM(PolygonM((0 0 1, 0 1 2, 1 0 3, 0 0 1)))" ) );
|
|
QVERIFY( QgsGeometryCollection().cast( &pCast2 ) );
|
|
pCast2.fromWkt( QStringLiteral( "GeometryCollectionZM(PolygonZM((0 0 0 1, 0 1 1 2, 1 0 2 3, 0 0 0 1)))" ) );
|
|
QVERIFY( QgsGeometryCollection().cast( &pCast2 ) );
|
|
|
|
//transform
|
|
//CRS transform
|
|
QgsCoordinateReferenceSystem sourceSrs;
|
|
sourceSrs.createFromSrid( 3994 );
|
|
QgsCoordinateReferenceSystem destSrs;
|
|
destSrs.createFromSrid( 4202 ); // want a transform with ellipsoid change
|
|
QgsCoordinateTransform tr( sourceSrs, destSrs );
|
|
|
|
// 2d CRS transform
|
|
QgsGeometryCollection pTransform;
|
|
QgsLineString l21;
|
|
l21.setPoints( QgsPointSequence() << QgsPoint( 6374985, -3626584 )
|
|
<< QgsPoint( 6274985, -3526584 )
|
|
<< QgsPoint( 6474985, -3526584 )
|
|
<< QgsPoint( 6374985, -3626584 ) );
|
|
pTransform.addGeometry( l21.clone() );
|
|
pTransform.addGeometry( l21.clone() );
|
|
pTransform.transform( tr, QgsCoordinateTransform::ForwardTransform );
|
|
const QgsLineString *extR = static_cast< const QgsLineString * >( pTransform.geometryN( 0 ) );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).x(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).x(), 176.958633, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().xMinimum(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().yMinimum(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().xMaximum(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().yMaximum(), -38.7999, 0.001 );
|
|
const QgsLineString *intR = static_cast< const QgsLineString * >( pTransform.geometryN( 1 ) );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).x(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).x(), 176.958633, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().xMinimum(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().yMinimum(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().xMaximum(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().yMaximum(), -38.7999, 0.001 );
|
|
|
|
//3d CRS transform
|
|
QgsLineString l22;
|
|
l22.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 6374985, -3626584, 1, 2 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 6274985, -3526584, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 6474985, -3526584, 5, 6 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 6374985, -3626584, 1, 2 ) );
|
|
pTransform.clear();
|
|
pTransform.addGeometry( l22.clone() );
|
|
pTransform.addGeometry( l22.clone() );
|
|
pTransform.transform( tr, QgsCoordinateTransform::ForwardTransform );
|
|
extR = static_cast< const QgsLineString * >( pTransform.geometryN( 0 ) );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).x(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).x(), 176.958633, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).z(), 5.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).m(), 6.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().xMinimum(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().yMinimum(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().xMaximum(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().yMaximum(), -38.7999, 0.001 );
|
|
intR = static_cast< const QgsLineString * >( pTransform.geometryN( 1 ) );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).x(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).x(), 176.958633, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).y(), -38.7999, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).z(), 5.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).m(), 6.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).x(), 175.771, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).y(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().xMinimum(), 174.581448, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().yMinimum(), -39.724, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().xMaximum(), 176.959, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().yMaximum(), -38.7999, 0.001 );
|
|
|
|
//reverse transform
|
|
pTransform.transform( tr, QgsCoordinateTransform::ReverseTransform );
|
|
extR = static_cast< const QgsLineString * >( pTransform.geometryN( 0 ) );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).x(), 6374984, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).y(), -3626584, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).x(), 6274984, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).y(), -3526584, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).x(), 6474984, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).y(), -3526584, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).z(), 5.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).m(), 6.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).x(), 6374984, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).y(), -3626584, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().xMinimum(), 6274984, 100 );
|
|
QGSCOMPARENEAR( extR->boundingBox().yMinimum(), -3626584, 100 );
|
|
QGSCOMPARENEAR( extR->boundingBox().xMaximum(), 6474984, 100 );
|
|
QGSCOMPARENEAR( extR->boundingBox().yMaximum(), -3526584, 100 );
|
|
intR = static_cast< const QgsLineString * >( pTransform.geometryN( 1 ) );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).x(), 6374984, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).y(), -3626584, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).x(), 6274984, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).y(), -3526584, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).x(), 6474984, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).y(), -3526584, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).z(), 5.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).m(), 6.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).x(), 6374984, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).y(), -3626584, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).z(), 1.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).m(), 2.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().xMinimum(), 6274984, 100 );
|
|
QGSCOMPARENEAR( intR->boundingBox().yMinimum(), -3626584, 100 );
|
|
QGSCOMPARENEAR( intR->boundingBox().xMaximum(), 6474984, 100 );
|
|
QGSCOMPARENEAR( intR->boundingBox().yMaximum(), -3526584, 100 );
|
|
|
|
//z value transform
|
|
pTransform.transform( tr, QgsCoordinateTransform::ForwardTransform, true );
|
|
extR = static_cast< const QgsLineString * >( pTransform.geometryN( 0 ) );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).z(), -19.249066, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).z(), -19.148357, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).z(), -19.092128, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).z(), -19.249066, 0.001 );
|
|
intR = static_cast< const QgsLineString * >( pTransform.geometryN( 1 ) );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).z(), -19.249066, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).z(), -19.148357, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).z(), -19.092128, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).z(), -19.249066, 0.001 );
|
|
pTransform.transform( tr, QgsCoordinateTransform::ReverseTransform, true );
|
|
extR = static_cast< const QgsLineString * >( pTransform.geometryN( 0 ) );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).z(), 1, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).z(), 3, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).z(), 5, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).z(), 1, 0.001 );
|
|
intR = static_cast< const QgsLineString * >( pTransform.geometryN( 1 ) );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).z(), 1, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).z(), 3, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).z(), 5, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).z(), 1, 0.001 );
|
|
|
|
//QTransform transform
|
|
QTransform qtr = QTransform::fromScale( 2, 3 );
|
|
QgsLineString l23;
|
|
l23.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 11, 12, 13, 14 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 12, 23, 24 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 1, 2, 3, 4 ) );
|
|
QgsGeometryCollection pTransform2;
|
|
pTransform2.addGeometry( l23.clone() );
|
|
pTransform2.addGeometry( l23.clone() );
|
|
pTransform2.transform( qtr );
|
|
|
|
extR = static_cast< const QgsLineString * >( pTransform2.geometryN( 0 ) );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).x(), 2, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).y(), 6, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 0 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).x(), 22, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).y(), 36, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).z(), 13.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 1 ).m(), 14.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).x(), 2, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).y(), 36, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).z(), 23.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 2 ).m(), 24.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).x(), 2, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).y(), 6, 100 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->pointN( 3 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().xMinimum(), 2, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().yMinimum(), 6, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().xMaximum(), 22, 0.001 );
|
|
QGSCOMPARENEAR( extR->boundingBox().yMaximum(), 36, 0.001 );
|
|
intR = static_cast< const QgsLineString * >( pTransform2.geometryN( 1 ) );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).x(), 2, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).y(), 6, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 0 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).x(), 22, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).y(), 36, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).z(), 13.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 1 ).m(), 14.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).x(), 2, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).y(), 36, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).z(), 23.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 2 ).m(), 24.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).x(), 2, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).y(), 6, 100 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).z(), 3.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->pointN( 3 ).m(), 4.0, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().xMinimum(), 2, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().yMinimum(), 6, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().xMaximum(), 22, 0.001 );
|
|
QGSCOMPARENEAR( intR->boundingBox().yMaximum(), 36, 0.001 );
|
|
|
|
|
|
// closestSegment
|
|
QgsPoint pt;
|
|
QgsVertexId v;
|
|
bool leftOf = false;
|
|
QgsGeometryCollection empty;
|
|
( void )empty.closestSegment( QgsPoint( 1, 2 ), pt, v ); // empty collection, just want no crash
|
|
|
|
QgsGeometryCollection p21;
|
|
QgsLineString p21ls;
|
|
p21ls.setPoints( QgsPointSequence() << QgsPoint( 5, 10 ) << QgsPoint( 7, 12 ) << QgsPoint( 5, 15 ) << QgsPoint( 5, 10 ) );
|
|
p21.addGeometry( p21ls.clone() );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 4, 11 ), pt, v, &leftOf ), 1.0, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 11, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 8, 11 ), pt, v, &leftOf ), 2.0, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 7, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 12, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 6, 11.5 ), pt, v, &leftOf ), 0.125000, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 6.25, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 11.25, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, true );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 7, 16 ), pt, v, &leftOf ), 4.923077, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5.153846, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 14.769231, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 5.5, 13.5 ), pt, v, &leftOf ), 0.173077, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5.846154, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 13.730769, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, true );
|
|
// point directly on segment
|
|
QCOMPARE( p21.closestSegment( QgsPoint( 5, 15 ), pt, v, &leftOf ), 0.0 );
|
|
QCOMPARE( pt, QgsPoint( 5, 15 ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
// with interior ring
|
|
p21ls.setPoints( QgsPointSequence() << QgsPoint( 6, 11.5 ) << QgsPoint( 6.5, 12 ) << QgsPoint( 6, 13 ) << QgsPoint( 6, 11.5 ) );
|
|
p21.addGeometry( p21ls.clone() );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 4, 11 ), pt, v, &leftOf ), 1.0, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 11, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 8, 11 ), pt, v, &leftOf ), 2.0, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 7, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 12, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 6, 11.4 ), pt, v, &leftOf ), 0.01, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 6.0, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 11.5, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 1, 0, 1 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 7, 16 ), pt, v, &leftOf ), 4.923077, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5.153846, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 14.769231, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, false );
|
|
QGSCOMPARENEAR( p21.closestSegment( QgsPoint( 5.5, 13.5 ), pt, v, &leftOf ), 0.173077, 0.0001 );
|
|
QGSCOMPARENEAR( pt.x(), 5.846154, 0.01 );
|
|
QGSCOMPARENEAR( pt.y(), 13.730769, 0.01 );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( leftOf, true );
|
|
// point directly on segment
|
|
QCOMPARE( p21.closestSegment( QgsPoint( 6, 13 ), pt, v, &leftOf ), 0.0 );
|
|
QCOMPARE( pt, QgsPoint( 6, 13 ) );
|
|
QCOMPARE( v, QgsVertexId( 1, 0, 2 ) );
|
|
|
|
//nextVertex
|
|
QgsGeometryCollection p22;
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 0, -2 );
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 0, 10 );
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
QgsLineString lp22;
|
|
lp22.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 12 ) << QgsPoint( 1, 2 ) );
|
|
p22.addGeometry( lp22.clone() );
|
|
v = QgsVertexId( 0, 0, 4 ); //out of range
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 0, -5 );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 0, 0, -1 );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 0 ) );
|
|
QCOMPARE( pt, QgsPoint( 1, 2 ) );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 1 ) );
|
|
QCOMPARE( pt, QgsPoint( 11, 12 ) );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 2 ) );
|
|
QCOMPARE( pt, QgsPoint( 1, 12 ) );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 0, 0, 3 ) );
|
|
QCOMPARE( pt, QgsPoint( 1, 2 ) );
|
|
v = QgsVertexId( 1, 0, 0 );
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 1, 0, 0 );
|
|
// add another part
|
|
lp22.setPoints( QgsPointSequence() << QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 11, 22 ) << QgsPoint( 11, 12 ) );
|
|
p22.addGeometry( lp22.clone() );
|
|
v = QgsVertexId( 1, 0, 4 ); //out of range
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 1, 0, -5 );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 1, 0, -1 );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 1, 0, 0 ) );
|
|
QCOMPARE( pt, QgsPoint( 11, 12 ) );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 1, 0, 1 ) );
|
|
QCOMPARE( pt, QgsPoint( 21, 22 ) );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 1, 0, 2 ) );
|
|
QCOMPARE( pt, QgsPoint( 11, 22 ) );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 1, 0, 3 ) );
|
|
QCOMPARE( pt, QgsPoint( 11, 12 ) );
|
|
v = QgsVertexId( 2, 0, 0 );
|
|
QVERIFY( !p22.nextVertex( v, pt ) );
|
|
v = QgsVertexId( 1, 1, 0 );
|
|
QVERIFY( p22.nextVertex( v, pt ) );
|
|
QCOMPARE( v, QgsVertexId( 1, 1, 1 ) ); //test that part number is maintained
|
|
QCOMPARE( pt, QgsPoint( 21, 22 ) );
|
|
|
|
|
|
// dropZValue
|
|
QgsGeometryCollection p23;
|
|
p23.dropZValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QgsLineString lp23;
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 12 ) << QgsPoint( 1, 2 ) );
|
|
p23.addGeometry( lp23.clone() );
|
|
p23.addGeometry( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
p23.dropZValue(); // not z
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QCOMPARE( p23.geometryN( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.geometryN( 0 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( p23.geometryN( 1 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.geometryN( 1 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
// with z
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2, 3 ) << QgsPoint( 11, 12, 13 ) << QgsPoint( 1, 12, 23 ) << QgsPoint( 1, 2, 3 ) );
|
|
p23.clear();
|
|
p23.addGeometry( lp23.clone() );
|
|
p23.addGeometry( lp23.clone() );
|
|
p23.dropZValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QCOMPARE( p23.geometryN( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.geometryN( 0 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( p23.geometryN( 1 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.geometryN( 1 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
// with zm
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2, 3, 4 ) << QgsPoint( 11, 12, 13, 14 ) << QgsPoint( 1, 12, 23, 24 ) << QgsPoint( 1, 2, 3, 4 ) );
|
|
p23.clear();
|
|
p23.addGeometry( lp23.clone() );
|
|
p23.addGeometry( lp23.clone() );
|
|
p23.dropZValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QCOMPARE( p23.geometryN( 0 )->wkbType(), QgsWkbTypes::LineStringM );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.geometryN( 0 ) )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
QCOMPARE( p23.geometryN( 1 )->wkbType(), QgsWkbTypes::LineStringM );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.geometryN( 1 ) )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 ) );
|
|
|
|
|
|
// dropMValue
|
|
p23.clear();
|
|
p23.dropMValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 1, 12 ) << QgsPoint( 1, 2 ) );
|
|
p23.addGeometry( lp23.clone() );
|
|
p23.addGeometry( lp23.clone() );
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
p23.dropMValue(); // not zm
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QCOMPARE( p23.geometryN( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.geometryN( 0 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( p23.geometryN( 1 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.geometryN( 1 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
// with m
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) << QgsPoint( QgsWkbTypes::PointM, 11, 12, 0, 13 ) << QgsPoint( QgsWkbTypes::PointM, 1, 12, 0, 23 ) << QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 3 ) );
|
|
p23.clear();
|
|
p23.addGeometry( lp23.clone() );
|
|
p23.addGeometry( lp23.clone() );
|
|
p23.dropMValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QCOMPARE( p23.geometryN( 0 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.geometryN( 0 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
QCOMPARE( p23.geometryN( 1 )->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.geometryN( 1 ) )->pointN( 0 ), QgsPoint( 1, 2 ) );
|
|
// with zm
|
|
lp23.setPoints( QgsPointSequence() << QgsPoint( 1, 2, 3, 4 ) << QgsPoint( 11, 12, 13, 14 ) << QgsPoint( 1, 12, 23, 24 ) << QgsPoint( 1, 2, 3, 4 ) );
|
|
p23.clear();
|
|
p23.addGeometry( lp23.clone() );
|
|
p23.addGeometry( lp23.clone() );
|
|
p23.dropMValue();
|
|
QCOMPARE( p23.wkbType(), QgsWkbTypes::GeometryCollection );
|
|
QCOMPARE( p23.geometryN( 0 )->wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.geometryN( 0 ) )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
QCOMPARE( p23.geometryN( 1 )->wkbType(), QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( static_cast< const QgsLineString *>( p23.geometryN( 1 ) )->pointN( 0 ), QgsPoint( QgsWkbTypes::PointZ, 1, 2, 3 ) );
|
|
|
|
//vertexAngle
|
|
QgsGeometryCollection p24;
|
|
( void )p24.vertexAngle( QgsVertexId() ); //just want no crash
|
|
( void )p24.vertexAngle( QgsVertexId( 0, 0, 0 ) ); //just want no crash
|
|
( void )p24.vertexAngle( QgsVertexId( 0, 1, 0 ) ); //just want no crash
|
|
( void )p24.vertexAngle( QgsVertexId( 1, 0, 0 ) ); //just want no crash
|
|
( void )p24.vertexAngle( QgsVertexId( -1, 0, 0 ) ); //just want no crash
|
|
QgsLineString l38;
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0.5, 0 ) << QgsPoint( 1, 0 )
|
|
<< QgsPoint( 2, 1 ) << QgsPoint( 1, 2 ) << QgsPoint( 0, 2 ) << QgsPoint( 0, 0 ) );
|
|
p24.addGeometry( l38.clone() );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 0 ) ), 2.35619, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 1 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 2 ) ), 1.17809, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 3 ) ), 0.0, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 4 ) ), 5.10509, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 5 ) ), 3.92699, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 0, 0, 6 ) ), 2.35619, 0.00001 );
|
|
p24.addGeometry( l38.clone() );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 1, 0, 0 ) ), 2.35619, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 1, 0, 1 ) ), 1.5708, 0.0001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 1, 0, 2 ) ), 1.17809, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 1, 0, 3 ) ), 0.0, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 1, 0, 4 ) ), 5.10509, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 1, 0, 5 ) ), 3.92699, 0.00001 );
|
|
QGSCOMPARENEAR( p24.vertexAngle( QgsVertexId( 1, 0, 6 ) ), 2.35619, 0.00001 );
|
|
|
|
//insert vertex
|
|
|
|
//insert vertex in empty collection
|
|
QgsGeometryCollection p25;
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 1, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 1, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( p25.isEmpty() );
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0.5, 0 ) << QgsPoint( 1, 0 )
|
|
<< QgsPoint( 2, 1 ) << QgsPoint( 1, 2 ) << QgsPoint( 0, 2 ) << QgsPoint( 0, 0 ) );
|
|
p25.addGeometry( l38.clone() );
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 0.3, 0 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 8 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 0 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 1 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 2 ), QgsPoint( 0.5, 0 ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 0, -1 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 0, 0, 100 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 1, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
// first vertex
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 0, 0.1 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 9 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 0 ), QgsPoint( 0, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 2 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 3 ), QgsPoint( 0.5, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 7 ), QgsPoint( 0, 2 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 8 ), QgsPoint( 0, 0 ) );
|
|
// last vertex
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 0, 0, 9 ), QgsPoint( 0.1, 0.1 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 10 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 0 ), QgsPoint( 0, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 2 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 3 ), QgsPoint( 0.5, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 8 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 0 ) )->pointN( 9 ), QgsPoint( 0.1, 0.1 ) );
|
|
// with second part
|
|
p25.addGeometry( l38.clone() );
|
|
QCOMPARE( p25.nCoordinates(), 17 );
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 1, 0, 1 ), QgsPoint( 0.3, 0 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 18 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 0 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 1 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 2 ), QgsPoint( 0.5, 0 ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 1, 0, -1 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 1, 0, 100 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p25.insertVertex( QgsVertexId( 2, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
// first vertex in second part
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 1, 0, 0 ), QgsPoint( 0, 0.1 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 19 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 0 ), QgsPoint( 0, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 2 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 3 ), QgsPoint( 0.5, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 7 ), QgsPoint( 0, 2 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 8 ), QgsPoint( 0, 0 ) );
|
|
// last vertex in second part
|
|
QVERIFY( p25.insertVertex( QgsVertexId( 1, 0, 9 ), QgsPoint( 0.1, 0.1 ) ) );
|
|
QCOMPARE( p25.nCoordinates(), 20 );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 0 ), QgsPoint( 0, 0.1 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 2 ), QgsPoint( 0.3, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 3 ), QgsPoint( 0.5, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 8 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p25.geometryN( 1 ) )->pointN( 9 ), QgsPoint( 0.1, 0.1 ) );
|
|
|
|
//move vertex
|
|
|
|
//empty collection
|
|
QgsGeometryCollection p26;
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( -1, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 1, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( p26.isEmpty() );
|
|
|
|
//valid collection
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 1, 2 ) );
|
|
p26.addGeometry( l38.clone() );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 0, 1 ), QgsPoint( 16.0, 17.0 ) ) );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 0, 0, 2 ), QgsPoint( 26.0, 27.0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.geometryN( 0 ) )->pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.geometryN( 0 ) )->pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.geometryN( 0 ) )->pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.geometryN( 0 ) )->pointN( 3 ), QgsPoint( 1, 2 ) );
|
|
|
|
//out of range
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 0, -1 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 0, 0, 10 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 1, 0, 0 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.geometryN( 0 ) )->pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.geometryN( 0 ) )->pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.geometryN( 0 ) )->pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.geometryN( 0 ) )->pointN( 3 ), QgsPoint( 1.0, 2.0 ) );
|
|
|
|
// with second part
|
|
p26.addGeometry( l38.clone() );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 1, 0, 0 ), QgsPoint( 6.0, 7.0 ) ) );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 1, 0, 1 ), QgsPoint( 16.0, 17.0 ) ) );
|
|
QVERIFY( p26.moveVertex( QgsVertexId( 1, 0, 2 ), QgsPoint( 26.0, 27.0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.geometryN( 1 ) )->pointN( 0 ), QgsPoint( 6.0, 7.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.geometryN( 1 ) )->pointN( 1 ), QgsPoint( 16.0, 17.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.geometryN( 1 ) )->pointN( 2 ), QgsPoint( 26.0, 27.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p26.geometryN( 1 ) )->pointN( 3 ), QgsPoint( 1.0, 2.0 ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 1, 0, -1 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 1, 0, 10 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
QVERIFY( !p26.moveVertex( QgsVertexId( 2, 0, 0 ), QgsPoint( 3.0, 4.0 ) ) );
|
|
|
|
//delete vertex
|
|
|
|
//empty collection
|
|
QgsGeometryCollection p27;
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 1, 0 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 1, 1, 0 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( -1, 1, 0 ) ) );
|
|
QVERIFY( p27.isEmpty() );
|
|
|
|
//valid collection
|
|
l38.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 5, 2 ) << QgsPoint( 6, 2 ) << QgsPoint( 7, 2 )
|
|
<< QgsPoint( 11, 12 ) << QgsPoint( 21, 22 ) << QgsPoint( 1, 2 ) );
|
|
|
|
p27.addGeometry( l38.clone() );
|
|
//out of range vertices
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 0, -1 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 0, 0, 100 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 1, 0, 1 ) ) );
|
|
|
|
//valid vertices
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 1 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 0 ), QgsPoint( 1.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 1 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 2 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 3 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 5 ), QgsPoint( 1.0, 2.0 ) );
|
|
|
|
// delete first vertex
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 0 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 1 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 2 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 3 ), QgsPoint( 21.0, 22.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 4 ), QgsPoint( 1.0, 2.0 ) );
|
|
|
|
// delete last vertex
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 4 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 0 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 1 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 2 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 0 ) )->pointN( 3 ), QgsPoint( 21.0, 22.0 ) );
|
|
|
|
// delete some more vertices - should remove part
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( !p27.geometryN( 0 ) );
|
|
|
|
// with two parts
|
|
p27.addGeometry( l38.clone() );
|
|
p27.addGeometry( l38.clone() );
|
|
|
|
//out of range vertices
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 1, 0, -1 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 1, 0, 100 ) ) );
|
|
QVERIFY( !p27.deleteVertex( QgsVertexId( 2, 0, 1 ) ) );
|
|
|
|
//valid vertices
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 1, 0, 1 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 0 ), QgsPoint( 1.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 1 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 2 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 3 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 5 ), QgsPoint( 1.0, 2.0 ) );
|
|
|
|
// delete first vertex
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 1, 0, 0 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 0 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 1 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 2 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 3 ), QgsPoint( 21.0, 22.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 4 ), QgsPoint( 1.0, 2.0 ) );
|
|
|
|
// delete last vertex
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 1, 0, 4 ) ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 0 ), QgsPoint( 6.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 1 ), QgsPoint( 7.0, 2.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 2 ), QgsPoint( 11.0, 12.0 ) );
|
|
QCOMPARE( static_cast< const QgsLineString * >( p27.geometryN( 1 ) )->pointN( 3 ), QgsPoint( 21.0, 22.0 ) );
|
|
|
|
// delete some more vertices - should remove part
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 1, 0, 1 ) ) );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 1, 0, 1 ) ) );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 1, 0, 1 ) ) );
|
|
QCOMPARE( p27.numGeometries(), 1 );
|
|
QVERIFY( p27.geometryN( 0 ) );
|
|
|
|
// test that second geometry is "promoted" when first is removed
|
|
p27.addGeometry( l38.clone() );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( p27.numGeometries(), 2 );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( p27.numGeometries(), 2 );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( p27.numGeometries(), 2 );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QVERIFY( p27.deleteVertex( QgsVertexId( 0, 0, 0 ) ) );
|
|
QCOMPARE( p27.numGeometries(), 1 );
|
|
QVERIFY( p27.geometryN( 0 ) );
|
|
|
|
//boundary
|
|
|
|
// collections have no boundary defined
|
|
QgsGeometryCollection boundaryCollection;
|
|
QVERIFY( !boundaryCollection.boundary() );
|
|
// add a geometry and retest, should still be undefined
|
|
QgsLineString *lineBoundary = new QgsLineString();
|
|
lineBoundary->setPoints( QList<QgsPoint>() << QgsPoint( 0, 0 ) << QgsPoint( 1, 0 ) );
|
|
boundaryCollection.addGeometry( lineBoundary );
|
|
QVERIFY( !boundaryCollection.boundary() );
|
|
|
|
// segmentize
|
|
QgsGeometryCollection segmentC;
|
|
QgsCircularString toSegment;
|
|
toSegment.setPoints( QgsPointSequence() << QgsPoint( 1, 2 )
|
|
<< QgsPoint( 11, 10 ) << QgsPoint( 21, 2 ) );
|
|
segmentC.addGeometry( toSegment.clone() );
|
|
std::unique_ptr<QgsGeometryCollection> segmentized( static_cast< QgsGeometryCollection * >( segmentC.segmentize() ) );
|
|
const QgsLineString *segmentizedLine = static_cast< const QgsLineString * >( segmentized->geometryN( 0 ) );
|
|
QCOMPARE( segmentizedLine->numPoints(), 156 );
|
|
QCOMPARE( segmentizedLine->vertexCount(), 156 );
|
|
QCOMPARE( segmentizedLine->ringCount(), 1 );
|
|
QCOMPARE( segmentizedLine->partCount(), 1 );
|
|
QCOMPARE( segmentizedLine->wkbType(), QgsWkbTypes::LineString );
|
|
QVERIFY( !segmentizedLine->is3D() );
|
|
QVERIFY( !segmentizedLine->isMeasure() );
|
|
QCOMPARE( segmentizedLine->pointN( 0 ), toSegment.pointN( 0 ) );
|
|
QCOMPARE( segmentizedLine->pointN( segmentizedLine->numPoints() - 1 ), toSegment.pointN( toSegment.numPoints() - 1 ) );
|
|
|
|
// hasCurvedSegments
|
|
QgsGeometryCollection c30;
|
|
QVERIFY( !c30.hasCurvedSegments() );
|
|
c30.addGeometry( part.clone() );
|
|
QVERIFY( !c30.hasCurvedSegments() );
|
|
c30.addGeometry( toSegment.clone() );
|
|
QVERIFY( c30.hasCurvedSegments() );
|
|
}
|
|
|
|
void TestQgsGeometry::triangle2()
|
|
{
|
|
//test constructor
|
|
QgsTriangle t1;
|
|
QVERIFY( t1.isEmpty() );
|
|
QCOMPARE( t1.numInteriorRings(), 0 );
|
|
QCOMPARE( t1.nCoordinates(), 0 );
|
|
QCOMPARE( t1.ringCount(), 0 );
|
|
QCOMPARE( t1.partCount(), 0 );
|
|
QVERIFY( !t1.is3D() );
|
|
QVERIFY( !t1.isMeasure() );
|
|
QCOMPARE( t1.wkbType(), QgsWkbTypes::Triangle );
|
|
QCOMPARE( t1.wktTypeStr(), QString( "Triangle" ) );
|
|
QCOMPARE( t1.geometryType(), QString( "Triangle" ) );
|
|
QCOMPARE( t1.dimension(), 2 );
|
|
QVERIFY( !t1.hasCurvedSegments() );
|
|
QCOMPARE( t1.area(), 0.0 );
|
|
QCOMPARE( t1.perimeter(), 0.0 );
|
|
QVERIFY( !t1.exteriorRing() );
|
|
QVERIFY( !t1.interiorRing( 0 ) );
|
|
|
|
// invalid triangles
|
|
QgsTriangle invalid( QgsPointXY( 0, 0 ), QgsPointXY( 0, 0 ), QgsPointXY( 10, 10 ) );
|
|
QVERIFY( invalid.isEmpty() );
|
|
invalid = QgsTriangle( QPointF( 0, 0 ), QPointF( 0, 0 ), QPointF( 10, 10 ) );
|
|
QVERIFY( invalid.isEmpty() );
|
|
//set exterior ring
|
|
|
|
//try with no ring
|
|
std::unique_ptr< QgsLineString > ext;
|
|
t1.setExteriorRing( nullptr );
|
|
QVERIFY( t1.isEmpty() );
|
|
QCOMPARE( t1.numInteriorRings(), 0 );
|
|
QCOMPARE( t1.nCoordinates(), 0 );
|
|
QCOMPARE( t1.ringCount(), 0 );
|
|
QCOMPARE( t1.partCount(), 0 );
|
|
QVERIFY( !t1.exteriorRing() );
|
|
QVERIFY( !t1.interiorRing( 0 ) );
|
|
QCOMPARE( t1.wkbType(), QgsWkbTypes::Triangle );
|
|
|
|
//valid exterior ring
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 0, 0 ) );
|
|
QVERIFY( ext->isClosed() );
|
|
t1.setExteriorRing( ext->clone() );
|
|
QVERIFY( !t1.isEmpty() );
|
|
QCOMPARE( t1.numInteriorRings(), 0 );
|
|
QCOMPARE( t1.nCoordinates(), 4 );
|
|
QCOMPARE( t1.ringCount(), 1 );
|
|
QCOMPARE( t1.partCount(), 1 );
|
|
QVERIFY( !t1.is3D() );
|
|
QVERIFY( !t1.isMeasure() );
|
|
QCOMPARE( t1.wkbType(), QgsWkbTypes::Triangle );
|
|
QCOMPARE( t1.wktTypeStr(), QString( "Triangle" ) );
|
|
QCOMPARE( t1.geometryType(), QString( "Triangle" ) );
|
|
QCOMPARE( t1.dimension(), 2 );
|
|
QVERIFY( !t1.hasCurvedSegments() );
|
|
QCOMPARE( t1.area(), 50.0 );
|
|
QGSCOMPARENEAR( t1.perimeter(), 34.1421, 0.001 );
|
|
QVERIFY( t1.exteriorRing() );
|
|
QVERIFY( !t1.interiorRing( 0 ) );
|
|
|
|
//retrieve exterior ring and check
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( t1.exteriorRing() ) ), *ext );
|
|
|
|
//set new ExteriorRing
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 10 ) << QgsPoint( 5, 5 ) << QgsPoint( 10, 10 )
|
|
<< QgsPoint( 0, 10 ) );
|
|
QVERIFY( ext->isClosed() );
|
|
t1.setExteriorRing( ext->clone() );
|
|
QVERIFY( !t1.isEmpty() );
|
|
QCOMPARE( t1.numInteriorRings(), 0 );
|
|
QCOMPARE( t1.nCoordinates(), 4 );
|
|
QCOMPARE( t1.ringCount(), 1 );
|
|
QCOMPARE( t1.partCount(), 1 );
|
|
QVERIFY( !t1.is3D() );
|
|
QVERIFY( !t1.isMeasure() );
|
|
QCOMPARE( t1.wkbType(), QgsWkbTypes::Triangle );
|
|
QCOMPARE( t1.wktTypeStr(), QString( "Triangle" ) );
|
|
QCOMPARE( t1.geometryType(), QString( "Triangle" ) );
|
|
QCOMPARE( t1.dimension(), 2 );
|
|
QVERIFY( !t1.hasCurvedSegments() );
|
|
QCOMPARE( t1.area(), 25.0 );
|
|
QGSCOMPARENEAR( t1.perimeter(), 24.1421, 0.001 );
|
|
QVERIFY( t1.exteriorRing() );
|
|
QVERIFY( !t1.interiorRing( 0 ) );
|
|
QCOMPARE( *( static_cast< const QgsLineString * >( t1.exteriorRing() ) ), *ext );
|
|
|
|
//test that a non closed exterior ring will be automatically closed
|
|
QgsTriangle t2;
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 ) );
|
|
QVERIFY( !ext->isClosed() );
|
|
t2.setExteriorRing( ext.release() );
|
|
QVERIFY( !t2.isEmpty() );
|
|
QVERIFY( t2.exteriorRing()->isClosed() );
|
|
QCOMPARE( t2.nCoordinates(), 4 );
|
|
|
|
// invalid number of points
|
|
ext.reset( new QgsLineString() );
|
|
t2.clear();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) );
|
|
t2.setExteriorRing( ext.release() );
|
|
QVERIFY( t2.isEmpty() );
|
|
|
|
ext.reset( new QgsLineString() );
|
|
t2.clear();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 ) << QgsPoint( 5, 10 ) << QgsPoint( 8, 10 ) );
|
|
t2.setExteriorRing( ext.release() );
|
|
QVERIFY( t2.isEmpty() );
|
|
|
|
// invalid exterior ring
|
|
ext.reset( new QgsLineString() );
|
|
t2.clear();
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 ) << QgsPoint( 5, 10 ) );
|
|
t2.setExteriorRing( ext.release() );
|
|
QVERIFY( t2.isEmpty() );
|
|
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 0, 0 ) );
|
|
t2.setExteriorRing( ext.release() );
|
|
QVERIFY( t2.isEmpty() );
|
|
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 0, 0 ) );
|
|
t2.setExteriorRing( ext.release() );
|
|
QVERIFY( t2.isEmpty() );
|
|
|
|
// circular ring
|
|
QgsCircularString *circularRing = new QgsCircularString();
|
|
t2.clear();
|
|
circularRing->setPoints( QgsPointSequence() << QgsPoint( 0, 0 ) << QgsPoint( 0, 10 ) << QgsPoint( 10, 10 ) );
|
|
QVERIFY( circularRing->hasCurvedSegments() );
|
|
t2.setExteriorRing( circularRing );
|
|
QVERIFY( t2.isEmpty() );
|
|
|
|
//constructor with 3 points
|
|
// double points
|
|
QgsTriangle t3( QgsPoint( 0, 0 ), QgsPoint( 0, 0 ), QgsPoint( 10, 10 ) );
|
|
QVERIFY( t3.isEmpty() );
|
|
QCOMPARE( t3.numInteriorRings(), 0 );
|
|
QCOMPARE( t3.nCoordinates(), 0 );
|
|
QCOMPARE( t3.ringCount(), 0 );
|
|
QCOMPARE( t3.partCount(), 0 );
|
|
QVERIFY( !t3.is3D() );
|
|
QVERIFY( !t3.isMeasure() );
|
|
QCOMPARE( t3.wkbType(), QgsWkbTypes::Triangle );
|
|
QCOMPARE( t3.wktTypeStr(), QString( "Triangle" ) );
|
|
QCOMPARE( t3.geometryType(), QString( "Triangle" ) );
|
|
QCOMPARE( t3.dimension(), 2 );
|
|
QVERIFY( !t3.hasCurvedSegments() );
|
|
QCOMPARE( t3.area(), 0.0 );
|
|
QCOMPARE( t3.perimeter(), 0.0 );
|
|
QVERIFY( !t3.exteriorRing() );
|
|
QVERIFY( !t3.interiorRing( 0 ) );
|
|
|
|
// colinear
|
|
t3 = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 0, 10 ) );
|
|
QVERIFY( t3.isEmpty() );
|
|
QCOMPARE( t3.numInteriorRings(), 0 );
|
|
QCOMPARE( t3.nCoordinates(), 0 );
|
|
QCOMPARE( t3.ringCount(), 0 );
|
|
QCOMPARE( t3.partCount(), 0 );
|
|
QVERIFY( !t3.is3D() );
|
|
QVERIFY( !t3.isMeasure() );
|
|
QCOMPARE( t3.wkbType(), QgsWkbTypes::Triangle );
|
|
QCOMPARE( t3.wktTypeStr(), QString( "Triangle" ) );
|
|
QCOMPARE( t3.geometryType(), QString( "Triangle" ) );
|
|
QCOMPARE( t3.dimension(), 2 );
|
|
QVERIFY( !t3.hasCurvedSegments() );
|
|
QCOMPARE( t3.area(), 0.0 );
|
|
QCOMPARE( t3.perimeter(), 0.0 );
|
|
QVERIFY( !t3.exteriorRing() );
|
|
QVERIFY( !t3.interiorRing( 0 ) );
|
|
|
|
t3 = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 10 ), QgsPoint( 10, 10 ) );
|
|
QVERIFY( !t3.isEmpty() );
|
|
QCOMPARE( t3.numInteriorRings(), 0 );
|
|
QCOMPARE( t3.nCoordinates(), 4 );
|
|
QCOMPARE( t3.ringCount(), 1 );
|
|
QCOMPARE( t3.partCount(), 1 );
|
|
QVERIFY( !t3.is3D() );
|
|
QVERIFY( !t3.isMeasure() );
|
|
QCOMPARE( t3.wkbType(), QgsWkbTypes::Triangle );
|
|
QCOMPARE( t3.wktTypeStr(), QString( "Triangle" ) );
|
|
QCOMPARE( t3.geometryType(), QString( "Triangle" ) );
|
|
QCOMPARE( t3.dimension(), 2 );
|
|
QVERIFY( !t3.hasCurvedSegments() );
|
|
QCOMPARE( t3.area(), 50.0 );
|
|
QGSCOMPARENEAR( t3.perimeter(), 34.1421, 0.001 );
|
|
QVERIFY( t3.exteriorRing() );
|
|
QVERIFY( !t3.interiorRing( 0 ) );
|
|
|
|
// equality
|
|
QVERIFY( QgsTriangle() == QgsTriangle() ); // empty
|
|
QVERIFY( QgsTriangle() == QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 0, 10 ) ) ); // empty
|
|
QVERIFY( QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 0, 10 ) ) == QgsTriangle() ); // empty
|
|
QVERIFY( QgsTriangle() != QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 5, 5 ), QgsPoint( 0, 10 ) ) );
|
|
QVERIFY( QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 5, 5 ), QgsPoint( 0, 10 ) ) != QgsTriangle() );
|
|
QVERIFY( QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 5, 5 ), QgsPoint( 0, 10 ) ) != QgsTriangle( QgsPoint( 0, 10 ), QgsPoint( 5, 5 ), QgsPoint( 0, 0 ) ) );
|
|
|
|
// clone
|
|
QgsTriangle *t4 = t3.clone();
|
|
QCOMPARE( t3, *t4 );
|
|
delete t4;
|
|
|
|
// constructor from QgsPointXY and QPointF
|
|
QgsTriangle t_qgspoint = QgsTriangle( QgsPointXY( 0, 0 ), QgsPointXY( 0, 10 ), QgsPointXY( 10, 10 ) );
|
|
QVERIFY( t3 == t_qgspoint );
|
|
QgsTriangle t_pointf = QgsTriangle( QPointF( 0, 0 ), QPointF( 0, 10 ), QPointF( 10, 10 ) );
|
|
QVERIFY( t3 == t_pointf );
|
|
|
|
// fromWkt
|
|
QgsTriangle t5;
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 ) );
|
|
t5.setExteriorRing( ext.release() );
|
|
QString wkt = t5.asWkt();
|
|
QVERIFY( !wkt.isEmpty() );
|
|
QgsTriangle t6;
|
|
QVERIFY( t6.fromWkt( wkt ) );
|
|
QCOMPARE( t5, t6 );
|
|
|
|
// conversion
|
|
QgsPolygonV2 p1;
|
|
ext.reset( new QgsLineString() );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 1, 5 )
|
|
<< QgsPoint( QgsWkbTypes::PointZM, 0, 10, 2, 6 ) << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 3, 7 ) );
|
|
p1.setExteriorRing( ext.release() );
|
|
//toPolygon
|
|
std::unique_ptr< QgsPolygonV2 > poly( t5.toPolygon() );
|
|
QCOMPARE( *poly, p1 );
|
|
//surfaceToPolygon
|
|
std::unique_ptr< QgsPolygonV2 > surface( t5.surfaceToPolygon() );
|
|
QCOMPARE( *surface, p1 );
|
|
|
|
//bad WKT
|
|
QVERIFY( !t6.fromWkt( "Point()" ) );
|
|
QVERIFY( t6.isEmpty() );
|
|
QVERIFY( !t6.exteriorRing() );
|
|
QCOMPARE( t6.numInteriorRings(), 0 );
|
|
QVERIFY( !t6.is3D() );
|
|
QVERIFY( !t6.isMeasure() );
|
|
QCOMPARE( t6.wkbType(), QgsWkbTypes::Triangle );
|
|
|
|
// WKB
|
|
QByteArray wkb = t5.asWkb();
|
|
t6.clear();
|
|
QgsConstWkbPtr wkb16ptr5( wkb );
|
|
t6.fromWkb( wkb16ptr5 );
|
|
QCOMPARE( t5.wkbType(), QgsWkbTypes::TriangleZM );
|
|
QCOMPARE( t5, t6 );
|
|
|
|
//bad WKB - check for no crash
|
|
t6.clear();
|
|
QgsConstWkbPtr nullPtr( nullptr, 0 );
|
|
QVERIFY( !t6.fromWkb( nullPtr ) );
|
|
QCOMPARE( t6.wkbType(), QgsWkbTypes::Triangle );
|
|
QgsPoint point( 1, 2 );
|
|
QByteArray wkbPoint = point.asWkb();
|
|
QgsConstWkbPtr wkbPointPtr( wkbPoint );
|
|
QVERIFY( !t6.fromWkb( wkbPointPtr ) );
|
|
QCOMPARE( t6.wkbType(), QgsWkbTypes::Triangle );
|
|
|
|
// lengths and angles
|
|
QgsTriangle t7( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) );
|
|
|
|
QVector<double> a_tested, a_t7 = t7.angles();
|
|
a_tested.append( M_PI / 4.0 );
|
|
a_tested.append( M_PI / 2.0 );
|
|
a_tested.append( M_PI / 4.0 );
|
|
QGSCOMPARENEAR( a_tested.at( 0 ), a_t7.at( 0 ), 0.0001 );
|
|
QGSCOMPARENEAR( a_tested.at( 1 ), a_t7.at( 1 ), 0.0001 );
|
|
QGSCOMPARENEAR( a_tested.at( 2 ), a_t7.at( 2 ), 0.0001 );
|
|
|
|
QVector<double> l_tested, l_t7 = t7.lengths();
|
|
l_tested.append( 5 );
|
|
l_tested.append( 5 );
|
|
l_tested.append( std::sqrt( 5 * 5 + 5 * 5 ) );
|
|
QGSCOMPARENEAR( l_tested.at( 0 ), l_t7.at( 0 ), 0.0001 );
|
|
QGSCOMPARENEAR( l_tested.at( 1 ), l_t7.at( 1 ), 0.0001 );
|
|
QGSCOMPARENEAR( l_tested.at( 2 ), l_t7.at( 2 ), 0.0001 );
|
|
|
|
// type of triangle
|
|
QVERIFY( t7.isRight() );
|
|
QVERIFY( t7.isIsocele() );
|
|
QVERIFY( !t7.isScalene() );
|
|
QVERIFY( !t7.isEquilateral() );
|
|
|
|
QgsTriangle t8( QgsPoint( 7.2825, 4.2368 ), QgsPoint( 13.0058, 3.3218 ), QgsPoint( 9.2145, 6.5242 ) );
|
|
// angles in radians 58.8978;31.1036;89.9985
|
|
// length 5.79598;4.96279;2.99413
|
|
QVERIFY( t8.isRight() );
|
|
QVERIFY( !t8.isIsocele() );
|
|
QVERIFY( t8.isScalene() );
|
|
QVERIFY( !t8.isEquilateral() );
|
|
|
|
QgsTriangle t9( QgsPoint( 10, 10 ), QgsPoint( 16, 10 ), QgsPoint( 13, 15.1962 ) );
|
|
QVERIFY( !t9.isRight() );
|
|
QVERIFY( t9.isIsocele() );
|
|
QVERIFY( !t9.isScalene() );
|
|
QVERIFY( t9.isEquilateral() );
|
|
|
|
// vertex
|
|
QCOMPARE( t9.vertexAt( -1 ), QgsPoint( 0, 0 ) );
|
|
QCOMPARE( t9.vertexAt( 0 ), QgsPoint( 10, 10 ) );
|
|
QCOMPARE( t9.vertexAt( 1 ), QgsPoint( 16, 10 ) );
|
|
QCOMPARE( t9.vertexAt( 2 ), QgsPoint( 13, 15.1962 ) );
|
|
QCOMPARE( t9.vertexAt( 3 ), QgsPoint( 10, 10 ) );
|
|
QCOMPARE( t9.vertexAt( 4 ), QgsPoint( 0, 0 ) );
|
|
|
|
// altitudes
|
|
QgsTriangle t10( QgsPoint( 20, 2 ), QgsPoint( 16, 6 ), QgsPoint( 26, 2 ) );
|
|
QVector<QgsLineString> alt = t10.altitudes();
|
|
QGSCOMPARENEARPOINT( alt.at( 0 ).pointN( 1 ), QgsPoint( 20.8276, 4.0690 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( alt.at( 1 ).pointN( 1 ), QgsPoint( 16, 2 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( alt.at( 2 ).pointN( 1 ), QgsPoint( 23, -1 ), 0.0001 );
|
|
|
|
// orthocenter
|
|
QCOMPARE( QgsPoint( 16, -8 ), t10.orthocenter() );
|
|
QCOMPARE( QgsPoint( 0, 5 ), t7.orthocenter() );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 13, 11.7321 ), t9.orthocenter(), 0.0001 );
|
|
|
|
// circumscribed circle
|
|
QCOMPARE( QgsPoint( 2.5, 2.5 ), t7.circumscribedCenter() );
|
|
QGSCOMPARENEAR( 3.5355, t7.circumscribedRadius(), 0.0001 );
|
|
QCOMPARE( QgsPoint( 23, 9 ), t10.circumscribedCenter() );
|
|
QGSCOMPARENEAR( 7.6158, t10.circumscribedRadius(), 0.0001 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 13, 11.7321 ), t9.circumscribedCenter(), 0.0001 );
|
|
QGSCOMPARENEAR( 3.4641, t9.circumscribedRadius(), 0.0001 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 13, 11.7321 ), t9.circumscribedCircle().center(), 0.0001 );
|
|
QGSCOMPARENEAR( 3.4641, t9.circumscribedCircle().radius(), 0.0001 );
|
|
|
|
// inscribed circle
|
|
QGSCOMPARENEARPOINT( QgsPoint( 1.4645, 3.5355 ), t7.inscribedCenter(), 0.001 );
|
|
QGSCOMPARENEAR( 1.4645, t7.inscribedRadius(), 0.0001 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 20.4433, 3.0701 ), t10.inscribedCenter(), 0.001 );
|
|
QGSCOMPARENEAR( 1.0701, t10.inscribedRadius(), 0.0001 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 13, 11.7321 ), t9.inscribedCenter(), 0.0001 );
|
|
QGSCOMPARENEAR( 1.7321, t9.inscribedRadius(), 0.0001 );
|
|
QGSCOMPARENEARPOINT( QgsPoint( 13, 11.7321 ), t9.inscribedCircle().center(), 0.0001 );
|
|
QGSCOMPARENEAR( 1.7321, t9.inscribedCircle().radius(), 0.0001 );
|
|
|
|
// medians
|
|
QVector<QgsLineString> med = t7.medians();
|
|
QCOMPARE( med.at( 0 ).pointN( 0 ), t7.vertexAt( 0 ) );
|
|
QGSCOMPARENEARPOINT( med.at( 0 ).pointN( 1 ), QgsPoint( 2.5, 5 ), 0.0001 );
|
|
QCOMPARE( med.at( 1 ).pointN( 0 ), t7.vertexAt( 1 ) );
|
|
QGSCOMPARENEARPOINT( med.at( 1 ).pointN( 1 ), QgsPoint( 2.5, 2.5 ), 0.0001 );
|
|
QCOMPARE( med.at( 2 ).pointN( 0 ), t7.vertexAt( 2 ) );
|
|
QGSCOMPARENEARPOINT( med.at( 2 ).pointN( 1 ), QgsPoint( 0, 2.5 ), 0.0001 );
|
|
med.clear();
|
|
|
|
med = t10.medians();
|
|
QCOMPARE( med.at( 0 ).pointN( 0 ), t10.vertexAt( 0 ) );
|
|
QGSCOMPARENEARPOINT( med.at( 0 ).pointN( 1 ), QgsPoint( 21, 4 ), 0.0001 );
|
|
QCOMPARE( med.at( 1 ).pointN( 0 ), t10.vertexAt( 1 ) );
|
|
QGSCOMPARENEARPOINT( med.at( 1 ).pointN( 1 ), QgsPoint( 23, 2 ), 0.0001 );
|
|
QCOMPARE( med.at( 2 ).pointN( 0 ), t10.vertexAt( 2 ) );
|
|
QGSCOMPARENEARPOINT( med.at( 2 ).pointN( 1 ), QgsPoint( 18, 4 ), 0.0001 );
|
|
med.clear();
|
|
alt.clear();
|
|
|
|
med = t9.medians();
|
|
alt = t9.altitudes();
|
|
QGSCOMPARENEARPOINT( med.at( 0 ).pointN( 0 ), alt.at( 0 ).pointN( 0 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( med.at( 0 ).pointN( 1 ), alt.at( 0 ).pointN( 1 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( med.at( 1 ).pointN( 0 ), alt.at( 1 ).pointN( 0 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( med.at( 1 ).pointN( 1 ), alt.at( 1 ).pointN( 1 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( med.at( 2 ).pointN( 0 ), alt.at( 2 ).pointN( 0 ), 0.0001 );
|
|
QGSCOMPARENEARPOINT( med.at( 2 ).pointN( 1 ), alt.at( 2 ).pointN( 1 ), 0.0001 );
|
|
|
|
// medial
|
|
QCOMPARE( t7.medial(), QgsTriangle( QgsPoint( 0, 2.5 ), QgsPoint( 2.5, 5 ), QgsPoint( 2.5, 2.5 ) ) );
|
|
QCOMPARE( t9.medial(), QgsTriangle( QgsGeometryUtils::midpoint( t9.vertexAt( 0 ), t9.vertexAt( 1 ) ),
|
|
QgsGeometryUtils::midpoint( t9.vertexAt( 1 ), t9.vertexAt( 2 ) ),
|
|
QgsGeometryUtils::midpoint( t9.vertexAt( 2 ), t9.vertexAt( 0 ) ) ) );
|
|
|
|
// bisectors
|
|
QVector<QgsLineString> bis = t7.bisectors();
|
|
QCOMPARE( bis.at( 0 ).pointN( 0 ), t7.vertexAt( 0 ) );
|
|
QGSCOMPARENEARPOINT( bis.at( 0 ).pointN( 1 ), QgsPoint( 2.0711, 5 ), 0.0001 );
|
|
QCOMPARE( bis.at( 1 ).pointN( 0 ), t7.vertexAt( 1 ) );
|
|
QGSCOMPARENEARPOINT( bis.at( 1 ).pointN( 1 ), QgsPoint( 2.5, 2.5 ), 0.0001 );
|
|
QCOMPARE( bis.at( 2 ).pointN( 0 ), t7.vertexAt( 2 ) );
|
|
QGSCOMPARENEARPOINT( bis.at( 2 ).pointN( 1 ), QgsPoint( 0, 2.9289 ), 0.0001 );
|
|
|
|
// "deleted" method
|
|
ext.reset( new QgsLineString() );
|
|
QgsTriangle t11( QgsPoint( 0, 0 ), QgsPoint( 100, 100 ), QgsPoint( 0, 200 ) );
|
|
ext->setPoints( QgsPointSequence() << QgsPoint( 5, 5 )
|
|
<< QgsPoint( 50, 50 ) << QgsPoint( 0, 25 )
|
|
<< QgsPoint( 5, 5 ) );
|
|
t11.addInteriorRing( ext.release() );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 100 100, 0 200, 0 0))" ) );
|
|
|
|
/* QList<QgsCurve *> lc;
|
|
lc.append(ext);
|
|
t11.setInteriorRings( lc );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 100 100, 0 200, 0 0))" ) );*/
|
|
|
|
QgsVertexId id( 0, 0, 1 );
|
|
QVERIFY( !t11.deleteVertex( id ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 100 100, 0 200, 0 0))" ) );
|
|
QVERIFY( !t11.insertVertex( id, QgsPoint( 5, 5 ) ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 100 100, 0 200, 0 0))" ) );
|
|
|
|
//move vertex
|
|
QgsPoint pt1( 5, 5 );
|
|
// invalid part
|
|
id.part = -1;
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
id.part = 1;
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
// invalid ring
|
|
id.part = 0;
|
|
id.ring = -1;
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
id.ring = 1;
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
id.ring = 0;
|
|
id.vertex = -1;
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
id.vertex = 5;
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
|
|
// valid vertex
|
|
id.vertex = 0;
|
|
QVERIFY( t11.moveVertex( id, pt1 ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((5 5, 100 100, 0 200, 5 5))" ) );
|
|
pt1 = QgsPoint();
|
|
QVERIFY( t11.moveVertex( id, pt1 ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 100 100, 0 200, 0 0))" ) );
|
|
id.vertex = 4;
|
|
pt1 = QgsPoint( 5, 5 );
|
|
QVERIFY( t11.moveVertex( id, pt1 ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((5 5, 100 100, 0 200, 5 5))" ) );
|
|
pt1 = QgsPoint();
|
|
QVERIFY( t11.moveVertex( id, pt1 ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 100 100, 0 200, 0 0))" ) );
|
|
id.vertex = 1;
|
|
pt1 = QgsPoint( 5, 5 );
|
|
QVERIFY( t11.moveVertex( id, pt1 ) );
|
|
QCOMPARE( t11.asWkt(), QString( "Triangle ((0 0, 5 5, 0 200, 0 0))" ) );
|
|
// colinear
|
|
pt1 = QgsPoint( 0, 100 );
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
// duplicate point
|
|
pt1 = QgsPoint( 0, 0 );
|
|
QVERIFY( !t11.moveVertex( id, pt1 ) );
|
|
|
|
//toCurveType
|
|
QgsTriangle t12( QgsPoint( 7, 4 ), QgsPoint( 13, 3 ), QgsPoint( 9, 6 ) );
|
|
std::unique_ptr< QgsCurvePolygon > curveType( t12.toCurveType() );
|
|
QCOMPARE( curveType->wkbType(), QgsWkbTypes::CurvePolygon );
|
|
QCOMPARE( curveType->exteriorRing()->numPoints(), 4 );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 7, 4 ) );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( 13, 3 ) );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( 9, 6 ) );
|
|
QCOMPARE( curveType->exteriorRing()->vertexAt( QgsVertexId( 0, 0, 3 ) ), QgsPoint( 7, 4 ) );
|
|
QCOMPARE( curveType->numInteriorRings(), 0 );
|
|
|
|
// boundary
|
|
QVERIFY( !QgsTriangle().boundary() );
|
|
std::unique_ptr< QgsCurve > boundary( QgsTriangle( QgsPoint( 7, 4 ), QgsPoint( 13, 3 ), QgsPoint( 9, 6 ) ).boundary() );
|
|
QCOMPARE( boundary->wkbType(), QgsWkbTypes::LineString );
|
|
QCOMPARE( boundary->numPoints(), 4 );
|
|
QCOMPARE( boundary->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 7, 4 ) );
|
|
QCOMPARE( boundary->vertexAt( QgsVertexId( 0, 0, 1 ) ), QgsPoint( 13, 3 ) );
|
|
QCOMPARE( boundary->vertexAt( QgsVertexId( 0, 0, 2 ) ), QgsPoint( 9, 6 ) );
|
|
QCOMPARE( boundary->vertexAt( QgsVertexId( 0, 0, 3 ) ), QgsPoint( 7, 4 ) );
|
|
|
|
// cast
|
|
QgsTriangle pCast;
|
|
QVERIFY( QgsPolygonV2().cast( &pCast ) );
|
|
QgsTriangle pCast2( QgsPoint( 7, 4 ), QgsPoint( 13, 3 ), QgsPoint( 9, 6 ) );;
|
|
QVERIFY( QgsPolygonV2().cast( &pCast2 ) );
|
|
}
|
|
|
|
void TestQgsGeometry::fromQgsPointXY()
|
|
{
|
|
QgsPointXY point( 1.0, 2.0 );
|
|
QgsGeometry result( QgsGeometry::fromPoint( point ) );
|
|
QCOMPARE( result.wkbType(), QgsWkbTypes::Point );
|
|
QgsPointXY resultPoint = result.asPoint();
|
|
QCOMPARE( resultPoint, point );
|
|
}
|
|
|
|
void TestQgsGeometry::fromQPoint()
|
|
{
|
|
QPointF point( 1.0, 2.0 );
|
|
QgsGeometry result( QgsGeometry::fromQPointF( point ) );
|
|
QCOMPARE( result.wkbType(), QgsWkbTypes::Point );
|
|
QgsPointXY resultPoint = result.asPoint();
|
|
QCOMPARE( resultPoint.x(), 1.0 );
|
|
QCOMPARE( resultPoint.y(), 2.0 );
|
|
}
|
|
|
|
void TestQgsGeometry::fromQPolygonF()
|
|
{
|
|
//test with a polyline
|
|
QPolygonF polyline;
|
|
polyline << QPointF( 1.0, 2.0 ) << QPointF( 4.0, 6.0 ) << QPointF( 4.0, 3.0 ) << QPointF( 2.0, 2.0 );
|
|
QgsGeometry result( QgsGeometry::fromQPolygonF( polyline ) );
|
|
QCOMPARE( result.wkbType(), QgsWkbTypes::LineString );
|
|
QgsPolyline resultLine = result.asPolyline();
|
|
QCOMPARE( resultLine.size(), 4 );
|
|
QCOMPARE( resultLine.at( 0 ), QgsPointXY( 1.0, 2.0 ) );
|
|
QCOMPARE( resultLine.at( 1 ), QgsPointXY( 4.0, 6.0 ) );
|
|
QCOMPARE( resultLine.at( 2 ), QgsPointXY( 4.0, 3.0 ) );
|
|
QCOMPARE( resultLine.at( 3 ), QgsPointXY( 2.0, 2.0 ) );
|
|
|
|
//test with a closed polygon
|
|
QPolygonF polygon;
|
|
polygon << QPointF( 1.0, 2.0 ) << QPointF( 4.0, 6.0 ) << QPointF( 4.0, 3.0 ) << QPointF( 2.0, 2.0 ) << QPointF( 1.0, 2.0 );
|
|
QgsGeometry result2( QgsGeometry::fromQPolygonF( polygon ) );
|
|
QCOMPARE( result2.wkbType(), QgsWkbTypes::Polygon );
|
|
QgsPolygon resultPolygon = result2.asPolygon();
|
|
QCOMPARE( resultPolygon.size(), 1 );
|
|
QCOMPARE( resultPolygon.at( 0 ).at( 0 ), QgsPointXY( 1.0, 2.0 ) );
|
|
QCOMPARE( resultPolygon.at( 0 ).at( 1 ), QgsPointXY( 4.0, 6.0 ) );
|
|
QCOMPARE( resultPolygon.at( 0 ).at( 2 ), QgsPointXY( 4.0, 3.0 ) );
|
|
QCOMPARE( resultPolygon.at( 0 ).at( 3 ), QgsPointXY( 2.0, 2.0 ) );
|
|
QCOMPARE( resultPolygon.at( 0 ).at( 4 ), QgsPointXY( 1.0, 2.0 ) );
|
|
}
|
|
|
|
void TestQgsGeometry::asQPointF()
|
|
{
|
|
QPointF point( 1.0, 2.0 );
|
|
QgsGeometry geom( QgsGeometry::fromQPointF( point ) );
|
|
QPointF resultPoint = geom.asQPointF();
|
|
QCOMPARE( resultPoint, point );
|
|
|
|
//non point geom
|
|
QPointF badPoint = mpPolygonGeometryA.asQPointF();
|
|
QVERIFY( badPoint.isNull() );
|
|
}
|
|
|
|
void TestQgsGeometry::asQPolygonF()
|
|
{
|
|
//test polygon
|
|
QPolygonF fromPoly = mpPolygonGeometryA.asQPolygonF();
|
|
QVERIFY( fromPoly.isClosed() );
|
|
QCOMPARE( fromPoly.size(), 5 );
|
|
QCOMPARE( fromPoly.at( 0 ).x(), mPoint1.x() );
|
|
QCOMPARE( fromPoly.at( 0 ).y(), mPoint1.y() );
|
|
QCOMPARE( fromPoly.at( 1 ).x(), mPoint2.x() );
|
|
QCOMPARE( fromPoly.at( 1 ).y(), mPoint2.y() );
|
|
QCOMPARE( fromPoly.at( 2 ).x(), mPoint3.x() );
|
|
QCOMPARE( fromPoly.at( 2 ).y(), mPoint3.y() );
|
|
QCOMPARE( fromPoly.at( 3 ).x(), mPoint4.x() );
|
|
QCOMPARE( fromPoly.at( 3 ).y(), mPoint4.y() );
|
|
QCOMPARE( fromPoly.at( 4 ).x(), mPoint1.x() );
|
|
QCOMPARE( fromPoly.at( 4 ).y(), mPoint1.y() );
|
|
|
|
//test polyline
|
|
QgsPolyline testline;
|
|
testline << mPoint1 << mPoint2 << mPoint3;
|
|
QgsGeometry lineGeom( QgsGeometry::fromPolyline( testline ) );
|
|
QPolygonF fromLine = lineGeom.asQPolygonF();
|
|
QVERIFY( !fromLine.isClosed() );
|
|
QCOMPARE( fromLine.size(), 3 );
|
|
QCOMPARE( fromLine.at( 0 ).x(), mPoint1.x() );
|
|
QCOMPARE( fromLine.at( 0 ).y(), mPoint1.y() );
|
|
QCOMPARE( fromLine.at( 1 ).x(), mPoint2.x() );
|
|
QCOMPARE( fromLine.at( 1 ).y(), mPoint2.y() );
|
|
QCOMPARE( fromLine.at( 2 ).x(), mPoint3.x() );
|
|
QCOMPARE( fromLine.at( 2 ).y(), mPoint3.y() );
|
|
|
|
//test a bad geometry
|
|
QgsGeometry badGeom( QgsGeometry::fromPoint( mPoint1 ) );
|
|
QPolygonF fromBad = badGeom.asQPolygonF();
|
|
QVERIFY( fromBad.isEmpty() );
|
|
}
|
|
|
|
void TestQgsGeometry::comparePolylines()
|
|
{
|
|
QgsPolyline line1;
|
|
line1 << mPoint1 << mPoint2 << mPoint3;
|
|
QgsPolyline line2;
|
|
line2 << mPoint1 << mPoint2 << mPoint3;
|
|
QVERIFY( QgsGeometry::compare( line1, line2 ) );
|
|
|
|
//different number of nodes
|
|
QgsPolyline line3;
|
|
line3 << mPoint1 << mPoint2 << mPoint3 << mPoint4;
|
|
QVERIFY( !QgsGeometry::compare( line1, line3 ) );
|
|
|
|
//different nodes
|
|
QgsPolyline line4;
|
|
line3 << mPoint1 << mPointA << mPoint3 << mPoint4;
|
|
QVERIFY( !QgsGeometry::compare( line3, line4 ) );
|
|
}
|
|
|
|
void TestQgsGeometry::comparePolygons()
|
|
{
|
|
QgsPolyline ring1;
|
|
ring1 << mPoint1 << mPoint2 << mPoint3 << mPoint1;
|
|
QgsPolyline ring2;
|
|
ring2 << mPoint4 << mPointA << mPointB << mPoint4;
|
|
QgsPolygon poly1;
|
|
poly1 << ring1 << ring2;
|
|
QgsPolygon poly2;
|
|
poly2 << ring1 << ring2;
|
|
QVERIFY( QgsGeometry::compare( poly1, poly2 ) );
|
|
|
|
//different number of rings
|
|
QgsPolygon poly3;
|
|
poly3 << ring1;
|
|
QVERIFY( !QgsGeometry::compare( poly1, poly3 ) );
|
|
|
|
//different rings
|
|
QgsPolygon poly4;
|
|
poly4 << ring2;
|
|
QVERIFY( !QgsGeometry::compare( poly3, poly4 ) );
|
|
}
|
|
|
|
|
|
|
|
// MK, Disabled 14.11.2014
|
|
// Too unclear what exactly should be tested and which variations are allowed for the line
|
|
#if 0
|
|
void TestQgsGeometry::simplifyCheck1()
|
|
{
|
|
QVERIFY( mpPolylineGeometryD->simplify( 0.5 ) );
|
|
// should be a single polygon as A intersect B
|
|
QgsGeometry *mypSimplifyGeometry = mpPolylineGeometryD->simplify( 0.5 );
|
|
qDebug( "Geometry Type: %s", QgsWkbTypes::displayString( mypSimplifyGeometry->wkbType() ) );
|
|
QVERIFY( mypSimplifyGeometry->wkbType() == QgsWkbTypes::LineString );
|
|
QgsPolyline myLine = mypSimplifyGeometry->asPolyline();
|
|
QVERIFY( myLine.size() > 0 ); //check that the union created a feature
|
|
dumpPolyline( myLine );
|
|
delete mypSimplifyGeometry;
|
|
QVERIFY( renderCheck( "geometry_simplifyCheck1", "Checking simplify of line" ) );
|
|
}
|
|
#endif
|
|
|
|
void TestQgsGeometry::intersectionCheck1()
|
|
{
|
|
QVERIFY( mpPolygonGeometryA.intersects( mpPolygonGeometryB ) );
|
|
// should be a single polygon as A intersect B
|
|
QgsGeometry mypIntersectionGeometry = mpPolygonGeometryA.intersection( mpPolygonGeometryB );
|
|
qDebug() << "Geometry Type: " << QgsWkbTypes::displayString( mypIntersectionGeometry.wkbType() );
|
|
QVERIFY( mypIntersectionGeometry.wkbType() == QgsWkbTypes::Polygon );
|
|
QgsPolygon myPolygon = mypIntersectionGeometry.asPolygon();
|
|
QVERIFY( myPolygon.size() > 0 ); //check that the union created a feature
|
|
dumpPolygon( myPolygon );
|
|
QVERIFY( renderCheck( "geometry_intersectionCheck1", "Checking if A intersects B" ) );
|
|
}
|
|
void TestQgsGeometry::intersectionCheck2()
|
|
{
|
|
QVERIFY( !mpPolygonGeometryA.intersects( mpPolygonGeometryC ) );
|
|
}
|
|
|
|
void TestQgsGeometry::translateCheck1()
|
|
{
|
|
QString wkt = QStringLiteral( "LineString (0 0, 10 0, 10 10)" );
|
|
QgsGeometry geom( QgsGeometry::fromWkt( wkt ) );
|
|
geom.translate( 10, -5 );
|
|
QString obtained = geom.exportToWkt();
|
|
QString expected = QStringLiteral( "LineString (10 -5, 20 -5, 20 5)" );
|
|
QCOMPARE( obtained, expected );
|
|
geom.translate( -10, 5 );
|
|
obtained = geom.exportToWkt();
|
|
QCOMPARE( obtained, wkt );
|
|
|
|
wkt = QStringLiteral( "Polygon ((-2 4, -2 -10, 2 3, -2 4),(1 1, -1 1, -1 -1, 1 1))" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
geom.translate( -2, 10 );
|
|
obtained = geom.exportToWkt();
|
|
expected = QStringLiteral( "Polygon ((-4 14, -4 0, 0 13, -4 14),(-1 11, -3 11, -3 9, -1 11))" );
|
|
QCOMPARE( obtained, expected );
|
|
geom.translate( 2, -10 );
|
|
obtained = geom.exportToWkt();
|
|
QCOMPARE( obtained, wkt );
|
|
|
|
wkt = QStringLiteral( "Point (40 50)" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
geom.translate( -2, 10 );
|
|
obtained = geom.exportToWkt();
|
|
expected = QStringLiteral( "Point (38 60)" );
|
|
QCOMPARE( obtained, expected );
|
|
geom.translate( 2, -10 );
|
|
obtained = geom.exportToWkt();
|
|
QCOMPARE( obtained, wkt );
|
|
|
|
}
|
|
|
|
void TestQgsGeometry::rotateCheck1()
|
|
{
|
|
QString wkt = QStringLiteral( "LineString (0 0, 10 0, 10 10)" );
|
|
QgsGeometry geom( QgsGeometry::fromWkt( wkt ) );
|
|
geom.rotate( 90, QgsPointXY( 0, 0 ) );
|
|
QString obtained = geom.exportToWkt();
|
|
QString expected = QStringLiteral( "LineString (0 0, 0 -10, 10 -10)" );
|
|
QCOMPARE( obtained, expected );
|
|
geom.rotate( -90, QgsPointXY( 0, 0 ) );
|
|
obtained = geom.exportToWkt();
|
|
QCOMPARE( obtained, wkt );
|
|
|
|
wkt = QStringLiteral( "Polygon ((-2 4, -2 -10, 2 3, -2 4),(1 1, -1 1, -1 -1, 1 1))" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
geom.rotate( 90, QgsPointXY( 0, 0 ) );
|
|
obtained = geom.exportToWkt();
|
|
expected = QStringLiteral( "Polygon ((4 2, -10 2, 3 -2, 4 2),(1 -1, 1 1, -1 1, 1 -1))" );
|
|
QCOMPARE( obtained, expected );
|
|
geom.rotate( -90, QgsPointXY( 0, 0 ) );
|
|
obtained = geom.exportToWkt();
|
|
QCOMPARE( obtained, wkt );
|
|
|
|
wkt = QStringLiteral( "Point (40 50)" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
geom.rotate( 90, QgsPointXY( 0, 0 ) );
|
|
obtained = geom.exportToWkt();
|
|
expected = QStringLiteral( "Point (50 -40)" );
|
|
QCOMPARE( obtained, expected );
|
|
geom.rotate( -90, QgsPointXY( 0, 0 ) );
|
|
obtained = geom.exportToWkt();
|
|
QCOMPARE( obtained, wkt );
|
|
geom.rotate( 180, QgsPointXY( 40, 0 ) );
|
|
expected = QStringLiteral( "Point (40 -50)" );
|
|
obtained = geom.exportToWkt();
|
|
QCOMPARE( obtained, expected );
|
|
geom.rotate( 180, QgsPointXY( 40, 0 ) ); // round-trip
|
|
obtained = geom.exportToWkt();
|
|
QCOMPARE( obtained, wkt );
|
|
|
|
}
|
|
|
|
void TestQgsGeometry::unionCheck1()
|
|
{
|
|
// should be a multipolygon with 2 parts as A does not intersect C
|
|
QgsGeometry mypUnionGeometry = mpPolygonGeometryA.combine( mpPolygonGeometryC );
|
|
qDebug() << "Geometry Type: " << QgsWkbTypes::displayString( mypUnionGeometry.wkbType() );
|
|
QVERIFY( mypUnionGeometry.wkbType() == QgsWkbTypes::MultiPolygon );
|
|
QgsMultiPolygon myMultiPolygon = mypUnionGeometry.asMultiPolygon();
|
|
QVERIFY( myMultiPolygon.size() > 0 ); //check that the union did not fail
|
|
dumpMultiPolygon( myMultiPolygon );
|
|
QVERIFY( renderCheck( "geometry_unionCheck1", "Checking A union C produces 2 polys" ) );
|
|
}
|
|
|
|
void TestQgsGeometry::unionCheck2()
|
|
{
|
|
// should be a single polygon as A intersect B
|
|
QgsGeometry mypUnionGeometry = mpPolygonGeometryA.combine( mpPolygonGeometryB );
|
|
qDebug() << "Geometry Type: " << QgsWkbTypes::displayString( mypUnionGeometry.wkbType() );
|
|
QVERIFY( mypUnionGeometry.wkbType() == QgsWkbTypes::Polygon );
|
|
QgsPolygon myPolygon = mypUnionGeometry.asPolygon();
|
|
QVERIFY( myPolygon.size() > 0 ); //check that the union created a feature
|
|
dumpPolygon( myPolygon );
|
|
QVERIFY( renderCheck( "geometry_unionCheck2", "Checking A union B produces single union poly" ) );
|
|
}
|
|
|
|
void TestQgsGeometry::differenceCheck1()
|
|
{
|
|
// should be same as A since A does not intersect C so diff is 100% of A
|
|
QgsGeometry mypDifferenceGeometry( mpPolygonGeometryA.difference( mpPolygonGeometryC ) );
|
|
qDebug() << "Geometry Type: " << QgsWkbTypes::displayString( mypDifferenceGeometry.wkbType() );
|
|
QVERIFY( mypDifferenceGeometry.wkbType() == QgsWkbTypes::Polygon );
|
|
QgsPolygon myPolygon = mypDifferenceGeometry.asPolygon();
|
|
QVERIFY( myPolygon.size() > 0 ); //check that the union did not fail
|
|
dumpPolygon( myPolygon );
|
|
QVERIFY( renderCheck( "geometry_differenceCheck1", "Checking (A - C) = A" ) );
|
|
}
|
|
|
|
void TestQgsGeometry::differenceCheck2()
|
|
{
|
|
// should be a single polygon as (A - B) = subset of A
|
|
QgsGeometry mypDifferenceGeometry( mpPolygonGeometryA.difference( mpPolygonGeometryB ) );
|
|
qDebug() << "Geometry Type: " << QgsWkbTypes::displayString( mypDifferenceGeometry.wkbType() );
|
|
QVERIFY( mypDifferenceGeometry.wkbType() == QgsWkbTypes::Polygon );
|
|
QgsPolygon myPolygon = mypDifferenceGeometry.asPolygon();
|
|
QVERIFY( myPolygon.size() > 0 ); //check that the union created a feature
|
|
dumpPolygon( myPolygon );
|
|
QVERIFY( renderCheck( "geometry_differenceCheck2", "Checking (A - B) = subset of A" ) );
|
|
}
|
|
void TestQgsGeometry::bufferCheck()
|
|
{
|
|
// should be a single polygon
|
|
QgsGeometry mypBufferGeometry( mpPolygonGeometryB.buffer( 10, 10 ) );
|
|
qDebug() << "Geometry Type: " << QgsWkbTypes::displayString( mypBufferGeometry.wkbType() );
|
|
QVERIFY( mypBufferGeometry.wkbType() == QgsWkbTypes::Polygon );
|
|
QgsPolygon myPolygon = mypBufferGeometry.asPolygon();
|
|
QVERIFY( myPolygon.size() > 0 ); //check that the buffer created a feature
|
|
dumpPolygon( myPolygon );
|
|
QVERIFY( renderCheck( "geometry_bufferCheck", "Checking buffer(10,10) of B", 10 ) );
|
|
}
|
|
|
|
void TestQgsGeometry::smoothCheck()
|
|
{
|
|
//can't smooth a point
|
|
QString wkt = QStringLiteral( "Point (40 50)" );
|
|
QgsGeometry geom( QgsGeometry::fromWkt( wkt ) );
|
|
QgsGeometry result = geom.smooth( 1, 0.25 );
|
|
QString obtained = result.exportToWkt();
|
|
QCOMPARE( obtained, wkt );
|
|
|
|
//linestring
|
|
wkt = QStringLiteral( "LineString(0 0, 10 0, 10 10, 20 10)" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
result = geom.smooth( 1, 0.25 );
|
|
QgsPolyline line = result.asPolyline();
|
|
QgsPolyline expectedLine;
|
|
expectedLine << QgsPointXY( 0, 0 ) << QgsPointXY( 7.5, 0 ) << QgsPointXY( 10.0, 2.5 )
|
|
<< QgsPointXY( 10.0, 7.5 ) << QgsPointXY( 12.5, 10.0 ) << QgsPointXY( 20.0, 10.0 );
|
|
QVERIFY( QgsGeometry::compare( line, expectedLine ) );
|
|
|
|
//linestring, with min distance
|
|
wkt = QStringLiteral( "LineString(0 0, 10 0, 10 10, 15 10, 15 20)" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
result = geom.smooth( 1, 0.25, 6 );
|
|
line = result.asPolyline();
|
|
expectedLine.clear();
|
|
expectedLine << QgsPointXY( 0, 0 ) << QgsPointXY( 7.5, 0 ) << QgsPointXY( 10.0, 2.5 )
|
|
<< QgsPointXY( 10.0, 7.5 ) << QgsPointXY( 15, 12.5 ) << QgsPointXY( 15.0, 20.0 );
|
|
QVERIFY( QgsGeometry::compare( line, expectedLine ) );
|
|
|
|
//linestring, with max angle
|
|
wkt = QStringLiteral( "LineString(0 0, 10 0, 15 5, 25 -5, 30 -5 )" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
result = geom.smooth( 1, 0.25, 0, 50 );
|
|
line = result.asPolyline();
|
|
expectedLine.clear();
|
|
expectedLine << QgsPointXY( 0, 0 ) << QgsPointXY( 7.5, 0 ) << QgsPointXY( 11.25, 1.25 )
|
|
<< QgsPointXY( 15.0, 5.0 ) << QgsPointXY( 22.5, -2.5 ) << QgsPointXY( 26.25, -5 ) << QgsPointXY( 30, -5 );
|
|
QVERIFY( QgsGeometry::compare( line, expectedLine ) );
|
|
|
|
//linestring, with max angle, other direction
|
|
wkt = QStringLiteral( "LineString( 30 -5, 25 -5, 15 5, 10 0, 0 0 )" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
result = geom.smooth( 1, 0.25, 0, 50 );
|
|
line = result.asPolyline();
|
|
expectedLine.clear();
|
|
expectedLine << QgsPointXY( 30, -5 ) << QgsPointXY( 26.25, -5 ) << QgsPointXY( 22.5, -2.5 )
|
|
<< QgsPointXY( 15.0, 5.0 ) << QgsPointXY( 11.25, 1.25 ) << QgsPointXY( 7.5, 0 ) << QgsPointXY( 0, 0 );
|
|
QVERIFY( QgsGeometry::compare( line, expectedLine ) );
|
|
|
|
//linestring, max angle, first corner sharp
|
|
wkt = QStringLiteral( "LineString(0 0, 10 0, 10 10 )" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
result = geom.smooth( 1, 0.25, 0, 50 );
|
|
line = result.asPolyline();
|
|
expectedLine.clear();
|
|
expectedLine << QgsPointXY( 0, 0 ) << QgsPointXY( 10, 0 ) << QgsPointXY( 10, 10 );
|
|
QVERIFY( QgsGeometry::compare( line, expectedLine ) );
|
|
|
|
wkt = QStringLiteral( "MultiLineString ((0 0, 10 0, 10 10, 20 10),(30 30, 40 30, 40 40, 50 40))" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
result = geom.smooth( 1, 0.25 );
|
|
QgsMultiPolyline multiLine = result.asMultiPolyline();
|
|
QgsMultiPolyline expectedMultiline;
|
|
expectedMultiline << ( QgsPolyline() << QgsPointXY( 0, 0 ) << QgsPointXY( 7.5, 0 ) << QgsPointXY( 10.0, 2.5 )
|
|
<< QgsPointXY( 10.0, 7.5 ) << QgsPointXY( 12.5, 10.0 ) << QgsPointXY( 20.0, 10.0 ) )
|
|
<< ( QgsPolyline() << QgsPointXY( 30.0, 30.0 ) << QgsPointXY( 37.5, 30.0 ) << QgsPointXY( 40.0, 32.5 )
|
|
<< QgsPointXY( 40.0, 37.5 ) << QgsPointXY( 42.5, 40.0 ) << QgsPointXY( 50.0, 40.0 ) );
|
|
QVERIFY( QgsGeometry::compare( multiLine, expectedMultiline ) );
|
|
|
|
//polygon
|
|
wkt = QStringLiteral( "Polygon ((0 0, 10 0, 10 10, 0 10, 0 0 ),(2 2, 4 2, 4 4, 2 4, 2 2))" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
result = geom.smooth( 1, 0.25 );
|
|
QgsPolygon poly = result.asPolygon();
|
|
QgsPolygon expectedPolygon;
|
|
expectedPolygon << ( QgsPolyline() << QgsPointXY( 2.5, 0 ) << QgsPointXY( 7.5, 0 ) << QgsPointXY( 10.0, 2.5 )
|
|
<< QgsPointXY( 10.0, 7.5 ) << QgsPointXY( 7.5, 10.0 ) << QgsPointXY( 2.5, 10.0 ) << QgsPointXY( 0, 7.5 )
|
|
<< QgsPointXY( 0, 2.5 ) << QgsPointXY( 2.5, 0 ) )
|
|
<< ( QgsPolyline() << QgsPointXY( 2.5, 2.0 ) << QgsPointXY( 3.5, 2.0 ) << QgsPointXY( 4.0, 2.5 )
|
|
<< QgsPointXY( 4.0, 3.5 ) << QgsPointXY( 3.5, 4.0 ) << QgsPointXY( 2.5, 4.0 )
|
|
<< QgsPointXY( 2.0, 3.5 ) << QgsPointXY( 2.0, 2.5 ) << QgsPointXY( 2.5, 2.0 ) );
|
|
QVERIFY( QgsGeometry::compare( poly, expectedPolygon ) );
|
|
|
|
//polygon with max angle - should be unchanged
|
|
wkt = QStringLiteral( "Polygon ((0 0, 10 0, 10 10, 0 10, 0 0))" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
result = geom.smooth( 1, 0.25, -1, 50 );
|
|
poly = result.asPolygon();
|
|
expectedPolygon.clear();
|
|
expectedPolygon << ( QgsPolyline() << QgsPointXY( 0, 0 ) << QgsPointXY( 10, 0 ) << QgsPointXY( 10.0, 10 )
|
|
<< QgsPointXY( 0, 10 ) << QgsPointXY( 0, 0 ) );
|
|
QVERIFY( QgsGeometry::compare( poly, expectedPolygon ) );
|
|
|
|
//multipolygon)
|
|
wkt = QStringLiteral( "MultiPolygon (((0 0, 10 0, 10 10, 0 10, 0 0 )),((2 2, 4 2, 4 4, 2 4, 2 2)))" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
result = geom.smooth( 1, 0.1 );
|
|
QgsMultiPolygon multipoly = result.asMultiPolygon();
|
|
QgsMultiPolygon expectedMultiPoly;
|
|
expectedMultiPoly
|
|
<< ( QgsPolygon() << ( QgsPolyline() << QgsPointXY( 1.0, 0 ) << QgsPointXY( 9, 0 ) << QgsPointXY( 10.0, 1 )
|
|
<< QgsPointXY( 10.0, 9 ) << QgsPointXY( 9, 10.0 ) << QgsPointXY( 1, 10.0 ) << QgsPointXY( 0, 9 )
|
|
<< QgsPointXY( 0, 1 ) << QgsPointXY( 1, 0 ) ) )
|
|
<< ( QgsPolygon() << ( QgsPolyline() << QgsPointXY( 2.2, 2.0 ) << QgsPointXY( 3.8, 2.0 ) << QgsPointXY( 4.0, 2.2 )
|
|
<< QgsPointXY( 4.0, 3.8 ) << QgsPointXY( 3.8, 4.0 ) << QgsPointXY( 2.2, 4.0 ) << QgsPointXY( 2.0, 3.8 )
|
|
<< QgsPointXY( 2, 2.2 ) << QgsPointXY( 2.2, 2 ) ) );
|
|
QVERIFY( QgsGeometry::compare( multipoly, expectedMultiPoly ) );
|
|
}
|
|
|
|
void TestQgsGeometry::unaryUnion()
|
|
{
|
|
//test QgsGeometry::unaryUnion with null geometry
|
|
QString wkt1 = QStringLiteral( "Polygon ((0 0, 10 0, 10 10, 0 10, 0 0 ))" );
|
|
QString wkt2 = QStringLiteral( "Polygon ((2 2, 4 2, 4 4, 2 4, 2 2))" );
|
|
QgsGeometry geom1( QgsGeometry::fromWkt( wkt1 ) );
|
|
QgsGeometry geom2( QgsGeometry::fromWkt( wkt2 ) );
|
|
QgsGeometry empty;
|
|
QList< QgsGeometry > list;
|
|
list << geom1 << empty << geom2;
|
|
|
|
QgsGeometry result( QgsGeometry::unaryUnion( list ) );
|
|
Q_UNUSED( result );
|
|
}
|
|
|
|
void TestQgsGeometry::dataStream()
|
|
{
|
|
QString wkt = QStringLiteral( "Point (40 50)" );
|
|
QgsGeometry geom( QgsGeometry::fromWkt( wkt ) );
|
|
|
|
QByteArray ba;
|
|
QDataStream ds( &ba, QIODevice::ReadWrite );
|
|
ds << geom;
|
|
|
|
QgsGeometry resultGeometry;
|
|
ds.device()->seek( 0 );
|
|
ds >> resultGeometry;
|
|
|
|
QCOMPARE( geom.geometry()->asWkt(), resultGeometry.geometry()->asWkt() );
|
|
|
|
//also test with geometry without data
|
|
std::unique_ptr<QgsGeometry> emptyGeom( new QgsGeometry() );
|
|
|
|
QByteArray ba2;
|
|
QDataStream ds2( &ba2, QIODevice::ReadWrite );
|
|
ds2 << emptyGeom.get();
|
|
|
|
ds2.device()->seek( 0 );
|
|
ds2 >> resultGeometry;
|
|
|
|
QVERIFY( resultGeometry.isNull() );
|
|
}
|
|
|
|
void TestQgsGeometry::exportToGeoJSON()
|
|
{
|
|
//Point
|
|
QString wkt = QStringLiteral( "Point (40 50)" );
|
|
QgsGeometry geom( QgsGeometry::fromWkt( wkt ) );
|
|
QString obtained = geom.exportToGeoJSON();
|
|
QString geojson = QStringLiteral( "{\"type\": \"Point\", \"coordinates\": [40, 50]}" );
|
|
QCOMPARE( obtained, geojson );
|
|
|
|
//MultiPoint
|
|
wkt = QStringLiteral( "MultiPoint (0 0, 10 0, 10 10, 20 10)" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
obtained = geom.exportToGeoJSON();
|
|
geojson = QStringLiteral( "{\"type\": \"MultiPoint\", \"coordinates\": [ [0, 0], [10, 0], [10, 10], [20, 10]] }" );
|
|
QCOMPARE( obtained, geojson );
|
|
|
|
//Linestring
|
|
wkt = QStringLiteral( "LineString(0 0, 10 0, 10 10, 20 10)" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
obtained = geom.exportToGeoJSON();
|
|
geojson = QStringLiteral( "{\"type\": \"LineString\", \"coordinates\": [ [0, 0], [10, 0], [10, 10], [20, 10]]}" );
|
|
QCOMPARE( obtained, geojson );
|
|
|
|
//MultiLineString
|
|
wkt = QStringLiteral( "MultiLineString ((0 0, 10 0, 10 10, 20 10),(30 30, 40 30, 40 40, 50 40))" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
obtained = geom.exportToGeoJSON();
|
|
geojson = QStringLiteral( "{\"type\": \"MultiLineString\", \"coordinates\": [[ [0, 0], [10, 0], [10, 10], [20, 10]], [ [30, 30], [40, 30], [40, 40], [50, 40]]] }" );
|
|
QCOMPARE( obtained, geojson );
|
|
|
|
//Polygon
|
|
wkt = QStringLiteral( "Polygon ((0 0, 10 0, 10 10, 0 10, 0 0 ),(2 2, 4 2, 4 4, 2 4, 2 2))" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
obtained = geom.exportToGeoJSON();
|
|
geojson = QStringLiteral( "{\"type\": \"Polygon\", \"coordinates\": [[ [0, 0], [10, 0], [10, 10], [0, 10], [0, 0]], [ [2, 2], [4, 2], [4, 4], [2, 4], [2, 2]]] }" );
|
|
QCOMPARE( obtained, geojson );
|
|
|
|
//MultiPolygon
|
|
wkt = QStringLiteral( "MultiPolygon (((0 0, 10 0, 10 10, 0 10, 0 0 )),((2 2, 4 2, 4 4, 2 4, 2 2)))" );
|
|
geom = QgsGeometry::fromWkt( wkt );
|
|
obtained = geom.exportToGeoJSON();
|
|
geojson = QStringLiteral( "{\"type\": \"MultiPolygon\", \"coordinates\": [[[ [0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]], [[ [2, 2], [4, 2], [4, 4], [2, 4], [2, 2]]]] }" );
|
|
QCOMPARE( obtained, geojson );
|
|
|
|
// no geometry
|
|
QgsGeometry nullGeom( nullptr );
|
|
obtained = nullGeom.exportToGeoJSON();
|
|
geojson = QStringLiteral( "null" );
|
|
QCOMPARE( obtained, geojson );
|
|
}
|
|
|
|
bool TestQgsGeometry::renderCheck( const QString &testName, const QString &comment, int mismatchCount )
|
|
{
|
|
mReport += "<h2>" + testName + "</h2>\n";
|
|
mReport += "<h3>" + comment + "</h3>\n";
|
|
QString myTmpDir = QDir::tempPath() + '/';
|
|
QString myFileName = myTmpDir + testName + ".png";
|
|
mImage.save( myFileName, "PNG" );
|
|
QgsRenderChecker myChecker;
|
|
myChecker.setControlName( "expected_" + testName );
|
|
myChecker.setRenderedImage( myFileName );
|
|
bool myResultFlag = myChecker.compareImages( testName, mismatchCount );
|
|
mReport += myChecker.report();
|
|
return myResultFlag;
|
|
}
|
|
|
|
void TestQgsGeometry::dumpMultiPolygon( QgsMultiPolygon &multiPolygon )
|
|
{
|
|
qDebug( "Multipolygon Geometry Dump" );
|
|
for ( int i = 0; i < multiPolygon.size(); i++ )
|
|
{
|
|
QgsPolygon myPolygon = multiPolygon.at( i );
|
|
qDebug( "\tPolygon in multipolygon: %d", i );
|
|
dumpPolygon( myPolygon );
|
|
}
|
|
}
|
|
|
|
void TestQgsGeometry::dumpPolygon( QgsPolygon &polygon )
|
|
{
|
|
QVector<QPointF> myPoints;
|
|
for ( int j = 0; j < polygon.size(); j++ )
|
|
{
|
|
QgsPolyline myPolyline = polygon.at( j ); //rings of polygon
|
|
qDebug( "\t\tRing in polygon: %d", j );
|
|
|
|
for ( int k = 0; k < myPolyline.size(); k++ )
|
|
{
|
|
QgsPointXY myPoint = myPolyline.at( k );
|
|
qDebug( "\t\t\tPoint in ring %d : %s", k, myPoint.toString().toLocal8Bit().constData() );
|
|
myPoints << QPointF( myPoint.x(), myPoint.y() );
|
|
}
|
|
}
|
|
mpPainter->drawPolygon( myPoints );
|
|
}
|
|
|
|
void TestQgsGeometry::dumpPolyline( QgsPolyline &polyline )
|
|
{
|
|
QVector<QPointF> myPoints;
|
|
// QgsPolyline myPolyline = polyline.at( j ); //rings of polygon
|
|
for ( int j = 0; j < polyline.size(); j++ )
|
|
{
|
|
QgsPointXY myPoint = polyline.at( j );
|
|
// QgsPolyline myPolyline = polygon.at( j ); //rings of polygon
|
|
myPoints << QPointF( myPoint.x(), myPoint.y() );
|
|
qDebug( "\t\tPoint in line: %d", j );
|
|
|
|
// for ( int k = 0; k < myPolyline.size(); k++ )
|
|
// {
|
|
// QgsPointXY myPoint = myPolyline.at( k );
|
|
// qDebug( "\t\t\tPoint in ring %d : %s", k, myPoint.toString().toLocal8Bit().constData() );
|
|
// myPoints << QPointF( myPoint.x(), myPoint.y() );
|
|
// }
|
|
}
|
|
mpPainter->drawPolyline( myPoints );
|
|
}
|
|
|
|
QString TestQgsGeometry::elemToString( const QDomElement &elem ) const
|
|
{
|
|
QString s;
|
|
QTextStream stream( &s );
|
|
elem.save( stream, -1 );
|
|
|
|
return s;
|
|
}
|
|
|
|
void TestQgsGeometry::wkbInOut()
|
|
{
|
|
// Premature end of WKB
|
|
// See https://issues.qgis.org/issues/14182
|
|
const char *hexwkb = "0102000000EF0000000000000000000000000000000000000000000000000000000000000000000000";
|
|
int size;
|
|
unsigned char *wkb = hex2bytes( hexwkb, &size );
|
|
QgsGeometry g14182;
|
|
// NOTE: wkb onwership transferred to QgsGeometry
|
|
g14182.fromWkb( wkb, size );
|
|
//QList<QgsGeometry::Error> errors;
|
|
//g14182.validateGeometry(errors);
|
|
// Check with valgrind !
|
|
QString wkt = g14182.exportToWkt();
|
|
QCOMPARE( wkt, QString() );
|
|
|
|
//WKB with a truncated header
|
|
const char *badHeaderHexwkb = "0102";
|
|
wkb = hex2bytes( badHeaderHexwkb, &size );
|
|
QgsGeometry badHeader;
|
|
// NOTE: wkb onwership transferred to QgsGeometry
|
|
badHeader.fromWkb( wkb, size );
|
|
QVERIFY( badHeader.isNull() );
|
|
QCOMPARE( badHeader.wkbType(), QgsWkbTypes::Unknown );
|
|
}
|
|
|
|
void TestQgsGeometry::directionNeutralSegmentation()
|
|
{
|
|
//Tests, if segmentation of a circularstring is the same in both directions
|
|
QString CWCircularStringWkt( QStringLiteral( "CIRCULARSTRING( 0 0, 0.5 0.5, 0.83 7.33 )" ) );
|
|
QgsCircularString *CWCircularString = static_cast<QgsCircularString *>( QgsGeometryFactory::geomFromWkt( CWCircularStringWkt ).release() );
|
|
QgsLineString *CWLineString = CWCircularString->curveToLine();
|
|
|
|
QString CCWCircularStringWkt( QStringLiteral( "CIRCULARSTRING( 0.83 7.33, 0.5 0.5, 0 0 )" ) );
|
|
QgsCircularString *CCWCircularString = static_cast<QgsCircularString *>( QgsGeometryFactory::geomFromWkt( CCWCircularStringWkt ).release() );
|
|
QgsLineString *CCWLineString = CCWCircularString->curveToLine();
|
|
QgsLineString *reversedCCWLineString = CCWLineString->reversed();
|
|
|
|
QCOMPARE( CWLineString->asWkt(), reversedCCWLineString->asWkt() );
|
|
bool equal = ( *CWLineString == *reversedCCWLineString );
|
|
|
|
delete CWCircularString;
|
|
delete CCWCircularString;
|
|
delete CWLineString;
|
|
delete CCWLineString;
|
|
delete reversedCCWLineString;
|
|
|
|
QVERIFY( equal );
|
|
}
|
|
|
|
void TestQgsGeometry::poleOfInaccessibility()
|
|
{
|
|
QString poly1Wkt( "Polygon ((3116 3071, 3394 3431, 3563 3362, 3611 3205, 3599 3181, 3477 3281, 3449 3160, 3570 3127, 3354 3116,"
|
|
" 3436 3008, 3158 2907, 2831 2438, 3269 2916, 3438 2885, 3295 2799, 3407 2772, 3278 2629, 3411 2689, 3329 2611,"
|
|
" 3360 2531, 3603 2800, 3598 2501, 3317 2429, 3329 2401, 3170 2340, 3142 2291, 3524 2403, 3598 2233, 3460 2117,"
|
|
" 3590 1931, 3364 1753, 3597 1875, 3639 1835, 3660 1733, 3600 1771, 3538 1694, 3661 1732, 3359 1554, 3334 1554,"
|
|
" 3341 1588, 3317 1588, 3305 1644, 3286 1656, 3115 1255, 3072 1252, 3078 1335, 3046 1355, 2984 1234, 2983 1409,"
|
|
" 2876 1222, 2525 1161, 2488 787, 2162 913, 2079 661, 2270 380, 2188 823, 2510 592, 2659 992, 2911 1118, 2943 938,"
|
|
" 2957 1097, 3092 1002, 3006 1097, 3233 1282, 3325 1291, 3296 1116, 3333 1115, 3391 1333, 3434 1274, 3413 1326,"
|
|
" 3449 1327, 3473 1408, 3490 1430, 3526 1434, 3198 -112, 3263 -87, 3289 -128, 4224 -128, 4224 -128, 3474 -128,"
|
|
" 3475 -116, 3486 -120, 3458 -49, 3523 -78, 3513 -128, 3509 -119, 3509 -128, 3717 -128, 3705 -60, 3735 -16,"
|
|
" 3714 38, 3758 88, 3825 47, 3812 -11, 3859 -51, 3871 49, 3760 149, 3636 -74, 3510 126, 3501 245, 3504 270,"
|
|
" 3511 284, 3582 16, 3631 19, 3569 125, 3570 193, 3610 212, 3583 119, 3655 29, 3738 170, 3561 466, 3826 549,"
|
|
" 3527 604, 3609 833, 3681 798, 3956 1127, 3917 964, 4043 850, 4049 1096, 4193 1052, 4191 1078, 4208 1106,"
|
|
" 4222 1110, 4224 1109, 4224 1144, 4202 1158, 4177 1161, 4182 1181, 4075 1201, 4141 1275, 4215 1215, 4221 1223,"
|
|
" 4219 1231, 4224 1243, 4224 1257, 4224 1262, 4224 1345, 4224 1339, 4224 1328, 4215 1335, 4203 1355, 4215 1369,"
|
|
" 4224 1363, 4215 1377, 4208 1387, 4217 1401, 4224 1403, 4224 1520, 4219 1535, 4221 1544, 4199 1593, 4223 1595,"
|
|
" 4206 1626, 4214 1648, 4224 1645, 4224 1640, 4224 2108, 4220 2125, 4224 2125, 4224 2143, 4205 2141, 4180 2159,"
|
|
" 4201 2182, 4163 2189, 4176 2229, 4199 2211, 4210 2218, 4212 2210, 4223 2214, 4224 2207, 4224 2216, 4217 2225,"
|
|
" 4221 2233, 4203 2227, 4209 2248, 4185 2240, 4198 2276, 4144 2218, 4091 2343, 4119 2332, 4121 2347, 4155 2337,"
|
|
" 4180 2355, 4200 2342, 4201 2354, 4213 2352, 4224 2348, 4224 2356, 4207 2361, 4184 2358, 4176 2367, 4106 2355,"
|
|
" 3983 2765, 4050 3151, 4139 2720, 4209 2589, 4211 2600, 4219 2599, 4224 2592, 4224 2574, 4223 2566, 4224 2562,"
|
|
" 4224 2553, 4224 2552, 4224 -128, 4224 4224, 4205 4224, 4015 3513, 3993 3494, 3873 3533, 3887 3539, 3923 3524,"
|
|
" 3950 3529, 4018 3572, 3987 3633, 3983 3571, 3955 3583, 3936 3547, 3882 3539, 3913 3557, 3920 3598, 3901 3596,"
|
|
" 3923 3631, 3914 3628, 3919 3647, 3922 3656, 3917 3666, 3523 3438, 3631 3564, 3527 3597, 3718 3655, 3578 3672,"
|
|
" 3660 3867, 3543 3628, 3416 3725, 3487 3503, 3274 3583, 3271 3644, 3197 3671, 3210 3775, 3184 3788, 3181 3672,"
|
|
" 3306 3521, 3292 3508, 3229 3565, 3219 3564, 3216 3574, 3192 3578, 3297 3444, 3089 3395, 3029 3028, 2973 3133,"
|
|
" 2529 2945, 2538 2811, 2461 2901, 2170 2839, 2121 2797, 2156 2733, 2105 2709, 2096 2695, 2114 2621, 2102 2693,"
|
|
" 2168 2738, 2167 2778, 2447 2765, 2441 2866, 2527 2793, 2670 2938, 2626 2651, 2688 2623, 2740 2922, 3084 2960,"
|
|
" 3116 3071),(4016 1878, 4029 1859, 4008 1839, 4006 1863, 4016 1878),(3315 1339, 3331 1324, 3290 1293, 3305 1315,"
|
|
" 3315 1339),(4136 3071, 4136 3080, 4143 3020, 4137 3036, 4136 3071),(4218 3073, 4183 3114, 4117 3157, 4159 3147,"
|
|
" 4218 3073),(3912 3542, 3934 3536, 3955 3536, 3937 3527, 3900 3540, 3912 3542),(4050 3172, 4043 3210, 4085 3209,"
|
|
" 4090 3179, 4050 3172),(4151 2998, 4158 2977, 4159 2946, 4147 2988, 4151 2998),(2920 3005, 2935 2994, 2864 2973,"
|
|
" 2905 3016, 2920 3005),(3571 2424, 3545 2469, 3608 2480, 3596 2434, 3571 2424),(4095 1229, 4073 1234, 4076 1293,"
|
|
" 4121 1285, 4095 1229),(4173 1536, 4153 1576, 4166 1585, 4198 1571, 4188 1532, 4213 1535, 4224 1512, 4224 1511,"
|
|
" 4209 1511, 4198 1506, 4190 1517, 4194 1509, 4192 1499, 4200 1496, 4202 1504, 4224 1510, 4224 1488, 4215 1486,"
|
|
" 4216 1478, 4224 1472, 4224 1464, 4207 1458, 4193 1464, 4173 1536),(3934 1537, 3968 1630, 3960 1666, 3968 1673,"
|
|
" 3975 1562, 3934 1537),(4182 1653, 4196 1624, 4166 1614, 4157 1674, 4216 1671, 4182 1653),(4200 1619, 4196 1620,"
|
|
" 4200 1632, 4195 1642, 4207 1648, 4200 1619),(4026 1835, 4025 1830, 4016 1808, 4007 1836, 4026 1835),(4199 1384,"
|
|
" 4182 1389, 4206 1412, 4216 1401, 4199 1384),(3926 1251, 3969 1206, 3913 1149, 3878 1173, 3876 1229, 3926 1251),"
|
|
" (3926 1354, 3958 1389, 3997 1384, 3991 1352, 3960 1322, 3955 1299, 3926 1354),(3964 1319, 3974 1329, 3984 1285,"
|
|
" 3963 1301, 3964 1319),(3687 959, 3696 903, 3678 885, 3665 930, 3687 959),(3452 79, 3437 124, 3456 149, 3476 141,"
|
|
" 3452 79),(3751 927, 3738 906, 3719 942, 3739 929, 3751 927))" );
|
|
|
|
QString poly2Wkt( "Polygon ((-128 4224, -128 2734, -11 2643, -101 2919, 120 2654, 19 2846, 217 2897, -13 2873, -79 2998, -106 2989,"
|
|
" -128 3002, -128 4224, -128 4224, 1249 4224, 1247 4199, 1231 4132, 909 3902, 775 3278, 509 2903, 470 2603, 663 2311,"
|
|
" 889 2134, 989 2146, 534 2585, 575 2880, 833 3112, 833 3037, 1025 2977, 834 3096, 946 3217, 923 3153, 971 3094,"
|
|
" 997 3103, 1166 3423, 1198 3329, 1233 3367, 1270 3327, 1274 3354, 1290 3360, 1321 3322, 1331 3318, 1343 3325,"
|
|
" 1310 3073, 1363 3093, 1413 3186, 1325 3398, 1458 3364, 1493 3426, 1526 3394, 1588 3465, 1417 3824, 1458 3825,"
|
|
" 1522 3849, 1729 3488, 2018 3223, 1908 3291, 1924 3238, 1899 3187, 1913 3150, 2070 3041, 2102 3063, 2112 3053,"
|
|
" 2168 3085, 2101 2994, 2265 2863, 1890 2593, 2106 2713, 2130 2706, 2108 2678, 2117 2647, 2105 2636, 2099 2604,"
|
|
" 2094 2591, 2088 2575, 2088 2564, 2249 2751, 2441 2618, 2689 1728, 2681 2323, 2776 1685, 2711 1708, 2673 1680,"
|
|
" 2675 1639, 2810 1522, 2765 1535, 2734 1510, 2850 1332, 2863 1186, 2847 1025, 2832 985, 2739 1025, 2850 1090,"
|
|
" 2859 1174, 2853 1235, 2827 1235, 2839 1279, 2811 1286, 2751 1272, 2851 1160, 2788 1159, 2724 1204, 2713 1198,"
|
|
" 2708 1213, 2699 1221, 2724 1179, 2797 1145, 2785 1123, 2848 1143, 2821 1092, 2284 980, 2288 963, 2264 962,"
|
|
" 2261 948, 2247 958, 2194 947, 2120 900, 2047 809, 2434 923, 2450 817, 2528 737, 2527 667, 2641 544, 2641 460,"
|
|
" 2710 452, 2687 447, 2681 435, 2693 330, 2772 327, 2766 291, 2779 245, 2769 219, 2771 198, 2816 219, 2781 342,"
|
|
" 2612 647, 2903 188, 2803 539, 2950 206, 2927 342, 3123 339, 3092 300, 3073 175, 3082 160, 3412 -103, 4224 -128,"
|
|
" 4032 167, 3572 63, 3554 109, 3606 211, 3604 232, 3454 124, 3332 345, 3237 212, 3181 415, 2953 364, 2761 692,"
|
|
" 2819 788, 2997 769, 2997 626, 3199 659, 3155 730, 2929 805, 2908 841, 3218 717, 3276 744, 3246 723, 3270 658,"
|
|
" 4223 473, 4224 589, 3906 681, 3818 677, 3915 686, 4224 592, 4224 4224, -128 4224, -128 4224),(2049 3181,"
|
|
" 2224 3084, 2204 3040, 2169 3036, 2174 3084, 2155 3102, 2126 3123, 2109 3127, 2103 3102, 2049 3181),(1578 3811,"
|
|
" 1567 3883, 1675 3768, 1658 3712, 1659 3751, 1578 3811),(2304 2930, 2335 2918, 2287 2880, 2279 2926, 2304 2930),"
|
|
" (2316 2895, 2317 2895, 2316 2901, 2331 2901, 2332 2889, 2316 2895),(2304 2850, 2335 2861, 2344 2910, 2357 2828,"
|
|
" 2304 2850),(1714 3583, 1725 3638, 1682 3717, 1797 3564, 1714 3583),(1537 3873, 1456 3827, 1405 3876, 1461 3898,"
|
|
" 1537 3873),(2547 2560, 2375 2815, 2384 2825, 2470 2722, 2685 2336, 2648 2310, 2547 2560),(2107 3073, 2107 3098,"
|
|
" 2144 3086, 2122 3073, 2113 3059, 2107 3073),(2117 3120, 2156 3099, 2164 3083, 2106 3103, 2117 3120),(2303 2981,"
|
|
" 2226 3010, 2232 3064, 2286 3012, 2344 2928, 2303 2981),(2304 2858, 2291 2864, 2303 2885, 2324 2870, 2304 2858),"
|
|
" (2175 3002, 2179 2983, 2152 2991, 2175 3002, 2175 3002),(2175 3022, 2150 3017, 2144 3048, 2159 3031, 2184 3030,"
|
|
" 2175 3022),(2265 2953, 2270 2950, 2262 2950, 2254 2963, 2253 2979, 2265 2953),(2229 2928, 2250 2928, 2241 2922,"
|
|
" 2239 2914, 2224 2900, 2237 2914, 2229 2928),(2531 2473, 2520 2466, 2521 2474, 2511 2503, 2531 2473),(2547 2526,"
|
|
" 2529 2519, 2528 2541, 2544 2538, 2547 2526),(2559 646, 2513 810, 2463 835, 2462 930, 2746 731, 2559 646),(3840 653,"
|
|
" 3809 641, 3718 689, 3547 733, 3553 712, 3440 780, 3840 653),(3327 741, 3242 750, 3195 745, 3180 758, 3326 764,"
|
|
" 3440 742, 3327 741),(3282 702, 3265 699, 3273 721, 3290 714, 3282 702),(3762 662, 3783 654, 3786 638, 3742 653,"
|
|
" 3762 662),(3071 703, 3082 741, 3079 655, 3064 657, 3071 703),(3881 637, 3904 647, 3914 626, 3861 638, 3881 637))" );
|
|
|
|
QgsGeometry poly1 = QgsGeometry::fromWkt( poly1Wkt );
|
|
QgsGeometry poly2 = QgsGeometry::fromWkt( poly2Wkt );
|
|
|
|
double distance;
|
|
QgsPointXY point = poly1.poleOfInaccessibility( 1, &distance ).asPoint();
|
|
QGSCOMPARENEAR( point.x(), 3867.37, 0.01 );
|
|
QGSCOMPARENEAR( point.y(), 2126.45, 0.01 );
|
|
QGSCOMPARENEAR( distance, 289.51, 0.01 );
|
|
|
|
point = poly1.poleOfInaccessibility( 50 ).asPoint();
|
|
QGSCOMPARENEAR( point.x(), 3855.33, 0.01 );
|
|
QGSCOMPARENEAR( point.y(), 2117.55, 0.01 );
|
|
|
|
point = poly2.poleOfInaccessibility( 1 ).asPoint();
|
|
QGSCOMPARENEAR( point.x(), 3263.50, 0.01 );
|
|
QGSCOMPARENEAR( point.y(), 3263.50, 0.01 );
|
|
|
|
//test degenerate polygons
|
|
QgsGeometry degen1 = QgsGeometry::fromWkt( QStringLiteral( "Polygon(( 0 0, 1 0, 2 0, 0 0 ))" ) );
|
|
point = degen1.poleOfInaccessibility( 1 ).asPoint();
|
|
QGSCOMPARENEAR( point.x(), 0, 0.01 );
|
|
QGSCOMPARENEAR( point.y(), 0, 0.01 );
|
|
|
|
QgsGeometry degen2 = QgsGeometry::fromWkt( QStringLiteral( "Polygon(( 0 0, 1 0, 1 1 , 1 0, 0 0 ))" ) );
|
|
point = degen2.poleOfInaccessibility( 1 ).asPoint();
|
|
QGSCOMPARENEAR( point.x(), 0, 0.01 );
|
|
QGSCOMPARENEAR( point.y(), 0, 0.01 );
|
|
|
|
//empty geometry
|
|
QVERIFY( QgsGeometry().poleOfInaccessibility( 1 ).isNull() );
|
|
|
|
// not a polygon
|
|
QgsGeometry lineString = QgsGeometry::fromWkt( QStringLiteral( "LineString(1 0, 2 2 )" ) );
|
|
QVERIFY( lineString.poleOfInaccessibility( 1 ).isNull() );
|
|
|
|
// invalid threshold
|
|
QVERIFY( poly1.poleOfInaccessibility( -1 ).isNull() );
|
|
QVERIFY( poly1.poleOfInaccessibility( 0 ).isNull() );
|
|
|
|
// curved geometry
|
|
QgsGeometry curved = QgsGeometry::fromWkt( "CurvePolygon( CompoundCurve( CircularString(-0.44 0.35, 0.51 0.34, 0.56 0.21, 0.11 -0.33, 0.15 -0.35,"
|
|
"-0.93 -0.30, -1.02 -0.22, -0.49 0.01, -0.23 -0.04),(-0.23 -0.04, -0.44, 0.35)))" );
|
|
point = curved.poleOfInaccessibility( 0.01 ).asPoint();
|
|
QGSCOMPARENEAR( point.x(), -0.4324, 0.0001 );
|
|
QGSCOMPARENEAR( point.y(), -0.2434, 0.0001 );
|
|
|
|
// multipolygon
|
|
QgsGeometry multiPoly = QgsGeometry::fromWkt( QStringLiteral( "MultiPolygon (((0 0, 10 0, 10 10, 0 10, 0 0)),((30 30, 50 30, 50 60, 30 60, 30 30)))" ) );
|
|
point = multiPoly.poleOfInaccessibility( 0.01, &distance ).asPoint();
|
|
QGSCOMPARENEAR( point.x(), 40, 0.0001 );
|
|
QGSCOMPARENEAR( point.y(), 45, 0.0001 );
|
|
QGSCOMPARENEAR( distance, 10.0, 0.00001 );
|
|
}
|
|
|
|
void TestQgsGeometry::makeValid()
|
|
{
|
|
typedef QPair<QString, QString> InputAndExpectedWktPair;
|
|
QList<InputAndExpectedWktPair> geoms;
|
|
// dimension collapse
|
|
geoms << qMakePair( QStringLiteral( "LINESTRING(0 0)" ),
|
|
QStringLiteral( "POINT(0 0)" ) );
|
|
// unclosed ring
|
|
geoms << qMakePair( QStringLiteral( "POLYGON((10 22,10 32,20 32,20 22))" ),
|
|
QStringLiteral( "POLYGON((10 22,10 32,20 32,20 22,10 22))" ) );
|
|
// butterfly polygon (self-intersecting ring)
|
|
geoms << qMakePair( QStringLiteral( "POLYGON((0 0, 10 10, 10 0, 0 10, 0 0))" ),
|
|
QStringLiteral( "MULTIPOLYGON(((5 5, 0 0, 0 10, 5 5)),((5 5, 10 10, 10 0, 5 5)))" ) );
|
|
// polygon with extra tail (a part of the ring does not form any area)
|
|
geoms << qMakePair( QStringLiteral( "POLYGON((0 0, 1 0, 1 1, 0 1, 0 0, -1 0, 0 0))" ),
|
|
QStringLiteral( "GEOMETRYCOLLECTION(POLYGON((0 0, 0 1, 1 1, 1 0, 0 0)), LINESTRING(0 0, -1 0))" ) );
|
|
// collection with invalid geometries
|
|
geoms << qMakePair( QStringLiteral( "GEOMETRYCOLLECTION(LINESTRING(0 0, 0 0), POLYGON((0 0, 10 10, 10 0, 0 10, 0 0)), LINESTRING(10 0, 10 10))" ),
|
|
QStringLiteral( "GEOMETRYCOLLECTION(POINT(0 0), MULTIPOLYGON(((5 5, 0 0, 0 10, 5 5)),((5 5, 10 10, 10 0, 5 5))), LINESTRING(10 0, 10 10)))" ) );
|
|
|
|
Q_FOREACH ( const InputAndExpectedWktPair &pair, geoms )
|
|
{
|
|
QgsGeometry gInput = QgsGeometry::fromWkt( pair.first );
|
|
QgsGeometry gExp = QgsGeometry::fromWkt( pair.second );
|
|
QVERIFY( !gInput.isNull() );
|
|
QVERIFY( !gExp.isNull() );
|
|
|
|
QgsGeometry gValid = gInput.makeValid();
|
|
QVERIFY( gValid.isGeosValid() );
|
|
QVERIFY( gValid.isGeosEqual( gExp ) );
|
|
}
|
|
}
|
|
|
|
void TestQgsGeometry::isSimple()
|
|
{
|
|
typedef QPair<QString, bool> InputWktAndExpectedResult;
|
|
QList<InputWktAndExpectedResult> geoms;
|
|
geoms << qMakePair( QStringLiteral( "LINESTRING(0 0, 1 0, 1 1)" ), true );
|
|
geoms << qMakePair( QStringLiteral( "LINESTRING(0 0, 1 0, 1 1, 0 0)" ), true ); // may be closed (linear ring)
|
|
geoms << qMakePair( QStringLiteral( "LINESTRING(0 0, 1 0, 1 1, 0 -1)" ), false ); // self-intersection
|
|
geoms << qMakePair( QStringLiteral( "LINESTRING(0 0, 1 0, 1 1, 0.5 0, 0 1)" ), false ); // self-tangency
|
|
geoms << qMakePair( QStringLiteral( "POINT(1 1)" ), true ); // points are simple
|
|
geoms << qMakePair( QStringLiteral( "POLYGON((0 0, 1 1, 1 1, 0 0))" ), true ); // polygons are always simple, even if they are invalid
|
|
geoms << qMakePair( QStringLiteral( "MULTIPOINT((1 1), (2 2))" ), true );
|
|
geoms << qMakePair( QStringLiteral( "MULTIPOINT((1 1), (1 1))" ), false ); // must not contain the same point twice
|
|
geoms << qMakePair( QStringLiteral( "MULTILINESTRING((0 0, 1 0), (0 1, 1 1))" ), true );
|
|
geoms << qMakePair( QStringLiteral( "MULTILINESTRING((0 0, 1 0), (0 0, 1 0))" ), true ); // may be touching at endpoints
|
|
geoms << qMakePair( QStringLiteral( "MULTILINESTRING((0 0, 1 1), (0 1, 1 0))" ), false ); // must not intersect each other
|
|
geoms << qMakePair( QStringLiteral( "MULTIPOLYGON(((0 0, 1 1, 1 1, 0 0)),((0 0, 1 1, 1 1, 0 0)))" ), true ); // multi-polygons are always simple
|
|
|
|
Q_FOREACH ( const InputWktAndExpectedResult &pair, geoms )
|
|
{
|
|
QgsGeometry gInput = QgsGeometry::fromWkt( pair.first );
|
|
QVERIFY( !gInput.isNull() );
|
|
|
|
bool res = gInput.isSimple();
|
|
QCOMPARE( res, pair.second );
|
|
}
|
|
}
|
|
|
|
void TestQgsGeometry::reshapeGeometryLineMerge()
|
|
{
|
|
int res;
|
|
QgsGeometry g2D = QgsGeometry::fromWkt( QStringLiteral( "LINESTRING(10 10, 20 20)" ) );
|
|
QgsGeometry g3D = QgsGeometry::fromWkt( QStringLiteral( "LINESTRINGZ(10 10 1, 20 20 2)" ) );
|
|
|
|
// prepare 2D reshaping line
|
|
QVector<QgsPoint> v2D_1, v2D_2;
|
|
v2D_1 << QgsPoint( 20, 20 ) << QgsPoint( 30, 30 );
|
|
v2D_2 << QgsPoint( 10, 10 ) << QgsPoint( -10, -10 );
|
|
QgsLineString line2D_1( v2D_1 ), line2D_2( v2D_2 );
|
|
|
|
// prepare 3D reshaping line
|
|
QVector<QgsPoint> v3D_1, v3D_2;
|
|
v3D_1 << QgsPoint( QgsWkbTypes::PointZ, 20, 20, 2 ) << QgsPoint( QgsWkbTypes::PointZ, 30, 30, 3 );
|
|
v3D_2 << QgsPoint( QgsWkbTypes::PointZ, 10, 10, 1 ) << QgsPoint( QgsWkbTypes::PointZ, -10, -10, -1 );
|
|
QgsLineString line3D_1( v3D_1 ), line3D_2( v3D_2 );
|
|
|
|
// append with 2D line
|
|
QgsGeometry g2D_1 = g2D;
|
|
res = g2D_1.reshapeGeometry( line2D_1 );
|
|
QCOMPARE( res, 0 );
|
|
QCOMPARE( g2D_1.exportToWkt(), QString( "LineString (10 10, 20 20, 30 30)" ) );
|
|
|
|
// prepend with 2D line
|
|
QgsGeometry g2D_2 = g2D;
|
|
res = g2D_2.reshapeGeometry( line2D_2 );
|
|
QCOMPARE( res, 0 );
|
|
QCOMPARE( g2D_2.exportToWkt(), QString( "LineString (-10 -10, 10 10, 20 20)" ) );
|
|
|
|
// append with 3D line
|
|
QgsGeometry g3D_1 = g3D;
|
|
res = g3D_1.reshapeGeometry( line3D_1 );
|
|
QCOMPARE( res, 0 );
|
|
QCOMPARE( g3D_1.exportToWkt(), QString( "LineStringZ (10 10 1, 20 20 2, 30 30 3)" ) );
|
|
|
|
// prepend with 3D line
|
|
QgsGeometry g3D_2 = g3D;
|
|
res = g3D_2.reshapeGeometry( line3D_2 );
|
|
QCOMPARE( res, 0 );
|
|
QCOMPARE( g3D_2.exportToWkt(), QString( "LineStringZ (-10 -10 -1, 10 10 1, 20 20 2)" ) );
|
|
}
|
|
|
|
void TestQgsGeometry::createCollectionOfType()
|
|
{
|
|
std::unique_ptr< QgsGeometryCollection > collect( QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::Unknown ) );
|
|
QVERIFY( !collect );
|
|
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::Point );
|
|
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiPoint );
|
|
QVERIFY( dynamic_cast< QgsMultiPointV2 *>( collect.get() ) );
|
|
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::PointM );
|
|
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiPointM );
|
|
QVERIFY( dynamic_cast< QgsMultiPointV2 *>( collect.get() ) );
|
|
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::PointZM );
|
|
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiPointZM );
|
|
QVERIFY( dynamic_cast< QgsMultiPointV2 *>( collect.get() ) );
|
|
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::PointZ );
|
|
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiPointZ );
|
|
QVERIFY( dynamic_cast< QgsMultiPointV2 *>( collect.get() ) );
|
|
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::MultiPoint );
|
|
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiPoint );
|
|
QVERIFY( dynamic_cast< QgsMultiPointV2 *>( collect.get() ) );
|
|
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::LineStringZ );
|
|
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiLineStringZ );
|
|
QVERIFY( dynamic_cast< QgsMultiLineString *>( collect.get() ) );
|
|
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::PolygonM );
|
|
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiPolygonM );
|
|
QVERIFY( dynamic_cast< QgsMultiPolygonV2 *>( collect.get() ) );
|
|
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::GeometryCollectionZ );
|
|
QCOMPARE( collect->wkbType(), QgsWkbTypes::GeometryCollectionZ );
|
|
QVERIFY( dynamic_cast< QgsGeometryCollection *>( collect.get() ) );
|
|
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::CurvePolygonM );
|
|
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiSurfaceM );
|
|
QVERIFY( dynamic_cast< QgsMultiSurface *>( collect.get() ) );
|
|
}
|
|
|
|
void TestQgsGeometry::minimalEnclosingCircle()
|
|
{
|
|
QgsGeometry geomTest;
|
|
QgsGeometry result, resultTest;
|
|
QgsPointXY center;
|
|
double radius;
|
|
|
|
// empty
|
|
result = geomTest.minimalEnclosingCircle( center, radius );
|
|
QCOMPARE( center, QgsPointXY() );
|
|
QCOMPARE( radius, 0.0 );
|
|
QCOMPARE( result, QgsGeometry() );
|
|
|
|
// caase 1
|
|
geomTest = QgsGeometry::fromPoint( QgsPointXY( 5, 5 ) );
|
|
result = geomTest.minimalEnclosingCircle( center, radius );
|
|
QCOMPARE( center, QgsPointXY( 5, 5 ) );
|
|
QCOMPARE( radius, 0.0 );
|
|
resultTest.setGeometry( QgsCircle( QgsPoint( center ), radius ).toPolygon( 36 ) );
|
|
QCOMPARE( result, resultTest );
|
|
|
|
// case 2
|
|
geomTest = QgsGeometry::fromWkt( QStringLiteral( "MULTIPOINT( 3 8, 7 4 )" ) );
|
|
result = geomTest.minimalEnclosingCircle( center, radius );
|
|
QGSCOMPARENEARPOINT( center, QgsPointXY( 5, 6 ), 0.0001 );
|
|
QGSCOMPARENEAR( radius, sqrt( 2 ) * 2, 0.0001 );
|
|
resultTest.setGeometry( QgsCircle( QgsPoint( center ), radius ).toPolygon( 36 ) );
|
|
QCOMPARE( result, resultTest );
|
|
|
|
geomTest = QgsGeometry::fromWkt( QStringLiteral( "LINESTRING( 0 5, 2 2, 0 -5, -1 -1 )" ) );
|
|
result = geomTest.minimalEnclosingCircle( center, radius );
|
|
QGSCOMPARENEARPOINT( center, QgsPointXY( 0, 0 ), 0.0001 );
|
|
QGSCOMPARENEAR( radius, 5, 0.0001 );
|
|
resultTest.setGeometry( QgsCircle( QgsPoint( center ), radius ).toPolygon( 36 ) );
|
|
QCOMPARE( result, resultTest );
|
|
|
|
geomTest = QgsGeometry::fromWkt( QStringLiteral( "MULTIPOINT( 0 5, 2 2, 0 -5, -1 -1 )" ) );
|
|
result = geomTest.minimalEnclosingCircle( center, radius );
|
|
QGSCOMPARENEARPOINT( center, QgsPointXY( 0, 0 ), 0.0001 );
|
|
QGSCOMPARENEAR( radius, 5, 0.0001 );
|
|
resultTest.setGeometry( QgsCircle( QgsPoint( center ), radius ).toPolygon( 36 ) );
|
|
QCOMPARE( result, resultTest );
|
|
|
|
geomTest = QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 0 5, 2 2, 0 -5, -1 -1 ))" ) );
|
|
result = geomTest.minimalEnclosingCircle( center, radius );
|
|
QGSCOMPARENEARPOINT( center, QgsPointXY( 0, 0 ), 0.0001 );
|
|
QGSCOMPARENEAR( radius, 5, 0.0001 );
|
|
resultTest.setGeometry( QgsCircle( QgsPoint( center ), radius ).toPolygon( 36 ) );
|
|
QCOMPARE( result, resultTest );
|
|
|
|
geomTest = QgsGeometry::fromWkt( QStringLiteral( "MULTIPOINT( 0 5, 0 -5, 0 0 )" ) );
|
|
result = geomTest.minimalEnclosingCircle( center, radius );
|
|
QGSCOMPARENEARPOINT( center, QgsPointXY( 0, 0 ), 0.0001 );
|
|
QGSCOMPARENEAR( radius, 5, 0.0001 );
|
|
resultTest.setGeometry( QgsCircle( QgsPoint( center ), radius ).toPolygon( 36 ) );
|
|
QCOMPARE( result, resultTest );
|
|
|
|
// case 3
|
|
geomTest = QgsGeometry::fromWkt( QStringLiteral( "MULTIPOINT((0 0), (5 5), (0 -5), (0 5), (-5 0))" ) );
|
|
result = geomTest.minimalEnclosingCircle( center, radius );
|
|
QGSCOMPARENEARPOINT( center, QgsPointXY( 0.8333, 0.8333 ), 0.0001 );
|
|
QGSCOMPARENEAR( radius, 5.8926, 0.0001 );
|
|
resultTest.setGeometry( QgsCircle( QgsPoint( center ), radius ).toPolygon( 36 ) );
|
|
QCOMPARE( result, resultTest );
|
|
|
|
}
|
|
|
|
|
|
QGSTEST_MAIN( TestQgsGeometry )
|
|
#include "testqgsgeometry.moc"
|