void QgsLineString::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() ); } clearCache(); //set bounding box invalid }
bool QgsLineString::moveVertex( 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(); } clearCache(); //set bounding box invalid return true; }
bool QgsLineStringV2::moveVertex( const QgsVertexId& position, const QgsPointV2& newPos ) { if ( position.vertex < 0 || position.vertex >= mCoords.size() ) { return false; } mCoords[position.vertex].rx() = newPos.x(); mCoords[position.vertex].ry() = 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 QgsMapToolIdentify::closestVertexAttributes( const QgsAbstractGeometryV2& geometry, QgsVertexId vId, QgsMapLayer *layer, QMap< QString, QString >& derivedAttributes ) { QString str = QLocale::system().toString( vId.vertex + 1 ); derivedAttributes.insert( tr( "Closest vertex number" ), str ); QgsPointV2 closestPoint = geometry.vertexAt( vId ); QgsPoint closestPointMapCoords = mCanvas->mapSettings().layerToMapCoordinates( layer, QgsPoint( closestPoint.x(), closestPoint.y() ) ); str = QLocale::system().toString( closestPointMapCoords.x(), 'g', 10 ); derivedAttributes.insert( "Closest vertex X", str ); str = QLocale::system().toString( closestPointMapCoords.y(), 'g', 10 ); derivedAttributes.insert( "Closest vertex Y", str ); if ( closestPoint.is3D() ) { str = QLocale::system().toString( closestPoint.z(), 'g', 10 ); derivedAttributes.insert( "Closest vertex Z", str ); } if ( closestPoint.isMeasure() ) { str = QLocale::system().toString( closestPoint.m(), 'g', 10 ); derivedAttributes.insert( "Closest vertex M", str ); } }
void QgsCircularString::segmentize( const QgsPointV2& p1, const QgsPointV2& p2, const QgsPointV2& p3, QgsPointSequence &points, double tolerance, SegmentationToleranceType toleranceType ) const { //adapted code from postgis double radius = 0; double centerX = 0; double centerY = 0; QgsGeometryUtils::circleCenterRadius( p1, p2, p3, radius, centerX, centerY ); int segSide = segmentSide( p1, p3, p2 ); if ( p1 != p3 && ( radius < 0 || qgsDoubleNear( segSide, 0.0 ) ) ) //points are colinear { points.append( p1 ); points.append( p2 ); points.append( p3 ); return; } bool clockwise = false; if ( segSide == -1 ) { clockwise = true; } double increment = tolerance; //one segment per degree if ( toleranceType == QgsAbstractGeometry::MaximumDifference ) { double halfAngle = acos( -tolerance / radius + 1 ); increment = 2 * halfAngle; } //angles of pt1, pt2, pt3 double a1 = atan2( p1.y() - centerY, p1.x() - centerX ); double a2 = atan2( p2.y() - centerY, p2.x() - centerX ); double a3 = atan2( p3.y() - centerY, p3.x() - centerX ); if ( clockwise ) { increment *= -1; /* Adjust a3 down so we can decrement from a1 to a3 cleanly */ if ( a3 >= a1 ) a3 -= 2.0 * M_PI; if ( a2 > a1 ) a2 -= 2.0 * M_PI; } else { /* Adjust a3 up so we can increment from a1 to a3 cleanly */ if ( a3 <= a1 ) a3 += 2.0 * M_PI; if ( a2 < a1 ) a2 += 2.0 * M_PI; } bool hasZ = is3D(); bool hasM = isMeasure(); double x, y; double z = 0; double m = 0; points.append( p1 ); if ( p2 != p3 && p1 != p2 ) //draw straight line segment if two points have the same position { QgsWkbTypes::Type pointWkbType = QgsWkbTypes::Point; if ( hasZ ) pointWkbType = QgsWkbTypes::addZ( pointWkbType ); if ( hasM ) pointWkbType = QgsWkbTypes::addM( pointWkbType ); //make sure the curve point p2 is part of the segmentized vertices. But only if p1 != p3 bool addP2 = true; if ( qgsDoubleNear( p1.x(), p3.x() ) && qgsDoubleNear( p1.y(), p3.y() ) ) { addP2 = false; } for ( double angle = a1 + increment; clockwise ? angle > a3 : angle < a3; angle += increment ) { if (( addP2 && clockwise && angle < a2 ) || ( addP2 && !clockwise && angle > a2 ) ) { points.append( p2 ); addP2 = false; } x = centerX + radius * cos( angle ); y = centerY + radius * sin( angle ); if ( !hasZ && !hasM ) { points.append( QgsPointV2( x, y ) ); continue; } if ( hasZ ) { z = interpolateArc( angle, a1, a2, a3, p1.z(), p2.z(), p3.z() ); } if ( hasM ) { m = interpolateArc( angle, a1, a2, a3, p1.m(), p2.m(), p3.m() ); } points.append( QgsPointV2( pointWkbType, x, y, z, m ) ); } } points.append( p3 ); }