~ubuntu-branches/ubuntu/quantal/qgis/quantal

« back to all changes in this revision

Viewing changes to src/qgslabel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve Halasz
  • Date: 2004-12-21 09:46:27 UTC
  • Revision ID: james.westby@ubuntu.com-20041221094627-r9lb6mlz2o3yp8gn
Tags: upstream-0.6.0
ImportĀ upstreamĀ versionĀ 0.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                         qgslabel.cpp - render vector labels
 
3
                             -------------------
 
4
    begin                : August 2004
 
5
    copyright            : (C) 2004 by Radim Blazek
 
6
    email                : blazek@itc.it
 
7
 ***************************************************************************/
 
8
/***************************************************************************
 
9
 *                                                                         *
 
10
 *   This program is free software; you can redistribute it and/or modify  *
 
11
 *   it under the terms of the GNU General Public License as published by  *
 
12
 *   the Free Software Foundation; either version 2 of the License, or     *
 
13
 *   (at your option) any later version.                                   *
 
14
 *                                                                         *
 
15
 ***************************************************************************/
 
16
#include <iostream>
 
17
#include <fstream>
 
18
#include <math.h> //needed for win32 build (ts)
 
19
 
 
20
#include <qstring.h>
 
21
#include <qfont.h>
 
22
#include <qfontmetrics.h>
 
23
 
 
24
#include <qpainter.h>
 
25
#include <qpaintdevice.h>
 
26
#include <qwmatrix.h>
 
27
#include <qdom.h>
 
28
 
 
29
#include "qgis.h"
 
30
#include "qgsfeature.h"
 
31
#include "qgsfield.h"
 
32
#include "qgsrect.h"
 
33
#include "qgscoordinatetransform.h"
 
34
 
 
35
#include "qgslabelattributes.h"
 
36
#include "qgslabeldialog.h"
 
37
#include "qgslabel.h"
 
38
 
 
39
// use M_PI define PI 3.141592654
 
40
#ifdef WIN32
 
41
#define M_PI 4*atan(1.0)
 
42
#endif
 
43
 
 
44
static const char * const ident_ =
 
45
    "$Id: qgslabel.cpp,v 1.21 2004/12/01 01:07:36 mcoletti Exp $";
 
46
 
 
47
 
 
48
QgsLabel::QgsLabel( std::vector<QgsField>& fields )
 
49
{
 
50
#ifdef QGISDEBUG
 
51
    std::cerr << "QgsLabel::QgsLabel()" << std::endl;
 
52
#endif
 
53
 
 
54
    mField = fields;
 
55
    mLabelField.resize ( LabelFieldCount );
 
56
    mLabelFieldIdx.resize ( LabelFieldCount );
 
57
    for ( int i = 0; i < LabelFieldCount; i++ )
 
58
    {
 
59
        mLabelField[i] = "";
 
60
        mLabelFieldIdx[i] = -1;
 
61
    }
 
62
    mLabelAttributes = new QgsLabelAttributes ( true );
 
63
}
 
64
 
 
65
QgsLabel::~QgsLabel()
 
66
{}
 
67
 
 
68
QString QgsLabel::fieldValue ( int attr, QgsFeature *feature )
 
69
{
 
70
    if ( mLabelField[attr].isEmpty() )
 
71
        return QString();
 
72
 
 
73
    std::vector<QgsFeatureAttribute> fields =  feature->attributeMap();
 
74
 
 
75
    for ( unsigned int i = 0; i < fields.size(); i++ )
 
76
    {
 
77
        if ( fields[i].fieldName().lower().compare(mLabelField[attr]) == 0 )
 
78
        {
 
79
            return fields[i].fieldValue();
 
80
        }
 
81
    }
 
82
    return QString();
 
83
}
 
84
 
 
85
void QgsLabel::renderLabel( QPainter * painter, QgsRect *viewExtent,
 
86
                            QgsCoordinateTransform *transform, QPaintDevice* device,
 
87
                            QgsFeature *feature, bool selected, QgsLabelAttributes *classAttributes )
 
