QGIS API Documentation
3.14.0-Pi (9f7028fd23)
|
Go to the documentation of this file.
40 return a.second > b.second;
48 int np = coords.count();
52 double x0 = coords[0].x(), y0 = coords[0].y();
55 for (
int i = 1; i < np; ++i )
59 dist += std::sqrt( ( x1 - x0 ) * ( x1 - x0 ) + ( y1 - y0 ) * ( y1 - y0 ) );
70 double sqrDist = std::numeric_limits<double>::max();
72 int plcount = pl.count();
73 double prevX = pldata[0].
x(), prevY = pldata[0].
y();
74 double segmentPtX, segmentPtY;
75 for (
int i = 1; i < plcount; ++i )
77 double currentX = pldata[i].
x();
78 double currentY = pldata[i].
y();
80 if ( testDist < sqrDist )
135 const auto constEdges = edges;
141 int v1 = -1, v2 = -1;
174 int eIdx = g->
e.count() - 1;
175 g->
v[v1].edges << eIdx;
176 g->
v[v2].edges << eIdx;
185 if ( v1 == -1 || v2 == -1 )
186 return QVector<QgsPointXY>();
190 std::priority_queue< DijkstraQueueItem, std::vector< DijkstraQueueItem >,
comp > Q;
193 QVector<double> D( g.
v.count(), std::numeric_limits<double>::max() );
197 QVector<bool> F( g.
v.count() );
200 QVector<int> S( g.
v.count(), -1 );
217 const int *vuEdges = vu.
edges.constData();
218 int count = vu.
edges.count();
219 for (
int i = 0; i < count; ++i )
224 if ( !F[v] && D[u] + w < D[v] )
236 return QVector<QgsPointXY>();
240 QVector<QgsPointXY> points;
246 QVector<QgsPointXY> edgePoints = e.
coords;
247 if ( edgePoints[0] != g.
v[u].pt )
248 std::reverse( edgePoints.begin(), edgePoints.end() );
249 if ( !points.isEmpty() )
250 points.remove( points.count() - 1 );
251 points << edgePoints;
255 std::reverse( path.begin(), path.end() );
259 std::reverse( points.begin(), points.end() );
268 for (
int i = 0; i < g.
v.count(); ++i )
271 if ( v.
pt == pt || ( std::fabs( v.
pt.
x() - pt.
x() ) < epsilon && std::fabs( v.
pt.
y() - pt.
y() ) < epsilon ) )
281 for (
int i = 0; i < g.
e.count(); ++i )
287 int vertexAfter = -1;
291 lineVertexAfter = vertexAfter;
301 int count1 = lineVertexAfter;
302 int count2 = points.count() - lineVertexAfter;
304 for (
int i = 0; i < count1; ++i )
306 if ( points[lineVertexAfter - 1] != pt )
309 if ( pt != points[lineVertexAfter] )
311 for (
int i = 0; i < count2; ++i )
312 pts2 << points[i + lineVertexAfter];
320 int eIdx =
point2edge( g, pt, lineVertexAfter );
334 int vIdx = g.
v.count();
335 int e1Idx = g.
e.count();
336 int e2Idx = e1Idx + 1;
342 v.
edges << e1Idx << e2Idx;
355 v1.
edges.replace( v1.
edges.indexOf( eIdx ), e1Idx );
356 v2.
edges.replace( v2.
edges.indexOf( eIdx ), e2Idx );
391 if ( eIdx >= g.
e.count() )
395 for (
int i = 0; i < v1.
edges.count(); ++i )
397 if ( v1.
edges[i] >= g.
e.count() )
398 v1.
edges.remove( i-- );
403 for (
int i = 0; i < v2.
edges.count(); ++i )
405 if ( v2.
edges[i] >= g.
e.count() )
406 v2.
edges.remove( i-- );
423 if ( !segmentizedGeomV2 )
472 bool QgsTracer::initGraph()
477 mHasTopologyProblem =
false;
486 QElapsedTimer t1, t2, t2a, t3;
489 int featuresCounted = 0;
490 bool enableInvisibleFeature =
QgsSettings().
value( QStringLiteral(
"/qgis/digitizing/snap_invisible_feature" ),
false ).toBool();
495 std::unique_ptr< QgsFeatureRenderer > renderer;
496 std::unique_ptr<QgsRenderContext> ctx;
498 if ( !enableInvisibleFeature && mRenderContext && vl->renderer() )
500 renderer.reset( vl->renderer()->clone() );
505 renderer->startRender( *ctx.get(), vl->fields() );
526 ctx->expressionContext().setFeature( f );
527 if ( !renderer->willRenderFeature( f, *ctx.get() ) )
536 if ( mMaxFeatureCount != 0 && featuresCounted >= mMaxFeatureCount )
542 renderer->stopRender( *ctx.get() );
545 int timeExtract = t1.elapsed();
551 int timeNodingCall = 0;
564 timeNodingCall = t2a.elapsed();
570 catch ( GEOSException &e )
575 mHasTopologyProblem =
true;
577 QgsDebugMsg( QStringLiteral(
"Tracer Noding Exception: %1" ).arg( e.what() ) );
581 int timeNoding = t2.elapsed();
587 int timeMake = t3.elapsed();
589 Q_UNUSED( timeExtract )
590 Q_UNUSED( timeNoding )
591 Q_UNUSED( timeNodingCall )
593 QgsDebugMsg( QStringLiteral(
"tracer extract %1 ms, noding %2 ms (call %3 ms), make %4 ms" )
594 .arg( timeExtract ).arg( timeNoding ).arg( timeNodingCall ).arg( timeMake ) );
617 disconnect( layer, &QObject::destroyed,
this, &QgsTracer::onLayerDestroyed );
630 connect( layer, &QObject::destroyed,
this, &QgsTracer::onLayerDestroyed );
639 mTransformContext = context;
665 quadSegments = mOffsetSegments;
666 joinStyle = mOffsetJoinStyle;
667 miterLimit = mOffsetMiterLimit;
672 mOffsetSegments = quadSegments;
673 mOffsetJoinStyle = joinStyle;
674 mOffsetMiterLimit = miterLimit;
691 mGraph.reset(
nullptr );
713 void QgsTracer::onAttributeValueChanged(
QgsFeatureId fid,
int idx,
const QVariant &value )
721 void QgsTracer::onDataChanged( )
726 void QgsTracer::onStyleChanged( )
731 void QgsTracer::onLayerDestroyed( QObject *obj )
744 return QVector<QgsPointXY>();
751 int tPrep = t.elapsed();
756 return QVector<QgsPointXY>();
761 return QVector<QgsPointXY>();
767 int tPath = t2.elapsed();
771 QgsDebugMsg( QStringLiteral(
"path timing: prep %1 ms, path %2 ms" ).arg( tPrep ).arg( tPath ) );
775 if ( !points.isEmpty() && mOffset != 0 )
777 QVector<QgsPointXY> pointsInput( points );
780 std::unique_ptr<QgsAbstractGeometry> linestringOffset( linestringEngine->offsetCurve( mOffset, mOffsetSegments, mOffsetJoinStyle, mOffsetMiterLimit ) );
781 if (
QgsLineString *ls2 = qgsgeometry_cast<QgsLineString *>( linestringOffset.get() ) )
784 for (
int i = 0; i < ls2->numPoints(); ++i )
788 if ( points.count() >= 2 )
790 QgsPointXY res1 = points.first(), res2 = points.last();
791 double diffNormal = res1.
distance( p1 ) + res2.distance( p2 );
792 double diffReversed = res1.
distance( p2 ) + res2.distance( p1 );
793 if ( diffReversed < diffNormal )
794 std::reverse( points.begin(), points.end() );
815 int e =
point2edge( *mGraph, pt, lineVertexAfter );
@ Filter
Features may be filtered, i.e. some features may not be rendered (categorized, rule based ....
QgsTracerGraph * makeGraph(const QVector< QgsPolylineXY > &edges)
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item.
QVector< QgsPointXY > findShortestPath(const QgsPointXY &p1, const QgsPointXY &p2, PathError *error=nullptr)
Given two points, find the shortest path and return points on the way.
static QgsGeometry fromMultiPolylineXY(const QgsMultiPolylineXY &multiline)
Creates a new geometry from a QgsMultiPolylineXY object.
bool init()
Build the internal data structures.
static QgsGeometry geometryFromGeos(GEOSGeometry *geos)
Creates a new QgsGeometry object, feeding in a geometry in GEOS format.
const QgsCoordinateReferenceSystem & crs
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
QgsPointXY pt
location of the vertex
int otherVertex(int v0) const
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
void setOffset(double offset)
Set offset in map units that should be applied to the traced paths returned from findShortestPath().
QgsWkbTypes::Type wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
@ ErrNoPath
Points are not connected in the graph.
int point2vertex(const QgsTracerGraph &g, const QgsPointXY &pt, double epsilon=1e-6)
double offset() const
Gets offset in map units that should be applied to the traced paths returned from findShortestPath().
void featureDeleted(QgsFeatureId fid)
Emitted when a feature has been deleted.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Line string geometry type, with support for z-dimension and m-values.
QList< QgsVectorLayer * > layers() const
Gets layers used for tracing.
QVector< QgsPointXY > coords
coordinates of the edge (including endpoints)
double closestSegment(const QgsPolylineXY &pl, const QgsPointXY &pt, int &vertexAfter, double epsilon)
void extractLinework(const QgsGeometry &g, QgsMultiPolylineXY &mpl)
QgsMultiPolylineXY asMultiPolyline() const
Returns the contents of the geometry as a multi-linestring.
@ ErrPoint2
End point cannot be joined to the graph.
QgsExpressionContext * expressionContext()
Returns the expression context used to evaluate filter expressions.
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
void invalidateGraph()
Destroy the existing graph structure if any (de-initialize)
QgsRectangle extent() const
Gets extent to which graph's features will be limited (empty extent means no limit)
void setRenderContext(const QgsRenderContext *renderContext)
Sets the renderContext used for tracing only on visible features.
void setOffsetParameters(int quadSegments, int joinStyle, double miterLimit)
Set extra parameters for offset curve algorithm (used when offset is non-zero)
QVector< int > edges
indices of adjacent edges (used in Dijkstra algorithm)
static geos::unique_ptr asGeos(const QgsGeometry &geometry, double precision=0)
Returns a geos geometry - caller takes ownership of the object (should be deleted with GEOSGeom_destr...
QgsPolygonXY asPolygon() const
Returns the contents of the geometry as a polygon.
std::pair< int, double > DijkstraQueueItem
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the crs and transform context used for tracing.
int joinedVertices
Temporarily added vertices (for each there are two extra edges)
void styleChanged()
Signal emitted whenever a change affects the layer's style.
void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &value)
Emitted whenever an attribute value change is done in the edit buffer.
QVector< E > e
Edges of the graph.
QgsTracer()
Constructor for QgsTracer.
double distance(double x, double y) const
Returns the distance between this point and a specified x, y coordinate.
@ ErrTooManyFeatures
Max feature count threshold was reached while reading features.
void setExtent(const QgsRectangle &extent)
Sets extent to which graph's features will be limited (empty extent means no limit)
QSet< int > inactiveEdges
Temporarily removed edges.
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
static double sqrDistToLine(double ptX, double ptY, double x1, double y1, double x2, double y2, double &minDistX, double &minDistY, double epsilon)
Returns the squared distance between a point and a line.
int joinVertexToGraph(QgsTracerGraph &g, const QgsPointXY &pt)
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
void offsetParameters(int &quadSegments, int &joinStyle, double &miterLimit)
Gets extra parameters for offset curve algorithm (used when offset is non-zero)
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
int point2edge(const QgsTracerGraph &g, const QgsPointXY &pt, int &lineVertexAfter, double epsilon=1e-6)
Abstract base class for all geometries.
static GEOSContextHandle_t getGEOSHandler()
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
void dataChanged()
Data of layer changed.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine.
void resetGraph(QgsTracerGraph &g)
bool nextFeature(QgsFeature &f)
Simple graph structure for shortest path search.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void splitLinestring(const QgsPolylineXY &points, const QgsPointXY &pt, int lineVertexAfter, QgsPolylineXY &pts1, QgsPolylineXY &pts2)
void geometryChanged(QgsFeatureId fid, const QgsGeometry &geometry)
Emitted whenever a geometry change is done in the edit buffer.
virtual void configure()
Allows derived classes to setup the settings just before the tracer is initialized.
QVector< V > v
Vertices of the graph.
QgsPolylineXY asPolyline() const
Returns the contents of the geometry as a polyline.
static bool isCurvedType(Type type)
Returns true if the WKB type is a curved type or can contain curved geometries.
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
double distance2D(const QgsPolylineXY &coords)
int v1
vertices that the edge connects
PathError
Possible errors that may happen when calling findShortestPath()
bool isPointSnapped(const QgsPointXY &pt)
Find out whether the point is snapped to a vertex or edge (i.e. it can be used for tracing start/stop...
QVector< QgsPointXY > shortestPath(const QgsTracerGraph &g, int v1, int v2)
bool isEmpty() const
Returns true if the rectangle is empty.
void setLayers(const QList< QgsVectorLayer * > &layers)
Sets layers used for tracing.
bool operator()(DijkstraQueueItem a, DijkstraQueueItem b)
@ ErrPoint1
Start point cannot be joined to the graph.
static Type flatType(Type type)
Returns the flat type for a WKB type.
QgsMultiPolygonXY asMultiPolygon() const
Returns the contents of the geometry as a multi-polygon.
int pointInGraph(QgsTracerGraph &g, const QgsPointXY &pt)
void featureAdded(QgsFeatureId fid)
Emitted when a new feature has been added to the layer.