22 #include <QFontMetrics>
26 #include <QDomElement>
44 #define M_PI 4*atan(1.0)
49 mMaxScale( 100000000 ),
50 mScaleBasedVisibility( false )
69 return idx < 0 ? QString() : feature.
attribute( idx ).toString();
76 Q_UNUSED( classAttributes );
89 double x1 = point.
x();
91 double x2 = point.
x();
92 double scale = ( x2 - x1 ) * 0.001;
96 if ( value.isEmpty() )
107 if ( value.isEmpty() )
113 font.setFamily( value );
118 if ( value.isEmpty() )
124 size = value.toDouble();
128 if ( value.isEmpty() )
132 value = value.toLower();
133 if ( value.compare(
"mapunits" ) == 0 )
144 double sizeMM = size * 0.3527;
152 if ((
int )size <= 0 )
156 font.setPixelSize( size );
159 if ( value.isEmpty() )
165 pen.setColor( QColor( value ) );
169 if ( value.isEmpty() )
175 font.setBold((
bool ) value.toInt() );
179 if ( value.isEmpty() )
185 font.setItalic((
bool ) value.toInt() );
189 if ( value.isEmpty() )
195 font.setUnderline((
bool ) value.toInt() );
199 if ( value.isEmpty() )
205 font.setStrikeOut((
bool ) value.toInt() );
210 bool useOverridePoint =
false;
212 if ( !value.isEmpty() )
214 overridePoint.
setX( value.toDouble() );
215 useOverridePoint =
true;
218 if ( !value.isEmpty() )
220 overridePoint.
setY( value.toDouble() );
221 useOverridePoint =
true;
226 QFontMetrics fm( font );
231 QStringList texts = text.split(
"\n" );
234 for (
int i = 0; i < texts.size(); i++ )
236 int w = fm.width( texts[i] );
241 height = fm.height() * texts.size();
245 width = fm.width( text );
246 height = fm.height();
253 if ( value.isEmpty() )
259 value = value.toLower();
263 if ( value.contains(
"left" ) )
264 alignment |= Qt::AlignLeft;
265 else if ( value.contains(
"right" ) )
266 alignment |= Qt::AlignRight;
268 alignment |= Qt::AlignHCenter;
270 if ( value.contains(
"bottom" ) )
271 alignment |= Qt::AlignBottom;
272 else if ( value.contains(
"top" ) )
273 alignment |= Qt::AlignTop;
275 alignment |= Qt::AlignVCenter;
278 if ( alignment & Qt::AlignLeft )
282 else if ( alignment & Qt::AlignHCenter )
286 else if ( alignment & Qt::AlignRight )
291 if ( alignment & Qt::AlignBottom )
295 else if ( alignment & Qt::AlignVCenter )
299 else if ( alignment & Qt::AlignTop )
305 double xoffset, yoffset;
307 if ( value.isEmpty() )
313 xoffset = value.toDouble();
316 if ( value.isEmpty() )
322 yoffset = value.toDouble();
333 xoffset = xoffset * 0.3527 * renderContext.
scaleFactor();
334 yoffset = yoffset * 0.3527 * renderContext.
scaleFactor();
340 if ( value.isEmpty() )
346 ang = value.toDouble();
353 if ( useOverridePoint )
355 renderLabel( renderContext, overridePoint, text, font, pen, dx, dy,
356 xoffset, yoffset, ang, width, height, alignment );
360 std::vector<labelpoint> points;
362 for ( uint i = 0; i < points.size(); ++i )
364 renderLabel( renderContext, points[i].p, text, font, pen, dx, dy,
372 QString text, QFont font, QPen pen,
374 double xoffset,
double yoffset,
376 int width,
int height,
int alignment )
378 QPainter *painter = renderContext.
painter();
390 QgsDebugMsg(
"Caught transform error. Skipping rendering this label" );
397 double x = point.
x();
398 double y = point.
y();
400 double rad = ang *
M_PI / 180;
402 x = x + xoffset * cos( rad ) - yoffset * sin( rad );
403 y = y - xoffset * sin( rad ) - yoffset * cos( rad );
406 painter->setFont( font );
407 painter->translate( x, y );
410 painter->rotate( -ang );
425 bufferPen.setColor( Qt::white );
427 painter->setPen( bufferPen );
429 double bufferStepSize;
439 for (
double i = dx - myBufferSize; i <= dx + myBufferSize; i += bufferStepSize )
441 for (
double j = dy - myBufferSize; j <= dy + myBufferSize; j += bufferStepSize )
444 painter->drawText( QRectF( i, j - height, width, height ), alignment, text );
446 painter->drawText( QPointF( i, j ), text );
451 painter->setPen( pen );
453 painter->drawText( dx, dy - height, width, height, alignment, text );
455 painter->drawText( dx, dy, text );
466 for ( QgsAttributeList::iterator it = fields.begin(); it != fields.end(); ++it )
507 return mFields[fieldIndex].name();
518 const unsigned char *geom = geometry->
asWkb();
519 size_t geomlen = geometry->
wkbSize();
533 points.push_back( point );
545 Q_ASSERT( 1 +
sizeof( wkbType ) +
sizeof(
int ) <= geomlen );
546 geom += 1 +
sizeof( wkbType );
547 int nFeatures = *(
unsigned int * )geom;
548 geom +=
sizeof( int );
550 const unsigned char *feature = geom;
551 for (
int i = 0; i < nFeatures && feature; ++i )
553 feature =
labelPoint( point, feature, geom + geomlen - feature );
554 points.push_back( point );
559 QgsDebugMsg(
"Unknown geometry type of " + QString::number( wkbType ) );
566 Q_ASSERT(
sizeof(
int ) == 4 );
568 Q_ASSERT(
sizeof(
double ) == 8 );
578 const unsigned char *geomend = geom + geomlen;
582 Q_ASSERT( geom + 1 +
sizeof( wkbType ) <= geomend );
585 memcpy( &wkbType, geom,
sizeof( wkbType ) );
586 geom +=
sizeof( wkbType );
595 Q_ASSERT( geom + 2*
sizeof(
double ) <= geomend );
596 double *pts = (
double * )geom;
597 point.
p.
set( pts[0], pts[1] );
599 geom += 2 *
sizeof( double );
607 Q_ASSERT( geom +
sizeof(
int ) <= geomend );
608 int nPoints = *(
unsigned int * )geom;
609 geom +=
sizeof( int );
611 Q_ASSERT( geom + nPoints*
sizeof(
double )*dims <= geomend );
614 double *pts = (
double * )geom;
616 for (
int i = 1; i < nPoints; i++ )
618 double dx = pts[dims*i] - pts[dims*( i-1 )];
619 double dy = pts[dims*i+1] - pts[dims*( i-1 )+1];
620 tl += sqrt( dx * dx + dy * dy );
626 for (
int i = 1; i < nPoints; i++ )
628 double dx = pts[dims*i] - pts[dims*( i-1 )];
629 double dy = pts[dims*i+1] - pts[dims*( i-1 )+1];
630 double dl = sqrt( dx * dx + dy * dy );
634 double k = ( tl - l ) / dl;
636 point.
p.
set( pts[dims*( i-1 )] + k * dx,
637 pts[dims*( i-1 )+1] + k * dy );
638 point.
angle = atan2( dy, dx ) * 180.0 * M_1_PI;
645 geom += nPoints *
sizeof( double ) * dims;
653 Q_ASSERT( geom +
sizeof(
int ) <= geomend );
654 int nRings = *(
unsigned int * )geom;
655 geom +=
sizeof( int );
657 for (
int i = 0; i < nRings; ++i )
659 Q_ASSERT( geom +
sizeof(
int ) <= geomend );
660 int nPoints = *(
unsigned int * )geom;
661 geom +=
sizeof( int );
663 Q_ASSERT( geom + nPoints*
sizeof(
double )*dims <= geomend );
667 double sx = 0.0, sy = 0.0;
668 double *pts = (
double* ) geom;
669 for (
int j = 0; j < nPoints - 1; j++ )
674 point.
p.
set( sx / ( nPoints - 1 ),
675 sy / ( nPoints - 1 ) );
679 geom += nPoints *
sizeof( double ) * dims;
696 QString name = prefix +
"name";
698 if ( el.hasAttribute( name ) )
700 name = el.attribute( name );
705 if (
mFields[idx].name() == name )
717 else if ( el.hasAttribute( prefix ) )
719 QString value = el.attribute( prefix );
731 QgsDebugMsg(
" called for layer label properties, got node " + node.nodeName() );
733 QDomNode scratchNode;
736 int red, green, blue;
740 scratchNode = node.namedItem(
"label" );
742 if ( scratchNode.isNull() )
744 QgsDebugMsg(
"couldn't find QgsLabel ``label'' attribute" );
748 el = scratchNode.toElement();
754 scratchNode = node.namedItem(
"family" );
756 if ( scratchNode.isNull() )
758 QgsDebugMsg(
"couldn't find QgsLabel ``family'' attribute" );
762 el = scratchNode.toElement();
768 scratchNode = node.namedItem(
"size" );
770 if ( scratchNode.isNull() )
772 QgsDebugMsg(
"couldn't find QgsLabel ``size'' attribute" );
776 el = scratchNode.toElement();
777 if ( !el.hasAttribute(
"unitfield" ) && !el.hasAttribute(
"unitfieldname" ) )
790 scratchNode = node.namedItem(
"bold" );
792 if ( scratchNode.isNull() )
794 QgsDebugMsg(
"couldn't find QgsLabel ``bold'' attribute" );
798 el = scratchNode.toElement();
804 scratchNode = node.namedItem(
"italic" );
806 if ( scratchNode.isNull() )
808 QgsDebugMsg(
"couldn't find QgsLabel ``italic'' attribute" );
812 el = scratchNode.toElement();
818 scratchNode = node.namedItem(
"underline" );
820 if ( scratchNode.isNull() )
822 QgsDebugMsg(
"couldn't find QgsLabel ``underline'' attribute" );
826 el = scratchNode.toElement();
832 scratchNode = node.namedItem(
"strikeout" );
834 if ( scratchNode.isNull() )
836 QgsDebugMsg(
"couldn't find QgsLabel ``strikeout'' attribute" );
840 el = scratchNode.toElement();
846 scratchNode = node.namedItem(
"color" );
848 if ( scratchNode.isNull() )
850 QgsDebugMsg(
"couldn't find QgsLabel ``color'' attribute" );
854 el = scratchNode.toElement();
856 red = el.attribute(
"red",
"0" ).toInt();
857 green = el.attribute(
"green",
"0" ).toInt();
858 blue = el.attribute(
"blue",
"0" ).toInt();
866 scratchNode = node.namedItem(
"x" );
868 if ( scratchNode.isNull() )
870 QgsDebugMsg(
"couldn't find QgsLabel ``x'' attribute" );
874 el = scratchNode.toElement();
879 scratchNode = node.namedItem(
"y" );
881 if ( scratchNode.isNull() )
883 QgsDebugMsg(
"couldn't find QgsLabel ``y'' attribute" );
887 el = scratchNode.toElement();
893 scratchNode = node.namedItem(
"offset" );
895 if ( scratchNode.isNull() )
897 QgsDebugMsg(
"couldn't find QgsLabel ``offset'' attribute" );
901 double xoffset, yoffset;
903 el = scratchNode.toElement();
906 xoffset = el.attribute(
"x",
"0.0" ).toDouble();
907 yoffset = el.attribute(
"y",
"0.0" ).toDouble();
915 scratchNode = node.namedItem(
"angle" );
917 if ( scratchNode.isNull() )
919 QgsDebugMsg(
"couldn't find QgsLabel ``angle'' attribute" );
923 el = scratchNode.toElement();
930 scratchNode = node.namedItem(
"alignment" );
932 if ( scratchNode.isNull() )
934 QgsDebugMsg(
"couldn't find QgsLabel ``alignment'' attribute" );
938 el = scratchNode.toElement();
945 scratchNode = node.namedItem(
"buffercolor" );
947 if ( scratchNode.isNull() )
949 QgsDebugMsg(
"couldn't find QgsLabel ``buffercolor'' attribute" );
953 el = scratchNode.toElement();
955 red = el.attribute(
"red",
"0" ).toInt();
956 green = el.attribute(
"green",
"0" ).toInt();
957 blue = el.attribute(
"blue",
"0" ).toInt();
963 scratchNode = node.namedItem(
"buffersize" );
965 if ( scratchNode.isNull() )
967 QgsDebugMsg(
"couldn't find QgsLabel ``bffersize'' attribute" );
971 el = scratchNode.toElement();
978 scratchNode = node.namedItem(
"bufferenabled" );
980 if ( scratchNode.isNull() )
982 QgsDebugMsg(
"couldn't find QgsLabel ``bufferenabled'' attribute" );
986 el = scratchNode.toElement();
992 scratchNode = node.namedItem(
"multilineenabled" );
994 if ( scratchNode.isNull() )
996 QgsDebugMsg(
"couldn't find QgsLabel ``multilineenabled'' attribute" );
1000 el = scratchNode.toElement();
1006 scratchNode = node.namedItem(
"selectedonly" );
1008 if ( scratchNode.isNull() )
1010 QgsDebugMsg(
"couldn't find QgsLabel ``selectedonly'' attribute" );
1014 el = scratchNode.toElement();
1024 QDomElement labelattributes = document.createElement(
"labelattributes" );
1027 QDomElement label = document.createElement(
"label" );
1035 label.setAttribute(
"fieldname",
"" );
1037 labelattributes.appendChild( label );
1040 QDomElement family = document.createElement(
"family" );
1051 family.setAttribute(
"fieldname",
"" );
1056 family.setAttribute(
"name",
"Arial" );
1057 family.setAttribute(
"fieldname",
"" );
1059 labelattributes.appendChild( family );
1062 QDomElement
size = document.createElement(
"size" );
1081 size.setAttribute(
"fieldname",
"" );
1086 size.setAttribute(
"value",
"12" );
1087 size.setAttribute(
"units",
"Points" );
1088 size.setAttribute(
"fieldname",
"" );
1090 labelattributes.appendChild( size );
1093 QDomElement bold = document.createElement(
"bold" );
1103 bold.setAttribute(
"fieldname",
"" );
1108 bold.setAttribute(
"on", 0 );
1109 bold.setAttribute(
"fieldname", 0 );
1111 labelattributes.appendChild( bold );
1114 QDomElement italic = document.createElement(
"italic" );
1124 italic.setAttribute(
"fieldname",
"" );
1129 italic.setAttribute(
"on",
"0" );
1130 italic.setAttribute(
"fieldname",
"" );
1132 labelattributes.appendChild( italic );
1135 QDomElement underline = document.createElement(
"underline" );
1145 underline.setAttribute(
"fieldname",
"" );
1150 underline.setAttribute(
"on", 0 );
1151 underline.setAttribute(
"fieldname",
"" );
1153 labelattributes.appendChild( underline );
1156 QDomElement strikeOut = document.createElement(
"strikeout" );
1166 strikeOut.setAttribute(
"fieldname",
"" );
1171 strikeOut.setAttribute(
"on", 0 );
1172 strikeOut.setAttribute(
"fieldname",
"" );
1174 labelattributes.appendChild( strikeOut );
1177 QDomElement color = document.createElement(
"color" );
1189 color.setAttribute(
"fieldname",
"" );
1194 color.setAttribute(
"red", 0 );
1195 color.setAttribute(
"green", 0 );
1196 color.setAttribute(
"blue", 0 );
1197 color.setAttribute(
"fieldname",
"" );
1199 labelattributes.appendChild( color );
1202 QDomElement x = document.createElement(
"x" );
1209 x.setAttribute(
"fieldname",
"" );
1211 labelattributes.appendChild( x );
1214 QDomElement y = document.createElement(
"y" );
1221 y.setAttribute(
"fieldname",
"" );
1223 labelattributes.appendChild( y );
1228 QDomElement offset = document.createElement(
"offset" );
1234 labelattributes.appendChild( offset );
1238 QDomElement
angle = document.createElement(
"angle" );
1248 angle.setAttribute(
"fieldname",
"" );
1253 angle.setAttribute(
"value",
"" );
1254 angle.setAttribute(
"fieldname",
"" );
1257 labelattributes.appendChild( angle );
1262 QDomElement alignment = document.createElement(
"alignment" );
1265 labelattributes.appendChild( alignment );
1269 QDomElement buffercolor = document.createElement(
"buffercolor" );
1281 buffercolor.setAttribute(
"fieldname",
"" );
1286 buffercolor.setAttribute(
"red",
"" );
1287 buffercolor.setAttribute(
"green",
"" );
1288 buffercolor.setAttribute(
"blue",
"" );
1289 buffercolor.setAttribute(
"fieldname",
"" );
1291 labelattributes.appendChild( buffercolor );
1294 QDomElement buffersize = document.createElement(
"buffersize" );
1305 buffersize.setAttribute(
"fieldname",
"" );
1310 buffersize.setAttribute(
"value",
"" );
1311 buffersize.setAttribute(
"units",
"" );
1312 buffersize.setAttribute(
"fieldname",
"" );
1314 labelattributes.appendChild( buffersize );
1317 QDomElement bufferenabled = document.createElement(
"bufferenabled" );
1327 bufferenabled.setAttribute(
"fieldname",
"" );
1332 bufferenabled.setAttribute(
"on",
"" );
1333 bufferenabled.setAttribute(
"fieldname",
"" );
1335 labelattributes.appendChild( bufferenabled );
1338 QDomElement multilineenabled = document.createElement(
"multilineenabled" );
1348 multilineenabled.setAttribute(
"fieldname",
"" );
1353 multilineenabled.setAttribute(
"on",
"" );
1354 multilineenabled.setAttribute(
"fieldname",
"" );
1356 labelattributes.appendChild( multilineenabled );
1358 QDomElement selectedonly = document.createElement(
"selectedonly" );
1365 selectedonly.setAttribute(
"on",
"" );
1367 labelattributes.appendChild( selectedonly );
1369 layer_node.appendChild( labelattributes );