PyQGISで段階的なレンダラーを適用しますか?[閉まっている]


9

単にpyqgisクックブックに記載されている次のコードを実行して、段階的な色のシンボルを作成しようとしています(2つのクラスの例のように)

シェープファイルのソース情報を定義しますが、テストプラグイン内でコードを実行すると、分類せずにレイヤーが追加されるだけです。通常どおり追加するだけで、すべてのポリラインが同じように表示されます。

解決策または作業コード/メソッドはありますか?

クックブックのコードへのリンク http://www.qgis.org/pyqgis-cookbook/vector.html#gradd-symbol-renderer

from qgis.core import  (QgsVectorLayer, QgsMapLayerRegistry, QgsGraduatedSymbolRendererV2, QgsSymbolV2,QgsRendererRangeV2)

myVectorLayer = QgsVectorLayer('C:/my_test_shape_file.shp', 'test_shp_file', 'ogr')

myTargetField = 'target_field'
myRangeList = []
myOpacity = 1

# Make our first symbol and range...
myMin = 0.0
myMax = 50.0
myLabel = 'Group 1'
myColour = QtGui.QColor('#ffee00')
mySymbol1 = QgsSymbolV2.defaultSymbol(myVectorLayer.geometryType())
mySymbol1.setColor(myColour)
mySymbol1.setAlpha(myOpacity)
myRange1 = QgsRendererRangeV2(myMin, myMax, mySymbol1, myLabel)
myRangeList.append(myRange1)

#now make another symbol and range...
myMin = 50.1
myMax = 100
myLabel = 'Group 2'
myColour = QtGui.QColor('#00eeff')
mySymbol2 = QgsSymbolV2.defaultSymbol(myVectorLayer.geometryType())
mySymbol2.setColor(myColour)
mySymbol2.setAlpha(myOpacity)
myRange2 = QgsRendererRangeV2( myMin, myMax, mySymbol2, myLabel)
myRangeList.append(myRange2)

myRenderer = QgsGraduatedSymbolRendererV2('', myRangeList)
myRenderer.setMode(QgsGraduatedSymbolRendererV2.EqualInterval)
myRenderer.setClassAttribute(myTargetField)
myVectorLayer.setRendererV2(myRenderer)
QgsMapLayerRegistry.instance().addMapLayer(myVectorLayer) 

@ケリーのコードは完全に動作します。

ただし、両方のコード(最初のメッセージに入力したコードと2番目のメッセージに入力したコード)の両方がQGIS v1.7.3では機能せず、QGIS v1.8.0では機能することに気付きました。これはv1.8.0ですでに解決されたバグ(?)だと思います

そしてもう一つ質問。

与えられたクラスの数に基づいた「numeric_attribute_field」の(自然な区切り、Jenks)分類のサンプルコードはありますか(つまり、「n」のように、コード内で変数になるクラスはありません。それを、プラグインGUIすなわちn = spinBox.value())


1
このサイトのコードをフォーマットする方法のヘルプを読んでください。今回は修正しました。
Nathan W

回答:


19

どのようなレイヤーを使用していますか?

ポイントレイヤーでは、次の行を使用していたことがわかりました。 None

mySymbol1 = QgsSymbolV2.defaultSymbol(myVectorLayer.geometryType())

ただし、これをvalidatedDefaultSymbol以下のコードからのメソッドの呼び出しに置き換えることで修正できます。基本的な前提は、電話QgsSymbolV2.defaultSymbol()してから検証し、必要に応じて修正することです。

編集:QGIS 1.8と現在のマスターの両方との互換性を確保するための変更(27/01/13); より広い範囲の一連の例に拡張されました。

以下のスニペットは、Pythonコンソールに貼り付けられ、Natural Earth Data 1:10m Populated Placesに適用されるようにフォーマットされていますここから入手できます。後のスニペットは最初の定義からの定義とインポートに依存していることに注意してください。

1)これは、カスタムであるがハードコードされたカテゴリーを特定のレイヤーに適用する例です。

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)この例は、QgsGraduatedSymbolRendererV2によってサポートされる各標準モードに適用されます。クラスの値は、特定のモードごとに必要なルールではなく、ヒントとして扱われます。必要に応じて、setSizeScaleField行のコメントを解除できますが、LABELRANK列の値が大きすぎて、標準のズームレベルでは見栄えがよくありません。

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)この例は、動的カスタム分割の適用を示しています。この場合、機能は値で並べ替えられ、各カテゴリの値の合計が等しくなるようにグループに分割されます。つまり、世界の人口を3分の1に分割し、人口の最小、中、最大の場所に住んでいます。

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] ) 

いくつかお話ししたいと思います。まず、@ Kellyから上記の回答を再作成しようとしている場合は、Kellyのリンクから「ダウンロード済みの場所をダウンロード」ファイルを選択してください。PyQGIS 3 / QGIS 3.xのこのコードの更新バージョンを確認したい場合は、次のスレッドを参照してください。gis.stackexchange.com/ questions / 303990 / 別のシェープファイルを使用していることに注意してください。しかし、コードは非常に似ており、あなたはそれに従うことができるはずです。いくつかのメソッドと、物事はQGIS 3.変更されました
エーリヒPurpur
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.