第 10 章光栅参考

目录
10.1. 光栅支持的数据类型
10.2. 光栅管理
10.3. 光栅构造函数
10.4. 光栅访问器
10.5. 光栅波段访问器
10.6. 光栅像素访问器和设置器
10.7. 光栅编辑器
10.8. 光栅波段编辑器
10.9. 光栅波段统计和分析
10.10. 光栅输入
10.11. 光栅输出
10.12. 光栅处理:地图代数
10.13. 内置地图代数回调函数
10.14. 光栅处理:DEM(高程)
10.15. 光栅处理:光栅到几何
10.16. 光栅运算符
10.17. 光栅和光栅波段空间关系
10.18. 光栅提示
10.18.1. 数据库外部光栅

下面给出的函数是 PostGIS 光栅用户可能需要且当前在 PostGIS 光栅中可用的函数。还有其他函数是光栅对象的必需支持函数,对普通用户没有用。

raster 是用于存储和分析光栅数据的 PostGIS 新类型。

有关从光栅文件加载光栅的信息,请参阅 第 9.1 节“加载和创建光栅”

在本参考中的示例中,我们将使用虚拟光栅的光栅表 - 使用以下代码形成

CREATE TABLE dummy_rast(rid integer, rast raster);
INSERT INTO dummy_rast(rid, rast)
VALUES (1,
('01' -- little endian (uint8 ndr)
||
'0000' -- version (uint16 0)
||
'0000' -- nBands (uint16 0)
||
'0000000000000040' -- scaleX (float64 2)
||
'0000000000000840' -- scaleY (float64 3)
||
'000000000000E03F' -- ipX (float64 0.5)
||
'000000000000E03F' -- ipY (float64 0.5)
||
'0000000000000000' -- skewX (float64 0)
||
'0000000000000000' -- skewY (float64 0)
||
'00000000' -- SRID (int32 0)
||
'0A00' -- width (uint16 10)
||
'1400' -- height (uint16 20)
)::raster
),
-- Raster: 5 x 5 pixels, 3 bands, PT_8BUI pixel type, NODATA = 0
(2,  ('01000003009A9999999999A93F9A9999999999A9BF000000E02B274A' ||
'41000000007719564100000000000000000000000000000000FFFFFFFF050005000400FDFEFDFEFEFDFEFEFDF9FAFEF' ||
'EFCF9FBFDFEFEFDFCFAFEFEFE04004E627AADD16076B4F9FE6370A9F5FE59637AB0E54F58617087040046566487A1506CA2E3FA5A6CAFFBFE4D566DA4CB3E454C5665')::raster);

10.1. 光栅支持的数据类型

摘要

本节列出了专门创建用于支持光栅功能的 PostgreSQL 数据类型。

geomval — 一个具有两个字段的空间数据类型 - geom(保存几何对象)和 val(保存光栅波段中的双精度像素值)。
addbandarg — 一个复合类型,用作 ST_AddBand 函数的输入,用于定义新波段的属性和初始值。
rastbandarg — 当需要表示光栅和该光栅的波段索引时使用的复合类型。
raster — 光栅空间数据类型。
reclassarg — 复合类型,用作 ST_Reclass 函数的输入,用于定义重新分类的行为。
summarystats — ST_SummaryStats 和 ST_SummaryStatsAgg 函数返回的复合类型。
unionarg — 复合类型,用作 ST_Union 函数的输入,用于定义要处理的波段和 UNION 操作的行为。

10.2. 光栅管理

