mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Merge pull request #4838 from aaime/textsymbolizer_sc
SLD label exports. fixes #8925
This commit is contained in:
commit
cf042dc5dd
@ -76,6 +76,11 @@ Try to create instance of an implementation based on the XML data
|
||||
:rtype: QgsAbstractVectorLayerLabeling
|
||||
%End
|
||||
|
||||
virtual void toSld( QDomNode &parent, const QgsStringMap &props ) const;
|
||||
%Docstring
|
||||
Writes the SE 1.1 TextSymbolizer element based on the current layer labeling settings
|
||||
%End
|
||||
|
||||
private:
|
||||
QgsAbstractVectorLayerLabeling( const QgsAbstractVectorLayerLabeling &rhs );
|
||||
};
|
||||
@ -105,6 +110,7 @@ Constructs simple labeling configuration with given initial settings
|
||||
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const;
|
||||
virtual bool requiresAdvancedEffects() const;
|
||||
|
||||
virtual void toSld( QDomNode &parent, const QgsStringMap &props ) const;
|
||||
|
||||
static QgsVectorLayerSimpleLabeling *create( const QDomElement &element, const QgsReadWriteContext &context );
|
||||
%Docstring
|
||||
|
@ -481,6 +481,14 @@ Create ogr feature style string for pen
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
static void createAnchorPointElement( QDomDocument &doc, QDomElement &element, QPointF anchor );
|
||||
%Docstring
|
||||
Creates a SE 1.1 anchor point element as a child of the specified element
|
||||
\param doc The document
|
||||
\param element The parent element
|
||||
\param anchor An anchor specification, with values between 0 and 1
|
||||
%End
|
||||
|
||||
static void createOnlineResourceElement( QDomDocument &doc, QDomElement &element, const QString &path, const QString &format );
|
||||
static bool onlineResourceFromSldElement( QDomElement &element, QString &path, QString &format );
|
||||
%Docstring
|
||||
|
@ -2205,11 +2205,6 @@ bool QgsVectorLayer::writeSld( QDomNode &node, QDomDocument &doc, QString &error
|
||||
{
|
||||
Q_UNUSED( errorMessage );
|
||||
|
||||
// store the Name element
|
||||
QDomElement nameNode = doc.createElement( QStringLiteral( "se:Name" ) );
|
||||
nameNode.appendChild( doc.createTextNode( name() ) );
|
||||
node.appendChild( nameNode );
|
||||
|
||||
QgsStringMap localProps = QgsStringMap( props );
|
||||
if ( hasScaleBasedVisibility() )
|
||||
{
|
||||
@ -2218,7 +2213,27 @@ bool QgsVectorLayer::writeSld( QDomNode &node, QDomDocument &doc, QString &error
|
||||
|
||||
if ( isSpatial() )
|
||||
{
|
||||
node.appendChild( mRenderer->writeSld( doc, name(), localProps ) );
|
||||
// store the Name element
|
||||
QDomElement nameNode = doc.createElement( "se:Name" );
|
||||
nameNode.appendChild( doc.createTextNode( name() ) );
|
||||
node.appendChild( nameNode );
|
||||
|
||||
QDomElement userStyleElem = doc.createElement( "UserStyle" );
|
||||
node.appendChild( userStyleElem );
|
||||
|
||||
QDomElement nameElem = doc.createElement( "se:Name" );
|
||||
nameElem.appendChild( doc.createTextNode( name() ) );
|
||||
|
||||
userStyleElem.appendChild( nameElem );
|
||||
|
||||
QDomElement featureTypeStyleElem = doc.createElement( "se:FeatureTypeStyle" );
|
||||
userStyleElem.appendChild( featureTypeStyleElem );
|
||||
|
||||
mRenderer->toSld( doc, featureTypeStyleElem, localProps );
|
||||
if ( labelsEnabled() )
|
||||
{
|
||||
mLabeling->toSld( featureTypeStyleElem, localProps );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -17,6 +17,10 @@
|
||||
#include "qgspallabeling.h"
|
||||
#include "qgsrulebasedlabeling.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgssymbollayerutils.h"
|
||||
#include "qgssymbollayer.h"
|
||||
#include "qgsmarkersymbollayer.h"
|
||||
#include "qgis.h"
|
||||
|
||||
|
||||
QgsAbstractVectorLayerLabeling *QgsAbstractVectorLayerLabeling::create( const QDomElement &element, const QgsReadWriteContext &context )
|
||||
@ -88,3 +92,457 @@ QgsVectorLayerSimpleLabeling *QgsVectorLayerSimpleLabeling::create( const QDomEl
|
||||
|
||||
return new QgsVectorLayerSimpleLabeling( QgsPalLayerSettings() );
|
||||
}
|
||||
|
||||
QPointF quadOffsetToSldAnchor( QgsPalLayerSettings::QuadrantPosition quadrantPosition )
|
||||
{
|
||||
double quadOffsetX = 0.5, quadOffsetY = 0.5;
|
||||
|
||||
// adjust quadrant offset of labels
|
||||
switch ( quadrantPosition )
|
||||
{
|
||||
case QgsPalLayerSettings::QuadrantAboveLeft:
|
||||
quadOffsetX = 1;
|
||||
quadOffsetY = 0;
|
||||
break;
|
||||
case QgsPalLayerSettings::QuadrantAbove:
|
||||
quadOffsetX = 0.5;
|
||||
quadOffsetY = 0;
|
||||
break;
|
||||
case QgsPalLayerSettings::QuadrantAboveRight:
|
||||
quadOffsetX = 0;
|
||||
quadOffsetY = 0;
|
||||
break;
|
||||
case QgsPalLayerSettings::QuadrantLeft:
|
||||
quadOffsetX = 1;
|
||||
quadOffsetY = 0.5;
|
||||
break;
|
||||
case QgsPalLayerSettings::QuadrantRight:
|
||||
quadOffsetX = 0;
|
||||
quadOffsetY = 0.5;
|
||||
break;
|
||||
case QgsPalLayerSettings::QuadrantBelowLeft:
|
||||
quadOffsetX = 1;
|
||||
quadOffsetY = 1;
|
||||
break;
|
||||
case QgsPalLayerSettings::QuadrantBelow:
|
||||
quadOffsetX = 0.5;
|
||||
quadOffsetY = 1;
|
||||
break;
|
||||
case QgsPalLayerSettings::QuadrantBelowRight:
|
||||
quadOffsetX = 0;
|
||||
quadOffsetY = 1.0;
|
||||
break;
|
||||
case QgsPalLayerSettings::QuadrantOver:
|
||||
break;
|
||||
}
|
||||
|
||||
return QPointF( quadOffsetX, quadOffsetY );
|
||||
}
|
||||
|
||||
/*
|
||||
* This is not a generic function encoder, just enough to encode the label case control functions
|
||||
*/
|
||||
void appendSimpleFunction( QDomDocument &doc, QDomElement &parent, const QString &name, const QString &attribute )
|
||||
{
|
||||
QDomElement function = doc.createElement( QStringLiteral( "ogc:Function" ) );
|
||||
function.setAttribute( QStringLiteral( "name" ), name );
|
||||
parent.appendChild( function );
|
||||
QDomElement property = doc.createElement( QStringLiteral( "ogc:PropertyName" ) );
|
||||
property.appendChild( doc.createTextNode( attribute ) );
|
||||
function.appendChild( property );
|
||||
}
|
||||
|
||||
std::unique_ptr<QgsMarkerSymbolLayer> backgroundToMarkerLayer( const QgsTextBackgroundSettings &settings )
|
||||
{
|
||||
std::unique_ptr<QgsMarkerSymbolLayer> layer;
|
||||
switch ( settings.type() )
|
||||
{
|
||||
case QgsTextBackgroundSettings::ShapeSVG:
|
||||
{
|
||||
QgsSvgMarkerSymbolLayer *svg = new QgsSvgMarkerSymbolLayer( settings.svgFile() );
|
||||
svg->setStrokeWidth( settings.strokeWidth() );
|
||||
svg->setStrokeWidthUnit( settings.strokeWidthUnit() );
|
||||
layer.reset( svg );
|
||||
break;
|
||||
}
|
||||
case QgsTextBackgroundSettings::ShapeCircle:
|
||||
case QgsTextBackgroundSettings::ShapeEllipse:
|
||||
case QgsTextBackgroundSettings::ShapeRectangle:
|
||||
case QgsTextBackgroundSettings::ShapeSquare:
|
||||
{
|
||||
QgsSimpleMarkerSymbolLayer *marker = new QgsSimpleMarkerSymbolLayer();
|
||||
// default value
|
||||
QgsSimpleMarkerSymbolLayerBase::Shape shape = shape = QgsSimpleMarkerSymbolLayerBase::Diamond;
|
||||
switch ( settings.type() )
|
||||
{
|
||||
case QgsTextBackgroundSettings::ShapeCircle:
|
||||
case QgsTextBackgroundSettings::ShapeEllipse:
|
||||
shape = QgsSimpleMarkerSymbolLayerBase::Circle;
|
||||
break;
|
||||
case QgsTextBackgroundSettings::ShapeRectangle:
|
||||
case QgsTextBackgroundSettings::ShapeSquare:
|
||||
shape = QgsSimpleMarkerSymbolLayerBase::Square;
|
||||
break;
|
||||
case QgsTextBackgroundSettings::ShapeSVG:
|
||||
break;
|
||||
}
|
||||
|
||||
marker->setShape( shape );
|
||||
marker->setStrokeWidth( settings.strokeWidth() );
|
||||
marker->setStrokeWidthUnit( settings.strokeWidthUnit() );
|
||||
layer.reset( marker );
|
||||
}
|
||||
}
|
||||
layer->setEnabled( true );
|
||||
// a marker does not have a size x and y, just a size (and it should be at least one)
|
||||
QSizeF size = settings.size();
|
||||
layer->setSize( qMax( 1., qMax( size.width(), size.height() ) ) );
|
||||
layer->setSizeUnit( settings.sizeUnit() );
|
||||
// fill and stroke
|
||||
QColor fillColor = settings.fillColor();
|
||||
QColor strokeColor = settings.strokeColor();
|
||||
if ( settings.opacity() < 1 )
|
||||
{
|
||||
int alpha = qRound( settings.opacity() * 255 );
|
||||
fillColor.setAlpha( alpha );
|
||||
strokeColor.setAlpha( alpha );
|
||||
}
|
||||
layer->setFillColor( fillColor );
|
||||
layer->setStrokeColor( strokeColor );
|
||||
// rotation
|
||||
if ( settings.rotationType() == QgsTextBackgroundSettings::RotationFixed )
|
||||
{
|
||||
layer->setAngle( settings.rotation() );
|
||||
}
|
||||
// offset
|
||||
layer->setOffset( settings.offset() );
|
||||
layer->setOffsetUnit( settings.offsetUnit() );
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
void QgsVectorLayerSimpleLabeling::toSld( QDomNode &parent, const QgsStringMap &props ) const
|
||||
{
|
||||
|
||||
if ( mSettings->drawLabels )
|
||||
{
|
||||
QDomDocument doc = parent.ownerDocument();
|
||||
|
||||
QDomElement ruleElement = doc.createElement( QStringLiteral( "se:Rule" ) );
|
||||
parent.appendChild( ruleElement );
|
||||
|
||||
// scale dependencies
|
||||
if ( mSettings->scaleVisibility )
|
||||
{
|
||||
QgsStringMap scaleProps = QgsStringMap();
|
||||
scaleProps.insert( "scaleMinDenom", qgsDoubleToString( mSettings->minimumScale ) );
|
||||
scaleProps.insert( "scaleMaxDenom", qgsDoubleToString( mSettings->maximumScale ) );
|
||||
QgsSymbolLayerUtils::applyScaleDependency( doc, ruleElement, scaleProps );
|
||||
}
|
||||
|
||||
// text symbolizer
|
||||
QDomElement textSymbolizerElement = doc.createElement( QStringLiteral( "se:TextSymbolizer" ) );
|
||||
ruleElement.appendChild( textSymbolizerElement );
|
||||
|
||||
// label
|
||||
QgsTextFormat format = mSettings->format();
|
||||
QFont font = format.font();
|
||||
QDomElement labelElement = doc.createElement( QStringLiteral( "se:Label" ) );
|
||||
textSymbolizerElement.appendChild( labelElement );
|
||||
if ( mSettings->isExpression )
|
||||
{
|
||||
labelElement.appendChild( doc.createComment( QStringLiteral( "SE Export for %1 not implemented yet" ).arg( mSettings->getLabelExpression()->dump() ) ) );
|
||||
labelElement.appendChild( doc.createTextNode( "Placeholder" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( font.capitalization() == QFont::AllUppercase )
|
||||
{
|
||||
appendSimpleFunction( doc, labelElement, QStringLiteral( "strToUpperCase" ), mSettings->fieldName );
|
||||
}
|
||||
else if ( font.capitalization() == QFont::AllLowercase )
|
||||
{
|
||||
appendSimpleFunction( doc, labelElement, QStringLiteral( "strToLowerCase" ), mSettings->fieldName );
|
||||
}
|
||||
else if ( font.capitalization() == QFont::Capitalize )
|
||||
{
|
||||
appendSimpleFunction( doc, labelElement, QStringLiteral( "strCapitalize" ), mSettings->fieldName );
|
||||
}
|
||||
else
|
||||
{
|
||||
QDomElement propertyNameElement = doc.createElement( QStringLiteral( "ogc:PropertyName" ) );
|
||||
propertyNameElement.appendChild( doc.createTextNode( mSettings->fieldName ) );
|
||||
labelElement.appendChild( propertyNameElement );
|
||||
}
|
||||
}
|
||||
|
||||
// font
|
||||
QDomElement fontElement = doc.createElement( QStringLiteral( "se:Font" ) );
|
||||
textSymbolizerElement.appendChild( fontElement );
|
||||
fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-family" ), font.family() ) );
|
||||
double fontSize = QgsSymbolLayerUtils::rescaleUom( format.size(), format.sizeUnit(), props );
|
||||
fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-size" ), QString::number( fontSize ) ) );
|
||||
if ( format.font().italic() )
|
||||
{
|
||||
fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-style" ), QStringLiteral( "italic" ) ) );
|
||||
}
|
||||
if ( format.font().bold() )
|
||||
{
|
||||
fontElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "font-weight" ), QStringLiteral( "bold" ) ) );
|
||||
}
|
||||
|
||||
// label placement
|
||||
QDomElement labelPlacement = doc.createElement( QStringLiteral( "se:LabelPlacement" ) );
|
||||
textSymbolizerElement.appendChild( labelPlacement );
|
||||
double maxDisplacement = 0;
|
||||
double repeatDistance = 0;
|
||||
switch ( mSettings->placement )
|
||||
{
|
||||
case QgsPalLayerSettings::OverPoint:
|
||||
{
|
||||
QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
|
||||
labelPlacement.appendChild( pointPlacement );
|
||||
// anchor point
|
||||
QPointF anchor = quadOffsetToSldAnchor( mSettings->quadOffset );
|
||||
QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, anchor );
|
||||
// displacement
|
||||
if ( mSettings->xOffset > 0 || mSettings->yOffset > 0 )
|
||||
{
|
||||
QgsUnitTypes::RenderUnit offsetUnit = mSettings->offsetUnits;
|
||||
double dx = QgsSymbolLayerUtils::rescaleUom( mSettings->xOffset, offsetUnit, props );
|
||||
double dy = QgsSymbolLayerUtils::rescaleUom( mSettings->yOffset, offsetUnit, props );
|
||||
QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( dx, dy ) );
|
||||
}
|
||||
// rotation
|
||||
if ( mSettings->angleOffset != 0 )
|
||||
{
|
||||
QDomElement rotation = doc.createElement( "se:Rotation" );
|
||||
pointPlacement.appendChild( rotation );
|
||||
rotation.appendChild( doc.createTextNode( QString::number( mSettings->angleOffset ) ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QgsPalLayerSettings::AroundPoint:
|
||||
case QgsPalLayerSettings::OrderedPositionsAroundPoint:
|
||||
{
|
||||
QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
|
||||
labelPlacement.appendChild( pointPlacement );
|
||||
|
||||
// SLD cannot do either, but let's do a best effort setting the distance using
|
||||
// anchor point and displacement
|
||||
QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, QPointF( 0, 0.5 ) );
|
||||
QgsUnitTypes::RenderUnit distUnit = mSettings->distUnits;
|
||||
double radius = QgsSymbolLayerUtils::rescaleUom( mSettings->dist, distUnit, props );
|
||||
double offset = sqrt( radius * radius / 2 ); // make it start top/right
|
||||
maxDisplacement = radius + 1; // lock the distance
|
||||
QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( offset, offset ) );
|
||||
}
|
||||
break;
|
||||
case QgsPalLayerSettings::Horizontal:
|
||||
case QgsPalLayerSettings::Free:
|
||||
{
|
||||
// still a point placement (for "free" it's a fallback, there is no SLD equivalent)
|
||||
QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
|
||||
labelPlacement.appendChild( pointPlacement );
|
||||
QgsSymbolLayerUtils::createAnchorPointElement( doc, pointPlacement, QPointF( 0.5, 0.5 ) );
|
||||
QgsUnitTypes::RenderUnit distUnit = mSettings->distUnits;
|
||||
double dist = QgsSymbolLayerUtils::rescaleUom( mSettings->dist, distUnit, props );
|
||||
QgsSymbolLayerUtils::createDisplacementElement( doc, pointPlacement, QPointF( 0, dist ) );
|
||||
break;
|
||||
}
|
||||
case QgsPalLayerSettings::Line:
|
||||
case QgsPalLayerSettings::Curved:
|
||||
case QgsPalLayerSettings::PerimeterCurved:
|
||||
{
|
||||
QDomElement linePlacement = doc.createElement( "se:LinePlacement" );
|
||||
labelPlacement.appendChild( linePlacement );
|
||||
|
||||
// perpendicular distance if required
|
||||
if ( mSettings->dist > 0 )
|
||||
{
|
||||
QgsUnitTypes::RenderUnit distUnit = mSettings->distUnits;
|
||||
double dist = QgsSymbolLayerUtils::rescaleUom( mSettings->dist, distUnit, props );
|
||||
QDomElement perpendicular = doc.createElement( "se:PerpendicularOffset" );
|
||||
linePlacement.appendChild( perpendicular );
|
||||
perpendicular.appendChild( doc.createTextNode( qgsDoubleToString( dist, 2 ) ) );
|
||||
}
|
||||
|
||||
// repeat distance if required
|
||||
if ( mSettings->repeatDistance > 0 )
|
||||
{
|
||||
QDomElement repeat = doc.createElement( "se:Repeat" );
|
||||
linePlacement.appendChild( repeat );
|
||||
repeat.appendChild( doc.createTextNode( QStringLiteral( "true" ) ) );
|
||||
QDomElement gap = doc.createElement( "se:Gap" );
|
||||
linePlacement.appendChild( gap );
|
||||
repeatDistance = QgsSymbolLayerUtils::rescaleUom( mSettings->repeatDistance, mSettings->repeatDistanceUnit, props );
|
||||
gap.appendChild( doc.createTextNode( qgsDoubleToString( repeatDistance, 2 ) ) );
|
||||
}
|
||||
|
||||
// always generalized
|
||||
QDomElement generalize = doc.createElement( "se:GeneralizeLine" );
|
||||
linePlacement.appendChild( generalize );
|
||||
generalize.appendChild( doc.createTextNode( QStringLiteral( "true" ) ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// halo
|
||||
QgsTextBufferSettings buffer = format.buffer();
|
||||
if ( buffer.enabled() )
|
||||
{
|
||||
QDomElement haloElement = doc.createElement( QStringLiteral( "se:Halo" ) );
|
||||
textSymbolizerElement.appendChild( haloElement );
|
||||
|
||||
QDomElement radiusElement = doc.createElement( QStringLiteral( "se:Radius" ) );
|
||||
haloElement.appendChild( radiusElement );
|
||||
// the SLD uses a radius, which is actually half of the link thickness the buffer size specifies
|
||||
double radius = QgsSymbolLayerUtils::rescaleUom( buffer.size(), buffer.sizeUnit(), props ) / 2;
|
||||
radiusElement.appendChild( doc.createTextNode( qgsDoubleToString( radius ) ) );
|
||||
|
||||
QDomElement fillElement = doc.createElement( QStringLiteral( "se:Fill" ) );
|
||||
haloElement.appendChild( fillElement );
|
||||
fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill" ), buffer.color().name() ) );
|
||||
if ( buffer.opacity() != 1 )
|
||||
{
|
||||
fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill-opacity" ), QString::number( buffer.opacity() ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
// fill
|
||||
QDomElement fillElement = doc.createElement( QStringLiteral( "se:Fill" ) );
|
||||
textSymbolizerElement.appendChild( fillElement );
|
||||
fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill" ), format.color().name() ) );
|
||||
if ( format.opacity() != 1 )
|
||||
{
|
||||
fillElement.appendChild( QgsSymbolLayerUtils::createSvgParameterElement( doc, QStringLiteral( "fill-opacity" ), QString::number( format.opacity() ) ) );
|
||||
}
|
||||
|
||||
// background graphic (not supported by SE 1.1, but supported by the GeoTools ecosystem as an extension)
|
||||
QgsTextBackgroundSettings background = format.background();
|
||||
if ( background.enabled() )
|
||||
{
|
||||
std::unique_ptr<QgsMarkerSymbolLayer> layer = backgroundToMarkerLayer( background );
|
||||
layer->writeSldMarker( doc, textSymbolizerElement, props );
|
||||
}
|
||||
|
||||
// priority and zIndex, the default values are 0 and 5 in qgis (and between 0 and 10),
|
||||
// in the GeoTools ecosystem there is a single priority value set at 1000 by default
|
||||
if ( mSettings->priority != 5 || mSettings->zIndex > 0 )
|
||||
{
|
||||
QDomElement priorityElement = doc.createElement( QStringLiteral( "se:Priority" ) );
|
||||
textSymbolizerElement.appendChild( priorityElement );
|
||||
int priority = 500 + 1000 * mSettings->zIndex + ( mSettings->priority - 5 ) * 100;
|
||||
if ( mSettings->priority == 0 && mSettings->zIndex > 0 )
|
||||
{
|
||||
// small adjustment to make sure labels in z index n+1 are all above level n despite the priority value
|
||||
priority += 1;
|
||||
}
|
||||
priorityElement.appendChild( doc.createTextNode( QString::number( priority ) ) );
|
||||
}
|
||||
|
||||
// vendor options for text appearance
|
||||
if ( font.underline() )
|
||||
{
|
||||
QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "underlineText" ), QStringLiteral( "true" ) );
|
||||
textSymbolizerElement.appendChild( vo );
|
||||
}
|
||||
if ( font.strikeOut() )
|
||||
{
|
||||
QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "strikethroughText" ), QStringLiteral( "true" ) );
|
||||
textSymbolizerElement.appendChild( vo );
|
||||
}
|
||||
// vendor options for text positioning
|
||||
if ( maxDisplacement > 0 )
|
||||
{
|
||||
QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "maxDisplacement" ), qgsDoubleToString( maxDisplacement, 2 ) );
|
||||
textSymbolizerElement.appendChild( vo );
|
||||
}
|
||||
if ( mSettings->placement == QgsPalLayerSettings::Curved || mSettings->placement == QgsPalLayerSettings::PerimeterCurved )
|
||||
{
|
||||
QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "followLine" ), QStringLiteral( "true" ) );
|
||||
textSymbolizerElement.appendChild( vo );
|
||||
if ( mSettings->maxCurvedCharAngleIn > 0 || mSettings->maxCurvedCharAngleOut > 0 )
|
||||
{
|
||||
// SLD has no notion for this, the GeoTools ecosystem can only do a single angle
|
||||
double angle = qMin( qAbs( mSettings->maxCurvedCharAngleIn ), qAbs( mSettings->maxCurvedCharAngleOut ) );
|
||||
QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "maxAngleDelta" ), qgsDoubleToString( angle ) );
|
||||
textSymbolizerElement.appendChild( vo );
|
||||
}
|
||||
}
|
||||
if ( repeatDistance > 0 )
|
||||
{
|
||||
QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "repeat" ), qgsDoubleToString( repeatDistance, 2 ) );
|
||||
textSymbolizerElement.appendChild( vo );
|
||||
}
|
||||
// miscellaneous options
|
||||
if ( mSettings->displayAll )
|
||||
{
|
||||
QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "conflictResolution" ), QStringLiteral( "false" ) );
|
||||
textSymbolizerElement.appendChild( vo );
|
||||
}
|
||||
if ( mSettings->upsidedownLabels == QgsPalLayerSettings::ShowAll )
|
||||
{
|
||||
QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "forceLeftToRight" ), QStringLiteral( "false" ) );
|
||||
textSymbolizerElement.appendChild( vo );
|
||||
}
|
||||
if ( mSettings->mergeLines )
|
||||
{
|
||||
QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "group" ), QStringLiteral( "yes" ) );
|
||||
textSymbolizerElement.appendChild( vo );
|
||||
if ( mSettings->labelPerPart )
|
||||
{
|
||||
QDomElement vo = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "labelAllGroup" ), QStringLiteral( "true" ) );
|
||||
textSymbolizerElement.appendChild( vo );
|
||||
}
|
||||
}
|
||||
// background symbol resize handling
|
||||
if ( background.enabled() )
|
||||
{
|
||||
// enable resizing if needed
|
||||
switch ( background.sizeType() )
|
||||
{
|
||||
case QgsTextBackgroundSettings::SizeBuffer:
|
||||
{
|
||||
QString resizeType;
|
||||
if ( background.type() == QgsTextBackgroundSettings::ShapeRectangle || background.type() == QgsTextBackgroundSettings::ShapeEllipse )
|
||||
{
|
||||
resizeType = QStringLiteral( "stretch" );
|
||||
}
|
||||
else
|
||||
{
|
||||
resizeType = QStringLiteral( "proportional" );
|
||||
}
|
||||
QDomElement voResize = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "graphic-resize" ), resizeType );
|
||||
textSymbolizerElement.appendChild( voResize );
|
||||
|
||||
// now hadle margin
|
||||
QSizeF size = background.size();
|
||||
if ( size.width() > 0 || size.height() > 0 )
|
||||
{
|
||||
double x = QgsSymbolLayerUtils::rescaleUom( size.width(), background.sizeUnit(), props );
|
||||
double y = QgsSymbolLayerUtils::rescaleUom( size.height(), background.sizeUnit(), props );
|
||||
// in case of ellipse qgis pads the size generously to make sure the text is inside the ellipse
|
||||
// the following seems to do the trick and keep visual output similar
|
||||
if ( background.type() == QgsTextBackgroundSettings::ShapeEllipse )
|
||||
{
|
||||
x += fontSize / 2;
|
||||
y += fontSize;
|
||||
}
|
||||
QString resizeSpec = QString( "%1 %2" ).arg( qgsDoubleToString( x, 2 ) ).arg( qgsDoubleToString( y, 2 ) );
|
||||
QDomElement voMargin = QgsSymbolLayerUtils::createVendorOptionElement( doc, QStringLiteral( "graphic-margin" ), resizeSpec );
|
||||
textSymbolizerElement.appendChild( voMargin );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QgsTextBackgroundSettings::SizeFixed:
|
||||
case QgsTextBackgroundSettings::SizePercent:
|
||||
// nothing to do here
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -19,9 +19,9 @@
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QDomNode>
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgis_sip.h"
|
||||
#include "qgis.h"
|
||||
|
||||
class QDomDocument;
|
||||
class QDomElement;
|
||||
@ -76,6 +76,17 @@ class CORE_EXPORT QgsAbstractVectorLayerLabeling
|
||||
//! Try to create instance of an implementation based on the XML data
|
||||
static QgsAbstractVectorLayerLabeling *create( const QDomElement &element, const QgsReadWriteContext &context ) SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Writes the SE 1.1 TextSymbolizer element based on the current layer labeling settings
|
||||
*/
|
||||
virtual void toSld( QDomNode &parent, const QgsStringMap &props ) const
|
||||
{
|
||||
Q_UNUSED( parent )
|
||||
Q_UNUSED( props )
|
||||
QDomDocument doc = parent.ownerDocument();
|
||||
parent.appendChild( doc.createComment( QStringLiteral( "SE Export for %1 not implemented yet" ).arg( type() ) ) );
|
||||
}
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY( QgsAbstractVectorLayerLabeling )
|
||||
|
||||
@ -105,6 +116,7 @@ class CORE_EXPORT QgsVectorLayerSimpleLabeling : public QgsAbstractVectorLayerLa
|
||||
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const override;
|
||||
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const override;
|
||||
bool requiresAdvancedEffects() const override;
|
||||
virtual void toSld( QDomNode &parent, const QgsStringMap &props ) const override;
|
||||
|
||||
//! Create the instance from a DOM element with saved configuration
|
||||
static QgsVectorLayerSimpleLabeling *create( const QDomElement &element, const QgsReadWriteContext &context );
|
||||
|
@ -2313,15 +2313,32 @@ void QgsSymbolLayerUtils::createDisplacementElement( QDomDocument &doc, QDomElem
|
||||
element.appendChild( displacementElem );
|
||||
|
||||
QDomElement dispXElem = doc.createElement( QStringLiteral( "se:DisplacementX" ) );
|
||||
dispXElem.appendChild( doc.createTextNode( qgsDoubleToString( offset.x() ) ) );
|
||||
dispXElem.appendChild( doc.createTextNode( qgsDoubleToString( offset.x(), 2 ) ) );
|
||||
|
||||
QDomElement dispYElem = doc.createElement( QStringLiteral( "se:DisplacementY" ) );
|
||||
dispYElem.appendChild( doc.createTextNode( qgsDoubleToString( offset.y() ) ) );
|
||||
dispYElem.appendChild( doc.createTextNode( qgsDoubleToString( offset.y(), 2 ) ) );
|
||||
|
||||
displacementElem.appendChild( dispXElem );
|
||||
displacementElem.appendChild( dispYElem );
|
||||
}
|
||||
|
||||
void QgsSymbolLayerUtils::createAnchorPointElement( QDomDocument &doc, QDomElement &element, QPointF anchor )
|
||||
{
|
||||
// anchor is not tested for null, (0,0) is _not_ the default value (0.5, 0) is.
|
||||
|
||||
QDomElement anchorElem = doc.createElement( QStringLiteral( "se:AnchorPoint" ) );
|
||||
element.appendChild( anchorElem );
|
||||
|
||||
QDomElement anchorXElem = doc.createElement( QStringLiteral( "se:AnchorPointX" ) );
|
||||
anchorXElem.appendChild( doc.createTextNode( qgsDoubleToString( anchor.x() ) ) );
|
||||
|
||||
QDomElement anchorYElem = doc.createElement( QStringLiteral( "se:AnchorPointY" ) );
|
||||
anchorYElem.appendChild( doc.createTextNode( qgsDoubleToString( anchor.y() ) ) );
|
||||
|
||||
anchorElem.appendChild( anchorXElem );
|
||||
anchorElem.appendChild( anchorYElem );
|
||||
}
|
||||
|
||||
bool QgsSymbolLayerUtils::displacementFromSldElement( QDomElement &element, QPointF &offset )
|
||||
{
|
||||
offset = QPointF( 0, 0 );
|
||||
@ -2656,7 +2673,7 @@ QgsStringMap QgsSymbolLayerUtils::getSvgParameterList( QDomElement &element )
|
||||
|
||||
QDomElement QgsSymbolLayerUtils::createVendorOptionElement( QDomDocument &doc, const QString &name, const QString &value )
|
||||
{
|
||||
QDomElement nodeElem = doc.createElement( QStringLiteral( "VendorOption" ) );
|
||||
QDomElement nodeElem = doc.createElement( QStringLiteral( "se:VendorOption" ) );
|
||||
nodeElem.setAttribute( QStringLiteral( "name" ), name );
|
||||
nodeElem.appendChild( doc.createTextNode( value ) );
|
||||
return nodeElem;
|
||||
@ -4028,8 +4045,26 @@ double QgsSymbolLayerUtils::rescaleUom( double size, QgsUnitTypes::RenderUnit un
|
||||
scale = 1 / 0.28;
|
||||
roundToUnit = true;
|
||||
break;
|
||||
// we don't have a good case for map units, as pixel values won't change based on zoom
|
||||
default:
|
||||
case QgsUnitTypes::RenderInches:
|
||||
scale = 1 / 0.28 * 25.4;
|
||||
roundToUnit = true;
|
||||
break;
|
||||
case QgsUnitTypes::RenderPoints:
|
||||
scale = 90. /* dots per inch according to OGC SLD */ / 72. /* points per inch */;
|
||||
roundToUnit = true;
|
||||
break;
|
||||
case QgsUnitTypes::RenderPixels:
|
||||
// pixel is pixel
|
||||
scale = 1;
|
||||
break;
|
||||
case QgsUnitTypes::RenderMapUnits:
|
||||
case QgsUnitTypes::RenderMetersInMapUnits:
|
||||
// already handed via uom
|
||||
scale = 1;
|
||||
break;
|
||||
case QgsUnitTypes::RenderPercentage:
|
||||
case QgsUnitTypes::RenderUnknownUnit:
|
||||
// these do not make sense and should not really reach here
|
||||
scale = 1;
|
||||
}
|
||||
}
|
||||
|
@ -332,6 +332,14 @@ class CORE_EXPORT QgsSymbolLayerUtils
|
||||
static void createDisplacementElement( QDomDocument &doc, QDomElement &element, QPointF offset );
|
||||
static bool displacementFromSldElement( QDomElement &element, QPointF &offset );
|
||||
|
||||
/**
|
||||
* \brief Creates a SE 1.1 anchor point element as a child of the specified element
|
||||
* \param doc The document
|
||||
* \param element The parent element
|
||||
* \param anchor An anchor specification, with values between 0 and 1
|
||||
*/
|
||||
static void createAnchorPointElement( QDomDocument &doc, QDomElement &element, QPointF anchor );
|
||||
|
||||
static void createOnlineResourceElement( QDomDocument &doc, QDomElement &element, const QString &path, const QString &format );
|
||||
static bool onlineResourceFromSldElement( QDomElement &element, QString &path, QString &format );
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
test_qgssymbollayer_createsld.py
|
||||
@ -25,15 +23,16 @@ __revision__ = '$Format:%H$'
|
||||
|
||||
import qgis # NOQA
|
||||
|
||||
from qgis.PyQt.QtCore import Qt, QDir, QFile, QIODevice, QPointF
|
||||
from qgis.PyQt.QtCore import Qt, QDir, QFile, QIODevice, QPointF, QSizeF
|
||||
from qgis.PyQt.QtXml import QDomDocument
|
||||
from qgis.PyQt.QtGui import QColor
|
||||
from qgis.PyQt.QtGui import QColor, QFont
|
||||
|
||||
from qgis.core import (
|
||||
QgsSimpleMarkerSymbolLayer, QgsSimpleMarkerSymbolLayerBase, QgsUnitTypes, QgsSvgMarkerSymbolLayer,
|
||||
QgsFontMarkerSymbolLayer, QgsEllipseSymbolLayer, QgsSimpleLineSymbolLayer,
|
||||
QgsMarkerLineSymbolLayer, QgsMarkerSymbol, QgsSimpleFillSymbolLayer, QgsSVGFillSymbolLayer,
|
||||
QgsLinePatternFillSymbolLayer, QgsPointPatternFillSymbolLayer, QgsVectorLayer)
|
||||
QgsLinePatternFillSymbolLayer, QgsPointPatternFillSymbolLayer, QgsVectorLayer, QgsVectorLayerSimpleLabeling,
|
||||
QgsTextBufferSettings, QgsPalLayerSettings, QgsTextBackgroundSettings)
|
||||
from qgis.testing import start_app, unittest
|
||||
from utilities import unitTestDataPath
|
||||
|
||||
@ -57,32 +56,6 @@ class TestQgsSymbolLayerCreateSld(unittest.TestCase):
|
||||
|
||||
self.assertStaticRotation(root, '50')
|
||||
|
||||
def assertStaticRotation(self, root, expectedValue, index=0):
|
||||
# Check the rotation element is a literal, not a
|
||||
rotation = root.elementsByTagName('se:Rotation').item(index)
|
||||
literal = rotation.firstChild()
|
||||
self.assertEqual("ogc:Literal", literal.nodeName())
|
||||
self.assertEqual(expectedValue, literal.firstChild().nodeValue())
|
||||
|
||||
def assertStaticDisplacement(self, root, expectedDispX, expectedDispY):
|
||||
displacement = root.elementsByTagName('se:Displacement').item(0)
|
||||
self.assertIsNotNone(displacement)
|
||||
dx = displacement.firstChild()
|
||||
self.assertIsNotNone(dx)
|
||||
self.assertEqual("se:DisplacementX", dx.nodeName())
|
||||
self.assertSldNumber(expectedDispX, dx.firstChild().nodeValue())
|
||||
dy = displacement.lastChild()
|
||||
self.assertIsNotNone(dy)
|
||||
self.assertEqual("se:DisplacementY", dy.nodeName())
|
||||
self.assertSldNumber(expectedDispY, dy.firstChild().nodeValue())
|
||||
|
||||
def assertSldNumber(self, expected, stringValue):
|
||||
value = float(stringValue)
|
||||
self.assertFloatEquals(expected, value, 0.01)
|
||||
|
||||
def assertFloatEquals(self, expected, actual, tol):
|
||||
self.assertLess(abs(expected - actual), tol)
|
||||
|
||||
def testSimpleMarkerUnitDefault(self):
|
||||
symbol = QgsSimpleMarkerSymbolLayer(
|
||||
QgsSimpleMarkerSymbolLayerBase.Star, color=QColor(255, 0, 0), strokeColor=QColor(0, 255, 0), size=10)
|
||||
@ -98,14 +71,6 @@ class TestQgsSymbolLayerCreateSld(unittest.TestCase):
|
||||
self.assertStrokeWidth(root, 2, 11)
|
||||
self.assertStaticDisplacement(root, 18, 36)
|
||||
|
||||
def assertStrokeWidth(self, root, svgParameterIdx, expectedWidth):
|
||||
strokeWidth = root.elementsByTagName(
|
||||
'se:SvgParameter').item(svgParameterIdx)
|
||||
svgParameterName = strokeWidth.attributes().namedItem('name')
|
||||
self.assertEqual("stroke-width", svgParameterName.nodeValue())
|
||||
self.assertSldNumber(
|
||||
expectedWidth, strokeWidth.firstChild().nodeValue())
|
||||
|
||||
def testSimpleMarkerUnitPixels(self):
|
||||
symbol = QgsSimpleMarkerSymbolLayer(
|
||||
QgsSimpleMarkerSymbolLayerBase.Star, color=QColor(255, 0, 0), strokeColor=QColor(0, 255, 0), size=10)
|
||||
@ -530,21 +495,666 @@ class TestQgsSymbolLayerCreateSld(unittest.TestCase):
|
||||
|
||||
gt = filter.firstChild()
|
||||
expectedGtName = "ogc:PropertyIsGreaterThanOrEqualTo" if includeMin else "ogc:PropertyIsGreaterThan"
|
||||
self.assertEquals(expectedGtName, gt.nodeName())
|
||||
self.assertEqual(expectedGtName, gt.nodeName())
|
||||
gtProperty = gt.firstChild()
|
||||
self.assertEquals("ogc:PropertyName", gtProperty.nodeName())
|
||||
self.assertEquals(attributeName, gtProperty.toElement().text())
|
||||
self.assertEqual("ogc:PropertyName", gtProperty.nodeName())
|
||||
self.assertEqual(attributeName, gtProperty.toElement().text())
|
||||
gtValue = gt.childNodes().item(1)
|
||||
self.assertEquals(min, gtValue.toElement().text())
|
||||
self.assertEqual(min, gtValue.toElement().text())
|
||||
|
||||
lt = filter.childNodes().item(1)
|
||||
expectedLtName = "ogc:PropertyIsLessThanOrEqualTo" if includeMax else "ogc:PropertyIsLessThan"
|
||||
self.assertEquals(expectedLtName, lt.nodeName())
|
||||
self.assertEqual(expectedLtName, lt.nodeName())
|
||||
ltProperty = lt.firstChild()
|
||||
self.assertEquals("ogc:PropertyName", ltProperty.nodeName())
|
||||
self.assertEquals(attributeName, ltProperty.toElement().text())
|
||||
self.assertEqual("ogc:PropertyName", ltProperty.nodeName())
|
||||
self.assertEqual(attributeName, ltProperty.toElement().text())
|
||||
ltValue = lt.childNodes().item(1)
|
||||
self.assertEquals(max, ltValue.toElement().text())
|
||||
self.assertEqual(max, ltValue.toElement().text())
|
||||
|
||||
def testSimpleLabeling(self):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
# Pick a local default font
|
||||
fontFamily = QFont().family()
|
||||
settings = layer.labeling().settings()
|
||||
format = settings.format()
|
||||
font = format.font()
|
||||
font.setFamily(fontFamily)
|
||||
font.setBold(False)
|
||||
font.setItalic(False)
|
||||
format.setFont(font)
|
||||
settings.setFormat(format)
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Simple label text symbolizer" + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
self.assertPropertyName(ts, 'se:Label', 'NAME')
|
||||
font = self.assertElement(ts, 'se:Font', 0)
|
||||
self.assertEqual(fontFamily, self.assertSvgParameter(font, 'font-family').text())
|
||||
self.assertEqual('11', self.assertSvgParameter(font, 'font-size').text())
|
||||
|
||||
fill = self.assertElement(ts, 'se:Fill', 0)
|
||||
self.assertEqual('#000000', self.assertSvgParameter(fill, "fill").text())
|
||||
self.assertIsNone(self.assertSvgParameter(fill, "fill-opacity", True))
|
||||
|
||||
def testLabelingUomMillimeter(self):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
self.updateLayerLabelingUnit(layer, QgsUnitTypes.RenderMillimeters)
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
#print("Label sized in mm " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
font = self.assertElement(ts, 'se:Font', 0)
|
||||
self.assertEqual('32', self.assertSvgParameter(font, 'font-size').text())
|
||||
|
||||
def testLabelingUomPixels(self):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
self.updateLayerLabelingUnit(layer, QgsUnitTypes.RenderPixels)
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label sized in pixels " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
font = self.assertElement(ts, 'se:Font', 0)
|
||||
self.assertEqual('9', self.assertSvgParameter(font, 'font-size').text())
|
||||
|
||||
def testLabelingUomInches(self):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
self.updateLayerLabelingUnit(layer, QgsUnitTypes.RenderInches)
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label sized in inches " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
font = self.assertElement(ts, 'se:Font', 0)
|
||||
self.assertEqual('816', self.assertSvgParameter(font, 'font-size').text())
|
||||
|
||||
def testTextStyle(self):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
|
||||
# testing regular
|
||||
self.updateLayerLabelingFontStyle(layer, False, False)
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Simple label italic text" + dom.toString())
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
font = self.assertElement(ts, 'se:Font', 0)
|
||||
self.assertIsNone(self.assertSvgParameter(font, 'font-weight', True))
|
||||
self.assertIsNone(self.assertSvgParameter(font, 'font-style', True))
|
||||
|
||||
# testing bold
|
||||
self.updateLayerLabelingFontStyle(layer, True, False)
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Simple label bold text" + dom.toString())
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
font = self.assertElement(ts, 'se:Font', 0)
|
||||
self.assertEqual('bold', self.assertSvgParameter(font, 'font-weight').text())
|
||||
self.assertIsNone(self.assertSvgParameter(font, 'font-style', True))
|
||||
|
||||
# testing italic
|
||||
self.updateLayerLabelingFontStyle(layer, False, True)
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Simple label italic text" + dom.toString())
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
font = self.assertElement(ts, 'se:Font', 0)
|
||||
self.assertEqual('italic', self.assertSvgParameter(font, 'font-style').text())
|
||||
self.assertIsNone(self.assertSvgParameter(font, 'font-weight', True))
|
||||
|
||||
# testing bold italic
|
||||
self.updateLayerLabelingFontStyle(layer, True, True)
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Simple label bold and italic text" + dom.toString())
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
font = self.assertElement(ts, 'se:Font', 0)
|
||||
self.assertEqual('italic', self.assertSvgParameter(font, 'font-style').text())
|
||||
self.assertEqual('bold', self.assertSvgParameter(font, 'font-weight').text())
|
||||
|
||||
# testing underline and strikethrough vendor options
|
||||
self.updateLayerLabelingFontStyle(layer, False, False, True, True)
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Simple label underline and strikethrough text" + dom.toString())
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
font = self.assertElement(ts, 'se:Font', 0)
|
||||
self.assertEqual('true', self.assertVendorOption(ts, 'underlineText').text())
|
||||
self.assertEqual('true', self.assertVendorOption(ts, 'strikethroughText').text())
|
||||
|
||||
def testTextMixedCase(self):
|
||||
self.assertCapitalizationFunction(QFont.MixedCase, None)
|
||||
|
||||
def testTextUppercase(self):
|
||||
self.assertCapitalizationFunction(QFont.AllUppercase, "strToUpperCase")
|
||||
|
||||
def testTextLowercase(self):
|
||||
self.assertCapitalizationFunction(QFont.AllLowercase, "strToLowerCase")
|
||||
|
||||
def testTextCapitalcase(self):
|
||||
self.assertCapitalizationFunction(QFont.Capitalize, "strCapitalize")
|
||||
|
||||
def assertCapitalizationFunction(self, capitalization, expectedFunction):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
|
||||
settings = layer.labeling().settings()
|
||||
format = settings.format()
|
||||
font = format.font()
|
||||
font.setCapitalization(capitalization)
|
||||
format.setFont(font)
|
||||
settings.setFormat(format)
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Simple text with capitalization " + str(QFont.AllUppercase) + ": " + dom.toString())
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
label = self.assertElement(ts, "se:Label", 0)
|
||||
if expectedFunction is None:
|
||||
property = self.assertElement(label, "ogc:PropertyName", 0)
|
||||
self.assertEqual("NAME", property.text())
|
||||
else:
|
||||
function = self.assertElement(label, "ogc:Function", 0)
|
||||
self.assertEqual(expectedFunction, function.attribute("name"))
|
||||
property = self.assertElement(function, "ogc:PropertyName", 0)
|
||||
self.assertEqual("NAME", property.text())
|
||||
|
||||
def testLabelingTransparency(self):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
settings = layer.labeling().settings()
|
||||
format = settings.format()
|
||||
format.setOpacity(0.5)
|
||||
settings.setFormat(format)
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label with transparency " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
fill = self.assertElement(ts, 'se:Fill', 0)
|
||||
self.assertEqual('#000000', self.assertSvgParameter(fill, "fill").text())
|
||||
self.assertEqual('0.5', self.assertSvgParameter(fill, "fill-opacity").text())
|
||||
|
||||
def testLabelingBuffer(self):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
buffer = QgsTextBufferSettings()
|
||||
buffer.setEnabled(True)
|
||||
buffer.setSize(10)
|
||||
buffer.setSizeUnit(QgsUnitTypes.RenderPixels)
|
||||
buffer.setColor(QColor("Black"))
|
||||
self.setLabelBufferSettings(layer, buffer)
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label with buffer 10 px " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
halo = self.assertElement(ts, 'se:Halo', 0)
|
||||
# not full width, just radius here
|
||||
self.assertEqual('5', self.assertElement(ts, 'se:Radius', 0).text())
|
||||
haloFill = self.assertElement(halo, 'se:Fill', 0)
|
||||
self.assertEqual('#000000', self.assertSvgParameter(haloFill, "fill").text())
|
||||
|
||||
def testLabelingBufferPointTranslucent(self):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
buffer = QgsTextBufferSettings()
|
||||
buffer.setEnabled(True)
|
||||
buffer.setSize(10)
|
||||
buffer.setSizeUnit(QgsUnitTypes.RenderPoints)
|
||||
buffer.setColor(QColor("Red"))
|
||||
buffer.setOpacity(0.5)
|
||||
self.setLabelBufferSettings(layer, buffer)
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label with buffer 10 points, red 50% transparent " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
halo = self.assertElement(ts, 'se:Halo', 0)
|
||||
# not full width, just radius here
|
||||
self.assertEqual('6.5', self.assertElement(ts, 'se:Radius', 0).text())
|
||||
haloFill = self.assertElement(halo, 'se:Fill', 0)
|
||||
self.assertEqual('#ff0000', self.assertSvgParameter(haloFill, "fill").text())
|
||||
self.assertEqual('0.5', self.assertSvgParameter(haloFill, "fill-opacity").text())
|
||||
|
||||
def testLabelingLowPriority(self):
|
||||
self.assertLabelingPriority(0, 0, '0')
|
||||
|
||||
def testLabelingDefaultPriority(self):
|
||||
self.assertLabelingPriority(0, 5, None)
|
||||
|
||||
def testLabelingHighPriority(self):
|
||||
self.assertLabelingPriority(0, 10, '1000')
|
||||
|
||||
def testLabelingZIndexLowPriority(self):
|
||||
self.assertLabelingPriority(1, 0, '1001')
|
||||
|
||||
def testLabelingZIndexDefaultPriority(self):
|
||||
self.assertLabelingPriority(1, 5, "1500")
|
||||
|
||||
def testLabelingZIndexHighPriority(self):
|
||||
self.assertLabelingPriority(1, 10, '2000')
|
||||
|
||||
def assertLabelingPriority(self, zIndex, priority, expectedSldPriority):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
settings = layer.labeling().settings()
|
||||
settings.zIndex = zIndex
|
||||
settings.priority = priority
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label with zIndex at " + str(zIndex) + " and priority at " + str(priority) + ": " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
priorityElement = self.assertElement(ts, "se:Priority", 0, True)
|
||||
if expectedSldPriority is None:
|
||||
self.assertIsNone(priorityElement)
|
||||
else:
|
||||
self.assertEqual(expectedSldPriority, priorityElement.text())
|
||||
|
||||
def testLabelingPlacementOverPointOffsetRotation(self):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
settings = layer.labeling().settings()
|
||||
settings.placement = QgsPalLayerSettings.OverPoint
|
||||
settings.xOffset = 5
|
||||
settings.yOffset = 10
|
||||
settings.offsetUnits = QgsUnitTypes.RenderMillimeters
|
||||
settings.quadOffset = QgsPalLayerSettings.QuadrantOver
|
||||
settings.angleOffset = 30
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label with 'over point' placement " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
pointPlacement = self.assertPointPlacement(ts)
|
||||
self.assertStaticDisplacement(pointPlacement, 18, 36)
|
||||
self.assertStaticAnchorPoint(pointPlacement, 0.5, 0.5)
|
||||
|
||||
def testPointPlacementAboveLeft(self):
|
||||
self.assertLabelQuadrant(QgsPalLayerSettings.QuadrantAboveLeft, "AboveLeft", 1, 0)
|
||||
|
||||
def testPointPlacementAbove(self):
|
||||
self.assertLabelQuadrant(QgsPalLayerSettings.QuadrantAbove, "Above", 0.5, 0)
|
||||
|
||||
def testPointPlacementAboveRight(self):
|
||||
self.assertLabelQuadrant(QgsPalLayerSettings.QuadrantAboveRight, "AboveRight", 0, 0)
|
||||
|
||||
def testPointPlacementLeft(self):
|
||||
self.assertLabelQuadrant(QgsPalLayerSettings.QuadrantLeft, "Left", 1, 0.5)
|
||||
|
||||
def testPointPlacementRight(self):
|
||||
self.assertLabelQuadrant(QgsPalLayerSettings.QuadrantRight, "Right", 0, 0.5)
|
||||
|
||||
def testPointPlacementBelowLeft(self):
|
||||
self.assertLabelQuadrant(QgsPalLayerSettings.QuadrantBelowLeft, "BelowLeft", 1, 1)
|
||||
|
||||
def testPointPlacementBelow(self):
|
||||
self.assertLabelQuadrant(QgsPalLayerSettings.QuadrantBelow, "Below", 0.5, 1)
|
||||
|
||||
def testPointPlacementAboveRight(self):
|
||||
self.assertLabelQuadrant(QgsPalLayerSettings.QuadrantBelowRight, "BelowRight", 0, 1)
|
||||
|
||||
def testPointPlacementCartoraphic(self):
|
||||
self.assertPointPlacementDistance(QgsPalLayerSettings.OrderedPositionsAroundPoint)
|
||||
|
||||
def testPointPlacementCartoraphic(self):
|
||||
self.assertPointPlacementDistance(QgsPalLayerSettings.AroundPoint)
|
||||
|
||||
def testLineParallelPlacement(self):
|
||||
layer = QgsVectorLayer("LineString", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "lineLabel")
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label with parallel line placement " + dom.toString())
|
||||
linePlacement = self.assertLinePlacement(root)
|
||||
generalize = self.assertElement(linePlacement, 'se:GeneralizeLine', 0)
|
||||
self.assertEqual("true", generalize.text())
|
||||
|
||||
def testLineParallelPlacementOffsetRepeat(self):
|
||||
layer = QgsVectorLayer("LineString", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "lineLabel")
|
||||
self.updateLinePlacementProperties(layer, QgsPalLayerSettings.Line, 2, 50)
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label with parallel line placement, perp. offset and repeat " + dom.toString())
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
linePlacement = self.assertLinePlacement(ts)
|
||||
generalize = self.assertElement(linePlacement, 'se:GeneralizeLine', 0)
|
||||
self.assertEqual("true", generalize.text())
|
||||
offset = self.assertElement(linePlacement, 'se:PerpendicularOffset', 0)
|
||||
self.assertEqual("7", offset.text())
|
||||
repeat = self.assertElement(linePlacement, 'se:Repeat', 0)
|
||||
self.assertEqual("true", repeat.text())
|
||||
gap = self.assertElement(linePlacement, 'se:Gap', 0)
|
||||
self.assertEqual("179", gap.text())
|
||||
self.assertEqual("179", self.assertVendorOption(ts, "repeat").text())
|
||||
|
||||
def testLineCurvePlacementOffsetRepeat(self):
|
||||
layer = QgsVectorLayer("LineString", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "lineLabel")
|
||||
self.updateLinePlacementProperties(layer, QgsPalLayerSettings.Curved, 2, 50, 30, 40)
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label with curved line placement " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
linePlacement = self.assertLinePlacement(ts)
|
||||
generalize = self.assertElement(linePlacement, 'se:GeneralizeLine', 0)
|
||||
self.assertEqual("true", generalize.text())
|
||||
offset = self.assertElement(linePlacement, 'se:PerpendicularOffset', 0)
|
||||
self.assertEqual("7", offset.text())
|
||||
repeat = self.assertElement(linePlacement, 'se:Repeat', 0)
|
||||
self.assertEqual("true", repeat.text())
|
||||
gap = self.assertElement(linePlacement, 'se:Gap', 0)
|
||||
self.assertEqual("179", gap.text())
|
||||
self.assertEqual("179", self.assertVendorOption(ts, "repeat").text())
|
||||
self.assertEqual("true", self.assertVendorOption(ts, "followLine").text())
|
||||
self.assertEqual("30", self.assertVendorOption(ts, "maxAngleDelta").text())
|
||||
|
||||
def testLineCurveMergeLines(self):
|
||||
layer = QgsVectorLayer("LineString", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "lineLabel")
|
||||
settings = layer.labeling().settings()
|
||||
settings.placement = QgsPalLayerSettings.Curved
|
||||
settings.mergeLines = True
|
||||
settings.labelPerPart = True
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label with curved line and line grouping " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
self.assertEqual("yes", self.assertVendorOption(ts, "group").text())
|
||||
self.assertEqual("true", self.assertVendorOption(ts, "labelAllGroup").text())
|
||||
|
||||
def testLabelingPolygonFree(self):
|
||||
layer = QgsVectorLayer("Polygon", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "polygonLabel")
|
||||
settings = layer.labeling().settings()
|
||||
settings.placement = QgsPalLayerSettings.Free
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Polygon label with 'Free' placement " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
pointPlacement = self.assertPointPlacement(ts)
|
||||
self.assertIsNone(self.assertElement(ts, "se:Displacement", 0, True))
|
||||
self.assertStaticAnchorPoint(pointPlacement, 0.5, 0.5)
|
||||
|
||||
def testLabelingPolygonPerimeterCurved(self):
|
||||
layer = QgsVectorLayer("Polygon", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "polygonLabel")
|
||||
self.updateLinePlacementProperties(layer, QgsPalLayerSettings.PerimeterCurved, 2, 50, 30, -40)
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Polygon Label with curved perimeter line placement " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
linePlacement = self.assertLinePlacement(ts)
|
||||
generalize = self.assertElement(linePlacement, 'se:GeneralizeLine', 0)
|
||||
self.assertEqual("true", generalize.text())
|
||||
offset = self.assertElement(linePlacement, 'se:PerpendicularOffset', 0)
|
||||
self.assertEqual("7", offset.text())
|
||||
repeat = self.assertElement(linePlacement, 'se:Repeat', 0)
|
||||
self.assertEqual("true", repeat.text())
|
||||
gap = self.assertElement(linePlacement, 'se:Gap', 0)
|
||||
self.assertEqual("179", gap.text())
|
||||
self.assertEqual("179", self.assertVendorOption(ts, "repeat").text())
|
||||
self.assertEqual("true", self.assertVendorOption(ts, "followLine").text())
|
||||
self.assertEqual("30", self.assertVendorOption(ts, "maxAngleDelta").text())
|
||||
|
||||
def testLabelScaleDependencies(self):
|
||||
layer = QgsVectorLayer("Polygon", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "polygonLabel")
|
||||
settings = layer.labeling().settings()
|
||||
settings.scaleVisibility = True
|
||||
settings.minimumScale = 1000000
|
||||
settings.maximumScale = 10000000
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Labeling with scale dependencies " + dom.toString())
|
||||
self.assertScaleDenominator(root, "1000000", "10000000", 1)
|
||||
|
||||
def testLabelShowAll(self):
|
||||
layer = QgsVectorLayer("Polygon", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "polygonLabel")
|
||||
settings = layer.labeling().settings()
|
||||
settings.displayAll = True
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Labeling, showing all labels " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
self.assertVendorOption(ts, "conflictResolution", "false")
|
||||
|
||||
def testLabelUpsideDown(self):
|
||||
layer = QgsVectorLayer("Polygon", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "polygonLabel")
|
||||
settings = layer.labeling().settings()
|
||||
settings.upsidedownLabels = QgsPalLayerSettings.ShowAll
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Labeling, showing upside down labels on lines " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
self.assertVendorOption(ts, "forceLeftToRight", "false")
|
||||
|
||||
def testLabelBackgroundSquareResize(self):
|
||||
self.assertLabelBackground(QgsTextBackgroundSettings.ShapeSquare, 'square',
|
||||
QgsTextBackgroundSettings.SizeBuffer, 'proportional')
|
||||
|
||||
def testLabelBackgroundRectangleResize(self):
|
||||
self.assertLabelBackground(QgsTextBackgroundSettings.ShapeRectangle, 'square',
|
||||
QgsTextBackgroundSettings.SizeBuffer, 'stretch')
|
||||
|
||||
def testLabelBackgroundCircleResize(self):
|
||||
self.assertLabelBackground(QgsTextBackgroundSettings.ShapeCircle, 'circle',
|
||||
QgsTextBackgroundSettings.SizeBuffer, 'proportional')
|
||||
|
||||
def testLabelBackgroundEllipseResize(self):
|
||||
self.assertLabelBackground(QgsTextBackgroundSettings.ShapeEllipse, 'circle',
|
||||
QgsTextBackgroundSettings.SizeBuffer, 'stretch')
|
||||
|
||||
def testLabelBackgroundSquareAbsolute(self):
|
||||
self.assertLabelBackground(QgsTextBackgroundSettings.ShapeSquare, 'square',
|
||||
QgsTextBackgroundSettings.SizeFixed, None)
|
||||
|
||||
def testLabelBackgroundRectangleAbsolute(self):
|
||||
self.assertLabelBackground(QgsTextBackgroundSettings.ShapeRectangle, 'square',
|
||||
QgsTextBackgroundSettings.SizeFixed, None)
|
||||
|
||||
def testLabelBackgroundCircleAbsolute(self):
|
||||
self.assertLabelBackground(QgsTextBackgroundSettings.ShapeCircle, 'circle',
|
||||
QgsTextBackgroundSettings.SizeFixed, None)
|
||||
|
||||
def testLabelBackgroundEllipseAbsolute(self):
|
||||
self.assertLabelBackground(QgsTextBackgroundSettings.ShapeEllipse, 'circle',
|
||||
QgsTextBackgroundSettings.SizeFixed, None)
|
||||
|
||||
def assertLabelBackground(self, backgroundType, expectedMarkName, sizeType, expectedResize):
|
||||
layer = QgsVectorLayer("Polygon", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "polygonLabel")
|
||||
settings = layer.labeling().settings()
|
||||
background = QgsTextBackgroundSettings()
|
||||
background.setEnabled(True)
|
||||
background.setType(backgroundType)
|
||||
background.setFillColor(QColor('yellow'))
|
||||
background.setStrokeColor(QColor('black'))
|
||||
background.setStrokeWidth(2)
|
||||
background.setSize(QSizeF(10, 10))
|
||||
background.setSizeType(sizeType)
|
||||
format = settings.format()
|
||||
format.setBackground(background)
|
||||
settings.setFormat(format)
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Labeling, with background type " + str(backgroundType) + " and size type " + str(sizeType) + ": " + dom.toString())
|
||||
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
graphic = self.assertElement(ts, "se:Graphic", 0)
|
||||
self.assertEqual("36", self.assertElement(graphic, 'se:Size', 0).text())
|
||||
self.assertWellKnownMark(graphic, 0, expectedMarkName, '#ffff00', '#000000', 7)
|
||||
if expectedResize is None:
|
||||
self.assertIsNone(expectedResize, self.assertVendorOption(ts, 'graphic-resize', True))
|
||||
else:
|
||||
self.assertEqual(expectedResize, self.assertVendorOption(ts, 'graphic-resize').text())
|
||||
if sizeType == 0:
|
||||
# check extra padding for proportional ellipse
|
||||
if backgroundType == QgsTextBackgroundSettings.ShapeEllipse:
|
||||
self.assertEqual("42.5 49", self.assertVendorOption(ts, 'graphic-margin').text())
|
||||
else:
|
||||
self.assertEqual("36 36", self.assertVendorOption(ts, 'graphic-margin').text())
|
||||
else:
|
||||
self.assertIsNone(self.assertVendorOption(ts, 'graphic-margin', True))
|
||||
|
||||
def updateLinePlacementProperties(self, layer, linePlacement, distance, repeat, maxAngleInternal=25, maxAngleExternal=-25):
|
||||
settings = layer.labeling().settings()
|
||||
settings.placement = linePlacement
|
||||
settings.dist = distance
|
||||
settings.repeatDistance = repeat
|
||||
settings.maxCurvedCharAngleIn = maxAngleInternal
|
||||
settings.maxCurvedCharAngleOut = maxAngleExternal
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
def assertPointPlacementDistance(self, placement):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
|
||||
settings = layer.labeling().settings()
|
||||
settings.placement = placement
|
||||
settings.xOffset = 0
|
||||
settings.yOffset = 0
|
||||
settings.dist = 2
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label with around point placement " + dom.toString())
|
||||
ts = self.getTextSymbolizer(root, 1, 0)
|
||||
pointPlacement = self.assertPointPlacement(ts)
|
||||
self.assertStaticAnchorPoint(pointPlacement, 0, 0.5)
|
||||
self.assertStaticDisplacement(pointPlacement, 4.95, 4.95)
|
||||
|
||||
def assertLabelQuadrant(self, quadrant, label, ax, ay):
|
||||
layer = QgsVectorLayer("Point", "addfeat", "memory")
|
||||
self.loadStyleWithCustomProperties(layer, "simpleLabel")
|
||||
|
||||
settings = layer.labeling().settings()
|
||||
settings.placement = QgsPalLayerSettings.OverPoint
|
||||
settings.xOffset = 0
|
||||
settings.yOffset = 0
|
||||
settings.quadOffset = quadrant
|
||||
settings.angleOffset = 0
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
dom, root = self.layerToSld(layer)
|
||||
# print("Label with " + label + " placement " + dom.toString())
|
||||
self.assertStaticAnchorPoint(root, ax, ay)
|
||||
|
||||
def setLabelBufferSettings(self, layer, buffer):
|
||||
settings = layer.labeling().settings()
|
||||
format = settings.format()
|
||||
format.setBuffer(buffer)
|
||||
settings.setFormat(format)
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
def updateLayerLabelingFontStyle(self, layer, bold, italic, underline=False, strikeout=False):
|
||||
settings = layer.labeling().settings()
|
||||
format = settings.format()
|
||||
font = format.font()
|
||||
font.setBold(bold)
|
||||
font.setItalic(italic)
|
||||
font.setUnderline(underline)
|
||||
font.setStrikeOut(strikeout)
|
||||
format.setFont(font)
|
||||
settings.setFormat(format)
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
def updateLayerLabelingUnit(self, layer, unit):
|
||||
settings = layer.labeling().settings()
|
||||
format = settings.format()
|
||||
format.setSizeUnit(unit)
|
||||
settings.setFormat(format)
|
||||
layer.setLabeling(QgsVectorLayerSimpleLabeling(settings))
|
||||
|
||||
def loadStyleWithCustomProperties(self, layer, qmlFileName):
|
||||
# load the style, only vector symbology
|
||||
path = QDir.toNativeSeparators('%s/symbol_layer/%s.qml' % (unitTestDataPath(), qmlFileName))
|
||||
|
||||
# labeling is in custom properties, they need to be loaded separately
|
||||
status = layer.loadNamedStyle(path)
|
||||
doc = QDomDocument()
|
||||
file = QFile(path)
|
||||
file.open(QIODevice.ReadOnly)
|
||||
doc.setContent(file, True)
|
||||
file.close()
|
||||
flag = layer.readCustomProperties(doc.documentElement())
|
||||
|
||||
def assertPointPlacement(self, textSymbolizer):
|
||||
labelPlacement = self.assertElement(textSymbolizer, 'se:LabelPlacement', 0)
|
||||
self.assertIsNone(self.assertElement(labelPlacement, 'se:LinePlacement', 0, True))
|
||||
pointPlacement = self.assertElement(labelPlacement, 'se:PointPlacement', 0)
|
||||
return pointPlacement
|
||||
|
||||
def assertLinePlacement(self, textSymbolizer):
|
||||
labelPlacement = self.assertElement(textSymbolizer, 'se:LabelPlacement', 0)
|
||||
self.assertIsNone(self.assertElement(labelPlacement, 'se:PointPlacement', 0, True))
|
||||
linePlacement = self.assertElement(labelPlacement, 'se:LinePlacement', 0)
|
||||
return linePlacement
|
||||
|
||||
def assertElement(self, container, elementName, index, allowMissing=False):
|
||||
list = container.elementsByTagName(elementName)
|
||||
if list.size() <= index:
|
||||
if allowMissing:
|
||||
return None
|
||||
else:
|
||||
self.fail('Expected to find at least ' + str(index + 1) + ' ' + elementName + ' in ' + container.nodeName() + ' but found ' + str(list.size()))
|
||||
|
||||
node = list.item(index)
|
||||
self.assertTrue(node.isElement(), 'Found node but it''s not an element')
|
||||
return node.toElement()
|
||||
|
||||
def getTextSymbolizer(self, root, ruleIndex, textSymbolizerIndex):
|
||||
rule = self.assertElement(root, 'se:Rule', ruleIndex)
|
||||
textSymbolizer = self.assertElement(rule, 'se:TextSymbolizer', textSymbolizerIndex)
|
||||
return textSymbolizer
|
||||
|
||||
def assertPropertyName(self, root, containerProperty, expectedAttributeName):
|
||||
container = root.elementsByTagName(containerProperty).item(0).toElement()
|
||||
property = container.elementsByTagName("ogc:PropertyName").item(0).toElement()
|
||||
self.assertEqual(expectedAttributeName, property.text())
|
||||
|
||||
def assertSvgParameter(self, container, expectedName, allowMissing=False):
|
||||
list = container.elementsByTagName("se:SvgParameter")
|
||||
for i in range(0, list.size()):
|
||||
item = list.item(i)
|
||||
if item.isElement and item.isElement() and item.toElement().attribute('name') == expectedName:
|
||||
return item.toElement()
|
||||
if allowMissing:
|
||||
return None
|
||||
else:
|
||||
self.fail('Could not find a se:SvgParameter named ' + expectedName + ' in ' + container.nodeName())
|
||||
|
||||
def assertVendorOption(self, container, expectedName, allowMissing=False):
|
||||
list = container.elementsByTagName("se:VendorOption")
|
||||
for i in range(0, list.size()):
|
||||
item = list.item(i)
|
||||
if item.isElement and item.isElement() and item.toElement().attribute('name') == expectedName:
|
||||
return item.toElement()
|
||||
if allowMissing:
|
||||
return None
|
||||
else:
|
||||
self.fail('Could not find a se:VendorOption named ' + expectedName + ' in ' + container.nodeName())
|
||||
|
||||
def assertScaleDenominator(self, root, expectedMinScale, expectedMaxScale, index=0):
|
||||
rule = root.elementsByTagName('se:Rule').item(index).toElement()
|
||||
@ -615,6 +1225,52 @@ class TestQgsSymbolLayerCreateSld(unittest.TestCase):
|
||||
self.assertEqual('stroke-width', parameter.attribute('name'))
|
||||
self.assertEqual(str(expectedStrokeWidth), parameter.text())
|
||||
|
||||
def assertStaticRotation(self, root, expectedValue, index=0):
|
||||
# Check the rotation element is a literal, not a
|
||||
rotation = root.elementsByTagName('se:Rotation').item(index)
|
||||
literal = rotation.firstChild()
|
||||
self.assertEqual("ogc:Literal", literal.nodeName())
|
||||
self.assertEqual(expectedValue, literal.firstChild().nodeValue())
|
||||
|
||||
def assertStaticDisplacement(self, root, expectedAnchorX, expectedAnchorY):
|
||||
displacement = root.elementsByTagName('se:Displacement').item(0)
|
||||
self.assertIsNotNone(displacement)
|
||||
dx = displacement.firstChild()
|
||||
self.assertIsNotNone(dx)
|
||||
self.assertEqual("se:DisplacementX", dx.nodeName())
|
||||
self.assertSldNumber(expectedAnchorX, dx.firstChild().nodeValue())
|
||||
dy = displacement.lastChild()
|
||||
self.assertIsNotNone(dy)
|
||||
self.assertEqual("se:DisplacementY", dy.nodeName())
|
||||
self.assertSldNumber(expectedAnchorY, dy.firstChild().nodeValue())
|
||||
|
||||
def assertStaticAnchorPoint(self, root, expectedDispX, expectedDispY):
|
||||
anchor = root.elementsByTagName('se:AnchorPoint').item(0)
|
||||
self.assertIsNotNone(anchor)
|
||||
ax = anchor.firstChild()
|
||||
self.assertIsNotNone(ax)
|
||||
self.assertEqual("se:AnchorPointX", ax.nodeName())
|
||||
self.assertSldNumber(expectedDispX, ax.firstChild().nodeValue())
|
||||
ay = anchor.lastChild()
|
||||
self.assertIsNotNone(ay)
|
||||
self.assertEqual("se:AnchorPointY", ay.nodeName())
|
||||
self.assertSldNumber(expectedDispY, ay.firstChild().nodeValue())
|
||||
|
||||
def assertSldNumber(self, expected, stringValue):
|
||||
value = float(stringValue)
|
||||
self.assertFloatEquals(expected, value, 0.01)
|
||||
|
||||
def assertFloatEquals(self, expected, actual, tol):
|
||||
self.assertLess(abs(expected - actual), tol, 'Expected %d but was %d' % (expected, actual))
|
||||
|
||||
def assertStrokeWidth(self, root, svgParameterIdx, expectedWidth):
|
||||
strokeWidth = root.elementsByTagName(
|
||||
'se:SvgParameter').item(svgParameterIdx)
|
||||
svgParameterName = strokeWidth.attributes().namedItem('name')
|
||||
self.assertEqual("stroke-width", svgParameterName.nodeValue())
|
||||
self.assertSldNumber(
|
||||
expectedWidth, strokeWidth.firstChild().nodeValue())
|
||||
|
||||
def symbolToSld(self, symbolLayer):
|
||||
dom = QDomDocument()
|
||||
root = dom.createElement("FakeRoot")
|
||||
|
242
tests/testdata/symbol_layer/lineLabel.qml
vendored
Normal file
242
tests/testdata/symbol_layer/lineLabel.qml
vendored
Normal file
@ -0,0 +1,242 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis simplifyAlgorithm="0" hasScaleBasedVisibilityFlag="0" maxScale="0" mincale="1e+08" simplifyDrawingHints="1" simplifyLocal="1" version="2.99.0-Master" readOnly="0" simplifyDrawingTol="1" simplifyMaxScale="1">
|
||||
<renderer-v2 forceraster="0" enableorderby="0" symbollevels="0" type="singleSymbol">
|
||||
<symbols>
|
||||
<symbol name="0" alpha="1" type="line" clip_to_extent="1">
|
||||
<layer locked="0" class="SimpleLine" pass="0" enabled="1">
|
||||
<prop v="square" k="capstyle"/>
|
||||
<prop v="5;2" k="customdash"/>
|
||||
<prop v="3x:0,0,0,0,0,0" k="customdash_map_unit_scale"/>
|
||||
<prop v="MM" k="customdash_unit"/>
|
||||
<prop v="0" k="draw_inside_polygon"/>
|
||||
<prop v="bevel" k="joinstyle"/>
|
||||
<prop v="198,33,179,255" k="line_color"/>
|
||||
<prop v="solid" k="line_style"/>
|
||||
<prop v="0.26" k="line_width"/>
|
||||
<prop v="MM" k="line_width_unit"/>
|
||||
<prop v="0" k="offset"/>
|
||||
<prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/>
|
||||
<prop v="MM" k="offset_unit"/>
|
||||
<prop v="0" k="use_custom_dash"/>
|
||||
<prop v="3x:0,0,0,0,0,0" k="width_map_unit_scale"/>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</symbols>
|
||||
<rotation/>
|
||||
<sizescale/>
|
||||
</renderer-v2>
|
||||
<labeling type="simple">
|
||||
<settings>
|
||||
<text-style namedStyle="Regular" fontSize="10" fontLetterSpacing="0" multilineHeight="1" fontWordSpacing="0" useSubstitutions="0" fontUnderline="0" previewBkgrdColor="#ffffff" isExpression="0" fontWeight="50" fontCapitals="0" fieldName="name" textColor="0,0,0,255" textOpacity="1" fontStrikeout="0" fontFamily="Noto Sans" fontSizeMapUnitScale="3x:0,0,0,0,0,0" blendMode="0" fontSizeUnit="Point" fontItalic="0">
|
||||
<text-buffer bufferSize="1" bufferDraw="0" bufferColor="255,255,255,255" bufferJoinStyle="128" bufferSizeMapUnitScale="3x:0,0,0,0,0,0" bufferNoFill="1" bufferBlendMode="0" bufferSizeUnits="MM" bufferOpacity="1"/>
|
||||
<background shapeRotation="0" shapeBorderWidthUnit="MM" shapeOffsetMapUnitScale="3x:0,0,0,0,0,0" shapeRadiiY="0" shapeBorderWidth="0" shapeRadiiUnit="MM" shapeBorderColor="128,128,128,255" shapeBorderWidthMapUnitScale="3x:0,0,0,0,0,0" shapeOffsetX="0" shapeOffsetY="0" shapeJoinStyle="64" shapeSizeX="0" shapeRadiiMapUnitScale="3x:0,0,0,0,0,0" shapeSizeY="0" shapeRotationType="0" shapeSizeUnit="MM" shapeBlendMode="0" shapeDraw="0" shapeSizeType="0" shapeRadiiX="0" shapeSVGFile="" shapeOffsetUnit="MM" shapeSizeMapUnitScale="3x:0,0,0,0,0,0" shapeFillColor="255,255,255,255" shapeType="0" shapeOpacity="1"/>
|
||||
<shadow shadowOffsetAngle="135" shadowOffsetGlobal="1" shadowOffsetDist="1" shadowOffsetMapUnitScale="3x:0,0,0,0,0,0" shadowDraw="0" shadowUnder="0" shadowOpacity="0.7" shadowOffsetUnit="MM" shadowRadiusMapUnitScale="3x:0,0,0,0,0,0" shadowBlendMode="6" shadowRadiusAlphaOnly="0" shadowScale="100" shadowRadius="1.5" shadowRadiusUnit="MM" shadowColor="0,0,0,255"/>
|
||||
<substitutions/>
|
||||
</text-style>
|
||||
<text-format placeDirectionSymbol="0" multilineAlign="4294967295" wrapChar="" rightDirectionSymbol=">" leftDirectionSymbol="<" plussign="0" formatNumbers="0" reverseDirectionSymbol="0" addDirectionSymbol="0" decimals="3"/>
|
||||
<placement rotationAngle="0" dist="0" priority="5" placement="2" placementFlags="10" labelOffsetInMapUnits="1" quadOffset="4" repeatDistanceUnit="1" distInMapUnits="0" centroidWhole="0" yOffset="0" centroidInside="0" maxCurvedCharAngleIn="25" repeatDistanceMapUnitScale="3x:0,0,0,0,0,0" distMapUnitScale="3x:0,0,0,0,0,0" maxCurvedCharAngleOut="-25" labelOffsetMapUnitScale="3x:0,0,0,0,0,0" xOffset="0" repeatDistance="0" predefinedPositionOrder="TR,TL,BR,BL,R,L,TSR,BSR" preserveRotation="1" fitInPolygonOnly="0" offsetType="0"/>
|
||||
<rendering obstacle="1" zIndex="0" mergeLines="0" scaleVisibility="0" limitNumLabels="0" maxNumLabels="2000" drawLabels="1" scaleMax="0" fontLimitPixelSize="0" fontMinPixelSize="3" minFeatureSize="0" labelPerPart="0" obstacleFactor="1" displayAll="0" obstacleType="0" scaleMin="0" upsidedownLabels="0" fontMaxPixelSize="10000"/>
|
||||
<dd_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</dd_properties>
|
||||
</settings>
|
||||
</labeling>
|
||||
<customproperties>
|
||||
<property value="0" key="embeddedWidgets/count"/>
|
||||
<property key="variableNames"/>
|
||||
<property key="variableValues"/>
|
||||
</customproperties>
|
||||
<blendMode>0</blendMode>
|
||||
<featureBlendMode>0</featureBlendMode>
|
||||
<layerOpacity>1</layerOpacity>
|
||||
<SingleCategoryDiagramRenderer sizeLegend="0" diagramType="Histogram" attributeLegend="1">
|
||||
<DiagramCategory sizeType="MM" opacity="1" scaleBasedVisibility="0" width="15" backgroundColor="#ffffff" enabled="0" penAlpha="255" lineSizeScale="3x:0,0,0,0,0,0" penWidth="0" scaleDependency="Area" rotationOffset="270" lineSizeType="MM" labelPlacementMethod="XHeight" backgroundAlpha="255" barWidth="5" penColor="#000000" minScaleDenominator="0" sizeScale="3x:0,0,0,0,0,0" minimumSize="0" maxScaleDenominator="1e+08" diagramOrientation="Up" height="15">
|
||||
<fontProperties style="" description="Noto Sans,9,-1,5,50,0,0,0,0,0"/>
|
||||
</DiagramCategory>
|
||||
<symbol name="sizeSymbol" alpha="1" type="marker" clip_to_extent="1">
|
||||
<layer locked="0" class="SimpleMarker" pass="0" enabled="1">
|
||||
<prop v="0" k="angle"/>
|
||||
<prop v="255,0,0,255" k="color"/>
|
||||
<prop v="1" k="horizontal_anchor_point"/>
|
||||
<prop v="bevel" k="joinstyle"/>
|
||||
<prop v="circle" k="name"/>
|
||||
<prop v="0,0" k="offset"/>
|
||||
<prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/>
|
||||
<prop v="MM" k="offset_unit"/>
|
||||
<prop v="0,0,0,255" k="outline_color"/>
|
||||
<prop v="solid" k="outline_style"/>
|
||||
<prop v="0" k="outline_width"/>
|
||||
<prop v="3x:0,0,0,0,0,0" k="outline_width_map_unit_scale"/>
|
||||
<prop v="MM" k="outline_width_unit"/>
|
||||
<prop v="diameter" k="scale_method"/>
|
||||
<prop v="2" k="size"/>
|
||||
<prop v="3x:0,0,0,0,0,0" k="size_map_unit_scale"/>
|
||||
<prop v="MM" k="size_unit"/>
|
||||
<prop v="1" k="vertical_anchor_point"/>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</SingleCategoryDiagramRenderer>
|
||||
<DiagramLayerSettings placement="2" obstacle="0" showAll="1" priority="0" dist="0" zIndex="0" linePlacementFlags="18">
|
||||
<properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" value="" type="QString"/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" value="collection" type="QString"/>
|
||||
</Option>
|
||||
</properties>
|
||||
</DiagramLayerSettings>
|
||||
<fieldConfiguration>
|
||||
<field name="dissolve">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="scalerank">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="featurecla">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="name">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="name_alt">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="rivernum">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="note">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
</fieldConfiguration>
|
||||
<aliases>
|
||||
<alias name="" field="dissolve" index="0"/>
|
||||
<alias name="" field="scalerank" index="1"/>
|
||||
<alias name="" field="featurecla" index="2"/>
|
||||
<alias name="" field="name" index="3"/>
|
||||
<alias name="" field="name_alt" index="4"/>
|
||||
<alias name="" field="rivernum" index="5"/>
|
||||
<alias name="" field="note" index="6"/>
|
||||
</aliases>
|
||||
<excludeAttributesWMS/>
|
||||
<excludeAttributesWFS/>
|
||||
<defaults>
|
||||
<default field="dissolve" expression=""/>
|
||||
<default field="scalerank" expression=""/>
|
||||
<default field="featurecla" expression=""/>
|
||||
<default field="name" expression=""/>
|
||||
<default field="name_alt" expression=""/>
|
||||
<default field="rivernum" expression=""/>
|
||||
<default field="note" expression=""/>
|
||||
</defaults>
|
||||
<constraints>
|
||||
<constraint field="dissolve" unique_strength="0" notnull_strength="0" exp_strength="0" constraints="0"/>
|
||||
<constraint field="scalerank" unique_strength="0" notnull_strength="0" exp_strength="0" constraints="0"/>
|
||||
<constraint field="featurecla" unique_strength="0" notnull_strength="0" exp_strength="0" constraints="0"/>
|
||||
<constraint field="name" unique_strength="0" notnull_strength="0" exp_strength="0" constraints="0"/>
|
||||
<constraint field="name_alt" unique_strength="0" notnull_strength="0" exp_strength="0" constraints="0"/>
|
||||
<constraint field="rivernum" unique_strength="0" notnull_strength="0" exp_strength="0" constraints="0"/>
|
||||
<constraint field="note" unique_strength="0" notnull_strength="0" exp_strength="0" constraints="0"/>
|
||||
</constraints>
|
||||
<constraintExpressions>
|
||||
<constraint field="dissolve" desc="" exp=""/>
|
||||
<constraint field="scalerank" desc="" exp=""/>
|
||||
<constraint field="featurecla" desc="" exp=""/>
|
||||
<constraint field="name" desc="" exp=""/>
|
||||
<constraint field="name_alt" desc="" exp=""/>
|
||||
<constraint field="rivernum" desc="" exp=""/>
|
||||
<constraint field="note" desc="" exp=""/>
|
||||
</constraintExpressions>
|
||||
<attributeactions>
|
||||
<defaultAction value="{00000000-0000-0000-0000-000000000000}" key="Canvas"/>
|
||||
</attributeactions>
|
||||
<attributetableconfig sortExpression="" actionWidgetStyle="dropDown" sortOrder="0">
|
||||
<columns>
|
||||
<column name="dissolve" hidden="0" type="field" width="-1"/>
|
||||
<column name="scalerank" hidden="0" type="field" width="-1"/>
|
||||
<column name="featurecla" hidden="0" type="field" width="-1"/>
|
||||
<column name="name" hidden="0" type="field" width="-1"/>
|
||||
<column name="name_alt" hidden="0" type="field" width="-1"/>
|
||||
<column name="rivernum" hidden="0" type="field" width="-1"/>
|
||||
<column name="note" hidden="0" type="field" width="-1"/>
|
||||
<column hidden="1" type="actions" width="-1"/>
|
||||
</columns>
|
||||
</attributetableconfig>
|
||||
<editform></editform>
|
||||
<editforminit/>
|
||||
<editforminitcodesource>0</editforminitcodesource>
|
||||
<editforminitfilepath></editforminitfilepath>
|
||||
<editforminitcode><![CDATA[# -*- coding: utf-8 -*-
|
||||
"""
|
||||
QGIS forms can have a Python function that is called when the form is
|
||||
opened.
|
||||
|
||||
Use this function to add extra logic to your forms.
|
||||
|
||||
Enter the name of the function in the "Python Init function"
|
||||
field.
|
||||
An example follows:
|
||||
"""
|
||||
from qgis.PyQt.QtWidgets import QWidget
|
||||
|
||||
def my_form_open(dialog, layer, feature):
|
||||
geom = feature.geometry()
|
||||
control = dialog.findChild(QWidget, "MyLineEdit")
|
||||
]]></editforminitcode>
|
||||
<featformsuppress>0</featformsuppress>
|
||||
<editorlayout>generatedlayout</editorlayout>
|
||||
<widgets/>
|
||||
<conditionalstyles>
|
||||
<rowstyles/>
|
||||
<fieldstyles/>
|
||||
</conditionalstyles>
|
||||
<expressionfields/>
|
||||
<previewExpression>name</previewExpression>
|
||||
<mapTip></mapTip>
|
||||
<layerGeometryType>1</layerGeometryType>
|
||||
</qgis>
|
910
tests/testdata/symbol_layer/polygonLabel.qml
vendored
Normal file
910
tests/testdata/symbol_layer/polygonLabel.qml
vendored
Normal file
@ -0,0 +1,910 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis version="2.99.0-Master" simplifyDrawingHints="1" simplifyLocal="1" readOnly="0" mincale="1e+08" hasScaleBasedVisibilityFlag="0" maxScale="0" simplifyAlgorithm="0" simplifyDrawingTol="1" simplifyMaxScale="1">
|
||||
<renderer-v2 symbollevels="0" forceraster="0" type="singleSymbol" enableorderby="0">
|
||||
<symbols>
|
||||
<symbol alpha="1" name="0" clip_to_extent="1" type="fill">
|
||||
<layer pass="0" enabled="1" locked="0" class="SimpleFill">
|
||||
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||
<prop k="color" v="143,107,163,255"/>
|
||||
<prop k="joinstyle" v="bevel"/>
|
||||
<prop k="offset" v="0,0"/>
|
||||
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||
<prop k="offset_unit" v="MM"/>
|
||||
<prop k="outline_color" v="0,0,0,255"/>
|
||||
<prop k="outline_style" v="solid"/>
|
||||
<prop k="outline_width" v="0.26"/>
|
||||
<prop k="outline_width_unit" v="MM"/>
|
||||
<prop k="style" v="solid"/>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</symbols>
|
||||
<rotation/>
|
||||
<sizescale/>
|
||||
</renderer-v2>
|
||||
<labeling type="simple">
|
||||
<settings>
|
||||
<text-style fontWeight="50" fieldName="name" blendMode="0" fontItalic="0" isExpression="0" fontStrikeout="0" fontSizeMapUnitScale="3x:0,0,0,0,0,0" fontSize="10" fontFamily="Noto Sans" previewBkgrdColor="#ffffff" useSubstitutions="0" fontUnderline="0" textOpacity="1" textColor="0,0,0,255" fontSizeUnit="Point" fontWordSpacing="0" fontCapitals="0" namedStyle="Regular" multilineHeight="1" fontLetterSpacing="0">
|
||||
<text-buffer bufferColor="255,255,255,255" bufferSize="1" bufferSizeUnits="MM" bufferBlendMode="0" bufferOpacity="1" bufferSizeMapUnitScale="3x:0,0,0,0,0,0" bufferNoFill="1" bufferJoinStyle="128" bufferDraw="0"/>
|
||||
<background shapeRotationType="0" shapeType="0" shapeSizeX="0" shapeOpacity="1" shapeRadiiMapUnitScale="3x:0,0,0,0,0,0" shapeRadiiY="0" shapeSizeMapUnitScale="3x:0,0,0,0,0,0" shapeBlendMode="0" shapeOffsetY="0" shapeRotation="0" shapeOffsetMapUnitScale="3x:0,0,0,0,0,0" shapeOffsetX="0" shapeOffsetUnit="MM" shapeFillColor="255,255,255,255" shapeBorderWidthMapUnitScale="3x:0,0,0,0,0,0" shapeBorderColor="128,128,128,255" shapeSVGFile="" shapeRadiiUnit="MM" shapeDraw="0" shapeSizeType="0" shapeBorderWidthUnit="MM" shapeSizeY="0" shapeRadiiX="0" shapeBorderWidth="0" shapeJoinStyle="64" shapeSizeUnit="MM"/>
|
||||
<shadow shadowOffsetGlobal="1" shadowRadiusUnit="MM" shadowBlendMode="6" shadowOffsetDist="1" shadowOffsetAngle="135" shadowUnder="0" shadowOffsetMapUnitScale="3x:0,0,0,0,0,0" shadowScale="100" shadowRadius="1.5" shadowRadiusMapUnitScale="3x:0,0,0,0,0,0" shadowColor="0,0,0,255" shadowOpacity="0.7" shadowDraw="0" shadowOffsetUnit="MM" shadowRadiusAlphaOnly="0"/>
|
||||
<substitutions/>
|
||||
</text-style>
|
||||
<text-format reverseDirectionSymbol="0" placeDirectionSymbol="0" multilineAlign="4294967295" plussign="0" rightDirectionSymbol=">" formatNumbers="0" leftDirectionSymbol="<" decimals="3" wrapChar="" addDirectionSymbol="0"/>
|
||||
<placement offsetType="0" priority="5" dist="0" repeatDistanceUnit="1" labelOffsetInMapUnits="1" predefinedPositionOrder="TR,TL,BR,BL,R,L,TSR,BSR" repeatDistanceMapUnitScale="3x:0,0,0,0,0,0" distInMapUnits="0" preserveRotation="1" yOffset="0" labelOffsetMapUnitScale="3x:0,0,0,0,0,0" centroidInside="0" rotationAngle="0" distMapUnitScale="3x:0,0,0,0,0,0" maxCurvedCharAngleOut="-25" maxCurvedCharAngleIn="25" placementFlags="10" repeatDistance="0" xOffset="0" placement="0" fitInPolygonOnly="0" quadOffset="4" centroidWhole="0"/>
|
||||
<rendering drawLabels="1" labelPerPart="0" obstacleFactor="1" scaleVisibility="0" scaleMax="0" mergeLines="0" scaleMin="0" minFeatureSize="0" obstacle="1" fontMaxPixelSize="10000" zIndex="0" fontMinPixelSize="3" obstacleType="0" fontLimitPixelSize="0" limitNumLabels="0" upsidedownLabels="0" maxNumLabels="2000" displayAll="0"/>
|
||||
<dd_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</dd_properties>
|
||||
</settings>
|
||||
</labeling>
|
||||
<customproperties>
|
||||
<property key="embeddedWidgets/count" value="0"/>
|
||||
<property key="variableNames"/>
|
||||
<property key="variableValues"/>
|
||||
</customproperties>
|
||||
<blendMode>0</blendMode>
|
||||
<featureBlendMode>0</featureBlendMode>
|
||||
<layerOpacity>1</layerOpacity>
|
||||
<SingleCategoryDiagramRenderer diagramType="Histogram" sizeLegend="0" attributeLegend="1">
|
||||
<DiagramCategory rotationOffset="270" barWidth="5" scaleDependency="Area" penWidth="0" minimumSize="0" height="15" penAlpha="255" sizeType="MM" enabled="0" lineSizeScale="3x:0,0,0,0,0,0" minScaleDenominator="0" maxScaleDenominator="1e+08" sizeScale="3x:0,0,0,0,0,0" scaleBasedVisibility="0" width="15" diagramOrientation="Up" labelPlacementMethod="XHeight" lineSizeType="MM" backgroundAlpha="255" penColor="#000000" backgroundColor="#ffffff" opacity="1">
|
||||
<fontProperties description="Noto Sans,9,-1,5,50,0,0,0,0,0" style=""/>
|
||||
</DiagramCategory>
|
||||
<symbol alpha="1" name="sizeSymbol" clip_to_extent="1" type="marker">
|
||||
<layer pass="0" enabled="1" locked="0" class="SimpleMarker">
|
||||
<prop k="angle" v="0"/>
|
||||
<prop k="color" v="255,0,0,255"/>
|
||||
<prop k="horizontal_anchor_point" v="1"/>
|
||||
<prop k="joinstyle" v="bevel"/>
|
||||
<prop k="name" v="circle"/>
|
||||
<prop k="offset" v="0,0"/>
|
||||
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||
<prop k="offset_unit" v="MM"/>
|
||||
<prop k="outline_color" v="0,0,0,255"/>
|
||||
<prop k="outline_style" v="solid"/>
|
||||
<prop k="outline_width" v="0"/>
|
||||
<prop k="outline_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||
<prop k="outline_width_unit" v="MM"/>
|
||||
<prop k="scale_method" v="diameter"/>
|
||||
<prop k="size" v="2"/>
|
||||
<prop k="size_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||
<prop k="size_unit" v="MM"/>
|
||||
<prop k="vertical_anchor_point" v="1"/>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</SingleCategoryDiagramRenderer>
|
||||
<DiagramLayerSettings obstacle="0" priority="0" linePlacementFlags="18" dist="0" zIndex="0" showAll="1" placement="0">
|
||||
<properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</properties>
|
||||
</DiagramLayerSettings>
|
||||
<fieldConfiguration>
|
||||
<field name="scalerank">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="featurecla">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="labelrank">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="sovereignt">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="sov_a3">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="adm0_dif">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="level">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="type">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="admin">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="adm0_a3">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="geou_dif">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="geounit">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="gu_a3">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="su_dif">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="subunit">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="su_a3">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="brk_diff">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="name">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="name_long">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="brk_a3">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="brk_name">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="brk_group">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="abbrev">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="postal">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="formal_en">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="formal_fr">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="note_adm0">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="note_brk">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="name_sort">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="name_alt">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="mapcolor7">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="mapcolor8">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="mapcolor9">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="mapcolor13">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="pop_est">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="gdp_md_est">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="pop_year">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="lastcensus">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="gdp_year">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="economy">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="income_grp">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="wikipedia">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="fips_10">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="iso_a2">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="iso_a3">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="iso_n3">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="un_a3">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="wb_a2">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="wb_a3">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="woe_id">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="adm0_a3_is">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="adm0_a3_us">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="adm0_a3_un">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="adm0_a3_wb">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="continent">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="region_un">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="subregion">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="region_wb">
|
||||
<editWidget type="TextEdit">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="name_len">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="long_len">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="abbrev_len">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="tiny">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
<field name="homepart">
|
||||
<editWidget type="Range">
|
||||
<config>
|
||||
<Option/>
|
||||
</config>
|
||||
</editWidget>
|
||||
</field>
|
||||
</fieldConfiguration>
|
||||
<aliases>
|
||||
<alias field="scalerank" name="" index="0"/>
|
||||
<alias field="featurecla" name="" index="1"/>
|
||||
<alias field="labelrank" name="" index="2"/>
|
||||
<alias field="sovereignt" name="" index="3"/>
|
||||
<alias field="sov_a3" name="" index="4"/>
|
||||
<alias field="adm0_dif" name="" index="5"/>
|
||||
<alias field="level" name="" index="6"/>
|
||||
<alias field="type" name="" index="7"/>
|
||||
<alias field="admin" name="" index="8"/>
|
||||
<alias field="adm0_a3" name="" index="9"/>
|
||||
<alias field="geou_dif" name="" index="10"/>
|
||||
<alias field="geounit" name="" index="11"/>
|
||||
<alias field="gu_a3" name="" index="12"/>
|
||||
<alias field="su_dif" name="" index="13"/>
|
||||
<alias field="subunit" name="" index="14"/>
|
||||
<alias field="su_a3" name="" index="15"/>
|
||||
<alias field="brk_diff" name="" index="16"/>
|
||||
<alias field="name" name="" index="17"/>
|
||||
<alias field="name_long" name="" index="18"/>
|
||||
<alias field="brk_a3" name="" index="19"/>
|
||||
<alias field="brk_name" name="" index="20"/>
|
||||
<alias field="brk_group" name="" index="21"/>
|
||||
<alias field="abbrev" name="" index="22"/>
|
||||
<alias field="postal" name="" index="23"/>
|
||||
<alias field="formal_en" name="" index="24"/>
|
||||
<alias field="formal_fr" name="" index="25"/>
|
||||
<alias field="note_adm0" name="" index="26"/>
|
||||
<alias field="note_brk" name="" index="27"/>
|
||||
<alias field="name_sort" name="" index="28"/>
|
||||
<alias field="name_alt" name="" index="29"/>
|
||||
<alias field="mapcolor7" name="" index="30"/>
|
||||
<alias field="mapcolor8" name="" index="31"/>
|
||||
<alias field="mapcolor9" name="" index="32"/>
|
||||
<alias field="mapcolor13" name="" index="33"/>
|
||||
<alias field="pop_est" name="" index="34"/>
|
||||
<alias field="gdp_md_est" name="" index="35"/>
|
||||
<alias field="pop_year" name="" index="36"/>
|
||||
<alias field="lastcensus" name="" index="37"/>
|
||||
<alias field="gdp_year" name="" index="38"/>
|
||||
<alias field="economy" name="" index="39"/>
|
||||
<alias field="income_grp" name="" index="40"/>
|
||||
<alias field="wikipedia" name="" index="41"/>
|
||||
<alias field="fips_10" name="" index="42"/>
|
||||
<alias field="iso_a2" name="" index="43"/>
|
||||
<alias field="iso_a3" name="" index="44"/>
|
||||
<alias field="iso_n3" name="" index="45"/>
|
||||
<alias field="un_a3" name="" index="46"/>
|
||||
<alias field="wb_a2" name="" index="47"/>
|
||||
<alias field="wb_a3" name="" index="48"/>
|
||||
<alias field="woe_id" name="" index="49"/>
|
||||
<alias field="adm0_a3_is" name="" index="50"/>
|
||||
<alias field="adm0_a3_us" name="" index="51"/>
|
||||
<alias field="adm0_a3_un" name="" index="52"/>
|
||||
<alias field="adm0_a3_wb" name="" index="53"/>
|
||||
<alias field="continent" name="" index="54"/>
|
||||
<alias field="region_un" name="" index="55"/>
|
||||
<alias field="subregion" name="" index="56"/>
|
||||
<alias field="region_wb" name="" index="57"/>
|
||||
<alias field="name_len" name="" index="58"/>
|
||||
<alias field="long_len" name="" index="59"/>
|
||||
<alias field="abbrev_len" name="" index="60"/>
|
||||
<alias field="tiny" name="" index="61"/>
|
||||
<alias field="homepart" name="" index="62"/>
|
||||
</aliases>
|
||||
<excludeAttributesWMS/>
|
||||
<excludeAttributesWFS/>
|
||||
<defaults>
|
||||
<default field="scalerank" expression=""/>
|
||||
<default field="featurecla" expression=""/>
|
||||
<default field="labelrank" expression=""/>
|
||||
<default field="sovereignt" expression=""/>
|
||||
<default field="sov_a3" expression=""/>
|
||||
<default field="adm0_dif" expression=""/>
|
||||
<default field="level" expression=""/>
|
||||
<default field="type" expression=""/>
|
||||
<default field="admin" expression=""/>
|
||||
<default field="adm0_a3" expression=""/>
|
||||
<default field="geou_dif" expression=""/>
|
||||
<default field="geounit" expression=""/>
|
||||
<default field="gu_a3" expression=""/>
|
||||
<default field="su_dif" expression=""/>
|
||||
<default field="subunit" expression=""/>
|
||||
<default field="su_a3" expression=""/>
|
||||
<default field="brk_diff" expression=""/>
|
||||
<default field="name" expression=""/>
|
||||
<default field="name_long" expression=""/>
|
||||
<default field="brk_a3" expression=""/>
|
||||
<default field="brk_name" expression=""/>
|
||||
<default field="brk_group" expression=""/>
|
||||
<default field="abbrev" expression=""/>
|
||||
<default field="postal" expression=""/>
|
||||
<default field="formal_en" expression=""/>
|
||||
<default field="formal_fr" expression=""/>
|
||||
<default field="note_adm0" expression=""/>
|
||||
<default field="note_brk" expression=""/>
|
||||
<default field="name_sort" expression=""/>
|
||||
<default field="name_alt" expression=""/>
|
||||
<default field="mapcolor7" expression=""/>
|
||||
<default field="mapcolor8" expression=""/>
|
||||
<default field="mapcolor9" expression=""/>
|
||||
<default field="mapcolor13" expression=""/>
|
||||
<default field="pop_est" expression=""/>
|
||||
<default field="gdp_md_est" expression=""/>
|
||||
<default field="pop_year" expression=""/>
|
||||
<default field="lastcensus" expression=""/>
|
||||
<default field="gdp_year" expression=""/>
|
||||
<default field="economy" expression=""/>
|
||||
<default field="income_grp" expression=""/>
|
||||
<default field="wikipedia" expression=""/>
|
||||
<default field="fips_10" expression=""/>
|
||||
<default field="iso_a2" expression=""/>
|
||||
<default field="iso_a3" expression=""/>
|
||||
<default field="iso_n3" expression=""/>
|
||||
<default field="un_a3" expression=""/>
|
||||
<default field="wb_a2" expression=""/>
|
||||
<default field="wb_a3" expression=""/>
|
||||
<default field="woe_id" expression=""/>
|
||||
<default field="adm0_a3_is" expression=""/>
|
||||
<default field="adm0_a3_us" expression=""/>
|
||||
<default field="adm0_a3_un" expression=""/>
|
||||
<default field="adm0_a3_wb" expression=""/>
|
||||
<default field="continent" expression=""/>
|
||||
<default field="region_un" expression=""/>
|
||||
<default field="subregion" expression=""/>
|
||||
<default field="region_wb" expression=""/>
|
||||
<default field="name_len" expression=""/>
|
||||
<default field="long_len" expression=""/>
|
||||
<default field="abbrev_len" expression=""/>
|
||||
<default field="tiny" expression=""/>
|
||||
<default field="homepart" expression=""/>
|
||||
</defaults>
|
||||
<constraints>
|
||||
<constraint field="scalerank" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="featurecla" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="labelrank" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="sovereignt" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="sov_a3" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="adm0_dif" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="level" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="type" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="admin" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="adm0_a3" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="geou_dif" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="geounit" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="gu_a3" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="su_dif" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="subunit" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="su_a3" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="brk_diff" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="name" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="name_long" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="brk_a3" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="brk_name" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="brk_group" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="abbrev" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="postal" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="formal_en" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="formal_fr" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="note_adm0" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="note_brk" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="name_sort" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="name_alt" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="mapcolor7" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="mapcolor8" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="mapcolor9" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="mapcolor13" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="pop_est" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="gdp_md_est" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="pop_year" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="lastcensus" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="gdp_year" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="economy" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="income_grp" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="wikipedia" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="fips_10" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="iso_a2" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="iso_a3" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="iso_n3" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="un_a3" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="wb_a2" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="wb_a3" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="woe_id" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="adm0_a3_is" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="adm0_a3_us" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="adm0_a3_un" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="adm0_a3_wb" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="continent" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="region_un" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="subregion" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="region_wb" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="name_len" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="long_len" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="abbrev_len" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="tiny" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
<constraint field="homepart" unique_strength="0" exp_strength="0" constraints="0" notnull_strength="0"/>
|
||||
</constraints>
|
||||
<constraintExpressions>
|
||||
<constraint field="scalerank" desc="" exp=""/>
|
||||
<constraint field="featurecla" desc="" exp=""/>
|
||||
<constraint field="labelrank" desc="" exp=""/>
|
||||
<constraint field="sovereignt" desc="" exp=""/>
|
||||
<constraint field="sov_a3" desc="" exp=""/>
|
||||
<constraint field="adm0_dif" desc="" exp=""/>
|
||||
<constraint field="level" desc="" exp=""/>
|
||||
<constraint field="type" desc="" exp=""/>
|
||||
<constraint field="admin" desc="" exp=""/>
|
||||
<constraint field="adm0_a3" desc="" exp=""/>
|
||||
<constraint field="geou_dif" desc="" exp=""/>
|
||||
<constraint field="geounit" desc="" exp=""/>
|
||||
<constraint field="gu_a3" desc="" exp=""/>
|
||||
<constraint field="su_dif" desc="" exp=""/>
|
||||
<constraint field="subunit" desc="" exp=""/>
|
||||
<constraint field="su_a3" desc="" exp=""/>
|
||||
<constraint field="brk_diff" desc="" exp=""/>
|
||||
<constraint field="name" desc="" exp=""/>
|
||||
<constraint field="name_long" desc="" exp=""/>
|
||||
<constraint field="brk_a3" desc="" exp=""/>
|
||||
<constraint field="brk_name" desc="" exp=""/>
|
||||
<constraint field="brk_group" desc="" exp=""/>
|
||||
<constraint field="abbrev" desc="" exp=""/>
|
||||
<constraint field="postal" desc="" exp=""/>
|
||||
<constraint field="formal_en" desc="" exp=""/>
|
||||
<constraint field="formal_fr" desc="" exp=""/>
|
||||
<constraint field="note_adm0" desc="" exp=""/>
|
||||
<constraint field="note_brk" desc="" exp=""/>
|
||||
<constraint field="name_sort" desc="" exp=""/>
|
||||
<constraint field="name_alt" desc="" exp=""/>
|
||||
<constraint field="mapcolor7" desc="" exp=""/>
|
||||
<constraint field="mapcolor8" desc="" exp=""/>
|
||||
<constraint field="mapcolor9" desc="" exp=""/>
|
||||
<constraint field="mapcolor13" desc="" exp=""/>
|
||||
<constraint field="pop_est" desc="" exp=""/>
|
||||
<constraint field="gdp_md_est" desc="" exp=""/>
|
||||
<constraint field="pop_year" desc="" exp=""/>
|
||||
<constraint field="lastcensus" desc="" exp=""/>
|
||||
<constraint field="gdp_year" desc="" exp=""/>
|
||||
<constraint field="economy" desc="" exp=""/>
|
||||
<constraint field="income_grp" desc="" exp=""/>
|
||||
<constraint field="wikipedia" desc="" exp=""/>
|
||||
<constraint field="fips_10" desc="" exp=""/>
|
||||
<constraint field="iso_a2" desc="" exp=""/>
|
||||
<constraint field="iso_a3" desc="" exp=""/>
|
||||
<constraint field="iso_n3" desc="" exp=""/>
|
||||
<constraint field="un_a3" desc="" exp=""/>
|
||||
<constraint field="wb_a2" desc="" exp=""/>
|
||||
<constraint field="wb_a3" desc="" exp=""/>
|
||||
<constraint field="woe_id" desc="" exp=""/>
|
||||
<constraint field="adm0_a3_is" desc="" exp=""/>
|
||||
<constraint field="adm0_a3_us" desc="" exp=""/>
|
||||
<constraint field="adm0_a3_un" desc="" exp=""/>
|
||||
<constraint field="adm0_a3_wb" desc="" exp=""/>
|
||||
<constraint field="continent" desc="" exp=""/>
|
||||
<constraint field="region_un" desc="" exp=""/>
|
||||
<constraint field="subregion" desc="" exp=""/>
|
||||
<constraint field="region_wb" desc="" exp=""/>
|
||||
<constraint field="name_len" desc="" exp=""/>
|
||||
<constraint field="long_len" desc="" exp=""/>
|
||||
<constraint field="abbrev_len" desc="" exp=""/>
|
||||
<constraint field="tiny" desc="" exp=""/>
|
||||
<constraint field="homepart" desc="" exp=""/>
|
||||
</constraintExpressions>
|
||||
<attributeactions>
|
||||
<defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/>
|
||||
</attributeactions>
|
||||
<attributetableconfig actionWidgetStyle="dropDown" sortOrder="0" sortExpression="">
|
||||
<columns>
|
||||
<column name="scalerank" type="field" hidden="0" width="-1"/>
|
||||
<column name="featurecla" type="field" hidden="0" width="-1"/>
|
||||
<column name="labelrank" type="field" hidden="0" width="-1"/>
|
||||
<column name="sovereignt" type="field" hidden="0" width="-1"/>
|
||||
<column name="sov_a3" type="field" hidden="0" width="-1"/>
|
||||
<column name="adm0_dif" type="field" hidden="0" width="-1"/>
|
||||
<column name="level" type="field" hidden="0" width="-1"/>
|
||||
<column name="type" type="field" hidden="0" width="-1"/>
|
||||
<column name="admin" type="field" hidden="0" width="-1"/>
|
||||
<column name="adm0_a3" type="field" hidden="0" width="-1"/>
|
||||
<column name="geou_dif" type="field" hidden="0" width="-1"/>
|
||||
<column name="geounit" type="field" hidden="0" width="-1"/>
|
||||
<column name="gu_a3" type="field" hidden="0" width="-1"/>
|
||||
<column name="su_dif" type="field" hidden="0" width="-1"/>
|
||||
<column name="subunit" type="field" hidden="0" width="-1"/>
|
||||
<column name="su_a3" type="field" hidden="0" width="-1"/>
|
||||
<column name="brk_diff" type="field" hidden="0" width="-1"/>
|
||||
<column name="name" type="field" hidden="0" width="-1"/>
|
||||
<column name="name_long" type="field" hidden="0" width="-1"/>
|
||||
<column name="brk_a3" type="field" hidden="0" width="-1"/>
|
||||
<column name="brk_name" type="field" hidden="0" width="-1"/>
|
||||
<column name="brk_group" type="field" hidden="0" width="-1"/>
|
||||
<column name="abbrev" type="field" hidden="0" width="-1"/>
|
||||
<column name="postal" type="field" hidden="0" width="-1"/>
|
||||
<column name="formal_en" type="field" hidden="0" width="-1"/>
|
||||
<column name="formal_fr" type="field" hidden="0" width="-1"/>
|
||||
<column name="note_adm0" type="field" hidden="0" width="-1"/>
|
||||
<column name="note_brk" type="field" hidden="0" width="-1"/>
|
||||
<column name="name_sort" type="field" hidden="0" width="-1"/>
|
||||
<column name="name_alt" type="field" hidden="0" width="-1"/>
|
||||
<column name="mapcolor7" type="field" hidden="0" width="-1"/>
|
||||
<column name="mapcolor8" type="field" hidden="0" width="-1"/>
|
||||
<column name="mapcolor9" type="field" hidden="0" width="-1"/>
|
||||
<column name="mapcolor13" type="field" hidden="0" width="-1"/>
|
||||
<column name="pop_est" type="field" hidden="0" width="-1"/>
|
||||
<column name="gdp_md_est" type="field" hidden="0" width="-1"/>
|
||||
<column name="pop_year" type="field" hidden="0" width="-1"/>
|
||||
<column name="lastcensus" type="field" hidden="0" width="-1"/>
|
||||
<column name="gdp_year" type="field" hidden="0" width="-1"/>
|
||||
<column name="economy" type="field" hidden="0" width="-1"/>
|
||||
<column name="income_grp" type="field" hidden="0" width="-1"/>
|
||||
<column name="wikipedia" type="field" hidden="0" width="-1"/>
|
||||
<column name="fips_10" type="field" hidden="0" width="-1"/>
|
||||
<column name="iso_a2" type="field" hidden="0" width="-1"/>
|
||||
<column name="iso_a3" type="field" hidden="0" width="-1"/>
|
||||
<column name="iso_n3" type="field" hidden="0" width="-1"/>
|
||||
<column name="un_a3" type="field" hidden="0" width="-1"/>
|
||||
<column name="wb_a2" type="field" hidden="0" width="-1"/>
|
||||
<column name="wb_a3" type="field" hidden="0" width="-1"/>
|
||||
<column name="woe_id" type="field" hidden="0" width="-1"/>
|
||||
<column name="adm0_a3_is" type="field" hidden="0" width="-1"/>
|
||||
<column name="adm0_a3_us" type="field" hidden="0" width="-1"/>
|
||||
<column name="adm0_a3_un" type="field" hidden="0" width="-1"/>
|
||||
<column name="adm0_a3_wb" type="field" hidden="0" width="-1"/>
|
||||
<column name="continent" type="field" hidden="0" width="-1"/>
|
||||
<column name="region_un" type="field" hidden="0" width="-1"/>
|
||||
<column name="subregion" type="field" hidden="0" width="-1"/>
|
||||
<column name="region_wb" type="field" hidden="0" width="-1"/>
|
||||
<column name="name_len" type="field" hidden="0" width="-1"/>
|
||||
<column name="long_len" type="field" hidden="0" width="-1"/>
|
||||
<column name="abbrev_len" type="field" hidden="0" width="-1"/>
|
||||
<column name="tiny" type="field" hidden="0" width="-1"/>
|
||||
<column name="homepart" type="field" hidden="0" width="-1"/>
|
||||
<column type="actions" hidden="1" width="-1"/>
|
||||
</columns>
|
||||
</attributetableconfig>
|
||||
<editform></editform>
|
||||
<editforminit/>
|
||||
<editforminitcodesource>0</editforminitcodesource>
|
||||
<editforminitfilepath></editforminitfilepath>
|
||||
<editforminitcode><![CDATA[# -*- coding: utf-8 -*-
|
||||
"""
|
||||
QGIS forms can have a Python function that is called when the form is
|
||||
opened.
|
||||
|
||||
Use this function to add extra logic to your forms.
|
||||
|
||||
Enter the name of the function in the "Python Init function"
|
||||
field.
|
||||
An example follows:
|
||||
"""
|
||||
from qgis.PyQt.QtWidgets import QWidget
|
||||
|
||||
def my_form_open(dialog, layer, feature):
|
||||
geom = feature.geometry()
|
||||
control = dialog.findChild(QWidget, "MyLineEdit")
|
||||
]]></editforminitcode>
|
||||
<featformsuppress>0</featformsuppress>
|
||||
<editorlayout>generatedlayout</editorlayout>
|
||||
<widgets/>
|
||||
<conditionalstyles>
|
||||
<rowstyles/>
|
||||
<fieldstyles/>
|
||||
</conditionalstyles>
|
||||
<expressionfields/>
|
||||
<previewExpression>name</previewExpression>
|
||||
<mapTip></mapTip>
|
||||
<layerGeometryType>2</layerGeometryType>
|
||||
</qgis>
|
285
tests/testdata/symbol_layer/simpleLabel.qml
vendored
Normal file
285
tests/testdata/symbol_layer/simpleLabel.qml
vendored
Normal file
@ -0,0 +1,285 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis version="2.18.0" simplifyAlgorithm="0" minimumScale="0" maximumScale="1e+08" simplifyDrawingHints="0" minLabelScale="0" maxLabelScale="1e+08" simplifyDrawingTol="1" simplifyMaxScale="1" hasScaleBasedVisibilityFlag="0" simplifyLocal="1" scaleBasedLabelVisibilityFlag="0">
|
||||
<edittypes>
|
||||
<edittype widgetv2type="TextEdit" name="ID">
|
||||
<widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
|
||||
</edittype>
|
||||
<edittype widgetv2type="TextEdit" name="AUTHORITY">
|
||||
<widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
|
||||
</edittype>
|
||||
<edittype widgetv2type="TextEdit" name="NAME">
|
||||
<widgetv2config IsMultiline="0" fieldEditable="1" constraint="" UseHtml="0" labelOnTop="0" constraintDescription="" notNull="0"/>
|
||||
</edittype>
|
||||
</edittypes>
|
||||
<renderer-v2 forceraster="0" symbollevels="0" type="singleSymbol" enableorderby="0">
|
||||
<symbols>
|
||||
<symbol alpha="1" clip_to_extent="1" type="marker" name="0">
|
||||
<layer pass="0" class="SimpleMarker" locked="0">
|
||||
<prop k="angle" v="0"/>
|
||||
<prop k="color" v="160,80,26,255"/>
|
||||
<prop k="horizontal_anchor_point" v="1"/>
|
||||
<prop k="joinstyle" v="bevel"/>
|
||||
<prop k="name" v="circle"/>
|
||||
<prop k="offset" v="0,0"/>
|
||||
<prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="offset_unit" v="MM"/>
|
||||
<prop k="outline_color" v="0,0,0,255"/>
|
||||
<prop k="outline_style" v="solid"/>
|
||||
<prop k="outline_width" v="0"/>
|
||||
<prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="outline_width_unit" v="MM"/>
|
||||
<prop k="scale_method" v="diameter"/>
|
||||
<prop k="size" v="5"/>
|
||||
<prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="size_unit" v="MM"/>
|
||||
<prop k="vertical_anchor_point" v="1"/>
|
||||
</layer>
|
||||
</symbol>
|
||||
</symbols>
|
||||
<rotation/>
|
||||
<sizescale scalemethod="diameter"/>
|
||||
</renderer-v2>
|
||||
<labeling type="simple"/>
|
||||
<customproperties>
|
||||
<property key="embeddedWidgets/count" value="0"/>
|
||||
<property key="labeling" value="pal"/>
|
||||
<property key="labeling/addDirectionSymbol" value="false"/>
|
||||
<property key="labeling/angleOffset" value="0"/>
|
||||
<property key="labeling/blendMode" value="0"/>
|
||||
<property key="labeling/bufferBlendMode" value="0"/>
|
||||
<property key="labeling/bufferColorA" value="255"/>
|
||||
<property key="labeling/bufferColorB" value="255"/>
|
||||
<property key="labeling/bufferColorG" value="255"/>
|
||||
<property key="labeling/bufferColorR" value="255"/>
|
||||
<property key="labeling/bufferDraw" value="false"/>
|
||||
<property key="labeling/bufferJoinStyle" value="128"/>
|
||||
<property key="labeling/bufferNoFill" value="false"/>
|
||||
<property key="labeling/bufferSize" value="1"/>
|
||||
<property key="labeling/bufferSizeInMapUnits" value="false"/>
|
||||
<property key="labeling/bufferSizeMapUnitScale" value="0,0,0,0,0,0"/>
|
||||
<property key="labeling/bufferTransp" value="0"/>
|
||||
<property key="labeling/centroidInside" value="false"/>
|
||||
<property key="labeling/centroidWhole" value="false"/>
|
||||
<property key="labeling/decimals" value="3"/>
|
||||
<property key="labeling/displayAll" value="false"/>
|
||||
<property key="labeling/dist" value="0"/>
|
||||
<property key="labeling/distInMapUnits" value="false"/>
|
||||
<property key="labeling/distMapUnitScale" value="0,0,0,0,0,0"/>
|
||||
<property key="labeling/drawLabels" value="true"/>
|
||||
<property key="labeling/enabled" value="true"/>
|
||||
<property key="labeling/fieldName" value="NAME"/>
|
||||
<property key="labeling/fitInPolygonOnly" value="false"/>
|
||||
<property key="labeling/fontCapitals" value="0"/>
|
||||
<property key="labeling/fontFamily" value="Liberation Mono"/>
|
||||
<property key="labeling/fontItalic" value="true"/>
|
||||
<property key="labeling/fontLetterSpacing" value="0"/>
|
||||
<property key="labeling/fontLimitPixelSize" value="false"/>
|
||||
<property key="labeling/fontMaxPixelSize" value="10000"/>
|
||||
<property key="labeling/fontMinPixelSize" value="3"/>
|
||||
<property key="labeling/fontSize" value="9"/>
|
||||
<property key="labeling/fontSizeInMapUnits" value="false"/>
|
||||
<property key="labeling/fontSizeMapUnitScale" value="0,0,0,0,0,0"/>
|
||||
<property key="labeling/fontStrikeout" value="false"/>
|
||||
<property key="labeling/fontUnderline" value="false"/>
|
||||
<property key="labeling/fontWeight" value="75"/>
|
||||
<property key="labeling/fontWordSpacing" value="0"/>
|
||||
<property key="labeling/formatNumbers" value="false"/>
|
||||
<property key="labeling/isExpression" value="false"/>
|
||||
<property key="labeling/labelOffsetInMapUnits" value="true"/>
|
||||
<property key="labeling/labelOffsetMapUnitScale" value="0,0,0,0,0,0"/>
|
||||
<property key="labeling/labelPerPart" value="false"/>
|
||||
<property key="labeling/leftDirectionSymbol" value="<"/>
|
||||
<property key="labeling/limitNumLabels" value="false"/>
|
||||
<property key="labeling/maxCurvedCharAngleIn" value="25"/>
|
||||
<property key="labeling/maxCurvedCharAngleOut" value="-25"/>
|
||||
<property key="labeling/maxNumLabels" value="2000"/>
|
||||
<property key="labeling/mergeLines" value="false"/>
|
||||
<property key="labeling/minFeatureSize" value="0"/>
|
||||
<property key="labeling/multilineAlign" value="3"/>
|
||||
<property key="labeling/multilineHeight" value="1"/>
|
||||
<property key="labeling/namedStyle" value="Regular"/>
|
||||
<property key="labeling/obstacle" value="true"/>
|
||||
<property key="labeling/obstacleFactor" value="1"/>
|
||||
<property key="labeling/obstacleType" value="0"/>
|
||||
<property key="labeling/offsetType" value="0"/>
|
||||
<property key="labeling/placeDirectionSymbol" value="0"/>
|
||||
<property key="labeling/placement" value="1"/>
|
||||
<property key="labeling/placementFlags" value="10"/>
|
||||
<property key="labeling/plussign" value="false"/>
|
||||
<property key="labeling/predefinedPositionOrder" value="TR,TL,BR,BL,R,L,TSR,BSR"/>
|
||||
<property key="labeling/preserveRotation" value="true"/>
|
||||
<property key="labeling/previewBkgrdColor" value="#ffffff"/>
|
||||
<property key="labeling/priority" value="5"/>
|
||||
<property key="labeling/quadOffset" value="7"/>
|
||||
<property key="labeling/repeatDistance" value="0"/>
|
||||
<property key="labeling/repeatDistanceMapUnitScale" value="0,0,0,0,0,0"/>
|
||||
<property key="labeling/repeatDistanceUnit" value="1"/>
|
||||
<property key="labeling/reverseDirectionSymbol" value="false"/>
|
||||
<property key="labeling/rightDirectionSymbol" value=">"/>
|
||||
<property key="labeling/scaleMax" value="10000000"/>
|
||||
<property key="labeling/scaleMin" value="1"/>
|
||||
<property key="labeling/scaleVisibility" value="false"/>
|
||||
<property key="labeling/shadowBlendMode" value="6"/>
|
||||
<property key="labeling/shadowColorB" value="0"/>
|
||||
<property key="labeling/shadowColorG" value="0"/>
|
||||
<property key="labeling/shadowColorR" value="0"/>
|
||||
<property key="labeling/shadowDraw" value="false"/>
|
||||
<property key="labeling/shadowOffsetAngle" value="135"/>
|
||||
<property key="labeling/shadowOffsetDist" value="1"/>
|
||||
<property key="labeling/shadowOffsetGlobal" value="true"/>
|
||||
<property key="labeling/shadowOffsetMapUnitScale" value="0,0,0,0,0,0"/>
|
||||
<property key="labeling/shadowOffsetUnits" value="1"/>
|
||||
<property key="labeling/shadowRadius" value="1.5"/>
|
||||
<property key="labeling/shadowRadiusAlphaOnly" value="false"/>
|
||||
<property key="labeling/shadowRadiusMapUnitScale" value="0,0,0,0,0,0"/>
|
||||
<property key="labeling/shadowRadiusUnits" value="1"/>
|
||||
<property key="labeling/shadowScale" value="100"/>
|
||||
<property key="labeling/shadowTransparency" value="30"/>
|
||||
<property key="labeling/shadowUnder" value="0"/>
|
||||
<property key="labeling/shapeBlendMode" value="0"/>
|
||||
<property key="labeling/shapeBorderColorA" value="255"/>
|
||||
<property key="labeling/shapeBorderColorB" value="128"/>
|
||||
<property key="labeling/shapeBorderColorG" value="128"/>
|
||||
<property key="labeling/shapeBorderColorR" value="128"/>
|
||||
<property key="labeling/shapeBorderWidth" value="0"/>
|
||||
<property key="labeling/shapeBorderWidthMapUnitScale" value="0,0,0,0,0,0"/>
|
||||
<property key="labeling/shapeBorderWidthUnits" value="1"/>
|
||||
<property key="labeling/shapeDraw" value="false"/>
|
||||
<property key="labeling/shapeFillColorA" value="255"/>
|
||||
<property key="labeling/shapeFillColorB" value="255"/>
|
||||
<property key="labeling/shapeFillColorG" value="255"/>
|
||||
<property key="labeling/shapeFillColorR" value="255"/>
|
||||
<property key="labeling/shapeJoinStyle" value="64"/>
|
||||
<property key="labeling/shapeOffsetMapUnitScale" value="0,0,0,0,0,0"/>
|
||||
<property key="labeling/shapeOffsetUnits" value="1"/>
|
||||
<property key="labeling/shapeOffsetX" value="0"/>
|
||||
<property key="labeling/shapeOffsetY" value="0"/>
|
||||
<property key="labeling/shapeRadiiMapUnitScale" value="0,0,0,0,0,0"/>
|
||||
<property key="labeling/shapeRadiiUnits" value="1"/>
|
||||
<property key="labeling/shapeRadiiX" value="0"/>
|
||||
<property key="labeling/shapeRadiiY" value="0"/>
|
||||
<property key="labeling/shapeRotation" value="0"/>
|
||||
<property key="labeling/shapeRotationType" value="0"/>
|
||||
<property key="labeling/shapeSVGFile" value=""/>
|
||||
<property key="labeling/shapeSizeMapUnitScale" value="0,0,0,0,0,0"/>
|
||||
<property key="labeling/shapeSizeType" value="0"/>
|
||||
<property key="labeling/shapeSizeUnits" value="1"/>
|
||||
<property key="labeling/shapeSizeX" value="0"/>
|
||||
<property key="labeling/shapeSizeY" value="0"/>
|
||||
<property key="labeling/shapeTransparency" value="0"/>
|
||||
<property key="labeling/shapeType" value="0"/>
|
||||
<property key="labeling/substitutions" value="<substitutions/>"/>
|
||||
<property key="labeling/textColorA" value="255"/>
|
||||
<property key="labeling/textColorB" value="0"/>
|
||||
<property key="labeling/textColorG" value="0"/>
|
||||
<property key="labeling/textColorR" value="0"/>
|
||||
<property key="labeling/textTransp" value="0"/>
|
||||
<property key="labeling/upsidedownLabels" value="0"/>
|
||||
<property key="labeling/useSubstitutions" value="false"/>
|
||||
<property key="labeling/wrapChar" value=""/>
|
||||
<property key="labeling/xOffset" value="0"/>
|
||||
<property key="labeling/yOffset" value="0"/>
|
||||
<property key="labeling/zIndex" value="0"/>
|
||||
<property key="variableNames" value="_fields_"/>
|
||||
<property key="variableValues" value=""/>
|
||||
</customproperties>
|
||||
<blendMode>0</blendMode>
|
||||
<featureBlendMode>0</featureBlendMode>
|
||||
<layerTransparency>0</layerTransparency>
|
||||
<displayfield>NAME</displayfield>
|
||||
<label>0</label>
|
||||
<labelattributes>
|
||||
<label fieldname="" text="Etichetta"/>
|
||||
<family fieldname="" name="Liberation Mono"/>
|
||||
<size fieldname="" units="pt" value="12"/>
|
||||
<bold fieldname="" on="0"/>
|
||||
<italic fieldname="" on="0"/>
|
||||
<underline fieldname="" on="0"/>
|
||||
<strikeout fieldname="" on="0"/>
|
||||
<color fieldname="" red="0" blue="0" green="0"/>
|
||||
<x fieldname=""/>
|
||||
<y fieldname=""/>
|
||||
<offset x="0" y="0" units="pt" yfieldname="" xfieldname=""/>
|
||||
<angle fieldname="" value="0" auto="0"/>
|
||||
<alignment fieldname="" value="center"/>
|
||||
<buffercolor fieldname="" red="255" blue="255" green="255"/>
|
||||
<buffersize fieldname="" units="pt" value="1"/>
|
||||
<bufferenabled fieldname="" on=""/>
|
||||
<multilineenabled fieldname="" on=""/>
|
||||
<selectedonly on=""/>
|
||||
</labelattributes>
|
||||
<SingleCategoryDiagramRenderer diagramType="Histogram" sizeLegend="0" attributeLegend="1">
|
||||
<DiagramCategory penColor="#000000" labelPlacementMethod="XHeight" penWidth="0" diagramOrientation="Up" sizeScale="0,0,0,0,0,0" minimumSize="0" barWidth="5" penAlpha="255" maxScaleDenominator="1e+08" backgroundColor="#ffffff" transparency="0" width="15" scaleDependency="Area" backgroundAlpha="255" angleOffset="1440" scaleBasedVisibility="0" enabled="0" height="15" lineSizeScale="0,0,0,0,0,0" sizeType="MM" lineSizeType="MM" minScaleDenominator="inf">
|
||||
<fontProperties description="Liberation Mono,9,-1,5,50,0,0,0,0,0" style=""/>
|
||||
</DiagramCategory>
|
||||
<symbol alpha="1" clip_to_extent="1" type="marker" name="sizeSymbol">
|
||||
<layer pass="0" class="SimpleMarker" locked="0">
|
||||
<prop k="angle" v="0"/>
|
||||
<prop k="color" v="255,0,0,255"/>
|
||||
<prop k="horizontal_anchor_point" v="1"/>
|
||||
<prop k="joinstyle" v="bevel"/>
|
||||
<prop k="name" v="circle"/>
|
||||
<prop k="offset" v="0,0"/>
|
||||
<prop k="offset_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="offset_unit" v="MM"/>
|
||||
<prop k="outline_color" v="0,0,0,255"/>
|
||||
<prop k="outline_style" v="solid"/>
|
||||
<prop k="outline_width" v="0"/>
|
||||
<prop k="outline_width_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="outline_width_unit" v="MM"/>
|
||||
<prop k="scale_method" v="diameter"/>
|
||||
<prop k="size" v="2"/>
|
||||
<prop k="size_map_unit_scale" v="0,0,0,0,0,0"/>
|
||||
<prop k="size_unit" v="MM"/>
|
||||
<prop k="vertical_anchor_point" v="1"/>
|
||||
</layer>
|
||||
</symbol>
|
||||
</SingleCategoryDiagramRenderer>
|
||||
<DiagramLayerSettings yPosColumn="-1" showColumn="-1" linePlacementFlags="10" placement="0" dist="0" xPosColumn="-1" priority="0" obstacle="0" zIndex="0" showAll="1"/>
|
||||
<annotationform></annotationform>
|
||||
<aliases>
|
||||
<alias field="ID" index="0" name=""/>
|
||||
<alias field="AUTHORITY" index="1" name=""/>
|
||||
<alias field="NAME" index="2" name=""/>
|
||||
</aliases>
|
||||
<excludeAttributesWMS/>
|
||||
<excludeAttributesWFS/>
|
||||
<attributeactions default="-1"/>
|
||||
<attributetableconfig actionWidgetStyle="dropDown" sortExpression="" sortOrder="2359551">
|
||||
<columns>
|
||||
<column width="-1" hidden="0" type="field" name="ID"/>
|
||||
<column width="-1" hidden="0" type="field" name="AUTHORITY"/>
|
||||
<column width="-1" hidden="0" type="field" name="NAME"/>
|
||||
<column width="-1" hidden="1" type="actions"/>
|
||||
</columns>
|
||||
</attributetableconfig>
|
||||
<editform></editform>
|
||||
<editforminit/>
|
||||
<editforminitcodesource>0</editforminitcodesource>
|
||||
<editforminitfilepath></editforminitfilepath>
|
||||
<editforminitcode><![CDATA[# -*- coding: utf-8 -*-
|
||||
"""
|
||||
QGIS forms can have a Python function that is called when the form is
|
||||
opened.
|
||||
|
||||
Use this function to add extra logic to your forms.
|
||||
|
||||
Enter the name of the function in the "Python Init function"
|
||||
field.
|
||||
An example follows:
|
||||
"""
|
||||
from qgis.PyQt.QtWidgets import QWidget
|
||||
|
||||
def my_form_open(dialog, layer, feature):
|
||||
geom = feature.geometry()
|
||||
control = dialog.findChild(QWidget, "MyLineEdit")
|
||||
]]></editforminitcode>
|
||||
<featformsuppress>0</featformsuppress>
|
||||
<editorlayout>generatedlayout</editorlayout>
|
||||
<widgets/>
|
||||
<conditionalstyles>
|
||||
<rowstyles/>
|
||||
<fieldstyles/>
|
||||
</conditionalstyles>
|
||||
<layerGeometryType>0</layerGeometryType>
|
||||
</qgis>
|
Loading…
x
Reference in New Issue
Block a user