double QgsGeometryUtils::distanceToVertex( const QgsAbstractGeometryV2 &geom, const QgsVertexId &id ) { double currentDist = 0; QgsVertexId vertexId; QgsPointV2 vertex; QgsPointV2 previousVertex; bool first = true; while ( geom.nextVertex( vertexId, vertex ) ) { if ( !first ) { currentDist += sqrt( QgsGeometryUtils::sqrDistance2D( previousVertex, vertex ) ); } previousVertex = vertex; first = false; if ( vertexId == id ) { //found target vertex return currentDist; } } //could not find target vertex return -1; }
QgsPointV2 QgsGeometryUtils::closestVertex( const QgsAbstractGeometryV2& geom, const QgsPointV2& pt, QgsVertexId& id ) { double minDist = std::numeric_limits<double>::max(); double currentDist = 0; QgsPointV2 minDistPoint; QgsVertexId vertexId; QgsPointV2 vertex; while ( geom.nextVertex( vertexId, vertex ) ) { currentDist = QgsGeometryUtils::sqrDistance2D( pt, vertex ); // The <= is on purpose: for geometries with closing vertices, this ensures // that the closing vertex is retuned. For the node tool, the rubberband // of the closing vertex is above the opening vertex, hence with the <= // situations where the covered opening vertex rubberband is selected are // avoided. if ( currentDist <= minDist ) { minDist = currentDist; minDistPoint = vertex; id.part = vertexId.part; id.ring = vertexId.ring; id.vertex = vertexId.vertex; } } return minDistPoint; }
void QgsGeometryRubberBand::paint( QPainter* painter ) { if ( !mGeometry || !painter ) { return; } painter->save(); painter->translate( -pos() ); if ( mGeometryType == QGis::Polygon ) { painter->setBrush( mBrush ); } else { painter->setBrush( Qt::NoBrush ); } painter->setPen( mPen ); QgsAbstractGeometryV2* paintGeom = mGeometry->clone(); paintGeom->transform( mMapCanvas->getCoordinateTransform()->transform() ); paintGeom->draw( *painter ); //draw vertices QgsVertexId vertexId; QgsPointV2 vertex; while ( paintGeom->nextVertex( vertexId, vertex ) ) { drawVertex( painter, vertex.x(), vertex.y() ); } delete paintGeom; painter->restore(); }