[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