¿Qué tipo de capa estás usando?
Descubrí que con la capa de puntos estaba usando la siguiente línea devuelta None
mySymbol1 = QgsSymbolV2.defaultSymbol(myVectorLayer.geometryType())
Sin embargo, esto podría solucionarse reemplazándolo con una llamada al validatedDefaultSymbol
método desde el siguiente código. La premisa básica es llamar QgsSymbolV2.defaultSymbol()
y luego validar y, si es necesario, hacer correcciones.
Editar: Cambios para garantizar la compatibilidad con QGIS 1.8 y el maestro actual (27/01/13); extendido a una serie de ejemplos con un alcance más amplio.
Los fragmentos a continuación están formateados para ser pegados en la consola de Python y para ser aplicados a los Datos Naturales de la Tierra 1: 10 millones de lugares poblados disponibles desde aquí . Tenga en cuenta que los fragmentos posteriores dependen de las definiciones e importaciones del primero.
1) Este es un ejemplo de aplicación de categorías personalizadas pero codificadas a una capa determinada.
from PyQt4.QtGui import *
def validatedDefaultSymbol( geometryType ):
symbol = QgsSymbolV2.defaultSymbol( geometryType )
if symbol is None:
if geometryType == QGis.Point:
symbol = QgsMarkerSymbolV2()
elif geometryType == QGis.Line:
symbol = QgsLineSymbolV2 ()
elif geometryType == QGis.Polygon:
symbol = QgsFillSymbolV2 ()
return symbol
def makeSymbologyForRange( layer, min , max, title, color):
symbol = validatedDefaultSymbol( layer.geometryType() )
symbol.setColor( color )
range = QgsRendererRangeV2( min, max, symbol, title )
return range
def applySymbologyFixedDivisions( layer, field ):
rangeList = []
rangeList.append( makeSymbologyForRange( layer, -99, 999999.9, '<1 Million', QColor("Green") ) )
rangeList.append( makeSymbologyForRange( layer, 1000000, 10000000, '1-10 Million', QColor("Purple") ) )
rangeList.append( makeSymbologyForRange( layer, 10000000.1, 100000000, '>10 Million', QColor("Orange") ) )
renderer = QgsGraduatedSymbolRendererV2( field, rangeList )
renderer.setMode( QgsGraduatedSymbolRendererV2.Custom )
layer.setRendererV2( renderer )
targetField = 'POP_OTHER'
layer = QgsVectorLayer( 'C:/data/ne_10m_populated_places.shp', 'Fixed Divisions', 'ogr' )
if layer.isValid():
applySymbologyFixedDivisions( layer, targetField )
QgsMapLayerRegistry.instance().addMapLayers( [layer] )
2) Este ejemplo se aplica, a su vez, a cada uno de los modos estándar admitidos por QgsGraduatedSymbolRendererV2. El valor de las clases se tratará como una pista en lugar de como una regla según lo requiera cada modo específico. La línea setSizeScaleField se puede descomentar si se desea, sin embargo, los valores de la columna LABELRANK son demasiado grandes para verse bien en los niveles de zoom estándar.
def applyGraduatedSymbologyStandardMode( layer, field, classes, mode):
symbol = validatedDefaultSymbol( layer.geometryType() )
colorRamp = QgsVectorGradientColorRampV2.create({'color1':'255,0,0,255', 'color2':'0,0,255,255','stops':'0.25;255,255,0,255:0.50;0,255,0,255:0.75;0,255,255,255'})
renderer = QgsGraduatedSymbolRendererV2.createRenderer( layer, field, classes, mode, symbol, colorRamp )
#renderer.setSizeScaleField("LABELRANK")
layer.setRendererV2( renderer )
modes = { QgsGraduatedSymbolRendererV2.EqualInterval : "Equal Interval",
QgsGraduatedSymbolRendererV2.Quantile : "Quantile",
QgsGraduatedSymbolRendererV2.Jenks : "Natural Breaks (Jenks)",
QgsGraduatedSymbolRendererV2.StdDev : "Standard Deviation",
QgsGraduatedSymbolRendererV2.Pretty : "Pretty Breaks"
}
targetField = 'POP_OTHER'
classes = 6
for mode in modes.keys():
layer = QgsVectorLayer('C:/data/ne_10m_populated_places.shp', modes[mode] , 'ogr')
if layer.isValid():
applyGraduatedSymbologyStandardMode( layer, targetField, classes, mode)
QgsMapLayerRegistry.instance().addMapLayers( [layer] )
3) Este ejemplo demuestra la aplicación de divisiones personalizadas dinámicas. En este caso, las características se ordenan por valor, luego se dividen en grupos de modo que la suma de los valores en cada categoría sea igual. es decir, dividir la población mundial en tercios que viven en lugares de la población más pequeña / mediana / más grande.
def getSortedFloatsFromAttributeTable( layer, fieldName ):
provider = layer.dataProvider()
fieldIndex = provider.fieldNameIndex(fieldName)
provider.select( [fieldIndex] )
values = []
feature = QgsFeature()
while provider.nextFeature( feature ):
values.append( feature.attributeMap()[fieldIndex].toFloat()[0] )
values.sort()
return values
def arbitaryColor( amount, max ):
color = QColor()
color.setHsv( 240 * amount / float( max - 1 ), 255, 255 )
return color
def makeGraduatedRendererFromDivisionsList( layer, fieldName, divisions ):
classes = len( divisions ) - 1
rangeList = []
for i in range( classes ):
label = str( divisions[i] ) + " < X < " + str( divisions[i+1] )
rangeList.append( makeSymbologyForRange( layer, divisions[i] , divisions[i+1], label, arbitaryColor( i, classes ) ) )
renderer = QgsGraduatedSymbolRendererV2( fieldName, rangeList )
renderer.setMode( QgsGraduatedSymbolRendererV2.Custom )
return renderer
def applySymbologyEqualTotalValue( layer, classes, fieldName):
values = getSortedFloatsFromAttributeTable( layer, fieldName )
total = sum( values )
step = total / float( classes )
nextStep = step
divisions = [ values[0] ]
runningTotal = 0
for value in values:
runningTotal += value
if runningTotal >= nextStep:
divisions.append( value )
nextStep += step
if divisions[-1] != values[-1]:
divisions.append(values[-1])
renderer = makeGraduatedRendererFromDivisionsList( layer, fieldName, divisions )
layer.setRendererV2( renderer )
targetField = 'POP_OTHER'
classes = 3
layer = QgsVectorLayer( 'C:/data/ne_10m_populated_places.shp', 'Equal Total Value', 'ogr')
if layer.isValid():
applySymbologyEqualTotalValue(layer, classes, targetField)
QgsMapLayerRegistry.instance().addMapLayers( [layer] )