bool QgsGeometryCollection::dropMValue() { if ( mWkbType != QgsWkbTypes::GeometryCollection && !isMeasure() ) return false; mWkbType = QgsWkbTypes::dropM( mWkbType ); for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) { geom->dropMValue(); } clearCache(); return true; }
bool QgsCircularString::fromWkt( const QString &wkt ) { clear(); QPair<QgsWkbTypes::Type, QString> parts = QgsGeometryUtils::wktReadBlock( wkt ); if ( QgsWkbTypes::flatType( parts.first ) != QgsWkbTypes::CircularString ) return false; mWkbType = parts.first; setPoints( QgsGeometryUtils::pointsFromWKT( parts.second, is3D(), isMeasure() ) ); return true; }
bool QgsMultiLineString::addGeometry( QgsAbstractGeometry *g ) { if ( !dynamic_cast<QgsLineString *>( g ) ) { delete g; return false; } if ( mGeometries.empty() ) { setZMTypeFromSubGeometry( g, QgsWkbTypes::MultiLineString ); } if ( is3D() && !g->is3D() ) g->addZValue(); else if ( !is3D() && g->is3D() ) g->dropZValue(); if ( isMeasure() && !g->isMeasure() ) g->addMValue(); else if ( !isMeasure() && g->isMeasure() ) g->dropMValue(); return QgsGeometryCollection::addGeometry( g ); }
bool QgsMultiPolygon::addGeometry( QgsAbstractGeometry *g ) { if ( !qgsgeometry_cast<QgsPolygon *>( g ) ) { delete g; return false; } if ( mGeometries.empty() ) { setZMTypeFromSubGeometry( g, QgsWkbTypes::MultiPolygon ); } if ( is3D() && !g->is3D() ) g->addZValue(); else if ( !is3D() && g->is3D() ) g->dropZValue(); if ( isMeasure() && !g->isMeasure() ) g->addMValue(); else if ( !isMeasure() && g->isMeasure() ) g->dropMValue(); return QgsGeometryCollection::addGeometry( g ); // clazy:exclude=skipped-base-method }
void QgsCircularString::deleteVertex( int i ) { mX.remove( i ); mY.remove( i ); if ( is3D() ) { mZ.remove( i ); } if ( isMeasure() ) { mM.remove( i ); } clearCache(); }
QgsPointV2 QgsCircularString::pointN( int i ) const { if ( qMin( mX.size(), mY.size() ) <= i ) { return QgsPointV2(); } double x = mX.at( i ); double y = mY.at( i ); double z = 0; double m = 0; if ( is3D() ) { z = mZ.at( i ); } if ( isMeasure() ) { m = mM.at( i ); } QgsWkbTypes::Type t = QgsWkbTypes::Point; if ( is3D() && isMeasure() ) { t = QgsWkbTypes::PointZM; } else if ( is3D() ) { t = QgsWkbTypes::PointZ; } else if ( isMeasure() ) { t = QgsWkbTypes::PointM; } return QgsPointV2( t, x, y, z, m ); }
QgsCircularString *QgsCircularString::reversed() const { QgsCircularString *copy = clone(); std::reverse( copy->mX.begin(), copy->mX.end() ); std::reverse( copy->mY.begin(), copy->mY.end() ); if ( is3D() ) { std::reverse( copy->mZ.begin(), copy->mZ.end() ); } if ( isMeasure() ) { std::reverse( copy->mM.begin(), copy->mM.end() ); } return copy; }
bool QgsCurvePolygon::dropMValue() { if ( !isMeasure() ) return false; mWkbType = QgsWkbTypes::dropM( mWkbType ); if ( mExteriorRing ) mExteriorRing->dropMValue(); for ( QgsCurve *curve : qgis::as_const( mInteriorRings ) ) { curve->dropMValue(); } clearCache(); return true; }
void QgsLineStringV2::addVertex( const QgsPointV2& pt ) { if ( mWkbType == QgsWKBTypes::Unknown ) { setZMTypeFromSubGeometry( &pt, QgsWKBTypes::LineString ); } mCoords.append( QPointF( pt.x(), pt.y() ) ); if ( is3D() ) { mZ.append( pt.z() ); } if ( isMeasure() ) { mM.append( pt.m() ); } }
bool QgsLineStringV2::insertVertex( const QgsVertexId& position, const QgsPointV2& vertex ) { if ( position.vertex < 0 || position.vertex > mCoords.size() ) { return false; } mCoords.insert( position.vertex, QPointF( vertex.x(), vertex.y() ) ); if ( is3D() ) { mZ.insert( position.vertex, vertex.z() ); } if ( isMeasure() ) { mM.insert( position.vertex, vertex.m() ); } return true; }
void QgsLineString::filterVertices( const std::function<bool ( const QgsPoint & )> &filter ) { bool hasZ = is3D(); bool hasM = isMeasure(); int size = mX.size(); double *srcX = mX.data(); double *srcY = mY.data(); double *srcM = hasM ? mM.data() : nullptr; double *srcZ = hasZ ? mZ.data() : nullptr; double *destX = srcX; double *destY = srcY; double *destM = srcM; double *destZ = srcZ; int filteredPoints = 0; for ( int i = 0; i < size; ++i ) { double x = *srcX++; double y = *srcY++; double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN(); double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN(); if ( filter( QgsPoint( x, y, z, m ) ) ) { filteredPoints++; *destX++ = x; *destY++ = y; if ( hasM ) *destM++ = m; if ( hasZ ) *destZ++ = z; } } mX.resize( filteredPoints ); mY.resize( filteredPoints ); if ( hasZ ) mZ.resize( filteredPoints ); if ( hasM ) mM.resize( filteredPoints ); clearCache(); }
bool QgsLineStringV2::deleteVertex( const QgsVertexId& position ) { if ( position.vertex >= mCoords.size() || position.vertex < 0 ) { return false; } mCoords.remove( position.vertex ); if ( is3D() ) { mZ.remove( position.vertex ); } if ( isMeasure() ) { mM.remove( position.vertex ); } return true; }
void QgsLineStringV2::addVertex( const QgsPointV2& pt ) { if ( mWkbType == QgsWKBTypes::Unknown ) { setZMTypeFromSubGeometry( &pt, QgsWKBTypes::LineString ); } mCoords.append( QPointF( pt.x(), pt.y() ) ); if ( is3D() ) { mZ.append( pt.z() ); } if ( isMeasure() ) { mM.append( pt.m() ); } mBoundingBox = QgsRectangle(); //set bounding box invalid so it needs to be recalculated next time }
bool QgsLineStringV2::insertVertex( const QgsVertexId& position, const QgsPointV2& vertex ) { if ( position.vertex < 0 || position.vertex >= mCoords.size() ) { return false; } mCoords.insert( position.vertex, QPointF( vertex.x(), vertex.y() ) ); if ( is3D() ) { mZ.insert( position.vertex, vertex.z() ); } if ( isMeasure() ) { mM.insert( position.vertex, vertex.m() ); } mBoundingBox = QgsRectangle(); //set bounding box invalid so it needs to be recalculated next time return true; }
bool QgsLineStringV2::moveVertex( const QgsVertexId& position, const QgsPointV2& newPos ) { if ( position.vertex < 0 || position.vertex >= mX.size() ) { return false; } mX[position.vertex] = newPos.x(); mY[position.vertex] = newPos.y(); if ( is3D() && newPos.is3D() ) { mZ[position.vertex] = newPos.z(); } if ( isMeasure() && newPos.isMeasure() ) { mM[position.vertex] = newPos.m(); } mBoundingBox = QgsRectangle(); //set bounding box invalid return true; }
void QgsLineStringV2::addVertex( const QgsPointV2& pt ) { if ( mWkbType == QgsWKBTypes::Unknown || mX.isEmpty() ) { setZMTypeFromSubGeometry( &pt, QgsWKBTypes::LineString ); } mX.append( pt.x() ); mY.append( pt.y() ); if ( is3D() ) { mZ.append( pt.z() ); } if ( isMeasure() ) { mM.append( pt.m() ); } mBoundingBox = QgsRectangle(); //set bounding box invalid }
bool QgsLineString::moveVertex( QgsVertexId position, const QgsPoint &newPos ) { if ( position.vertex < 0 || position.vertex >= mX.size() ) { return false; } mX[position.vertex] = newPos.x(); mY[position.vertex] = newPos.y(); if ( is3D() && newPos.is3D() ) { mZ[position.vertex] = newPos.z(); } if ( isMeasure() && newPos.isMeasure() ) { mM[position.vertex] = newPos.m(); } clearCache(); //set bounding box invalid return true; }
bool QgsLineStringV2::deleteVertex( const QgsVertexId& position ) { if ( position.vertex >= mCoords.size() || position.vertex < 0 ) { return false; } mCoords.remove( position.vertex ); if ( is3D() ) { mZ.remove( position.vertex ); } if ( isMeasure() ) { mM.remove( position.vertex ); } mBoundingBox = QgsRectangle(); //set bounding box invalid so it needs to be recalculated next time return true; }
void QgsCurvePolygon::addInteriorRing( QgsCurve *ring ) { if ( !ring ) return; //ensure dimensionality of ring matches curve polygon if ( !is3D() ) ring->dropZValue(); else if ( !ring->is3D() ) ring->addZValue(); if ( !isMeasure() ) ring->dropMValue(); else if ( !ring->isMeasure() ) ring->addMValue(); mInteriorRings.append( ring ); clearCache(); }
QgsPointV2 QgsLineStringV2::pointN( int i ) const { if ( i < 0 || i >= mX.size() ) { return QgsPointV2(); } double x = mX.at( i ); double y = mY.at( i ); double z = 0; double m = 0; bool hasZ = is3D(); if ( hasZ ) { z = mZ.at( i ); } bool hasM = isMeasure(); if ( hasM ) { m = mM.at( i ); } QgsWKBTypes::Type t = QgsWKBTypes::Point; if ( mWkbType == QgsWKBTypes::LineString25D ) { t = QgsWKBTypes::Point25D; } else if ( hasZ && hasM ) { t = QgsWKBTypes::PointZM; } else if ( hasZ ) { t = QgsWKBTypes::PointZ; } else if ( hasM ) { t = QgsWKBTypes::PointM; } return QgsPointV2( t, x, y, z, m ); }
QgsPoint QgsLineString::pointN( int i ) const { if ( i < 0 || i >= mX.size() ) { return QgsPoint(); } double x = mX.at( i ); double y = mY.at( i ); double z = std::numeric_limits<double>::quiet_NaN(); double m = std::numeric_limits<double>::quiet_NaN(); bool hasZ = is3D(); if ( hasZ ) { z = mZ.at( i ); } bool hasM = isMeasure(); if ( hasM ) { m = mM.at( i ); } QgsWkbTypes::Type t = QgsWkbTypes::Point; if ( mWkbType == QgsWkbTypes::LineString25D ) { t = QgsWkbTypes::Point25D; } else if ( hasZ && hasM ) { t = QgsWkbTypes::PointZM; } else if ( hasZ ) { t = QgsWkbTypes::PointZ; } else if ( hasM ) { t = QgsWkbTypes::PointM; } return QgsPoint( t, x, y, z, m ); }
void MeasureBase::scanElements(void* data, void (*func)(void*, Element*), bool all) { if (isMeasure()) { for (Element* e : _el) { if (score()->tagIsValid(e->tag())) { if (e->staffIdx() >= score()->staves().size()) qDebug("MeasureBase::scanElements: bad staffIdx %d in element %s", e->staffIdx(), e->name()); if ((e->track() == -1) || e->systemFlag() || ((Measure*)this)->visible(e->staffIdx())) e->scanElements(data, func, all); } } } else { for (Element* e : _el) { if (score()->tagIsValid(e->tag())) e->scanElements(data, func, all); } } func(data, this); }
bool QgsLineStringV2::deleteVertex( const QgsVertexId& position ) { if ( position.vertex >= mX.size() || position.vertex < 0 ) { return false; } mX.remove( position.vertex ); mY.remove( position.vertex ); if ( is3D() ) { mZ.remove( position.vertex ); } if ( isMeasure() ) { mM.remove( position.vertex ); } mBoundingBox = QgsRectangle(); //set bounding box invalid return true; }
void QgsLineString::transform( const QTransform &t, double zTranslate, double zScale, double mTranslate, double mScale ) { int nPoints = numPoints(); bool hasZ = is3D(); bool hasM = isMeasure(); for ( int i = 0; i < nPoints; ++i ) { qreal x, y; t.map( mX.at( i ), mY.at( i ), &x, &y ); mX[i] = x; mY[i] = y; if ( hasZ ) { mZ[i] = mZ.at( i ) * zScale + zTranslate; } if ( hasM ) { mM[i] = mM.at( i ) * mScale + mTranslate; } } clearCache(); }
bool QgsCircularString::fromWkb( QgsConstWkbPtr &wkbPtr ) { if ( !wkbPtr ) return false; QgsWkbTypes::Type type = wkbPtr.readHeader(); if ( QgsWkbTypes::flatType( type ) != QgsWkbTypes::CircularString ) { return false; } clearCache(); mWkbType = type; //type bool hasZ = is3D(); bool hasM = isMeasure(); int nVertices = 0; wkbPtr >> nVertices; mX.resize( nVertices ); mY.resize( nVertices ); hasZ ? mZ.resize( nVertices ) : mZ.clear(); hasM ? mM.resize( nVertices ) : mM.clear(); for ( int i = 0; i < nVertices; ++i ) { wkbPtr >> mX[i]; wkbPtr >> mY[i]; if ( hasZ ) { wkbPtr >> mZ[i]; } if ( hasM ) { wkbPtr >> mM[i]; } } return true; }
void QgsLineStringV2::importVerticesFromWkb( const QgsConstWkbPtr& wkb ) { bool hasZ = is3D(); bool hasM = isMeasure(); int nVertices = 0; wkb >> nVertices; mCoords.resize( nVertices ); hasZ ? mZ.resize( nVertices ) : mZ.clear(); hasM ? mM.resize( nVertices ) : mM.clear(); for ( int i = 0; i < nVertices; ++i ) { wkb >> mCoords[i].rx(); wkb >> mCoords[i].ry(); if ( hasZ ) { wkb >> mZ[i]; } if ( hasM ) { wkb >> mM[i]; } } }
bool QgsLineStringV2::operator==( const QgsLineStringV2& other ) const { if ( mWkbType != other.mWkbType ) return false; if ( mX.count() != other.mX.count() ) return false; for ( int i = 0; i < mX.count(); ++i ) { if ( !qgsDoubleNear( mX.at( i ), other.mX.at( i ) ) || !qgsDoubleNear( mY.at( i ), other.mY.at( i ) ) ) return false; if ( is3D() && !qgsDoubleNear( mZ.at( i ), other.mZ.at( i ) ) ) return false; if ( isMeasure() && !qgsDoubleNear( mM.at( i ), other.mM.at( i ) ) ) return false; } return true; }
QgsPointV2 QgsLineStringV2::pointN( int i ) const { if ( mCoords.size() <= i ) { return QgsPointV2(); } const QPointF& pt = mCoords.at( i ); double z = 0; double m = 0; bool hasZ = is3D(); if ( hasZ ) { z = mZ.at( i ); } bool hasM = isMeasure(); if ( hasM ) { m = mM.at( i ); } QgsWKBTypes::Type t = QgsWKBTypes::Point; if ( hasZ && hasM ) { t = QgsWKBTypes::PointZM; } else if ( hasZ ) { t = QgsWKBTypes::PointZ; } else if ( hasM ) { t = QgsWKBTypes::PointM; } return QgsPointV2( t, pt.x(), pt.y(), z, m ); }
bool QgsCurve::snapToGridPrivate( double hSpacing, double vSpacing, double dSpacing, double mSpacing, const QVector<double> &srcX, const QVector<double> &srcY, const QVector<double> &srcZ, const QVector<double> &srcM, QVector<double> &outX, QVector<double> &outY, QVector<double> &outZ, QVector<double> &outM ) const { int length = numPoints(); if ( length <= 0 ) return false; bool hasZ = is3D(); bool hasM = isMeasure(); // helper functions auto roundVertex = [hSpacing, vSpacing, dSpacing, mSpacing, hasZ, hasM, &srcX, &srcY, &srcZ, &srcM]( QgsPoint & out, int i ) { if ( hSpacing > 0 ) out.setX( std::round( srcX.at( i ) / hSpacing ) * hSpacing ); else out.setX( srcX.at( i ) ); if ( vSpacing > 0 ) out.setY( std::round( srcY.at( i ) / vSpacing ) * vSpacing ); else out.setY( srcY.at( i ) ); if ( hasZ ) { if ( dSpacing > 0 ) out.setZ( std::round( srcZ.at( i ) / dSpacing ) * dSpacing ); else out.setZ( srcZ.at( i ) ); } if ( hasM ) { if ( mSpacing > 0 ) out.setM( std::round( srcM.at( i ) / mSpacing ) * mSpacing ); else out.setM( srcM.at( i ) ); } }; auto append = [hasZ, hasM, &outX, &outY, &outM, &outZ]( QgsPoint const & point ) { outX.append( point.x() ); outY.append( point.y() ); if ( hasZ ) outZ.append( point.z() ); if ( hasM ) outM.append( point.m() ); }; auto isPointEqual = [dSpacing, mSpacing, hasZ, hasM]( const QgsPoint & a, const QgsPoint & b ) { return ( a.x() == b.x() ) && ( a.y() == b.y() ) && ( !hasZ || dSpacing <= 0 || a.z() == b.z() ) && ( !hasM || mSpacing <= 0 || a.m() == b.m() ); }; // temporary values QgsWkbTypes::Type pointType = QgsWkbTypes::zmType( QgsWkbTypes::Point, hasZ, hasM ); QgsPoint last( pointType ); QgsPoint current( pointType ); // Actual code (what does all the work) roundVertex( last, 0 ); append( last ); for ( int i = 1; i < length; ++i ) { roundVertex( current, i ); if ( !isPointEqual( current, last ) ) { append( current ); last = current; } } // if it's not closed, with 2 points you get a correct line // if it is, you need at least 4 (3 + the vertex that closes) if ( outX.length() < 2 || ( isClosed() && outX.length() < 4 ) ) return false; return true; }
bool QgsGeometryCollection::fromCollectionWkt( const QString &wkt, const QVector<QgsAbstractGeometry *> &subtypes, const QString &defaultChildWkbType ) { clear(); QPair<QgsWkbTypes::Type, QString> parts = QgsGeometryUtils::wktReadBlock( wkt ); if ( QgsWkbTypes::flatType( parts.first ) != QgsWkbTypes::flatType( wkbType() ) ) { qDeleteAll( subtypes ); return false; } mWkbType = parts.first; QString defChildWkbType = QStringLiteral( "%1%2%3 " ).arg( defaultChildWkbType, is3D() ? QStringLiteral( "Z" ) : QString(), isMeasure() ? QStringLiteral( "M" ) : QString() ); const QStringList blocks = QgsGeometryUtils::wktGetChildBlocks( parts.second, defChildWkbType ); for ( const QString &childWkt : blocks ) { QPair<QgsWkbTypes::Type, QString> childParts = QgsGeometryUtils::wktReadBlock( childWkt ); bool success = false; for ( const QgsAbstractGeometry *geom : subtypes ) { if ( QgsWkbTypes::flatType( childParts.first ) == QgsWkbTypes::flatType( geom->wkbType() ) ) { mGeometries.append( geom->clone() ); if ( mGeometries.back()->fromWkt( childWkt ) ) { success = true; break; } } } if ( !success ) { clear(); qDeleteAll( subtypes ); return false; } } qDeleteAll( subtypes ); //scan through geometries and check if dimensionality of geometries is different to collection. //if so, update the type dimensionality of the collection to match bool hasZ = false; bool hasM = false; for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) { hasZ = hasZ || geom->is3D(); hasM = hasM || geom->isMeasure(); if ( hasZ && hasM ) break; } if ( hasZ ) addZValue( 0 ); if ( hasM ) addMValue( 0 ); return true; }