AddRasterConstraints — 为特定列的已加载光栅表添加光栅约束,该列约束空间参考、比例、块大小、对齐方式、波段、波段类型以及一个标志,以表示光栅列是否为常规块。必须使用数据加载表才能推断约束。如果约束设置成功,则返回 true,否则发出通知。
DropRasterConstraints — 删除引用光栅表列的 PostGIS 光栅约束。如果您需要重新加载数据或更新光栅列数据,则此功能非常有用。
AddOverviewConstraints — 将光栅列标记为另一个光栅列的概览。
DropOverviewConstraints — 取消将光栅列标记为另一个光栅列的概览。
PostGIS_GDAL_Version — 报告 PostGIS 使用的 GDAL 库版本。
PostGIS_Raster_Lib_Build_Date — 报告完整的栅格库构建日期。
PostGIS_Raster_Lib_Version — 报告完整的栅格版本和构建配置信息。
ST_GDALDrivers — 返回 PostGIS 通过 GDAL 支持的栅格格式列表。只有 can_write=True 的格式才能由 ST_AsGDALRaster 使用
ST_Contour — 使用 GDAL 等值线算法,根据提供的栅格波段生成一组矢量等值线。
ST_InterpolateRaster — 根据输入的 3-d 点集对网格表面进行插值,使用 X 和 Y 值对点在网格上的位置,以及点的 Z 值作为表面高程。
UpdateRasterSRID — 更改用户指定的列和表中所有栅格的 SRID。
ST_CreateOverview — 创建给定栅格覆盖范围的低分辨率版本。

10.3. 栅格构造函数

ST_AddBand — 返回一个光栅,其中添加了给定类型的新的波段,并在给定的索引位置具有给定的初始值。如果没有指定索引,则将波段添加到末尾。
ST_AsRaster — 将 PostGIS 几何转换为 PostGIS 栅格。
ST_Band — 将现有栅格的一个或多个波段作为新栅格返回。对于从现有栅格构建新栅格很有用。
ST_MakeEmptyCoverage — 用空栅格切片的网格覆盖地理参考区域。
ST_MakeEmptyRaster — 返回一个空栅格(没有波段),具有给定的尺寸(宽度和高度)、左上角 X 和 Y、像素大小和旋转(scalex、scaley、skewx 和 skewy)以及参考系 (srid)。如果传入栅格,则返回一个具有相同大小、对齐方式和 SRID 的新栅格。如果省略 srid,则空间参考设置为未知 (0)。
ST_Tile — 返回一组栅格,这些栅格是根据输出栅格的所需尺寸对输入栅格进行拆分的结果。
ST_Retile — 从任意切片的栅格覆盖范围返回一组配置的切片。
ST_FromGDALRaster — 从受支持的 GDAL 栅格文件返回栅格。

10.4. 栅格访问器

ST_GeoReference — 以 GDAL 或 ESRI 格式返回地理参考元数据,通常在 world 文件中看到。默认值为 GDAL。
ST_Height — 返回栅格的高度(以像素为单位)。
ST_IsEmpty — 如果栅格为空(宽度 = 0 且高度 = 0),则返回 true。否则,返回 false。
ST_MemSize — 返回光栅占用的空间量(以字节为单位)。
ST_MetaData — 返回光栅对象的元数据,如像素大小、旋转(倾斜)、左上角、左下角等。
ST_NumBands — 返回光栅对象中的波段数。
ST_PixelHeight — 返回空间参考系统中几何单位的像素高度。
ST_PixelWidth — 返回空间参考系统中几何单位的像素宽度。
ST_ScaleX — 返回坐标参考系统单位中像素宽度的 X 组件。
ST_ScaleY — 返回坐标参考系统单位中像素高度的 Y 组件。
ST_RasterToWorldCoord — 给定列和行,返回光栅左上角的几何 X 和 Y(经度和纬度)。列和行从 1 开始。
ST_RasterToWorldCoordX — 返回光栅左上角的几何 X 坐标、列和行。列和行的编号从 1 开始。
ST_RasterToWorldCoordY — 返回光栅左上角的几何 Y 坐标、列和行。列和行的编号从 1 开始。
ST_Rotation — 返回光栅的旋转(以弧度为单位)。
ST_SkewX — 返回地理参考 X 倾斜(或旋转参数)。
ST_SkewY — 返回地理参考 Y 倾斜(或旋转参数)。
ST_SRID — 返回 spatial_ref_sys 表中定义的光栅的空间参考标识符。
ST_Summary — 返回栅格内容的文本摘要。
ST_UpperLeftX — 返回投影空间参考中栅格的左上角 X 坐标。
ST_UpperLeftY — 返回投影空间参考中栅格的左上角 Y 坐标。
ST_Width — 返回栅格的宽度(以像素为单位)。
ST_WorldToRasterCoord — 返回给定几何 X 和 Y(经度和纬度)或以栅格的空间参考坐标系表示的点几何作为列和行形式的左上角。
ST_WorldToRasterCoordX — 返回以栅格的世界空间参考系表示的点几何 (pt) 或 X 和 Y 世界坐标 (xw, yw) 在栅格中的列。
ST_WorldToRasterCoordY — 返回以栅格的世界空间参考系表示的点几何 (pt) 或 X 和 Y 世界坐标 (xw, yw) 在栅格中的行。

