PostGIS-GROUP BY para valores de dados contínuos?

8

No código de exemplo para a função PostGIS ST_ConvexHull , vários polígonos seriam criados com base em diferentes valores discretos encontrados no campo "disease_type".

--Get estimate of infected area based on point observations
SELECT d.disease_type,
    ST_ConvexHull(ST_Collect(d.the_geom)) As the_geom
    FROM disease_obs As d
    GROUP BY d.disease_type;

Digamos que havia um campo numérico (vamos chamá-lo "myfield") com valores contínuos de 0 a 5. Como você produziria resultados semelhantes ao GROUP BY, mas definindo seus próprios pontos de interrupção (por exemplo: 0-1,25, 1,25-3,5, 3,5-5)?

RyanKDalton
fonte
Não é realmente uma pergunta GIS, mas já foi respondida.
Underdark

Respostas:

9

Você pode usar o CASE para criar classes. Algo parecido:

SELECT 
d.disease_type,
ST_ConvexHull(ST_Collect(d.the_geom)) As the_geom
FROM 
    (
    SELECT
    diseaseobs.the_geom,
    (CASE diseaseobs.number WHEN number BETWEEN 0 AND 1.5 THEN 'type one'
         WHEN number BETWEEN 1.6 AND 3 THEN 'type two'       
         ELSE 'other'
    END ) as disease_type
    FROM schema.diseaseobs

    ) AS d

GROUP BY d.disease_type;
Pablo
fonte
Obrigado Pablo. Isso é ótimo ... Eu mesmo preciso testá-lo, mas espero que esta seja a resposta que eu estava procurando.
precisa saber é o seguinte
2

Hallo

O que costumo fazer nesses casos é criar uma tabela com as classes e ingressar contra elas ou usar uma subconsulta para criar uma lista de classes.

Eu acho que isso dá uma abordagem mais intuitiva e acho que é mais flexível, pois você pode atualizar as classes apenas atualizando uma tabela.

Outro benefício é que você também pode obter as aulas vazias.

a abordagem de subconsulta pode ser algo como:

SELECT
d.disease_type,
ST_ConvexHull(ST_Collect(d.the_geom)) AS the_geom FROM disease_obs
RIGHT JOIN
(SELECT 0::float AS classbottom, 1.25::float AS classtop, 1::int AS classid
UNION ALL    
SELECT 1.25::float AS classbottom, 3.5::float AS classtop, 2::int AS classid
UNION ALL    
SELECT 3.5::float AS classbottom, 5::float AS classtop, 3::int AS classid) AS classes
ON disease_obs.continuous_value>=classes.classbottom AND disease_obs.continuous_value<classes.classbottom
GROUP BY classes.id;

Aqui, usei uma junção correta para obter também as classes vazias, que podem ser úteis algumas vezes. Se você não quiser os vazios, mude para uma junção interna.

Se você mover as classes para uma tabela e colocar o restante da consulta em uma exibição, poderá alterar as classes sem tocar na consulta.

HTH / Nicklas

Nicklas Avén
fonte
Obrigado pela sugestão. Pensei em seguir esse caminho, mas gostaria de colocar isso em um aplicativo em que o usuário possa escolher seus próprios pontos de interrupção, o que torna essa solução não tão favorável.
precisa saber é o seguinte