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;
424 lPos <<
new LabelPosition( i, labelX, labelY, labelWidth, labelHeight, angle, cost,
this,
false, quadrant );
446 double candidateAngleIncrement = 2 *
M_PI / numberCandidates;
449 double a90 =
M_PI / 2;
451 double a270 = a180 + a90;
452 double a360 = 2 *
M_PI;
454 double gamma1, gamma2;
456 if ( distanceToLabel > 0 )
458 gamma1 = atan2( labelHeight / 2, distanceToLabel + labelWidth / 2 );
459 gamma2 = atan2( labelWidth / 2, distanceToLabel + labelHeight / 2 );
463 gamma1 = gamma2 = a90 / 3.0;
466 if ( gamma1 > a90 / 3.0 )
469 if ( gamma2 > a90 / 3.0 )
475 double angleToCandidate;
476 for ( i = 0, angleToCandidate =
M_PI / 4; i < numberCandidates; i++, angleToCandidate += candidateAngleIncrement )
481 if ( angleToCandidate > a360 )
482 angleToCandidate -= a360;
486 if ( angleToCandidate < gamma1 || angleToCandidate > a360 - gamma1 )
488 labelX += distanceToLabel;
489 double iota = ( angleToCandidate + gamma1 );
490 if ( iota > a360 - gamma1 )
494 labelY += -labelHeight + labelHeight * iota / ( 2 * gamma1 );
498 else if ( angleToCandidate < a90 - gamma2 )
500 labelX += distanceToLabel * cos( angleToCandidate );
501 labelY += distanceToLabel * sin( angleToCandidate );
504 else if ( angleToCandidate < a90 + gamma2 )
507 labelX += -labelWidth * ( angleToCandidate - a90 + gamma2 ) / ( 2 * gamma2 );
508 labelY += distanceToLabel;
511 else if ( angleToCandidate < a180 - gamma1 )
513 labelX += distanceToLabel * cos( angleToCandidate ) - labelWidth;
514 labelY += distanceToLabel * sin( angleToCandidate );
517 else if ( angleToCandidate < a180 + gamma1 )
519 labelX += -distanceToLabel - labelWidth;
521 labelY += - ( angleToCandidate - a180 + gamma1 ) * labelHeight / ( 2 * gamma1 );
524 else if ( angleToCandidate < a270 - gamma2 )
526 labelX += distanceToLabel * cos( angleToCandidate ) - labelWidth;
527 labelY += distanceToLabel * sin( angleToCandidate ) - labelHeight;
530 else if ( angleToCandidate < a270 + gamma2 )
532 labelY += -distanceToLabel - labelHeight;
534 labelX += -labelWidth + ( angleToCandidate - a270 + gamma2 ) * labelWidth / ( 2 * gamma2 );
537 else if ( angleToCandidate < a360 )
539 labelX += distanceToLabel * cos( angleToCandidate );
540 labelY += distanceToLabel * sin( angleToCandidate ) - labelHeight;
546 if ( numberCandidates == 1 )
549 cost = 0.0001 + 0.0020 * double( icost ) / double( numberCandidates - 1 );
560 candidates <<
new LabelPosition( i, labelX, labelY, labelWidth, labelHeight, angle, cost,
this,
false, quadrant );
564 if ( icost == numberCandidates )
566 icost = numberCandidates - 1;
569 else if ( icost > numberCandidates )
571 icost = numberCandidates - 2;
579 for (
int i = 0; i < candidates.
count(); ++i )
581 lPos << candidates.
at( i );
585 return candidates.
count();
601 double bx, by, ex, ey;
621 d =
new double[nbPoints-1];
625 for ( i = 0; i < line->
nbPoints - 1; i++ )
630 ad[i] = ad[i-1] + d[i-1];
638 nbls =
static_cast< int >( ll / xrm );
646 dist = qMin( yrm, xrm );
650 l = - ( xrm - ll ) / 2.0;
658 while ( l < ll - xrm )
667 birdfly = sqrt(( x[nbPoints-1] - x[0] ) * ( x[nbPoints-1] - x[0] )
668 + ( y[nbPoints-1] - y[0] ) * ( y[nbPoints-1] - y[0] ) );
670 birdfly = sqrt(( ex - bx ) * ( ex - bx ) + ( ey - by ) * ( ey - by ) );
672 cost = birdfly / xrm;
676 cost = ( 1 - cost ) / 100;
679 double costCenter = qAbs( ll / 2 - ( l + xrm / 2 ) ) / ll;
680 cost += costCenter / 1000;
687 alpha = atan2( ey - by, ex - bx );
689 beta = alpha +
M_PI / 2;
694 bool isRightToLeft = ( alpha >
M_PI / 2 || alpha <= -
M_PI / 2 );
704 positions.
append(
new LabelPosition( i, bx + cos( beta ) *distlabel, by + sin( beta ) *distlabel, xrm, yrm, alpha, cost,
this, isRightToLeft ) );
709 positions.
append(
new LabelPosition( i, bx - cos( beta ) *( distlabel + yrm ), by - sin( beta ) *( distlabel + yrm ), xrm, yrm, alpha, cost,
this, isRightToLeft ) );
714 positions.
append(
new LabelPosition( i, bx - yrm*cos( beta ) / 2, by - yrm*sin( beta ) / 2, xrm, yrm, alpha, cost,
this, isRightToLeft ) );
719 positions.
append(
new LabelPosition( i, bx - xrm / 2, by - yrm / 2, xrm, yrm, 0, cost,
this ) );
739 int nbp = positions.
size();
752 while ( distance < 0 && index > 1 )
755 distance += path_distances[
index];
758 if ( index <= 1 && distance < 0 )
764 while ( index < path_positions->
nbPoints && distance > path_distances[index] )
766 distance -= path_distances[
index];
769 if ( index >= path_positions->
nbPoints )
777 int initial_index =
index;
778 double initial_distance = distance;
781 double old_x = path_positions->
x[index-1];
782 double old_y = path_positions->
y[index-1];
784 double new_x = path_positions->
x[
index];
785 double new_y = path_positions->
y[
index];
787 double dx = new_x - old_x;
788 double dy = new_y - old_y;
790 double segment_length = path_distances[
index];
800 double angle = atan2( -dy, dx );
802 bool orientation_forced = ( orientation != 0 );
803 if ( !orientation_forced )
804 orientation = ( angle > 0.55 *
M_PI || angle < -0.45 *
M_PI ? -1 : 1 );
806 int upside_down_char_count = 0;
808 for (
int i = 0; i < li->
char_num; i++ )
810 double last_character_angle =
angle;
823 double start_x = old_x + dx * distance / segment_length;
824 double start_y = old_y + dy * distance / segment_length;
829 if ( segment_length - distance >= ci.
width )
832 distance += ci.
width;
833 end_x = old_x + dx * distance / segment_length;
834 end_y = old_y + dy * distance / segment_length;
845 if ( index >= path_positions->
nbPoints )
850 new_x = path_positions->
x[
index];
851 new_y = path_positions->
y[
index];
854 segment_length = path_distances[
index];
856 while ( sqrt( pow( start_x - new_x, 2 ) + pow( start_y - new_y, 2 ) ) < ci.
width );
862 distance = sqrt( pow( old_x - end_x, 2 ) + pow( old_y - end_y, 2 ) );
866 angle = atan2( start_y - end_y, end_x - start_x );
872 double angle_delta = last_character_angle -
angle;
874 while ( angle_delta >
M_PI ) angle_delta -= 2 *
M_PI;
875 while ( angle_delta < -
M_PI ) angle_delta += 2 *
M_PI;
879 && angle_delta < li->max_char_angle_outside*(
M_PI / 180 ) ) )
888 if ( orientation < 0 )
890 start_x += dist * cos( angle +
M_PI_2 );
891 start_y -= dist * sin( angle +
M_PI_2 );
893 double render_angle =
angle;
895 double render_x = start_x;
896 double render_y = start_y;
902 if ( orientation < 0 )
905 render_x += ci.
width * cos( render_angle );
906 render_y -= ci.
width * sin( render_angle );
907 render_angle +=
M_PI;
922 while ( render_angle >= 2*
M_PI ) render_angle -= 2 *
M_PI;
923 while ( render_angle < 0 ) render_angle += 2 *
M_PI;
925 if ( render_angle >
M_PI / 2 && render_angle < 1.5*
M_PI )
926 upside_down_char_count++;
931 if ( upside_down_char_count >= li->
char_num / 2.0 )
934 if ( !orientation_forced )
936 orientation = -orientation;
967 double* path_distances =
new double[mapShape->
nbPoints];
968 double total_distance = 0;
969 double old_x = -1.0, old_y = -1.0;
970 for (
int i = 0; i < mapShape->
nbPoints; i++ )
973 path_distances[i] = 0;
975 path_distances[i] = sqrt( pow( old_x - mapShape->
x[i], 2 ) + pow( old_y - mapShape->
y[i], 2 ) );
976 old_x = mapShape->
x[i];
977 old_y = mapShape->
y[i];
979 total_distance += path_distances[i];
984 delete[] path_distances;
990 double bx = mapShape->
x[0];
991 double by = mapShape->
y[0];
992 double ex = mapShape->
x[ mapShape->
nbPoints - 1 ];
993 double ey = mapShape->
y[ mapShape->
nbPoints - 1 ];
999 lineAngle = atan2( ey - by, ex - bx );
1002 bool isRightToLeft = ( lineAngle >
M_PI / 2 || lineAngle <= -
M_PI / 2 );
1005 double delta = qMax( li->
label_height, total_distance / 10.0 );
1015 for (
int i = 0; i*delta < total_distance; i++ )
1022 double angle_diff = 0.0, angle_last = 0.0, diff;
1024 double sin_avg = 0, cos_avg = 0;
1029 diff = fabs( tmp->
getAlpha() - angle_last );
1030 if ( diff > 2*
M_PI ) diff -= 2 *
M_PI;
1031 diff = qMin( diff, 2 *
M_PI - diff );
1041 double angle_diff_avg = li->
char_num > 1 ? ( angle_diff / ( li->
char_num - 1 ) ) : 0;
1042 double cost = angle_diff_avg / 100;
1043 if ( cost < 0.0001 ) cost = 0.0001;
1047 double costCenter = qAbs( total_distance / 2 - labelCenter ) / total_distance;
1048 cost += costCenter / 1000;
1052 double angle_avg = atan2( sin_avg / li->
char_num, cos_avg / li->
char_num );
1054 for (
int i = 0; i <= 2; ++i )
1061 if ( i == 2 && (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) ) )
1068 while ( within && currentPos )
1089 int nbp = positions.
size();
1090 for (
int i = 0; i < nbp; i++ )
1095 delete[] path_distances;
1126 mapShape->
parent =
nullptr;
1128 shapes_toProcess.
append( mapShape );
1130 splitPolygons( shapes_toProcess, shapes_final, labelWidth, labelHeight );
1134 if ( !shapes_final.
isEmpty() )
1146 double diago = sqrt( labelWidth * labelWidth / 4.0 + labelHeight * labelHeight / 4 );
1152 while ( !shapes_final.
isEmpty() )
1164 dx = labelWidth / 2.0;
1165 dy = labelHeight / 2.0;
1176 for ( bbid = 0; bbid < j; bbid++ )
1197 bool enoughPlace =
false;
1201 px = ( box->
x[0] + box->
x[2] ) / 2 - labelWidth;
1202 py = ( box->
y[0] + box->
y[2] ) / 2 - labelHeight;
1208 for ( rx = px, i = 0; i < 2; rx = rx + 2 * labelWidth, i++ )
1210 for ( ry = py, j = 0; j < 2; ry = ry + 2 * labelHeight, j++ )
1214 enoughPlace =
false;
1230 else if ( box->
length > 1.5*labelWidth && box->
width > 1.5*labelWidth )
1250 beta = atan2( labelHeight, labelWidth ) + alpha;
1256 dlx = cos( beta ) * diago;
1257 dly = sin( beta ) * diago;
1261 px0 = box->
width / 2.0;
1264 px0 -= ceil( px0 / dx ) * dx;
1265 py0 -= ceil( py0 / dy ) * dy;
1267 for ( px = px0; px <= box->
width; px += dx )
1269 for ( py = py0; py <= box->
length; py += dy )
1281 if ( candidateAcceptable )
1284 positions.
append(
new LabelPosition(
id++, rx - dlx, ry - dly, labelWidth, labelHeight, alpha, 0.0001,
this ) );
1290 nbp = positions.
size();
1298 while ( nbp == 0 && numTry < maxTry );
1300 nbp = positions.
size();
1302 for ( i = 0; i < nbp; i++ )
1307 for ( bbid = 0; bbid < j; bbid++ )
1323 double bboxMin[2],
double bboxMax[2],
1328 bbox[0] = bboxMin[0];
1329 bbox[1] = bboxMin[1];
1330 bbox[2] = bboxMax[0];
1331 bbox[3] = bboxMax[1];
1351 case GEOS_LINESTRING:
1386 bool outside =
false;
1403 return lPos.
count();
1412 int geomType = GEOSGeomTypeId_r( ctxt,
mGeos );
1414 double sizeCost = 0;
1415 if ( geomType == GEOS_LINESTRING )
1420 if ( GEOSLength_r( ctxt,
mGeos, &length ) != 1 )
1423 catch ( GEOSException &e )
1428 double bbox_length = qMax( bbx[2] - bbx[0], bby[2] - bby[0] );
1429 if ( length >= bbox_length / 4 )
1432 sizeCost = 1 - ( length / ( bbox_length / 4 ) );
1434 else if ( geomType == GEOS_POLYGON )
1439 if ( GEOSArea_r( ctxt,
mGeos, &area ) != 1 )
1442 catch ( GEOSException &e )
1447 double bbox_area = ( bbx[2] - bbx[0] ) * ( bby[2] - bby[0] );
1448 if ( area >= bbox_area / 16 )
1451 sizeCost = 1 - ( area / ( bbox_area / 16 ) );
1457 for (
int i = 0; i < nbp; i++ )
1459 lPos.
at( i )->setCost( lPos.
at( i )->cost() + sizeCost / 100 );
1472 catch ( GEOSException &e )
1483 if ( !other->
mGeos )
1489 GEOSGeometry* g1 = GEOSGeom_clone_r( ctxt,
mGeos );
1490 GEOSGeometry* g2 = GEOSGeom_clone_r( ctxt, other->
mGeos );
1491 GEOSGeometry* geoms[2] = { g1, g2 };
1492 GEOSGeometry* g = GEOSGeom_createCollection_r( ctxt, GEOS_MULTILINESTRING, geoms, 2 );
1493 GEOSGeometry* gTmp = GEOSLineMerge_r( ctxt, g );
1494 GEOSGeom_destroy_r( ctxt, g );
1496 if ( GEOSGeomTypeId_r( ctxt, gTmp ) != GEOS_LINESTRING )
1499 GEOSGeom_destroy_r( ctxt, gTmp );
1514 catch ( GEOSException &e )
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.
Label below point, slightly right of center.
bool centroidInside() const
Returns whether labels placed at the centroid of features within the layer are forced to be placed in...
Label on bottom-left of point.
virtual ~FeaturePart()
Delete the feature.
int createCandidatesForPolygon(QList< LabelPosition *> &lPos, PointSet *mapShape)
Generate candidates for polygon features.
double distLabel() const
Applies to "around point" placement strategy or linestring features.
bool isIntersect(double *bbox)
Is the labelposition intersect the bounding-box ?
bool containsPoint(double x, double y) const
Tests whether point set contains a specified point.
QgsFeatureId featureId() const
Returns the unique ID of the feature.
QgsFeatureId id() const
Identifier of the label (unique within the parent label provider)
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
double priority() const
Returns the feature's labeling priority.
bool alwaysShow() const
Whether label should be always shown (sets very high label priority)
Label on top-left of point.
void setCost(double newCost)
Sets the candidate label position's geographical cost.
double getY(int i=0) const
get the down-left y coordinate
QgsPoint positionOffset() const
Applies only to "offset from point" placement strategy.
A set of features which influence the labelling process.
PredefinedPointPosition
Positions for labels when using the QgsPalLabeling::OrderedPositionsAroundPoint placement mode...
void offsetPosition(double xOffset, double yOffset)
Shift the label by specified offset.
const T & at(int i) const
void createGeosGeom() const
Candidates are placed in predefined positions around a point.
friend class LabelPosition
const GEOSPreparedGeometry * permissibleZonePrepared() const
Returns a GEOS prepared geometry representing the label's permissibleZone().
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.
const QSizeF & symbolSize() const
Returns the size of the rendered symbol associated with this feature, if applicable.
bool mergeWithFeaturePart(FeaturePart *other)
Merge other (connected) part with this one and save the result in this part (other is unchanged)...
bool isConnected(FeaturePart *p2)
Check whether this part is connected with some other part.
QgsPoint fixedPosition() const
Coordinates of the fixed position (relevant only if hasFixedPosition() returns true) ...
double getLabelDistance() const
int createCandidatesAtOrderedPositionsOverPoint(double x, double y, QList< LabelPosition *> &lPos, double angle)
Generates candidates following a prioritised list of predefined positions around a point...
QString tr(const char *sourceText, const char *disambiguation, int n)
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
double y() const
Get the y value of the point.
Arranges candidates following the curvature of a line feature.
CharacterInfo * char_info
bool isInside(double *bbox)
Is the labelposition inside the bounding-box ?
int createCandidatesAroundPoint(double x, double y, QList< LabelPosition *> &lPos, double angle)
Generate candidates for point feature, located around a specified point.
double priority() const
Returns the layer's priority, between 0 and 1.
int count(const T &value) const
pal::LabelInfo * curvedLabelInfo() const
Get additional infor required for curved label placement. Returns null if not set.
bool hasFixedQuadrant() const
Returns whether the quadrant for the label is fixed.
static bool containsCandidate(const GEOSPreparedGeometry *geom, double x, double y, double width, double height, double alpha)
Returns true if a GEOS prepared geometry totally contains a label candidate.
QgsGeometry permissibleZone() const
Returns the label's permissible zone geometry.
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.
void addSizePenalty(int nbp, QList< LabelPosition *> &lPos, double bbx[4], double bby[4])
double width() const
Width of the rectangle.
static LabelPosition * _createCurvedCandidate(LabelPosition *lp, double angle, double dist)
Arranges candidates in a circle around a point (or centroid of a polygon).
LabelPosition * getNextPart() const
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 calculatePriority() const
Calculates the priority for the feature.
QgsPalLayerSettings::Placement arrangement() const
Returns the layer's arrangement policy.
bool hasFixedAngle() const
Whether the label should use a fixed angle instead of using angle from automatic placement.
void insertIntoIndex(RTree< LabelPosition *, double, 2, double > *index)
static double dist_euc2d(double x1, double y1, double x2, double y2)
pal::Layer * layer() const
Get PAL layer of the label feature. Should be only used internally in PAL.
int createCandidatesAlongLine(QList< LabelPosition *> &lPos, PointSet *mapShape)
Generate candidates for line feature.
GEOSContextHandle_t geosContext()
Get GEOS context handle to be used in all GEOS library calls with reentrant API.
double fixedAngle() const
Angle in degrees of the fixed angle (relevant only if hasFixedAngle() returns true) ...
double getLabelHeight() const
Stores visual margins for labels (left, right, top and bottom)
Main class to handle feature.
Offset distance applies from rendered symbol bounds.
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)
int createCandidatesOverPoint(double x, double y, QList< LabelPosition *> &lPos, double angle)
Generate one candidate over or offset the specified point.
QPointF quadOffset() const
Applies to "offset from point" placement strategy and "around point" (in case hasFixedQuadrant() retu...
const VisualMargin & visualMargin() const
Returns the visual margin for the label feature.
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...
bool hasFixedPosition() const
Whether the label should use a fixed position instead of being automatically placed.
The QgsLabelFeature class describes a feature that should be used within the labeling engine...
bool hasSameLabelFeatureAs(FeaturePart *part) const
Tests whether this feature part belongs to the same QgsLabelFeature as another feature part...
double getAlpha() const
get alpha
double length() const
Returns length of line geometry.
QgsPalLayerSettings::OffsetType offsetType() const
Returns the offset type, which determines how offsets and distance to label behaves.
double getX(int i=0) const
get the down-left x coordinate
double max_char_angle_inside
double right
Right margin.
QgsRectangle boundingBox() const
Returns the bounding box of this feature.
Label below point, slightly left of center.
void extractCoords(const GEOSGeometry *geom)
read coordinates from a GEOS geom
QString name() const
Returns the layer's name.
double getLabelWidth() const
LabelPosition is a candidate feature label position.
Label on top of point, slightly left of center.
Quadrant
Position of label candidate relative to feature.
const GEOSPreparedGeometry * preparedGeom() const
LineArrangementFlags arrangementFlags() const
Returns the layer's arrangement flags.
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...
FeaturePart(QgsLabelFeature *lf, const GEOSGeometry *geom)
Creates a new generic feature.
QVector< QgsPalLayerSettings::PredefinedPointPosition > predefinedPositionOrder() const
Returns the priority ordered list of predefined positions for label candidates.
void getCentroid(double &px, double &py, bool forceInside=false) const
static void splitPolygons(QLinkedList< PointSet *> &shapes_toProcess, QLinkedList< PointSet *> &shapes_final, double xrm, double yrm)
Split a concave shape into several convex shapes.
LabelPosition * curvedPlacementAtOffset(PointSet *path_positions, double *path_distances, int orientation, int index, double distance)
double x() const
Get the x value of the point.
void append(const T &value)
double height() const
Height of the rectangle.
int connectedFeatureId(QgsFeatureId featureId) const
Returns the connected feature ID for a label feature ID, which is unique for all features which have ...
int createCurvedCandidatesAlongLine(QList< LabelPosition *> &lPos, PointSet *mapShape)
Generate curved candidates for line features.
Arranges candidates scattered throughout a polygon feature.