下面给出的函数是 PostGIS 栅格用户可能需要且目前在 PostGIS 栅格中可用的函数。还有其他函数是栅格对象的必需支持函数,对普通用户没有用处。
raster
是一种新的 PostGIS 类型,用于存储和分析栅格数据。
有关从栅格文件加载栅格的信息,请参阅第 10.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);
本节列出了专门为支持栅格功能而创建的 PostgreSQL 数据类型。
exclude_nodata_value
设置为 false,则所有像素(包括 nodata
像素)都被认为相交并返回值。如果未传入 exclude_nodata_value
,则从栅格的元数据中读取。NODATA
值。NODATA
值的二维双精度数组,该像素由列 X 和行 Y 或在与栅格相同的空间参考坐标系中表示的几何点指定。crop
或为 TRUE,则会裁剪输出栅格。如果 touched
设置为 TRUE,则包含接触到的像素,否则仅当像素的中心位于几何图形中时才包含该像素。本节介绍了与 PostGIS 栅格相关的各种陷阱和提示。
当 GDAL 打开文件时,GDAL 会急切地扫描该文件的目录,以构建其他文件的目录。如果此目录包含许多文件(例如,数千个、数百万个),则打开该文件会变得非常慢(尤其是在该文件恰好位于网络驱动器(如 NFS)上时)。
为了控制此行为,GDAL 提供了以下环境变量: GDAL_DISABLE_READDIR_ON_OPEN。将 GDAL_DISABLE_READDIR_ON_OPEN
设置为 TRUE
以禁用目录扫描。
在 Ubuntu 中(并假设您使用 PostgreSQL 的 Ubuntu 包),可以在 /etc/postgresql/POSTGRESQL_VERSION/CLUSTER_NAME/environment 中设置 GDAL_DISABLE_READDIR_ON_OPEN
(其中 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'
考虑到系统由人类用户使用,Linux 和 PostgreSQL 允许的最大打开文件数通常是保守的(通常每个进程 1024 个打开文件)。对于外部数据库栅格,单个有效查询很容易超过此限制(例如,一个 10 年的数据集,其中每天有一个栅格,其中包含最低和最高温度,我们想知道该数据集中像素的绝对最小值和最大值)。
最容易进行的更改是以下 PostgreSQL 设置: max_files_per_process。默认值设置为 1000,对于外部数据库栅格来说太低了。安全的起始值可以是 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 内核的打开文件限制。这有两个部分
整个系统的最大打开文件数
每个进程的最大打开文件数
您可以使用以下示例检查整个系统的当前最大打开文件数
$ 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
我们需要增加 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 进程并不重要,任何一个都可以。我们感兴趣的响应是 Max open files。
我们希望增加 Max open files 的 Soft Limit 和 Hard Limit,使其大于我们为 PostgreSQL 设置 max_files_per_process
指定的值。在我们的示例中,我们将 max_files_per_process
设置为 65536。
在 Ubuntu 中(并假设您使用 PostgreSQL 的 Ubuntu 包),更改 Soft Limit 和 Hard Limit 的最简单方法是编辑 /etc/init.d/postgresql (SysV) 或 /lib/systemd/system/postgresql*.service (systemd)。
让我们首先处理 SysV Ubuntu 的情况,其中我们将 ulimit -H -n 262144 和 ulimit -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 的情况。我们将 LimitNOFILE=131072 添加到每个 /lib/systemd/system/postgresql*.service 文件中的 [Service] 部分。
...
[Service]
LimitNOFILE=131072
...
[Install]
WantedBy=multi-user.target
...
进行必要的 systemd 更改后,请确保重新加载守护进程
systemctl daemon-reload