【问题标题】:How can I avoid double counts from overlapping areas in Postgis?如何避免 Postgis 中重叠区域的重复计数?
【发布时间】:2020-03-10 14:36:25
【问题描述】:

我想使用 Postgis 计算城镇中事件的影响。我有一个包含事件点位置 (event_count_2019_geo) 的表和一个包含城镇所有建筑物 (utrecht_2020) 以及点位置的表。我统计了活动周围200多米范围内的所有房屋,并统计了有人居住的房屋数量。请参阅下面的代码。

-- In a range of ~200 meters
UPDATE event_count_2019_geo
SET gw200 = temp.aantal_woningen
FROM (SELECT locatie, count(event_count_2019_geo.locatie) AS aantal_woningen
      FROM event_count_2019_geo
           INNER JOIN utrecht_2020 AS bag ON (ST_DWithin(bag.geo_lokatie, event_count_2019_geo.geo_lokatie, 0.002))  
      WHERE  bag.verblijfsobjectgebruiksdoel LIKE '%woonfunctie%'
      GROUP BY locatie
     ) AS temp
WHERE event_count_2019_geo.locatie = temp.locatie;

问题是我最终得到了太多的房子受到事件的影响。我绘制了每个事件周围 200m 的所有范围(见下图)。重叠区域计数两次、三次或事件四次。每个事件的房屋都被正确计算,但我无法总结结果。有没有办法纠正这些重叠,以便我可以在所有选定事件中得出正确的房屋总数?

编辑:示例

只是一个非常简单的例子:对事件 1 的查询产生房屋 A、B、D;事件 2 = C、D、E。每个事件的计数为 3,它们的总和为 6(这确实是正确的行为),我希望看到的是 5,因为 D 被计算为双倍。

【问题讨论】:

  • 嗨阿诺德。为了确保我的问题是正确的:您的问题是否与某些缓冲区(区域)重叠并因此单个几何图形可能位于多个缓冲区内的事实有关?六边形会代替缓冲区吗?您能否提供一些示例数据和确切的预期结果?您描述的行为实际上是预期的,因为房屋确实在 200m 半径内:)
  • @JimJones,你是对的,它与重叠区域有关。我知道这种行为是预期的,但在我的情况下是不需要的。添加了简单的示例:这有帮助吗?
  • 那么您感兴趣的只是房屋总数而不是每个缓冲区的房屋数量?
  • 由于我不熟悉您的数据集,我不能肯定地告诉您,但我相信 DISTINCT ON () 可能会从您的计数中消除重复记录。
  • 如果它不起作用,请在您的问题中添加一些几何图形,以便我可以执行您的查询并重现问题。干杯:)

标签: geolocation gis postgis


【解决方案1】:

感谢@JimJones 的建议,我找到了解决方案。我定义了两种视图:一种以旧方式查找所有房屋 (find_houses_all),另一种仅返回唯一房屋 (find_houses_unique)。

-- Find all houses within a radius of ~200m of an event
DROP VIEW IF EXISTS find_houses_all;

CREATE VIEW find_houses_all AS 
    SELECT bag.openbareruimte, bag.huisnummer, bag.huisletter, bag.huisnummertoevoeging,
           event_count_2019_geo.locatie
    FROM event_count_2019_geo
         INNER JOIN utrecht_2020 AS bag ON (ST_DWithin(bag.geo_lokatie, event_count_2019_geo.geo_lokatie, 0.002));  

-- Find all *unique* houses within a radius of ~200m of an event 
-- Each house is uniquely identiefied by openbareruimte, huisnummer, huisletter
-- and huisnummertoevoeging, so these are the columns to apply DISTINCT ON
DROP VIEW IF EXISTS find_houses_unique;

CREATE VIEW find_houses_unique AS 
    SELECT DISTINCT ON(bag.openbareruimte, bag.huisnummer, bag.huisletter, bag.huisnummertoevoeging) 
           bag.openbareruimte, bag.huisnummer, bag.huisletter, bag.huisnummertoevoeging,
           event_count_2019_geo.locatie
    FROM event_count_2019_geo
         INNER JOIN utrecht_2020 AS bag ON (ST_DWithin(bag.geo_lokatie, event_count_2019_geo.geo_lokatie, 0.002));

我运行了这两个脚本并确实得到了我预期的输出。

SELECT locatie, COUNT (locatie)
FROM find_houses_all -- find_houses_unique
GROUP BY locatie
ORDER BY locatie;

find_houses_all 的输出在所有情况下都大于或等于 find_houses_unique 的输出。电子表格中的示例输出并减去如下所示:

Locatie         All Unique  All - Unique
achter st.-ptr. 617 222     395
berlijnplein    87   87       0
boothstraat     653 175     478
breedstraat    1057 564     493
buurkerkhof     914 163     751
catharijnesngl. 134  38      96
domplein        842 149     693
 ...
Total         35399 13196   22203

负数表示错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    相关资源
    最近更新 更多