postgresql - 要作为列插入表中的栅格记录的像素值

标签 postgresql pivot postgis crosstab raster

我有一个包含以下列的表格:

(ID, row_num, col_num, pix_centroid, pix_val1). 

我有超过 1000 条记录。我正在使用以下方法插入数据:

insert into pixelbased (row_num, col_num, pix_centroid, pix_val)
select
    (ST_PixelAsPolygons(rast, 1)).x as X,
    (ST_PixelAsPolygons(rast, 1)).y as Y,
    (ST_Centroid((ST_PixelAsPolygons(rast, 1)).geom)) as geom,
    (ST_PixelAsPolygons(rast, 1)).val as pix_val1
from mytable 
where rid=1`

现在我尝试将所有其他记录作为列插入,_pix_val1_ 列对我来说很重要。所有其他列将保持不变。换句话说,我希望最终表具有这些列:

(ID, row_num, col_num, pix_centroid, pix_val1, pix_val2, pix_val3, ....)

有办法吗?

最佳答案

如果可能的话,我希望将此数据作为位图存储在 bytea 中。以下是获取一系列字节值并将其转换为 bytea 的方法:

WITH bytes(b) AS (SELECT x % 256 FROM generate_series(1,53000) x)
SELECT ('\x'||string_agg(lpad(to_hex(b),2,'0'),''))::bytea FROM bytes;

您可以使用 substr 函数访问字节数组的字段或范围。此 bytea 被组织为线性像素阵列,但您可能会发现将其组织为更传统的位图格式更有用。此外,如果您的像素超过一个字节,您可能需要处理大端与小端。您可以在 SQL 中执行此操作,但在 PL/Perl 等过程语言中可能会容易得多。


否则,多维数组将是一个比较合理的选择。

使用 generate_series 语句代替您的 pix_val 字段以方便测试,此查询使用两次聚合传递生成一个二维整数数组:

SELECT ('{'||string_agg(subarray, ',')||'}')::integer[] AS arr
FROM (
   SELECT array_agg(x order by x)::text 
   FROM generate_series(1,53000) x
   GROUP BY width_bucket(x, 1, 53001, 100)
) a(subarray);

由于 array_agg 无法聚合数组,因此不得不不幸地使用二维数组的字符串文字形式。在我看来,这是 PostgreSQL 中真正的缺陷;一般来说,它的多维数组很难与大多数应用程序和语言实现数组的方式一起使用并且不一致。

您可以通过索引从数组中取出字段。示例:

regress=> SELECT ('{'||string_agg(subarray, ',')||'}')::integer[] AS arr INTO test FROM (SELECT array_agg(x order by x)::text from generate_series(1,53000) x GROUP BY width_bucket(x, 1, 53001, 100)) a(subarray);

regress=> \d test

      Table "public.test"
 Column |   Type    | Modifiers 
--------+-----------+-----------
 arr   | integer[] | 

test 包含一个二维数组:

regress=> \x
regress=> select array_dims(test.arr), array_ndims(test.arr), array_length(test.arr,1), array_length(test.arr,2) FROM test;
-[ RECORD 1 ]+---------------
array_dims   | [1:100][1:530]
array_ndims  | 2
array_length | 100
array_length | 530

我可以通过二级索引获取元素:

regress=> SELECT test.arr[4][4] FROM test;
 arr  
------
 1594
(1 row)

或带有切片的“列”:

regress=> SELECT test.arr[4:4][1:530] FROM test;

奇怪的是,这仍然是一个二维数组,顶层维度只有一个元素深。如果需要,您可以使用 unnestarray_agg 将其(低效地)展平。

PostgreSQL 中的二维数组有点奇怪,如您所见,但您尝试做的事情也是如此。

关于postgresql - 要作为列插入表中的栅格记录的像素值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13146046/

相关文章:

postgresql - 如何在 PostgreSQL 服务器端 C 函数中为数据库 NULL 创建 Datum?

mysql - (行到列/数据透视)+ SUM

sql - PIVOTing可变数量的行到列

openstreetmap - 具有速度限制的本地提名 openstreetmap

postgresql - 如何在 PostGIS/PostgreSQL 中选择排名最高的几何体?

postgresql - 查找与点相交的所有区域,反之亦然 - PostGIS

postgresql - Osm2pgsql 由于错误 : PBF error: invalid BlobHeader size (> max_blob_header_size) 而失败

sql - 如何将线串分割成单独的线段?

postgresql - 如何获取 PostgreSQL 中函数的源代码(包括创建或替换格式的参数)?

sql - 使用交叉表函数的 PostgreSQL 和数据透视表