Как я могу избежать двойного счета в перекрывающихся областях в Postgis? - PullRequest
1 голос
/ 10 марта 2020

Я хочу вычислить влияние событий в городе, используя 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;

Беда в том, что в результате этого события на меня повлияло слишком много домов. Я нарисовал все диапазоны 200 м вокруг каждого события (см. Рисунок ниже). Пересекающиеся области подсчитываются дважды, трижды или четыре раза. Дома подсчитываются правильно для каждого события, но я не могу суммировать результаты. Есть ли способ исправить эти совпадения, чтобы я мог получить точное количество домов по всем выбранным событиям?

200 meter ranges around each event

Редактировать: Пример

Просто очень простой пример: запрос события 1 дает дома A, B, D; событие 2 = C, D, E. Количество для каждого события равно 3, их сумма равна 6 (это действительно правильное поведение), и то, что я хотел бы видеть, равно 5, поскольку D считается двойным.

1 Ответ

1 голос
/ 10 марта 2020

Благодаря предложению @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

отрицательные числа указали бы на ошибку.

...