88
{
 
89
#if QGISDEBUG > 3
 
90
    std::cerr << "QgsLabel::renderLabel()" << std::endl;
 
91
#endif
 
92
 
 
93
    QPen pen;
 
94
    QFont font;
 
95
    QString value;
 
96
    QString text;
 
97
    double scale, x1, x2;
 
98
 
 
99
    /* Clac scale (not nice) */
 
100
    QgsPoint point;
 
101
    point = transform->transform ( 0, 0 );
 
102
    x1 = point.x();
 
103
    point = transform->transform ( 1000, 0 );
 
104
    x2 = point.x();
 
105
    scale = (x2-x1)/1000;
 
106
 
 
107
    /* Text */
 
108
    value = fieldValue ( Text, feature );
 
109
    if ( value.isEmpty() )
 
110
    {
 
111
        text = mLabelAttributes->text();
 
112
    }
 
113
    else
 
114
    {
 
115
        text = value;
 
116
    }
 
117
 
 
118
    /* Font */
 
119
    value = fieldValue ( Family, feature );
 
120
    if ( value.isEmpty() )
 
121
    {
 
122
        font.setFamily ( mLabelAttributes->family() );
 
123
    }
 
124
    else
 
125
    {
 
126
        font.setFamily ( value );
 
127
    }
 
128
 
 
129
    double size;
 
130
    value = fieldValue ( Size, feature );
 
131
    if ( value.isEmpty() )
 
132
    {
 
133
        size =  mLabelAttributes->size();
 
134
    }
 
135
    else
 
136
    {
 
137
        size =  value.toDouble();
 
138
    }
 
139
    if (  mLabelAttributes->sizeType() == QgsLabelAttributes::MapUnits )
 
140
    {
 
141
        size *= scale;
 
142
    }
 
143
    font.setPointSizeFloat ( size );
 
144
 
 
145
    value = fieldValue ( Color, feature );
 
146
    if ( value.isEmpty() )
 
147
    {
 
148
        pen.setColor ( mLabelAttributes->color() );
 
149
    }
 
150
    else
 
151
    {
 
152
        pen.setColor ( QColor(value) );
 
153
    }
 
154
 
 
155
    value = fieldValue ( Bold, feature );
 
156
    if ( value.isEmpty() )
 
157
    {
 
158
        font.setBold ( mLabelAttributes->bold() );
 
159
    }
 
160
    else
 
161
    {
 
162
        font.setBold ( (bool) value.toInt() );
 
163
    }
 
164
 
 
165
    value = fieldValue ( Italic, feature );
 
166
    if ( value.isEmpty() )
 
167
    {
 
168
        font.setItalic ( mLabelAttributes->italic() );
 
169
    }
 
170
    else
 
171
    {
 
172
        font.setItalic ( (bool) value.toInt() );
 
173
    }
 
174
 
 
175
    value = fieldValue ( Underline, feature );
 
176
    if ( value.isEmpty() )
 
177
    {
 
178
        font.setUnderline ( mLabelAttributes->underline() );
 
179
    }
 
180
    else
 
181
    {
 
182
        font.setUnderline ( (bool) value.toInt() );
 
183
    }
 
184
 
 
185
 
 
186
    /* Coordinates */
 
187
    double x, y, xoffset, yoffset, ang;
 
188
 
 
189
    point = labelPoint ( feature );
 
190
 
 
191
    value = fieldValue ( XCoordinate, feature );
 
192
    if ( !value.isEmpty() )
 
193
    {
 
194
        point.setX ( value.toDouble() );
 
195
    }
 
196
    value = fieldValue ( YCoordinate, feature );
 
197
    if ( !value.isEmpty() )
 
198
    {
 
199
        point.setY ( value.toDouble() );
 
200
    }
 
201
 
 
202
    transform->transform(&point);
 
203
    x = point.x();
 
204
    y = point.y();
 
205
 
 
206
    value = fieldValue ( XOffset, feature );
 
207
    if ( value.isEmpty() )
 
208
    {
 
209
        xoffset = mLabelAttributes->xOffset();
 
210
    }
 
211
    else
 
212
    {
 
213
        xoffset = value.toDouble();
 
214
    }
 
215
    value = fieldValue ( YOffset, feature );
 
216
    if ( value.isEmpty() )
 
217
    {
 
218
        yoffset = mLabelAttributes->yOffset();
 
219
    }
 
220
    else
 
221
    {
 
222
        yoffset = value.toDouble();
 
223
    }
 
224
 
 
225
    // recalc offset to points
 
226
    if (  mLabelAttributes->offsetType() == QgsLabelAttributes::MapUnits )
 
227
    {
 
228
        xoffset *= scale;
 
229
        yoffset *= scale;
 
230
    }
 
231
 
 
232
    value = fieldValue ( Angle, feature );
 
233
    if ( value.isEmpty() )
 
234
    {
 
235
        ang = mLabelAttributes->angle();
 
236
    }
 
237
    else
 
238
    {
 
239
        ang = value.toDouble();
 
240
    }
 
241
    double rad = ang * M_PI/180;
 
242
 
 
243
    x = x + xoffset * cos(rad) - yoffset * sin(rad);
 
244
    y = y - xoffset * sin(rad) - yoffset * cos(rad);
 
245
 
 
246
    /* Alignment */
 
247
    int alignment;
 
248
    QFontMetrics fm ( font );
 
249
    int width = fm.width ( text );
 
250
    int height = fm.height();
 
251
    int dx, dy;
 
252
 
 
253
    value = fieldValue ( Alignment, feature );
 
254
    if ( value.isEmpty() )
 
255
    {
 
256
        alignment = mLabelAttributes->alignment();
 
257
    }
 
258
    else
 
259
    {
 
260
        value = value.lower();
 
261
        alignment = Qt::AlignCenter;
 
262
        if ( value.compare("left") == 0 )
 
263
        {
 
264
            alignment = Qt::AlignLeft | Qt::AlignVCenter;
 
265
        }
 
266
        else if ( value.compare("right") == 0 )
 
267
        {
 
268
            alignment = Qt::AlignRight | Qt::AlignVCenter;
 
269
        }
 
270
        else if ( value.compare("bottom") == 0 )
 
271
        {
 
272
            alignment = Qt::AlignBottom | Qt::AlignHCenter;
 
273
        }
 
274
        else if ( value.compare("top") == 0 )
 
275
        {
 
276
            alignment = Qt::AlignTop | Qt::AlignHCenter;
 
277
        }
 
278
    }
 
279
 
 
280
    if ( alignment & Qt::AlignLeft )
 
281
    {
 
282
        dx = 0;
 
283
    }
 
284
    else if ( alignment & Qt::AlignHCenter )
 
285
    {
 
286
        dx = -width/2;
 
287
    }
 
288
    else if ( alignment & Qt::AlignRight )
 
289
    {
 
290
        dx = -width;
 
291
    }
 
292
 
 
293
    if ( alignment & Qt::AlignBottom )
 
294
    {
 
295
        dy = 0;
 
296
    }
 
297
    else if ( alignment & Qt::AlignVCenter )
 
298
    {
 
299
        dy = height/2;
 
300
    }
 
301
    else if ( alignment & Qt::AlignTop )
 
302
    {
 
303
        dy = height;
 
304
    }
 
305
 
 
306
    painter->save();
 
307
    painter->setFont ( font );
 
308
    painter->translate ( x, y );
 
309
    painter->rotate ( -ang );
 
310
    //
 
311
    // Draw a buffer behind the text if one is desired
 
312
    //
 
313
    if (mLabelAttributes->bufferSizeIsSet() && mLabelAttributes->bufferEnabled())
 
314
    {
 
315
        int myBufferSize = static_cast<int>(mLabelAttributes->bufferSize());
 
316
        if (mLabelAttributes->bufferColorIsSet())
 
317
        {
 
318
            painter->setPen( mLabelAttributes->bufferColor());
 
319
        }
 
320
        else //default to a white buffer
 
321
        {
 
322
            painter->setPen( Qt::white);
 
323
        }
 
324
        for (int i = dx-myBufferSize; i <= dx+myBufferSize; i++)
 
325
        {
 
326
            for (int j = dy-myBufferSize; j <= dy+myBufferSize; j++)
 
327
            {
 
328
                painter->drawText( i ,j, text);
 
329
            }
 
330
        }
 
331
    }
 
332
    painter->setPen ( pen );
 
333
    painter->drawText ( dx, dy, text );
 
334
    painter->restore();
 
335
}
 
