Áp dụng trình kết xuất tốt nghiệp trong PyQGIS? [đóng cửa]


9

Chỉ cần cố gắng chạy mã sau đây đã được đưa ra trong sách dạy nấu ăn pyqgis để tạo ra hệ thống ký hiệu màu tốt nghiệp (ví dụ như với 2 lớp)

Tôi xác định thông tin nguồn cho shapefile nhưng khi tôi chạy thực thi mã trong plugin thử nghiệm của mình, nó chỉ thêm lớp mà không cần classifiying. Chỉ cần thêm như bình thường, tất cả các polylines xuất hiện như nhau.

Bất kỳ giải pháp hoặc mã / phương pháp làm việc?

liên kết đến mã trong sách dạy nấu ăn http://www.qgis.org/pyqgis-cookbook/vector.html#graduated-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) 

Mã của Kelly hoạt động hoàn hảo.

Tuy nhiên, tôi nhận thấy rằng cả mã (một mã tôi đã nhập trong tin nhắn đầu tiên của tôi và mã của bạn trong tin nhắn thứ 2) KHÔNG hoạt động trong QGIS v1.7.3 mà hoạt động trong QGIS v1.8.0. Tôi nghĩ rằng đây là một lỗi (?) Đã được giải quyết trong v1.8.0

Và một câu hỏi nữa;

Bạn có bất kỳ mã mẫu nào để phân loại (phá vỡ tự nhiên, Jenks) của "num_attribution_field" dựa trên số lượng lớp đã cho không (ví dụ: không có lớp nào sẽ là biến trong mã, nói "n" và tôi sẽ chuyển nó từ GUI GUI tức là n = spinBox.value ())


1
Vui lòng đọc trợ giúp về cách định dạng mã cho trang web này. Tôi đã sửa nó cho bạn lần này.
Nathan W

Câu trả lời:


19

Bạn đang sử dụng loại lớp nào?

Tôi thấy rằng với lớp điểm tôi đang sử dụng dòng sau được trả về None

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

Tuy nhiên, điều này có thể được khắc phục bằng cách thay thế nó bằng một cuộc gọi đến validatedDefaultSymbolphương thức từ mã bên dưới. Tiền đề cơ bản là gọi QgsSymbolV2.defaultSymbol()và sau đó xác nhận và nếu cần thực hiện chỉnh sửa.

Chỉnh sửa: Thay đổi để đảm bảo khả năng tương thích với cả QGIS 1.8 và chủ hiện tại (27/01/13); mở rộng đến một loạt các ví dụ với phạm vi rộng hơn.

Các đoạn bên dưới được định dạng để dán vào bảng điều khiển python và được áp dụng cho Dữ liệu địa điểm tự nhiên 1: 10m có sẵn từ đây . Lưu ý rằng các đoạn mã sau có phụ thuộc vào định nghĩa và nhập từ từ đầu tiên.

1) Đây là một ví dụ về việc áp dụng các danh mục tùy chỉnh nhưng được mã hóa cứng cho một lớp nhất định.

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) Ví dụ này áp dụng lần lượt từng chế độ tiêu chuẩn được hỗ trợ bởi QssGraduatedSymbolRendererV2. Giá trị lớp sẽ được coi là một gợi ý thay vì quy tắc theo yêu cầu của từng chế độ cụ thể. Dòng setSizeScaleField có thể không bị thiếu nếu muốn, tuy nhiên, các giá trị của cột LABELRANK quá lớn để có thể nhìn tốt ở các mức thu phóng tiêu chuẩn.

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) Ví dụ này cho thấy việc áp dụng các bộ phận tùy chỉnh động. Trong trường hợp này, các tính năng được sắp xếp theo giá trị, sau đó chia thành các nhóm sao cho tổng các giá trị trong mỗi danh mục bằng nhau. tức là chia dân số thế giới thành một phần ba sống ở những nơi có dân số nhỏ nhất / trung bình / lớn nhất.

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

Tôi muốn nói một vài điều. Đầu tiên, nếu bạn đang cố gắng tạo lại câu trả lời ở trên từ @Kelly, hãy đảm bảo chọn tệp "tải xuống các địa điểm dân cư" từ liên kết của Kelly. Nếu bạn muốn xem phiên bản cập nhật của mã này cho PyQGIS 3 / QGIS 3.x, hãy xem chủ đề này: gis.stackexchange.com/questions/303990/. Tôi đang sử dụng một shapefile khác, hãy ghi nhớ. Nhưng mã rất giống nhau và bạn sẽ có thể làm theo nó. Một vài phương pháp và mọi thứ đã thay đổi cho QGIS 3.
Erich Purpur
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.