10.5. 栅格波段访问器

ST_BandMetaData — 返回特定栅格波段的基本元数据。如果未指定,则假定波段编号为 1。
ST_BandNoDataValue — 返回给定波段中表示无数据的数值。如果未指定,则假定波段编号为 1。
ST_BandIsNoData — 如果波段仅填充无数据值,则返回 true。
ST_BandPath — 返回存储在文件系统中的波段的系统文件路径。如果未指定波段编号,则假定为 1。
ST_BandFileSize — 返回存储在文件系统中的波段的文件大小。如果未指定波段编号,则假定为 1。
ST_BandFileTimestamp — 返回存储在文件系统中的波段的文件时间戳。如果未指定波段编号,则假定为 1。
ST_BandPixelType — 返回给定波段的像素类型。如果未指定波段编号,则假定为 1。
ST_MinPossibleValue — 返回此像素类型可存储的最小值。
ST_HasNoBand — 如果没有具有给定波段编号的波段,则返回 true。如果未指定波段编号,则假定波段编号为 1。

10.6. 栅格像素访问器和设置器

ST_PixelAsPolygon — 返回限定特定行和列的像素的多边形几何。
ST_PixelAsPolygons — 返回一个多边形几何图形,它围绕栅格带的每个像素的边界,以及每个像素的值、X 和 Y 栅格坐标。
ST_PixelAsPoint — 返回像素左上角的一个点几何图形。
ST_PixelAsPoints — 返回一个点几何图形,用于栅格带的每个像素,以及每个像素的值、X 和 Y 栅格坐标。点几何图形的坐标是像素左上角的坐标。
ST_PixelAsCentroid — 返回一个像素所表示区域的质心(点几何图形)。
ST_PixelAsCentroids — 返回一个质心(点几何图形),用于栅格带的每个像素,以及每个像素的值、X 和 Y 栅格坐标。点几何图形是一个像素所表示区域的质心。
ST_Value — 返回给定列 x、行 y 像素或特定几何点中给定波段的值。波段号从 1 开始,如果没有指定,则假定为 1。如果将 exclude_nodata_value 设置为 false,则所有像素包括 nodata 像素都被视为相交并返回值。如果未传入 exclude_nodata_value,则从栅格的元数据中读取它。
ST_NearestValue — 返回给定波段像素的最近非 NODATA 值,该像素由列 x 和行 y 或以与栅格相同的空间参考坐标系表示的几何点指定。
ST_SetZ — 返回一个几何图形,其 X/Y 坐标与输入几何图形相同,并且使用请求的重采样算法将栅格中的值复制到 Z 维度。
ST_SetM — 返回一个几何图形,其 X/Y 坐标与输入几何图形相同,并且使用请求的重采样算法将栅格中的值复制到 M 维度。
ST_Neighborhood — 返回由给定波段像素周围的非-NODATA值组成的 2-D 双精度数组,该像素由 columnX 和 rowY 或以与栅格相同的空间参考坐标系表示的几何点指定。
ST_SetValue — 返回修改后的栅格,该栅格是通过设置给定 band 中给定 columnx、rowy 像素或与特定几何相交的像素的值而生成的。波段编号从 1 开始,如果未指定,则假定为 1。
ST_SetValues — 返回通过设置给定波段的值而生成的修改后的栅格。
ST_DumpValues — 以二维数组的形式获取指定波段的值。
ST_PixelOfValue — 获取其值等于搜索值的像素的 columnx、rowy 坐标。

