Quantum GIS API Documentation
1.8
|
00001 /*************************************************************************** 00002 qgsvectorfieldsymbollayer.cpp 00003 ----------------------------- 00004 begin : Octorer 25, 2011 00005 copyright : (C) 2011 by Marco Hugentobler 00006 email : marco dot hugentobler at sourcepole dot ch 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 #include "qgsvectorfieldsymbollayer.h" 00019 #include "qgsvectorlayer.h" 00020 00021 QgsVectorFieldSymbolLayer::QgsVectorFieldSymbolLayer(): mXAttribute( "" ), mYAttribute( "" ), mScale( 1.0 ), 00022 mVectorFieldType( Cartesian ), mAngleOrientation( ClockwiseFromNorth ), mAngleUnits( Degrees ), mXIndex( -1 ), mYIndex( -1 ) 00023 { 00024 setSubSymbol( new QgsLineSymbolV2() ); 00025 } 00026 00027 QgsVectorFieldSymbolLayer::~QgsVectorFieldSymbolLayer() 00028 { 00029 } 00030 00031 QgsSymbolLayerV2* QgsVectorFieldSymbolLayer::create( const QgsStringMap& properties ) 00032 { 00033 QgsVectorFieldSymbolLayer* symbolLayer = new QgsVectorFieldSymbolLayer(); 00034 if ( properties.contains( "x_attribute" ) ) 00035 { 00036 symbolLayer->setXAttribute( properties["x_attribute"] ); 00037 } 00038 if ( properties.contains( "y_attribute" ) ) 00039 { 00040 symbolLayer->setYAttribute( properties["y_attribute"] ); 00041 } 00042 if ( properties.contains( "scale" ) ) 00043 { 00044 symbolLayer->setScale( properties["scale"].toDouble() ); 00045 } 00046 if ( properties.contains( "vector_field_type" ) ) 00047 { 00048 symbolLayer->setVectorFieldType(( VectorFieldType )( properties["vector_field_type"].toInt() ) ); 00049 } 00050 if ( properties.contains( "angle_orientation" ) ) 00051 { 00052 symbolLayer->setAngleOrientation(( AngleOrientation )( properties["angle_orientation"].toInt() ) ); 00053 } 00054 if ( properties.contains( "angle_units" ) ) 00055 { 00056 symbolLayer->setAngleUnits(( AngleUnits )( properties["angle_units"].toInt() ) ); 00057 } 00058 return symbolLayer; 00059 } 00060 00061 bool QgsVectorFieldSymbolLayer::setSubSymbol( QgsSymbolV2* symbol ) 00062 { 00063 if ( symbol->type() == QgsSymbolV2::Line ) 00064 { 00065 mLineSymbol = static_cast<QgsLineSymbolV2*>( symbol ); 00066 return true; 00067 } 00068 return false; 00069 } 00070 00071 void QgsVectorFieldSymbolLayer::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context ) 00072 { 00073 if ( !mLineSymbol ) 00074 { 00075 return; 00076 } 00077 00078 const QgsFeature* f = context.feature(); 00079 if ( !f ) 00080 { 00081 //preview 00082 QPolygonF line; 00083 line << QPointF( 0, 50 ); 00084 line << QPointF( 100, 50 ); 00085 mLineSymbol->renderPolyline( line, 0, context.renderContext() ); 00086 } 00087 00088 double xComponent = 0; 00089 double yComponent = 0; 00090 00091 double xVal = 0; 00092 if ( mXIndex != -1 ) 00093 { 00094 xVal = f->attributeMap()[mXIndex].toDouble(); 00095 } 00096 double yVal = 0; 00097 if ( mYIndex != -1 ) 00098 { 00099 yVal = f->attributeMap()[mYIndex].toDouble(); 00100 } 00101 00102 switch ( mVectorFieldType ) 00103 { 00104 case Cartesian: 00105 xComponent = context.outputLineWidth( xVal ); 00106 yComponent = context.outputLineWidth( yVal ); 00107 break; 00108 case Polar: 00109 convertPolarToCartesian( xVal, yVal, xComponent, yComponent ); 00110 xComponent = context.outputLineWidth( xComponent ); 00111 yComponent = context.outputLineWidth( yComponent ); 00112 break; 00113 case Height: 00114 xComponent = 0; 00115 yComponent = context.outputLineWidth( yVal ); 00116 break; 00117 default: 00118 break; 00119 } 00120 00121 xComponent *= mScale; 00122 yComponent *= mScale; 00123 00124 QPolygonF line; 00125 line << point; 00126 line << QPointF( point.x() + xComponent, point.y() - yComponent ); 00127 mLineSymbol->renderPolyline( line, f, context.renderContext() ); 00128 } 00129 00130 void QgsVectorFieldSymbolLayer::startRender( QgsSymbolV2RenderContext& context ) 00131 { 00132 if ( mLineSymbol ) 00133 { 00134 mLineSymbol->startRender( context.renderContext() ); 00135 } 00136 00137 const QgsVectorLayer* layer = context.layer(); 00138 if ( layer ) 00139 { 00140 mXIndex = layer->fieldNameIndex( mXAttribute ); 00141 mYIndex = layer->fieldNameIndex( mYAttribute ); 00142 } 00143 else 00144 { 00145 mXIndex = -1; 00146 mYIndex = -1; 00147 } 00148 } 00149 00150 void QgsVectorFieldSymbolLayer::stopRender( QgsSymbolV2RenderContext& context ) 00151 { 00152 if ( mLineSymbol ) 00153 { 00154 mLineSymbol->stopRender( context.renderContext() ); 00155 } 00156 } 00157 00158 QgsSymbolLayerV2* QgsVectorFieldSymbolLayer::clone() const 00159 { 00160 QgsSymbolLayerV2* clonedLayer = QgsVectorFieldSymbolLayer::create( properties() ); 00161 if ( mLineSymbol ) 00162 { 00163 clonedLayer->setSubSymbol( mLineSymbol->clone() ); 00164 } 00165 return clonedLayer; 00166 } 00167 00168 QgsStringMap QgsVectorFieldSymbolLayer::properties() const 00169 { 00170 QgsStringMap properties; 00171 properties["x_attribute"] = mXAttribute; 00172 properties["y_attribute"] = mYAttribute; 00173 properties["scale"] = QString::number( mScale ); 00174 properties["vector_field_type"] = QString::number( mVectorFieldType ); 00175 properties["angle_orientation"] = QString::number( mAngleOrientation ); 00176 properties["angle_units"] = QString::number( mAngleUnits ); 00177 return properties; 00178 } 00179 00180 void QgsVectorFieldSymbolLayer::toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props ) const 00181 { 00182 element.appendChild( doc.createComment( "VectorField not implemented yet..." ) ); 00183 mLineSymbol->toSld( doc, element, props ); 00184 } 00185 00186 QgsSymbolLayerV2* QgsVectorFieldSymbolLayer::createFromSld( QDomElement &element ) 00187 { 00188 Q_UNUSED( element ); 00189 return NULL; 00190 } 00191 00192 void QgsVectorFieldSymbolLayer::drawPreviewIcon( QgsSymbolV2RenderContext& context, QSize size ) 00193 { 00194 if ( mLineSymbol ) 00195 { 00196 mLineSymbol->drawPreviewIcon( context.renderContext().painter(), size ); 00197 } 00198 } 00199 00200 QSet<QString> QgsVectorFieldSymbolLayer::usedAttributes() const 00201 { 00202 QSet<QString> attributes; 00203 if ( !mXAttribute.isEmpty() ) 00204 { 00205 attributes.insert( mXAttribute ); 00206 } 00207 if ( !mYAttribute.isEmpty() ) 00208 { 00209 attributes.insert( mYAttribute ); 00210 } 00211 return attributes; 00212 } 00213 00214 void QgsVectorFieldSymbolLayer::convertPolarToCartesian( double length, double angle, double& x, double& y ) const 00215 { 00216 //convert angle to degree and to north orientation 00217 if ( mAngleOrientation == CounterclockwiseFromEast ) 00218 { 00219 if ( angle <= 90 ) 00220 { 00221 angle = 90 - angle; 00222 } 00223 else 00224 { 00225 angle = 360 - angle + 90; 00226 } 00227 } 00228 00229 if ( mAngleUnits == Degrees ) 00230 { 00231 angle = angle * M_PI / 180.0; 00232 } 00233 00234 x = length * sin( angle ); 00235 y = length * cos( angle ); 00236 }