10 栅格的使用

这一章整体上还是相对简单,主要是在以前的研究中使用了很多内容进行栅格数据的批处理等,所以还是要多练习使用。

10.1 介绍

栅格呈现一种独特的空间数据类型,许多地理处理工具专门设计用于利用栅格数据结构。 ArcPy 包括 arcpy.sa (Spatial Analyst) 和 arcpy.ia (Image Analyst) 模块,它们提供对许多地理处理工具的访问以处理影像和栅格数据。本章说明如何使用 ArcPy 处理栅格对象、列出和描述栅格以及执行栅格数据分析和处理。 ArcPy 还将地图代数集成到 Python 环境中。还涵盖了 arcpy.sa 和 arcpy.ia 模块的其他函数和类,包括支持工具参数的特定类、迭代单个像元的栅格像元迭代器以及复制栅格函数功能的函数。

10.2 理解栅格数据

在栅格数据模型中,地球表面表示为由相同大小的单元格组成的网格,也称为像素。每个单元代表地球的一小部分。细胞的属性告诉我们关于地球那部分的一些事情。
图像和栅格这两个术语通常可以互换使用,但它们并不完全相同。图像是一种二维图形表示,例如航空照片或卫星图像。栅格是用于以像元形式存储信息的数据模型。在 GIS 中,影像存储为栅格数据集。栅格数据集是存储在磁盘或地理数据库中的栅格空间数据模型。
但是,许多栅格数据集并不代表影像,例如高程数据或降雨量的栅格。实际上,所有图像都是光栅,但并非所有光栅都是图像。许多适用于影像的工具也适用于其他类型的栅格,因此区别对于学习如何执行栅格数据集的处理和分析并不总是至关重要的。
一些栅格仅存储有关单元的一条信息,例如,高程栅格可能仅以米为单位存储高程值。此信息可以存储在单个栅格波段中,该波段表示栅格数据集中的一个图层。其他栅格存储有关细胞的多条信息——例如,卫星图像可以捕获不同波长的信息。此信息需要多个波段。

在栅格数据集中,每个像元都包含该位置的属性信息。通常,该属性是通过取每个单元占据的整个空间的平均值来确定的。例如,如果 Landsat 图像的像元大小为 30 米,则每个像元对应于地面上 30 x 30 米的区域。为给定单元记录的属性(例如反射率值)表示该区域 30 x 30 米的平均值。因此,具有较小像元的栅格(覆盖地面较小的区域)可提供更多细节。栅格的像元大小也称为栅格的空间分辨率。小单元尺寸意味着更多细节,这意味着更高的空间分辨率。其他类型的分辨率包括光谱分辨率(波段数)、时间分辨率(频率)和辐射分辨率(传感器的灵敏度)。
根据数据所表示的内容,有几种不同的栅格数据类型。它们包括连续栅格,用于海拔或降雨等现象;**离散栅格,用于土地利用和土壤等现象;图像,使用飞机、无人机和卫星获得。影像是一种特殊形式的连续栅格,因为像元值通常以连续比例存储反射率值。
栅格数据集可以多种
格式存储,包括独立格式,例如 TIFF(.tif 文件扩展名)和 Esri GRID(无文件扩展名)。**栅格数据集也可以存储在地理数据库中。栅格数据集是组织成一个或多个波段的任何有效栅格格式。可以将多个栅格数据集附加在一起以创建更大区域的镶嵌数据集。镶嵌数据集是存储在目录中的栅格数据集的集合。
ArcGIS Pro 具有许多用于管理、分析、可视化和共享栅格数据的功能。通过使用 ArcPy 在 Python 脚本中使用这些功能有多种方法。这些方法包括:
1、许多栅格和影像数据管理任务可以使用 ArcPy 函数完成。
例如,ArcGIS Pro 中的数据管理工具箱包括一个栅格工具集,其中包含数十种地理处理工具,用于对栅格数据进行基本操作,包括处理栅格数据集、使用镶嵌和管理栅格数据集的属性。可以在其他工具箱和工具集中找到其他几个用于栅格数据的工具,例如,用于栅格和其他投影格式之间的数据转换。
2、ArcGIS Pro 的 Spatial Analyst 和 Image Analyst 扩展模块包括许多其他用于处理影像和栅格数据的专用地理处理工具。大多数这些工具分别作为 arcpy.sa 和 arcpy.ia 模块的功能提供。
3、arcpy.sa 和 arcpy.ia 的其他函数复制了 ArcGIS Pro 栅格函数中的功能。栅格函数包括地理处理工具中没有的功能。
4、可以将栅格数据集转换为 NumPy 数组以在其他 Python 包中使用。