336
 
 
337
void QgsLabel::addRequiredFields ( std::list<int> *fields )
 
338
{
 
339
    for ( int i = 0; i < LabelFieldCount; i++ )
 
340
    {
 
341
        if ( mLabelFieldIdx[i] == -1 )
 
342
            continue;
 
343
        bool found = false;
 
344
        for (std::list<int>::iterator it = fields->
 
345
                                           begin();
 
346
                it != fields->end();
 
347
                ++it)
 
348
        {
 
349
            if ( *it == mLabelFieldIdx[i] )
 
350
            {
 
351
                found = true;
 
352
                break;
 
353
            }
 
354
        }
 
355
        if (!found)
 
356
        {
 
357
            fields->push_back(mLabelFieldIdx[i])
 
358
            ;
 
359
        }
 
360
    }
 
361
}
 
362
 
 
363
std::vector<QgsField> & QgsLabel::fields ( void )
 
364
{
 
365
    return mField;
 
366
}
 
367
 
 
368
void QgsLabel::setLabelField ( int attr, const QString str )
 
369
{
 
370
    if ( attr >= LabelFieldCount )
 
371
        return;
 
372
 
 
373
 
 
374
    mLabelField[attr] = str;
 
375
 
 
376
    mLabelFieldIdx[attr] = -1;
 
377
    for ( int i = 0; i < mField.size(); i++ )
 
378
    {
 
379
        if ( mField[i].name().compare(str) == 0 )
 
380
        {
 
381
            mLabelFieldIdx[attr] = i;
 
382
        }
 
383
    }
 
384
}
 
385
 
 
386
QString QgsLabel::labelField ( int attr )
 
387
{
 
388
    if ( attr > LabelFieldCount )
 
389
        return QString();
 
390
 
 
391
    return mLabelField[attr];
 
392
}
 
393
 
 
394
QgsLabelAttributes *QgsLabel::layerAttributes ( void )
 
395
{
 
396
    return mLabelAttributes;
 
397
}
 
398
 
 
399
QgsPoint QgsLabel::labelPoint ( QgsFeature *feature )
 
