Todos nós temos no nosso imaginário a colocação de pins em mapas pendurados na parede quando se queria identificar ocorrências ou pontos de interesse em determinados países, cidades ou localidades. Isto foram os primórdios do Geocoding (ou Geocodificação). Ao longo de 10 anos de experiência em trabalhos na área das tecnologias de análise espacial, esta foi das tarefas em que senti uma maior evolução e simplificação de procedimentos: o Geocoding – conversão de endereços ou moradas em coordenadas geográficas. Muito graças às API da Google. O Geocoding procede de uma interpolação automática de elementos do tipo linha (endereço, toponímia de estradas e rios) ou mesmo de um polígono (unidades administrativas, códigos postais, parcelas cadastrais, etc) para atribuir as coordenadas geográficas de um ponto central. No caso de ser um ponto (caso de escolas, cafés ou outros pontos de interesse) é simplesmente atribuído as coordenadas desse ponto. Existe ainda o Reverse Geocoding que é o geoprocessamento inverso: atribuição de um endereço a partir umas coordenadas geográficas, muito útil quando temos coordenadas GPS e queremos identificar os seus endereços.

Este geoprocessamento é utilizado quando temos uma lista de moradas ou endereços e queremos mapear os seus conteúdos de modo a identificar clusters, padrões, tendências e mapear todas as variáveis que se queira analisar. É usado em várias áreas como o geomarketing, epidemiologia, inventários, ciências policiais, educação. O que vou mostrar neste Post é quatro exemplos da utilização da análise espacial com comandos de geocoding do Google recorrendo às aplicações Google Spreadsheet e o Google My Maps com os Scripts (ou funções) da Google API: Cálculo de distâncias (routing) por diferentes meios de transporte, distância direta (distância de circulo máximo), tempo a percorrer o caminho pelos vários meios de transporte, e a atribuição de coordenadas geográficas a partir do endereço (Geocoding) e o inverso (ReverGeocoding). O sucesso desta tarefa depende, acima de tudo de três fatores:

      – Qualidade dos mapas de base que dispomos para a busca. Neste caso serão os mapas da Google e a qualidade vai depender do seu local de estudo;
      – Qualidade e precisão da lista de endereços que tem para mapear (moradas completas, com vários níveis de precisão e sem erros);
      – Motor de busca, neste caso será o API da Google de Geocoding, mas existem outras opções como programas Desktop.

Novo Documento
Adicionar novo documento no Google Drive

O exemplo que iremos usar neste post é o mapeamento da escola e do endereço de alunos com as variáveis que desejar ver mapeados de modo a poder identificar algum tipo de padronização por área de residência e criar mapas temáticos. Para iniciar, entre na sua conta da Google Drive e crie uma nova folha Google Spreadsheet. Adicione os campos “Nome Aluno” (coluna A), “Endereço” (coluna B), “latitude” (coluna C), “longitude” (coluna D), “Endereço Obtido” (coluna E), “Distância Metros Carro” (coluna F), “Distancia Metros a pé” (coluna G), “Tempo Minutos Carro” (coluna H), “Tempo Minutos pé” (coluna I),”Distância Circulo máximo” (coluna J). Pode ainda acrescentar outros campos ache interessante para caracterizar o aluno (Nacionalidade, Avaliação, Idade, Tipo de transporte que usa, etc).

Opções da Janela Google Apps Script
Opções da Janela Google Apps Script

Vamos dar início à criação das funções, os chamados script, de geoprocessamento através do menu Tools –> Script editor… . Se nunca criou um script vai aparecer-lhe a janela de Google Apps Script, idêntica a esta, e escolha a opção “Blank Project”. A primeira coisa a fazer é renomear o projeto, neste caso pode dar o nome de “Funções de geocodificação”. O primeiro script a criar vai ser para obter as coordenadas Latitude e Longitude a partir do endereço (Geocoding) e o geoprocessamento inverso de atribuição de endereços a partir das coordenadas Latitude e Longitude (Reverse Geocoding). Copiamos o código existente na caixa em baixo e substituímos o texto existente na caixa de código. Gravamos e renomeamos o código para “GetLatLong”. Para terminar, publicamos o script em Publish –> Deploy as a web app… . Escolhemos a opção Deploy e finalizamos a publicação com OK.

