File indexing completed on 2025-01-05 03:58:57
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2008-2009 Torsten Rahn <tackat@kde.org> 0004 // SPDX-FileCopyrightText: 2009 Patrick Spendrin <ps_ml@gmx.de> 0005 // 0006 0007 0008 #ifndef MARBLE_GEODATALINESTRING_H 0009 #define MARBLE_GEODATALINESTRING_H 0010 0011 #include <QVector> 0012 #include <QMetaType> 0013 0014 #include "MarbleGlobal.h" 0015 0016 #include "digikam_export.h" 0017 #include "GeoDataGeometry.h" 0018 0019 0020 namespace Marble 0021 { 0022 class GeoDataCoordinates; 0023 class GeoDataLineStringPrivate; 0024 0025 /*! 0026 \class GeoDataLineString 0027 \brief A LineString that allows to store a contiguous set of line segments. 0028 0029 GeoDataLineString is a tool class that implements the LineString tag/class 0030 of the Open Geospatial Consortium standard KML 2.2. 0031 0032 GeoDataLineString extends GeoDataGeometry to store and edit 0033 LineStrings. 0034 0035 In the QPainter API "pure" LineStrings are also referred to as "polylines". 0036 As such they are similar to the outline of a non-closed QPolygon. 0037 0038 Whenever a LineString is painted GeoDataLineStyle should be used to assign a 0039 color and line width. 0040 0041 A GeoDataLineString consists of several (geodetic) nodes which are each 0042 connected through line segments. The nodes are stored as GeoDataCoordinates 0043 objects. 0044 0045 The API which provides access to the nodes is similar to the API of 0046 QVector. 0047 0048 GeoDataLineString allows LineStrings to be tessellated in order to make them 0049 follow the terrain and the curvature of the earth. The tessellation options 0050 allow for different ways of visualization: 0051 0052 \li Not tessellated: A LineString that connects each two nodes directly and 0053 straight in screen coordinate space. 0054 \li A tessellated line: Each line segment is bent so that the LineString 0055 follows the curvature of the earth and its terrain. A tessellated 0056 line segment connects two nodes at the shortest possible distance 0057 ("along great circles"). 0058 \li A tessellated line that follows latitude circles whenever possible: 0059 In this case Latitude circles are followed as soon as two subsequent 0060 nodes have exactly the same amount of latitude. In all other places the 0061 line segments follow great circles. 0062 0063 Some convenience methods have been added that allow to calculate the 0064 geodesic bounding box or the length of a LineString. 0065 */ 0066 0067 class DIGIKAM_EXPORT GeoDataLineString : public GeoDataGeometry 0068 { 0069 0070 public: 0071 using Iterator = QVector<GeoDataCoordinates>::Iterator; 0072 using ConstIterator = QVector<GeoDataCoordinates>::ConstIterator; 0073 using const_iterator = QVector<GeoDataCoordinates>::const_iterator; 0074 0075 0076 /*! 0077 \brief Creates a new LineString. 0078 */ 0079 explicit GeoDataLineString( TessellationFlags f = NoTessellation ); 0080 0081 0082 /*! 0083 \brief Creates a LineString from an existing geometry object. 0084 */ 0085 explicit GeoDataLineString( const GeoDataGeometry &other ); 0086 0087 0088 /*! 0089 \brief Destroys a LineString. 0090 */ 0091 ~GeoDataLineString() override; 0092 0093 const char *nodeType() const override; 0094 0095 EnumGeometryId geometryId() const override; 0096 0097 GeoDataGeometry *copy() const override; 0098 0099 /*! 0100 \brief Returns whether a LineString is a closed polygon. 0101 0102 \return <code>false</code> if the LineString is not a LinearRing. 0103 */ 0104 virtual bool isClosed() const; 0105 0106 0107 /*! 0108 \brief Returns whether the LineString follows the earth's surface. 0109 0110 \return <code>true</code> if the LineString's line segments follow the 0111 earth's surface and terrain along great circles. 0112 */ 0113 bool tessellate() const; 0114 0115 0116 /*! 0117 \brief Sets the tessellation property for the LineString. 0118 0119 If \a tessellate is <code>true</code> then the LineString's line segments 0120 are bent and follow the earth's surface and terrain along great circles. 0121 If \a tessellate is <code>false</code> then the LineString's line segments 0122 are rendered as straight lines in screen coordinate space. 0123 */ 0124 void setTessellate( bool tessellate ); 0125 0126 0127 /*! 0128 \brief Returns the tessellation flags for a LineString. 0129 */ 0130 TessellationFlags tessellationFlags() const; 0131 0132 0133 /*! 0134 \brief Sets the given tessellation flags for a LineString. 0135 */ 0136 void setTessellationFlags( TessellationFlags f ); 0137 0138 /*! 0139 \brief Reverses the LineString. 0140 @since 0.26.0 0141 */ 0142 void reverse(); 0143 0144 /*! 0145 \brief Returns the smallest latLonAltBox that contains the LineString. 0146 0147 \see GeoDataLatLonAltBox 0148 */ 0149 0150 const GeoDataLatLonAltBox& latLonAltBox() const override; 0151 0152 /** 0153 * @brief Returns the length of LineString across a sphere starting from a coordinate in LineString 0154 * This method can be used as an approximation for distances along LineStrings. 0155 * The unit used for the resulting length matches the unit of the planet 0156 * radius. 0157 * @param planetRadius radius of the sphere 0158 * @param offset position of coordinate within LineString 0159 */ 0160 virtual qreal length( qreal planetRadius, int offset = 0 ) const; 0161 0162 /*! 0163 \brief Provides a more generic representation of the LineString. 0164 0165 The LineString is normalized, and pole corrected. 0166 0167 Deprecation Warning: This method will likely be removed from the public API. 0168 */ 0169 virtual GeoDataLineString toRangeCorrected() const; 0170 0171 0172 /*! 0173 \brief The line string with nodes that have proper longitude/latitude ranges. 0174 0175 \return A LineString that resembles the original linestring with nodes that 0176 have longitude values between -180 and +180 deg and that 0177 feature latitude values between -90 and +90 deg. 0178 0179 Deprecation Warning: This method will likely be removed from the public API. 0180 */ 0181 virtual GeoDataLineString toNormalized() const; 0182 0183 0184 /*! 0185 \brief The line string with more generic pole values. 0186 0187 \return A LineString that resembles the original linestring. Nodes that 0188 represent one of the poles are duplicated to allow for a better 0189 visualization of flat projections. 0190 0191 Deprecation Warning: This method will likely be removed from the public API. 0192 */ 0193 virtual GeoDataLineString toPoleCorrected() const; 0194 0195 0196 /*! 0197 \brief The line string corrected for date line crossing. 0198 0199 \return A set of LineStrings that don't cross the dateline and which 0200 resemble the original linestring. 0201 0202 Deprecation Warning: This method will likely be removed from the public API. 0203 */ 0204 virtual QVector<GeoDataLineString*> toDateLineCorrected() const; 0205 0206 0207 0208 // "Reimplementation" of QVector API 0209 /*! 0210 \brief Returns whether the LineString has no nodes at all. 0211 0212 \return <code>true</code> if there are no nodes inside the line string. 0213 */ 0214 bool isEmpty() const; 0215 0216 0217 /*! 0218 \brief Returns the number of nodes in a LineString. 0219 */ 0220 int size() const; 0221 0222 0223 /*! 0224 \brief Returns a reference to the coordinates of a node at a given position. 0225 This method detaches the returned coordinate object from the line string. 0226 */ 0227 GeoDataCoordinates& at( int pos ); 0228 0229 0230 /*! 0231 \brief Returns a reference to the coordinates of a node at a given position. 0232 This method does not detach the returned coordinate object from the line string. 0233 */ 0234 const GeoDataCoordinates& at( int pos ) const; 0235 0236 0237 /*! 0238 \brief Returns a reference to the coordinates of a node at a given position. 0239 This method detaches the returned coordinate object from the line string. 0240 */ 0241 GeoDataCoordinates& operator[]( int pos ); 0242 0243 0244 /** 0245 Returns a sub-string which contains elements from this vector, starting at position pos. If length is -1 0246 (the default), all elements after pos are included; otherwise length elements (or all remaining elements if 0247 there are less than length elements) are included. 0248 */ 0249 GeoDataLineString mid(int pos, int length = -1) const; 0250 0251 /*! 0252 \brief Returns a reference to the coordinates of a node at a given position. 0253 This method does not detach the returned coordinate object from the line string. 0254 */ 0255 const GeoDataCoordinates& operator[]( int pos ) const; 0256 0257 0258 /*! 0259 \brief Returns a reference to the first node in the LineString. 0260 This method detaches the returned coordinate object from the line string. 0261 */ 0262 GeoDataCoordinates& first(); 0263 0264 0265 /*! 0266 \brief Returns a reference to the first node in the LineString. 0267 This method does not detach the returned coordinate object from the line string. 0268 */ 0269 const GeoDataCoordinates& first() const; 0270 0271 0272 /*! 0273 \brief Returns a reference to the last node in the LineString. 0274 This method detaches the returned coordinate object from the line string. 0275 */ 0276 GeoDataCoordinates& last(); 0277 0278 0279 /*! 0280 \brief Returns a reference to the last node in the LineString. 0281 This method does not detach the returned coordinate object from the line string. 0282 */ 0283 const GeoDataCoordinates& last() const; 0284 0285 0286 /*! 0287 \brief Inserts a new node at the given index. 0288 */ 0289 void insert( int index, const GeoDataCoordinates& value ); 0290 0291 /*! 0292 \brief Attempts to allocate memory for at least \a size coordinates. 0293 */ 0294 void reserve(int size); 0295 0296 /*! 0297 \brief Appends a given geodesic position as a new node to the LineString. 0298 */ 0299 void append ( const GeoDataCoordinates& value ); 0300 0301 0302 /*! 0303 \brief Appends a given geodesic position as new nodes to the LineString. 0304 */ 0305 void append(const QVector<GeoDataCoordinates>& values); 0306 0307 0308 /*! 0309 \brief Appends a given geodesic position as a new node to the LineString. 0310 */ 0311 GeoDataLineString& operator << ( const GeoDataCoordinates& value ); 0312 0313 0314 /*! 0315 \brief Appends a given LineString to the end of the LineString. 0316 */ 0317 GeoDataLineString& operator << ( const GeoDataLineString& lineString ); 0318 0319 0320 /*! 0321 \brief Returns true/false depending on whether this and other are/are not equal. 0322 */ 0323 bool operator==( const GeoDataLineString &other ) const; 0324 bool operator!=( const GeoDataLineString &other ) const; 0325 0326 0327 /*! 0328 \brief Returns an iterator that points to the begin of the LineString. 0329 */ 0330 QVector<GeoDataCoordinates>::Iterator begin(); 0331 QVector<GeoDataCoordinates>::ConstIterator begin() const; 0332 0333 0334 /*! 0335 \brief Returns an iterator that points to the end of the LineString. 0336 */ 0337 QVector<GeoDataCoordinates>::Iterator end(); 0338 QVector<GeoDataCoordinates>::ConstIterator end() const; 0339 0340 0341 /*! 0342 \brief Returns a const iterator that points to the begin of the LineString. 0343 */ 0344 QVector<GeoDataCoordinates>::ConstIterator constBegin() const; 0345 0346 0347 /*! 0348 \brief Returns a const iterator that points to the end of the LineString. 0349 */ 0350 QVector<GeoDataCoordinates>::ConstIterator constEnd() const; 0351 0352 0353 /*! 0354 \brief Destroys all nodes in a LineString. 0355 */ 0356 void clear(); 0357 0358 0359 /*! 0360 \brief Removes the node at the given position and returns it. 0361 */ 0362 QVector<GeoDataCoordinates>::Iterator erase ( const QVector<GeoDataCoordinates>::Iterator& position ); 0363 0364 0365 /*! 0366 \brief Removes the nodes within the given range and returns them. 0367 */ 0368 QVector<GeoDataCoordinates>::Iterator erase ( const QVector<GeoDataCoordinates>::Iterator& begin, 0369 const QVector<GeoDataCoordinates>::Iterator& end ); 0370 0371 0372 /*! 0373 \brief Removes the node at the given position and destroys it. 0374 */ 0375 void remove ( int i ); 0376 0377 /*! 0378 \brief Returns a linestring with detail values assigned to each node. 0379 */ 0380 GeoDataLineString optimized() const; 0381 0382 /*! 0383 \brief Returns a javascript-style list (that can be used e.g. with the QML GeoPolyline element). 0384 */ 0385 QVariantList toVariantList() const; 0386 0387 // Serialization 0388 /*! 0389 \brief Serialize the LineString to a stream. 0390 \param stream the stream. 0391 */ 0392 void pack( QDataStream& stream ) const override; 0393 0394 0395 /*! 0396 \brief Unserialize the LineString from a stream. 0397 \param stream the stream. 0398 */ 0399 void unpack( QDataStream& stream ) override; 0400 0401 protected: 0402 explicit GeoDataLineString(GeoDataLineStringPrivate* priv); 0403 0404 private: 0405 Q_DECLARE_PRIVATE(GeoDataLineString) 0406 }; 0407 0408 } 0409 0410 Q_DECLARE_METATYPE( Marble::GeoDataLineString ) 0411 0412 #endif