Skip to content

Commit

Permalink
Merge pull request #3476 from mhugent/fix_event_layer
Browse files Browse the repository at this point in the history
Fix for event layer functionality in 2.4
  • Loading branch information
mhugent authored Sep 12, 2016
2 parents 4aaa6d4 + 9290ee3 commit c151724
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 26 deletions.
59 changes: 38 additions & 21 deletions src/analysis/vector/qgsgeometryanalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1178,29 +1178,32 @@ QgsGeometry* QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, dou
}

QgsMultiPolyline resultGeom;
QgsWKBTypes::Type wkbType = lineGeom->geometry()->wkbType();

//need to go with WKB and z coordinate until QgsGeometry supports M values
QgsConstWkbPtr wkbPtr( lineGeom->asWkb(), lineGeom->wkbSize() );
wkbPtr.readHeader();

QGis::WkbType wkbType = lineGeom->wkbType();
if ( wkbType != QGis::WKBLineString25D && wkbType != QGis::WKBMultiLineString25D )
//only linestring / multilinestring types supported at the moment
if ( QgsWKBTypes::singleType( QgsWKBTypes::flatType( wkbType ) ) != QgsWKBTypes::LineString || QgsWKBTypes::coordDimensions( wkbType ) < 3 )
{
return nullptr;
}

if ( wkbType == QGis::WKBLineString25D )
bool hasZM = QgsWKBTypes::hasZ( wkbType ) && QgsWKBTypes::hasM( wkbType );


QgsConstWkbPtr wkbPtr( lineGeom->asWkb(), lineGeom->wkbSize() );
wkbPtr.readHeader();

if ( QgsWKBTypes::flatType( wkbType ) == QgsWKBTypes::LineString )
{
locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure );
locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure, hasZM );
}
else if ( wkbType == QGis::WKBMultiLineString25D )
else if ( QgsWKBTypes::flatType( wkbType ) == QgsWKBTypes::MultiLineString )
{
int nLines;
wkbPtr >> nLines;
for ( int i = 0; i < nLines; ++i )
{
wkbPtr.readHeader();
wkbPtr = locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure );
wkbPtr = locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure, hasZM );
}
}

Expand All @@ -1213,7 +1216,7 @@ QgsGeometry* QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, dou

