Skip to content

Commit b7946b4

Browse files
committed
add qgslinevectorlayerdirector
1 parent 0391f97 commit b7946b4

File tree

5 files changed

+445
-5
lines changed

5 files changed

+445
-5
lines changed

src/analysis/network/CMakeLists.txt

+5-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ SET(QGIS_NETWORK_ANALYSIS_SRCS
77
qgsgraph.cpp
88
qgsgraphbuilder.cpp
99
qgsdistanceedgeproperter.cpp
10+
qgslinevectorlayerdirector.cpp
1011
)
1112

1213
INCLUDE_DIRECTORIES(BEFORE raster)
@@ -50,14 +51,14 @@ INSTALL(TARGETS qgis_networkanalysis
5051
ARCHIVE DESTINATION ${QGIS_LIB_DIR})
5152

5253

53-
# Added by Tim to install headers
54-
5554
SET(QGIS_NETWORK_ANALYSIS_HDRS
5655
qgsgraph.h
57-
qgsgraphbuilderinterface.h
56+
qgsgraphbuilderintr.h
5857
qgsgraphbuilder.h
5958
qgsedgeproperter.h
60-
qgsdistanceedgeproperter.h )
59+
qgsdistanceedgeproperter.h
60+
qgsgraphdirector.h
61+
qgslinevectorlayerdirector.h )
6162

6263
INSTALL(CODE "MESSAGE(\"Installing NETWORK ANALYSIS headers...\")")
6364
INSTALL(FILES ${QGIS_NETWORK_ANALYSIS_HDRS} ${QGIS_NETWORK_ANALYSIS_MOC_HDRS} DESTINATION ${QGIS_INCLUDE_DIR})

