Skip to content
Permalink
Browse files
Add possibility to force eventLayer features to single geometry type
  • Loading branch information
mhugent committed Mar 21, 2012
1 parent c27c890 commit 2d4a596399d56459eaa9596043ece9657a8936a3
Showing with 54 additions and 14 deletions.
  1. +2 −1 python/analysis/qgsgeometryanalyzer.sip
  2. +49 −11 src/analysis/vector/qgsgeometryanalyzer.cpp
  3. +3 −2 src/analysis/vector/qgsgeometryanalyzer.h
@@ -60,7 +60,8 @@ class QgsGeometryAnalyzer
@param p progress dialog or 0 if no progress dialog should be shown
*/
bool eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer* eventLayer, int lineField, int eventField, QList<int>& unlocatedFeatureIds /Out/,
const QString& outputLayer, const QString& outputFormat, int locationField1, int locationField2 = -1, QgsVectorDataProvider* memoryProvider = 0, QProgressDialog* p = 0 );
const QString& outputLayer, const QString& outputFormat, int locationField1, int locationField2 = -1, bool forceSingleGeometry = false,
QgsVectorDataProvider* memoryProvider = 0, QProgressDialog* p = 0 );

/**Returns multilinestring*/
QgsGeometry* locateBetweenMeasures( double fromMeasure, double toMeasure, QgsGeometry* lineGeom );
@@ -910,7 +910,7 @@ void QgsGeometryAnalyzer::bufferFeature( QgsFeature& f, int nProcessedFeatures,
}

bool QgsGeometryAnalyzer::eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer* eventLayer, int lineField, int eventField, QList<int>& unlocatedFeatureIds, const QString& outputLayer,
const QString& outputFormat, int locationField1, int locationField2, QgsVectorDataProvider* memoryProvider, QProgressDialog* p )
const QString& outputFormat, int locationField1, int locationField2, bool forceSingleGeometry, QgsVectorDataProvider* memoryProvider, QProgressDialog* p )
{
if ( !lineLayer || !eventLayer || !lineLayer->isValid() || !eventLayer->isValid() )
{
@@ -932,10 +932,19 @@ bool QgsGeometryAnalyzer::eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer*
QgsFeatureList memoryProviderFeatures;
if ( !memoryProvider )
{
QGis::WkbType memoryProviderType = QGis::WKBMultiLineString;
if ( locationField2 == -1 )
{
memoryProviderType = forceSingleGeometry ? QGis::WKBPoint : QGis::WKBMultiPoint;
}
else
{
memoryProviderType = forceSingleGeometry ? QGis::WKBLineString : QGis::WKBMultiLineString;
}
fileWriter = new QgsVectorFileWriter( outputLayer,
eventLayer->dataProvider()->encoding(),
eventLayer->pendingFields(),
locationField2 == -1 ? QGis::WKBMultiPoint : QGis::WKBMultiLineString,
memoryProviderType,
&( lineLayer->crs() ),
outputFormat );
}
@@ -1003,15 +1012,7 @@ bool QgsGeometryAnalyzer::eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer*
if ( lrsGeom )
{
++nOutputFeatures;
fet.setGeometry( lrsGeom );
if ( memoryProvider )
{
memoryProviderFeatures << fet;
}
else if ( fileWriter )
{
fileWriter->addFeature( fet );
}
addEventLayerFeature( fet, lrsGeom, fileWriter, memoryProviderFeatures, forceSingleGeometry );
}
}
if ( nOutputFeatures < 1 )
@@ -1033,6 +1034,43 @@ bool QgsGeometryAnalyzer::eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer*
return true;
}

void QgsGeometryAnalyzer::addEventLayerFeature( QgsFeature& feature, QgsGeometry* geom, QgsVectorFileWriter* fileWriter, QgsFeatureList& memoryFeatures, bool forceSingleType )
{
if ( !geom )
{
return;
}

QList<QgsGeometry*> geomList;
if ( forceSingleType )
{
geomList = geom->asGeometryCollection();
}
else
{
geomList.push_back( geom );
}

QList<QgsGeometry*>::iterator geomIt = geomList.begin();
for ( ; geomIt != geomList.end(); ++geomIt )
{
feature.setGeometry( *geomIt );
if ( fileWriter )
{
fileWriter->addFeature( feature );
}
else
{
memoryFeatures << feature;
}
}

if ( forceSingleType )
{
delete geom;
}
}

QgsGeometry* QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, double toMeasure, QgsGeometry* lineGeom )
{
if ( !lineGeom )
@@ -111,11 +111,12 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
@param unlocatedFeatureIds out: ids of event features where linear referencing was not successful
@param locationField1 attribute index of location field in event layer
@param locationField2 attribute index of location end field (or -1 for point layer)
@param forceSingleGeometry force layer to single point/line type. Feature attributes are copied in case of multiple matches
@param memoryProvider memory provider to write output to (can be 0 if output is written to a file)
@param p progress dialog or 0 if no progress dialog should be shown
*/
bool eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer* eventLayer, int lineField, int eventField, QList<int>& unlocatedFeatureIds, const QString& outputLayer,
const QString& outputFormat, int locationField1, int locationField2 = -1, QgsVectorDataProvider* memoryProvider = 0, QProgressDialog* p = 0 );
const QString& outputFormat, int locationField1, int locationField2 = -1, bool forceSingleGeometry = false, QgsVectorDataProvider* memoryProvider = 0, QProgressDialog* p = 0 );

/**Returns linear reference geometry as a multiline (or 0 if no match). Currently, the z-coordinates are considered to be the measures (no support for m-values in QGIS)*/
QgsGeometry* locateBetweenMeasures( double fromMeasure, double toMeasure, QgsGeometry* lineGeom );
@@ -140,7 +141,7 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
void dissolveFeature( QgsFeature& f, int nProcessedFeatures, QgsGeometry** dissolveGeometry );

//helper functions for event layer

void addEventLayerFeature( QgsFeature& feature, QgsGeometry* geom, QgsVectorFileWriter* fileWriter, QgsFeatureList& memoryFeatures, bool forceSingleType = false );
unsigned char* locateBetweenWkbString( unsigned char* ptr, QgsMultiPolyline& result, double fromMeasure, double toMeasure );
unsigned char* locateAlongWkbString( unsigned char* ptr, QgsMultiPoint& result, double measure );
static bool clipSegmentByRange( double x1, double y1, double m1, double x2, double y2, double m2, double range1, double range2, QgsPoint& pt1, QgsPoint& pt2, bool& secondPointClipped );

0 comments on commit 2d4a596

Please sign in to comment.