10.3 使用 Spatial Analyst 和 Image Analyst 模块

ArcGIS Pro 包括两个用于处理影像和栅格数据的扩展模块:Spatial Analyst 和 Image Analyst。这些扩展的功能分别使用 arcpy .sa 和 arcpy.ia 模块在 ArcPy 中实现。这些模块提供的功能与其各自工具箱中的工具大致相同。例如,您可以使用 arcpy .sa 模块来运行坡度工具。此外,arcpy.sa 和 arcpy.ia 模块将地图代数直接集成到 Python 环境中。地图代数是一种通过应用运算符创建新的栅格图层来定义组合栅格图层的语法的语言。这两个模块为地图代数运算符提供支持。这些运算符与栅格计算器等地理处理工具中使用的运算符相同,例如加法 (+)、乘法 (*) 和布尔与 (&)。
Spatial Analyst 和 Image Analyst 模块的功能有很大的重叠。两个模块共有的工具包括地图代数、叠加、图像分类和统计分析工具。 Spatial Analyst 独有的工具包括许多通用栅格分析工具(例如,用于距离分析、插值、重新分类等的工具),以及更多特定于领域的工具(例如,用于地下水、水文和太阳辐射的工具)。 Image Analyst 独有的工具包括用于深度学习和运动图像分析的专用工具。所有这些工具都可以通过 arcpy.sa 和 arcpy.ia 模块在 ArcPy 中使用。
结合起来,这两个模块提供对许多栅格地理处理工具的访问。考虑以下运行坡度工具的代码:

import arcpy
elev = arcpy.Raster("C:/Raster/elevation")
outraster = arcpy.sa.Slope(elev)

示例代码使用 Raster 类创建一个栅格对象;下一节将更详细地讨论这一点。请注意,坡度工具是使用 arcpy.sa.Slope 调用的,它似乎遵循用于所有工具的常规语法:arcpy>.。但是,替代的 arcpy。
_语法不适用于此处,并且 arcpy .Slope_sa 无效。因为 sa 是一个模块,而不仅仅是工具箱的别名,所以代码可以简化如下:

import arcpy
from arcpy.sa import *
elev = arcpy.Raster("C:/Raster/elevation")
outraster = Slope(elev)

from arcpy.sa import * 语句从 arcpy.sa 模块中导入所有函数,因此可以直接调用工具,例如 Slope 与 arcpy.sa.Slope。最初,这似乎不会节省多少,但想象一下在一个脚本中有几十个函数 - 省略 arcpy.sa 几十次会使您的代码更短且更易于阅读。
Spatial Analyst 和 Image Analyst 与其他扩展程序一样,需要许可证。第 5 章详细介绍了许可。 ArcGIS Pro 中最常见的许可类型是指定用户许可。使用这种类型的许可证,扩展的许可由用户帐户设置。在从 arcpy.sa 或 arcpy.ia 运行工具之前,您应该检查 Spatial Analyst 或 Image Analyst 许可是否可用。
一个典型的脚本完成这个任务如下:

import arcpy
arcpy.env.workspace = "C:/Raster"
if arcpy.CheckExtension("Spatial") == "Available":
        print("Spatial Analyst license is available.")
        <map algebra or geoprocessing tools>
       print("Processing complete.")
else:
       print("Spatial Analyst license is unavailable.")