src/analysis/network/qgsgraphbuilderintr.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
/**
3030
* \ingroup analysis
3131
* \class QgsGraphBuilderInterface
32-
* \brief Determine interface for creating a graph. Contains the settings of the graph.
32+
* \brief Determine interface for creating a graph. Contains the settings of the graph. QgsGraphBuilder and QgsGraphDirector is a Builder pattern
3333
*/
3434
class ANALYSIS_EXPORT QgsGraphBuilderInterface
3535
{
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/***************************************************************************
2+
qgsgraphdirector.h
3+
--------------------------------------
4+
Date : 2010-10-18
5+
Copyright : (C) 2010 by Yakushev Sergey
6+
Email : YakushevS <at> list.ru
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+
#ifndef QGSGRAPHDIRECTORH
16+
#define QGSGRAPHDIRECTORH
17+
18+
//QT4 includes
19+
#include <QObject>
20+
#include <QVector>
21+
#include <QList>
22+
23+
//QGIS includes
24+
#include <qgspoint.h>
25+
#include "qgsedgeproperter.h"
26+
27+
//forward declarations
28+
class QgsGraphBuilderInterface;
29+
30+
/**
31+
* \ingroup analysis
32+
* \class QgsGraphDirector
33+
* \brief Determine making the graph. QgsGraphBuilder and QgsGraphDirector is a builder patter.
34+
*/
35+
class ANALYSIS_EXPORT QgsGraphDirector : public QObject
36+
{
37+
Q_OBJECT
38+
39+
signals:
40+
void buildProgress( int, int ) const;
41+
void buildMessage( QString ) const;
42+
43+
public:
44+
//! Destructor
45+
virtual ~QgsGraphDirector() { };
46+
47+
/**
48+
* Make a graph using RgGraphBuilder
49+
*
50+
* @param builder The graph builder
51+
*
52+
* @param additionalPoints Vector of points that must be tied to the graph
53+
*
54+
* @param tiedPoints Vector of tied points
55+
*
56+
* @note if tiedPoints[i]==QgsPoint(0.0,0.0) then tied failed.
57+
*/
58+
virtual void makeGraph( QgsGraphBuilderInterface* builder,
59+
const QVector< QgsPoint >& additionalPoints,
60+
QVector< QgsPoint>& tiedPoints ) const = 0;
61+
62+
void addProperter( QgsEdgeProperter* prop )
63+
{
64+
mProperterList.push_back( prop );
65+
}
66+
67+
/**
68+
* return Director name
69+
*/
70+
virtual QString name() const = 0;
71+
72+
protected:
73+
QList<QgsEdgeProperter*> mProperterList;
74+
};
75+
#endif //QGSGRAPHDIRECTORH
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
/***************************************************************************
2+
* Copyright (C) 2010 by Sergey Yakushev *
3+
* yakushevs <at> list.ru *
4+
* *
5+
* *
6+
* This program is free software; you can redistribute it and/or modify *
7+
* it under the terms of the GNU General Public License as published by *
8+
* the Free Software Foundation; either version 2 of the License, or *
9+
* (at your option) any later version. *
10+
***************************************************************************/
11+
12+
/**
13+
* \file qgslinevectorlayerdirector.cpp
14+
* \brief implementation of QgsLineVectorLayerDirector
15+
*/
16+
17+
#include "qgslinevectorlayerdirector.h"
18+
#include "qgsgraphbuilderintr.h"
19+
20+
// Qgis includes
21+
#include <qgsvectorlayer.h>
22+
#include <qgsmaplayerregistry.h>
23+
#include <qgsvectordataprovider.h>
24+
#include <qgspoint.h>
25+
#include <qgsgeometry.h>
26+
#include <qgsdistancearea.h>
27+
28+
// QT includes
29+
#include <QString>
30+
#include <QtAlgorithms>
31+
32+
//standard includes
33+
#include <limits>
34+
35+
QgsLineVectorLayerDirector::QgsLineVectorLayerDirector( const QString& layerId,
36+
int directionFieldId,
37+
const QString& directDirectionValue,
38+
const QString& reverseDirectionValue,
39+
const QString& bothDirectionValue,
40+
int defaultDirection
41+
)
42+
{
43+
mLayerId = layerId;
44+
mDirectionFieldId = directionFieldId;
45+
mDirectDirectionValue = directDirectionValue;
46+
mReverseDirectionValue = reverseDirectionValue;
47+
mDefaultDirection = defaultDirection;
48+
mBothDirectionValue = bothDirectionValue;
49+
}
50+
51+
QgsLineVectorLayerDirector::~QgsLineVectorLayerDirector()
52+
{
53+
54+
}
55+
56+
QString QgsLineVectorLayerDirector::name() const
57+
{
58+
return QString( "Vector line" );
59+
}
60+
61+
void QgsLineVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, const QVector< QgsPoint >& additionalPoints,
62+
QVector< QgsPoint >& tiedPoint ) const
63+
{
64+
QgsVectorLayer *vl = myLayer();
65+
66+
if ( vl == NULL )
67+
return;
68+
69+
int featureCount = ( int ) vl->featureCount() * 2;
70+
int step = 0;
71+
72+
QgsCoordinateTransform ct( vl->crs(), builder->destinationCrs() );
73+
74+
QgsDistanceArea da;
75+
da.setSourceCrs( builder->destinationCrs().srsid() );
76+
da.setProjectionsEnabled( true );
77+
78+
tiedPoint = QVector< QgsPoint >( additionalPoints.size(), QgsPoint( 0.0, 0.0 ) );
79+
TiePointInfo tmpInfo;
80+
tmpInfo.mLength = std::numeric_limits<double>::infinity();
81+
82+
QVector< TiePointInfo > pointLengthMap( additionalPoints.size(), tmpInfo );
83+
QVector< TiePointInfo >::iterator pointLengthIt;
84+
85+
// begin: tie points to the graph
86+
QgsAttributeList la;
87+
vl->select( la );
88+
QgsFeature feature;
89+
while ( vl->nextFeature( feature ) )
90+
{
91+
QgsPoint pt1, pt2;
92+
bool isFirstPoint = true;
93+
QgsPolyline pl = feature.geometry()->asPolyline();
94+
QgsPolyline::iterator pointIt;
95+
for ( pointIt = pl.begin(); pointIt != pl.end(); ++pointIt )
96+
{
97+
pt2 = ct.transform( *pointIt );
98+
if ( !isFirstPoint )
99+
{
100+
int i = 0;
101+
for ( i = 0; i != additionalPoints.size(); ++i )
102+
{
103+
TiePointInfo info;
104+
info.mLength = additionalPoints[ i ].sqrDistToSegment( pt1.x(), pt1.y(), pt2.x(), pt2.y(), info.mTiedPoint );
105+
106+
if ( pointLengthMap[ i ].mLength > info.mLength )
107+
{
108+
info.mTiedPoint = info.mTiedPoint ;
109+
info.mFirstPoint = pt1;
110+
info.mLastPoint = pt2;
111+
112+
pointLengthMap[ i ] = info;
113+
tiedPoint[ i ] = info.mTiedPoint;
114+
}
115+
}
116+
}
117+
pt1 = pt2;
118+
isFirstPoint = false;
119+
}
120+
emit buildProgress( ++step, featureCount );
121+
}
122+
123+
// end: tie points to graph
124+
125+
// add tied point to graph
126+
int i = 0;
127+
for ( i = 0; i < tiedPoint.size(); ++i )
128+
{
129+
if ( tiedPoint[ i ] != QgsPoint( 0.0, 0.0 ) )
130+
{
131+
tiedPoint[ i ] = builder->addVertex( tiedPoint[ i ] );
132+
}
133+
}
134+
135+
{ // fill attribute list 'la'
136+
QgsAttributeList tmpAttr;
137+
if ( mDirectionFieldId != -1 )
138+
{
139+
tmpAttr.push_back( mDirectionFieldId );
140+
}
141+
142+
QList< QgsEdgeProperter* >::const_iterator it;
143+
QgsAttributeList::const_iterator it2;
144+
145+
for ( it = mProperterList.begin(); it != mProperterList.end(); ++it )
146+
{
147+
QgsAttributeList tmp = (*it)->requiredAttributes();
148+
for ( it2 = tmp.begin(); it2 != tmp.end(); ++it2 )
149+
{
150+
tmpAttr.push_back( *it2 );
151+
}
152+
}
153+
qSort( tmpAttr.begin(), tmpAttr.end() );
154+
155+
int lastAttrId = -1;
156+
for ( it2 = tmpAttr.begin(); it2 != tmpAttr.end(); ++it2 )
157+
{
158+
if ( *it2 == lastAttrId )
159+
{
160+
continue;
161+
}
162+
163+
la.push_back( *it2 );
164+
165+
lastAttrId = *it2;
166+
}
167+
} // end fill attribute list 'la'
168+
169+
// begin graph construction
170+
vl->select( la );
171+
while ( vl->nextFeature( feature ) )
172+
{
173+
QgsAttributeMap attr = feature.attributeMap();
174+
int directionType = mDefaultDirection;
175+
QgsAttributeMap::const_iterator it;
176+
// What direction have feature?
177+
for ( it = attr.constBegin(); it != attr.constEnd(); ++it )
178+
{
179+
if ( it.key() != mDirectionFieldId )
180+
{
181+
continue;
182+
}
183+
QString str = it.value().toString();
184+
if ( str == mBothDirectionValue )
185+
{
186+
directionType = 3;
187+
}
188+
else if ( str == mDirectDirectionValue )
189+
{
190+
directionType = 1;
191+
}
192+
else if ( str == mReverseDirectionValue )
193+
{
194+
directionType = 2;
195+
}
196+
}
197+
198+
// begin features segments and add arc to the Graph;
199+
QgsPoint pt1, pt2;
200+
201+
bool isFirstPoint = true;
202+
QgsPolyline pl = feature.geometry()->asPolyline();
203+
QgsPolyline::iterator pointIt;
204+
for ( pointIt = pl.begin(); pointIt != pl.end(); ++pointIt )
205+
{
206+
pt2 = builder->addVertex( ct.transform( *pointIt ) );
207+
208+
std::map< double, QgsPoint > pointsOnArc;
209+
pointsOnArc[ 0.0 ] = pt1;
210+
pointsOnArc[ pt1.sqrDist( pt2 )] = pt2;
211+
212+
for ( pointLengthIt = pointLengthMap.begin(); pointLengthIt != pointLengthMap.end(); ++pointLengthIt )
213+
{
214+
if ( pointLengthIt->mFirstPoint == pt1 && pointLengthIt->mLastPoint == pt2 )
215+
{
216+
QgsPoint tiedPoint = pointLengthIt->mTiedPoint;
217+
pointsOnArc[ pt1.sqrDist( tiedPoint )] = tiedPoint;
218+
}
219+
}
220+
221+
if ( !isFirstPoint )
222+
{
223+
std::map< double, QgsPoint >::iterator pointsIt;
224+
QgsPoint pt1;
225+
QgsPoint pt2;
226+
bool isFirstPoint = true;
227+
for ( pointsIt = pointsOnArc.begin(); pointsIt != pointsOnArc.end(); ++pointsIt )
228+
{
229+
pt2 = pointsIt->second;
230+
if ( !isFirstPoint )
231+
{
232+
double distance = da.measureLine( pt1, pt2 );
233+
QVector< QVariant > prop;
234+
QList< QgsEdgeProperter* >::const_iterator it;
235+
for ( it = mProperterList.begin(); it != mProperterList.end(); ++it )
236+
{
237+
prop.push_back( (*it)->property( distance, feature ) );
238+
}
239+
240+
if ( directionType == 1 ||
241+
directionType == 3 )
242+
{
243+
builder->addArc( pt1, pt2, prop );
244+
}
245+
if ( directionType == 2 ||
246+
directionType == 3 )
247+
{
248+
builder->addArc( pt2, pt1, prop );
249+
}
250+
}
251+
pt1 = pt2;
252+
isFirstPoint = false;
253+
}
254+
} // if ( !isFirstPoint )
255+
pt1 = pt2;
256+
isFirstPoint = false;
257+
} // for (it = pl.begin(); it != pl.end(); ++it)
258+
emit buildProgress( ++step, featureCount );
259+
} // while( vl->nextFeature(feature) )
260+
} // makeGraph( QgsGraphBuilderInterface *builder, const QVector< QgsPoint >& additionalPoints, QVector< QgsPoint >& tiedPoint )
261+
262+
QgsVectorLayer* QgsLineVectorLayerDirector::myLayer() const
263+
{
264+
QMap <QString, QgsMapLayer*> m = QgsMapLayerRegistry::instance()->mapLayers();
265+
QMap <QString, QgsMapLayer*>::const_iterator it = m.find( mLayerId );
266+
if ( it == m.end() )
267+
{
268+
return NULL;
269+
}
270+
// return NULL if it.value() isn't QgsVectorLayer()
271+
return dynamic_cast<QgsVectorLayer*>( it.value() );
272+
}

0 commit comments

Comments
 (0)