PostGIS - 多边形中的点数(并在边界内平均它们的特征)

时间:2016-03-15 23:13:00

标签: postgresql postgis contains points polygons

我的桌子上有一些代表建筑物的点

CREATE TABLE buildings(
  pk serial NOT NULL,
  geom geometry(Point,4326),
  height double precision,
  area double precision,
  perimeter double precision
)

另一张包含折线的表(大多数已关闭):

CREATE TABLE regions
(
  pk serial NOT NULL,
  geom geometry(Polygon,4326)
)

我想:

  1. 计算每个区域内的点数 (buildings_n)
  2. 在区域边界内找到一个特征(例如区域)的平均值 (area_avg)
  3. 添加两个新列:

    ALTER TABLE regions ADD COLUMN buildings_n integer;
    ALTER TABLE regions ADD COLUMN area_avg double precision;
    

    如何进行这两项查询?

    我已经尝试过第1点,但它失败了:

    INSERT INTO  regions (buildings_n)
    SELECT  count(b.geom) 
    FROM  regions a, buildings b
    WHERE st_contains(a.geom,b.geom); 
    

    谢谢,

    斯特凡诺

1 个答案:

答案 0 :(得分:0)

区域几何

你遇到的第一个问题是ST_Contains带有'折线'或者线条只能找到线串的几何上的点。如果你想要一个由线串表示的区域内的点,它就不会起作用,特别是如果它们没有关闭的话。请参阅此处的有效ST_Contains关系示例: http://www.postgis.org/docs/ST_Contains.html

要使空间关系起作用,您必须事先或在查询中动态地将区域的几何体转换为多边形。例如:

ST_Contains(ST_MakePolygon(a.geom),b.geom)

有关详细信息,请参阅此参考: http://www.postgis.org/docs/ST_MakePolygon.html

计算总值

第二个问题是,要对建筑物表(而不是整个表)的子集使用聚合函数计数或平均值,您需要将区域ID与每个建筑物相关联...

SELECT a.pk region_pk, b.pk building_pk, b.area
FROM regions a, buildings b
WHERE ST_Contains(ST_MakePolygon(a.geom),b.geom)

..然后按照他们所属的地区对您的建筑数据进行分组:

SELECT region_pk, count(), avg(area) average
FROM joined_regions_and_buildings
GROUP BY region_pk;

更新新列

第三个问题是您正在使用INSERT向新创建的列添加值。 INSERT用于向表中添加新记录,UPDATE用于更改表中现有记录的值。

解决方案

因此,上面的所有点合并产生以下查询:

WITH joined_regions_and_buildings AS (
    SELECT a.pk region_pk, b.pk building_pk, b.area
    FROM regions a, buildings b
    WHERE ST_Contains(ST_MakePolygon(a.geom),b.geom)
)
UPDATE regions a
SET buildings_n = b.count, area_avg = b.average
FROM (
    SELECT region_pk, count(), avg(area) average
    FROM joined_regions_and_buildings
    GROUP BY region_pk
    ) b
WHERE a.pk = b.region_pk;