在 Postgresql 中检索一个点到具有给定值的最近栅格像素的距离

问题描述 投票:0回答:2

背景

我的 Postgresql 数据库中有一个表 (hs_buildings),其中包含我的建筑物的点位置 (hs_buildings.coordinates)。然后我有一个包含存储在 Postgresql 栅格表(名为 hs_raster_values)中的土地使用的栅格。

光栅的分辨率为 100x100,所有几何图形均采用 epsg 2056。

问题

如何检索从建筑物位置到具有给定值的像素(比方说 170005)的最短距离

将光栅像素转换为点

以下查询可以工作,但效率很低,如果在整个构建表上运行,则需要很长时间。

WITH hs_points AS
(
    WITH gv AS 
    (
        SELECT
            (ST_PixelAsCentroids(hs_raster_values.geometry, 1, true)).*
        FROM hs_raster_values
        WHERE hs_raster_values.raster_id = 1
    )

    SELECT
        (gv).x,
        (gv).y,
        (gv).val,
        gv.geom 
    FROM gv 
    WHERE val = 170005
)
SELECT 
    ST_Distance(hs_points.geom, hs_buildings.coordinates)
FROM hs_points, hs_buildings
WHERE hs_buildings.id = 1
ORDER BY hs_buildings.coordinates <-> hs_points.geom

LIMIT 1

内置Postgis栅格功能

通过查看文档,我发现有一个 Postgis 函数可以实现此结果:ST_MinDist4ma。然而,文档非常差,我发现自己无法理解必须在函数中传递的适当参数。

我尝试了这个查询:

WITH building_pixel AS 
(
    SELECT 
        (ST_WorldToRasterCoordX(hs_raster_values.geometry, hs_buildings.coordinates),
        ST_WorldToRasterCoordY(hs_raster_values.geometry, hs_buildings.coordinates)) AS xy
    FROM hs_raster_values
    INNER JOIN hs_buildings ON ST_Intersects(hs_buildings.coordinates, hs_raster_values.geometry)
    WHERE hs_raster_values.raster_id = 1
    AND hs_buildings.egid = 1
    AND ST_Intersects(hs_buildings.coordinates, hs_raster_values.geometry)
)

SELECT 
    ST_MinDist4ma(170005, building_pixel.xy, hs_raster_values.geometry) AS min_distance
FROM hs_raster_values, building_pixel
WHERE raster_id = 1;

并出现以下错误:

ERROR:  function st_mindist4ma(integer, record, raster) does not exist LINE 14:  ST_MinDist4ma(170005, building_pixel.xy, hs_raster_values.g...

有人知道我可以使用这个功能吗?

sql postgresql raster postgis-raster
2个回答
0
投票

您传递给 ST_MinDist4ma 的参数似乎可能存在问题。该函数可能不接受您提供的类型。您是否检查了函数签名并确保数据类型匹配?


0
投票

感谢您的帮助。我确实错误地使用了 ST_MinDist4ma 。我现在这样用:

SELECT
        ST_Value(ST_SetSRID(ST_MapAlgebra(
            hs_raster_values.geometry, 
            ARRAY[170005]::integer[],
            'ST_MinDist4ma(double precision[], int[], text[])'::regprocedure
        ), 2056), hs_buildings.coordinates) AS min_distance
    FROM hs_buildings
    INNER JOIN hs_raster_values ON ST_Intersects(hs_raster_values.geometry, hs_buildings.coordinates)
    WHERE hs_raster_values.raster_id = 1 AND hs_buildings.id =1

这给了我一个栅格作为输出,然后我尝试在建筑物的位置找到相关的值。但是,我收到以下错误:

NOTICE:  All input rasters do not have bands at indicated indexes. Returning empty raster

ERROR:  Could not find raster band of index 1 when getting pixel value. Returning NULL 

SQL state: XX000
© www.soinside.com 2019 - 2024. All rights reserved.