10.7. 栅格编辑器

ST_SetGeoReference — 在一次调用中设置地理参考 6 个地理参考参数。数字应以空格分隔。接受 GDAL 或 ESRI 格式的输入。默认值为 GDAL。
ST_SetRotation — 以弧度为单位设置栅格的旋转。
ST_SetScale — 设置像素的 X 和 Y 大小,单位为坐标参考系。数字单位/像素宽度/高度。
ST_SetSkew — 设置地理参考 X 和 Y 偏斜(或旋转参数)。如果只传入一个,则将 X 和 Y 设置为相同的值。
ST_SetSRID — 将栅格的 SRID 设置为 spatial_ref_sys 表中定义的特定整数 srid。
ST_SetUpperLeft — 将栅格像素左上角的值设置为投影的 X 和 Y 坐标。
ST_Resample — 使用指定重采样算法、新尺寸、任意格网角以及从另一个栅格定义或借用的栅格地理参考属性集对栅格进行重采样。
ST_Rescale — 通过仅调整其比例(或像素大小)对栅格进行重采样。使用最近邻(英语或美式拼写)、双线性、三次、三次样条、Lanczos、最大值或最小值重采样算法计算新像素值。默认值为最近邻。
ST_Reskew — 通过仅调整其倾斜度(或旋转参数)对栅格进行重采样。使用最近邻(英语或美式拼写)、双线性、三次、三次样条或 Lanczos 重采样算法计算新像素值。默认值为最近邻。
ST_SnapToGrid — 通过将栅格捕捉到格网对其进行重采样。使用最近邻(英语或美式拼写)、双线性、三次、三次样条或 Lanczos 重采样算法计算新像素值。默认值为最近邻。
ST_Resize — 将栅格调整为新的宽度/高度
ST_Transform — 使用指定的重采样算法将已知空间参考系统中的栅格重新投影到另一个已知空间参考系统。选项包括最近邻、双线性、三次、三次样条、Lanczos,默认值为最近邻。

10.8. 栅格波段编辑器

ST_SetBandNoDataValue — 设置给定波段中表示无数据的值。如果没有指定波段,则假定为波段 1。要将波段标记为没有无数据值,请将无数据值设置为 NULL。
ST_SetBandIsNoData — 将波段的 isnodata 标志设置为 TRUE。
ST_SetBandPath — 更新外部路径和外部数据库波段的波段号
ST_SetBandIndex — 更新外部波段号

10.9. 栅格波段统计和分析

ST_Count — 返回栅格或栅格覆盖中给定波段中的像素数。如果未指定波段,则默认为波段 1。如果 exclude_nodata_value 设置为 true,则只计算不等于 nodata 值的像素。
ST_CountAgg — 聚合。返回一组栅格中给定波段中的像素数。如果未指定波段,则默认为波段 1。如果 exclude_nodata_value 设置为 true,则只计算不等于 NODATA 值的像素。
ST_Histogram — 返回一组记录,总结栅格或栅格覆盖数据分布的单独 bin 范围。如果未指定,则自动计算 bin 的数量。
ST_Quantile — 在样本或总体的情况下,计算栅格或栅格表覆盖的四分位数。因此,可以检查一个值是否在栅格的 25%、50%、75% 百分位数。
ST_SummaryStats — 返回栅格或栅格覆盖的给定栅格波段的汇总统计信息,包括计数、总和、平均值、标准差、最小值、最大值。如果未指定波段,则假设为波段 1。
ST_SummaryStatsAgg — 聚合。返回一组栅格的给定栅格波段的汇总统计信息,包括计数、总和、平均值、标准差、最小值、最大值。如果未指定波段,则假设为波段 1。
ST_ValueCount — 返回一组记录,其中包含像素波段值和给定栅格(或栅格覆盖)的给定波段中具有给定值集的像素数。如果未指定波段,则默认为波段 1。默认情况下,不计算 nodata 值像素。输出像素中的所有其他值,并将像素波段值四舍五入到最接近的整数。