400
{
 
401
    int wkbType;
 
402
    double *x, *y;
 
403
    unsigned char *ptr;
 
404
    int *nPoints;
 
405
 
 
406
    unsigned char *geom = feature->getGeometry();
 
407
 
 
408
    memcpy(&wkbType, (geom+1), sizeof(wkbType));
 
409
 
 
410
    QgsPoint point;
 
411
 
 
412
    switch (wkbType)
 
413
    {
 
414
    case QGis::WKBPoint:
 
415
        x = (double *) (geom + 5);
 
416
        y = (double *) (geom + 5 + sizeof(double));
 
417
        point.setX(*x);
 
418
        point.setY(*y);
 
419
        break;
 
420
 
 
421
    case QGis::WKBLineString: // Line center
 
422
        double dx, dy, tl, l;
 
423
        ptr = geom + 5;
 
424
        nPoints = (int *)ptr;
 
425
        ptr = geom + 1 + 2 * sizeof(int);
 
426
 
 
427
        tl = 0;
 
428
        for (int i = 1; i < *nPoints; i++)
 
429
        {
 
430
            dx = ((double *)ptr)[2*i] - ((double *)ptr)[2*i-2];
 
431
            dy = ((double *)ptr)[2*i+1] - ((double *)ptr)[2*i-1];
 
432
            tl += sqrt(dx*dx + dy*dy);
 
433
        }
 
434
        tl /= 2;
 
435
 
 
436
        l = 0;
 
437
        for (int i = 1; i < *nPoints; i++)
 
438
        {
 
439
            double dl;
 
440
 
 
441
            dx = ((double *)ptr)[2*i] - ((double *)ptr)[2*i-2];
 
442
            dy = ((double *)ptr)[2*i+1] - ((double *)ptr)[2*i-1];
 
443
            dl = sqrt(dx*dx + dy*dy);
 
444
 
 
445
            if ( l+dl > tl )
 
446
            {
 
447
                l = tl - l;
 
448
                double k = l/dl;
 
449
 
 
450
                point.setX ( ((double *)ptr)[2*i-2] +  k * dx  );
 
451
                point.setY ( ((double *)ptr)[2*i-1] + k * dy );
 
452
                break;
 
453
            }
 
454
            l += dl;
 
455
        }
 
456
        break;
 
457
 
 
458
    case QGis::WKBPolygon:
 
459
        double sx, sy;
 
460
        ptr = geom + 1 + 2 * sizeof(int); // set pointer to the first ring
 
461
        nPoints = (int *) ptr;
 
462
        ptr += 4;
 
463
 
 
464
        sx = sy = 0;
 
465
        for (int i = 0; i < *nPoints-1; i++)
 
466
        {
 
467
            sx += ((double *)ptr)[2*i];
 
468
            sy += ((double *)ptr)[2*i+1];
 
469
        }
 
470
        point.setX ( sx/(*nPoints-1) );
 
471
        point.setY ( sy/(*nPoints-1) );
 
472
 
 
473
        break;
 
474
    case QGis::WKBMultiPolygon:
 
475
        break; ///// <--------------remove this when code below needs testing..........
 
476
        {
 
477
            double sx, sy;
 
478
            unsigned char *ptr;
 
479
            int idx, jdx, kdx;
 
480
            int *numPolygons, *numRings;
 
481
 
 
482
            // get the number of polygons
 
483
            ptr = geom + 5;
 
484
            numPolygons = (int *) ptr;
 
485
#ifdef QGISDEBUG
 
486
 
 
487
            std::cout << "Finding label point for mutipolygon with "
 
488
            << *numPolygons << " parts " << std::endl;
 
489
#endif
 
490
            //for (kdx = 0; kdx < *numPolygons; kdx++)
 
491
            for (kdx = 0; kdx < 1; kdx++) //just label the first sub polygon
 
492
            {
 
493
                //skip the endian and feature type info and
 
494
                // get number of rings in the polygon
 
495
                ptr+=14;
 
496
                numRings = (int *) ptr;
 
497
                ptr += 4;
 
498
#ifdef QGISDEBUG
 
499
 
 
500
                std::cout << "Multipolygon part " << kdx << " ring iteration  " << std::endl;
 
501
#endif
 
502
 
 
503
                for (idx = 0; idx < *numRings; idx++)
 
504
                {
 
505
#ifdef QGISDEBUG
 
506
                    std::cout << "Multipolygon part " << kdx << " ring " << idx
 
507
                    << std::endl;
 
508
#endif
 
509
                    // get number of points in the ring
 
510
                    nPoints = (int *) ptr;
 
511
                    ptr += 4;
 
512
                    sx = sy = 0;
 
513
 
 
514
                    //loop through vertices skipping last which == first
 
515
                    for (int i = 0; i < *nPoints-1; i++)
 
516
                    {
 
517
                        x = (double *)ptr;
 
518
                        ptr += sizeof(double);
 
519
                        y = (double *)ptr;
 
520
                        ptr += sizeof(double);
 
521
                        sx += *x;
 
522
                        sy += *y;
 
523
#ifdef QGISDEBUG
 
524
 
 
525
                        std::cout << "\tVertex " << i << " x: " << *x << " y: " << *y  << std::endl;
 
526
#endif
 
527
 
 
528
                    }
 
529
                }
 
530
#ifdef QGISDEBUG
 
531
                std::cout << "Setting multipart polygon label point to" << sx/(*nPoints-1) << ", "<< sy/(*nPoints-1) << std::endl;
 
532
#endif
 
533
 
 
534
                point.setX ( sx/(*nPoints-1) );
 
535
                point.setY ( sy/(*nPoints-1) );
 
536
            }
 
537
            break;
 
538
 
 
539
 
 
540
        }
 
541
    }
 
542
    return QgsPoint ( point );
 
543
}
 
544
 
 
545
void QgsLabel::readXML( const QDomNode& node )
 
