Re: [Portugal] expressão sql para preencher tabela com rua mais próxima
Diego Moreira
moreira.geo at gmail.com
Sun Aug 21 21:04:11 EDT 2011
Boa Noite Pedro,
Como sugestão do Pedro Venâncio, e tbm considero importante vamos dar
fechamento ao post. Vou voltar a te responder aqui para caso alguem venha
depois, será mais fácil encontrar uma resposta.
Segue a conversa referente a esse post, mas que estava em outro.
*Em 20-08-2011 23:34, Diego Moreira escreveu: *
*
*
* Opá,
Então Pedro,
Esse problema, no meu ponto de vista, pode ser resolvido de duas formas:
1 - Refatorar a tabela rua para que permita somente lineString. Uma Rua é
composta por vários trechos, cada tupla da tabela seria um trecho. (Acho a
mais interessante).
2 - "Encapsular" a função ST_Line_Interpolate_Point, caso vc tenha uma
MultiLine, ela calcula o ponto a X distancia para cada linha e retorna um
multPoint.
O que acha?
Diego Moreira Carvalho
Caro Diego,
Eu preferia optar pela segunda opção uma vez que não me era conveniente
modificar os trechos...Pode ajudar-me a fazer isso para testarmos?
*
*Com os melhores cumprimentos,
Pedro Costa
Geógrafo
Especializado em Sistemas de Informação Geográfica e Ordenamento do Território*
Respondendo:
Seguem duas funções:
*CREATE OR REPLACE FUNCTION smartUnion(geom1 geometry, geom2 geometry)
RETURNS geometry AS $$
-- Autor: Diego Moreira Carvalho
-- E-mail: moreira.geo gmail.com
-- Data: 20/08/2011
-- Descrição: Esta função retorna a união das duas geometrias, caso alguma
geometria seja inválida, retorna a que é válida.
DECLARE
retorno geometry;
BEGIN
IF ST_IsValid(geom1) AND ST_IsValid(geom2) THEN
retorno := ST_Union(geom1, geom2);
ELSIF ST_IsValid(geom1) THEN
retorno := geom1;
ELSIF ST_IsValid(geom2) THEN
retorno := geom2;
END IF;
RETURN retorno;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION Line_Interpolate_Point_Alter(a_linestring
geometry, a_fraction float) RETURNS geometry AS $$
-- Autor: Diego Moreira Carvalho
-- E-mail: moreira.geo gmail.com
-- Data: 21/08/2011
-- Descrição: Esta função é o encapsulamento da função
ST_Line_Interpolate_Point para aceitar multiLines
DECLARE
numGeometries integer;
it integer;
segment geometry;
point geometry;
retorno geometry;
BEGIN
numGeometries := ST_NumGeometries(a_linestring);
IF numGeometries > 0 THEN
numGeometries := numGeometries;
ELSE
numGeometries := 0;
END IF;
IF numGeometries > 0 THEN
it := 1;
WHILE it < (numGeometries + 1) LOOP
segment := ST_GeometryN(a_linestring, it);
point := ST_Line_Interpolate_Point(segment, a_fraction);
retorno := smartUnion(point, retorno);
it := it +1;
END LOOP;
ELSE
point := ST_Line_Interpolate_Point(a_linestring, a_fraction);
retorno := point;
END IF;
RETURN retorno;
END;
$$ LANGUAGE plpgsql;
*
Vc deve usa-la assim:
UPDATE passeios
SET rua =
(SELECT FID_ FROM ruas
ORDER BY ST_Distance(* Line_Interpolate_Point_Alter*(ruas.wkb_geometry,
0.5), passeios.wkb_geometry)) ASC LIMIT 1)
Qualquer problema é só falar;
Com os melhores cumprimentos,
Diego Moreira Carvalho
Em 19 de agosto de 2011 12:53, Pedro Costa <pedrocostaarma sapo.pt>escreveu:
> Encontrei que podemos acrescentar geometryN para aceita multi-geometrias:
>
> UPDATE passeios
> SET rua =
> (SELECT FID_ FROM ruas
>
>
> ORDER BY ST_Distance(ST_Line_Interpolate_Point(geometryN(ruas.wkb_geometry,
> 0.5), passeios.wkb_geometry)) ASC LIMIT 1)
>
>
> No entanto não reconhece a função
>
>
>
>
> On 19-08-2011 13:28, Diego Moreira wrote:
>
> Resolveu?
>
> Diego Moreira Carvalho
>
>
>
> Em 19 de agosto de 2011 09:13, Diego Moreira <moreira.geo gmail.com>escreveu:
>
>> O método ST_Line_Interpolate_Point retorna um ponto ao longo de uma linha
>> dado uma porcentagem do comprimento desta linha.... se passarmos sempre 0.5,
>> teremos sempre o meio da linha... independente do numero de vértices que ela
>> tem,
>> Agora eu acho que resolve
>>
>>
>> "UPDATE passeios SET rua =
>> (SELECT FID_ FROM eixos_rua ORDER BY ST_Distance(*ST_Line_Interpolate_Point(eixos_rua.wkb_geometry,
>> 0.5)* , passeios.wkb_geometry) ASC LIMIT 1)"
>>
>>
>> Diego Moreira Carvalho
>>
>>
>>
>>
>> Em 19 de agosto de 2011 08:54, Pedro Costa <pedrocostaarma sapo.pt>
>> escreveu:
>>
>> > Exactamente, neste caso estou a mudar a unha, mas sabes alguma maneira
>> mais
>> > rápida?
>> >
>> > Obrigado
>> >
>> >
>> >
>> > On 19-08-2011 12:50, Diego Moreira wrote:
>> >
>> > Provavelmente os mal atribuídos estao relacionados a ruas que tem
>> somente
>> > dois ou tres pontos.... da para resolver...
>> >
>> > Em 19/08/2011 06:47, "Pedro Costa" <pedrocostaarma sapo.pt> escreveu:
>> >> Caro Diego,
>> >>
>> >> Funcionou... Obrigado pela ajuda.
>> >> Apesar de tudo alguns passeios ainda são mal atribuídos, mas melhorou
>> >> bastante...
>> >>
>> >> Com os melhores cumprimentos,
>> >>
>> >> Pedro Costa
>> >>
>> >>
>> >>
>> >>
>> >>
>> >> Em 18-08-2011 20:04, Diego Moreira escreveu:
>> >>> Acho que vai dar certo, o pg numa divisão do tipo 3/2 retorna 1,
>> >>> retornaria 1.5 se fosse 3.0/2...
>> >>> Então... acho que vai funcionar.
>> >>>
>> >>> Diego Moreira Carvalho
>> >>>
>> >>>
>> >>>
>> >>> Em 18 de agosto de 2011 16:00, Diego Moreira <moreira.geo gmail.com
>> >>> <mailto:moreira.geo gmail.com>> escreveu:
>> >>>
>> >>> NumPoints(geometry)
>> >>>
>> >>> Encontra e Retorna o número de pontos na primeira linha na
>> >>> geometria. Retorna NULO se não há nenhuma linha na geometria.
>> >>>
>> >>> PointN(geometry,integer)
>> >>>
>> >>> Retorna o enésimo ponto na primeira linha na geometria.
>> >>> Retorna NULO se não há nenhuma linha na geometria.
>> >>>
>> >>> "UPDATE passeios SET rua =
>> >>> (SELECT FID_ FROM eixos_rua ORDER BY
>> >>> ST_Distance(PointN(eixos_rua.wkb_geometry,
>> >>> NumPoints(eixos_rua.wkb_geometry)/2) , passeios.wkb_geometry) ASC
>> >>> LIMIT 1)"
>> >>>
>> >>>
>> >>> Sera que isso dá certo? caso não, o problema é que a função PointN
>> >>> espera receber um inteiro, mas o resultado da divisão por 2
>> >>> retorna um numero tipo 3.5
>> >>>
>> >>> Diego Moreira Carvalho
>> >>>
>> >>>
>> >>>
>> >>> Em 18 de agosto de 2011 15:49, Pedro Costa <pedrocostaarma sapo.pt
>> >>> <mailto:pedrocostaarma sapo.pt>> escreveu:
>> >>>
>> >>> É exactamente por isso Diego. Mas sabes como faço para
>> >>> determinar a contagem de pontos em sql?
>> >>>
>> >>> Obrigado
>> >>>
>> >>>
>> >>>
>> >>>
>> >>> On 18-08-2011 19:40, Diego Moreira wrote:
>> >>>> Boa tarde Pedrom
>> >>>>
>> >>>> Acredito que tal problema ocorre porque as vezes a
>> >>>> estremidade da rua adjacente a que deveria ser escolhida é
>> >>>> mais próxima. Acho que o problema pode ser resolvido da
>> >>>> seguinte forma:
>> >>>>
>> >>>> Pego o ponto n/2 do eixo da rua: se a rua tem dez pontos pego
>> >>>> o 5 ponto, e executo aquela mesma sql, só que com este ponto,
>> >>>> e não com a geometria(eixos_rua.wkb_geometry).
>> >>>>
>> >>>> Acho que deve resolver.
>> >>>>
>> >>>> Espero ter ajudado.
>> >>>>
>> >>>> Diego Moreira Carvalho
>> >>>>
>> >>>>
>> >>>>
>> >>>> Em 18 de agosto de 2011 11:39, Pedro Costa
>> >>>> <pedrocostaarma sapo.pt <mailto:pedrocostaarma sapo.pt>>
>> >>>> escreveu:
>> >>>>
>> >>>> Pessoal é o seguinte, eu tenho duas tabelas no pgadmin
>> >>>> (passeios e ruas), e quero que o campo rua dos passeios
>> >>>> seja prenchido pela rua correspondente. Isto pode
>> >>>> fazer-se em função da distância, como o João Carvalho me
>> >>>> ajudou:
>> >>>>
>> >>>> "UPDATE passeios SET rua = (SELECT FID_ FROM eixos_rua
>> >>>> ORDER BY
>> >>>> ST_Distance(eixos_rua.wkb_geometry,passeios.wkb_geometry)
>> >>>> ASC LIMIT 1)"
>> >>>>
>> >>>> No entanto em muitos casos a rua escolhida não é a
>> >>>> correspondente, esta query não é muito eficiente neste
>> >>>> caso. Alguém sabe uma maneira diferente em que seja
>> >>>> escolhida a rua que está mais próxima "em toda a sua
>> >>>> extensão"?
>> >>>> Podem ver a imagem em anexo para perceberem melhor, as
>> >>>> linhas verdes são os passeios e as vermelhas os eixos de
>> >>>> rua. Alguém tem alguma ideia que possa ajudar?
>> >>>>
>> >>>> Obrigado
>> >>>>
>> >>>> _______________________________________________
>> >>>> Portugal mailing list
>> >>>> Portugal lists.osgeo.org <mailto:Portugal lists.osgeo.org>
>> >>>> http://lists.osgeo.org/mailman/listinfo/portugal
>> >>>>
>> >>>>
>> >>>>
>> >>>>
>> >>>> _______________________________________________
>> >>>> Portugal mailing list
>> >>>> Portugal lists.osgeo.org <mailto:Portugal lists.osgeo.org>
>> >>>> http://lists.osgeo.org/mailman/listinfo/portugal
>> >>>
>> >>>
>> >>> _______________________________________________
>> >>> Portugal mailing list
>> >>> Portugal lists.osgeo.org <mailto:Portugal lists.osgeo.org>
>> >>> http://lists.osgeo.org/mailman/listinfo/portugal
>> >>>
>> >>>
>> >>>
>> >>>
>> >>>
>> >>> _______________________________________________
>> >>> Portugal mailing list
>> >>> Portugal lists.osgeo.org
>> >>> http://lists.osgeo.org/mailman/listinfo/portugal
>> >
>> >
>> > _______________________________________________
>> > Portugal mailing list
>> > Portugal lists.osgeo.org
>> > http://lists.osgeo.org/mailman/listinfo/portugal
>> >
>> >
>> > _______________________________________________
>> > Portugal mailing list
>> > Portugal lists.osgeo.org
>> > http://lists.osgeo.org/mailman/listinfo/portugal
>> >
>> >
>>
>>
>
>
> _______________________________________________
> Portugal mailing listPortugal lists.osgeo.orghttp://lists.osgeo.org/mailman/listinfo/portugal
>
>
>
> _______________________________________________
> Portugal mailing list
> Portugal lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/portugal
>
>
-------------- próxima parte ----------
Um anexo em HTML foi limpo...
URL: http://lists.osgeo.org/pipermail/portugal/attachments/20110821/fa6d35ef/attachment-0001.html
More information about the Portugal
mailing list