PostGIS - 计算多边形中的点(并在边界内平均它们的特征)
PostGIS - Count Points in Polygons (and average their features within the boundaries)
我有一个 table,其中一些点代表 建筑物 :
CREATE TABLE buildings(
pk serial NOT NULL,
geom geometry(Point,4326),
height double precision,
area double precision,
perimeter double precision
)
还有一个 table 有 多段线(大部分关闭):
CREATE TABLE regions
(
pk serial NOT NULL,
geom geometry(Polygon,4326)
)
我愿意:
- 计算每个区域内的点数 (buildings_n)
- 求区域边界内的一个特征(例如面积)的平均值 (area_avg)
添加两个新列:
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);
谢谢,
斯特凡诺
区域几何
您遇到的第一个问题是 ST_Contains 与 'polylines' 或线串只能找到恰好位于线串几何图形上的点。如果您想要由线串表示的区域内的点,它将不起作用,尤其是当这些点未闭合时。请在此处查看有效 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
计算合计值
第二个问题是,要对建筑物 table(而不是整个 table)的子集使用聚合函数计数或平均,您需要将区域 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 用于向 table 添加新记录,UPDATE 用于更改 table.
中现有记录的值
解决方案
因此,上面所有的点结合起来会产生以下查询:
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;
我有一个 table,其中一些点代表 建筑物 :
CREATE TABLE buildings(
pk serial NOT NULL,
geom geometry(Point,4326),
height double precision,
area double precision,
perimeter double precision
)
还有一个 table 有 多段线(大部分关闭):
CREATE TABLE regions
(
pk serial NOT NULL,
geom geometry(Polygon,4326)
)
我愿意:
- 计算每个区域内的点数 (buildings_n)
- 求区域边界内的一个特征(例如面积)的平均值 (area_avg)
添加两个新列:
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);
谢谢,
斯特凡诺
区域几何
您遇到的第一个问题是 ST_Contains 与 'polylines' 或线串只能找到恰好位于线串几何图形上的点。如果您想要由线串表示的区域内的点,它将不起作用,尤其是当这些点未闭合时。请在此处查看有效 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
计算合计值
第二个问题是,要对建筑物 table(而不是整个 table)的子集使用聚合函数计数或平均,您需要将区域 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 用于向 table 添加新记录,UPDATE 用于更改 table.
中现有记录的值解决方案
因此,上面所有的点结合起来会产生以下查询:
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;