PyQGIS

本文档详细介绍了使用PyQGIS进行地图层操作的方法,包括获取地图层名称列表、编辑属性表、添加栅格图层、重投影、创建矢量文件及裁剪栅格图层等关键功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Getting list of layer names using PyQGIS?

from qgis.core import QgsProject
names = [layer.name() for layer in QgsProject.instance().mapLayers().values()]
print(names)

this produces a list of layers in the current project:

['GoogleSat', 'MyPointsLayer', 'Roads', 'House_numbers']

Edit shapefile attibute

layer = iface.activeLayer()
selection = layer.selectedFeatures()
layer.startEditing()
for feature in selection:
  layer.changeAttributeValue(feature.id(), 1, 0)
layer.commitChanges()

Add raster

from qgis.analysis import QgsRasterCalculator, QgsRasterCalculatorEntry
# Add raster 
rasterpath  = r'C:\Users\wgy\Desktop\fire\test\lc08_roi.tif'
bohLayer  = QgsRasterLayer(rasterpath, 'boh')
if not bohLayer.isValid():  print("Layer failed to load!")
QgsProject.instance().addMapLayer(bohLayer) # Load raster layer into canvas if needed
entries = []
ras = QgsRasterCalculatorEntry()
ras.ref = 'boh@1'
ras.raster = bohLayer
ras.bandNumber = 1
entries.append(ras)
outputfile_path = r'C:\Users\wgy\Desktop\fire\test\tmp.tif'
calc = QgsRasterCalculator( 'boh@1 > 10000', outputfile_path, 'GTiff', bohLayer.extent(), bohLayer.width(), bohLayer.height(), entries )
calc.processCalculation()

Do the reproject to a raster data:

rlayer = QgsProject.instance().mapLayersByName('tmp')[0]
parameter = {'INPUT': rlayer,\
    'TARGET_CRS': 'EPSG:32610', \
    'OUTPUT': r'C:/Users/wgy/Desktop/fire/test/tmp1.tif'}
processing.run('qgis:reprojectlayer', parameter)

the tutorial of raster calculator

outLayerName = 'rndbr_tmp'
lyr = QgsProject.instance().mapLayersByName(outLayerName)[0]
QgsProject.instance().removeMapLayer(lyr.id())
layername = 'ca3958812158520171009_20171004_20171105_rdnbr'
dir_path = r'C:\Users\wgy\Desktop\literature\forestFire\postFire\c\Landsat5TMSardinia\camp\DATA\2017\fire_level_tar_files'
lyr = QgsProject.instance().mapLayersByName(layername)[0]
entries = []
outputfile_path = os.path.join(dir_path, 'tiftif.tif')
ras = QgsRasterCalculatorEntry()
ras.ref = layername + '@1'
ras.raster = lyr
ras.bandNumber = 1
entries.append(ras)
calc = QgsRasterCalculator( ras.ref+'>400', outputfile_path, 'GTiff', lyr.extent(), lyr.width(), lyr.height(), entries )
calc.processCalculation()
bohLayer  = QgsRasterLayer(outputfile_path, outLayerName)
if bohLayer.isValid():
    QgsProject.instance().addMapLayer(bohLayer)

open the hdf5 file

import os, gdal
import numpy as np
## List input raster files
os.chdir(r'C:\Users\wgy\Desktop\fire\test\goesrVSmod14a1_cloudMask')
rasterFiles = os.listdir(os.getcwd())
dataset = gdal.Open(rasterFiles[0], gdal.GA_ReadOnly)
# Open raster layer
rlayer = gdal.Open(hdflayer.GetSubDatasets()[0][0], gdal.GA_ReadOnly)
raster_data = rlayer.ReadAsArray(0, 0, rlayer.RasterXSize, rlayer.RasterYSize)
for i in np.arange(raster_data.shape[0]):
    print(np.unique(raster_data[i,:,:]))