Gravação e publicação da Web App
Gravação e publicação da Web App

function getLat(address) {
  if (address == '') {
    Logger.log("Must provide an address");
    return;
  }
  var geocoder = Maps.newGeocoder();
  var location;
    // Geocode the address and plug the lat, lng pair into the
    // 2nd and 3rd elements of the current range row.
    location = geocoder.geocode(address);
    // Only change cells if geocoder seems to have gotten a
    // valid response.
    if (location.status == 'OK') {
      lat = location["results"][0]["geometry"]["location"]["lat"];
 return lat;
    }
};

function getLon(address) {
  if (address == '') {
    Logger.log("Must provide an address");
    return;
  }
  var geocoder = Maps.newGeocoder();
  var location;
    // Geocode the address and plug the lat, lng pair into the
    // 2nd and 3rd elements of the current range row.
    location = geocoder.geocode(address);
    // Only change cells if geocoder seems to have gotten a
    // valid response.
    if (location.status == 'OK') {
      lng = location["results"][0]["geometry"]["location"]["lng"];
 return lng;
  }
};

function geoname(lat,lng) {
  var response=Maps.newGeocoder().reverseGeocode(lat, lng);
  return response.results[0].formatted_address;
}; 

Fazemos o mesmo procedimento para o cálculo de distâncias em metros entre dois pontos de carro e a pé, neste caso entre a escola e local de residência. Para adicionar um novo script vá ao menu File –> New –> Script file… e atribua-lhe o nome de “Distancia”. Copie o código neste caixa e cole na nova folha, substituindo o texto existente nessa folha por este código.

function DrivingMetersCar(origin, destination) {
  var directions = Maps.newDirectionFinder()
  .setOrigin(origin)
  .setDestination(destination)
  .setMode(Maps.DirectionFinder.Mode.DRIVING)
  .getDirections();
  return directions.routes[0].legs[0].distance.value;
}
function DrivingMetersWalk(origin, destination) {
  var directions = Maps.newDirectionFinder()
  .setOrigin(origin)
  .setDestination(destination)
  .setMode(Maps.DirectionFinder.Mode.WALKING)
  .getDirections();
  return directions.routes[0].legs[0].distance.value;
}

Criamos mais um script para calcular o tempo (em minutos) a percorrer o mesmo caminho a pé e de carro.


function DrivingMinWalk(origin, destination) {
  var directions = Maps.newDirectionFinder()
  .setOrigin(origin)
  .setDestination(destination)
  .setMode(Maps.DirectionFinder.Mode.WALKING)
  .getDirections();
  return directions.routes[0].legs[0].duration.value / (60);  
}

function DrivingMinCar(origin, destination) {
  var directions = Maps.newDirectionFinder()
  .setOrigin(origin)
  .setDestination(destination)
  .setMode(Maps.DirectionFinder.Mode.DRIVING)
  .getDirections();
  return directions.routes[0].legs[0].duration.value / (60);  
}

Criamos o último script para calcular a distância mais curta entre dois pontos em esfera, (distância de círculo máximo), com pouca representação em distâncias tão curtas, mas pode ter relevância em distâncias grandes (usado para a navegação marítima e aérea).


function GCD1(lat1, lon1, lat2, lon2) {
// Return Great Circle Distance between points calculation
function radians(a) {
var outNum =Math.PI*a/180;
return outNum;
}
var R = 6372.795;
var d1=Math.sin(radians(lat1))*Math.sin(radians(lat2))+Math.cos(radians(lat1))*Math.cos(radians(lat2))*Math.cos(radians(lon2)-radians(lon1));
var d2=Math.cos(radians(lat2))*Math.sin(radians(lon2)-radians(lon1));
var d3=Math.cos(radians(lat1))*Math.sin(radians(lat2))-Math.sin(radians(lat1))*Math.cos(radians(lat2))*Math.cos(radians(lon2)-radians(lon1));
var len=R*Math.atan2(Math.sqrt(d2*d2+d3*d3),d1);
return len;
}​

