29static const double SOFT_CONSTRAINT_TOLERANCE_PIXEL = 15;
 
   30static const double SOFT_CONSTRAINT_TOLERANCE_DEGREES = 10;
 
   48  res.
softLockX = std::numeric_limits<double>::quiet_NaN();
 
   49  res.
softLockY = std::numeric_limits<double>::quiet_NaN();
 
   67  int numberOfHardLock = 0;
 
   94      const double dx = edgePt1.
x() - edgePt0.
x();
 
   97        point.
setY( edgePt0.
y() );
 
  101        const double dy = edgePt1.
y() - edgePt0.
y();
 
  102        point.
setY( edgePt0.
y() + ( dy * ( point.
x() - edgePt0.
x() ) ) / dx );
 
  114      if ( std::abs( point.
x() - vertex.
x() ) / ctx.
mapUnitsPerPixel < SOFT_CONSTRAINT_TOLERANCE_PIXEL )
 
  116        point.
setX( vertex.
x() );
 
  137      const double dy = edgePt1.
y() - edgePt0.
y();
 
  140        point.
setX( edgePt0.
x() );
 
  144        const double dx = edgePt1.
x() - edgePt0.
x();
 
  145        point.
setX( edgePt0.
x() + ( dx * ( point.
y() - edgePt0.
y() ) ) / dy );
 
  157      if ( std::abs( point.
y() - vertex.
y() ) / ctx.
mapUnitsPerPixel < SOFT_CONSTRAINT_TOLERANCE_PIXEL )
 
  159        point.
setY( vertex.
y() );
 
  175    double softAngle = std::atan2( point.
y() - previousPt.
y(),
 
  176                                   point.
x() - previousPt.
x() );
 
  177    double deltaAngle = 0;
 
  181      deltaAngle = std::atan2( previousPt.
y() - penultimatePt.
y(),
 
  182                               previousPt.
x() - penultimatePt.
x() );
 
  183      softAngle -= deltaAngle;
 
  185    const int quo = std::round( softAngle / commonAngle );
 
  186    if ( std::fabs( softAngle - quo * commonAngle ) * 180.0 * M_1_PI <= SOFT_CONSTRAINT_TOLERANCE_DEGREES )
 
  189      softAngle = quo * commonAngle;
 
  192      const double dist = std::fabs( std::cos( softAngle + deltaAngle ) * ( previousPt.
y() - point.
y() )
 
  193                                     - std::sin( softAngle + deltaAngle ) * ( previousPt.
x() - point.
x() ) );
 
  204  bool angleLocked = 
false, angleRelative = 
false;
 
  205  double angleValueDeg = 0;
 
  224    double angleValue = angleValueDeg * M_PI / 180;
 
  225    if ( angleRelative && ctx.
cadPoints().count() >= 3 )
 
  228      angleValue += std::atan2( previousPt.
y() - penultimatePt.
y(),
 
  229                                previousPt.
x() - penultimatePt.
x() );
 
  232    const double cosa = std::cos( angleValue );
 
  233    const double sina = std::sin( angleValue );
 
  234    const double v = ( point.
x() - previousPt.
x() ) * cosa + ( point.
y() - previousPt.
y() ) * sina;
 
  252        point.
setY( previousPt.
y() + x * sina / cosa );
 
  268        point.
setX( previousPt.
x() + y * cosa / sina );
 
  273      point.
setX( previousPt.
x() + cosa * v );
 
  274      point.
setY( previousPt.
y() + sina * v );
 
  282      const double x1 = previousPt.
x();
 
  283      const double y1 = previousPt.
y();
 
  284      const double x2 = previousPt.
x() + cosa;
 
  285      const double y2 = previousPt.
y() + sina;
 
  287      const double x3 = edgePt0.
x();
 
  288      const double y3 = edgePt0.
y();
 
  289      const double x4 = edgePt1.
x();
 
  290      const double y4 = edgePt1.
y();
 
  292      const double d = ( x1 - x2 ) * ( y3 - y4 ) - ( y1 - y2 ) * ( x3 - x4 );
 
  296      if ( std::fabs( d ) > 0.01 )
 
  298        point.