#*****************************************************
# read the nc file using netCDF4
import netCDF4
import os
dir_path = r'C:/Users/wgy/Desktop/fire/test/'
input_raster = r'OR_ABI-L1b-RadC-M3C07_G16_s20183121842181_e20183121844565_c20183121845003.nc'
database = netCDF4.Dataset(os.path.join(dir_path, input_raster))
raster = database.variables['Rad'] # temperature variable
raster = raster[:]
#*****************************************************
# read the TIF using rasterio
import rasterio as rio
import numpy as np
dir_path = 'C:/Users/wgy/Desktop/fire/test/'
file_name = 'c07_rad_roi.tif'
raster = rio.open(os.path.join(dir_path, file_name))
data = raster.read(1)
for i in np.arange(data.shape[0]):
    for j in np.arange(data.shape[1]):
        tmp = data[i,j]!=16383
        print('%d'%tmp, end='')
        print(' ', end='')
        if j == data.shape[1]-1:
            print('')

save as a tif file

import gdal, osr, netCDF4, os
import numpy as np
dir_path = r'C:/Users/wgy/Desktop/fire/test/University of Wisconsin Baseline Fit/'
input_raster = 'global_emis_inf10_location.nc'
file_path = dir_path + input_raster
dataset = gdal.Open("NETCDF:{0}:{1}".format(file_path, 'lat'))
band = dataset.GetRasterBand(1)
raster_lat = dataset.ReadAsArray(0, 0, dataset.RasterXSize, dataset.RasterYSize).astype(np.float)
raster_lat = np.swapaxes(raster_lat, 0, 1)
raster_lat = np.flipud(raster_lat)
dataset = gdal.Open("NETCDF:{0}:{1}".format(file_path, 'lon'))
band = dataset.GetRasterBand(1)
raster_lon = dataset.ReadAsArray(0, 0, dataset.RasterXSize, dataset.RasterYSize).astype(np.float)
raster_lon = np.swapaxes(raster_lon, 0, 1)
raster_lon = np.flipud(raster_lon)
input_raster = 'global_emis_inf10_monthFilled_MYD11C3.A2016306.041.nc'
# emis1, emis2, emis3, ..., emis10, emis_flag
file_path = dir_path + input_raster
dataset = netCDF4.Dataset(file_path)
raster_data = dataset.variables['emis1'][:]
raster_data = np.swapaxes(raster_data, 0, 1)
raster_data = np.flipud(raster_data)
outputfile_path = os.path.join(dir_path, 'uw_bf_emis306_01.tif')
driver = gdal.GetDriverByName("GTiff")
dst_ds = driver.Create(outputfile_path,
                       band.YSize,
                       band.XSize,
                       1,
                       band.DataType)
#setting extension of output raster
# top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution
geotransform = [0 for _ in np.arange(6)]
geotransform[0] = raster_lon[-1, -1]    # xOrigin
geotransform[1] = 0.05                # pixelWidth
geotransform[3] = raster_lat[0, -1]    # yOrigin
geotransform[5] = 0.05                # pixelHeight
dst_ds.GetRasterBand(1).WriteArray(raster_data)
dst_ds.SetGeoTransform(geotransform)
# setting spatial reference of output raster 
srs = osr.SpatialReference()
srs.ImportFromProj4('+proj=longlat +datum=WGS84 +no_defs')
dst_ds.SetProjection(srs.ExportToWkt())
dst_ds = None  #Close output raster dataset 
dataset = None  #Close main raster dataset

save a tif

import gdal,osr
import numpy as np
import struct
def changeRasterValues(band):
    fmttypes = {'Byte':'B', 'UInt16':'H', 'Int16':'h', 'UInt32':'I', 'Int32':'i', 'Float32':'f', 'Float64':'d'}
    data_type = band.DataType
    BandType = gdal.GetDataTypeName(band.DataType)
    raster = []
    for y in range(band.YSize):
        scanline = band.ReadRaster(0, y, band.XSize, 1, band.XSize, 1, data_type)
        values = struct.unpack(fmttypes[BandType] * band.XSize, scanline)
        raster.append(values)
    raster = [list(item) for item in raster]
    tmp = np.asarray(raster)
    # changing raster values
    for i, item in enumerate(raster):
        for j, value in enumerate(item):
            pass#raster[i][j] = int(raster[i][j] * 1000)
    raster = np.asarray(raster)  #transforming list in array
    return raster