10.10. 栅格输入

ST_RastFromWKB — 从众所周知的二进制 (WKB) 栅格返回栅格值。
ST_RastFromHexWKB — 从众所周知的二进制 (WKB) 栅格的十六进制表示形式返回栅格值。

10.11. 栅格输出

ST_AsBinary/ST_AsWKB — 返回栅格的众所周知的二进制 (WKB) 表示形式。
ST_AsHexWKB — 返回栅格的众所周知的二进制 (WKB) 的十六进制表示形式。
ST_AsGDALRaster — 以指定的 GDAL 栅格格式返回栅格切片。栅格格式是编译的库支持的格式之一。使用 ST_GDALDrivers() 获取库支持的格式列表。
ST_AsJPEG — 将栅格切片选定的波段作为单个联合摄影专家组 (JPEG) 图像(字节数组)返回。如果未指定波段且有 1 个或 3 个以上的波段,则仅使用第一个波段。如果只有 3 个波段,则使用所有 3 个波段并将其映射到 RGB。
ST_AsPNG — 将栅格切片选定的波段作为单个便携式网络图形 (PNG) 图像(字节数组)返回。如果栅格中有 1、3 或 4 个波段且未指定任何波段,则使用所有波段。如果有多个 2 个或 4 个以上的波段且未指定任何波段,则仅使用波段 1。波段映射到 RGB 或 RGBA 空间。
ST_AsTIFF — 将栅格选定的波段作为单个 TIFF 图像(字节数组)返回。如果未指定任何波段或任何指定的波段在栅格中不存在,则将尝试使用所有波段。

10.12. 栅格处理:地图代数

ST_Clip — 返回由输入几何剪切的栅格。如果未指定波段号,则处理所有波段。如果未指定 crop 或指定为 TRUE,则裁剪输出栅格。
ST_ColorMap — 根据源栅格和指定的波段创建最多四个 8BUI 波段(灰度、RGB、RGBA)的新栅格。如果未指定,则假定为波段 1。
ST_Grayscale — 从源栅格和表示红、绿和蓝的指定波段创建新的单 8BUI 波段栅格
ST_Intersection — 返回表示两个栅格的共享部分或栅格矢量化与几何图形的几何相交的栅格或一组几何像素值对。
ST_MapAlgebra(回调函数版本) — 回调函数版本 - 给定一个或多个输入栅格、波段索引和一个用户指定的回调函数,返回一个单波段栅格。
ST_MapAlgebra(表达式版本) — 表达式版本 - 给定一个或两个输入栅格、波段索引和一个或多个用户指定的 SQL 表达式,返回一个单波段栅格。
ST_MapAlgebraExpr — 1 个栅格波段版本:通过对输入栅格波段应用有效的 PostgreSQL 代数运算并提供像素类型来创建新的单波段栅格。如果没有指定波段,则假定为波段 1。
ST_MapAlgebraExpr — 2 个栅格波段版本:通过对两个输入栅格波段应用有效的 PostgreSQL 代数运算并提供像素类型来创建新的单波段栅格。如果没有指定波段号,则假定每个栅格的波段 1。结果栅格将与第一个栅格定义的网格对齐(比例、倾斜和像素角),并且其范围由“extenttype”参数定义。“extenttype”的值可以是:INTERSECTION、UNION、FIRST、SECOND。
ST_MapAlgebraFct — 1 个波段版本 - 通过对输入栅格波段应用有效的 PostgreSQL 函数并提供像素类型来创建新的单波段栅格。如果没有指定波段,则假定为波段 1。
ST_MapAlgebraFct — 2 个波段版本 - 通过对 2 个输入栅格波段应用有效的 PostgreSQL 函数并提供像素类型来创建新的单波段栅格。如果没有指定波段,则假定为波段 1。如果未指定,则范围类型默认为 INTERSECTION。
ST_MapAlgebraFctNgb — 1 个波段版本:使用用户定义的 PostgreSQL 函数进行 Map Algebra 最近邻。返回一个栅格,其值是涉及输入栅格波段邻域值的 PLPGSQL 用户函数的结果。
ST_Reclass — 创建一个新的栅格,其中波段类型从原始栅格重新分类。nband 是要更改的波段。如果未指定 nband,则假定为 1。所有其他波段保持不变。用例:将 16BUI 波段转换为 8BUI 等,以便以可视格式进行更简单的渲染。
ST_Union — 将一组栅格切片合并为一个由 1 个或多个波段组成的单一栅格。