对于浮动版许可证,您可以使用 CheckOutExtension() 函数从脚本中获取扩展许可证。第 5 章提供了代码示例。
由于两个扩展之间的重叠,许多工具都可以通过 arcpy.sa 和 arcpy.ia 模块使用。这种重叠也会影响许可证的使用方式。考虑 Con 工具的示例,该工具可通过 Spatial Analyst 或 Image Analyst 许可获得。以下脚本使用 arcpy.ia 模块中的 Con 工具:

import arcpy
from arcpy.ia import *
arcpy.env.workspace = "C:/Raster/Study.gdb"
inras = Raster("elevation")
where = "VALUE >= 1500"
outras = Con(inras, 1, 0, where)
outras.save("outcon")

考虑在运行时没有 Image Analyst 许可证可用,但 Spatial Analyst 许可证可用的场景。该脚本成功完成,因为至少有一个必要的许可证可用。也就是说,对于 arcpy.sa 和 arcpy.ia 中都可用的工具,无需担心在脚本中使用哪个模块。尽管如此,arcpy.ia 中只有少数工具可用,而 arcpy.sa 中不可用,而 arcpy.sa 包含的工具数量是迄今为止最多的。因此,大多数使用两个模块通用工具的脚本都应该使用 arcpy.sa 模块。

10.4 栅格对象的使用

ArcPy 包含一个引用栅格数据集的 Raster 类。可以通过三种方式创建栅格对象:
(1) 通过引用磁盘上的现有栅格,
(2) 通过运行地理处理工具,
(3) 通过使用地图代数语句。

在 Python 脚本中处理栅格数据集时,栅格对象非常重要,因为它们被广泛用作地理处理工具的输入和输出。
栅格对象的语法是:

Raster(inRaster, {is_multidimensional})

inRaster 参数是输入栅格数据集或栅格数据集列表。您还可以使用 RasterInfo 对象作为输入,它描述了一组栅格属性。后一种方法可用于从现有栅格数据集创建新栅格数据集,同时修改其某些属性。 is_multidimensional 参数是一个布尔值,用于指示输入是否是多维的。默认值为假。多维数据表示在不同时间和不同深度或高度捕获的数据,这在大气和海洋数据中很常见。多维数据的常用格式是 netCDF 和 HDF。但是,包含多个波段的栅格数据集不被视为多维数据集。
以下代码说明了如何通过引用磁盘上的栅格来创建栅格对象:

import arcpy
arcpy.env.workspace = "C:/Raster"
myraster = arcpy.Raster("elevation")

Raster 类是 ArcPy 的常规类,而不是 arcpy.sa 或 arcpy.ia 模块的类。因此,前面的示例代码不需要使用这些模块之一。
许多地理处理工具会返回一个栅格对象,如下所示:

import arcpy
from arcpy.sa import *
arcpy.env.workspace = "C:/Raster"
outraster = Slope("elevation")

因为使用了 Slope 工具,所以需要用到 arcpy.sa 模块。在这两种情况下,生成的栅格对象都可用于 Python 语句、其他地理处理工具和地图代数表达式。
栅格对象具有许多属性,包括 bandCount、compressionType、格式、高度、宽度、pixelType、spatialReference 等。这些属性大多是只读的。使用 Describe() 和 da.Describe() 函数也可以获得相同的属性,第 10.5 节对此进行了更详细的说明。一般来说,最佳实践是使用栅格对象访问栅格数据集的属性,但使用 Describe() 和 da.Describe() 函数也是有效的,有时是必需的。
以下示例显示了如何访问这些属性。该脚本通过引用磁盘上的栅格数据集来创建栅格对象并打印选定的属性,如下所示:

import arcpy
from arcpy.sa import *
arcpy.env.workspace = "C:/Raster/Study.gdb"
ras = Raster("elevation")
print(ras.catalogPath)
print(ras.compressionType)
print(ras.format)
print(ras.pixelType)
print(ras.spatialReference.name)