dir_path = r'C:/Users/wgy/Desktop/fire/test/'
input_file = 'c07_rad_wgs84.tif'
dataset = gdal.Open(os.path.join(dir_path, input_file))
band = dataset.GetRasterBand(1)
geotransform = dataset.GetGeoTransform()  # Get raster metadata
outputfile_path = os.path.join(dir_path, 'c07_rad_lat_lon.tif')  # Set name of output raster
# Create gtiff file with rows and columns from parent raster 
driver = gdal.GetDriverByName("GTiff")
raster1 = dataset.ReadAsArray(0, 0, dataset.RasterXSize, dataset.RasterYSize).astype(np.float)
raster = changeRasterValues(band)
dst_ds = driver.Create(outputfile_path, 
                       band.XSize, 
                       band.YSize, 
                       number_band, 
                       band.DataType)
#writting output raster
# coordinates in grid
import rasterio
bounds = rasterio.open(os.path.join(dir_path, input_file)).bounds
lon = np.linspace(bounds[0], bounds[2], band.XSize+1)
lat = np.linspace(bounds[3], bounds[1], band.YSize+1)
latC, lonC = 0.5 * (lat[:-1] + lat[1:]), 0.5 * (lon[:-1] + lon[1:])  # center points
latgrid, longrid = np.meshgrid(latC, lonC)  # make grid
dst_ds.GetRasterBand(1).WriteArray(raster)
#setting extension of output raster
# top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution
dst_ds.SetGeoTransform(geotransform)
# setting spatial reference of output raster 
srs = osr.SpatialReference(wkt = prj)  # prj???
dst_ds.SetProjection(srs.ExportToWkt())
dst_ds = None  #Close output raster dataset 
dataset = None  #Close main raster dataset

reprojection

dir_path = r'C:/Users/wgy/Desktop/fire/test/'
input_raster = r'c14_rad.tif'
input_raster = os.path.join(dir_path, input_raster)
output_raster = r"c14_rad_epsg4326.tif"
output_raster = os.path.join(dir_path, output_raster)
setting = 'gdalwarp' + \
          ' ' + '-s_srs EPSG:4326' + \
          ' ' + '-t_srs EPSG:4326' + \
          ' ' + '-r near' + \
          ' ' + '-of GTiff' + \
          ' ' + input_raster + \
          ' ' + output_raster
os.system(setting)

create shp (point)

from qgis.core import QgsFields, QgsFeature
fn = r'C:/Users/wgy/Desktop/fire/test/newpoints.shp'
fn = r'C:\Users\wgy\Desktop\literature\forestFire\火后\c\Landsat5TMSardinia\qinyuan\newpoints.shp'
layerFields = QgsFields()
layerFields.append(QgsField('id', QVariant.Int))
layerFields.append(QgsField('value', QVariant.Double))
layerFields.append(QgsField('name', QVariant.String))
writer = QgsVectorFileWriter(fn, 'UTF-8', layerFields, QgsWkbTypes.Point,\
         QgsCoordinateReferenceSystem('EPSG:26912'), 'ESRI Shapefile')
feat = QgsFeature()
feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(455618, 463221)))
feat.setAttributes([1, 1.1, 'name'])
writer.addFeature(feat)
iface.addVectorLayer(fn, 'points', 'ogr')
del(writer)

create shp (polygen)

import numpy as np
from qgis.core import QgsFields, QgsFeature
fn = r'C:\Users\wgy\Desktop\literature\forestFire\火后\c\Landsat5TMSardinia\qinyuan\mask.shp'
layerFields = QgsFields()
layerFields.append(QgsField('id', QVariant.Int))
layerFields.append(QgsField('name', QVariant.String))
writer = QgsVectorFileWriter(fn, 'UTF-8', layerFields, QgsWkbTypes.Point,\
         QgsCoordinateReferenceSystem('EPSG:32649'), 'ESRI Shapefile')

rlayer = iface.setActiveLayer()
width = rlayer.width()
height = rlayer.height()
pixelX = rlayer.rasterUnitsPerPixelX()
pixelY = rlayer.rasterUnitsPerPixelY()
for i in np.arange(width):
    for j in np.arange(height):
        x = 618805.34299999999348074
        y = 4077616.23410000000149012
        x_cur = x + pixelX*i + pixelX/2
        y_cur = y - pixelY*j - pixelY/2
        feat = QgsFeature()
        feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(x_cur, y_cur)))
        feat.setAttributes([1, 'roi'])
        writer.addFeature(feat)