10.13. 内置地图代数回调函数

ST_Distinct4ma — 光栅处理函数,用于计算邻域中唯一像素值的数目。
ST_InvDistWeight4ma — 光栅处理函数,用于根据像素的邻域插值像素的值。
ST_Max4ma — 光栅处理函数,用于计算邻域中的最大像素值。
ST_Mean4ma — 光栅处理函数,用于计算邻域中的平均像素值。
ST_Min4ma — 光栅处理函数,用于计算邻域中的最小像素值。
ST_MinDist4ma — 光栅处理函数,用于返回目标像素与具有值的相邻像素之间的最小距离(以像素数表示)。
ST_Range4ma — 光栅处理函数,用于计算邻域中像素值的范围。
ST_StdDev4ma — 光栅处理函数,用于计算邻域中像素值的标准差。
ST_Sum4ma — 光栅处理函数,用于计算邻域中所有像素值的总和。

10.14. 光栅处理:DEM(高程)

ST_Aspect — 返回高程光栅波段的坡向(默认为度)。用于分析地形。
ST_HillShade — 使用提供的方位角、高度角、亮度和比例输入,返回高程光栅波段的假设光照。
ST_Roughness — 返回具有计算出的 DEM“粗糙度”的光栅。
ST_Slope — 返回高程栅格波段的坡度(默认以度为单位)。对于分析地形很有用。
ST_TPI — 返回一个具有计算出的地形位置指数的栅格。
ST_TRI — 返回一个具有计算出的地形崎岖度指数的栅格。

10.15. 栅格处理:栅格到几何

Box3D — 返回栅格外接框的 3d 框表示。
ST_ConvexHull — 返回栅格的凸包几何,包括像素值等于 BandNoDataValue 的像素值。对于规则形状且未倾斜的栅格,这与 ST_Envelope 给出的结果相同,因此仅对形状不规则或倾斜的栅格有用。
ST_DumpAsPolygons — 从给定的栅格波段返回一组 geomval(geom、val)行。如果未指定波段号,则波段号默认为 1。
ST_Envelope — 返回栅格范围的多边形表示。
ST_MinConvexHull — 返回栅格的凸包几何,不包括 NODATA 像素。
ST_Polygon — 返回一个多边形几何,由像素值不为无数据值的像素的并集形成。如果未指定波段号,则波段号默认为 1。

10.16. 栅格运算符

&& — 如果 A 的边界框与 B 的边界框相交,则返回 TRUE
&< — 如果 A 的边界框在 B 的左侧,则返回 TRUE
&> — 如果 A 的边界框在 B 的右侧,则返回 TRUE
= — 如果 A 的边界框与 B 的边界框相同,则返回 TRUE。使用双精度边界框。
@ — 如果 A 的边界框包含在 B 的边界框中,则返回 TRUE。使用双精度边界框。
~= — 如果 A 的边界框与 B 的边界框相同,则返回 TRUE
~ — 如果 A 的边界框包含 B 的边界框,则返回 TRUE。使用双精度边界框。

10.17. 栅格和栅格波段空间关系

