Como discutimos anteriormente, pgRouting necessita de uma rede de vértices e arestas ao invés dos dados espaciais para calcular rotas. Nosso próximo passo serão utilizadas funções que estão incluídas no pgRouting para gerar a rede necessária.
Começamos abrindo o shell do PostgreSQL e, em seguida, carregando a extensão pgRouting:
psql -U postgres routing
Quando aparecer o prompt do psql, digite o seguinte comando:
CREATE EXTENSION pgrouting;
A função que iremos utilizar é a pgr_createTopology, que vai criar uma nova tabela que contém todos os pontos iniciais e finais de todas as linhas na tabela denominada ‘edges‘ (sem duplicar pontos compartilhados).
Por exemplo, se imaginarmos que estamos falando de estações de um metrô fica muito fácil, pois a função irá identificar as quatro estações marcadas com A, B, C e D.
Finalmente, a função irá adicionar as estações de origem e de destino para cada um dos segmentos, de tal modo que 1 tem origem em A e destino em B, e assim por diante.
Para o funcionamento da função pgr_createTopology, precisamos adicionar colunas de origem e de destino para a nossa tabela e depois executar o comando. Note que temos que indicar o nome da tabela (‘edges’) e a tolerância considerando dois vértices na rede.
ALTER TABLE edges ADD source INT4; ALTER TABLE edges ADD target INT4; SELECT pgr_createTopology('edges', 1);
Podemos agora verificar se as colunas de origem e de destino de nossa tabela foram preenchidas. Caso haja uma nova tabela denominada ‘edges_vertices_pgr‘ a qual enumera todos os vértices da rede, indica que o pgRouting detectou com sucesso.
Nós não resolvemos o problema de rede ainda, no entanto pgr_createTopology fez um bom trabalho de encontrar os vértices quando eles são divididos entre duas estações, mas e quando uma rodovia terminar no meio de uma outra rodovia?
No exemplo acima, temos novamente quatro vértices, mas não existe um caminho entre o ponto A e o ponto D sendo que o ponto C não é compartilhado entre os dois segmentos de linha.
Para lidar com estes casos, pgRouting tem uma função adicional, a pgr_nodeNetwork, que vai dividir o segmento 1 em dois novos segmentos 3 e 4, de modo que o ponto C pode servir como um “ponto de transferência” compartilhado.
A nova tabela edges_noded é criada pela função pgr_nodeNetwork e contém um atributo chamado old_id, que indica o valor do segmento originial para cada segmento derivado dele. A partir do exemplo acima, os segmentos 3 e 4 ambos tem na coluna old_id o valor 1.
SELECT pgr_nodeNetwork('edges', 1);
Nossa nova tabela edges_noded agora pode ser usada em uma chamada da função pgr_createTopology para adicionar os novos valores de origem e de destino.
SELECT pgr_createTopology('edges_noded', 1);
Porque pgr_nodeNetwork não copia todas as informações dos atributos da tabela original para a nova tabela, temos que mover as colunas name, highway (que vai mudar o nome de tipo para refletir melhor o significado), oneway e surface nós mesmos.
Primeiro adicione as novas colunas:
ALTER TABLE edges_noded ADD COLUMN name VARCHAR, ADD COLUMN type VARCHAR, ADD COLUMN oneway VARCHAR, ADD COLUMN surface VARCHAR;
Em seguida, copie os dados da tabela original. Ao copiar usaremos os nomes de um estado a outro nos casos em que o conjunto de dados não gravar um nome.
UPDATE edges_noded AS new SET name = CASE WHEN old.name IS NULL THEN old.ref ELSE old.name END, type = old.highway, oneway = old.oneway, surface = old.surface FROM edges AS old WHERE new.old_id = old.id;