Skip to content

Commit

Permalink
Remove QgsGeometry pointers from QgsGeometryAnalyzer
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Aug 14, 2016
1 parent 6d82cd6 commit 5f6dfae
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 54 deletions.
91 changes: 41 additions & 50 deletions src/analysis/vector/qgsgeometryanalyzer.cpp
Expand Up @@ -347,14 +347,14 @@ QList<double> QgsGeometryAnalyzer::simpleMeasure( QgsGeometry& mpGeometry )
list.append( measure.measureArea( mpGeometry ) );
if ( mpGeometry.type() == QgsWkbTypes::PolygonGeometry )
{
perim = perimeterMeasure( &mpGeometry, measure );
perim = perimeterMeasure( mpGeometry, measure );
list.append( perim );
}
}
return list;
}

double QgsGeometryAnalyzer::perimeterMeasure( QgsGeometry* geometry, QgsDistanceArea& measure )
double QgsGeometryAnalyzer::perimeterMeasure( const QgsGeometry& geometry, QgsDistanceArea& measure )
{
return measure.measurePerimeter( geometry );
}
Expand Down Expand Up @@ -520,7 +520,6 @@ bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shap
++jt;
}
QList<double> values;
// QgsGeometry* tmpGeometry = 0;
if ( dissolveGeometry.isEmpty() )
{
QgsDebugMsg( "no dissolved geometry - should not happen" );
Expand Down Expand Up @@ -615,7 +614,7 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef
}
}

QgsGeometry *dissolveGeometry = nullptr; //dissolve geometry
QgsGeometry dissolveGeometry; //dissolve geometry
QMultiMap<QString, QgsFeatureId>::const_iterator jt = map.constBegin();
QgsFeature outputFeature;
while ( jt != map.constEnd() )
Expand Down Expand Up @@ -653,7 +652,7 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef
outputFeature.setAttributes( currentFeature.attributes() );
first = false;
}
dissolveFeature( currentFeature, processedFeatures, &dissolveGeometry );
dissolveGeometry = dissolveFeature( currentFeature, dissolveGeometry );
++processedFeatures;
}
++jt;
Expand Down Expand Up @@ -686,38 +685,33 @@ bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapef
outputFeature.setAttributes( currentFeature.attributes() );
first = false;
}
dissolveFeature( currentFeature, processedFeatures, &dissolveGeometry );
dissolveGeometry = dissolveFeature( currentFeature, dissolveGeometry );
++processedFeatures;
++jt;
}
}
outputFeature.setGeometry( *dissolveGeometry );
delete dissolveGeometry;
outputFeature.setGeometry( dissolveGeometry );
vWriter.addFeature( outputFeature );
}
return true;
}

void QgsGeometryAnalyzer::dissolveFeature( QgsFeature& f, int nProcessedFeatures, QgsGeometry** dissolveGeometry )
QgsGeometry QgsGeometryAnalyzer::dissolveFeature( const QgsFeature& f, const QgsGeometry& dissolveInto )
{
if ( !f.hasGeometry() )
{
return;
return dissolveInto;
}

QgsGeometry featureGeometry = f.geometry();

if ( nProcessedFeatures == 0 )
if ( dissolveInto.isEmpty() )
{
int geomSize = featureGeometry.wkbSize();
*dissolveGeometry = new QgsGeometry();
unsigned char* wkb = new unsigned char[geomSize];
memcpy( wkb, featureGeometry.asWkb(), geomSize );
( *dissolveGeometry )->fromWkb( wkb, geomSize );
return featureGeometry;
}
else
{
**dissolveGeometry = ( *dissolveGeometry )->combine( featureGeometry );
return dissolveInto.combine( featureGeometry );
}
}

Expand All @@ -744,7 +738,7 @@ bool QgsGeometryAnalyzer::buffer( QgsVectorLayer* layer, const QString& shapefil

QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), layer->fields(), outputType, crs );
QgsFeature currentFeature;
QgsGeometry *dissolveGeometry = nullptr; //dissolve geometry (if dissolve enabled)
QgsGeometry dissolveGeometry; //dissolve geometry (if dissolve enabled)

//take only selection
if ( onlySelectedFeatures )
Expand Down Expand Up @@ -773,7 +767,7 @@ bool QgsGeometryAnalyzer::buffer( QgsVectorLayer* layer, const QString& shapefil
{
continue;
}
bufferFeature( currentFeature, processedFeatures, &vWriter, dissolve, *dissolveGeometry, bufferDistance, bufferDistanceField );
bufferFeature( currentFeature, processedFeatures, &vWriter, dissolve, dissolveGeometry, bufferDistance, bufferDistanceField );
++processedFeatures;
}