大多数属性返回一个字符串或数值,可以直接打印。 spatialReference 属性返回一个 SpatialReference 对象,该对象又具有许多属性。此处打印 SpatialReference 对象的 name 属性以进行说明。
对于这个栅格数据集,结果如下:

C:\Raster\Study.gdb\elevation
LZ77
FGDBR
S16
NAD_1983_Transverse_Mercator

非多维栅格对象只有一种方法:save()。默认情况下,从地理处理工具或地图代数表达式返回的栅格对象(变量和关联的数据集)是临时的。当变量超出范围时(例如,当 ArcGIS Pro 关闭或独立脚本关闭时),变量和数据集将被删除。 save() 方法可用于使栅格对象永久化。 save() 方法的语法是

Raster.save({name})

基于前面的示例,坡度工具返回的栅格对象是临时的,但可以使用以下代码使其永久化:

import arcpy
from arcpy.sa import *
arcpy.env.workspace = "C:/Raster"
outraster = Slope("elevation")
outraster.save("slope")

地理处理操作和地图代数表达式会导致临时输出,并且您需要单独的步骤来保存结果,这似乎违反直觉。通常,您希望最终结果是磁盘上的文件。请记住,使用栅格的典型工作流程通常涉及许多步骤。如果只需要最终输出,则将临时输出用于中间步骤会导致更少的输出文件和更低的存储要求。
多维栅格对象具有额外的方法来获取多维数据的属性、名称和值。

10.5 描述栅格属性

可以使用 Describe() 和 da.Describe() 函数来描述栅格。第 6 章讨论了这些功能。这两个函数都返回指定数据元素的属性。这些属性是动态的,这意味着它们取决于所描述的数据类型。例如,当对栅格使用 Describe() 函数时,除了特定栅格元素独有的属性外,还会返回一组通用属性。

提醒一下,这两个功能使您可以访问相同的信息,但方式略有不同。 Describe() 函数将信息作为 Describe 对象的属性返回,而 da.Decribe() 函数将信息作为字典返回,其中键对应于属性。尽管这种差异会影响语法,但两个函数的一般功能是相同的。

上一节讨论了如何使用栅格对象访问栅格数据集的属性,这些属性与 Describe() 和 da.Describe() 函数的功能之间存在大量重叠。但是,在某些情况下,使用这两个函数比使用栅格对象更方便。这包括使用栅格波段,而不是使用栅格数据集。因此,这两个重要的栅格数据元素之间的明显区别是有序的:
(1)栅格数据集—— 栅格数据集是存储在磁盘或地理数据库中的栅格空间数据模型。栅格数据集可以多种格式存储,包括 TIFF、JPEG、IMAGINE、Esri GRID 和 MrSID。栅格数据集可以是单波段或多波段。
(2)栅格波段——栅格波段是栅格数据集中的一层,表示电磁频谱中特定范围的数据值或通过操纵原始图像波段得出的其他值。例如,许多类型的卫星图像包含多个波段。

每个元素的属性各不相同。例如,格式(TIFF、JPEG 等)是栅格数据集的属性,而像元大小是栅格波段的属性。通用 dataType 属性可用于确定数据元素的类型。但是,所有属性都可以使用相同的 Describe() 和 da.Describe() 函数进行访问。
注意:dataType 属性不是栅格对象的属性,只能使用 Describe() 和 da.Describe() 访问。使用栅格对象时,隐含的假设是数据元素的类型是已知的,因此不需要此属性。但是,栅格对象的波段计数属性可用于确定栅格数据集是单波段还是多波段。
以下代码说明了 Describe() 函数的使用,该函数返回一个具有可访问属性的对象:

import arcpy
arcpy.env.workspace = "C:/Raster"
raster = "landcover.tif"
desc = arcpy.Describe(raster)
print(desc.dataType)

对于此 TIFF 格式的栅格示例,dataType 属性返回类型 RasterDataset。使用 da.Describe() 可以获得相同的信息,但该函数返回一个字典。在这个字典中,dataType 是键,RasterDataset 是对应的值:

desc = arcpy.da.Describe(raster)
print(desc["dataType"])

虽然这两个函数都可以用来获取相同的信息,但本章的其余部分使用 da.Describe(),因为字典提供了几个优点。
仅特定于栅格数据集的属性包括以下内容:
bandCount - 栅格数据集中的波段数
compressionType - 压缩类型(LZ77、JPEG、JPEG2000 或无),其中压缩会减小磁盘上文件的大小
格式 -光栅格式(GRID、IMAGINE、TIFF 等)
永久—指示光栅的永久状态:如果光栅是临时的,则为 False,如果光栅是永久的,则为 True
sensorType—用于捕获图像的传感器类型

注意:第一个其中三个属性也是 Raster 类的属性。但是,sensorType 不是 Raster 类的属性,而是使用 Raster 类的 isTemporary 属性而不是永久属性。

一旦确定元素是栅格数据集,就可以访问这些属性。例如,以下代码包含用于描述 TIFF 文件的几个属性:

import arcpy
from arcpy import env
env.workspace = "C:/Raster"
raster = "landcover.tif"
desc = arcpy.da.Describe(raster)
print(desc["dataType"])
print(desc["bandCount"])
print(desc["compressionType"])

此 .tif 文件是单波段未压缩 TIFF,因此属性 bandCount 返回值 1,compressionType 返回值 None。所有这些属性也可以使用光栅对象来确定。
通常与栅格相关的许多其他属性只能针对单个栅格波段进行访问。例如,像元分辨率是一个重要的栅格属性,但一个栅格数据集中的各个波段可以具有不同的分辨率。有几个属性特定于栅格波段,包括:
height——行数
isInteger——表示栅格波段是否为整数类型
meanCellHeight——y方向像元大小
meanCellWidth——x方向像元大小
noDataValue——栅格波段的NoData值
pixelType——像素类型,如8位整数、16位整数、单精度浮点数等
primaryField—字段的索引
tableType—表的类名
width—列数

对于单波段栅格数据集,波段本身不必指定(毕竟只有一个),可以通过描述栅格数据集直接访问属性。例如,以下代码确定单波段栅格的像元大小和像素类型:

import arcpy
from arcpy import env
env.workspace = "C:/Raster"
raster = "landcover.tif"
desc = arcpy.da.Describe(raster)
print(desc["meanCellHeight"])
print(desc["meanCellWidth"])
print(desc["pixelType"])

对于此示例,代码返回 30.0 x 30.0 和 U8 的值 - 表示像元大小为 30 x 30 米,像素类型为无符号 8 位整数。无符号整数不存储负值,而有符号整数则存储。这些属性不报告必须从空间参考信息中获取的水平单位。例如,以下代码确定空间参考的名称和单位:

spatialref = desc["spatialReference"]
print(spatialref.name)
print(spatialref.linearUnitName)

但是,对于多波段栅格,必须指定各个波段。如果没有特定的波段,则无法确定像元大小、高度、宽度和像素类型等属性。考虑以下名为 tm.img 的栅格示例,该栅格由使用相同脚本的三个波段组成:

import arcpy
from arcpy import env
env.workspace = "C:/Raster"
raster = "tm.img"
desc = arcpy.da.Describe(raster)
print(desc["meanCellHeight"])

由于栅格数据集 tm.img 包含多个波段,因此无法访问栅格数据集本身的波段特定属性,并且代码返回错误:

KeyError: 'meanCellHeight'

使用 Band_1、Band_2 等引用特定波段。以下代码说明了如何访问多波段栅格数据集中波段的属性:

import arcpy
from arcpy import env
env.workspace = "C:/Raster"
rasband = "sentinel.tif/Band_1"
desc = arcpy.da.Describe(rasband)
print(desc["dataType"])
print(desc["meanCellHeight"])