546
{
 
547
#if QGISDEBUG
 
548
    std::cout << "QgsLabel::readXML() called for layer label properties \n" << std::endl;
 
549
#endif
 
550
 
 
551
    qDebug( "%s:%d QgsLabel::readXML() got node %s", __FILE__, __LINE__, node.nodeName().ascii() );
 
552
 
 
553
    QDomNode scratchNode;       // DOM node re-used to get current QgsLabel attribute
 
554
    QDomElement el;
 
555
    
 
556
    int red, green, blue;
 
557
    int type;
 
558
 
 
559
    /* Text */
 
560
    scratchNode = node.namedItem("label");
 
561
 
 
562
    if ( scratchNode.isNull() )
 
563
    {
 
564
        qDebug( "%s:%d couldn't find QgsLabel ``label'' attribute", __FILE__, __LINE__ );
 
565
    }
 
566
    else
 
567
    {
 
568
        el = scratchNode.toElement();
 
569
        mLabelAttributes->setText ( el.attribute("text","") );
 
570
        setLabelField ( Text, el.attribute("field","") );
 
571
    }
 
572
 
 
573
    /* Family */
 
574
    scratchNode = node.namedItem("family");
 
575
 
 
576
    if ( scratchNode.isNull() )
 
577
    {
 
578
        qDebug( "%s:%d couldn't find QgsLabel ``family'' attribute", __FILE__, __LINE__  );
 
579
    }
 
580
    else
 
581
    {
 
582
        el = scratchNode.toElement();
 
583
        mLabelAttributes->setFamily ( el.attribute("name","") );
 
584
        setLabelField ( Family, el.attribute("field","") );
 
585
    }
 
586
 
 
587
    /* Size */
 
588
    scratchNode = node.namedItem("size");
 
589
 
 
590
    if ( scratchNode.isNull() )
 
591
    {
 
592
        qDebug( "%s:%d couldn't find QgsLabel ``size'' attribute", __FILE__, __LINE__  );
 
593
    }
 
594
    else
 
595
    {
 
596
        el = scratchNode.toElement();
 
597
        type = QgsLabelAttributes::unitsCode( el.attribute("units","") );
 
598
        mLabelAttributes->setSize ( el.attribute("value", "0.0").toDouble(), type );
 
599
        setLabelField ( Size, el.attribute("field","") );
 
600
    }
 
601
 
 
602
    /* Bold */
 
603
    scratchNode = node.namedItem("bold");
 
604
 
 
605
    if ( scratchNode.isNull() )
 
606
    {
 
607
        qDebug( "%s:%d couldn't find QgsLabel ``bold'' attribute", __FILE__, __LINE__  );
 
608
    }
 
609
    else
 
610
    {
 
611
        el = scratchNode.toElement();
 
612
        mLabelAttributes->setBold ( (bool)el.attribute("on","0").toInt() );
 
613
        setLabelField ( Bold, el.attribute("field","") );
 
614
    }
 
615
 
 
616
    /* Italic */
 
617
    scratchNode = node.namedItem("italic");
 
618
 
 
619
    if ( scratchNode.isNull() )
 
620
    {
 
621
        qDebug( "%s:%d couldn't find QgsLabel ``italic'' attribute", __FILE__, __LINE__  );
 
622
    }
 
623
    else
 
624
    {
 
625
        el = scratchNode.toElement();
 
626
        mLabelAttributes->setItalic ( (bool)el.attribute("on","0").toInt() );
 
627
        setLabelField ( Italic, el.attribute("field","") );
 
628
    }
 
629
 
 
630
    /* Underline */
 
631
    scratchNode = node.namedItem("underline");
 
632
 
 
633
    if ( scratchNode.isNull() )
 
634
    {
 
635
        qDebug( "%s:%d couldn't find QgsLabel ``underline'' attribute", __FILE__, __LINE__  );
 
636
    }
 
637
    else
 
638
    {
 
639
        el = scratchNode.toElement();
 
640
        mLabelAttributes->setUnderline ( (bool)el.attribute("on","0").toInt() );
 
641
        setLabelField ( Underline, el.attribute("field","") );
 
642
    }
 
643
 
 
644
    /* Color */
 
645
    scratchNode = node.namedItem("color");
 
646
 
 
647
    if ( scratchNode.isNull() )
 
648
    {
 
649
        qDebug( "%s:%d couldn't find QgsLabel ``color'' attribute", __FILE__, __LINE__  );
 
650
    }
 
651
    else
 
652
    {
 
653
        el = scratchNode.toElement();
 
654
 
 
655
        red = el.attribute("red","0").toInt();
 
656
        green = el.attribute("green","0").toInt();
 
657
        blue = el.attribute("blue","0").toInt();
 
658
 
 
659
        mLabelAttributes->setColor( QColor(red, green, blue) );
 
660
 
 
661
        setLabelField ( Color, el.attribute("field","") );
 
662
    }
 
663
 
 
664
    /* X */
 
665
    scratchNode = node.namedItem("x");
 
666
 
 
667
    if ( scratchNode.isNull() )
 
668
    {
 
669
        qDebug( "%s:%d couldn't find QgsLabel ``x'' attribute", __FILE__, __LINE__  );
 
670
    }
 
671
    else
 
672
    {
 
673
        el = scratchNode.toElement();
 
674
        setLabelField ( XCoordinate, el.attribute("field","") );
 
675
    }
 
676
 
 
677
    /* Y */
 
678
    scratchNode = node.namedItem("y");
 
679
 
 
680
    if ( scratchNode.isNull() )
 
681
    {
 
682
        qDebug( "%s:%d couldn't find QgsLabel ``y'' attribute", __FILE__, __LINE__  );
 
683
    }
 
684
    else
 
685
    {
 
686
        el = scratchNode.toElement();
 
687
        setLabelField ( YCoordinate, el.attribute("field","") );
 
688
    }
 
689
 
 
690
 
 
691
    /* X,Y offset */
 
692
    scratchNode = node.namedItem("offset");
 
693
 
 
694
    if ( scratchNode.isNull() )
 
695
    {
 
696
        qDebug( "%s:%d couldn't find QgsLabel ``offset'' attribute", __FILE__, __LINE__  );
 
697
    }
 
698
    else
 
699
    {
 
700
        double xoffset, yoffset;
 
701
 
 
702
        el = scratchNode.toElement();
 
703
 
 
704
        type = QgsLabelAttributes::unitsCode( el.attribute("units","") );
 
705
        xoffset = el.attribute("x","0.0").toDouble();
 
706
        yoffset = el.attribute("y","0.0").toDouble();
 
707
 
 
708
        mLabelAttributes->setOffset ( xoffset, yoffset, type );
 
709
        setLabelField ( XOffset, el.attribute("xfield","0") );
 
710
        setLabelField ( YOffset, el.attribute("yfield","0") );
 
711
    }
 
712
 
 
713
    /* Angle */
 
714
    scratchNode = node.namedItem("angle");
 
715
 
 
716
    if ( scratchNode.isNull() )
 
717
    {
 
718
        qDebug( "%s:%d couldn't find QgsLabel ``angle'' attribute", __FILE__, __LINE__  );
 
719
    }
 
720
    else
 
721
    {
 
722
        el = scratchNode.toElement();
 
723
        mLabelAttributes->setAngle ( el.attribute("value","0.0").toDouble() );
 
724
        setLabelField ( Angle, el.attribute("field","0.0") );
 
725
    }
 
726
 
 
727
    /* Alignment */
 
728
    scratchNode = node.namedItem("alignment");
 
729
 
 
730
    if ( scratchNode.isNull() )
 
731
    {
 
732
        qDebug( "%s:%d couldn't find QgsLabel ``alignment'' attribute", __FILE__, __LINE__  );
 
733
    }
 
734
    else
 
735
    {
 
736
        el = scratchNode.toElement();
 
737
        mLabelAttributes->setAlignment ( QgsLabelAttributes::alignmentCode(el.attribute("value","")) );
 
738
        setLabelField ( Alignment, el.attribute("field","") );
 
739
    }
 
740
 
 
741
 
 
742
    // Buffer
 
743
    scratchNode = node.namedItem("buffercolor");
 
744
 
 
745
    if ( scratchNode.isNull() )
 
746
    {
 
747
        qDebug( "%s:%d couldn't find QgsLabel ``buffercolor'' attribute", __FILE__, __LINE__  );
 
748
    }
 
749
    else
 
750
    {
 
751
        el = scratchNode.toElement();
 
752
 
 
753
        red = el.attribute("red","0").toInt();
 
754
        green = el.attribute("green","0").toInt();
 
755
        blue = el.attribute("blue","0").toInt();
 
756
 
 
757
        mLabelAttributes->setBufferColor( QColor(red, green, blue) );
 
758
        setLabelField ( BufferColor, el.attribute("field","") );
 
759
    }
 
760
 
 
761
    scratchNode = node.namedItem("buffersize");
 
762
 
 
763
    if ( scratchNode.isNull() )
 
764
    {
 
765
        qDebug( "%s:%d couldn't find QgsLabel ``buffersize'' attribute", __FILE__, __LINE__  );
 
766
    }
 
767
    else
 
768
    {
 
769
        el = scratchNode.toElement();
 
770
 
 
771
        type = QgsLabelAttributes::unitsCode( el.attribute("units","") );
 
772
        mLabelAttributes->setBufferSize ( el.attribute("value","0.0").toDouble(), type );
 
773
        setLabelField ( BufferSize, el.attribute("field","") );
 
774
    }
 
775
 
 
776
    scratchNode = node.namedItem("bufferenabled");
 
777
 
 
778
    if ( scratchNode.isNull() )
 
779
    {
 
780
        qDebug( "%s:%d couldn't find QgsLabel ``bufferenabled'' attribute", __FILE__, __LINE__  );
 
781
    }
 
782
    else
 
783
    {
 
784
        el = scratchNode.toElement();
 
785
 
 
786
        mLabelAttributes->setBufferEnabled ( (bool)el.attribute("on","0").toInt() );
 
787
        setLabelField ( BufferEnabled, el.attribute("field","") );
 
788
    }
 
789
 
 
790
} // QgsLabel::readXML()
 