Expand Down Expand Up @@ -804,7 +798,7 @@ bool QgsGeometryAnalyzer::buffer( QgsVectorLayer* layer, const QString& shapefil
{
break;
}
bufferFeature( currentFeature, processedFeatures, &vWriter, dissolve, *dissolveGeometry, bufferDistance, bufferDistanceField );
bufferFeature( currentFeature, processedFeatures, &vWriter, dissolve, dissolveGeometry, bufferDistance, bufferDistanceField );
++processedFeatures;
}
if ( p )
Expand All @@ -816,13 +810,12 @@ bool QgsGeometryAnalyzer::buffer( QgsVectorLayer* layer, const QString& shapefil
if ( dissolve )
{
QgsFeature dissolveFeature;
if ( !dissolveGeometry )
if ( dissolveGeometry.isEmpty() )
{
QgsDebugMsg( "no dissolved geometry - should not happen" );
return false;
}
dissolveFeature.setGeometry( *dissolveGeometry );
delete dissolveGeometry;
dissolveFeature.setGeometry( dissolveGeometry );
vWriter.addFeature( dissolveFeature );
}
return true;
Expand Down Expand Up @@ -977,7 +970,7 @@ bool QgsGeometryAnalyzer::eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer*
if ( !lrsGeom.isEmpty() )
{
++nOutputFeatures;
addEventLayerFeature( fet, &lrsGeom, featureIdIt->geometry(), fileWriter, memoryProviderFeatures, offsetField, offsetScale, forceSingleGeometry );
addEventLayerFeature( fet, lrsGeom, featureIdIt->geometry(), fileWriter, memoryProviderFeatures, offsetField, offsetScale, forceSingleGeometry );
}
}
if ( nOutputFeatures < 1 )
Expand All @@ -999,39 +992,41 @@ bool QgsGeometryAnalyzer::eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer*
return true;
}

