QgsGeometry QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, double toMeasure, const QgsGeometry& lineGeom ) { if ( lineGeom.isEmpty() ) { return QgsGeometry(); } QgsMultiPolyline resultGeom; //need to go with WKB and z coordinate until QgsGeometry supports M values QByteArray wkb( lineGeom.exportToWkb() ); QgsConstWkbPtr wkbPtr( wkb ); wkbPtr.readHeader(); QgsWkbTypes::Type wkbType = lineGeom.wkbType(); if ( wkbType != QgsWkbTypes::LineString25D && wkbType != QgsWkbTypes::MultiLineString25D ) { return QgsGeometry(); } if ( wkbType == QgsWkbTypes::LineString25D ) { locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure ); } else if ( wkbType == QgsWkbTypes::MultiLineString25D ) { int nLines; wkbPtr >> nLines; for ( int i = 0; i < nLines; ++i ) { wkbPtr.readHeader(); wkbPtr = locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure ); } }
QgsGeometry* QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, double toMeasure, const QgsGeometry* lineGeom ) { if ( !lineGeom ) { return nullptr; } QgsMultiPolyline resultGeom; //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 ) { return nullptr; } if ( wkbType == QGis::WKBLineString25D ) { locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure ); } else if ( wkbType == QGis::WKBMultiLineString25D ) { int nLines; wkbPtr >> nLines; for ( int i = 0; i < nLines; ++i ) { wkbPtr.readHeader(); wkbPtr = locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure ); } }
QgsGeometry* QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, double toMeasure, QgsGeometry* lineGeom ) { if ( !lineGeom ) { return 0; } QgsMultiPolyline resultGeom; //need to go with WKB and z coordinate until QgsGeometry supports M values unsigned char* lineWkb = lineGeom->asWkb(); unsigned char* ptr = lineWkb + 1; QGis::WkbType wkbType; memcpy( &wkbType, ptr, sizeof( wkbType ) ); ptr += sizeof( wkbType ); if ( wkbType != QGis::WKBLineString25D && wkbType != QGis::WKBMultiLineString25D ) { return 0; } if ( wkbType == QGis::WKBLineString25D ) { locateBetweenWkbString( ptr, resultGeom, fromMeasure, toMeasure ); } else if ( wkbType == QGis::WKBMultiLineString25D ) { int* nLines = ( int* )ptr; ptr += sizeof( int ); for ( int i = 0; i < *nLines; ++i ) { ptr += ( 1 + sizeof( wkbType ) ); ptr = locateBetweenWkbString( ptr, resultGeom, fromMeasure, toMeasure ); } } if ( resultGeom.size() < 1 ) { return 0; } return QgsGeometry::fromMultiPolyline( resultGeom ); }