File indexing completed on 2024-05-12 03:50:14

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 "geodata_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 GEODATA_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