mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-27 00:33:48 -05:00
Optimise and simplify tie point calculation
This commit is contained in:
parent
8a68a410bf
commit
ae8dc1cfb3
@ -89,20 +89,20 @@ template <typename RandIter, typename Type, typename CompareOp > RandIter my_bin
|
|||||||
|
|
||||||
struct TiePointInfo
|
struct TiePointInfo
|
||||||
{
|
{
|
||||||
|
TiePointInfo() = default;
|
||||||
|
TiePointInfo( QgsFeatureId featureId, const QgsPointXY &start, const QgsPointXY &end )
|
||||||
|
: mNetworkFeatureId( featureId )
|
||||||
|
, mFirstPoint( start )
|
||||||
|
, mLastPoint( end )
|
||||||
|
{}
|
||||||
|
|
||||||
QgsPointXY mTiedPoint;
|
QgsPointXY mTiedPoint;
|
||||||
double mLength;
|
double mLength = DBL_MAX;
|
||||||
|
QgsFeatureId mNetworkFeatureId = -1;
|
||||||
QgsPointXY mFirstPoint;
|
QgsPointXY mFirstPoint;
|
||||||
QgsPointXY mLastPoint;
|
QgsPointXY mLastPoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TiePointInfoCompare( const TiePointInfo &a, const TiePointInfo &b )
|
|
||||||
{
|
|
||||||
if ( a.mFirstPoint == b.mFirstPoint )
|
|
||||||
return a.mLastPoint.x() == b.mLastPoint.x() ? a.mLastPoint.y() < b.mLastPoint.y() : a.mLastPoint.x() < b.mLastPoint.x();
|
|
||||||
|
|
||||||
return a.mFirstPoint.x() == b.mFirstPoint.x() ? a.mFirstPoint.y() < b.mFirstPoint.y() : a.mFirstPoint.x() < b.mFirstPoint.x();
|
|
||||||
}
|
|
||||||
|
|
||||||
QgsVectorLayerDirector::QgsVectorLayerDirector( QgsFeatureSource *source,
|
QgsVectorLayerDirector::QgsVectorLayerDirector( QgsFeatureSource *source,
|
||||||
int directionFieldId,
|
int directionFieldId,
|
||||||
const QString &directDirectionValue,
|
const QString &directDirectionValue,
|
||||||
@ -157,11 +157,7 @@ void QgsVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, const
|
|||||||
|
|
||||||
snappedPoints = QVector< QgsPointXY >( additionalPoints.size(), QgsPointXY( 0.0, 0.0 ) );
|
snappedPoints = QVector< QgsPointXY >( additionalPoints.size(), QgsPointXY( 0.0, 0.0 ) );
|
||||||
|
|
||||||
TiePointInfo tmpInfo;
|
QVector< TiePointInfo > additionalTiePoints( additionalPoints.size() );
|
||||||
tmpInfo.mLength = std::numeric_limits<double>::infinity();
|
|
||||||
|
|
||||||
QVector< TiePointInfo > pointLengthMap( additionalPoints.size(), tmpInfo );
|
|
||||||
QVector< TiePointInfo >::iterator pointLengthIt;
|
|
||||||
|
|
||||||
//Graph's points;
|
//Graph's points;
|
||||||
QVector< QgsPointXY > points;
|
QVector< QgsPointXY > points;
|
||||||
@ -199,7 +195,7 @@ void QgsVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, const
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
for ( i = 0; i != additionalPoints.size(); ++i )
|
for ( i = 0; i != additionalPoints.size(); ++i )
|
||||||
{
|
{
|
||||||
TiePointInfo info;
|
TiePointInfo info( feature.id(), pt1, pt2 );
|
||||||
if ( pt1 == pt2 )
|
if ( pt1 == pt2 )
|
||||||
{
|
{
|
||||||
info.mLength = additionalPoints[ i ].sqrDist( pt1 );
|
info.mLength = additionalPoints[ i ].sqrDist( pt1 );
|
||||||
@ -211,12 +207,9 @@ void QgsVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, const
|
|||||||
pt2.x(), pt2.y(), info.mTiedPoint );
|
pt2.x(), pt2.y(), info.mTiedPoint );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pointLengthMap[ i ].mLength > info.mLength )
|
if ( additionalTiePoints[ i ].mLength > info.mLength )
|
||||||
{
|
{
|
||||||
info.mFirstPoint = pt1;
|
additionalTiePoints[ i ] = info;
|
||||||
info.mLastPoint = pt2;
|
|
||||||
|
|
||||||
pointLengthMap[ i ] = info;
|
|
||||||
snappedPoints[ i ] = info.mTiedPoint;
|
snappedPoints[ i ] = info.mTiedPoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,10 +224,15 @@ void QgsVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// end: tie points to graph
|
QHash< QgsFeatureId, QList< int > > tiePointNetworkFeatures;
|
||||||
|
int i = 0;
|
||||||
|
for ( TiePointInfo &info : additionalTiePoints )
|
||||||
|
{
|
||||||
|
tiePointNetworkFeatures[ info.mNetworkFeatureId ] << i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
// add tied point to graph
|
// add tied point to graph
|
||||||
int i = 0;
|
|
||||||
for ( i = 0; i < snappedPoints.size(); ++i )
|
for ( i = 0; i < snappedPoints.size(); ++i )
|
||||||
{
|
{
|
||||||
if ( snappedPoints[ i ] != QgsPointXY( 0.0, 0.0 ) )
|
if ( snappedPoints[ i ] != QgsPointXY( 0.0, 0.0 ) )
|
||||||
@ -255,8 +253,6 @@ void QgsVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, const
|
|||||||
for ( i = 0; i < snappedPoints.size() ; ++i )
|
for ( i = 0; i < snappedPoints.size() ; ++i )
|
||||||
snappedPoints[ i ] = *( my_binary_search( points.begin(), points.end(), snappedPoints[ i ], pointCompare ) );
|
snappedPoints[ i ] = *( my_binary_search( points.begin(), points.end(), snappedPoints[ i ], pointCompare ) );
|
||||||
|
|
||||||
std::sort( pointLengthMap.begin(), pointLengthMap.end(), TiePointInfoCompare );
|
|
||||||
|
|
||||||
// begin graph construction
|
// begin graph construction
|
||||||
fit = mSource->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( requiredAttributes() ) );
|
fit = mSource->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( requiredAttributes() ) );
|
||||||
while ( fit.nextFeature( feature ) )
|
while ( fit.nextFeature( feature ) )
|
||||||
@ -307,27 +303,15 @@ void QgsVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, const
|
|||||||
pointsOnArc[ 0.0 ] = pt1;
|
pointsOnArc[ 0.0 ] = pt1;
|
||||||
pointsOnArc[ pt1.sqrDist( pt2 )] = pt2;
|
pointsOnArc[ pt1.sqrDist( pt2 )] = pt2;
|
||||||
|
|
||||||
TiePointInfo t;
|
const QList< int > tiePointsForCurrentFeature = tiePointNetworkFeatures.value( feature.id() );
|
||||||
t.mFirstPoint = pt1;
|
if ( !tiePointsForCurrentFeature.empty() )
|
||||||
t.mLastPoint = pt2;
|
|
||||||
t.mLength = 0.0;
|
|
||||||
pointLengthIt = my_binary_search( pointLengthMap.begin(), pointLengthMap.end(), t, TiePointInfoCompare );
|
|
||||||
|
|
||||||
if ( pointLengthIt != pointLengthMap.end() )
|
|
||||||
{
|
{
|
||||||
QVector< TiePointInfo >::iterator it;
|
for ( int tiePointIdx : tiePointsForCurrentFeature )
|
||||||
for ( it = pointLengthIt; it - pointLengthMap.begin() >= 0; --it )
|
|
||||||
{
|
{
|
||||||
if ( it->mFirstPoint == pt1 && it->mLastPoint == pt2 )
|
const TiePointInfo &t = additionalTiePoints.at( tiePointIdx );
|
||||||
|
if ( t.mFirstPoint == pt1 && t.mLastPoint == pt2 )
|
||||||
{
|
{
|
||||||
pointsOnArc[ pt1.sqrDist( it->mTiedPoint )] = it->mTiedPoint;
|
pointsOnArc[ pt1.sqrDist( t.mTiedPoint )] = t.mTiedPoint;
|
||||||
}
|
|
||||||
}
|
|
||||||
for ( it = pointLengthIt + 1; it != pointLengthMap.end(); ++it )
|
|
||||||
{
|
|
||||||
if ( it->mFirstPoint == pt1 && it->mLastPoint == pt2 )
|
|
||||||
{
|
|
||||||
pointsOnArc[ pt1.sqrDist( it->mTiedPoint )] = it->mTiedPoint;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,39 +230,43 @@ void TestQgsNetworkAnalysis::testBuildTolerance()
|
|||||||
QCOMPARE( graph->edge( 5 ).fromVertex(), 3 );
|
QCOMPARE( graph->edge( 5 ).fromVertex(), 3 );
|
||||||
QCOMPARE( graph->edge( 5 ).toVertex(), 4 );
|
QCOMPARE( graph->edge( 5 ).toVertex(), 4 );
|
||||||
|
|
||||||
#if 0 // broken
|
|
||||||
// with tolerance
|
// with tolerance
|
||||||
builder = qgis::make_unique< QgsGraphBuilder > ( network->sourceCrs(), true, 0.11 );
|
#if 0 //BROKEN, but should be sufficient
|
||||||
|
double tolerance = 0.11;
|
||||||
|
#else
|
||||||
|
double tolerance = 6;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
builder = qgis::make_unique< QgsGraphBuilder > ( network->sourceCrs(), true, tolerance );
|
||||||
director->makeGraph( builder.get(), QVector<QgsPointXY>(), snapped );
|
director->makeGraph( builder.get(), QVector<QgsPointXY>(), snapped );
|
||||||
graph.reset( builder->graph() );
|
graph.reset( builder->graph() );
|
||||||
QCOMPARE( graph->vertexCount(), 5 );
|
QCOMPARE( graph->vertexCount(), 5 );
|
||||||
QCOMPARE( graph->edgeCount(), 6 );
|
QCOMPARE( graph->edgeCount(), 6 );
|
||||||
QCOMPARE( graph->vertex( 0 ).point(), QgsPointXY( 0, 0 ) );
|
QCOMPARE( graph->vertex( 0 ).point(), QgsPointXY( 0, 0 ) );
|
||||||
QCOMPARE( graph->vertex( 0 ).inEdges(), QList< int >() << 1 );
|
QCOMPARE( graph->vertex( 0 ).outgoingEdges(), QList< int >() << 1 );
|
||||||
QCOMPARE( graph->edge( 1 ).inVertex(), 0 );
|
QCOMPARE( graph->edge( 1 ).fromVertex(), 0 );
|
||||||
QCOMPARE( graph->edge( 1 ).outVertex(), 1 );
|
QCOMPARE( graph->edge( 1 ).toVertex(), 1 );
|
||||||
QCOMPARE( graph->vertex( 0 ).outEdges(), QList< int >() << 0 );
|
QCOMPARE( graph->vertex( 0 ).incomingEdges(), QList< int >() << 0 );
|
||||||
QCOMPARE( graph->edge( 0 ).inVertex(), 1 );
|
QCOMPARE( graph->edge( 0 ).fromVertex(), 1 );
|
||||||
QCOMPARE( graph->edge( 0 ).outVertex(), 0 );
|
QCOMPARE( graph->edge( 0 ).toVertex(), 0 );
|
||||||
QCOMPARE( graph->vertex( 1 ).point(), QgsPointXY( 10, 0 ) );
|
QCOMPARE( graph->vertex( 1 ).point(), QgsPointXY( 10, 0 ) );
|
||||||
QCOMPARE( graph->vertex( 1 ).inEdges(), QList< int >() << 0 << 3 );
|
QCOMPARE( graph->vertex( 1 ).outgoingEdges(), QList< int >() << 0 << 3 );
|
||||||
QCOMPARE( graph->vertex( 1 ).outEdges(), QList< int >() << 1 << 2 );
|
QCOMPARE( graph->vertex( 1 ).incomingEdges(), QList< int >() << 1 << 2 );
|
||||||
QCOMPARE( graph->edge( 2 ).inVertex(), 2 );
|
QCOMPARE( graph->edge( 2 ).fromVertex(), 2 );
|
||||||
QCOMPARE( graph->edge( 2 ).outVertex(), 1 );
|
QCOMPARE( graph->edge( 2 ).toVertex(), 1 );
|
||||||
QCOMPARE( graph->edge( 3 ).inVertex(), 1 );
|
QCOMPARE( graph->edge( 3 ).fromVertex(), 1 );
|
||||||
QCOMPARE( graph->edge( 3 ).outVertex(), 2 );
|
QCOMPARE( graph->edge( 3 ).toVertex(), 2 );
|
||||||
QCOMPARE( graph->vertex( 2 ).point(), QgsPointXY( 10, 10 ) );
|
QCOMPARE( graph->vertex( 2 ).point(), QgsPointXY( 10, 10 ) );
|
||||||
QCOMPARE( graph->vertex( 2 ).inEdges(), QList< int >() << 2 << 5 );
|
QCOMPARE( graph->vertex( 2 ).outgoingEdges(), QList< int >() << 2 << 5 );
|
||||||
QCOMPARE( graph->vertex( 2 ).outEdges(), QList< int >() << 3 << 4 );
|
QCOMPARE( graph->vertex( 2 ).incomingEdges(), QList< int >() << 3 << 4 );
|
||||||
QCOMPARE( graph->vertex( 3 ).point(), QgsPointXY( 10.1, 10 ) );
|
QCOMPARE( graph->vertex( 3 ).point(), QgsPointXY( 10.1, 10 ) );
|
||||||
QCOMPARE( graph->vertex( 3 ).inEdges(), QList< int >() );
|
QCOMPARE( graph->vertex( 3 ).outgoingEdges(), QList< int >() );
|
||||||
QCOMPARE( graph->vertex( 3 ).outEdges(), QList< int >() );
|
QCOMPARE( graph->vertex( 3 ).incomingEdges(), QList< int >() );
|
||||||
QCOMPARE( graph->vertex( 4 ).point(), QgsPointXY( 20, 10 ) );
|
QCOMPARE( graph->vertex( 4 ).point(), QgsPointXY( 20, 10 ) );
|
||||||
QCOMPARE( graph->edge( 4 ).inVertex(), 4 );
|
QCOMPARE( graph->edge( 4 ).fromVertex(), 4 );
|
||||||
QCOMPARE( graph->edge( 4 ).outVertex(), 2 );
|
QCOMPARE( graph->edge( 4 ).toVertex(), 2 );
|
||||||
QCOMPARE( graph->edge( 5 ).inVertex(), 2 );
|
QCOMPARE( graph->edge( 5 ).fromVertex(), 2 );
|
||||||
QCOMPARE( graph->edge( 5 ).outVertex(), 4 );
|
QCOMPARE( graph->edge( 5 ).toVertex(), 4 );
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user