O nosso trabalho de banco de dados foi concluído no último post e agora já podemos publicar o nosso roteamento como camadas dinâmicas no GeoServer. Primeiro crie um novo workspace chamado tutorial e uma nova store PostGIS que se conecte ao banco de dados.

stores

Nós estaremos criando duas camadas em GeoServer: shortest_path, que encontra a rota entre dois vértices em nossa rede de roteamento e retorna uma lista de características que representam esse caminho; e nearest_vertex, que encontra o vértice mais próximo de qualquer ponto do nosso conjunto de dados. Nossa aplicação irá permitir que o usuário selecione um ponto no mapa traduzindo-o em um vértice, que pode ser usado como origem ou destino na nossa camada de geração de rota.

Vamos configurar um novo modo de exibição SQL chamado shortest_path com a seguinte consulta SQL:

SELECT
  min(r.seq) AS seq,
  e.old_id AS id,
  e.name,
  e.type,
  e.oneway,
  sum(e.time) AS time,
  sum(e.distance) AS distance,
  ST_Collect(e.the_geom) AS geom
FROM
  pgr_dijkstra(
   'SELECT
    id,
    source::INT4,
    target::INT4,
    %cost% AS cost,
    CASE oneway
      WHEN ''yes'' THEN -1
      ELSE %cost%
    END AS reverse_cost
  FROM edges_noded', %source%, %target%, true, true) AS r,
  edges_noded AS e
WHERE
  r.id2 = e.id
GROUP BY
  e.old_id, e.name, e.type, e.oneway

A camada tem três parâmetros: source, target and cost. Os dois primeiros são o número de identificação do vértice e o custo a qualquer distância ou tempo, dependendo de qual métrica utilizada para calcular a rota.

Note-se também a função ST_Collect irá combinar os segmentos de linha em uma única geometria MultiLineString.

Por razões de segurança, quando estamos criando uma SQL View, devemos mudar a validação de expressão regular dos campos source e target para que somente dígitos sejam permitidos (^ [\ d] + $) e para o campo coast de tal forma que as palavras “time” e “distance”sejam permitidas (^ [\ w] + $).

route_view_params

Por último, certifique-se de que especificar qual atributo irá identificar cada recurso na rota, o tipo de geometria (MultiLineString) e o SRID (3857).

route_view_attributes

Isto é tudo o que precisamos configurar no GeoServer para fornecer rotas entre dois vértices, mas o nosso cliente precisa saber os números de identificação dos vértices, por isso vamos publicar a tabela edges_noded_vertices_pgr que foi criada automaticamente. Isso nos leva a nossa segunda SQL View, que vai encontrar o vértice mais próximo a um ponto no mapa como uma forma de selecionar o início ou o fim do nosso percurso.

Usaremos nearest_vertex como nome da camada para publicar a seguinte consulta SQL:

SELECT
  v.id,
  v.the_geom,
  string_agg(distinct(e.name),',') AS name
FROM
  edges_noded_vertices_pgr AS v,
  edges_noded AS e
WHERE
  v.id = (SELECT
            id
          FROM edges_noded_vertices_pgr
          ORDER BY the_geom <-> ST_SetSRID(ST_MakePoint(%x%, %y%), 3857) LIMIT 1)
  AND (e.source = v.id OR e.target = v.id)
GROUP BY v.id, v.the_geom

Devido o fato de que coordenadas podem conter números negativos ou positivos, certifique-se de mudar as expressões regulares de validação para incluir apenas dígitos e ambos os símbolos necessários: ^ [\ d .-] + $.

vertex_view

A subconsulta usa um truque para encontrar rapidamente o ponto mais próximo aos parâmetros x e y. Além de retornar a geometria deste ponto, irá criar uma lista de todas as estradas que se encontram no vértice. Como exemplo, veja a imagem abaixo:

intersection

Finalmente, se publicamos as tabelas edges_noded_vertices_pgr e edges_noded, podemos visualizar nossa rede de roteamento no GeoServer. Isso não é necessário para a nossa aplicação, mas ajuda a visualizar os dados que se está trabalhando.

network