42 #include <QLinkedList> 47 #define M_PI 3.14159265358979323846 56 mGeos =
const_cast<GEOSGeometry*
>( geom );
62 for (
int i = 0; i <
mHoles.count(); i++ )
64 mHoles.at( i )->holeOf =
this;
76 mHoles.last()->holeOf =
this;
90 const GEOSCoordSequence *coordSeq;
93 type = GEOSGeomTypeId_r( geosctxt, geom );
95 if (
type == GEOS_POLYGON )
97 if ( GEOSGetNumInteriorRings_r( geosctxt, geom ) > 0 )
99 int numHoles = GEOSGetNumInteriorRings_r( geosctxt, geom );
101 for (
int i = 0; i < numHoles; ++i )
103 const GEOSGeometry* interior = GEOSGetInteriorRingN_r( geosctxt, geom, i );
115 geom = GEOSGetExteriorRing_r( geosctxt, geom );
124 nbPoints = GEOSGetNumCoordinates_r( geosctxt, geom );
125 coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, geom );
136 for (
int i = 0; i <
nbPoints; ++i )
138 GEOSCoordSeq_getX_r( geosctxt, coordSeq, i, &
x[i] );
139 GEOSCoordSeq_getY_r( geosctxt, coordSeq, i, &
y[i] );
181 qreal quadOffsetX = quadOffset.
x(), quadOffsetY = quadOffset.
y();
183 if ( quadOffsetX < 0 )
185 if ( quadOffsetY < 0 )
189 else if ( quadOffsetY > 0 )
198 else if ( quadOffsetX > 0 )
200 if ( quadOffsetY < 0 )
204 else if ( quadOffsetY > 0 )
215 if ( quadOffsetY < 0 )
219 else if ( quadOffsetY > 0 )
238 double cost = 0.0001;
241 double xdiff = -labelW / 2.0;
242 double ydiff = -labelH / 2.0;
257 double xd = xdiff * cos( angle ) - ydiff * sin( angle );
258 double yd = xdiff * sin( angle ) + ydiff * cos( angle );
294 double lx = x + xdiff;
295 double ly = y + ydiff;
305 lPos <<
new LabelPosition(
id, lx, ly, labelW, labelH, angle, cost,
this,
false, quadrantFromOffset() );
320 double cost = 0.0001;
333 deltaX = -labelWidth + visualMargin.
right - symbolWidthOffset;
334 deltaY = -visualMargin.
bottom + symbolHeightOffset;
340 deltaX = -labelWidth / 4.0 - visualMargin.
left;
341 deltaY = -visualMargin.
bottom + symbolHeightOffset;
347 deltaX = -labelWidth / 2.0;
348 deltaY = -visualMargin.
bottom + symbolHeightOffset;
354 deltaX = -labelWidth * 3.0 / 4.0 + visualMargin.
right;
355 deltaY = -visualMargin.
bottom + symbolHeightOffset;
361 deltaX = - visualMargin.
left + symbolWidthOffset;
362 deltaY = -visualMargin.
bottom + symbolHeightOffset;
368 deltaX = -labelWidth + visualMargin.
right - symbolWidthOffset;
369 deltaY = -labelHeight / 2.0;
375 deltaX = -visualMargin.
left + symbolWidthOffset;
376 deltaY = -labelHeight / 2.0;
382 deltaX = -labelWidth + visualMargin.
right - symbolWidthOffset;
383 deltaY = -labelHeight + visualMargin.
top - symbolHeightOffset;
389 deltaX = -labelWidth / 4.0 - visualMargin.
left;
390 deltaY = -labelHeight + visualMargin.
top - symbolHeightOffset;
396 deltaX = -labelWidth / 2.0;
397 deltaY = -labelHeight + visualMargin.
top - symbolHeightOffset;
403 deltaX = -labelWidth * 3.0 / 4.0 + visualMargin.
right;
404 deltaY = -labelHeight + visualMargin.
top - symbolHeightOffset;
410 deltaX = -visualMargin.
left + symbolWidthOffset;
411 deltaY = -labelHeight + visualMargin.
top - symbolHeightOffset;
416 double referenceX = cos( alpha ) * distanceToLabel +
x;
417 double referenceY = sin( alpha ) * distanceToLabel +
y;
419 double labelX = referenceX + deltaX;
420 double labelY = referenceY + deltaY;
422 lPos <<
new LabelPosition( i, labelX, labelY, labelWidth, labelHeight, angle, cost,
this,
false, quadrant );
444 double candidateAngleIncrement = 2 *
M_PI / numberCandidates;
447 double a90 =
M_PI / 2;
449 double a270 = a180 + a90;
450 double a360 = 2 *
M_PI;
452 double gamma1, gamma2;
454 if ( distanceToLabel > 0 )
456 gamma1 = atan2( labelHeight / 2, distanceToLabel + labelWidth / 2 );
457 gamma2 = atan2( labelWidth / 2, distanceToLabel + labelHeight / 2 );
461 gamma1 = gamma2 = a90 / 3.0;
464 if ( gamma1 > a90 / 3.0 )
467 if ( gamma2 > a90 / 3.0 )
473 double angleToCandidate;
474 for ( i = 0, angleToCandidate =
M_PI / 4; i < numberCandidates; i++, angleToCandidate += candidateAngleIncrement )
479 if ( angleToCandidate > a360 )
480 angleToCandidate -= a360;
484 if ( angleToCandidate < gamma1 || angleToCandidate > a360 - gamma1 )
486 labelX += distanceToLabel;
487 double iota = ( angleToCandidate + gamma1 );
488 if ( iota > a360 - gamma1 )
492 labelY += -labelHeight + labelHeight * iota / ( 2 * gamma1 );
496 else if ( angleToCandidate < a90 - gamma2 )
498 labelX += distanceToLabel * cos( angleToCandidate );
499 labelY += distanceToLabel * sin( angleToCandidate );
502 else if ( angleToCandidate < a90 + gamma2 )
505 labelX += -labelWidth * ( angleToCandidate - a90 + gamma2 ) / ( 2 * gamma2 );
506 labelY += distanceToLabel;
509 else if ( angleToCandidate < a180 - gamma1 )
511 labelX += distanceToLabel * cos( angleToCandidate ) - labelWidth;
512 labelY += distanceToLabel * sin( angleToCandidate );
515 else if ( angleToCandidate < a180 + gamma1 )
517 labelX += -distanceToLabel - labelWidth;
519 labelY += - ( angleToCandidate - a180 + gamma1 ) * labelHeight / ( 2 * gamma1 );
522 else if ( angleToCandidate < a270 - gamma2 )
524 labelX += distanceToLabel * cos( angleToCandidate ) - labelWidth;
525 labelY += distanceToLabel * sin( angleToCandidate ) - labelHeight;
528 else if ( angleToCandidate < a270 + gamma2 )
530 labelY += -distanceToLabel - labelHeight;
532 labelX += -labelWidth + ( angleToCandidate - a270 + gamma2 ) * labelWidth / ( 2 * gamma2 );
535 else if ( angleToCandidate < a360 )
537 labelX += distanceToLabel * cos( angleToCandidate );
538 labelY += distanceToLabel * sin( angleToCandidate ) - labelHeight;
544 if ( numberCandidates == 1 )
547 cost = 0.0001 + 0.0020 * double( icost ) / double( numberCandidates - 1 );
558 candidates <<
new LabelPosition( i, labelX, labelY, labelWidth, labelHeight, angle, cost,
this,
false, quadrant );
562 if ( icost == numberCandidates )
564 icost = numberCandidates - 1;
567 else if ( icost > numberCandidates )
569 icost = numberCandidates - 2;
577 for (
int i = 0; i < candidates.
count(); ++i )
579 lPos << candidates.
at( i );
583 return candidates.
count();
599 double bx, by, ex, ey;
619 d =
new double[nbPoints-1];
623 for ( i = 0; i < line->
nbPoints - 1; i++ )
628 ad[i] = ad[i-1] + d[i-1];
636 nbls =
static_cast< int >( ll / xrm );
644 dist = qMin( yrm, xrm );
648 l = - ( xrm - ll ) / 2.0;
656 while ( l < ll - xrm )
665 birdfly = sqrt(( x[nbPoints-1] - x[0] ) * ( x[nbPoints-1] - x[0] )
666 + ( y[nbPoints-1] - y[0] ) * ( y[nbPoints-1] - y[0] ) );
668 birdfly = sqrt(( ex - bx ) * ( ex - bx ) + ( ey - by ) * ( ey - by ) );
670 cost = birdfly / xrm;
674 cost = ( 1 - cost ) / 100;
677 double costCenter = qAbs( ll / 2 - ( l + xrm / 2 ) ) / ll;
678 cost += costCenter / 1000;
685 alpha = atan2( ey - by, ex - bx );
687 beta = alpha +
M_PI / 2;
692 bool isRightToLeft = ( alpha >
M_PI / 2 || alpha <= -
M_PI / 2 );
702 positions.
append(
new LabelPosition( i, bx + cos( beta ) *distlabel, by + sin( beta ) *distlabel, xrm, yrm, alpha, cost,
this, isRightToLeft ) );
707 positions.
append(
new LabelPosition( i, bx - cos( beta ) *( distlabel + yrm ), by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha, cost,
this, isRightToLeft ) );
712 positions.
append(
new LabelPosition( i, bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha, cost,
this, isRightToLeft ) );
717 positions.
append(
new LabelPosition( i, bx - xrm / 2, by - yrm / 2, xrm, yrm, 0, cost,
this ) );
737 int nbp = positions.
size();
750 while ( distance < 0 && index > 1 )
753 distance += path_distances[
index];
756 if ( index <= 1 && distance < 0 )
762 while ( index < path_positions->
nbPoints && distance > path_distances[index] )
764 distance -= path_distances[
index];
767 if ( index >= path_positions->
nbPoints )
775 int initial_index =
index;
776 double initial_distance = distance;
779 double old_x = path_positions->
x[index-1];
780 double old_y = path_positions->
y[index-1];
782 double new_x = path_positions->
x[
index];
783 double new_y = path_positions->
y[
index];
785 double dx = new_x - old_x;
786 double dy = new_y - old_y;
788 double segment_length = path_distances[
index];
798 double angle = atan2( -dy, dx );
800 bool orientation_forced = ( orientation != 0 );
801 if ( !orientation_forced )
802 orientation = ( angle > 0.55 *
M_PI || angle < -0.45 *
M_PI ? -1 : 1 );
804 int upside_down_char_count = 0;
806 for (
int i = 0; i < li->
char_num; i++ )
808 double last_character_angle =
angle;
821 double start_x = old_x + dx * distance / segment_length;
822 double start_y = old_y + dy * distance / segment_length;
827 if ( segment_length - distance >= ci.
width )
830 distance += ci.
width;
831 end_x = old_x + dx * distance / segment_length;
832 end_y = old_y + dy * distance / segment_length;
843 if ( index >= path_positions->
nbPoints )
848 new_x = path_positions->
x[
index];
849 new_y = path_positions->
y[
index];
852 segment_length = path_distances[
index];
854 while ( sqrt( pow( start_x - new_x, 2 ) + pow( start_y - new_y, 2 ) ) < ci.
width );
860 distance = sqrt( pow( old_x - end_x, 2 ) + pow( old_y - end_y, 2 ) );
864 angle = atan2( start_y - end_y, end_x - start_x );
870 double angle_delta = last_character_angle -
angle;
872 while ( angle_delta >
M_PI ) angle_delta -= 2 *
M_PI;
873 while ( angle_delta < -
M_PI ) angle_delta += 2 *
M_PI;
877 && angle_delta < li->max_char_angle_outside*(
M_PI / 180 ) ) )
885 if ( orientation < 0 )
887 start_x += dist * cos( angle +
M_PI_2 );
888 start_y -= dist * sin( angle +
M_PI_2 );
890 double render_angle =
angle;
892 double render_x = start_x;
893 double render_y = start_y;
899 if ( orientation < 0 )
902 render_x += ci.
width * cos( render_angle );
903 render_y -= ci.
width * sin( render_angle );
904 render_angle +=
M_PI;
919 while ( render_angle >= 2*
M_PI ) render_angle -= 2 *
M_PI;
920 while ( render_angle < 0 ) render_angle += 2 *
M_PI;
922 if ( render_angle >
M_PI / 2 && render_angle < 1.5*
M_PI )
923 upside_down_char_count++;
928 if ( upside_down_char_count >= li->
char_num / 2.0 )
931 if ( !orientation_forced )
933 orientation = -orientation;
964 double* path_distances =
new double[mapShape->
nbPoints];
965 double total_distance = 0;
966 double old_x = -1.0, old_y = -1.0;
967 for (
int i = 0; i < mapShape->
nbPoints; i++ )
970 path_distances[i] = 0;
972 path_distances[i] = sqrt( pow( old_x - mapShape->
x[i], 2 ) + pow( old_y - mapShape->
y[i], 2 ) );
973 old_x = mapShape->
x[i];
974 old_y = mapShape->
y[i];
976 total_distance += path_distances[i];
981 delete[] path_distances;
987 double bx = mapShape->
x[0];
988 double by = mapShape->
y[0];
989 double ex = mapShape->
x[ mapShape->
nbPoints - 1 ];
990 double ey = mapShape->
y[ mapShape->
nbPoints - 1 ];
996 lineAngle = atan2( ey - by, ex - bx );
999 bool isRightToLeft = ( lineAngle >
M_PI / 2 || lineAngle <= -
M_PI / 2 );
1002 double delta = qMax( li->
label_height, total_distance / 10.0 );
1012 for (
int i = 0; i*delta < total_distance; i++ )
1019 double angle_diff = 0.0, angle_last = 0.0, diff;
1021 double sin_avg = 0, cos_avg = 0;
1026 diff = fabs( tmp->
getAlpha() - angle_last );
1027 if ( diff > 2*
M_PI ) diff -= 2 *
M_PI;
1028 diff = qMin( diff, 2 *
M_PI - diff );
1038 double angle_diff_avg = li->
char_num > 1 ? ( angle_diff / ( li->
char_num - 1 ) ) : 0;
1039 double cost = angle_diff_avg / 100;
1040 if ( cost < 0.0001 ) cost = 0.0001;
1044 double costCenter = qAbs( total_distance / 2 - labelCenter ) / total_distance;
1045 cost += costCenter / 1000;
1049 double angle_avg = atan2( sin_avg / li->
char_num, cos_avg / li->
char_num );
1055 if (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) )
1064 int nbp = positions.
size();
1065 for (
int i = 0; i < nbp; i++ )
1070 delete[] path_distances;
1101 mapShape->
parent =
nullptr;
1103 shapes_toProcess.
append( mapShape );
1105 splitPolygons( shapes_toProcess, shapes_final, labelWidth, labelHeight );
1109 if ( !shapes_final.
isEmpty() )
1121 double diago = sqrt( labelWidth * labelWidth / 4.0 + labelHeight * labelHeight / 4 );
1127 while ( !shapes_final.
isEmpty() )
1139 dx = labelWidth / 2.0;
1140 dy = labelHeight / 2.0;
1151 for ( bbid = 0; bbid < j; bbid++ )
1164 if ( box->
length < labelWidth || box->
width < labelHeight )
1171 bool enoughPlace =
false;
1175 px = ( box->
x[0] + box->
x[2] ) / 2 - labelWidth;
1176 py = ( box->
y[0] + box->
y[2] ) / 2 - labelHeight;
1182 for ( rx = px, i = 0; i < 2; rx = rx + 2 * labelWidth, i++ )
1184 for ( ry = py, j = 0; j < 2; ry = ry + 2 * labelHeight, j++ )
1188 enoughPlace =
false;
1204 else if ( box->
length > 1.5*labelWidth && box->
width > 1.5*labelWidth )
1224 beta = atan2( labelHeight, labelWidth ) + alpha;
1230 dlx = cos( beta ) * diago;
1231 dly = sin( beta ) * diago;
1235 px0 = box->
width / 2.0;
1238 px0 -= ceil( px0 / dx ) * dx;
1239 py0 -= ceil( py0 / dy ) * dy;
1241 for ( px = px0; px <= box->
width; px += dx )
1243 for ( py = py0; py <= box->
length; py += dy )
1255 if ( candidateAcceptable )
1258 positions.
append(
new LabelPosition(
id++, rx - dlx, ry - dly, labelWidth, labelHeight, alpha, 0.0001,
this ) );
1264 nbp = positions.
size();
1272 while ( nbp == 0 && numTry < maxTry );
1274 nbp = positions.
size();
1276 for ( i = 0; i < nbp; i++ )
1281 for ( bbid = 0; bbid < j; bbid++ )
1297 double bboxMin[2],
double bboxMax[2],
1302 bbox[0] = bboxMin[0];
1303 bbox[1] = bboxMin[1];
1304 bbox[2] = bboxMax[0];
1305 bbox[3] = bboxMax[1];
1325 case GEOS_LINESTRING:
1360 bool outside =
false;
1377 return lPos.
count();
1386 int geomType = GEOSGeomTypeId_r( ctxt,
mGeos );
1388 double sizeCost = 0;
1389 if ( geomType == GEOS_LINESTRING )
1394 if ( GEOSLength_r( ctxt,
mGeos, &length ) != 1 )
1397 catch ( GEOSException &e )
1402 double bbox_length = qMax( bbx[2] - bbx[0], bby[2] - bby[0] );
1403 if ( length >= bbox_length / 4 )
1406 sizeCost = 1 - ( length / ( bbox_length / 4 ) );
1408 else if ( geomType == GEOS_POLYGON )
1413 if ( GEOSArea_r( ctxt,
mGeos, &area ) != 1 )
1416 catch ( GEOSException &e )
1421 double bbox_area = ( bbx[2] - bbx[0] ) * ( bby[2] - bby[0] );
1422 if ( area >= bbox_area / 16 )
1425 sizeCost = 1 - ( area / ( bbox_area / 16 ) );
1431 for (
int i = 0; i < nbp; i++ )
1433 lPos.
at( i )->setCost( lPos.
at( i )->cost() + sizeCost / 100 );
1446 catch ( GEOSException &e )
1457 if ( !other->
mGeos )
1463 GEOSGeometry* g1 = GEOSGeom_clone_r( ctxt,
mGeos );
1464 GEOSGeometry* g2 = GEOSGeom_clone_r( ctxt, other->
mGeos );
1465 GEOSGeometry* geoms[2] = { g1, g2 };
1466 GEOSGeometry* g = GEOSGeom_createCollection_r( ctxt, GEOS_MULTILINESTRING, geoms, 2 );
1467 GEOSGeometry* gTmp = GEOSLineMerge_r( ctxt, g );
1468 GEOSGeom_destroy_r( ctxt, g );
1470 if ( GEOSGeomTypeId_r( ctxt, gTmp ) != GEOS_LINESTRING )
1473 GEOSGeom_destroy_r( ctxt, gTmp );
1488 catch ( GEOSException &e )
Label below point, slightly right of center.
pal::Layer * layer() const
Get PAL layer of the label feature. Should be only used internally in PAL.
Label on bottom-left of point.
virtual ~FeaturePart()
Delete the feature.
bool isIntersect(double *bbox)
Is the labelposition intersect the bounding-box ?
static bool candidateSortGrow(const LabelPosition *c1, const LabelPosition *c2)
Sorts label candidates in ascending order of cost.
QList< FeaturePart * > mHoles
double max_char_angle_outside
bool alwaysShow() const
Whether label should be always shown (sets very high label priority)
double getLabelHeight() const
Label on top-left of point.
void setCost(double newCost)
Sets the candidate label position's geographical cost.
A set of features which influence the labelling process.
PredefinedPointPosition
Positions for labels when using the QgsPalLabeling::OrderedPositionsAroundPoint placement mode...
int createCandidatesAlongLine(QList< LabelPosition * > &lPos, PointSet *mapShape)
Generate candidates for line feature.
void offsetPosition(double xOffset, double yOffset)
Shift the label by specified offset.
const T & at(int i) const
Candidates are placed in predefined positions around a point.
friend class LabelPosition
static void findLineCircleIntersection(double cx, double cy, double radius, double x1, double y1, double x2, double y2, double &xRes, double &yRes)
Label on top of point, slightly right of center.
QPointF quadOffset() const
Applies to "offset from point" placement strategy and "around point" (in case hasFixedQuadrant() retu...
void createGeosGeom() const
double getLabelWidth() const
double priority() const
Returns the layer's priority, between 0 and 1.
bool mergeWithFeaturePart(FeaturePart *other)
Merge other (connected) part with this one and save the result in this part (other is unchanged)...
bool centroidInside() const
Returns whether labels placed at the centroid of features within the layer are forced to be placed in...
double priority() const
Returns the feature's labeling priority.
bool isConnected(FeaturePart *p2)
Check whether this part is connected with some other part.
void addSizePenalty(int nbp, QList< LabelPosition * > &lPos, double bbx[4], double bby[4])
void getCentroid(double &px, double &py, bool forceInside=false) const
QString tr(const char *sourceText, const char *disambiguation, int n)
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
double x() const
Get the x value of the point.
int createCurvedCandidatesAlongLine(QList< LabelPosition * > &lPos, PointSet *mapShape)
Generate curved candidates for line features.
QgsPalLayerSettings::OffsetType offsetType() const
Returns the offset type, which determines how offsets and distance to label behaves.
Arranges candidates following the curvature of a line feature.
CharacterInfo * char_info
pal::LabelInfo * curvedLabelInfo() const
Get additional infor required for curved label placement. Returns null if not set.
bool isInside(double *bbox)
Is the labelposition inside the bounding-box ?
QgsPalLayerSettings::Placement arrangement() const
Returns the layer's arrangement policy.
bool hasFixedPosition() const
Whether the label should use a fixed position instead of being automatically placed.
const GEOSPreparedGeometry * preparedGeom() const
int count(const T &value) const
bool getShowPartial()
Get flag show partial label.
void getPointByDistance(double *d, double *ad, double dl, double *px, double *py)
Get a point a set distance along a line geometry.
double calculatePriority() const
Calculates the priority for the feature.
bool hasSameLabelFeatureAs(FeaturePart *part) const
Tests whether this feature part belongs to the same QgsLabelFeature as another feature part...
double getLabelDistance() const
const QSizeF & symbolSize() const
Returns the size of the rendered symbol associated with this feature, if applicable.
QgsPoint fixedPosition() const
Coordinates of the fixed position (relevant only if hasFixedPosition() returns true) ...
static LabelPosition * _createCurvedCandidate(LabelPosition *lp, double angle, double dist)
bool hasFixedQuadrant() const
Returns whether the quadrant for the label is fixed.
Arranges candidates in a circle around a point (or centroid of a polygon).
double bottom
Bottom margin.
static void logMessage(const QString &message, const QString &tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
Optional additional info about label (for curved labels)
Layer * layer()
Returns the layer that feature belongs to.
double length() const
Returns length of line geometry.
void insertIntoIndex(RTree< LabelPosition *, double, 2, double > *index)
static double dist_euc2d(double x1, double y1, double x2, double y2)
LabelPosition * getNextPart() const
GEOSContextHandle_t geosContext()
Get GEOS context handle to be used in all GEOS library calls with reentrant API.
Stores visual margins for labels (left, right, top and bottom)
Main class to handle feature.
bool containsLabelCandidate(double x, double y, double width, double height, double alpha=0) const
Tests whether a possible label candidate will fit completely within the shape.
Offset distance applies from rendered symbol bounds.
bool fitInPolygonOnly() const
Returns whether labels which do not fit completely within a polygon feature are discarded.
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
bool containsPoint(double x, double y) const
Tests whether point set contains a specified point.
static void splitPolygons(QLinkedList< PointSet * > &shapes_toProcess, QLinkedList< PointSet * > &shapes_final, double xrm, double yrm)
Split a concave shape into several convex shapes.
double getAlpha() const
get alpha
const VisualMargin & visualMargin() const
Returns the visual margin for the label feature.
int createCandidatesForPolygon(QList< LabelPosition * > &lPos, PointSet *mapShape)
Generate candidates for polygon features.
void setNextPart(LabelPosition *next)
CHullBox * compute_chull_bbox()
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point...
QgsPoint positionOffset() const
Applies only to "offset from point" placement strategy.
int createCandidates(QList< LabelPosition * > &lPos, double bboxMin[2], double bboxMax[2], PointSet *mapShape, RTree< LabelPosition *, double, 2, double > *candidates)
Generic method to generate label candidates for the feature.
int createCandidatesOverPoint(double x, double y, QList< LabelPosition * > &lPos, double angle, PointSet *mapShape=nullptr)
Generate one candidate over or offset the specified point.
The QgsLabelFeature class describes a feature that should be used within the labeling engine...
int createCandidatesAroundPoint(double x, double y, QList< LabelPosition * > &lPos, double angle, PointSet *mapShape=nullptr)
Generate candidates for point feature, located around a specified point.
int connectedFeatureId(QgsFeatureId featureId) const
Returns the connected feature ID for a label feature ID, which is unique for all features which have ...
QVector< QgsPalLayerSettings::PredefinedPointPosition > predefinedPositionOrder() const
Returns the priority ordered list of predefined positions for label candidates.
double max_char_angle_inside
double right
Right margin.
int createCandidatesAtOrderedPositionsOverPoint(double x, double y, QList< LabelPosition * > &lPos, double angle)
Generates candidates following a prioritised list of predefined positions around a point...
Label below point, slightly left of center.
void extractCoords(const GEOSGeometry *geom)
read coordinates from a GEOS geom
double distLabel() const
Applies to "around point" placement strategy or linestring features.
LabelPosition is a candidate feature label position.
QString name() const
Returns the layer's name.
LineArrangementFlags arrangementFlags() const
Returns the layer's arrangement flags.
Label on top of point, slightly left of center.
double y() const
Get the y value of the point.
Quadrant
Position of label candidate relative to feature.
static int reorderPolygon(int nbPoints, double *x, double *y)
Reorder points to have cross prod ((x,y)[i], (x,y)[i+1), point) > 0 when point is outside...
bool hasFixedAngle() const
Whether the label should use a fixed angle instead of using angle from automatic placement.
FeaturePart(QgsLabelFeature *lf, const GEOSGeometry *geom)
Creates a new generic feature.
LabelPosition * curvedPlacementAtOffset(PointSet *path_positions, double *path_distances, int orientation, int index, double distance)
double fixedAngle() const
Angle in degrees of the fixed angle (relevant only if hasFixedAngle() returns true) ...
void append(const T &value)
QgsFeatureId id() const
Identifier of the label (unique within the parent label provider)
QgsFeatureId featureId() const
Returns the unique ID of the feature.
Arranges candidates scattered throughout a polygon feature.