iface.addVectorLayer(fn, 'points', 'ogr')
del(writer)

clip raster with a shapefile

import os
import numpy as np
for i in np.arange(1, 12):
    dir_path = r'C:\Users\wgy\Desktop\literature\forestFire\火后\c\Landsat5TMSardinia\qinyuan\post\LC08_L1TP_125035_20190916_20190925_01_T1'
    input_raster = r'LC08_L1TP_125035_20190916_20190925_01_T1_B%d.tif' % i
    input_raster = os.path.join(dir_path, input_raster)
    output_raster = r"LC08_L1TP_125035_20190916_20190925_01_T1_B%d_roi.tif" % i
    output_raster = os.path.join(dir_path, output_raster)
    input_vector = r"roi.shp"
    input_vector = os.path.join(os.path.dirname(os.path.dirname(dir_path)), input_vector)
    if input_raster.split('.')[-1] == 'nc':
        input_raster_tmp = 'NETCDF:"{0}":{1}'.format(input_raster, 'Rad')
    elif input_raster.split('.')[-1] == 'tif':
        input_raster_tmp = '{0}'.format(input_raster)
    
    setting = 'gdalwarp' + \
        ' -of GTiff' + \
        ' -cutline ' + input_vector + \
        ' -cl roi'  + ' -crop_to_cutline' + \
        ' ' + input_raster_tmp + \
        ' ' + output_raster
    
    os.system(setting)

clip raster by mask layer

import os
def clip_raster_by_vector(input_raster, input_vector, output_raster, overwrite=False):
    if overwrite:
        if os.path.isfile(output_raster):
            os.remove(output_raster)
    if not os.path.isfile(input_raster):
        print ("File doesn't exists", input_raster)
        return None
    else:
        if input_raster.split('.')[-1] == 'nc':
            input_raster_tmp = "NETCDF:{0}:{1}".format(input_raster, 'Rad')
        else:
            input_raster_tmp = input_raster
        dataset = gdal.Open(input_raster_tmp)
        band = dataset.GetRasterBand(1)
        data_type = band.DataType
        params = {'INPUT': input_raster,
                  'MASK': input_vector,
                  'NODATA': 0,
                  'ALPHA_BAND': False,
                  'CROP_TO_CUTLINE': True,
                  'KEEP_RESOLUTION': True,
                  'OPTIONS': 'COMPRESS=LZW',
                  'DATA_TYPE': data_type,  # Byte
                  'OUTPUT': output_raster,
                  }
        feedback = qgis.core.QgsProcessingFeedback()
        alg_name = 'gdal:cliprasterbymasklayer'
        result = processing.run(alg_name, params, feedback=feedback)
        return result
dir_path = r'C:/Users/wgy/Desktop/fire/test/'
input_raster = r'OR_ABI-L1b-RadC-M3C07_G16_s20183121842181_e20183121844565_c20183121845003.nc'
input_raster = os.path.join(dir_path, input_raster)
output_raster = r"c07_rad_roi.tif"
output_raster = os.path.join(dir_path, output_raster)
input_vector = r"roi.shp"
input_vector = os.path.join(dir_path, input_vector)
result = clip_raster_by_vector(input_raster, input_vector, output_raster, overwrite=True)
print('result =', result)

#***********How to show a cube view of hyperspectral image??*********
from osgeo import gdal
src_filepath='rimData_int.tif'
src_fname = 'file.tif'
dst_fname = src_filepath[:-4]+'_show.tif'
driver = gdal.GetDriverByName('LAN')  #???
sds = gdal.Open(src_filepath)


