{"id":5564,"date":"2016-06-09T07:33:36","date_gmt":"2016-06-09T10:33:36","guid":{"rendered":"http:\/\/www.fernandoquadro.com.br\/html\/?p=5564"},"modified":"2016-08-12T15:16:22","modified_gmt":"2016-08-12T18:16:22","slug":"criando-um-aplicativo-de-rotas-com-pgrouting-parte-2","status":"publish","type":"post","link":"https:\/\/www.fernandoquadro.com.br\/html\/2016\/06\/09\/criando-um-aplicativo-de-rotas-com-pgrouting-parte-2\/","title":{"rendered":"Criando um aplicativo de rotas com pgRouting \u2013 Parte 2"},"content":{"rendered":"<p>Como <a href=\"http:\/\/www.fernandoquadro.com.br\/html\/2016\/06\/08\/criando-um-aplicativo-de-rotas-com-pgrouting-parte-1\/\" target=\"_blank\">discutimos anteriormente<\/a>, pgRouting necessita de uma rede de v\u00e9rtices e arestas ao inv\u00e9s dos dados espaciais para calcular rotas. Nosso pr\u00f3ximo passo ser\u00e3o utilizadas fun\u00e7\u00f5es que est\u00e3o inclu\u00eddas no pgRouting para gerar a rede necess\u00e1ria.<\/p>\n<p>Come\u00e7amos abrindo o shell do PostgreSQL e, em seguida, carregando a extens\u00e3o pgRouting:<\/p>\n<pre>psql -U postgres routing<\/pre>\n<p>Quando aparecer o prompt do psql, digite o seguinte comando:<\/p>\n<pre>CREATE EXTENSION pgrouting;<\/pre>\n<p>A fun\u00e7\u00e3o que iremos utilizar \u00e9 a <em>pgr_createTopology<\/em>, que vai criar uma nova tabela que cont\u00e9m todos os pontos iniciais e finais de todas as linhas na tabela denominada &#8216;<strong>edges<\/strong>&#8216; (sem duplicar pontos compartilhados).<\/p>\n<p>Por exemplo, se imaginarmos que estamos falando de esta\u00e7\u00f5es de um metr\u00f4 fica muito f\u00e1cil, pois a fun\u00e7\u00e3o ir\u00e1 identificar as quatro esta\u00e7\u00f5es marcadas com <strong>A, B, C<\/strong> e <strong>D<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/06\/topology1.png\" alt=\"topology1\" width=\"578\" height=\"167\" class=\"aligncenter size-full wp-image-5569\" srcset=\"https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/06\/topology1.png 578w, https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/06\/topology1-300x87.png 300w\" sizes=\"auto, (max-width: 578px) 100vw, 578px\" \/><\/p>\n<p>Finalmente, a fun\u00e7\u00e3o ir\u00e1 adicionar as esta\u00e7\u00f5es de origem e de destino para cada um dos segmentos, de tal modo que <strong>1<\/strong> tem origem em <strong>A<\/strong> e destino em <strong>B<\/strong>, e assim por diante.<\/p>\n<p>Para o funcionamento da fun\u00e7\u00e3o <em>pgr_createTopology<\/em>, 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 (&#8216;edges&#8217;) e a toler\u00e2ncia considerando dois v\u00e9rtices na rede.<\/p>\n<pre>ALTER TABLE edges ADD source INT4;\r\nALTER TABLE edges ADD target INT4;\r\nSELECT pgr_createTopology('edges', 1);<\/pre>\n<p>Podemos agora verificar se as colunas de origem e de destino de nossa tabela foram preenchidas. Caso haja uma nova tabela denominada &#8216;<em>edges_vertices_pgr<\/em>&#8216; a qual enumera todos os v\u00e9rtices da rede, indica que o pgRouting detectou com sucesso.<\/p>\n<p>N\u00f3s n\u00e3o resolvemos o problema de rede ainda, no entanto <em>pgr_createTopology <\/em>fez um bom trabalho de encontrar os v\u00e9rtices quando eles s\u00e3o divididos entre duas esta\u00e7\u00f5es, mas e quando uma rodovia terminar no meio de uma outra rodovia?<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/06\/topology2.png\" alt=\"topology2\" width=\"578\" height=\"303\" class=\"aligncenter size-full wp-image-5579\" srcset=\"https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/06\/topology2.png 578w, https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/06\/topology2-300x157.png 300w\" sizes=\"auto, (max-width: 578px) 100vw, 578px\" \/><\/p>\n<p>No exemplo acima, temos novamente quatro v\u00e9rtices, mas n\u00e3o existe um caminho entre o ponto <strong>A<\/strong> e o ponto <strong>D<\/strong> sendo que o ponto <strong>C<\/strong> n\u00e3o \u00e9 compartilhado entre os dois segmentos de linha.<\/p>\n<p>Para lidar com estes casos, pgRouting tem uma fun\u00e7\u00e3o adicional, a <em>pgr_nodeNetwork<\/em>, que vai dividir o segmento <strong>1<\/strong> em dois novos segmentos <strong>3<\/strong> e <strong>4<\/strong>, de modo que o ponto <strong>C<\/strong> pode servir como um &#8220;ponto de transfer\u00eancia&#8221; compartilhado.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/06\/topology3.png\" alt=\"topology3\" width=\"576\" height=\"303\" class=\"aligncenter size-full wp-image-5581\" srcset=\"https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/06\/topology3.png 576w, https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/06\/topology3-300x158.png 300w\" sizes=\"auto, (max-width: 576px) 100vw, 576px\" \/><\/p>\n<p>A nova tabela <i>edges_noded<\/i> \u00e9 criada pela fun\u00e7\u00e3o <i>pgr_nodeNetwork<\/i> e cont\u00e9m um atributo chamado <strong>old_id<\/strong>, que indica o valor do segmento originial para cada segmento derivado dele. A partir do exemplo acima, os segmentos <strong>3<\/strong> e <strong>4<\/strong> ambos tem na coluna old_id o valor <strong>1<\/strong>.<\/p>\n<pre>SELECT pgr_nodeNetwork('edges', 1);<\/pre>\n<p>Nossa nova tabela <i>edges_noded<\/i> agora pode ser usada em uma chamada da fun\u00e7\u00e3o <i>pgr_createTopology<\/i> para adicionar os novos valores de origem e de destino.<\/p>\n<pre>SELECT pgr_createTopology('edges_noded', 1);<\/pre>\n<p>Porque <i>pgr_nodeNetwork<\/i> n\u00e3o copia todas as informa\u00e7\u00f5es 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\u00f3s mesmos.<\/p>\n<p>Primeiro adicione as novas colunas:<\/p>\n<pre>ALTER TABLE edges_noded\r\n  ADD COLUMN name VARCHAR,\r\n  ADD COLUMN type VARCHAR,\r\n  ADD COLUMN oneway VARCHAR,\r\n  ADD COLUMN surface VARCHAR;<\/pre>\n<p>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\u00e3o gravar um nome.<\/p>\n<pre>UPDATE&nbsp;edges_noded&nbsp;AS&nbsp;new\r\nSET\r\n&nbsp;&nbsp;name&nbsp;=&nbsp;CASE&nbsp;WHEN&nbsp;old.name&nbsp;IS&nbsp;NULL&nbsp;THEN&nbsp;old.ref&nbsp;ELSE&nbsp;old.name&nbsp;END,\r\n&nbsp;&nbsp;type&nbsp;=&nbsp;old.highway,\r\n&nbsp;&nbsp;oneway&nbsp;=&nbsp;old.oneway,\r\n&nbsp;&nbsp;surface&nbsp;=&nbsp;old.surface\r\nFROM&nbsp;edges&nbsp;AS&nbsp;old\r\nWHERE&nbsp;new.old_id&nbsp;=&nbsp;old.id;<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Como discutimos anteriormente, pgRouting necessita de uma rede de v\u00e9rtices e arestas ao inv\u00e9s dos dados espaciais para calcular rotas. Nosso pr\u00f3ximo passo ser\u00e3o utilizadas fun\u00e7\u00f5es que est\u00e3o inclu\u00eddas no pgRouting para gerar a rede necess\u00e1ria. Come\u00e7amos abrindo o shell&#8230; <a class=\"more-link\" href=\"https:\/\/www.fernandoquadro.com.br\/html\/2016\/06\/09\/criando-um-aplicativo-de-rotas-com-pgrouting-parte-2\/\">Continue Reading &rarr;<\/a><\/p>\n","protected":false},"author":275,"featured_media":5550,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,24,132,11],"tags":[208,223,266,212],"class_list":["post-5564","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-geoserver","category-gis","category-openlayers","category-postgis","tag-geoserver","tag-gis","tag-pgrouting","tag-postgis"],"_links":{"self":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts\/5564","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/users\/275"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/comments?post=5564"}],"version-history":[{"count":21,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts\/5564\/revisions"}],"predecessor-version":[{"id":6214,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts\/5564\/revisions\/6214"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/media\/5550"}],"wp:attachment":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/media?parent=5564"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/categories?post=5564"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/tags?post=5564"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}