QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsmultipoint.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmultipoint.cpp
3  -------------------------------------------------------------------
4 Date : 29 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 "qgsmultipoint.h"
17 #include "qgsapplication.h"
18 #include "qgsgeometryutils.h"
19 #include "qgspoint.h"
20 #include "qgswkbptr.h"
21 
23 {
25 }
26 
28 {
29  return QStringLiteral( "MultiPoint" );
30 }
31 
33 {
34  auto result = qgis::make_unique< QgsMultiPoint >();
35  result->mWkbType = mWkbType;
36  return result.release();
37 }
38 
40 {
41  return new QgsMultiPoint( *this );
42 }
43 
45 {
46  return clone();
47 }
48 
49 bool QgsMultiPoint::fromWkt( const QString &wkt )
50 {
51  QString collectionWkt( wkt );
52  //test for non-standard MultiPoint(x1 y1, x2 y2) format
53  QRegExp regex( "^\\s*MultiPoint\\s*[ZM]*\\s*\\(\\s*[-\\d]" );
54  regex.setCaseSensitivity( Qt::CaseInsensitive );
55  if ( regex.indexIn( collectionWkt ) >= 0 )
56  {
57  //alternate style without extra brackets, upgrade to standard
58  collectionWkt.replace( '(', QLatin1String( "((" ) ).replace( ')', QLatin1String( "))" ) ).replace( ',', QLatin1String( "),(" ) );
59  }
60 
61  return fromCollectionWkt( collectionWkt, QVector<QgsAbstractGeometry *>() << new QgsPoint, QStringLiteral( "Point" ) );
62 }
63 
65 {
68 }
69 
70 QDomElement QgsMultiPoint::asGml2( QDomDocument &doc, int precision, const QString &ns, const AxisOrder axisOrder ) const
71 {
72  QDomElement elemMultiPoint = doc.createElementNS( ns, QStringLiteral( "MultiPoint" ) );
73 
74  if ( isEmpty() )
75  return elemMultiPoint;
76 
77  for ( const QgsAbstractGeometry *geom : mGeometries )
78  {
79  if ( qgsgeometry_cast<const QgsPoint *>( geom ) )
80  {
81  QDomElement elemPointMember = doc.createElementNS( ns, QStringLiteral( "pointMember" ) );
82  elemPointMember.appendChild( geom->asGml2( doc, precision, ns, axisOrder ) );
83  elemMultiPoint.appendChild( elemPointMember );
84  }
85  }
86 
87  return elemMultiPoint;
88 }
89 
90 QDomElement QgsMultiPoint::asGml3( QDomDocument &doc, int precision, const QString &ns, const QgsAbstractGeometry::AxisOrder axisOrder ) const
91 {
92  QDomElement elemMultiPoint = doc.createElementNS( ns, QStringLiteral( "MultiPoint" ) );
93 
94  if ( isEmpty() )
95  return elemMultiPoint;
96 
97  for ( const QgsAbstractGeometry *geom : mGeometries )
98  {
99  if ( qgsgeometry_cast<const QgsPoint *>( geom ) )
100  {
101  QDomElement elemPointMember = doc.createElementNS( ns, QStringLiteral( "pointMember" ) );
102  elemPointMember.appendChild( geom->asGml3( doc, precision, ns, axisOrder ) );
103  elemMultiPoint.appendChild( elemPointMember );
104  }
105  }
106 
107  return elemMultiPoint;
108 }
109 
110 QString QgsMultiPoint::asJson( int precision ) const
111 {
112  QString json = QStringLiteral( "{\"type\": \"MultiPoint\", \"coordinates\": " );
113 
114  QgsPointSequence pts;
115  for ( const QgsAbstractGeometry *geom : mGeometries )
116  {
117  if ( qgsgeometry_cast<const QgsPoint *>( geom ) )
118  {
119  const QgsPoint *point = static_cast<const QgsPoint *>( geom );
120  pts << *point;
121  }
122  }
123  json += QgsGeometryUtils::pointsToJSON( pts, precision );
124  json += QLatin1String( " }" );
125  return json;
126 }
127 
129 {
130  return mGeometries.size();
131 }
132 
134 {
135  if ( !qgsgeometry_cast<QgsPoint *>( g ) )
136  {
137  delete g;
138  return false;
139  }
140  if ( mGeometries.empty() )
141  {
143  }
144  if ( is3D() && !g->is3D() )
145  g->addZValue();
146  else if ( !is3D() && g->is3D() )
147  g->dropZValue();
148  if ( isMeasure() && !g->isMeasure() )
149  g->addMValue();
150  else if ( !isMeasure() && g->isMeasure() )
151  g->dropMValue();
152 
154 }
155 
157 {
158  if ( !g || QgsWkbTypes::flatType( g->wkbType() ) != QgsWkbTypes::Point )
159  {
160  delete g;
161  return false;
162  }
163 
164  return QgsGeometryCollection::insertGeometry( g, index );
165 }
166 
168 {
169  return nullptr;
170 }
171 
173 {
174  if ( id.part < 0 || id.part >= mGeometries.count() || id.vertex != 0 || id.ring != 0 )
175  return -1;
176 
177  return id.part; // can shortcut the calculation, since each part will have 1 vertex
178 }
179 
181 {
182  return 0.0;
183 }
184 
185 void QgsMultiPoint::filterVertices( const std::function<bool ( const QgsPoint & )> &filter )
186 {
187  mGeometries.erase( std::remove_if( mGeometries.begin(), mGeometries.end(), // clazy:exclude=detaching-member
188  [&filter]( const QgsAbstractGeometry * part )
189  {
190  if ( const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( part ) )
191  {
192  if ( !filter( *point ) )
193  {
194  delete point;
195  return true;
196  }
197  else
198  {
199  return false;
200  }
201  }
202  else
203  {
204  delete part;
205  return true;
206  }
207  } ), mGeometries.end() ); // clazy:exclude=detaching-member
208 }
209 
211 {
212  return true;
213 }
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
static QString pointsToJSON(const QgsPointSequence &points, int precision)
Returns a geoJSON coordinates string.
int precision
QgsMultiPoint * clone() const override
Clones the geometry by performing a deep copy.
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.
void filterVertices(const std::function< bool(const QgsPoint &) > &filter) override
Filters the vertices from the geometry in place, removing any which do not return true for the filter...
Multi point geometry collection.
Definition: qgsmultipoint.h:29
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
QgsWkbTypes::Type mWkbType
virtual bool insertGeometry(QgsAbstractGeometry *g, int index)
Inserts a geometry before a specified index and takes ownership.
bool isEmpty() const override
Returns true if the geometry is empty.
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.
bool isMeasure() const
Returns true if the geometry contains m values.
Utility class for identifying a unique vertex within a geometry.
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
Abstract base class for all geometries.
QString asJson(int precision=17) const override
Returns a GeoJSON representation of the geometry.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
AxisOrder
Axis order for GML generation.
QgsMultiPoint * toCurveType() const override
Returns the geometry converted to the more generic curve type.
QVector< QgsPoint > QgsPointSequence
bool addGeometry(QgsAbstractGeometry *g) override
Adds a geometry and takes ownership. Returns true in case of success.
QVector< QgsAbstractGeometry * > mGeometries
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
int vertexNumberFromVertexId(QgsVertexId id) const override
Returns the vertex number corresponding to a vertex id.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
double segmentLength(QgsVertexId startVertex) const override
Returns the length of the segment of the geometry which begins at startVertex.
bool wktOmitChildType() const override
Returns whether child type names are omitted from Wkt representations of the collection.
QgsMultiPoint * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership...
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry.
QString geometryType() const override
Returns a unique string representing the geometry type.
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:565
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
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.
virtual bool addGeometry(QgsAbstractGeometry *g)
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.
bool fromCollectionWkt(const QString &wkt, const QVector< QgsAbstractGeometry * > &subtypes, const QString &defaultChildWkbType=QString())
Reads a collection from a WKT string.