quarta-feira, 29 de julho de 2009

pgRouting - funcionalidades avançadas do PostGIS

Boa noite a todos,

Venho falando muito de PostGIS e PostgreSQL, e hoje não vai ser diferente. Não falarei as history tables, que é um assunto ainda extenso, mas sim do pgRouting.

O que é pgRouting? Bem pgRouting é uma extensão para o PostGIS que vai habilitar o usuário a construir redes e utilizar algoritmos de roteirização, dentro do PostGIS.

Toda rede à ser analisada, dentro de softwares proprietários ou livres, necessitam de um bocado de informação para funcionarem corretamente, e aqui não é diferente. Com uma rede pronta (existem exemplos no site), é possível utilizar diversos alfgoritmos e aplicar pesos a cada "logradouro" ou eixo à ser percorrido, tornando toda esta história de roteirização bastante útil para se encontrar o "melhor caminho".

Os algoritmos disponíveis pelo pgRouting são:

Shortest Path Djisktra;
Shortest Path A*
Shortest Path Shooting Star;
TSP - Travelling Sales Person;
e
Driving Distance calculation;

É bom lembrar que estes algoritmos funcionam em qualquer tipo de rede organizada, seja ela de estradas, rios, de transmissão e tudo mais o que você puder pensar.

Em geral os algoritmos vão retornar ao usuário uma série de linhas, contendo os nós à serem percorridos e os eixos (nodes and edges, para os íntimos).

Esta extensão só mostrar como o PostGIS pode dar ao usuário avançado de GIS um poder que somente se consegue com um Network Analyst (sem contar o armazenamento em banco de dados, flexibilidade de armazenamento, possibilidades de publicar conteúdo na WEB e claro, preço) que custa uns R$10.000,00.

Vão lá, olhem o site e testem.

Abraço

terça-feira, 14 de julho de 2009

History Tables, denovo.

Boa noite pessoal.

Uns posts atrás falei sobre uma função que permitisse e criasse automaticamente as regras e tabelas para armazenamento de registros históricos no PostGIS.

Bem, aqui vão algumas questões: O PostgreSQL nos permite lidar com este tipo de situação de duas formas: Rules e/ou Triggers.

No caso do nosso projetinho, foram utilizadas rules para lidar com o que precisamos fazer. Bem, o que deve ter um histórico de feições?

Primeiramente ele deve guardar todas as feições inseridas, atualizadas e deletadas, bem como a data, hora, nome do usuário que realizou a alteração, e uma coisa interessante, qual é a versão atual daquela feição. Desta forma podemos rastrear quais foram as alterações históricas de cada versão e caso preciso, achar a versão mais apropriada e restaurá-la para o banco de dados principal.

Além disso, temos um registro histórico de fato. Sabemos todas as alterações de uma feição. É possível entender como um lote mudou, por exemplo, ou como um animal rastreado por GPS está se movimentando. Outra coisa bacana, podemos saber como está evoluindo a cobertura vegetal de uma determinada região. Aumentou? Diminuiu? Não existe ambiguidade ou imperícia. Tudo pode ser restaurado e analisado de acordo com uma dimensão extra, o tempo.

Bem, vou postar aqui a estrutura de uma tabela histórica:
  1. CREATE TABLE foo_history(
  2. history_id serial not null,
  3. date_created timestamp not null default now(),
  4. date_deleted timestamp default null,
  5. operacao varchar(20) not null,
  6. usuario varchar(80) not null default current_user,
  7. versao_atual varchar(80),
  8. LIKE foo,
  9. CONSTRAINT foo_history_pk PRIMARY KEY(history_id));
É mais ou menos isso. Deêm uma olhada na linha 8, a expressão LIKE foo. Ela diz ao PostgreSQL que ele deve procurar a estrutura da tabela foo, e copiar ela todinha embaixo. Legal não?

Imagine a tabela foo:
  1. CREATE TABLE foo(
  2. fid serial not null,
  3. classe_vegetacao varchar(30) not null,
  4. CONSTRAINT foo_pk PRIMARY KEY(fid));
Nossa tabela foo_history final seria:
  1. CREATE TABLE foo_history(
  2. history_id serial not null,
  3. date_created timestamp not null default now(),
  4. date_deleted timestamp default null,
  5. operacao varchar(20) not null,
  6. usuario varchar(80) not null default current_user,
  7. versao_atual varchar(80),
  8. fid integer,
  9. classe_vegetacao varchar(30),
  10. CONSTRAINT foo_history_pk PRIMARY KEY(history_id));
*Uma particularidade: qualquer campo do tipo SERIAL (como fid, na tabela foo) é realmente do tipo INTEGER. Quando declaramos SERIAL, o PostgreSQL entende que deve criar uma sequência específica para aquele campo e escolhe o valor padrão para aquele campo o próximo valor daquela sequência.

Bem, para começar precisamos de um código SQL que gere automaticamente este código acima. Ele precisa gerar a tabela sem que o usuário digite nada, apenas escolha a tabela que ele quer montar um registro histórico.

Nosso código também precisa montar automaticamente as regras que vão realizar a gestão desta tabelinha acima. Lembre-se que precisamos de uma regra para cada tipo de modificação na tabela, uma para INSERT, uma para UPDATE e uma para DELETE.

Cada uma tem uma particularidade, pois as alterações na tabela histórica não são as mesmas. A regra para delete, por exemplo, não deve criar novo registro na série histórica, apenas indicar que o registro foi deletado.

Não é muito complicado, mas também não é muito simples. Daqui uns dias falo deste códigozinho e dou umas dicas sobre ele.

segunda-feira, 13 de julho de 2009

Novo emprego, novos desafios

Boa noite fellas,

Arrumei um novo emprego, depois de alguns meses meio que parado. O novo emprego na área de mineração e já estou em São Paulo ajudando o pessoal a organizar algumas coisinhas.

Daqui uns tempos, campo! Trecho, Obra, Mato. Chamem como quiserem, mas é bão demais.

"Novas tecnologias": ArcServer, SDE e de volta ao ninho ESRI.

Vamos lá.

George

quinta-feira, 9 de julho de 2009

Contribuindo um pouquinho...

Boa noite pessoar!

Alguns dias atrás me cadastrei no trac da OsGeo para ver se conseguia solucionar algum tiquete em aberto.

Para quem não sabe, trac é um sistema que controla as informações sobre bugs, melhoramentos entre outras coisas à fazer, dentro de um projeto de software. Ele permite um usuário aceitar uma tarefa, postar arquivos e mensagens e receber comentários em seu trabalho.

Aceitei o tíquete #180 que pede a criação de algumas funções para criar tabelas "históricas", permitindo o usuário saber quem alterou a tabela, como alterou, quando e todas as alterações feitas. À partir daí ele tem opções de restaurar uma feição que foi deletada ou editada de forma errada, entre outras coisinhas.

Montei algumas funções em pl/pgsql puro para gerar estes códigos, e as mesma estão disponíveis no link mostrado acima. Ainda existe muita discussão à ser feita para que elas comecem a pertencer ao código "oficial" do PostGIS, mas está caminhando.

O bacana, além de aprender e conhecer gente nova, é poder devolver um pouco pra um software excelente. Uma contribuição pequena, com certeza, mas que mais pra frente pode ajudar muita gente.

George