此代码返回数据类型的 RasterBand 以及此特定栅格波段的像元大小。
栅格中的各个波段有时称为 Layer_1、Layer_2 等,而不是 Band_1、Band_2 等。您可以使用 children 属性确定波段的名称。
该属性返回一个字典,就像 da.Describe() 函数返回的字典一样。您可以使用字典的键访问每个波段的属性,就像访问栅格数据集的属性一样。以下示例代码确定多波段栅格数据集的波段名称:

import arcpy
arcpy.env.workspace = "C:/Raster"
landsat = "tm.img"
desc = arcpy.da.Describe(landsat)
for rband in desc["children"]:
     print(rband["name"])

对于典型的多波段栅格数据集,结果如下:

Layer_1
Layer_2
Layer_3

编写脚本以使用栅格时,您可能需要确定波段数。适用于单波段栅格的代码可能不适用于多波段栅格。栅格数据集的 bandCount 属性可以确定波段的数量。如果波段数大于 1,则栅格数据集被视为多波段。您可以使用波段计数来使用基本 Layer_ 或 Band_ 生成波段名称列表。
以下示例代码打印单波段和多波段栅格的行数和列单元数。对于多波段栅格,将打印每个波段的属性。

import arcpy
from arcpy import env
env.workspace = "C:/Raster"
raster = "tm.img"
rdesc = arcpy.da.Describe(raster)
bandcount = rdesc["bandCount"]
if bandcount == 1:
    print("Raster name: " + str(rdesc["baseName"]))
    print("No. rows: " + str(rdesc["height"]))
    print("No. columns: " + str(rdesc["width"]))
if bandcount > 1:
    counter = 1
    while counter <= bandcount:
        band = "Layer_" + str(counter)
        bdesc = arcpy.da.Describe(raster + "/" + band)
        print("Raster name: " + str(rdesc["baseName"]))
        print("Band name: " + str(bdesc["baseName"]))
        print("No. rows: " + str(bdesc["height"]))
        print("No. columns: " + str(bdesc["width"]))
        counter += 1

该脚本使用栅格数据集的 bandCount 属性来确定栅格是单波段还是多波段。对于单波段栅格数据集,获取栅格数据集的名称、高度和宽度,无需指定具体波段。对于多波段栅格数据集,脚本会遍历称为 Layer_1、Layer_2 等的波段,直到达到波段总数。为每个波段确定名称、高度和宽度。
对于典型的多波段栅格数据集,输出如下:

Raster name: tm
Band name: Layer_1
No. rows: 1913
No. columns: 1990
Raster name: tm
Band name: Layer_2
No. rows: 1913
No. columns: 1990
Raster name: tm
Band name: Layer_3
No. rows: 1913
No. columns: 1990

在此示例中,多波段栅格中所有波段的属性都相同,但情况并非总是如此。
请注意,此示例代码中的假设是波段的名称以“Layer_”开头,但如果不确定,您可以使用 children 属性来确认名称,这是一种更稳健的解决方案。
尽管您可以使用 Describe() 或 da.Describe() 描述多波段栅格中的波段,但某些类型的分析可能需要您将波段作为栅格对象进行访问。这是通过遍历波段并使用 Raster 类创建每个波段的栅格对象来完成的。打印目录路径以供确认:

import arcpy
arcpy.env.workspace = "C:/Raster"
landsat = "tm.img"
desc = arcpy.da.Describe(landsat)
for rband in desc["children"]:
    name = rband["name"]
    ras = arcpy.Raster("tm.img" + "/" + name)
    print(ras.catalogPath)

结果:

C:\Raster\tm.img\Layer_1
C:\Raster\tm.img\Layer_2
C:\Raster\tm.img\Layer_3

这个解决方案比前面的例子更健壮和简洁,因为不需要将波段计数作为一个单独的步骤来确定,并且波段的名称是在脚本中确定的,而不会对它们的名称做任何假设。

10.6 栅格列表