setX( ( ( x3 - x4 ) * ( x1 * y2 - y1 * x2 ) - ( x1 - x2 ) * ( x3 * y4 - y3 * x4 ) ) / d );
 
  299        point.
setY( ( ( y3 - y4 ) * ( x1 * y2 - y1 * x2 ) - ( y1 - y2 ) * ( x3 * y4 - y3 * x4 ) ) / d );
 
  316      auto checkLineExtension = [&]( 
QgsPoint vertex )
 
  318        if ( vertex.isEmpty() )
 
  354          else if ( angleLocked )
 
  356            const double angleValue = angleValueDeg * M_PI / 180;
 
  357            const double cosa = std::cos( angleValue );
 
  358            const double sina = std::sin( angleValue );
 
  370            double angleValue = std::atan2( extensionPoint.
y() - vertex.y(),
 
  371                                            extensionPoint.
x() - vertex.x() );
 
  373            const double cosa = std::cos( angleValue );
 
  374            const double sina = std::sin( angleValue );
 
  375            const double v = ( point.
x() - extensionPoint.
x() ) * cosa + ( point.
y() - extensionPoint.
y() ) * sina;
 
  377            point.
setX( extensionPoint.
x() + cosa * v );
 
  378            point.
setY( extensionPoint.
y() + sina * v );
 
  406        bool checked = checkLineExtension( geom->
vertexAt( previousVertexId ) );
 
  410          lineExtensionPt1 = snap.
point();
 
  414        checked = checkLineExtension( geom->
vertexAt( nextVertexId ) );
 
  418          lineExtensionPt1 = snap.
point();
 
  436        const QgsPointXY verticalPt1( point.
x(), point.
y() + 1 );
 
  441          res.
valid &= intersect;
 
  443        else if ( !intersect )
 
  445          res.
softLockX = std::numeric_limits<double>::quiet_NaN();
 
  446          res.
softLockY = std::numeric_limits<double>::quiet_NaN(); 
 
  453        const QgsPointXY horizontalPt1( point.
x() + 1, point.
y() );
 
  458          res.
valid &= intersect;
 
  460        else if ( !intersect )
 
  462          res.
softLockY = std::numeric_limits<double>::quiet_NaN();
 
  478      const double dist = std::sqrt( point.
sqrDist( previousPt ) );
 
  488        point.
set( previousPt.
x() + ( point.
x() - previousPt.
x() ) * vP,
 
  489                   previousPt.
y() + ( point.
y() - previousPt.
y() ) * vP );
 
  502  QgsDebugMsgLevel( QStringLiteral( 
"point:             %1 %2" ).arg( point.
x() ).arg( point.
y() ), 4 );
 
  503  QgsDebugMsgLevel( QStringLiteral( 
"previous point:    %1 %2" ).arg( previousPt.
x() ).arg( previousPt.
y() ), 4 );
 
  504  QgsDebugMsgLevel( QStringLiteral( 
"penultimate point: %1 %2" ).arg( penultimatePt.
x() ).arg( penultimatePt.
y() ), 4 );
 
 
  515  QgsDebugMsgLevel( QStringLiteral( 
"Constraints (locked / relative / value" ), 1 );
 
 
@ AfterVertex
Lock to next vertex.
 
@ NoVertex
Don't lock to vertex.
 
@ BeforeVertex
Lock to previous vertex.
 
Abstract base class for all geometries.
 
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
 
virtual void adjacentVertices(QgsVertexId vertex, QgsVertexId &previousVertex, QgsVertexId &nextVertex) const =0
Returns the vertices adjacent to a specified vertex within a geometry.
 
bool locked
Whether the constraint is active, i.e. should be considered.
 
double value
Numeric value of the constraint (coordinate/distance in map units or angle in degrees)
 
bool relative
Whether the value is relative to previous value.
 
Defines constraints for the QgsCadUtils::alignMapPoint() method.
 
QgsCadUtils::AlignMapPointConstraint xyVertexConstraint
 
QgsCadUtils::AlignMapPointConstraint yConstraint
Constraint for Y coordinate.
 
QgsCadUtils::AlignMapPointConstraint xConstraint
Constraint for X coordinate.
 
double mapUnitsPerPixel
Map units/pixel ratio from map canvas.
 
