O mapa de calor (heatmap) orientado por palavra é uma idéia legal, e pode ser aplicado a todos os tipos de bancos de dados textuais. O principal requisito é que as ocorrências das palavras obedeçam a algum tipo de aglomeração, de modo que os mapas de calor possam mostrar um padrão discernível.

yelp_hipster

Vamos construir a nossa própria versão do mapa de calor, utilizando as seguintes ferramentas, ao longo desse post que você deve instalar agora:

 – OpenGeo Suite 4.x (disponível para Linux, Mac OSX e Windows)

A estrutura básica utilizada será:

 – A tabela espacial em PostGIS, com um índice full-text sobre os campos que deseja pesquisar
 – Uma SQL View no GeoServer, expondo uma consulta full-text parametrizada
 – Um aplicativo simples com GeoExt
 – Uma renderização no GeoServer, transformando os pontos a partir da consulta SQL em uma visualização heatmap

O fluxo da aplicação irá:

 – Receber uma palavra a partir da interface web do GeoExt, que irá
 – Passá-lo para GeoServer através de um parâmetro na URL do WMS, que irá
 – Passá-lo para o PostgreSQL como um parâmetro SQL, que irá
 – Executar uma pesquisa de texto completo para encontrar um conjunto de pontos cujos nomes contêm a palavra, que irá
 – Ser processado pelo GeoServer em uma visualização do mapa de calor, que vai
 – Ser exibido em uma janela de mapa na interface web pelo GeoExt.

Este tutorial requer que você utilize a extensão WPS para gerar a camada de mapa de calor (heatmap), então você precisa para garantir que ela foi incluído durante a instalação.

 – Durante a instalação do Windows, verifique se a opção WPS do GeoServer foi marcada.
 – No Linux, certifique-se de instalar o pacote geoserver-wps (mesmo nome de pacote para as duas distro: Red Hat e Ubuntu).
 – No MacOSX, você tem que copiar os arquivos WPS para o diretório webapps.

A parte mais difícil deste projeto, em alguns aspectos, é encontrar dados interessantes para alimentar o mapa. Dentre as possibilidades, foi decidido pelo uso de nomes geográficos (geonames), de modo a facilitar o acesso. Todas as outras possibilidades envolvidas envolviam pré-processamento complicado antes de pudessmos começar com a parte da cartografia.

O site geonames.org oferece downloads diretos de dados, então vamos baixar os dados para os EUA.

http://download.geonames.org/export/dump/US.zip

Olhando para dentro do arquivo zip, os dados estão em um arquivo texto denominado “US.txt”. Há também um arquivo readme.txt, um dicionário de dados que descreve as colunas do arquivo de dados.

As colunas que vamos extrair são:

– geonameid
– name
– latitude
– longitude
– feature code
– admin1 code

Nós podemos carregar diretamente o arquivo texto GeoNames usando o comand COPY do PostgreSQL, que importa os dados diretamente para a tabela a partir de arquivos de texto delimitados.

Para receber os dados, precisamos de uma tabela que possua o mesmo número de colunas do arquivo.

CREATE TABLE geonames_load (
  geonameid INTEGER PRIMARY KEY,
  name VARCHAR(200),
  asciiname VARCHAR(200),
  alternatenames VARCHAR,
  latitude FLOAT8,
  longitude FLOAT8,
  feature_class char(1),
  feature_code VARCHAR(10),
  country_code VARCHAR(2),
  cc2 VARCHAR(60),
  admin1 VARCHAR(20),
  admin2 VARCHAR(80),
  admin3 VARCHAR(20),
  admin4 VARCHAR(20),
  population INTEGER,
  elevation INTEGER,
  dem INTEGER,
  timezone VARCHAR(40),
  modification VARCHAR(18)
);

Uma vez que temos uma tabela em branco, podemos carregar o arquivo. Para ler o arquivo, ele deve estar em um local que seja acessível pelo banco de dados. Eu costumo usar o /tmp no Linux ou MacOSX e C:\Temp no Windows.

COPY geonames_load FROM '/tmp/US.txt' WITH (
  FORMAT csv,
  DELIMITER E'\t',
  QUOTE '*',
  HEADER false,
  ENCODING 'UTF8'
);

O formato “csv” geralmente suporta qualquer separador, não apenas vírgulas, e nós declaramos nosso delimitador como um caracter de tabulação. Conforme descrito no readme.txt o arquivo GeoNames não tem nenhuma linha de cabeçalho, e a codificação de texto é UTF8.

Uma vez que a tabela é carregada, podemos verificar quantas linhas tem, em seguida, criar um nova tabela apenas com as colunas que nos interessam:

-- There's over 2M records!
SELECT Count(*) FROM geonames_load;

-- Strip out columns we want, and create a point geometry.
CREATE TABLE geonames AS
SELECT
  geonameid AS id,
  name AS name,
  admin1 AS state,
  feature_code AS kind,
  ST_SetSRID(ST_MakePoint(longitude, latitude), 4326)::Geometry(Point,4326) AS geom
FROM geonames_load;

Finalmente, podemos adicionar um índice espacial, e declarar a chave primária. Isto irá acelerar a visualização dos dados.

ALTER TABLE geonames ADD PRIMARY KEY (id);
CREATE INDEX geonames_gix ON geonames USING GIST (geom);

No próximo post iremos configurar o Full-Text Seach, os dados no GeoServer e preparar a aplicação.