【问题标题】:Postgis: Query all rows within radius for given table of geometries. Nearest Neighbor modificationPostgis:查询给定几何表半径内的所有行。最近邻修改
【发布时间】:2016-01-28 17:45:51
【问题描述】:

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

现在,对于每个buildings.gid,我想知道同一张桌子的其他建筑物有多少在一定的半径内(我想测试不同的半径:20米,50米,100米,200米,500米,如果可以的话在足够的时间内完成)并将此信息添加到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 的这个solution 相关,这里有一个给定的坐标,周围是半径。但即使只测试 一个 gid,我也没有在可接受的时间内收到结果。

与我的问题不同的是,我希望对每个building 都执行此操作。

表定义

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);

高级问题

(以下可能是另一个问题,因此应该是关于stackoverflow的另一个问题,但可能有机会在第一个问题中实现)

此外,参考“特殊信息”,268238栋楼包含dist,instdate,capac的信息。其余建筑物的这些柱子是NULL

instdate 是建筑物安装“PV”的日期。我需要将表格建筑物转换为面板数据类型表,这意味着对于每个时期(在我的情况下为 11 个时期),同一建筑物存在一行。

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

【问题讨论】:

  • 一个问题是您的几何图形是纬度/经度 (EPSG:4326),但您的距离查询是以米为单位的。您要么需要选择使用 geography 类型(或至少在该演员表上构建一个 GiST 索引),要么选择并重新投影到合适的笛卡尔投影系统(如果一切都很好地融入其中)。事实上,子查询进行了无意义的计数。
  • 更新:我想在查询中使用centroid POINTS,为此我已经使用了索引CREATE INDEX build_centroid_gix ON public.buildings USING gist (st_transform(centroid, 31467))

标签: postgis nearest-neighbor


【解决方案1】:

尝试在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)

【讨论】:

  • 如果我使用CREATE INDEX build_centroid_gix ON public.buildings USING gist (st_transform(centroid, 31467)); 会怎样? SRID 31467 是否支持公制距离?因为我认为使用几何 31467 SRID 查询更快。我也想使用Centroid 积分,而不是geom。我在上面的问题中更新了这个。
猜你喜欢
  • 2016-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 2014-03-25
  • 2019-03-29
相关资源
最近更新 更多