mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-15 00:07:25 -05:00
QgsMultiLineString: add method measuredLine
This commit is contained in:
parent
6cb243571f
commit
a93136c313
@ -88,6 +88,14 @@ Returns the geometry converted to the more generic curve type :py:class:`QgsMult
|
||||
sipRes = PyUnicode_FromString( str.toUtf8().constData() );
|
||||
%End
|
||||
|
||||
QgsMultiLineString *measuredLine( double start, double end );
|
||||
%Docstring
|
||||
Re-write the measure ordinate (or add one, if it isn't already there) interpolating
|
||||
the measure between the supplied ``start`` and ``end`` values.
|
||||
|
||||
.. versionadded:: 3.36
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool wktOmitChildType() const;
|
||||
|
||||
@ -14,6 +14,7 @@ email : marco.hugentobler at sourcepole dot com
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsmultilinestring.h"
|
||||
#include "qgsabstractgeometry.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgscurve.h"
|
||||
#include "qgscircularstring.h"
|
||||
@ -178,3 +179,40 @@ bool QgsMultiLineString::wktOmitChildType() const
|
||||
return true;
|
||||
}
|
||||
|
||||
QgsMultiLineString *QgsMultiLineString::measuredLine( double start, double end )
|
||||
{
|
||||
|
||||
|
||||
QgsMultiLineString *result{createEmptyWithSameType()};
|
||||
|
||||
if ( isEmpty() )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if ( !result->convertTo( QgsWkbTypes::addM( mWkbType ) ) )
|
||||
{
|
||||
qDebug() << "Impossible to convert type to M type\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Calculate the total length of the line */
|
||||
const double length{this->length()};
|
||||
const double range{end - start};
|
||||
double length_so_far{0.0};
|
||||
|
||||
result->reserve( numGeometries() );
|
||||
for ( int i = 0; i < numGeometries(); i++ )
|
||||
{
|
||||
const double sub_length{geometryN( i )->length()};
|
||||
|
||||
const double sub_start{ ( start + range *length_so_far / length ) };
|
||||
const double sub_end{ ( start + range * ( length_so_far + sub_length ) / length ) };
|
||||
|
||||
result->addGeometry( qgsgeometry_cast<QgsLineString *>( geometryN( i ) )->measuredLine( sub_start, sub_end ) );
|
||||
|
||||
length_so_far += sub_length;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -127,6 +127,14 @@ class CORE_EXPORT QgsMultiLineString: public QgsMultiCurve
|
||||
% End
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Re-write the measure ordinate (or add one, if it isn't already there) interpolating
|
||||
* the measure between the supplied \a start and \a end values.
|
||||
*
|
||||
* \since QGIS 3.36
|
||||
*/
|
||||
QgsMultiLineString *measuredLine( double start, double end );
|
||||
|
||||
protected:
|
||||
|
||||
bool wktOmitChildType() const override;
|
||||
|
||||
@ -175,6 +175,7 @@ ADD_PYTHON_TEST(PyQgsMetadataBase test_qgsmetadatabase.py)
|
||||
ADD_PYTHON_TEST(PyQgsMetadataUtils test_qgsmetadatautils.py)
|
||||
ADD_PYTHON_TEST(PyQgsMemoryProvider test_provider_memory.py)
|
||||
ADD_PYTHON_TEST(PyQgsMeshLayerProfileGenerator test_qgsmeshlayerprofilegenerator.py)
|
||||
ADD_PYTHON_TEST(PyQgsMultiLineString test_qgsmultilinestring.py)
|
||||
ADD_PYTHON_TEST(PyQgsMssqlSqlQueryBuilder test_qgsmssqlsqlquerybuilder.py)
|
||||
ADD_PYTHON_TEST(PyQgsNetworkAccessManager test_qgsnetworkaccessmanager.py)
|
||||
ADD_PYTHON_TEST(PyQgsNetworkContentFetcher test_qgsnetworkcontentfetcher.py)
|
||||
|
||||
@ -27,18 +27,22 @@ class TestQgsLineString(QgisTestCase):
|
||||
self.assertEqual(line.endPoint(), QgsPoint(3, 4))
|
||||
|
||||
# With list
|
||||
line = QgsLineString([ [1, 2], [3, 4] ])
|
||||
line = QgsLineString([[1, 2], [3, 4]])
|
||||
self.assertEqual(line.startPoint(), QgsPoint(1, 2))
|
||||
self.assertEqual(line.endPoint(), QgsPoint(3, 4))
|
||||
|
||||
def testMeasureLine(self):
|
||||
line = QgsLineString([ [0, 0], [2, 0], [4, 0]])
|
||||
line = QgsLineString()
|
||||
m_line = line.measuredLine(10, 20)
|
||||
self.assertEqual(m_line, QgsLineString([QgsPoint(0, 0, m=10),QgsPoint(2, 0, m=15) ,QgsPoint(4, 0, m=20) ]))
|
||||
self.assertEqual(m_line, QgsLineString())
|
||||
|
||||
line = QgsLineString([ [0, 0], [9, 0], [10, 0]])
|
||||
line = QgsLineString([[0, 0], [2, 0], [4, 0]])
|
||||
m_line = line.measuredLine(10, 20)
|
||||
self.assertEqual(m_line, QgsLineString([QgsPoint(0, 0, m=10),QgsPoint(9, 0, m=19) ,QgsPoint(10, 0, m=20) ]))
|
||||
self.assertEqual(m_line, QgsLineString([QgsPoint(0, 0, m=10), QgsPoint(2, 0, m=15), QgsPoint(4, 0, m=20)]))
|
||||
|
||||
line = QgsLineString([[0, 0], [9, 0], [10, 0]])
|
||||
m_line = line.measuredLine(10, 20)
|
||||
self.assertEqual(m_line, QgsLineString([QgsPoint(0, 0, m=10), QgsPoint(9, 0, m=19), QgsPoint(10, 0, m=20)]))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
56
tests/src/python/test_qgsmultilinestring.py
Normal file
56
tests/src/python/test_qgsmultilinestring.py
Normal file
@ -0,0 +1,56 @@
|
||||
"""QGIS Unit tests for QgsMultiLineString.
|
||||
|
||||
.. note:: This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
"""
|
||||
__author__ = 'Loïc Bartoletti'
|
||||
__date__ = '12/12/2023'
|
||||
__copyright__ = 'Copyright 2023, The QGIS Project'
|
||||
|
||||
import qgis # NOQA
|
||||
|
||||
from qgis.core import QgsMultiLineString, QgsLineString, QgsPoint
|
||||
import unittest
|
||||
from qgis.testing import start_app, QgisTestCase
|
||||
|
||||
start_app()
|
||||
|
||||
|
||||
class TestQgsLineString(QgisTestCase):
|
||||
|
||||
def testConstruct(self):
|
||||
# With list
|
||||
line = QgsLineString([QgsPoint(1, 2), QgsPoint(3, 4)])
|
||||
multiline = QgsMultiLineString()
|
||||
multiline.addGeometry(line)
|
||||
self.assertEqual(multiline.numGeometries(), 1)
|
||||
line = multiline.geometryN(0)
|
||||
self.assertEqual(line.startPoint(), QgsPoint(1, 2))
|
||||
self.assertEqual(line.endPoint(), QgsPoint(3, 4))
|
||||
|
||||
def testMeasureLine(self):
|
||||
multiline = QgsMultiLineString()
|
||||
m_line = multiline.measuredLine(10, 20)
|
||||
self.assertEqual(m_line, QgsMultiLineString())
|
||||
|
||||
multiline.addGeometry(QgsLineString([[0, 0], [2, 0], [4, 0]]))
|
||||
m_line = multiline.measuredLine(10, 20)
|
||||
self.assertEqual(m_line.geometryN(0), QgsLineString([QgsPoint(0, 0, m=10), QgsPoint(2, 0, m=15), QgsPoint(4, 0, m=20)]))
|
||||
|
||||
multiline = QgsMultiLineString()
|
||||
multiline.addGeometry(QgsLineString([[0, 0], [9, 0], [10, 0]]))
|
||||
m_line = multiline.measuredLine(10, 20)
|
||||
self.assertEqual(m_line.geometryN(0), QgsLineString([QgsPoint(0, 0, m=10), QgsPoint(9, 0, m=19), QgsPoint(10, 0, m=20)]))
|
||||
|
||||
multiline = QgsMultiLineString()
|
||||
multiline.addGeometry(QgsLineString([[1, 0], [3, 0], [4, 0]]))
|
||||
multiline.addGeometry(QgsLineString([[0, 0], [9, 0], [10, 0]]))
|
||||
m_line = multiline.measuredLine(10, 20)
|
||||
self.assertEqual(m_line.numGeometries(), 2)
|
||||
self.assertEqual(m_line.asWkt(0), "MultiLineStringM ((1 0 10, 3 0 12, 4 0 12),(0 0 12, 9 0 19, 10 0 20))")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Loading…
x
Reference in New Issue
Block a user