QgsPoint cadPoint(int index) const
Returns the recent CAD point at the specified index (in map coordinates).
 
QgsCadUtils::AlignMapPointConstraint distanceConstraint
Constraint for distance.
 
bool snappingToFeaturesOverridesCommonAngle
Flag to set snapping to features priority over common angle.
 
QgsSnappingUtils * snappingUtils
Snapping utils that will be used to snap point to map. Must not be nullptr.
 
QgsCadUtils::AlignMapPointConstraint commonAngleConstraint
Constraint for soft lock to a common angle.
 
QQueue< QgsPointLocator::Match > lockedSnapVertices() const
Returns the queue of point locator matches that contain the locked vertices.
 
QgsCadUtils::AlignMapPointConstraint lineExtensionConstraint
 
QList< QgsPoint > cadPoints() const
Returns the list of recent CAD points in map coordinates.
 
void dump() const
Dumps the context's properties, for debugging.
 
QgsCadUtils::AlignMapPointConstraint angleConstraint
Constraint for angle.
 
Structure returned from alignMapPoint() method.
 
Qgis::LineExtensionSide softLockLineExtension
 
QgsPointXY finalMapPoint
map point aligned according to the constraints
 
bool valid
Whether the combination of constraints is actually valid.
 
QgsPointLocator::Match snapMatch
Snapped point - only valid if actually used for something.
 
QgsPointLocator::Match edgeMatch
Snapped segment - only valid if actually used for something.
 
double softLockCommonAngle
Angle (in degrees) to which we have soft-locked ourselves (if not set it is -1)
 
static QgsCadUtils::AlignMapPointOutput alignMapPoint(const QgsPointXY &originalMapPoint, const QgsCadUtils::AlignMapPointContext &ctx)
Applies X/Y/angle/distance constraints from the given context to a map point.
 
Wrapper for iterator of features from vector data provider or vector layer.
 
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
 
Wraps a request for features to a vector layer (or directly its vector data provider).
 
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
 
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
 
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets the feature ID that should be fetched.
 
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
 
static bool lineIntersection(const QgsPoint &p1, QgsVector v1, const QgsPoint &p2, QgsVector v2, QgsPoint &intersection)
Computes the intersection between two lines.
 
static bool lineCircleIntersection(const QgsPointXY ¢er, double radius, const QgsPointXY &linePoint1, const QgsPointXY &linePoint2, QgsPointXY &intersection)
Compute the intersection of a line and a circle.
 
static double distToInfiniteLine(const QgsPoint &point, const QgsPoint &linePoint1, const QgsPoint &linePoint2, double epsilon=1e-7)
Returns the distance between a point and an infinite line.
 
A geometry is the spatial representation of a feature.
 
bool vertexIdFromVertexNr(int number, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
 
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
 
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
 
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
 
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate.
 
void setY(double y)
Sets the y value of the point.
 
void set(double x, double y)
Sets the x and y value of the point.
 
void setX(double x)
Sets the x value of the point.
 
bool isEmpty() const
Returns true if the geometry is empty.
 
Point geometry type, with support for z-dimension and m-values.
 
QgsMapSettings mapSettings() const
 
QgsPointLocator::Match snapToMap(QPoint point, QgsPointLocator::MatchFilter *filter=nullptr, bool relaxed=false)
Snap to map according to the current configuration.
 
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
 
Represent a 2-dimensional vector.
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
#define QgsDebugMsgLevel(str, level)
 
Interface that allows rejection of some matches in intersection queries (e.g.
 
virtual bool acceptMatch(const QgsPointLocator::Match &match)=0
 
QgsFeatureId featureId() const
The id of the feature to which the snapped geometry belongs.
 
QgsVectorLayer * layer() const
The vector layer where the snap occurred.
 
QgsPointXY point() const
for vertex / edge match coords depending on what class returns it (geom.cache: layer coords,...
 
bool hasEdge() const
Returns true if the Match is an edge.
 
void edgePoints(QgsPointXY &pt1, QgsPointXY &pt2) const
Only for a valid edge match - obtain endpoints of the edge.
 
int vertexIndex() const
for vertex / edge match (first vertex of the edge)
 
Utility class for identifying a unique vertex within a geometry.
 
bool isValid() const
Returns true if the vertex id is valid.