ST_Contains — 如果栅格 rastB 的所有点都不位于栅格 rastA 的外部,并且 rastB 内部至少有一个点位于 rastA 内部,则返回 true。
ST_ContainsProperly — 如果 rastB 与 rastA 的内部相交,但不与 rastA 的边界或外部相交,则返回 true。
ST_Covers — 如果栅格 rastB 的所有点都不位于栅格 rastA 的外部,则返回 true。
ST_CoveredBy — 如果栅格 rastA 的所有点都不位于栅格 rastB 的外部,则返回 true。
ST_Disjoint — 如果栅格 rastA 与 rastB 在空间上不相交,则返回 true。
ST_Intersects — 如果栅格 rastA 与栅格 rastB 在空间上相交,则返回 true。
ST_Overlaps — 如果栅格 rastA 和 rastB 相交,但其中一个没有完全包含另一个,则返回 true。
ST_Touches — 如果栅格 rastA 和 rastB 至少有一个公共点,但它们的内部不相交,则返回 true。
ST_SameAlignment — 如果栅格具有相同的倾斜度、比例、空间参考和偏移量(像素可以放在同一网格上,而不会切入像素),则返回 true;如果不相同,则返回 false,并详细说明问题。
ST_NotSameAlignmentReason — 返回文本,说明栅格是否对齐,如果未对齐,则说明原因。
ST_Within — 如果栅格 rastA 的任何点都不位于栅格 rastB 的外部,并且 rastA 内部至少有一个点位于 rastB 内部,则返回 true。
ST_DWithin — 如果栅格 rastA 和 rastB 在彼此指定的距离内,则返回 true。
ST_DFullyWithin — 如果栅格 rastA 和 rastB 完全在彼此指定的距离内,则返回 true。

10.18. 栅格提示

摘要

本部分记录了与 PostGIS 栅格相关的各种疑难问题和提示。

10.18.1. Out-DB 栅格

10.18.1.1. 包含许多文件的目录

当 GDAL 打开一个文件时,GDAL 会急切地扫描该文件的目录以构建其他文件的目录。如果此目录包含许多文件(例如数千个、数百万个),则打开该文件会变得极其缓慢(尤其是当该文件恰好位于网络驱动器(如 NFS)上时)。

为了控制此行为,GDAL 提供了以下环境变量:GDAL_DISABLE_READDIR_ON_OPEN。将 GDAL_DISABLE_READDIR_ON_OPEN 设置为 TRUE 以禁用目录扫描。

在 Ubuntu 中(假设你正在使用 Ubuntu 的 PostgreSQL 包),GDAL_DISABLE_READDIR_ON_OPEN 可以设置在 /etc/postgresql/POSTGRESQL_VERSION/CLUSTER_NAME/environment 中(其中 POSTGRESQL_VERSION 是 PostgreSQL 的版本,例如 9.6,CLUSTER_NAME 是集群的名称,例如 maindb)。你也可以在此处设置 PostGIS 环境变量。

# environment variables for postmaster process
# This file has the same syntax as postgresql.conf:
#  VARIABLE = simple_value
#  VARIABLE2 = 'any value!'
# I. e. you need to enclose any value which does not only consist of letters,
# numbers, and '-', '_', '.' in single quotes. Shell commands are not
# evaluated.
POSTGIS_GDAL_ENABLED_DRIVERS = 'ENABLE_ALL'

POSTGIS_ENABLE_OUTDB_RASTERS = 1

GDAL_DISABLE_READDIR_ON_OPEN = 'TRUE'
                    

10.18.1.2. 最大打开文件数

Linux 和 PostgreSQL 允许的最大打开文件数通常是保守的(每个进程通常为 1024 个打开文件),因为系统会被人类用户消耗。对于 Out-DB 栅格,一个有效的查询很容易超过此限制(例如,一个数据集包含 10 年的栅格,每个栅格代表一天,包含最低和最高温度,并且我们想要知道该数据集中某个像素的绝对最小值和最大值)。

最容易更改的是以下 PostgreSQL 设置:max_files_per_process。默认设置为 1000,对于 Out-DB 光栅来说太低了。一个安全的初始值可能是 65536,但这实际上取决于你的数据集和针对这些数据集运行的查询。此设置只能在服务器启动时进行,并且可能只能在 PostgreSQL 配置文件中进行(例如,在 Ubuntu 环境中为 /etc/postgresql/POSTGRESQL_VERSION/CLUSTER_NAME/postgresql.conf)。

...
# - Kernel Resource Usage -

max_files_per_process = 65536           # min 25
                                        # (change requires restart)
