A receita de bolo do BitchMaps (parte 3 de 3)

2 de maio de 2008

Considerando que já temos uma coleção de endereços capturados e geocodificados, o natural é mostrá-los:

Parte III – Exibindo Mapas

Assim como existem vários serviços gratuitos de geocoding, outros tantos permitem exibir pontos arbitrários, embutindo o mapa no seu site e deixando o usuário navegar livremente dentro dele. Novamente temos que obter uma chave e usar uma API especializada – e continua valendo a sugestão de usar uma biblioteca que abstraia as diferentes APIs.

A que eu mais gostei foi o Mapstraction – que não é exclusivo de Ruby, podendo ser usada em qualquer plataforma (a “mágica” acontece no front-end, via Javascript). O site tem exemplos com vários provedores, e compensa dar uma olhada.

O caminho adotado no Bitchmaps foi outro: ao invés de embutir o mapa, o site exporta os endereços como KML, um formato de dados que permite representar localizações geográficas e seus metadados (descrições, telefones, endereços físicos, URLs, etc.). Vários softwares e sites são capazes de ler KML e exibir seus pontos num mapa (incluindo aí iPhone, que foi o principal atrativo).

O KML nada mais é que um XML com tags específicas. Veja um exemplo (extraído da Wikipedia):

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
  <Placemark>
    <description>New York City</description>
    <name>New York City</name>
    <Point>
      <coordinates>-74.006393,40.714172,0</coordinates>
    </Point>
  </Placemark>
</kml>

No Rails você pode gerar esse tipo de XML usando um template .rxml (ou, de forma mais contemporânea, um template .builder):

xml.instruct! :xml, :version=>"1.0"
xml.kml(:xmlns=>"http://earth.google.com/kml/2.1"){
  xml.Document {
    xml.name(@name)
    for place in @places
      xml.Placemark {
        xml.name(place.description)
        xml.description(place.url)
        xml.Point {
          xml.coordinates(place.lng.to_s+','+place.lat.to_s)
        }
        for phone in place.phones
          xml.phoneNumber(phone.phone)
        end
      }
    end
  }
}

Agora é só chamar este template colocando em @name o título do documento e em @places os locais capturados no banco. Neste exemplo, eles devem possuir as propriedades description, lat, lng e uma coleção phones contendo a propriedade phone (os nomes estão em inglês por mera conveniência de usar o ActiveRecord out-of-the-box sem mapear tabelas ou lançar mão de magia negra).

No caso do BitchMaps, eu chamo o arquivo acima de layer.rxml, e uso um código bem trivial no controller:

def layer
  filtro = ""
  case params[:id]
    when "sp"
      filtro = "Sao Paulo - SP"
    when "camp"
      filtro = "Campinas - SP"
    ..
  end
  @name = "BitchMaps"
  if filtro!=""
    @name = @name + " - " + filtro
  end
  @places = Place.find(:all, :conditions => ["city_state = ? and full_address is not null", filtro])
  #render :xml => @places.to_xml
  respond_to { |format|
    format.kml {}
  }
end

Com isso, ao chamar, por exemplo, http://localhost:3000/bm/layer?id=sp (bm é o ID do controller), eu obtenho o KML de São Paulo – SP.

Faltam apenas dois detalhes: o meu provedor é pobrinho e não suporta Ruby/Rails, e eu queria usar KMZ (a versão “zipada” do KML). Resolvo os dois problemas de uma só vez com um shell script que salva em arquivo e comprime cada uma das cidades:

#/bin/bash
# Salva os XMLs de cada cidade em arquivos kml
lista="sp camp cur lon poa rj bh"
rm published/kmz/*
for cidade in $lista; do wget http://localhost:3000/bm/layer/$cidade.kml -O published/kmz/$cidade.kml; done
# Transforma os kml em kmz
cd published/kmz
for cidade in $lista; do zip -m $cidade.kmz $cidade.kml; done

Daí é só copiar os arquivos .kmz para o servidor, no qual um arquivo .htaccess customizado ajuda o Apache a servir os arquivos com o tipo correto (para orientar o browser) e a redirecionar os nomes no formato bitchmaps.com/XX para bitchmaps.com/kmz/XX.kmz:

AddType application/vnd.google-earth.kml+xml .kml
AddType application/vnd.google-earth.kmz .kmz
RewriteEngine on
RewriteRule (sp|camp|cur|lon|poa|rj|bh)\/?$ http://bitchmaps.com/kmz/$1.kmz [R]

Enfim, é isso. Espero que esta série tenha matado a curiosidade de quem viu o BitchMaps e também que ajude a colocar mais informação geográfica na web. Até a próxima!

1 Comentário em A receita de bolo do BitchMaps (parte 3 de 3)
  1. fart_hc disse:

    pq na proxima versão se possivel não coloca uma opção de cartas médias, pois meu cel é um 2630 (128X160) se eu setar as cartas grandes nao vejo as cartas do meu parceiro e se deixa pequenas mal enxergo…de resto o jogo eh perfeito…alias o unico q eu jogo em todos os lugares….

    [Responder]

Comentários

Comentários


Related Posts Plugin for WordPress, Blogger...