QgsGeometry* QgsGeometryAnalyzer::locateAlongMeasure( double measure, const QgsGeometry *lineGeom )
{
if ( !lineGeom )
if ( !lineGeom || !lineGeom->geometry() )
{
return nullptr;
}
Expand All @@ -1222,25 +1225,29 @@ QgsGeometry* QgsGeometryAnalyzer::locateAlongMeasure( double measure, const QgsG

//need to go with WKB and z coordinate until QgsGeometry supports M values
QgsConstWkbPtr wkbPtr( lineGeom->asWkb(), lineGeom->wkbSize() );
QGis::WkbType wkbType = lineGeom->wkbType();
wkbPtr.readHeader();
QgsWKBTypes::Type wkbType = lineGeom->geometry()->wkbType();

if ( wkbType != QGis::WKBLineString25D && wkbType != QGis::WKBMultiLineString25D )
//only linestring / multilinestring types supported at the moment
if ( QgsWKBTypes::singleType( QgsWKBTypes::flatType( wkbType ) ) != QgsWKBTypes::LineString || QgsWKBTypes::coordDimensions( wkbType ) < 3 )
{
return nullptr;
}

if ( wkbType == QGis::WKBLineString25D )
bool hasZM = QgsWKBTypes::hasZ( wkbType ) && QgsWKBTypes::hasM( wkbType );

if ( QgsWKBTypes::flatType( wkbType ) == QgsWKBTypes::LineString )
{
locateAlongWkbString( wkbPtr, resultGeom, measure );
locateAlongWkbString( wkbPtr, resultGeom, measure, hasZM );
}
else if ( wkbType == QGis::WKBMultiLineString25D )
else if ( QgsWKBTypes::flatType( wkbType ) == QgsWKBTypes::MultiLineString )
{
int nLines;
wkbPtr >> nLines;
for ( int i = 0; i < nLines; ++i )
{
wkbPtr.readHeader();
wkbPtr = locateAlongWkbString( wkbPtr, resultGeom, measure );
wkbPtr = locateAlongWkbString( wkbPtr, resultGeom, measure, hasZM );
}
}

Expand All @@ -1252,7 +1259,7 @@ QgsGeometry* QgsGeometryAnalyzer::locateAlongMeasure( double measure, const QgsG
return QgsGeometry::fromMultiPoint( resultGeom );
}

QgsConstWkbPtr QgsGeometryAnalyzer::locateBetweenWkbString( QgsConstWkbPtr wkbPtr, QgsMultiPolyline& result, double fromMeasure, double toMeasure )
QgsConstWkbPtr QgsGeometryAnalyzer::locateBetweenWkbString( QgsConstWkbPtr wkbPtr, QgsMultiPolyline& result, double fromMeasure, double toMeasure, bool zm )
{
int nPoints;
wkbPtr >> nPoints;
Expand All @@ -1262,7 +1269,12 @@ QgsConstWkbPtr QgsGeometryAnalyzer::locateBetweenWkbString( QgsConstWkbPtr wkbPt
for ( int i = 0; i < nPoints; ++i )
{
double x, y, z;
wkbPtr >> x >> y >> z;
wkbPtr >> x >> y;
if ( zm )
{
wkbPtr += sizeof( double );
}
wkbPtr >> z;

if ( i > 0 )
{
Expand Down Expand Up @@ -1299,7 +1311,7 @@ QgsConstWkbPtr QgsGeometryAnalyzer::locateBetweenWkbString( QgsConstWkbPtr wkbPt
return wkbPtr;
}

QgsConstWkbPtr QgsGeometryAnalyzer::locateAlongWkbString( QgsConstWkbPtr wkbPtr, QgsMultiPoint& result, double measure )
QgsConstWkbPtr QgsGeometryAnalyzer::locateAlongWkbString( QgsConstWkbPtr wkbPtr, QgsMultiPoint& result, double measure, bool zm )
{
int nPoints;
wkbPtr >> nPoints;
Expand All @@ -1308,7 +1320,12 @@ QgsConstWkbPtr QgsGeometryAnalyzer::locateAlongWkbString( QgsConstWkbPtr wkbPtr,
double prevx = 0.0, prevy = 0.0, prevz = 0.0;
for ( int i = 0; i < nPoints; ++i )
{
wkbPtr >> x >> y >> z;
wkbPtr >> x >> y;
if ( zm )
{
wkbPtr += sizeof( double );
}
wkbPtr >> z;

if ( i > 0 )
{
Expand Down
10 changes: 5 additions & 5 deletions src/analysis/vector/qgsgeometryanalyzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
int uniqueIdField = -1, QProgressDialog* p = nullptr );

/** Creates an event layer (multipoint or multiline) by locating features from a (non-spatial) event table along the features of a line layer.
* Note that currently (until QgsGeometry supports m-values) the z-coordinate of the line layer is used for linear referencing
* Note that this function only supports linestring / multilinestring 25D/Z/M/ZM types as input
* @param lineLayer layer with the line geometry
* @param eventLayer layer with features and location field
* @param lineField join index in line layer
Expand All @@ -120,10 +120,10 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
const QString& outputFormat, int locationField1, int locationField2 = -1, int offsetField = -1, double offsetScale = 1.0,
bool forceSingleGeometry = false, QgsVectorDataProvider* memoryProvider = nullptr, QProgressDialog* p = nullptr );

/** 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)*/
/** Returns linear reference geometry as a multiline (or 0 if no match). This function only supports linestring/multilinestring 25D/Z/M/ZM types*/
QgsGeometry* locateBetweenMeasures( double fromMeasure, double toMeasure, const QgsGeometry *lineGeom );
/** Returns linear reference geometry. Unlike the PostGIS function, this method always returns multipoint or 0 if no match (not geometry collection).
* Currently, the z-coordinates are considered to be the measures (no support for m-values in QGIS)
* Note that this function only supports linestring / multilinestring 25D/Z/M/ZM types as input
*/
QgsGeometry* locateAlongMeasure( double measure, const QgsGeometry* lineGeom );

Expand Down Expand Up @@ -152,8 +152,8 @@ class ANALYSIS_EXPORT QgsGeometryAnalyzer
@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, QgsGeometry* lineGeom, double offset );
QgsPoint createPointOffset( double x, double y, double dist, QgsGeometry* lineGeom ) const;
QgsConstWkbPtr locateBetweenWkbString( QgsConstWkbPtr ptr, QgsMultiPolyline& result, double fromMeasure, double toMeasure );
QgsConstWkbPtr locateAlongWkbString( QgsConstWkbPtr ptr, QgsMultiPoint& result, double measure );
QgsConstWkbPtr locateBetweenWkbString( QgsConstWkbPtr ptr, QgsMultiPolyline& result, double fromMeasure, double toMeasure, bool zm );
QgsConstWkbPtr locateAlongWkbString( QgsConstWkbPtr ptr, QgsMultiPoint& result, double measure, bool zm );
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 );
static void locateAlongSegment( double x1, double y1, double m1, double x2, double y2, double m2, double measure, bool& pt1Ok, QgsPoint& pt1, bool& pt2Ok, QgsPoint& pt2 );
};
Expand Down

0 comments on commit c151724

Please sign in to comment.