Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE]: creation of event layers in analysis lib using linear refe…
…rencing
  • Loading branch information
mhugent committed Feb 1, 2012
1 parent df2d801 commit fb73d0f
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 0 deletions.
11 changes: 11 additions & 0 deletions python/analysis/qgsgeometryanalyzer.sip
Expand Up @@ -46,6 +46,17 @@ class QgsGeometryAnalyzer
bool onlySelectedFeatures = false,
int uniqueIdField = -1 );

/**Creates an event layer (multipoint or multiline). Note that currently (until QgsGeometry supports m-values) the z-coordinate of the line layer is used for linear referencing
@param lineLayer layer with the line geometry
@param eventLayer layer with features and location field
@param lineField join index in line layer
@param eventField join index in event layer
@param locationField1 attribute index of location field in event layer
@param locationField2 attribute index of location end field (or -1 for point layer)
*/
bool eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer* eventLayer, int lineField, int eventField, const QString& outputLayer,
const QString& outputFormat, int locationField1, int locationField2 = -1, QgsVectorDataProvider* memoryProvider = 0, QProgressDialog* p = 0 );

private:

QList<double> simpleMeasure( QgsGeometry* geometry );
Expand Down
100 changes: 100 additions & 0 deletions src/analysis/vector/qgsgeometryanalyzer.cpp
Expand Up @@ -908,3 +908,103 @@ void QgsGeometryAnalyzer::bufferFeature( QgsFeature& f, int nProcessedFeatures,
}
}
}

bool QgsGeometryAnalyzer::eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer* eventLayer, int lineField, int eventField, const QString& outputLayer,
const QString& outputFormat, int locationField1, int locationField2, QgsVectorDataProvider* memoryProvider, QProgressDialog* p )
{
if ( !lineLayer || !eventLayer || !lineLayer->isValid() || !eventLayer->isValid() )
{
return false;
}

//create line field / id map for line layer
QHash< QString, QgsFeatureId > lineLayerIdMap;
lineLayer->select( QgsAttributeList() << lineField,
QgsRectangle(), false, false );
QgsFeature fet;
while ( lineLayer->nextFeature( fet ) )
{
lineLayerIdMap.insert( fet.attributeMap()[lineField].toString(), fet.id() );
}

//create output datasource or attributes in memory provider
QgsVectorFileWriter* fileWriter = 0;
if ( !memoryProvider )
{
fileWriter = new QgsVectorFileWriter( outputLayer,
eventLayer->dataProvider()->encoding(),
eventLayer->pendingFields(),
locationField2 == -1 ? QGis::WKBMultiPoint25D : QGis::WKBMultiLineString25D,
&( lineLayer->crs() ),
outputFormat );
}
else
{
memoryProvider->addAttributes( eventLayer->pendingFields().values() );
}

//iterate over eventLayer and write new features to output file or layer
eventLayer->select( eventLayer->pendingAllAttributesList(), QgsRectangle(), true, false );
QgsGeometry* lrsGeom = 0;
QgsFeature lineFeature;
QgsGeometry* lineGeom = 0;
double measure1, measure2;

while ( eventLayer->nextFeature( fet ) )
{
//get corresponding line feature
QHash< QString, QgsFeatureId >::const_iterator layerIdIt = lineLayerIdMap.find( fet.attributeMap()[eventField].toString() );
if ( layerIdIt == lineLayerIdMap.constEnd() )
{
continue;
}
if ( !lineLayer->featureAtId( *layerIdIt, lineFeature, true, false ) )
{
continue;
}

measure1 = fet.attributeMap()[locationField1].toDouble();
if ( locationField2 == -1 )
{
lrsGeom = locateAlongMeasure( measure1, lineFeature.geometry() );
}
else
{
measure2 = fet.attributeMap()[locationField2].toDouble();
lrsGeom = locateBetweenMeasures( measure1, measure2, lineFeature.geometry() );
}

if ( lrsGeom )
{
fet.setGeometry( lrsGeom );
if ( memoryProvider )
{
memoryProvider->addFeatures( QgsFeatureList() << fet );
}
else
{
fileWriter->addFeature( fet );
}
}
}

return true;
}

QgsGeometry* QgsGeometryAnalyzer::locateAlongMeasure( double measure, const QgsGeometry* lineGeom )
{
//only for testing
QgsGeometry* geom = new QgsGeometry();
*geom = *lineGeom;
geom->convertToMultiType();
return geom;
}

QgsGeometry* QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, double toMeasure, const QgsGeometry* lineGeom )
{
//only for testing
QgsGeometry* geom = new QgsGeometry();
*geom = *lineGeom;
geom->convertToMultiType();
return geom;
}
13 changes: 13 additions & 0 deletions src/analysis/vector/qgsgeometryanalyzer.h
Expand Up @@ -100,6 +100,17 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
bool dissolve( QgsVectorLayer* layer, const QString& shapefileName, bool onlySelectedFeatures = false,
int uniqueIdField = -1, QProgressDialog* p = 0 );

/**Creates an event layer (multipoint or multiline). Note that currently (until QgsGeometry supports m-values) the z-coordinate of the line layer is used for linear referencing
@param lineLayer layer with the line geometry
@param eventLayer layer with features and location field
@param lineField join index in line layer
@param eventField join index in event layer
@param locationField1 attribute index of location field in event layer
@param locationField2 attribute index of location end field (or -1 for point layer)
*/
bool eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer* eventLayer, int lineField, int eventField, const QString& outputLayer,
const QString& outputFormat, int locationField1, int locationField2 = -1, QgsVectorDataProvider* memoryProvider = 0, QProgressDialog* p = 0 );

private:

QList<double> simpleMeasure( QgsGeometry* geometry );
Expand All @@ -115,6 +126,8 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
void convexFeature( QgsFeature& f, int nProcessedFeatures, QgsGeometry** dissolveGeometry );
/**Helper function to dissolve feature(s)*/
void dissolveFeature( QgsFeature& f, int nProcessedFeatures, QgsGeometry** dissolveGeometry );
QgsGeometry* locateAlongMeasure( double measure, const QgsGeometry* lineGeom );
QgsGeometry* locateBetweenMeasures( double fromMeasure, double toMeasure, const QgsGeometry* lineGeom );

};
#endif //QGSVECTORANALYZER

0 comments on commit fb73d0f

Please sign in to comment.