22 #include <QFontMetrics>
26 #include <QDomElement>
44 #define M_PI 4*atan(1.0)
52 mMaxScale( 100000000 ),
53 mScaleBasedVisibility( false )
77 QgsAttributeMap::const_iterator it = attrs.find(
mLabelFieldIdx[attr] );
79 if ( it != attrs.end() )
81 return it->toString();
104 double x1 = point.
x();
106 double x2 = point.
x();
107 double scale = ( x2 - x1 ) * 0.001;
111 if ( value.isEmpty() )
122 if ( value.isEmpty() )
128 font.setFamily( value );
133 if ( value.isEmpty() )
139 size = value.toDouble();
143 if ( value.isEmpty() )
147 value = value.toLower();
148 if ( value.compare(
"mapunits" ) == 0 )
159 double sizeMM = size * 0.3527;
167 if ((
int )size <= 0 )
171 font.setPixelSize( size );
174 if ( value.isEmpty() )
180 pen.setColor( QColor( value ) );
184 if ( value.isEmpty() )
190 font.setBold((
bool ) value.toInt() );
194 if ( value.isEmpty() )
200 font.setItalic((
bool ) value.toInt() );
204 if ( value.isEmpty() )
210 font.setUnderline((
bool ) value.toInt() );
214 if ( value.isEmpty() )
220 font.setStrikeOut((
bool ) value.toInt() );
225 bool useOverridePoint =
false;
227 if ( !value.isEmpty() )
229 overridePoint.
setX( value.toDouble() );
230 useOverridePoint =
true;
233 if ( !value.isEmpty() )
235 overridePoint.
setY( value.toDouble() );
236 useOverridePoint =
true;
241 QFontMetrics fm( font );
246 QStringList texts = text.split(
"\n" );
249 for (
int i = 0; i < texts.size(); i++ )
251 int w = fm.width( texts[i] );
256 height = fm.height() * texts.size();
260 width = fm.width( text );
261 height = fm.height();
268 if ( value.isEmpty() )
274 value = value.toLower();
278 if ( value.contains(
"left" ) )
279 alignment |= Qt::AlignLeft;
280 else if ( value.contains(
"right" ) )
281 alignment |= Qt::AlignRight;
283 alignment |= Qt::AlignHCenter;
285 if ( value.contains(
"bottom" ) )
286 alignment |= Qt::AlignBottom;
287 else if ( value.contains(
"top" ) )
288 alignment |= Qt::AlignTop;
290 alignment |= Qt::AlignVCenter;
293 if ( alignment & Qt::AlignLeft )
297 else if ( alignment & Qt::AlignHCenter )
301 else if ( alignment & Qt::AlignRight )
306 if ( alignment & Qt::AlignBottom )
310 else if ( alignment & Qt::AlignVCenter )
314 else if ( alignment & Qt::AlignTop )
320 double xoffset, yoffset;
322 if ( value.isEmpty() )
328 xoffset = value.toDouble();
331 if ( value.isEmpty() )
337 yoffset = value.toDouble();
348 xoffset = xoffset * 0.3527 * renderContext.
scaleFactor();
349 yoffset = yoffset * 0.3527 * renderContext.
scaleFactor();
355 if ( value.isEmpty() )
361 ang = value.toDouble();
368 if ( useOverridePoint )
370 renderLabel( renderContext, overridePoint, text, font, pen, dx, dy,
371 xoffset, yoffset, ang, width, height, alignment );
375 std::vector<labelpoint> points;
377 for ( uint i = 0; i < points.size(); ++i )
379 renderLabel( renderContext, points[i].p, text, font, pen, dx, dy,
387 QString text, QFont font, QPen pen,
389 double xoffset,
double yoffset,
391 int width,
int height,
int alignment )
393 QPainter *painter = renderContext.
painter();
405 QgsDebugMsg(
"Caught transform error. Skipping rendering this label" );
412 double x = point.
x();
413 double y = point.
y();
415 double rad = ang *
M_PI / 180;
417 x = x + xoffset * cos( rad ) - yoffset * sin( rad );
418 y = y - xoffset * sin( rad ) - yoffset * cos( rad );
421 painter->setFont( font );
422 painter->translate( x, y );
425 painter->rotate( -ang );
440 bufferPen.setColor( Qt::white );
442 painter->setPen( bufferPen );
444 double bufferStepSize;
454 for (
double i = dx - myBufferSize; i <= dx + myBufferSize; i += bufferStepSize )
456 for (
double j = dy - myBufferSize; j <= dy + myBufferSize; j += bufferStepSize )
459 painter->drawText( QRectF( i, j - height, width, height ), alignment, text );
461 painter->drawText( QPointF( i, j ), text );
466 painter->setPen( pen );
468 painter->drawText( dx, dy - height, width, height, alignment, text );
470 painter->drawText( dx, dy, text );
481 for ( QgsAttributeList::iterator it = fields.begin(); it != fields.end(); ++it )
520 return mField[fieldIndex].name();
536 unsigned char *geom = geometry->
asWkb();
537 size_t geomlen = geometry->
wkbSize();
551 points.push_back( point );
563 Q_ASSERT( 1 +
sizeof( wkbType ) +
sizeof(
int ) <= geomlen );
564 geom += 1 +
sizeof( wkbType );
565 int nFeatures = *(
unsigned int * )geom;
566 geom +=
sizeof( int );
568 unsigned char *feature = geom;
569 for (
int i = 0; i < nFeatures && feature; ++i )
571 feature =
labelPoint( point, feature, geom + geomlen - feature );
572 points.push_back( point );
577 QgsDebugMsg(
"Unknown geometry type of " + QString::number( wkbType ) );
584 Q_ASSERT(
sizeof(
int ) == 4 );
586 Q_ASSERT(
sizeof(
double ) == 8 );
596 unsigned char *geomend = geom + geomlen;
598 Q_ASSERT( geom + 1 +
sizeof( wkbType ) <= geomend );
601 memcpy( &wkbType, geom,
sizeof( wkbType ) );
602 geom +=
sizeof( wkbType );
611 Q_ASSERT( geom + 2*
sizeof(
double ) <= geomend );
612 double *pts = (
double * )geom;
613 point.
p.
set( pts[0], pts[1] );
615 geom += 2 *
sizeof( double );
623 Q_ASSERT( geom +
sizeof(
int ) <= geomend );
624 int nPoints = *(
unsigned int * )geom;
625 geom +=
sizeof( int );
627 Q_ASSERT( geom + nPoints*
sizeof(
double )*dims <= geomend );
630 double *pts = (
double * )geom;
632 for (
int i = 1; i < nPoints; i++ )
634 double dx = pts[dims*i] - pts[dims*( i-1 )];
635 double dy = pts[dims*i+1] - pts[dims*( i-1 )+1];
636 tl += sqrt( dx * dx + dy * dy );
642 for (
int i = 1; i < nPoints; i++ )
644 double dx = pts[dims*i] - pts[dims*( i-1 )];
645 double dy = pts[dims*i+1] - pts[dims*( i-1 )+1];
646 double dl = sqrt( dx * dx + dy * dy );
650 double k = ( tl - l ) / dl;
652 point.
p.
set( pts[dims*( i-1 )] + k * dx,
653 pts[dims*( i-1 )+1] + k * dy );
654 point.
angle = atan2( dy, dx ) * 180.0 * M_1_PI;
661 geom += nPoints *
sizeof( double ) * dims;
669 Q_ASSERT( geom +
sizeof(
int ) <= geomend );
670 int nRings = *(
unsigned int * )geom;
671 geom +=
sizeof( int );
673 for (
int i = 0; i < nRings; ++i )
675 Q_ASSERT( geom +
sizeof(
int ) <= geomend );
676 int nPoints = *(
unsigned int * )geom;
677 geom +=
sizeof( int );
679 Q_ASSERT( geom + nPoints*
sizeof(
double )*dims <= geomend );
683 double sx = 0.0, sy = 0.0;
684 double *pts = (
double* ) geom;
685 for (
int j = 0; j < nPoints - 1; j++ )
690 point.
p.
set( sx / ( nPoints - 1 ),
691 sy / ( nPoints - 1 ) );
695 geom += nPoints *
sizeof( double ) * dims;
712 QString name = prefix +
"name";
714 if ( el.hasAttribute( name ) )
716 name = el.attribute( name );
718 QgsFieldMap::const_iterator field_it =
mField.constBegin();
719 for ( ; field_it !=
mField.constEnd(); ++field_it )
721 if ( field_it.value().name() == name )
727 if ( field_it !=
mField.constEnd() )
733 else if ( el.hasAttribute( prefix ) )
735 QString value = el.attribute( prefix );
747 QgsDebugMsg(
" called for layer label properties, got node " + node.nodeName() );
749 QDomNode scratchNode;
752 int red, green, blue;
756 scratchNode = node.namedItem(
"label" );
758 if ( scratchNode.isNull() )
760 QgsDebugMsg(
"couldn't find QgsLabel ``label'' attribute" );
764 el = scratchNode.toElement();
770 scratchNode = node.namedItem(
"family" );
772 if ( scratchNode.isNull() )
774 QgsDebugMsg(
"couldn't find QgsLabel ``family'' attribute" );
778 el = scratchNode.toElement();
784 scratchNode = node.namedItem(
"size" );
786 if ( scratchNode.isNull() )
788 QgsDebugMsg(
"couldn't find QgsLabel ``size'' attribute" );
792 el = scratchNode.toElement();
793 if ( !el.hasAttribute(
"unitfield" ) && !el.hasAttribute(
"unitfieldname" ) )
806 scratchNode = node.namedItem(
"bold" );
808 if ( scratchNode.isNull() )
810 QgsDebugMsg(
"couldn't find QgsLabel ``bold'' attribute" );
814 el = scratchNode.toElement();
820 scratchNode = node.namedItem(
"italic" );
822 if ( scratchNode.isNull() )
824 QgsDebugMsg(
"couldn't find QgsLabel ``italic'' attribute" );
828 el = scratchNode.toElement();
834 scratchNode = node.namedItem(
"underline" );
836 if ( scratchNode.isNull() )
838 QgsDebugMsg(
"couldn't find QgsLabel ``underline'' attribute" );
842 el = scratchNode.toElement();
848 scratchNode = node.namedItem(
"strikeout" );
850 if ( scratchNode.isNull() )
852 QgsDebugMsg(
"couldn't find QgsLabel ``strikeout'' attribute" );
856 el = scratchNode.toElement();
862 scratchNode = node.namedItem(
"color" );
864 if ( scratchNode.isNull() )
866 QgsDebugMsg(
"couldn't find QgsLabel ``color'' attribute" );
870 el = scratchNode.toElement();
872 red = el.attribute(
"red",
"0" ).toInt();
873 green = el.attribute(
"green",
"0" ).toInt();
874 blue = el.attribute(
"blue",
"0" ).toInt();
882 scratchNode = node.namedItem(
"x" );
884 if ( scratchNode.isNull() )
886 QgsDebugMsg(
"couldn't find QgsLabel ``x'' attribute" );
890 el = scratchNode.toElement();
895 scratchNode = node.namedItem(
"y" );
897 if ( scratchNode.isNull() )
899 QgsDebugMsg(
"couldn't find QgsLabel ``y'' attribute" );
903 el = scratchNode.toElement();
909 scratchNode = node.namedItem(
"offset" );
911 if ( scratchNode.isNull() )
913 QgsDebugMsg(
"couldn't find QgsLabel ``offset'' attribute" );
917 double xoffset, yoffset;
919 el = scratchNode.toElement();
922 xoffset = el.attribute(
"x",
"0.0" ).toDouble();
923 yoffset = el.attribute(
"y",
"0.0" ).toDouble();
931 scratchNode = node.namedItem(
"angle" );
933 if ( scratchNode.isNull() )
935 QgsDebugMsg(
"couldn't find QgsLabel ``angle'' attribute" );
939 el = scratchNode.toElement();
946 scratchNode = node.namedItem(
"alignment" );
948 if ( scratchNode.isNull() )
950 QgsDebugMsg(
"couldn't find QgsLabel ``alignment'' attribute" );
954 el = scratchNode.toElement();
961 scratchNode = node.namedItem(
"buffercolor" );
963 if ( scratchNode.isNull() )
965 QgsDebugMsg(
"couldn't find QgsLabel ``buffercolor'' attribute" );
969 el = scratchNode.toElement();
971 red = el.attribute(
"red",
"0" ).toInt();
972 green = el.attribute(
"green",
"0" ).toInt();
973 blue = el.attribute(
"blue",
"0" ).toInt();
979 scratchNode = node.namedItem(
"buffersize" );
981 if ( scratchNode.isNull() )
983 QgsDebugMsg(
"couldn't find QgsLabel ``bffersize'' attribute" );
987 el = scratchNode.toElement();
994 scratchNode = node.namedItem(
"bufferenabled" );
996 if ( scratchNode.isNull() )
998 QgsDebugMsg(
"couldn't find QgsLabel ``bufferenabled'' attribute" );
1002 el = scratchNode.toElement();
1008 scratchNode = node.namedItem(
"multilineenabled" );
1010 if ( scratchNode.isNull() )
1012 QgsDebugMsg(
"couldn't find QgsLabel ``multilineenabled'' attribute" );
1016 el = scratchNode.toElement();
1022 scratchNode = node.namedItem(
"selectedonly" );
1024 if ( scratchNode.isNull() )
1026 QgsDebugMsg(
"couldn't find QgsLabel ``selectedonly'' attribute" );
1030 el = scratchNode.toElement();
1040 QDomElement labelattributes = document.createElement(
"labelattributes" );
1043 QDomElement label = document.createElement(
"label" );
1051 label.setAttribute(
"fieldname",
"" );
1053 labelattributes.appendChild( label );
1056 QDomElement family = document.createElement(
"family" );
1067 family.setAttribute(
"fieldname",
"" );
1072 family.setAttribute(
"name",
"Arial" );
1073 family.setAttribute(
"fieldname",
"" );
1075 labelattributes.appendChild( family );
1078 QDomElement size = document.createElement(
"size" );
1097 size.setAttribute(
"fieldname",
"" );
1102 size.setAttribute(
"value",
"12" );
1103 size.setAttribute(
"units",
"Points" );
1104 size.setAttribute(
"fieldname",
"" );
1106 labelattributes.appendChild( size );
1109 QDomElement bold = document.createElement(
"bold" );
1119 bold.setAttribute(
"fieldname",
"" );
1124 bold.setAttribute(
"on", 0 );
1125 bold.setAttribute(
"fieldname", 0 );
1127 labelattributes.appendChild( bold );
1130 QDomElement italic = document.createElement(
"italic" );
1140 italic.setAttribute(
"fieldname",
"" );
1145 italic.setAttribute(
"on",
"0" );
1146 italic.setAttribute(
"fieldname",
"" );
1148 labelattributes.appendChild( italic );
1151 QDomElement underline = document.createElement(
"underline" );
1161 underline.setAttribute(
"fieldname",
"" );
1166 underline.setAttribute(
"on", 0 );
1167 underline.setAttribute(
"fieldname",
"" );
1169 labelattributes.appendChild( underline );
1172 QDomElement strikeOut = document.createElement(
"strikeout" );
1182 strikeOut.setAttribute(
"fieldname",
"" );
1187 strikeOut.setAttribute(
"on", 0 );
1188 strikeOut.setAttribute(
"fieldname",
"" );
1190 labelattributes.appendChild( strikeOut );
1193 QDomElement color = document.createElement(
"color" );
1205 color.setAttribute(
"fieldname",
"" );
1210 color.setAttribute(
"red", 0 );
1211 color.setAttribute(
"green", 0 );
1212 color.setAttribute(
"blue", 0 );
1213 color.setAttribute(
"fieldname",
"" );
1215 labelattributes.appendChild( color );
1218 QDomElement x = document.createElement(
"x" );
1225 x.setAttribute(
"fieldname",
"" );
1227 labelattributes.appendChild( x );
1230 QDomElement y = document.createElement(
"y" );
1237 y.setAttribute(
"fieldname",
"" );
1239 labelattributes.appendChild( y );
1244 QDomElement offset = document.createElement(
"offset" );
1250 labelattributes.appendChild( offset );
1254 QDomElement
angle = document.createElement(
"angle" );
1264 angle.setAttribute(
"fieldname",
"" );
1269 angle.setAttribute(
"value",
"" );
1270 angle.setAttribute(
"fieldname",
"" );
1273 labelattributes.appendChild( angle );
1278 QDomElement alignment = document.createElement(
"alignment" );
1281 labelattributes.appendChild( alignment );
1285 QDomElement buffercolor = document.createElement(
"buffercolor" );
1297 buffercolor.setAttribute(
"fieldname",
"" );
1302 buffercolor.setAttribute(
"red",
"" );
1303 buffercolor.setAttribute(
"green",
"" );
1304 buffercolor.setAttribute(
"blue",
"" );
1305 buffercolor.setAttribute(
"fieldname",
"" );
1307 labelattributes.appendChild( buffercolor );
1310 QDomElement buffersize = document.createElement(
"buffersize" );
1321 buffersize.setAttribute(
"fieldname",
"" );
1326 buffersize.setAttribute(
"value",
"" );
1327 buffersize.setAttribute(
"units",
"" );
1328 buffersize.setAttribute(
"fieldname",
"" );
1330 labelattributes.appendChild( buffersize );
1333 QDomElement bufferenabled = document.createElement(
"bufferenabled" );
1343 bufferenabled.setAttribute(
"fieldname",
"" );
1348 bufferenabled.setAttribute(
"on",
"" );
1349 bufferenabled.setAttribute(
"fieldname",
"" );
1351 labelattributes.appendChild( bufferenabled );
1354 QDomElement multilineenabled = document.createElement(
"multilineenabled" );
1364 multilineenabled.setAttribute(
"fieldname",
"" );
1369 multilineenabled.setAttribute(
"on",
"" );
1370 multilineenabled.setAttribute(
"fieldname",
"" );
1372 labelattributes.appendChild( multilineenabled );
1374 QDomElement selectedonly = document.createElement(
"selectedonly" );
1381 selectedonly.setAttribute(
"on",
"" );
1383 labelattributes.appendChild( selectedonly );
1385 layer_node.appendChild( labelattributes );