[Portugal] expressão sql para preencher tabela com rua mais próxima

Pedro Costa pedrocostaarma at sapo.pt
Mon Aug 22 05:35:51 EDT 2011


Caro Diego,

Resultou perfeitamente...Os erros diminuíram bastante mas ainda vou 
testar em mais dois casos. Pedro Venâncio peço desculpa, mas estava à 
espera de finalizar para depois postar a resolução e os resultados. Mais 
logo vou falar dos resultados e já fica fechado..

Diego, as funções funcionam bem mas será que podes dizer-me como faço 
para as adicionar via shell?

Eu tentei assim:


SQL -d osm -c "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;"


Mas devolve-me o seguinte erro: " ERROR:  syntax error at or near "3582"
LINE 1: ...ion(geom1 geometry, geom2 geometry) RETURNS geometry AS 3582"


Alguém sabe como faço?

Obrigado



On 22-08-2011 02:04, Diego Moreira wrote:
> 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 <mailto: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 <mailto: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 
> <mailto: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 <mailto: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 <mailto: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
>>         <mailto: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>
>>         >>> <mailto: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>
>>         >>> <mailto: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>
>>         <mailto: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>
>>         <mailto: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>
>>         <mailto: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>
>>         <mailto: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 <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


-------------- próxima parte ----------
Um anexo em HTML foi limpo...
URL: http://lists.osgeo.org/pipermail/portugal/attachments/20110822/9338a6cf/attachment-0001.html


More information about the Portugal mailing list