void QgsGeometryAnalyzer::addEventLayerFeature( QgsFeature& feature, QgsGeometry* geom, const QgsGeometry& lineGeom, QgsVectorFileWriter* fileWriter, QgsFeatureList& memoryFeatures,
void QgsGeometryAnalyzer::addEventLayerFeature( QgsFeature& feature, const QgsGeometry& geom, const QgsGeometry& lineGeom, QgsVectorFileWriter* fileWriter, QgsFeatureList& memoryFeatures,
int offsetField, double offsetScale, bool forceSingleType )
{
if ( !geom )
if ( geom.isEmpty() )
{
return;
}

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

QList<QgsGeometry>::iterator geomIt = geomList.begin();
for ( ; geomIt != geomList.end(); ++geomIt )
{
//consider offset
QgsGeometry newGeom = *geomIt;
if ( offsetField >= 0 )
{
double offsetVal = feature.attribute( offsetField ).toDouble();
offsetVal *= offsetScale;
if ( !createOffsetGeometry( &( *geomIt ), lineGeom, offsetVal ) )
newGeom = createOffsetGeometry( *geomIt, lineGeom, offsetVal );
if ( newGeom.isEmpty() )
{
continue;
}
}

feature.setGeometry( *geomIt );
feature.setGeometry( newGeom );
if ( fileWriter )
{
fileWriter->addFeature( feature );
Expand All @@ -1041,57 +1036,52 @@ void QgsGeometryAnalyzer::addEventLayerFeature( QgsFeature& feature, QgsGeometry
memoryFeatures << feature;
}
}

if ( forceSingleType )
{
delete geom;
}
}

bool QgsGeometryAnalyzer::createOffsetGeometry( QgsGeometry* geom, const QgsGeometry& lineGeom, double offset )
QgsGeometry QgsGeometryAnalyzer::createOffsetGeometry( const QgsGeometry& geom, const QgsGeometry& lineGeom, double offset )
{
if ( !geom || lineGeom.isEmpty() )
{
return false;
return QgsGeometry();
}

QList<QgsGeometry> inputGeomList;

if ( geom->isMultipart() )
if ( geom.isMultipart() )
{
inputGeomList = geom->asGeometryCollection();
inputGeomList = geom.asGeometryCollection();
}
else
{
inputGeomList.push_back( *geom );
inputGeomList.push_back( geom );
}

QList<GEOSGeometry*> outputGeomList;
QList<QgsGeometry>::const_iterator inputGeomIt = inputGeomList.constBegin();
GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler();
for ( ; inputGeomIt != inputGeomList.constEnd(); ++inputGeomIt )
{
if ( geom->type() == QgsWkbTypes::LineGeometry )
if ( geom.type() == QgsWkbTypes::LineGeometry )
{
//geos 3.3 needed for line offsets
#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)))
GEOSGeometry* offsetGeom = GEOSOffsetCurve_r( geosctxt, ( *inputGeomIt ).asGeos(), -offset, 8 /*quadSegments*/, 0 /*joinStyle*/, 5.0 /*mitreLimit*/ );
if ( !offsetGeom || !GEOSisValid_r( geosctxt, offsetGeom ) )
{
return false;
return QgsGeometry();
}
if ( !GEOSisValid_r( geosctxt, offsetGeom ) || GEOSGeomTypeId_r( geosctxt, offsetGeom ) != GEOS_LINESTRING || GEOSGeomGetNumPoints_r( geosctxt, offsetGeom ) < 1 )
{
GEOSGeom_destroy_r( geosctxt, offsetGeom );
return false;
return QgsGeometry();
}
outputGeomList.push_back( offsetGeom );
#else
outputGeomList.push_back( GEOSGeom_clone_r( geosctxt, ( *inputGeomIt )->asGeos() ) );
#endif
}
else if ( geom->type() == QgsWkbTypes::PointGeometry )
else if ( geom.type() == QgsWkbTypes::PointGeometry )
{
QgsPoint p = ( *inputGeomIt ).asPoint();
p = createPointOffset( p.x(), p.y(), offset, lineGeom );
Expand All @@ -1103,12 +1093,13 @@ bool QgsGeometryAnalyzer::createOffsetGeometry( QgsGeometry* geom, const QgsGeom
}
}

if ( !geom->isMultipart() )
QgsGeometry outGeometry;
if ( !geom.isMultipart() )
{
GEOSGeometry* outputGeom = outputGeomList.at( 0 );
if ( outputGeom )
{
geom->fromGeos( outputGeom );
outGeometry.fromGeos( outputGeom );
}
}
else
Expand All @@ -1119,18 +1110,18 @@ bool QgsGeometryAnalyzer::createOffsetGeometry( QgsGeometry* geom, const QgsGeom
geomArray[i] = outputGeomList.at( i );
}
GEOSGeometry* collection = nullptr;
if ( geom->type() == QgsWkbTypes::PointGeometry )
if ( geom.type() == QgsWkbTypes::PointGeometry )
{
collection = GEOSGeom_createCollection_r( geosctxt, GEOS_MULTIPOINT, geomArray, outputGeomList.size() );
}
else if ( geom->type() == QgsWkbTypes::LineGeometry )
else if ( geom.type() == QgsWkbTypes::LineGeometry )
{
collection = GEOSGeom_createCollection_r( geosctxt, GEOS_MULTILINESTRING, geomArray, outputGeomList.size() );
}
geom->fromGeos( collection );
outGeometry.fromGeos( collection );
delete[] geomArray;
}
return true;
return outGeometry;
}

QgsPoint QgsGeometryAnalyzer::createPointOffset( double x, double y, double dist, const QgsGeometry& lineGeom ) const
Expand Down
8 changes: 4 additions & 4 deletions src/analysis/vector/qgsgeometryanalyzer.h
Expand Up @@ -128,7 +128,7 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
private:

QList<double> simpleMeasure( QgsGeometry& geometry );
double perimeterMeasure( QgsGeometry* geometry, QgsDistanceArea& measure );
double perimeterMeasure( const QgsGeometry& geometry, QgsDistanceArea& measure );
/** Helper function to simplify an individual feature*/
void simplifyFeature( QgsFeature& f, QgsVectorFileWriter* vfw, double tolerance );
/** Helper function to get the cetroid of an individual feature*/
Expand All @@ -139,16 +139,16 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
/** Helper function to get the convex hull of feature(s)*/
void convexFeature( QgsFeature& f, int nProcessedFeatures, QgsGeometry& dissolveGeometry );
/** Helper function to dissolve feature(s)*/
void dissolveFeature( QgsFeature& f, int nProcessedFeatures, QgsGeometry** dissolveGeometry );
QgsGeometry dissolveFeature( const QgsFeature& f, const QgsGeometry& dissolveInto );

//helper functions for event layer
void addEventLayerFeature( QgsFeature& feature, QgsGeometry* geom, const QgsGeometry& lineGeom, QgsVectorFileWriter* fileWriter, QgsFeatureList& memoryFeatures, int offsetField = -1, double offsetScale = 1.0,
void addEventLayerFeature( QgsFeature& feature, const QgsGeometry& geom, const QgsGeometry& lineGeom, QgsVectorFileWriter* fileWriter, QgsFeatureList& memoryFeatures, int offsetField = -1, double offsetScale = 1.0,
bool forceSingleType = false );
/** Create geometry offset relative to line geometry.
@param geom the geometry to modify
@param lineGeom the line geometry to which the feature is referenced
@param offset the offset value in layer unit. Negative values mean offset towards left, positive values offset to the right side*/
bool createOffsetGeometry( QgsGeometry* geom, const QgsGeometry& lineGeom, double offset );
QgsGeometry createOffsetGeometry( const QgsGeometry& geom, const QgsGeometry& lineGeom, double offset );
QgsPoint createPointOffset( double x, double y, double dist, const QgsGeometry& lineGeom ) const;
QgsConstWkbPtr locateBetweenWkbString( QgsConstWkbPtr ptr, QgsMultiPolyline& result, double fromMeasure, double toMeasure );
QgsConstWkbPtr locateAlongWkbString( QgsConstWkbPtr ptr, QgsMultiPoint& result, double measure );
Expand Down

0 comments on commit 5f6dfae

Please sign in to comment.