到目前为止,这些示例都适用于单个栅格数据集。在许多情况下,脚本用于执行许多栅格数据集的处理和分析任务。这就是列表函数的用武之地。
第 6 章解释了列表函数,但本章重新讨论了这些函数以演示它们在处理栅格数据集时的用途。 ListRasters() 函数返回工作空间中栅格名称的 Python 列表。该函数的语法是:

ListRasters({wild_card}, {raster_type})

可选的 wild_card 参数根据栅格名称限制列表。可选的 raster_type 参数根据栅格类型(例如 JPEG 或 TIFF)限制列表。
以下代码说明了使用 ListRasters() 函数在工作空间中打印栅格名称列表:

import arcpy
arcpy.env.workspace = "C:/raster"
rasterlist = arcpy.ListRasters()
for raster in rasterlist:
     print(raster)

结果:

elevation
landcover.tif
tm.img

打印每个光栅的名称以及可选的文件扩展名。例如,对于 ERDAS IMAGINE 格式,文件扩展名是 .img,对于 TIFF 格式是 .tif,对于 JPEG 格式是 .jpg,等等。没有为 Esri GRID(全球资源信息数据库)格式或存储在地理数据库中的栅格添加文件扩展名。因此,当不存在文件扩展名时,请务必确定您是使用 GRID 格式的栅格还是使用地理数据库中的栅格。
ListRasters() 函数的参数过滤结果。例如,以下代码打印工作空间中 ERDAS IMAGINE 格式的栅格列表:

import arcpy
arcpy.env.workspace = "C:/Raster"
rasterlist = arcpy.ListRasters("*", "IMG")
for raster in rasterlist:
     print(raster)

一旦获得栅格名称,就可以使用其他函数来描述数据或执行其他处理任务。重要的是要认识到 ListRasters() 函数返回的是栅格数据集的名称列表,而不是栅格对象。以下示例说明了如何遍历栅格名称列表并为每个栅格数据集创建栅格对象:

import arcpy
arcpy.env.workspace = "C:/Raster"
rasterlist = arcpy.ListRasters()
for raster in rasterlist:
    myras = arcpy.Raster(raster)
    print(myras.name)
    print(myras.format)

该脚本打印每个光栅对象的名称和格式,但打印仅用作更有意义任务的临时占位符。获取栅格对象后,即可在地理处理工具和地图代数语句中使用它们。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Qt中的布局(QGridLayout)时,如果按钮被压缩过度,可能会导致按钮变形。这通常是由于布局中某些行或列的大小没有设置得足够大,以适应按钮的大小。 要解决这个问题,可以尝试以下几个步骤: 1. 检查布局中每行和每列的大小是否足够大,以适应按钮的大小。可以使用`setColumnMinimumWidth`和`setRowMinimumHeight`函数来设置最小宽度和高度。 2. 如果按钮的大小受到其文本内容的影响,请尝试使用`setSizePolicy`函数来设置按钮的大小策略。可以使用`QSizePolicy::Expanding`选项来指定按钮应该尽可能地扩展,以适应其所在的单元。 3. 如果以上步骤都没有解决问题,可以尝试使用QSS(Qt样式表)来进一步调整按钮的大小和布局。可以使用`padding`和`margin`属性来设置按钮周围的填充和边距,以及使用`min-width`和`min-height`属性来设置按钮的最小宽度和高度。 下面是一个示例代码,其中包含了一些上述步骤的实现: ```cpp QGridLayout* layout = new QGridLayout; QPushButton* button = new QPushButton("Button"); button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 设置按钮的大小策略 layout->addWidget(button, 0, 0); // 将按钮添加到布局中的第一行第一列 layout->setColumnMinimumWidth(0, 100); // 设置第一列的最小宽度为100像素 layout->setRowMinimumHeight(0, 50); // 设置第一行的最小高度为50像素 // 使用QSS来设置按钮的最小宽度和高度,以及填充和边距 button->setStyleSheet("QPushButton {" " min-width: 100px;" " min-height: 50px;" " padding: 10px;" " margin: 10px;" "}"); ``` 希望这些步骤可以帮助您解决按钮变形的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值