...
                    

要进行的主要更改是 Linux 内核的打开文件限制。这分为两部分

  • 整个系统的最大打开文件数

  • 每个进程的最大打开文件数

10.18.1.2.1. 整个系统的最大打开文件数

你可以使用以下示例检查整个系统的当前最大打开文件数

$ sysctl -a | grep fs.file-max
fs.file-max = 131072
                    

如果返回的值不够大,请按照以下示例将文件添加到 /etc/sysctl.d/

$ echo "fs.file-max = 6145324" >> /etc/sysctl.d/fs.conf

$ cat /etc/sysctl.d/fs.conf
fs.file-max = 6145324

$ sysctl -p --system
* Applying /etc/sysctl.d/fs.conf ...
fs.file-max = 2097152
* Applying /etc/sysctl.conf ...

$ sysctl -a | grep fs.file-max
fs.file-max = 6145324
                    
10.18.1.2.2. 每个进程的最大打开文件数

我们需要增加 PostgreSQL 服务器进程的每个进程的最大打开文件数。

要查看当前 PostgreSQL 服务进程用于最大打开文件数的内容,请按照以下示例进行操作(确保 PostgreSQL 正在运行)

$ ps aux | grep postgres
postgres 31713  0.0  0.4 179012 17564 pts/0    S    Dec26   0:03 /home/dustymugs/devel/postgresql/sandbox/10/usr/local/bin/postgres -D /home/dustymugs/devel/postgresql/sandbox/10/pgdata
postgres 31716  0.0  0.8 179776 33632 ?        Ss   Dec26   0:01 postgres: checkpointer process
postgres 31717  0.0  0.2 179144  9416 ?        Ss   Dec26   0:05 postgres: writer process
postgres 31718  0.0  0.2 179012  8708 ?        Ss   Dec26   0:06 postgres: wal writer process
postgres 31719  0.0  0.1 179568  7252 ?        Ss   Dec26   0:03 postgres: autovacuum launcher process
postgres 31720  0.0  0.1  34228  4124 ?        Ss   Dec26   0:09 postgres: stats collector process
postgres 31721  0.0  0.1 179308  6052 ?        Ss   Dec26   0:00 postgres: bgworker: logical replication launcher

$ cat /proc/31718/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             15738                15738                processes
Max open files            1024                 4096                 files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       15738                15738                signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us
                    

在上面的示例中,我们检查了进程 31718 的打开文件限制。无论哪个 PostgreSQL 进程,都可以。我们感兴趣的响应是 最大打开文件

我们希望增加 软限制硬限制,使 最大打开文件 大于我们为 PostgreSQL 设置 max_files_per_process 指定的值。在我们的示例中,我们将 max_files_per_process 设置为 65536。

在 Ubuntu 中(假设你正在为 Ubuntu 使用 PostgreSQL 的软件包),更改 软限制硬限制 的最简单方法是编辑 /etc/init.d/postgresql(SysV)或 /lib/systemd/system/postgresql*.service(systemd)。

让我们首先解决 SysV Ubuntu 案例,其中我们将 ulimit -H -n 262144ulimit -n 131072 添加到 /etc/init.d/postgresql

...
case "$1" in
    start|stop|restart|reload)
        if [ "$1" = "start" ]; then
            create_socket_directory
        fi
    if [ -z "`pg_lsclusters -h`" ]; then
        log_warning_msg 'No PostgreSQL clusters exist; see "man pg_createcluster"'
        exit 0
    fi

    ulimit -H -n 262144
    ulimit -n 131072

    for v in $versions; do
        $1 $v || EXIT=$?
    done
    exit ${EXIT:-0}
        ;;
    status)
...

现在来解决 systemd Ubuntu 案例。我们将在 [Service] 部分将 LimitNOFILE=131072 添加到 /lib/systemd/system/postgresql*.service 文件中。

...
[Service]

LimitNOFILE=131072

...

[Install]
WantedBy=multi-user.target
...

在进行必要的 systemd 更改后,请务必重新加载守护程序

systemctl daemon-reload