47
47
#include " labelposition.h"
48
48
#include " pointset.h"
49
49
#include " util.h"
50
+ #include " qgis.h"
50
51
51
52
#ifndef M_PI
52
53
#define M_PI 3.14159265358979323846
@@ -75,6 +76,7 @@ namespace pal
75
76
, fixedAngle( 0.0 )
76
77
, repeatDist( 0.0 )
77
78
, alwaysShow( false )
79
+ , mFixedQuadrant ( false )
78
80
{
79
81
assert ( finite ( lx ) && finite ( ly ) );
80
82
}
@@ -351,7 +353,25 @@ namespace pal
351
353
}
352
354
}
353
355
354
- if ( f->offsetPos )
356
+ if ( f->layer ->getArrangement () == P_POINT )
357
+ {
358
+ // if in "around point" placement mode, then we use the label distance to determine
359
+ // the label's offset
360
+ if ( qgsDoubleNear ( f->quadOffsetX , 0.0 ) )
361
+ {
362
+ ydiff += f->quadOffsetY * f->distlabel ;
363
+ }
364
+ else if ( qgsDoubleNear ( f->quadOffsetY , 0.0 ) )
365
+ {
366
+ xdiff += f->quadOffsetX * f->distlabel ;
367
+ }
368
+ else
369
+ {
370
+ xdiff += f->quadOffsetX * M_SQRT1_2 * f->distlabel ;
371
+ ydiff += f->quadOffsetY * M_SQRT1_2 * f->distlabel ;
372
+ }
373
+ }
374
+ else if ( f->offsetPos )
355
375
{
356
376
if ( f->offsetPosX != 0 )
357
377
{
@@ -394,26 +414,20 @@ namespace pal
394
414
f->layer ->pal ->map_unit ,
395
415
dpi, scale, delta_width );
396
416
397
- int nbp = f->layer ->pal ->point_p ;
417
+ int numberCandidates = f->layer ->pal ->point_p ;
398
418
399
419
// std::cout << "Nbp : " << nbp << std::endl;
400
-
401
- int i;
402
420
int icost = 0 ;
403
421
int inc = 2 ;
404
422
405
- double alpha;
406
- double beta = 2 * M_PI / nbp; /* angle bw 2 pos */
423
+ double candidateAngleIncrement = 2 * M_PI / numberCandidates; /* angle bw 2 pos */
407
424
408
- double lx, ly; /* label pos */
409
-
410
- /* various alpha */
425
+ /* various angles */
411
426
double a90 = M_PI / 2 ;
412
427
double a180 = M_PI;
413
428
double a270 = a180 + a90;
414
429
double a360 = 2 * M_PI;
415
430
416
-
417
431
double gamma1, gamma2;
418
432
419
433
if ( distlabel > 0 )
@@ -426,7 +440,6 @@ namespace pal
426
440
gamma1 = gamma2 = a90 / 3.0 ;
427
441
}
428
442
429
-
430
443
if ( gamma1 > a90 / 3.0 )
431
444
gamma1 = a90 / 3.0 ;
432
445
@@ -439,101 +452,103 @@ namespace pal
439
452
std::cout << " Oups... label size error..." << std::endl;
440
453
}
441
454
442
- *lPos = new LabelPosition *[nbp ];
455
+ *lPos = new LabelPosition *[numberCandidates ];
443
456
444
- for ( i = 0 , alpha = M_PI / 4 ; i < nbp; i++, alpha += beta )
457
+ int i;
458
+ double angleToCandidate;
459
+ for ( i = 0 , angleToCandidate = M_PI / 4 ; i < numberCandidates; i++, angleToCandidate += candidateAngleIncrement )
445
460
{
446
- lx = x;
447
- ly = y;
461
+ double labelX = x;
462
+ double labelY = y;
448
463
449
- if ( alpha > a360 )
450
- alpha -= a360;
464
+ if ( angleToCandidate > a360 )
465
+ angleToCandidate -= a360;
451
466
452
467
LabelPosition::Quadrant quadrant = LabelPosition::QuadrantOver;
453
468
454
- if ( alpha < gamma1 || alpha > a360 - gamma1 ) // on the right
469
+ if ( angleToCandidate < gamma1 || angleToCandidate > a360 - gamma1 ) // on the right
455
470
{
456
- lx += distlabel;
457
- double iota = ( alpha + gamma1 );
471
+ labelX += distlabel;
472
+ double iota = ( angleToCandidate + gamma1 );
458
473
if ( iota > a360 - gamma1 )
459
474
iota -= a360;
460
475
461
476
// ly += -yrm/2.0 + tan(alpha)*(distlabel + xrm/2);
462
- ly += -yrm + yrm * iota / ( 2 * gamma1 );
477
+ labelY += -yrm + yrm * iota / ( 2 * gamma1 );
463
478
464
479
quadrant = LabelPosition::QuadrantRight;
465
480
}
466
- else if ( alpha < a90 - gamma2 ) // top-right
481
+ else if ( angleToCandidate < a90 - gamma2 ) // top-right
467
482
{
468
- lx += distlabel * cos ( alpha );
469
- ly += distlabel * sin ( alpha );
483
+ labelX += distlabel * cos ( angleToCandidate );
484
+ labelY += distlabel * sin ( angleToCandidate );
470
485
quadrant = LabelPosition::QuadrantAboveRight;
471
486
}
472
- else if ( alpha < a90 + gamma2 ) // top
487
+ else if ( angleToCandidate < a90 + gamma2 ) // top
473
488
{
474
489
// lx += -xrm/2.0 - tan(alpha+a90)*(distlabel + yrm/2);
475
- lx += -xrm * ( alpha - a90 + gamma2 ) / ( 2 * gamma2 );
476
- ly += distlabel;
490
+ labelX += -xrm * ( angleToCandidate - a90 + gamma2 ) / ( 2 * gamma2 );
491
+ labelY += distlabel;
477
492
quadrant = LabelPosition::QuadrantAbove;
478
493
}
479
- else if ( alpha < a180 - gamma1 ) // top left
494
+ else if ( angleToCandidate < a180 - gamma1 ) // top left
480
495
{
481
- lx += distlabel * cos ( alpha ) - xrm;
482
- ly += distlabel * sin ( alpha );
496
+ labelX += distlabel * cos ( angleToCandidate ) - xrm;
497
+ labelY += distlabel * sin ( angleToCandidate );
483
498
quadrant = LabelPosition::QuadrantAboveLeft;
484
499
}
485
- else if ( alpha < a180 + gamma1 ) // left
500
+ else if ( angleToCandidate < a180 + gamma1 ) // left
486
501
{
487
- lx += -distlabel - xrm;
502
+ labelX += -distlabel - xrm;
488
503
// ly += -yrm/2.0 - tan(alpha)*(distlabel + xrm/2);
489
- ly += - ( alpha - a180 + gamma1 ) * yrm / ( 2 * gamma1 );
504
+ labelY += - ( angleToCandidate - a180 + gamma1 ) * yrm / ( 2 * gamma1 );
490
505
quadrant = LabelPosition::QuadrantLeft;
491
506
}
492
- else if ( alpha < a270 - gamma2 ) // down - left
507
+ else if ( angleToCandidate < a270 - gamma2 ) // down - left
493
508
{
494
- lx += distlabel * cos ( alpha ) - xrm;
495
- ly += distlabel * sin ( alpha ) - yrm;
509
+ labelX += distlabel * cos ( angleToCandidate ) - xrm;
510
+ labelY += distlabel * sin ( angleToCandidate ) - yrm;
496
511
quadrant = LabelPosition::QuadrantBelowLeft;
497
512
}
498
- else if ( alpha < a270 + gamma2 ) // down
513
+ else if ( angleToCandidate < a270 + gamma2 ) // down
499
514
{
500
- ly += -distlabel - yrm;
515
+ labelY += -distlabel - yrm;
501
516
// lx += -xrm/2.0 + tan(alpha+a90)*(distlabel + yrm/2);
502
- lx += -xrm + ( alpha - a270 + gamma2 ) * xrm / ( 2 * gamma2 );
517
+ labelX += -xrm + ( angleToCandidate - a270 + gamma2 ) * xrm / ( 2 * gamma2 );
503
518
quadrant = LabelPosition::QuadrantBelow;
504
519
}
505
- else if ( alpha < a360 ) // down - right
520
+ else if ( angleToCandidate < a360 ) // down - right
506
521
{
507
- lx += distlabel * cos ( alpha );
508
- ly += distlabel * sin ( alpha ) - yrm;
522
+ labelX += distlabel * cos ( angleToCandidate );
523
+ labelY += distlabel * sin ( angleToCandidate ) - yrm;
509
524
quadrant = LabelPosition::QuadrantBelowRight;
510
525
}
511
526
512
527
double cost;
513
528
514
- if ( nbp == 1 )
529
+ if ( numberCandidates == 1 )
515
530
cost = 0.0001 ;
516
531
else
517
- cost = 0.0001 + 0.0020 * double ( icost ) / double ( nbp - 1 );
532
+ cost = 0.0001 + 0.0020 * double ( icost ) / double ( numberCandidates - 1 );
518
533
519
- ( *lPos )[i] = new LabelPosition ( i, lx, ly , xrm, yrm, angle, cost, this , false , quadrant );
534
+ ( *lPos )[i] = new LabelPosition ( i, labelX, labelY , xrm, yrm, angle, cost, this , false , quadrant );
520
535
521
536
icost += inc;
522
537
523
- if ( icost == nbp )
538
+ if ( icost == numberCandidates )
524
539
{
525
- icost = nbp - 1 ;
540
+ icost = numberCandidates - 1 ;
526
541
inc = -2 ;
527
542
}
528
- else if ( icost > nbp )
543
+ else if ( icost > numberCandidates )
529
544
{
530
- icost = nbp - 2 ;
545
+ icost = numberCandidates - 2 ;
531
546
inc = -2 ;
532
547
}
533
548
534
549
}
535
550
536
- return nbp ;
551
+ return numberCandidates ;
537
552
}
538
553
539
554
// TODO work with squared distance by remonving call to sqrt or dist_euc2d
@@ -1323,7 +1338,7 @@ namespace pal
1323
1338
switch ( type )
1324
1339
{
1325
1340
case GEOS_POINT:
1326
- if ( f->layer ->getArrangement () == P_POINT_OVER )
1341
+ if ( f->layer ->getArrangement () == P_POINT_OVER || f-> fixedQuadrant () )
1327
1342
nbp = setPositionOverPoint ( x[0 ], y[0 ], scale, lPos, delta, angle );
1328
1343
else
1329
1344
nbp = setPositionForPoint ( x[0 ], y[0 ], scale, lPos, delta, angle );
0 commit comments