Postgis:针对给定的 table 几何查询半径内的所有行。最近邻修改

Postgis: Query all rows within radius for given table of geometries. Nearest Neighbor modification

在我安装了 PostGis 2.2.0 的 Postgres 9.5 数据库中,我有一个带有几何数据(点)的 table buildings centroid. table 包含约 300 万个建筑物,其中约 300.000 个包含特殊信息。

现在,对于我想知道的每个 buildings.gid,在一定半径内有多少个相同 table 的其他建筑物(我想针对不同的半径进行测试:20 米、50 米、 100m、200m、500m(如果可以在足够的时间内完成)并将此信息添加到 buildings 的列中。相关列为 N20N50、...

查询

我想到使用类似的东西:

UPDATE buildings
SET N50=sub.N
FROM    (SELECT Count(n.gid) AS N
         FROM   buildings n, buildings b
         WHERE  ST_DWithin(b.centroid, n.centroid, 50) -- distance in meter
         ) sub

与@ErwinBrandstetter的这个相关,这里给定一个坐标,就产生了带半径的around。但是即使只测试 one gid,我也没有在 acceptable 的时间内收到结果。

与我的问题不同的是,我希望每个 building.

都执行此操作

Table定义

CREATE TABLE public.buildings
(
  gid integer NOT NULL DEFAULT nextval('buildings_gid_seq'::regclass),
  osm_id character varying(11),
  name character varying(48),
  type character varying(16),
  geom geometry(MultiPolygon,4326),
  centroid geometry(Point,4326),
  gembez character varying(50),
  gemname character varying(50),
  krsbez character varying(50),
  krsname character varying(50),
  pv boolean,
  gr numeric,
  capac double precision,
  instdate date,
  pvid integer,
  dist double precision,
  gemewz integer,
  n50 integer,
  n100 integer,
  n200 integer,
  n500 integer,
  n1000 integer,
  IBASE numeric,
  CONSTRAINT buildings_pkey PRIMARY KEY (gid)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.buildings
  OWNER TO postgres;

CREATE INDEX build_centroid_gix
  ON public.buildings
  USING gist
  (st_transform(centroid, 31467));

CREATE INDEX buildings_geom_idx
  ON public.buildings
  USING gist
  (geom);

高级问题

(下面可能是另一个问题,因此应该是Whosebug上的另一个问题,但可能有机会在第一个问题中实现)

此外,参考"special information",268238栋建筑包含distinstdatecapac的信息。剩余建筑物的这些列是 NULL.

instdate 是建筑物安装 "PV" 的日期。我需要将 table 建筑物转换为面板数据类型 table,这意味着同一建筑物的每个周期(在我的例子中为 11 个周期)都存在一行。

现在我需要检查半径内有多少其他建筑物已经安装了 "PV"。 为此,我想查询半径范围内的所有建筑物(,如第一个问题),例如 capac IS NOT NULL,但现在不应计算建筑物,但它们的信息关于 dist,instdate,capac 应作为字符串添加到 IBASE.

尝试在 geography 转换上建立索引,它可用于 ST_DWithin(因此您可以使用地理数据计算公制距离)

CREATE INDEX buildings_geog_idx ON buildings USING gist (geom::geography);

UPDATE buildings SET n50=c.count
FROM (
  SELECT a.gid, count(b.gid)
  FROM buildings a
  LEFT JOIN buildings b ON ST_DWithin(a.geom::geography, b.geom::geography, 50.0)
      AND a.gid <> b.gid
  GROUP BY a.gid
) c
WHERE c.gid = buildings.gid;

您也可以尝试在球体上进行计算以获得更快的性能,但球体距离的潜在误差:

ST_DWithin(a.geom::geography, b.geom::geography, 50.0, false)