Grave o projeto de script e volte à sua folha de cálculo do Google Spreadsheet. O procedimento de aplicação de funções nas células do Google Spreadsheet é idêntico à folha de Excel. Coloque os títulos das colunas na primeira linha e a segunda linha registe o local ao qual quer calcular as distâncias, por exemplo a escola. A partir da linha 3 serão preenchidos os alunos. Na linha 3 e para cada uma das colunas onde serão colocados os scripts criados, coloque o cursor em cada uma das células das colunas correspondentes, e use os seguintes comandos:

      – Coordenada Latitude do endereço –> =GetLat(B3)
      – Coordenada Longitude do endereço –> =GetLon(B3)
      – Obter novamente o endereço destas coordenada, desta o endereço obtido a partir dos mapas existentes nos servidores da Google –> =geoname(C3,D3)
      – Calcular a distância, em metros, do percurso de carro entre a escola e a morada de residência (“B$2” é para bloquear a célula do endereço da escola ao arrastar as células para baixo para calcular as restantes distâncias) –> =DrivingMetersCar(B3,B$2)
      – Calcular a distância, em metros, do percurso
a pé entre a escola e a morada de residência –> DrivingMetersWalk(B3,B$2)
      – Calcular o tempo, em minutos, que demora a percorrer de carro desde a morada de residencia à escola –> =DrivingMinCar(B3,B$2)
      – Calcular o tempo, em minutos, que demora a percorrer a pé o percurso desde a morada de residência à escola –> =DrivingMinWalk(B3,B$2)
      – Calcular a distância de círculo máximo entre a escola e a morada de residência do aluno –> =GCD1(C$2,D$2,C3,D3)

Resultado da Google Sheet Geocoding
Resultado da geocodigicação da Google Sheet

No fim pode arrastar cada uma destas células para preencher automaticamente as restantes linhas. Esta folha de cálculo pode ser partilhada pelos alunos e deixar que sejam eles a preencher o nome e o endereço e será atualizado automáticamente os campos com as funções espaciais. Ter em atenção que os utilizadores comuns de contas gmail tem acesso limitado a pedidos de API da Google (ver o limite de Quotas). Se exceder o número de pedido aparece um erro e só poderá proceder novamente ao seu cálculo passado 24h. Mas para a Educação e Governo, pode ser feito o pedido acesso ao limite máximo de pedidos. Para saber mais sobre os scripts em Google Sheet, consulte a página de configurações de funções.

Criação de mapas no Google My Maps a partir da importação dos dados da Google Spreadsheet

Para terminar, falta ver o resultado destas funções em mapas. Aceda à sua conta do Google My Maps e escolha a opção Create a new map. Altere o nome do mapa (“Mapa dos Alunos”) e da layer de dados (“Endereços dos Alunos”) e escolha a opção Import e a opção My Drive para importar a tabela criada anteriormente. Escolha as opção das coordenadas geográficas “Latitude” e “Longitude” ou uma das colunas com os “Endereços” para o posicionamento dos pontos e a coluna “Nome Aluno” para nome dos pontos. A partir de agora pode criar mapas temáticos escolhendo Style que quiser. Pode ainda editar o posicionamento ponto de modo a criar maior precisão da geocodificação. Mais uma vez, pode deixar que sejam os seus alunos a fazer esta tarefa partilhando com eles este mapa.

Resultado final da criação do mapa temático a partir dos dados existentes na tabela da Google SpreadSheet

Esta experiência de funções espaciais e de geocodificação será apresentada no primeiro evento da Google for Education em Portugal, carcavelos, no dia 29 e 30 de novembro. Se quiser participar no evento de modo realizar este e outros trabalhos recorrendo às API da Google, participe no Portugal Summit – AppsEvent. Inscrições em http://portugal.appsevents.com/registration. Pode aceder ao material usado para este post como a tabela com permissões para comentar e ao mapa final através destes links.

Acompanhe a publicação de novos recursos e mapas do livro subscrevendo o canal Youtube com os filmes demonstrativos da aplicação dos mapas e curtindo a página do facebook do livro. Desfrute de mais este recurso, partilhando o conhecimento com os seus alunos e colegas com criatividade e originalidade.

Para o curso “The Magic of Google Mapping”, será usado esta apresentação:
http://goo.gl/gPxgIA

Para o curso “Google Earth in the Classe Room”, será usado esta apresentação:
http://goo.gl/VcKEFJ