791
 
 
792
 
 
793
 
 
794
void QgsLabel::writeXML(std::ostream& xml)
 
795
{
 
796
 
 
797
    xml << "\t\t<labelattributes>\n";
 
798
 
 
799
    // else
 
800
    if ( mLabelAttributes->textIsSet() && !mLabelField[Text].isEmpty() )
 
801
    {
 
802
        xml << "\t\t\t<label text=\"" << mLabelAttributes->text() << "\" field=\"" << mLabelField[Text] << "\" />\n";
 
803
    }
 
804
    else if ( mLabelAttributes->textIsSet() )
 
805
    {
 
806
        xml << "\t\t\t<label text=\"" << mLabelAttributes->text() << "\" field=\"\" />\n";
 
807
    }
 
808
    else
 
809
    {
 
810
        xml << "\t\t\t<label text=\"" << mLabelAttributes->text() << "\" field=\"" << mLabelField[Text] << "\" />\n";
 
811
    }
 
812
 
 
813
    if ( mLabelAttributes->familyIsSet() && ! mLabelAttributes->family().isNull() && mLabelField[Family].isNull())
 
814
    {
 
815
        xml << "\t\t\t<family name=\"" << mLabelAttributes->family() << "\" field=\"" << mLabelField[Family] << "\" />\n";
 
816
    }
 
817
    else if ( mLabelAttributes->familyIsSet() && ! mLabelAttributes->family().isNull() )
 
818
    {
 
819
        xml << "\t\t\t<family name=\"" << mLabelAttributes->family() << "\" field=\"\" />\n";
 
820
    }
 
821
    else
 
822
    {
 
823
        xml << "\t\t\t<family name=\"Arial\" field=\"\" />\n";
 
824
    }
 
825
 
 
826
    //size and units
 
827
    if ( mLabelAttributes->sizeIsSet() && !mLabelField[Size].isEmpty())
 
828
    {
 
829
        xml << "\t\t\t<size value=\"" << mLabelAttributes->size() << "\" units=\""
 
830
            << (const char *)QgsLabelAttributes::unitsName(mLabelAttributes->sizeType()) << "\" field=\"" << mLabelField[Size] << "\" />\n";
 
831
    }
 
832
    else if ( mLabelAttributes->sizeIsSet() )
 
833
    {
 
834
        xml << "\t\t\t<size value=\"" << mLabelAttributes->size() << "\" units=\""
 
835
            << (const char *)QgsLabelAttributes::unitsName(mLabelAttributes->sizeType()) << "\" field=\"\" />\n";
 
836
    }
 
837
    else
 
838
    {
 
839
        xml << "\t\t\t<size value=\"12\" units=\"Points\" field=\"\" />\n";
 
840
    }
 
841
 
 
842
 
 
843
 
 
844
    //bold
 
845
    if ( mLabelAttributes->boldIsSet() && !mLabelField[Bold].isEmpty() )
 
846
    {
 
847
        xml << "\t\t\t<bold on=\"" << mLabelAttributes->bold() << "\" field=\"" << mLabelField[Bold] << "\" />\n";
 
848
    }
 
849
    else if ( mLabelAttributes->boldIsSet() )
 
850
    {
 
851
        xml << "\t\t\t<bold on=\"" << mLabelAttributes->bold() << "\" field=\"\" />\n";
 
852
    }
 
853
    else
 
854
    {
 
855
        xml << "\t\t\t<bold on=\"0\" field=\"0\" />\n";
 
856
    }
 
857
 
 
858
    //italics
 
859
    if ( mLabelAttributes->italicIsSet() && ! mLabelField[Italic].isEmpty())
 
860
    {
 
861
        xml << "\t\t\t<italic on=\"" << mLabelAttributes->italic() << "\" field=\"" << mLabelField[Italic] << "\" />\n";
 
862
    }
 
863
    else if ( mLabelAttributes->italicIsSet() )
 
864
    {
 
865
        xml << "\t\t\t<italic on=\"" << mLabelAttributes->italic() << "\" field=\"\" />\n";
 
866
    }
 
867
    else
 
868
    {
 
869
        xml << "\t\t\t<italic on=\"0\" field=\"\" />\n";
 
870
    }
 
871
    //underline
 
872
    if ( mLabelAttributes->underlineIsSet() && !mLabelField[Underline].isEmpty())
 
873
    {
 
874
        xml << "\t\t\t<underline on=\"" << mLabelAttributes->underline() << "\" field=\"" << mLabelField[Underline] << "\" />\n";
 
875
    }
 
876
    else if ( mLabelAttributes->underlineIsSet() )
 
877
    {
 
878
        xml << "\t\t\t<underline on=\"" << mLabelAttributes->underline() << "\" field=\"\" />\n";
 
879
    }
 
880
    else
 
881
    {
 
882
        xml << "\t\t\t<underline on=\"0\" field=\"\" />\n";
 
883
    }
 
884
 
 
885
    if ( mLabelAttributes->colorIsSet() && ! mLabelField[Color].isNull() )
 
886
    {
 
887
        xml << "\t\t\t<color red=\"" << mLabelAttributes->color().red() << "\" green=\"" << mLabelAttributes->color().green()
 
888
            << "\" blue=\"" << mLabelAttributes->color().blue() << "\" field=\"" << mLabelField[Color] << "\" />\n";
 
889
    }
 
890
    else if ( mLabelAttributes->colorIsSet() )
 
891
    {
 
892
        xml << "\t\t\t<color red=\"" << mLabelAttributes->color().red() << "\" green=\"" << mLabelAttributes->color().green()
 
893
            << "\" blue=\"" << mLabelAttributes->color().blue() << "\" field=\"\" />\n";
 
894
    }
 
895
    else
 
896
    {
 
897
        xml << "\t\t\t<color red=\"0\" green=\"0\" blue=\"0\" field=\"\" />\n";
 
898
    }
 
899
 
 
900
 
 
901
    /* X */
 
902
    if (! mLabelField[XCoordinate].isEmpty() )
 
903
    {
 
904
      xml << "\t\t\t<x field=\"" << mLabelField[XCoordinate] << "\" />\n";
 
905
    }
 
906
    else
 
907
    {
 
908
     xml << "\t\t\t<x field=\"" << "\" />\n";
 
909
    }
 
910
 
 
911
    /* Y */
 
912
    if (! mLabelField[YCoordinate].isEmpty() )
 
913
    {
 
914
      xml << "\t\t\t<y field=\"" << mLabelField[YCoordinate] << "\" />\n";
 
915
    }
 
916
    else
 
917
    {
 
918
     xml << "\t\t\t<y field=\"" << "\" />\n";
 
919
    }
 
920
 
 
921
    // offset
 
922
    if ( mLabelAttributes->offsetIsSet() )
 
923
    {
 
924
        xml << "\t\t\t<offset  units=\"" << QgsLabelAttributes::unitsName(mLabelAttributes->offsetType())
 
925
            << "\" x=\"" << mLabelAttributes->xOffset() << "\" xfield=\"" << mLabelField[XOffset]
 
926
            << "\" y=\"" << mLabelAttributes->yOffset() << "\" yfield=\"" << mLabelField[YOffset]
 
927
            << "\" />\n";
 
928
    }
 
929
 
 
930
    // Angle
 
931
    if ( mLabelAttributes->angleIsSet() )
 
932
    {
 
933
        xml << "\t\t\t<angle value=\"" << mLabelAttributes->angle() << "\" field=\"" << mLabelField[Angle] << "\" />\n";
 
934
    }
 
935
    else if ( mLabelAttributes->angleIsSet() )
 
936
    {
 
937
        xml << "\t\t\t<angle value=\"" << mLabelAttributes->angle() << "\" field=\"" << "\" />\n";
 
938
    }
 
939
    else
 
940
    {
 
941
        xml << "\t\t\t<angle value=\"" << "\" field=\"" << "\" />\n";
 
942
    }
 
943
 
 
944
    // alignment
 
945
    if ( mLabelAttributes->alignmentIsSet() )
 
946
    {
 
947
        xml << "\t\t\t<alignment value=\"" << QgsLabelAttributes::alignmentName(mLabelAttributes->alignment())
 
948
            << "\" field=\"" << mLabelField[Alignment] << "\" />\n";
 
949
    }
 
950
 
 
951
 
 
952
    if ( mLabelAttributes->bufferColorIsSet() && ! mLabelField[BufferColor].isNull() )
 
953
    {
 
954
        xml << "\t\t\t<buffercolor red=\"" << mLabelAttributes->bufferColor().red() << "\" green=\"" << mLabelAttributes->bufferColor().green()
 
955
            << "\" blue=\"" << mLabelAttributes->bufferColor().blue() << "\" field=\"" << mLabelField[BufferColor] << "\" />\n";
 
956
    }
 
957
    else if ( mLabelAttributes->bufferColorIsSet() )
 
958
    {
 
959
        xml << "\t\t\t<buffercolor red=\"" << mLabelAttributes->bufferColor().red() << "\" green=\"" << mLabelAttributes->bufferColor().green()
 
960
            << "\" blue=\"" << mLabelAttributes->bufferColor().blue() << "\" field=\"" <<  "\" />\n";
 
961
    }
 
962
    else
 
963
    {
 
964
        xml << "\t\t\t<buffercolor red=\""  << "\" green=\""
 
965
            << "\" blue=\""  << "\" field=\"" <<  "\" />\n";
 
966
    }
 
967
 
 
968
 
 
969
    if ( mLabelAttributes->bufferSizeIsSet() && ! mLabelField[BufferSize].isNull() )
 
970
    {
 
971
        xml << "\t\t\t<buffersize value=\"" << mLabelAttributes->bufferSize() << "\" units=\""
 
972
            << (const char *)QgsLabelAttributes::unitsName(mLabelAttributes->bufferSizeType()) << "\" field=\"" << mLabelField[BufferSize] << "\" />\n";
 
973
    }
 
974
    else if ( mLabelAttributes->bufferSizeIsSet() )
 
975
    {
 
976
        xml << "\t\t\t<buffersize value=\"" << mLabelAttributes->bufferSize() << "\" units=\""
 
977
            << (const char *)QgsLabelAttributes::unitsName(mLabelAttributes->bufferSizeType()) << "\" field=\"" << "\" />\n";
 
978
    }
 
979
    else
 
980
    {
 
981
        xml << "\t\t\t<buffersize value=\"" << "\" units=\""
 
982
            <<  "\" field=\"" <<  "\" />\n";
 
983
    }
 
984
 
 
985
 
 
986
    if ( mLabelAttributes->bufferEnabled() && ! mLabelField[BufferEnabled].isNull() )
 
987
    {
 
988
        xml << "\t\t\t<bufferenabled on=\"" << mLabelAttributes->bufferEnabled() << "\" field=\"" << mLabelField[BufferEnabled] << "\" />\n";
 
989
    }
 
990
    else if ( mLabelAttributes->bufferEnabled())
 
991
    {
 
992
        xml << "\t\t\t<bufferenabled on=\"" << mLabelAttributes->bufferEnabled() << "\" field=\"" << "\" />\n";
 
993
    }
 
994
    else
 
995
    {
 
996
        xml << "\t\t\t<bufferenabled on=\"" << "\" field=\"" << "\" />\n";
 
997
    }
 
998
    xml << "\t\t</labelattributes>\n";
 
999
}
 
1000