# # load the data
# result = []
# for i in range(1,225):
#   band = sds.GetRasterBand(1)
#   band1 = band.ReadAsArray()
#   print(i, type(band1), band1.dtype, band1.shape)
#   band1 = np.expand_dims(band1, axis=2)*10000
#   band1 = band1.astype(np.int16)
#   if i==1:
#     result = band1
#   else:
#     result = np.concatenate([result, band1], axis=2)
# print(result.shape)
# geotransform = list(sds.GetGeoTransform())  # Get raster metadata
# prj = sds.GetProjection()
# outputfile_path = os.path.join('rimData_int.tif')  # Set name of output raster  
# # Create gtiff file with rows and columns from parent raster 
# driver = gdal.GetDriverByName("GTiff")
# dst_ds = driver.Create(outputfile_path,
#                     result.shape[1],
#                     result.shape[0],
#                     224,
#                     gdal.GDT_Int16)
# #writting output raster
# for i in range(1,225):
#   dst_ds.GetRasterBand(i).WriteArray(result[:,:,i-1])
# #setting extension of output raster
# # top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution
# dst_ds.SetGeoTransform(geotransform)
# # setting spatial reference of output raster 
# srs = osr.SpatialReference(wkt = prj)  # prj???
# dst_ds.SetProjection(srs.ExportToWkt())
# dst_ds = None  #Close output raster dataset 
# assert 1==2


# the following Show errors!!!
dst = driver.CreateCopy(dst_fname, sds)
from spectral import view_cube,open_image,imshow
img = open_image(dst)
view = imshow(img, (29, 19, 9))
#view_cube(img, bands=[29, 19, 9])
dst = None  # close dataset; the file can now be used by other processes
'''


### PyQGIS 中 `setRenderer` 的用法 在 PyQGIS 中,`setRenderer` 方法用于为图层设置渲染器(renderer)。渲染器决定了矢量图层或栅格图层如何显示在地图画布上。以下是关于该方法的具体说明以及其实现方式。 #### 渲染器的作用 渲染器定义了地理数据的可视化样式。对于矢量图层,常见的渲染器有单符号渲染器 (`SingleSymbolRenderer`) 和分类渲染器 (`CategorizedSymbolRenderer`) 等[^1]。通过调用 `setRenderer` 方法可以更改这些渲染逻辑并更新图层外观。 #### 设置渲染器的方法 要使用 `setRenderer` 方法,通常需要先创建一个合适的渲染对象实例,再将其应用到目标图层。下面是一个完整的例子展示如何配置一种简单的类别化渲染: ```python from qgis.core import QgsVectorLayer, QgsFeature, QgsField, QgsCategorizedSymbolRenderer, QgsSymbol, QgsRendererCategory # 创建虚拟内存中的矢量图层作为演示用途 layer = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "example_layer", "memory") # 定义一些测试要素加入图层中 provider = layer.dataProvider() features = [ QgsFeature(layer.fields()), QgsFeature(layer.fields()) ] for i, feat in enumerate(features): feat.setAttribute('id', i + 1) provider.addFeatures([feat]) # 初始化类别化的符号列表 categories = [] symbols = [QgsSymbol.defaultSymbol(layer.geometryType()) for _ in range(2)] # 自定义第一个类别的颜色 symbols[0].setColor(QColor("blue")) category_blue = QgsRendererCategory(1, symbols[0], "First Category") # id=1对应蓝色 categories.append(category_blue) # 自定义第二个类别的颜色 symbols[1].setColor(QColor("red")) category_red = QgsRendererCategory(2, symbols[1], "Second Category") # id=2对应红色 categories.append(category_red) # 构建最终的分类渲染器并将它赋给图层 renderer = QgsCategorizedSymbolRenderer('id', categories) if renderer is not None: layer.setRenderer(renderer) # 刷新视图以便看到效果变化 layer.triggerRepaint() ``` 上述脚本展示了如何基于字段值来分配不同样式的图标表示不同的特征组。这里我们构建了一个具有两个类别的分类渲染器,并分别赋予它们特定的颜色属性。 #### 注意事项 当修改任何现有图层上的渲染参数之后,记得调用 `triggerRepaint()` 函数通知 QGIS 更新界面以反映最新的改变。 #### 总结 以上就是有关于 PyQGIS 中利用 `setRenderer` 进行自定义渲染的一个基本指南及其实际操作案例分享。这使得开发者能够灵活控制 GIS 数据的表现形式满足具体需求场景下的呈现标准。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值