QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsmulticurve.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmulticurve.cpp
3  -------------------------------------------------------------------
4 Date : 28 Oct 2014
5 Copyright : (C) 2014 by Marco Hugentobler
6 email : marco.hugentobler at sourcepole dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsmulticurve.h"
17 #include "qgsapplication.h"
18 #include "qgscurve.h"
19 #include "qgscircularstring.h"
20 #include "qgscompoundcurve.h"
21 #include "qgsgeometryutils.h"
22 #include "qgslinestring.h"
23 #include "qgsmultipoint.h"
24 #include <memory>
25 
27 {
29 }
30 
32 {
33  return QStringLiteral( "MultiCurve" );
34 }
35 
37 {
38  auto result = qgis::make_unique< QgsMultiCurve >();
39  result->mWkbType = mWkbType;
40  return result.release();
41 }
42 
44 {
45  return new QgsMultiCurve( *this );
46 }
47 
49 {
52 }
53 
55 {
56  return clone();
57 }
58 
59 bool QgsMultiCurve::fromWkt( const QString &wkt )
60 {
61  return fromCollectionWkt( wkt,
62  QVector<QgsAbstractGeometry *>() << new QgsLineString << new QgsCircularString << new QgsCompoundCurve,
63  QStringLiteral( "LineString" ) );
64 }
65 
66 QDomElement QgsMultiCurve::asGml2( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
67 {
68  // GML2 does not support curves
69  QDomElement elemMultiLineString = doc.createElementNS( ns, QStringLiteral( "MultiLineString" ) );
70 
71  if ( isEmpty() )
72  return elemMultiLineString;
73 
74  for ( const QgsAbstractGeometry *geom : mGeometries )
75  {
76  if ( qgsgeometry_cast<const QgsCurve *>( geom ) )
77  {
78  std::unique_ptr< QgsLineString > lineString( static_cast<const QgsCurve *>( geom )->curveToLine() );
79 
80  QDomElement elemLineStringMember = doc.createElementNS( ns, QStringLiteral( "lineStringMember" ) );
81  elemLineStringMember.appendChild( lineString->asGml2( doc, precision, ns, axisOrder ) );
82  elemMultiLineString.appendChild( elemLineStringMember );
83  }
84  }
85 
86  return elemMultiLineString;
87 }
88 
89 QDomElement QgsMultiCurve::asGml3( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
90 {
91  QDomElement elemMultiCurve = doc.createElementNS( ns, QStringLiteral( "MultiCurve" ) );
92 
93  if ( isEmpty() )
94  return elemMultiCurve;
95 
96  for ( const QgsAbstractGeometry *geom : mGeometries )
97  {
98  if ( qgsgeometry_cast<const QgsCurve *>( geom ) )
99  {
100  const QgsCurve *curve = static_cast<const QgsCurve *>( geom );
101 
102  QDomElement elemCurveMember = doc.createElementNS( ns, QStringLiteral( "curveMember" ) );
103  elemCurveMember.appendChild( curve->asGml3( doc, precision, ns, axisOrder ) );
104  elemMultiCurve.appendChild( elemCurveMember );
105  }
106  }
107 
108  return elemMultiCurve;
109 }
110 
111 QString QgsMultiCurve::asJson( int precision ) const
112 {
113  // GeoJSON does not support curves
114  QString json = QStringLiteral( "{\"type\": \"MultiLineString\", \"coordinates\": [" );
115  for ( const QgsAbstractGeometry *geom : mGeometries )
116  {
117  if ( qgsgeometry_cast<const QgsCurve *>( geom ) )
118  {
119  std::unique_ptr< QgsLineString > lineString( static_cast<const QgsCurve *>( geom )->curveToLine() );
120  QgsPointSequence pts;
121  lineString->points( pts );
122  json += QgsGeometryUtils::pointsToJSON( pts, precision ) + ", ";
123  }
124  }
125  if ( json.endsWith( QLatin1String( ", " ) ) )
126  {
127  json.chop( 2 ); // Remove last ", "
128  }
129  json += QLatin1String( "] }" );
130  return json;
131 }
132 
134 {
135  if ( !qgsgeometry_cast<QgsCurve *>( g ) )
136  {
137  delete g;
138  return false;
139  }
140 
141  if ( mGeometries.empty() )
142  {
144  }
145  if ( is3D() && !g->is3D() )
146  g->addZValue();
147  else if ( !is3D() && g->is3D() )
148  g->dropZValue();
149  if ( isMeasure() && !g->isMeasure() )
150  g->addMValue();
151  else if ( !isMeasure() && g->isMeasure() )
152  g->dropMValue();
153 
155 }
156 
158 {
159  if ( !g || !qgsgeometry_cast<QgsCurve *>( g ) )
160  {
161  delete g;
162  return false;
163  }
164 
165  return QgsGeometryCollection::insertGeometry( g, index );
166 }
167 
169 {
170  QgsMultiCurve *reversedMultiCurve = new QgsMultiCurve();
171  for ( const QgsAbstractGeometry *geom : mGeometries )
172  {
173  if ( qgsgeometry_cast<const QgsCurve *>( geom ) )
174  {
175  reversedMultiCurve->addGeometry( static_cast<const QgsCurve *>( geom )->reversed() );
176  }
177  }
178  return reversedMultiCurve;
179 }
180 
182 {
183  std::unique_ptr< QgsMultiPoint > multiPoint( new QgsMultiPoint() );
184  for ( int i = 0; i < mGeometries.size(); ++i )
185  {
186  if ( QgsCurve *curve = qgsgeometry_cast<QgsCurve *>( mGeometries.at( i ) ) )
187  {
188  if ( !curve->isClosed() )
189  {
190  multiPoint->addGeometry( new QgsPoint( curve->startPoint() ) );
191  multiPoint->addGeometry( new QgsPoint( curve->endPoint() ) );
192  }
193  }
194  }
195  if ( multiPoint->numGeometries() == 0 )
196  {
197  return nullptr;
198  }
199  return multiPoint.release();
200 }
QDomElement asGml2(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML2 representation of the geometry.
static QString pointsToJSON(const QgsPointSequence &points, int precision)
Returns a geoJSON coordinates string.
int precision
QgsMultiCurve * toCurveType() const override
Returns the geometry converted to the more generic curve type.
void clear() override
Clears the geometry, ie reset it to a null geometry.
bool insertGeometry(QgsAbstractGeometry *g, int index) override
Inserts a geometry before a specified index and takes ownership.
Multi point geometry collection.
Definition: qgsmultipoint.h:29
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
QString asJson(int precision=17) const override
Returns a GeoJSON representation of the geometry.
QgsWkbTypes::Type mWkbType
virtual bool insertGeometry(QgsAbstractGeometry *g, int index)
Inserts a geometry before a specified index and takes ownership.
QgsMultiCurve * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership...
bool isEmpty() const override
Returns true if the geometry is empty.
bool isMeasure() const
Returns true if the geometry contains m values.
QgsMultiCurve * reversed() const
Returns a copy of the multi curve, where each component curve has had its line direction reversed...
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
Multi curve geometry collection.
Definition: qgsmulticurve.h:29
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
Abstract base class for all geometries.
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
QString geometryType() const override
Returns a unique string representing the geometry type.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
AxisOrder
Axis order for GML generation.
QVector< QgsPoint > QgsPointSequence
QVector< QgsAbstractGeometry * > mGeometries
QgsMultiCurve * clone() const override
Clones the geometry by performing a deep copy.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:43
void clear() override
Clears the geometry, ie reset it to a null geometry.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
Compound curve geometry type.
Circular string geometry type.
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry.
QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML3 representation of the geometry.
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
virtual QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const =0
Returns a GML3 representation of the geometry.
bool fromCollectionWkt(const QString &wkt, const QVector< QgsAbstractGeometry * > &subtypes, const QString &defaultChildWkbType=QString())
Reads a collection from a WKT string.