Como dividir estradas OSM em segmentos individuais nos cruzamentos?


10

Quero criar uma rede de estradas para uso com pgRouting usando dados do OpenStreetMap. Carreguei um shapefile do GeoFabrik em uma tabela do Postgres (com o PostGIS ativado). No entanto, um problema que tive foi que as estradas nem sempre terminam nos cruzamentos, por isso decidi dividi-las em todos os cruzamentos ou cruzamentos.

Para identificar todas as interseções nas quais as estradas cruzaram ou cruzaram, usei o seguinte SQL(semelhante a uma pergunta anterior ):

CREATE TABLE split_points as
SELECT DISTINCT    
   ST_GeometryN(ST_Intersection(a.geom, b.geom),1) as geom      
FROM
   roads as a,
   roads as b
WHERE
    ST_Touches(a.geom, b.geom)
OR
    ST_Crosses(a.geom, b.geom)    
    AND a.gid != b.gid
GROUP BY
   ST_Intersection(a.geom, b.geom);

Agora eu quero dividir as estradas usando esses pontos. Eu usei a seguinte abordagem:

CREATE TABLE split_roads as
SELECT     
    ST_GeomFromEWKB((ST_Dump(ST_Split(g.geom, blade.geom))).geom) As geom,
    generate_series(1,ST_NumGeometries((ST_Split(g.geom, blade.geom)))) as gid
FROM    
    split_points as blade,
    roads as g
WHERE
    ST_Intersects(g.geom, blade.geom);

O problema dessa abordagem dividida é que a extensão total da estrada permanece além de todas as partes divididas. Para remover essas geometrias de estrada não divididas incluídas, usei a ST_Equals()função para identificá-las e excluí-las:

DELETE FROM split_roads USING roads
WHERE ST_Equals(split_roads.geom, roads.geom)

No entanto, essa abordagem não remove todas as geometrias não divididas originais (embora remova algumas delas). Existe uma abordagem melhor para exclusão (ou geral) para que eu tenha apenas as geometrias divididas em uma tabela?


De acordo com a documentação, ST_Split não retorna a geometria original não dividida. O que é esse '.geom' extra pendurado no último parêntese de fechamento na primeira linha da sua instrução SELECT? Pode ser tão simples quanto remover isso.
Scro

@ Scro a que .geomvocê está se referindo? Não consigo identificar!
DJQ

Eu acho que tecnicamente, essa seria a segunda linha da instrução SELECT. Também estou me referindo à criação da tabela "split_roads". É a linha que termina com '))). Geom) como geom'.
Scro

hmm, eu recebo um erro quando faço isso. ERROR: function st_geomfromewkb(geometry_dump) does not exist LINE 4: ST_GeomFromEWKB((ST_Dump(ST_Split(g.geom, blade.geom))))... ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
DJQ

Fez toda a aparência linha como esta: ST_GeomFromEWKB ((ST_Dump (ST_Split (g.geom, blade.geom)))) Como geom,
Scro

Respostas:


6

Não é uma solução real para o seu problema, mas tente o osm2po ... ele cria o código SQL perfeito para roteamento no pgrouting: http://osm2po.de/


Obrigado pela sugestão. Eu tentei, osm2pgroutingmas requer mais memória do que o meu servidor e termina sem concluir.
DJQ

2
@djq osm2po pode lidar com arquivos muito maiores que osm2pgrouting. Ele pode até mesmo carregar planet.osm
Subterrâneo

ah, originalmente eu pensei que osm2poera um erro de digitação. Existe um simples objetivo de instalá-lo no ubuntu?
DJQ

É um arquivo JAR compilado pronto (java). Basta executá-lo conforme explicado no site.
Estudante de GIS

11

Resposta simples: não. Você não deve fazer dessa maneira.

A partir dos Shapefiles da estrada OSM, é impossível distinguir entre cruzamentos e passagens superiores / inferiores. Você criará cruzamentos que não existem na realidade se você dividir todas as estradas que aparentemente parecem atravessar.

Você precisará sujar as mãos com o arquivo OSM original, se não quiser usar ferramentas existentes, como osm2pgrouting (onde a rede é pequena o suficiente) ou osm2po.


1
Exatamente . Este também é outro erro que algumas pessoas cometem quando processam dados navteq e teleatlas. Passagem inferior / viadutos são uma dor, mas uma realidade.
Ragi Yaser Burhum 08/10/12

1
Aceita. Bem-vindo ao GIS onde os dados são allways mais ou menos ruim
simplexio

3

Sobre o seu problema geral, usando pgRouting: Acho que @Uffer, @GisStudent e outros que estão mostrando como usar "OSC e etc.", estão certos. Siga as dicas de "melhores práticas" e "padrões" ...

Sobre a sua pergunta: "divida as estradas em segmentos individuais nos cruzamentos" ou "como remover todas as geometrias não divididas originais". Eu posso ajudar se você mostrar aqui seus resultados aqui, passo a passo ...

Primeiro passo: análise de topologia

 CREATE TABLE split_points_topo as
  SELECT     
    a.gid as gid_a, b.gid  as gid_b, ST_Relation(a.geom, b.geom) as DE9IM_code
  FROM
    roads as a,
    roads as b
  WHERE a.gid != b.gid AND a.geom && b.geom;

 SELECT DISTINCT st_geometryType(geom) FROM roads;
 SELECT DISTINCT DE9IM_code FROM split_points_topo;
 -- list here the results o these two queries!  ... after we can continue.

2

Outra "solução não real para o seu problema", mas nosso conversor OSM se divide em interseções enquanto converte de OSM para SHP. É mais eficiente dessa maneira, pois pode comparar o ID dos nós, em vez de fazer cálculos geométricos.


1

Uma maneira de resolvê-lo algoritmicamente seria adicionar o ponto inicial e final de cada estrada inteira ao conjunto de "interseções", para que você possa ter certeza de que cada segmento está entre duas interseções.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.