QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
qgsmultilinestring.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmultilinestring.cpp
3 -------------------------------------------------------------------
4Date : 28 Oct 2014
5Copyright : (C) 2014 by Marco Hugentobler
6email : 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 "qgsmultilinestring.h"
17#include "qgsabstractgeometry.h"
18#include "qgsapplication.h"
19#include "qgscurve.h"
20#include "qgscircularstring.h"
21#include "qgscompoundcurve.h"
22#include "qgsgeometryutils.h"
23#include "qgslinestring.h"
24#include "qgsmulticurve.h"
25
26#include <nlohmann/json.hpp>
27#include <QJsonObject>
28
33
34QgsMultiLineString::QgsMultiLineString( const QList<QgsLineString> &linestrings )
35{
36 if ( linestrings.empty() )
37 return;
38
39 mGeometries.reserve( linestrings.size() );
40 for ( const QgsLineString &line : linestrings )
41 {
42 mGeometries.append( line.clone() );
43 }
44
46}
47
48QgsMultiLineString::QgsMultiLineString( const QList<QgsLineString *> &linestrings )
49{
50 if ( linestrings.empty() )
51 return;
52
53 mGeometries.reserve( linestrings.size() );
54 for ( QgsLineString *line : linestrings )
55 {
56 mGeometries.append( line );
57 }
58
60}
61
63{
64 return qgsgeometry_cast< QgsLineString * >( geometryN( index ) );
65}
66
68{
69 return qgsgeometry_cast< const QgsLineString * >( geometryN( index ) );
70}
71
73{
74 return QStringLiteral( "MultiLineString" );
75}
76
78{
79 auto result = std::make_unique< QgsMultiLineString >();
80 result->mWkbType = mWkbType;
81 return result.release();
82}
83
85{
86 return new QgsMultiLineString( *this );
87}
88
94
95bool QgsMultiLineString::fromWkt( const QString &wkt )
96{
97 return fromCollectionWkt( wkt, QVector<QgsAbstractGeometry *>() << new QgsLineString, QStringLiteral( "LineString" ) );
98}
99
100QDomElement QgsMultiLineString::asGml2( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
101{
102 QDomElement elemMultiLineString = doc.createElementNS( ns, QStringLiteral( "MultiLineString" ) );
103
104 if ( isEmpty() )
105 return elemMultiLineString;
106
107 for ( const QgsAbstractGeometry *geom : mGeometries )
108 {
109 if ( const QgsLineString *lineString = qgsgeometry_cast<const QgsLineString *>( geom ) )
110 {
111 QDomElement elemLineStringMember = doc.createElementNS( ns, QStringLiteral( "lineStringMember" ) );
112 elemLineStringMember.appendChild( lineString->asGml2( doc, precision, ns, axisOrder ) );
113 elemMultiLineString.appendChild( elemLineStringMember );
114 }
115 }
116
117 return elemMultiLineString;
118}
119
120QDomElement QgsMultiLineString::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
121{
122 QDomElement elemMultiCurve = doc.createElementNS( ns, QStringLiteral( "MultiCurve" ) );
123
124 if ( isEmpty() )
125 return elemMultiCurve;
126
127 for ( const QgsAbstractGeometry *geom : mGeometries )
128 {
129 if ( const QgsLineString *lineString = qgsgeometry_cast<const QgsLineString *>( geom ) )
130 {
131 QDomElement elemCurveMember = doc.createElementNS( ns, QStringLiteral( "curveMember" ) );
132 elemCurveMember.appendChild( lineString->asGml3( doc, precision, ns, axisOrder ) );
133 elemMultiCurve.appendChild( elemCurveMember );
134 }
135 }
136
137 return elemMultiCurve;
138}
139
141{
142 json coordinates( json::array( ) );
143 for ( const QgsAbstractGeometry *geom : mGeometries )
144 {
145 if ( qgsgeometry_cast<const QgsCurve *>( geom ) )
146 {
147 const QgsLineString *lineString = static_cast<const QgsLineString *>( geom );
149 lineString->points( pts );
150 coordinates.push_back( QgsGeometryUtils::pointsToJson( pts, precision ) );
151 }
152 }
153 return
154 {
155 { "type", "MultiLineString" },
156 { "coordinates", coordinates }
157 };
158}
159
161{
162 if ( !dynamic_cast<QgsLineString *>( g ) )
163 {
164 delete g;
165 return false;
166 }
167
168 if ( mGeometries.empty() )
169 {
171 }
172 if ( is3D() && !g->is3D() )
173 g->addZValue();
174 else if ( !is3D() && g->is3D() )
175 g->dropZValue();
176 if ( isMeasure() && !g->isMeasure() )
177 g->addMValue();
178 else if ( !isMeasure() && g->isMeasure() )
179 g->dropMValue();
180 return QgsGeometryCollection::addGeometry( g ); // NOLINT(bugprone-parent-virtual-call) clazy:exclude=skipped-base-method
181}
182
183bool QgsMultiLineString::addGeometries( const QVector<QgsAbstractGeometry *> &geometries )
184{
185 for ( QgsAbstractGeometry *g : geometries )
186 {
187 if ( !qgsgeometry_cast<QgsLineString *>( g ) )
188 {
189 qDeleteAll( geometries );
190 return false;
191 }
192 }
193
194 if ( mGeometries.empty() && !geometries.empty() )
195 {
197 }
198 mGeometries.reserve( mGeometries.size() + geometries.size() );
199 for ( QgsAbstractGeometry *g : geometries )
200 {
201 if ( is3D() && !g->is3D() )
202 g->addZValue();
203 else if ( !is3D() && g->is3D() )
204 g->dropZValue();
205 if ( isMeasure() && !g->isMeasure() )
206 g->addMValue();
207 else if ( !isMeasure() && g->isMeasure() )
208 g->dropMValue();
209 mGeometries.append( g );
210 }
211
212 clearCache();
213 return true;
214}
215
217{
219 {
220 delete g;
221 return false;
222 }
223
224 return QgsMultiCurve::insertGeometry( g, index );
225}
226
228{
229 std::unique_ptr< QgsMultiLineString > result = std::make_unique< QgsMultiLineString >();
230 result->reserve( mGeometries.size() );
231 for ( int i = 0; i < mGeometries.size(); ++i )
232 {
233 result->addGeometry( mGeometries.at( i )->simplifyByDistance( tolerance ) );
234 }
235 return result.release();
236}
237
239{
240 QgsMultiCurve *multiCurve = new QgsMultiCurve();
241 multiCurve->reserve( mGeometries.size() );
242 for ( int i = 0; i < mGeometries.size(); ++i )
243 {
244 multiCurve->addGeometry( mGeometries.at( i )->toCurveType() );
245 }
246 return multiCurve;
247}
248
250{
251 return true;
252}
253
254QgsMultiLineString *QgsMultiLineString::measuredLine( double start, double end ) const
255{
256 std::unique_ptr< QgsMultiLineString > result = std::make_unique< QgsMultiLineString >();
257 if ( isEmpty() )
258 {
259 result->convertTo( QgsWkbTypes::addM( mWkbType ) );
260 return result.release();
261 }
262
263 /* Calculate the total length of the line */
264 const double length{this->length()};
265 const double range{end - start};
266 double lengthSoFar{0.0};
267
268 result->reserve( numGeometries() );
269 for ( int i = 0; i < numGeometries(); i++ )
270 {
271 const double subLength{geometryN( i )->length()};
272
273 const double subStart{ ( start + range *lengthSoFar / length ) };
274 const double subEnd{ ( start + range * ( lengthSoFar + subLength ) / length ) };
275
276 std::unique_ptr< QgsLineString > measuredLine = qgsgeometry_cast<QgsLineString *>( geometryN( i ) )->measuredLine( subStart, subEnd );
277 result->addGeometry( measuredLine.release() );
278
279 lengthSoFar += subLength;
280 }
281
282 return result.release();
283}
@ LineString
LineString.
@ MultiLineString
MultiLineString.
Abstract base class for all geometries.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry.
bool isMeasure() const
Returns true if the geometry contains m values.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
AxisOrder
Axis order for GML generation.
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, Qgis::WkbType baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
virtual double length() const
Returns the planar, 2-dimensional length of the geometry.
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
QVector< QgsAbstractGeometry * > mGeometries
void reserve(int size)
Attempts to allocate memory for at least size geometries.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
bool isEmpty() const override
Returns true if the geometry is empty.
double length() const override
Returns the planar, 2-dimensional length of the geometry.
virtual bool addGeometry(QgsAbstractGeometry *g)
Adds a geometry and takes ownership. Returns true in case of success.
bool fromCollectionWkt(const QString &wkt, const QVector< QgsAbstractGeometry * > &subtypes, const QString &defaultChildWkbType=QString())
Reads a collection from a WKT string.
int numGeometries() const
Returns the number of geometries within the collection.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
static json pointsToJson(const QgsPointSequence &points, int precision)
Returns coordinates as json object.
Line string geometry type, with support for z-dimension and m-values.
void points(QgsPointSequence &pt) const override
Returns a list of points within the curve.
Multi curve geometry collection.
bool insertGeometry(QgsAbstractGeometry *g, int index) override
Inserts a geometry before a specified index and takes ownership.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
void clear() override
Clears the geometry, ie reset it to a null geometry.
Multi line string geometry collection.
void clear() override
Clears the geometry, ie reset it to a null geometry.
QString geometryType() const override
Returns a unique string representing the geometry type.
bool addGeometries(const QVector< QgsAbstractGeometry * > &geometries) final
Adds a list of geometries to the collection, transferring ownership to the collection.
QgsMultiCurve * toCurveType() const override
Returns the geometry converted to the more generic curve type QgsMultiCurve.
bool wktOmitChildType() const override
Returns whether child type names are omitted from Wkt representations of the collection.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
bool insertGeometry(QgsAbstractGeometry *g, int index) override
Inserts a geometry before a specified index and takes ownership.
json asJsonObject(int precision=17) const override
Returns a json object representation of 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.
QgsMultiLineString * measuredLine(double start, double end) const
Re-write the measure ordinate (or add one, if it isn't already there) interpolating the measure betwe...
QgsMultiLineString * clone() const override
Clones the geometry by performing a deep copy.
QgsMultiLineString * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
QgsMultiLineString()
Constructor for an empty multilinestring geometry.
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
QgsMultiLineString * simplifyByDistance(double tolerance) const override
Simplifies the geometry by applying the Douglas Peucker simplification by distance algorithm.
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.
QgsLineString * lineStringN(int index)
Returns the line string with the specified index.
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
QVector< QgsPoint > QgsPointSequence
int precision