Sie sind auf Seite 1von 84

Desenvolvendo

WebMaps
Com a biblioteca Leaflet JavaScript
Um livro para aprender a desenvolver mapas digitais interativos para a
internet de modo fácil, rápido e eficiente
Marcos Eichemberger Ummus
ISBN 978-85-919820-0-4
Todos os Direitos Reservados © 2015 0001

Nenhuma parte deste livro pode ser reproduzida, armazenda em


repositórios digitais ou transmitida de forma nenhuma e por nenhum meio sem a
prévia autorização escrita do autor, exceto nos casos de produção acadêmica
(teses, dissertações e artigos). 101
Este livro foi escrito com o intuito de disseminar, para os países de língua
portuguesa, a utilização da biblioteca LeafletJS, tomando-se todos os cuidados
necessários para garantir a fidedignidade das informações e apresentar o
conteúdo de maneira clara e precisa, ainda assim, este livro é vendido sem
garantias de ordem nenhuma e sem quaisquer assunções por eventuais enganos
cometidos.
Particularmente, não nos colocamos contra a pirataria. No entanto, se você
possui meios para não piratear e obter conhecimento, esperamos que compreenda
que este livro foi elaborado de maneira independente e autônoma, o que implica
em gastos, impostos e mais de um ano intenso de trabalho. Além disso, parte das
vendas será investida na tradução da documentação da biblioteca o que te ajuda) e
na geração de atlas municipais, entregues para escolas públicas junto com oficinas
para os professores (o que ajuda um monte de gente legal!).
Assim, não piratear significa uma manifestação de apreço pelos esforços
envidados nesta construção e também um voto de confiança para as próximas
edições e novas obras que desejamos realizar, sempre com o intuito de disseminar
conhecimento.

501 htarop .h 2
Sobre este livro
Este livro não é escrito para especialistas. É claro que os especialistas em
geoprocessamento, por exemplo, poderão fazer um bom uso dele, mas a ideia que
nos move é ajudar qualquer pessoa a partir de zero (0!) conhecimento em internet e
webmaps chegar ao status de desenvolvedor de aplicações de mapas na web.

Sobre a organização do livro


Existe uma estrutura que ordena o livro, que o aproxima do modus operandis de
aprendizado de um autodidata: primeiro, fazemos, depois, pensamos sobre o que
fizemos e então aprendemos com isso.
Assim, exitem três seções que se repetem ao longo do livro: "Preparando um
ambiente de desenvolvimento", "...Mão na Massa!" e "...Dissecando o Código!".
Além disso, existem os anexos e outros textos que serão escritos, auxiliares a este
livro, que tocarão em assuntos mais básicos (o que é a internet, como montar um
servidor de internet) e assuntos mais avançados (desenvolver aplicações específicas,
trabalhar com serviços de mapas).
Este livro apresenta um caminho um pouco longo, mas sem muitas pedras para
quebrar.

Sobre o Autor
Marcos Eichemberger Ummus é geógrafo, formado pela Universidade de São Paulo
(USP), entusiasta das geotecnologias livres e atuante na área de geoprocessamento e
análises espaciais desde o século passado (!), tendo atuado em diferentes esferas do
poder público e privado, desenvolvendo projetos em diferentes estados brasileiros e
outros países latino-americanos.

501 htarop .h 3
Sumário

Prefácio...05
Um Simples WebMap...07
Um Mapa mais Interessante...22
Marcadores e Popups....30
Línhas, Círculos e Polígonos...45
Cartografia Temática...56
Expandindo as funcionalidades do nosso mapa...76

501 htarop .h 4
Prefácio

Cartografia é comunicação.
E esse tipo de comunicação já utilizou, como meios para se
realizar, a areia das praias, a terra sob nossos pés, diferentes tipos de
rochas e o papel.
Portanto, a linguagem cartográfica é adaptável a diferentes
mídias, mas, em nossa era, o início do século XXI, nos comunicamos
(em grande parte e cada vez mais) por meio de uma tela de (algum tipo
de) computador. Então, já há cerca de duas décadas, a cartografia vem
utilizando as mídias digitais como meio de comunicação.
Até há pouco tempo atrás, a comunicação cartográfica pela
internet demandava uma série de softwares, hardwares robustos e um
grande conhecimento de, pelo menos, meia dúzia de tecnologias
diferentes. Felizmente, a tecnologia resolveu caminhar no sentido de
aproximar-se da linguagem do homem e, para desenvolver webmaps
interessantes você não precisa, hoje em dia, de um conjunto muito
grande de técnicas, métodos e tecnologias.
É justamente disto que este livro trata: desenvolver mapas para
a web, sem muito esforço, incrementando a agilidade e o alcance das
produções cartográficas que realizamos em nosso dia a dia.
Por isso, o que você encontra aqui é uma espécie de guia para
desenvolver webmaps, utilizando a biblioteca JavaScript LeafletJS,
pensado para ser absolutamente acessível e tentando ser o menos
aborrecido o possível.
Assim, este livro é específico: os princípios da cartografia, do
geoprocessamento, do sensoreamento remoto e outras tecnologias da
informação geográfica não são cobertos, pelo menos não em
profundidade.
Apesar disso, o livro está organizado para que o leitor não
precise buscar conhecimentos básicos em fontes externas (embora a
curiosidade seja sempre desejável).
O que esperamos? Contribuir sensivelmente para o
aprimoramento pessoal e profissional do leitor. E, em um sentido mais
amplo, entendemos que disseminar o conhecimento sobre as
geotecnologias para a "comunidade do mundo dos mapas" nativa dos

501 htarop .h 5
países de língua portuguesa é parte da nossa missão.
Acreditamos que com o aumento da quantidade de utilizadores
de determinadas técnicas e tecnologias, existirá uma mudança
qualitativa significativa com relação a estas técnicas e tecnologias.
Não poderia deixar de agradecer, profundamente, Vladimir
Agafonkin, desenvolvedor da biblioteca LeafletJS, e toda a comunidade
de desenvolvedores e entusiastas dos softwares livres ao redor do
mundo.
O conhecimento só é real quando compartilhado.
Seja bem vind@ ao mundo dos webmaps!
Divirta-se!

Marcos Eichemberger Ummus

501 htarop .h 6
Um Simples WebMap
Preparar um ambiente de desenvolvimento local
Desenvolver seu primeiro Webmap
Entender o funcionamento básico da Biblioteca LeafletJS
...Preparando um Ambiente de Desenvolvimento
Vamos preparar um ambiente de desenvolvimento local para
entender como funciona a Biblioteca Leaflet JS.
Para isso, seguiremos alguns passos bem curtos, nos
certificando de que todos os itens da checklist a seguir estão
preparados corretamente:

Checklist
• Navegador Web (WebBrowser);
• Editor de Textos;
• Uma pasta para armazenar seus projetos;
• Biblioteca LeafletJS; e
• Conexão com a internet.

Ponto a ponto, seguem algumas boas dicas para cumprir sua


checklist com sucesso.
Navegadores Web
Como parece bastante óbvio, mapas na web são visualizados em
uma tela de computador (!) por meio de um Navegador Web
(WebBrowser). A Biblioteca Leaflet JS funciona na maioria deles:1

➔ Navegadores DeskTop:
➔ Chrome
➔ Firefox
➔ Safari 5+
➔ Opera 11.11+
➔ IE 7–11

➔ Navegadores Mobile:
➔ Safari para iOS 3/4/5/6+
➔ Android browser 2.2+, 3.1+, 4+
➔ Chrome para Android 4+ and iOS
➔ Firefox para Android
➔ Outros 'webkit-based browsers' (webOS, Blackberry 7+, etc.)
➔ IE10 para 'Win8-based devices'

Bom, você vai precisar de ao menos um navegador web


1 A lista completa e sempre atualizada de navegadores você encontra em http://leafletjs.com/
instalado em seu computador, para visualizar as aplicações de mapas
na web que iremos desenvolver.
Mas, lembre-se que uma boa prática a ser SEMPRE seguida é
testar o funcionamento da sua aplicação de mapas na web em todos os
navegadores disponíveis ou, pelo menos, nos navegadores mais
utilizados por quem vai acessar seus mapas (a lista acima é uma boa
referência).
Editores de Texto
Editores de Texto são pequenos programas de computador
utilizados para, acreditem, editar textos (!).
Esses programas serão utilizados por nós para escrever os
códigos das nossas aplicações de mapas na web. Existem dezenas de
opções disponíveis e, entre elas, destacamos três boas alternativas:

➔ Notepad++ (Windows)
http://notepad-plusplus.org/download/v6.5.3.html

➔ Komodo Edit (Mac)


http://www.activestate.com/komodo-edit

➔ Vim (Linux)
http://www.vim.org/

Outras alternativas são: SciTE, GNU Emacs e Aptana.


Em certo sentido, escolher um editor de textos é uma escolha
pessoal, ou seja, depende de como você se adapta à utilização de
determinado editor. Então, verifique entre as opções acima qual delas
faz com que você se sinta mais a vontade para escrever seus códigos.
Lembre-se ainda que alguns destes editores de textos são multi-
plataforma: funcionam bem em diferentes sistemas operacionais.

Biblioteca LeafletJS
Faça o download da biblioteca LeafletJS, versão 1.0.2 (a versão
mais atual no momento em que este livro foi escrito).

501 htarop .h 9
Os arquivos para download estão disponíveis no endereço
http://leafletjs.com/download.html, a página oficial da biblioteca
LeafletJS.

Conexão com a Internet


Você deverá estar conectado à internet para visualizar
corretamente os mapas na web que desenvolveremos ao longo desta
pequena jornada.
Mesmo nos primeiros capítulos, onde trabalharemos em um
ambiente local (nosso próprio computador) utilizaremos a internet
para acessar os tiles2 de nossas aplicações.

Diretórios e Pastas
Trabalhar de modo organizado é fundamental.
Para se acostumar a manter a saúde de suas aplicações de
mapas na web crie uma estrutura de pastas que permita encontrar
com facilidade os seus códigos e a correspondência entre eles e cada
capítulo deste livro.
Assim, crie uma pasta em seu computador, em um local de fácil
acesso e dê-lhe o nome de 'webmaps'. Você pode criar essa pasta em
qualquer diretório, mas recomendamos que use o diretório raiz do seu
computador (por exemplo, o diretório 'C:/', em ambiente Windows).
Dentro desta pasta 'webmaps' que você acaba de criar, crie uma
nova pasta chamada 'wm01' e, dentro desta última, mais uma pasta,
chamada 'leaflet'.
Nesta última pasta ('leaflet'), você extrairá os arquivos da
Biblioteca JavaScript Leaflet JS, disponível para download nos hiperlinks
apresentados acima. Isso significa que você copiará os arquivos “de
dentro” da pasta original para esta pasta que criamos.
Ao final destas primeiras tarefas, você terá construído a
estrutura de pastas apresentadas na figura a seguir:

2 Mais sobre tiles, você encontra no artigo "Entendendo Tiles", disponível em


http://geotecnologias.org/desenvolvendowebmaps/leituras-recomendadas/

501 htarop .h 10
FIGURA 01. ESTRUTURA DE PASTAS

É isso! Acabamos de estruturar um ambiente de trabalho


mínimo para começarmos a desenvolver nossos mapas na web!

501 htarop .h 11
...Mão na Massa!
Sem delongas.
Abra o seu Editor de Textos, copie e cole o seguinte código para
ele:

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="leaflet/leaflet.css"/>
<script src="leaflet/leaflet.js"></script>
<title>WebMap 01</title>
</head>
<body>
<div id="mapa" style="position: absolute; top: 0; left: 0; margin: 0; width: 100%;
height: 100%;"></div>
<script type="text/javascript">
var map = L.map('mapa').setView([-3.130409,-60.023426], 12);
L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
attribution: 'Mapas &copy; OpenCycleMap, Dados do Mapa &copy;
contribuidores do OpenStreetMap'
}).addTo(map);
</script>
</body>
</html>

Verifique o código copiado com cuidado e salve o arquivo com o


nome de 'index.html', dentro da pasta 'webmaps/wm01'.
Agora, vá até a pasta 'wm01', clique sobre o arquivo 'index.html'
com o botão direito do seu mouse e escolha a opção 'Abrir com' → {seu
navegador web}.

A tela a seguir deverá abrir em seu navegador:

501 htarop .h 12
FIGURA 02. VOILÀ!

Bom, seu mapa ainda não está na web, mas avançamos em


direção a isto, cumprindo algumas etapas importantes3.
Por hora, nosso próximo passo é entender o código com o qual
trabalhamos.

3 Neste livro, iremos entender como funciona a Biblioteca Leaflet JS e como desenvolver os
mapas a partir dela. Se você é muito impaciente, visite os anexos do livro e verifique como
colocar seus mapas na internet, no texto "Subindo os mapas para web!".

501 htarop .h 13
...Dissecando o código!
Bom, nós sabíamos que a hora dura ia chegar, certo?
Nossa grande sorte é que a Biblioteca LeafletJS é realmente
muito simples e fácil de entender. Vamos dar uma olhada em nosso
código mais uma vez, agora, com um novo olhar:

1. <!DOCTYPE html>
2. <html>
3. <head>
4. <link rel="stylesheet" type="text/css" href="leaflet/leaflet.css"/>
5. <script src="leaflet/leaflet.js"></script>
6. <title>WebMap 01</title>
7. </head>
8. <body>
9. <div id="mapa" style="position: absolute; top: 0; left: 0; margin:
0; width: 100%; height: 100%;"></div>
10. <script type="text/javascript">
11. var map = L.map('mapa').setView([-3.130409,-60.023426],12);
12. L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png',
{attribution: 'Mapas &copy; OpenCycleMap, Dados do Mapa &copy;
contribuidores do OpenStreetMap'}).addTo(map);
13. </script>
14. </body>
15. </html>

LEGENDA:

HTML: Hyper Text Markup Language


CSS: Cascade Style Sheeting
JS : JavaScript

Um mapa na web elaborado com a Biblioteca LeafletJS depende


(a princípio) de três linguagens diferentes (HTML, CSS e JavaScript). São
essas 03 linguagens que observamos acima.
Agora, que tal identificar cada uma destas linguagens e

501 htarop .h 14
descobrir o que elas fazem no momento em que visualizamos nosso
primeiro mapa na web?
Vamos lá!

1. <!DOCTYPE HTML>

A primeira linha é uma declaração, informando aos visitantes do


nosso código que o documento que ele está acessando é uma página
web codificada em HTML. É uma simples convenção e pode ser mais
ou menos específica4.
Para este livro, utilizaremos apenas a declaração acima.
A seção '<head>' da nossa página HTML apresenta dois links:

4. <link rel="stylesheet" type="text/css" href="leaflet/leaflet.css" />

Este é um link para o arquivo de folhas de estilo (CSS) localizado


em nossa pasta 'leaflet' ('webmap'/'wm01'/'leaflet'/'leaflet.css'). A
função deste link é trazer os estilos do arquivo CSS para que sejam
aplicados ao nosso mapa na web5.

5. <script src="leaflet/leaflet.js"></script>

Este é nosso outro link. Desta vez, ele faz a ligação com o
arquivo JavaScript localizado em nossa pasta 'leaflet'
('webmaps'/'wm01'/'leaflet'/'leaflet.js'). O arquivo linkado ('leaflet.js') é
a “máquina” do nosso mapa.

6. <title>WebMap 01</title>

Uma tag HTML para informar ao navegador o nome da nossa


página. Este título será exibido na aba do seu navegador.
Já na seção '<body>' vamos encontrar:

9. <div id="mapa" style="position: absolute; top: 0; left: 0; width: 100%; height:


100%;"></div>

4 http://www.w3.org/QA/2002/04/valid-dtd-list.html
5 Que tal ser curioso e abrir o arquivo 'leaflet.css' em seu editor de textos? Certifique-se apenas
de não alterá-lo, se não souber o que está fazendo, é claro...

501 htarop .h 15
Bom, relembrando, a tag '<div>' tem a função de criar “blocos de
elementos” em nossa página, indicando ao navegador web onde e
como “plotar” estes blocos na página.
A cada elemento '<div>' atribuímos um identificador 'id' único
(um caractere alfanumérico que não se repete em nosso código).
Nesse caso, nosso 'id' é 'mapa'.
Dentro de 'style=' encontramos especificações de posição e
tamanho da '<div>' onde está inserido nosso mapa na web, escritas em
linguagem CSS.
Agora, a seção '<script>':

10. <script type="text/javascript">


var map = L.map('mapa').setView([-3.130409,-60.023426], 12);
L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
attribution: 'Todos os Mapas &copy; OpenCycleMap, dados do mapa
&copy; contribuidores do OpenStreetMap'
}).addTo(map);
</script>

Vamos entender esse trecho linha por linha:

10. <script type="text/javascript">

A primeira linha deste bloco de código simplesmente informa ao


navegador: o que vem a seguir é um script, escrito em linguagem
JavaScript.
Em seguida, temos nosso primeiro trecho de JavaScript:

11. var map = L.map('mapa').setView([-3.119947,-60.020424], 12);

'var', em JavaScript, é uma palavra reservada para declarar uma


variável. A função da “variável” é armazenar um valor ou uma função
na memória, permitindo que acessemos essa variável posteriormente.
Na sentença acima, declaramos uma variável com o nome 'map'.
Essa declaração é feita a partir de uma “classe”, chamada
'L.map', que é responsável por efetivamente criar nosso mapa –
chamaremos essas classes de “construtores”.

501 htarop .h 16
Depois, vinculamos nosso mapa à '<div id= “mapa”>' que
havíamos criado, incluindo o 'id' da nossa '<div>' entre os parênteses
do nosso construtor → L.Map('mapa').
Ou seja, com o nosso código, dissemos o seguinte: “o mapa
deverá ficar dentro da '<div>' chamada 'mapa'.”
Em seguida, utilizamos o método 'setView' para definir as duas
opções que caracterizam nosso mapa.
As opções do 'setView' são: coordenadas do centro do mapa ao
iniciar a aplicação (latitude e longitude) '[-3.130409,-60.023426]' e o
zoom inicial do nosso mapa, identificado apenas com o nível de zoom
que é apresentado ao iniciarmos o mapa6.
Agora, temos o seguinte trecho:

12. L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
attribution: 'Todos os Mapas &copy; OpenCycleMap, dados do mapa
&copy; contribuidores do OpenStreetMap'
}).addTo(map);

'L.tileLayer(…)' é outra classe (construtor) da biblioteca LeafletJS,


utilizada para “carregar tiles” em nosso mapa. Os tiles são adicionados
ao nosso mapa, utilizando o 'método' – 'addTo(...)'. Tiles nada mais são
que recortes georreferenciados da imagem de um mapa. Os tiles ficam
armazenados em um servidor web e são acessados por meio de um
link URL (um endereço web). No nosso caso, estamos utlizando os tiles
do OpenCycleMap7.
O seguinte trecho...

attribution: 'Todos os Mapas &copy; OpenCycleMap, dados do mapa &copy;


contribuidores do OpenStreetMap'

...informa a fonte dos tiles que utilizamos, gerados pelo


OpenCycleMap.
É isso! Esse é o código básico para todas as aplicações de mapas
na web que você vai desenvolver com a Biblioteca LeafletJS.

6 Nosso mapa utiliza tiles do OSM – OpenStreetMap – e as opções de zoom variam de 0 a 19.
7 www.opencyclemap.org/docs e www.openstreetmaps.org

501 htarop .h 17
Coisas para tentar!
Antes de seguir até o próximo capítulo, gostaríamos de convidá-
lo para tentar algumas coisas a partir do código com o qual
trabalhamos anteriormente.
Tamanho e posição do mapa
A tag HTML '<div>' usa a linguagem CSS para especificar o
tamanho e a posição de um bloco da página. Em CSS, definimos a
altura e a largura (heigth e width), deste bloco, utilizando porcentagem
(%) ou pixels (px). Abra o seu código no editor de textos e modifique a
altura e a largura como mostrado abaixo:

<div id="mapa" style="position: absolute; top: 0; left: 0; margin: 0; width: 50%;


height: 50%;"></div>

Após alterar os valores de 'heigth:' e 'width:' para 50%, salve seu


arquivo na mesma pasta como 'index01.html' e abra-o em um
navegador web. Você deverá visualizar o seguinte:

FIGURA 03. HUH!

Agora, vamos fazer mais uma alteração:

<div id="mapa" style="position: absolute; top: 25%; left: 25%; margin: 0; width: 50%;
height:50%;"></div>

Altere os valores de 'top:' e 'left:' para 25%, salve as alterações


na mesma pasta como 'index02.html' e abra seu arquivo em um
navegador web. Você deverá observar a seguinte tela:

501 htarop .h 18
FIGURA 04. AHHH.....

Experimente aumentar e diminuir a janela do seu navegador.


Faça também algumas alterações utilizando pixels ao invés de valores
de porcentagem, utilizando os valores “700px” para altura e '500px”
para largura. É isso!
Modificando o zoom inicial
Abra nosso arquivo original no seu editor de textos e
experimente substituir o valor do zoom inicial ('12') por '18' e, e
seguida por '4'.

var map = L.map('mapa').setView([-3.130409,-60.023426], 12);

Salve na mesma pasta, respectivamente como 'index03.html' e


'index4.html'. Abra os arquivos em seu navegador web e observe as
alterações.

501 htarop .h 19
Modificando o mapa base
Abra seu arquivo de código original em seu editor de textos e
experimente substituir o endereço web do link para os tiles do
OpenCycleMap, encontrado na linha...

L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png')
...por cada em dos seguintes endereços, um de cada vez:

OpenStreetMap. 'http://{s}.www.toolserver.org/tiles/bw-mapnik/{z}/{x}/{y}.png'
BlackAndWhite
OpenMapSurfer.
Roads 'http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png'

Thunderforest. 'http://{s}.tile.thunderforest.com/landscape/{z}/{x}/{y}.png'
Landscape

Salve cada nova alteração como um index diferente:


'index05.html', 'index06.html' e 'index07.html' e abra em seu
navegador.
FIGURA 05. VOILÀ! II – A MISSÃO

Diferentes provedores de tiles = diferentes mapas-base8.

8 Veja uma lista de provedores de tiles clicando aqui!

501 htarop .h 20
501 htarop .h 21
Um Mapa mais
Interessante
Preparar um ambiente de desenvolvimento local
Adicionar marcadores ao seu mapa
Adicionar Popups aos seus marcadores
Adicionar múltiplos marcadores ao seu mapa
...Preparando um Ambiente de Desenvolvimento
No capítulo anterior nós preparamos nosso ambiente de
desenvolvimento local. Tudo o que faremos daqui por diante para
desenvolver novos mapas na web é reutilizá-lo.
Apenas relembrando: temos nosso(s) navegador(es) web, nosso
editor de textos favorito, a Biblioteca LeafletJS, uma conexão com a
Internet e nosso conjunto de diretórios e pastas já organizado, além, é
claro, do nosso código básico para aplicações de mapas na web.
Agora, criaremos uma cópia da nossa pasta 'wm01', salvando
essa cópia dentro da pasta 'webmaps' e renomeando-a para 'wm02'.
Dentro dela, deixaremos apenas a pasta 'leaflet' e o arquivo
'index.html' original.
Você terá a seguinte estrutura de pastas:

FIGURA 06. ESTRUTURA DE PASTAS

Só isso! Vamos adiante.

Adicionando um Marcador
...Mão na Massa!
Abra o arquivo 'index.html', salvo na pasta 'wm02', em seu
editor de textos. Insira o trecho de código destacado (abaixo) após o
construtor 'L.tileLayer(...);', como mostrado a seguir:
<script type="text/javascript">

var map = L.map('map').setView([-3.130409,-60.023426], 16);

L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {

attribution: 'Todos os Mapas &copy; OpenCycleMap, dados do mapa


&copy; contribuidores do OpenStreetMap'

}).addTo(map);

L.marker([-3.130409,-60.023426]).addTo(map)
.bindPopup('<center>Teatro Amazonas <br> inaugurado em
1896.</center>').openPopup();

</script>

Verifique o código copiado com cuidado e salve o arquivo com o


nome de 'index.html', sobrescrevendo o arquivo original, dentro da
pasta 'webmaps/wm02'.
Agora, vá até a pasta 'wm02', clique sobre o arquivo 'index.html'
com o botão direito do seu mouse e escolha a opção 'Abrir com' →
{seu navegador web}.
A tela a seguir deverá abrir em seu navegador:

FIGURA 07. VOILÀ! III, O RETORNO

501 htarop .h 24
...Dissecando o código!
Muito bem, vamos discutir como funciona a inserção de um
marcador em seu mapa desenvolvido com a Biblioteca Leaflet JS.
Nós inserimos o seguinte trecho de código:

L.marker([-3.130409,-60.023426]).addTo(map)
.bindPopup('<center>Teatro Amazonas <br> inaugurado em
1896.</center>').openPopup();

Perceba que utilizamos um novo construtor (Factory, como


aparece na documentação original do LeafletJS) chamado 'L.marker',
cuja responsabilidade é inserir marcadores em nosso mapa (marker =
marcador).
Quando utilizamos este construtor, nosso código acessa as
referências do código JavaScript que este construtor utiliza, no arquivo
'leaflet.js' que havíamos incluído como um link em nossa seção
'<head>'; lembra?
Em seguida, indicamos ao nosso objeto 'L.marker(...)' ONDE está
localizado o nosso marcador, informando a ele um par de
coordenadas geográficas (Lat, Long – Latitude e Longitude).
Então, o resultado é adicionado ao mapa por meio do método
'add.To('map')', que já havíamos discutido no capítulo anterior.
Em seguida, por meio do método '.bind' (que cria um “adendo”
ao nosso marcador), acrescentamos uma 'Popup' → '.bindPopup(...)'.
Por fim, utilizamos a linguagem HTML e suas tags para incluir o
conteúdo da nossa Popup:

('<center>Teatro Amazonas <br> inaugurado em 1896.</center>')

Além da utilização das tags HTML, nossa Popup pode ser


customizada por meio da utilização da linguagem CSS.
Très simple!

501 htarop .h 25
Adicionando Múltiplos Marcadores
Mapas com um único marcador são muito úteis para apresentar
a localização de um prédio, um equipamento público, um evento, etc,
mas, algumas vezes precisamos apresentar múltiplas localizações em
um mesmo mapa (por exemplo: pontos de checagem de uma corrida
de aventura ou todos os postos de saúde de uma cidade) e, para isso,
precisaremos inserir múltiplos marcadores em um único mapa.
E como fazemos isso? Colocando a...

...Mão na Massa!
Vamos lá! E, "para ir", utilizaremos o arquivo 'index.html' da
pasta 'wm02'. Faça uma cópia deste arquivo e renomeie-o para
'index01.html'. Abra-o em seu editor de textos.
Agora, copie e cole o código abaixo entre as tags '<script
type="text/javascript"><script>', apagando todo o código que estava lá
anteriormente:

var map = L.map('mapa').setView([-3.134635, -60.020704], 15);


L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
attribution: 'Mapas &copy; OpenCycleMap, Dados do Mapa &copy;
contribuidores do OpenStreetMap'
}).addTo(map);
L.marker([-3.130409,-60.023426]).addTo(map).bindPopup('<center>Teatro
Amazonas, <br> inaugurado em 1896.</center>').openPopup();
L.marker([-3.139973,
-60.023676]).addTo(map).bindPopup('<center>Mercado Municipal Adolpho
Lisboa, <br> inaugurado em 1883.</center>');
L.marker([-3.134978,
-60.016863]).addTo(map).bindPopup('<center>Palácio Rio Negro, <br> construido
no fim do seculo XIX.</center>');

Salve o arquivo 'index01.html', vá até a pasta 'wm02', clique com


o botão direito do mouse sobre o arquivo 'index01.html' e abra-o em
seu navegador web. Você verá:

501 htarop .h 26
FIGURA 08. ...'VOILÀ! III, O RETORNO DA MISSÃO'

Legal, agora temos três marcadores em nosso 'webmap' – note


que os três apontam a localização de diferentes edifícios históricos de
Manaus.
Clique sobre os três diferentes marcadores apresentados em
nosso mapa e cheque as popups.
Tudo OK?
Hummmm....quer dizer que você não sabe por que ao invés do
caractere “á” apareceu o caractere “á”?
E agora? Como vamos resolver essa questão?
Vamos resolvê-la...
...Dissecando o Código!
Calma! Antes de dissecarmos o código, mais um pouco de mão
na massa! Abra seu arquivo 'index01.html' em seu editor de textos e
insira o trecho de código destacado abaixo, de acordo com a estrutura
apresentada:
<head>

<link rel="stylesheet" type="text/css" href="leaflet/leaflet.css"/>

<meta charset="UTF-8">

<script src="leaflet/leaflet.js"></script>

<title>WebMap</title> </head>

501 htarop .h 27
Repita o procedimento (nosso conhecido procedimento...) e
abra o seu arquivo 'index01.html' em seu navegador web.
Clique novamente sobre o marcador referente à localização do
Palácio Rio Negro e confira a popup.
Hey! Agora sim!!
“- Avante, compañeros, vamos dissecar o código!”
O trecho '<meta charset= “UTF-8”>' é responsável por
apresentar, em nosso navegador web, os caracteres especiais (ç, á, é, í,
ó, ú, etc) e, como nossa língua mãe (querida mãe!) é rica nesses
caracteres, a partir de agora vamos sempre incluir esse trecho em
nossos códigos, ok?
Adiante!
Outra alteração em nosso código, que podemos observar, é
com relação ao ponto central do mapa e ao zoom inicial que aplicamos,
no seguinte trecho:

var map = L.map('mapa').setView([-3.134635, -60.020704], 15);

O centro do nosso mapa agora possui as coordenadas


-3.134635, -60.020704 e o zoom inicial que aplicamos é 15.
Estes ajustes foram realizados para obtermos uma visualização
'melhor ajustada' dos três marcadores na tela do computador e foram
realizados editando o código, como vimos nos capítulos anteriores.
O mapa base continua definido da mesma maneira (o trecho de
código que se inicia com 'LtileLayer') .
Agora, finalmente, vamos aos marcadores:

L.marker([-3.130409,-60.023426]).addTo(map).bindPopup('<center>Teatro
Amazonas, <br> inaugurado em 1896.</center>').openPopup();
L.marker([-3.139973,
-60.023676]).addTo(map).bindPopup('<center>Mercado Municipal Adolpho
Lisboa, <br> inaugurado em 1883.</center>');
L.marker([-3.134978,
-60.016863]).addTo(map).bindPopup('<center>Palacio Rio Negro, <br> construido
no fim do seculo XIX.</center>');

501 htarop .h 28
Nós mantivemos o marcador preexistente, com a localização do
Teatro Amazonas e acrescentamos dois novos marcadores.
Inserimos estes novos marcadores apenas reproduzindo o
formato de código9 que utilizamos para o primeiro marcador. Note
que, ao final de cada marcador utilizamos “;”, fechando as sentenças.
As alterações ficaram restritas, então, à localização de cada
marcador, às suas coordenadas e ao texto que apresentamos nas
popups. Note que em nossos novos marcadores, retiramos o trecho de
código “openPopup()”, assim, a popup a ser aberta quando iniciamos o
mapa no navegador web é a que se refere ao Teatro Amazonas.
(note esta outra nota: a biblioteca LeafletJS não abre, por
padrão, múltiplas popups. Ou seja, caso todos os três marcadores
possuíssem o código “openPopup()”, apenas o último abriria uma
popup).
Muito legal, né?
Respire, dê uma caminhada e volte para o nosso próximo capítulo!

9 Essa é uma prática muito comum, o "reaproveitamento" de um trecho de código. Acostume-se


e utilize essa técnica!

501 htarop .h 29
Tudo o que você sempre quis saber sobre

Marcadores e Popups
mas não tinha coragem de perguntar...

Preparar um ambiente de desenvolvimento local


Adicionar marcadores customizados ao seu mapa
Adicionar múltiplos marcadores customizados ao seu mapa
Adicionar Popups customizadas aos seus marcadores
Agrupar marcadores em camadas
Um marcador customizado
...Preparando um Ambiente de Desenvolvimento
Bom, você já deve ter se acostumado com o procedimento de
preparação de um ambiente de desenvolvimento, mas, ainda assim,
vamos lá! O que temos a fazer é criar uma cópia da pasta 'wm02' e
renomeá-la como 'wm03', apagando o arquivo 'index01.html',
entendido?
Apenas isso! Agora, arregace as mangas e...
...Mão na Massa!
Faça o download das imagens que utilizaremos para o nosso
marcador customizado através do endereço eletrônico
http://geotecnologias.org/desenvolvendo-webma ps/.
Após o download, salve todas as imagens na pasta
'webmaps/wm03/leaflet/images'.
OK!
Agora, abra o arquivo 'index.html' (na pasta 'wm03') e apague o
trecho do código referente ao marcador10 (este trecho se inicia em
'L.marker(...)' e termina em '.openPopup();').
No lugar do código que apagamos, copie e cole o trecho a
seguir:

var teatro = L.icon({


iconUrl: 'leaflet/images/teatro.png',
shadowUrl: 'leaflet/images/teatro-sombra.png',
iconSize: [80, 80],
shadowSize: [80, 46],
iconAnchor: [40, 40],
shadowAnchor: [60, 0],
popupAnchor: [0, -35]
});
L.marker([-3.130409,-60.023426], {icon:
teatro}).addTo(map).bindPopup('<center>Teatro Amazonas <br> inaugurado em
1896.</center>').openPopup();

10 Vimos qual é o trecho a que nos referimos no capítulo anterior, lembra?


Muito bom! Agora salve seu arquivo, vá até a pasta 'wm03' e
abra o arquivo 'index.html' em seu navegador. Logo adiante nós
discutiremos este trecho de código acima, detalhadamente.
Você deverá ver a seguinte imagem:

FIGURA 09. ...'VOILÀ!' IV – NUNCA MAIS 'VOILÀ!'

Legal! Isso funciona, hun?! Certo, agora, sigamos...

...Dissecando o código!
Antes de irmos por partes, vamos por partes...
O marcador “padrão” da Biblioteca LeafletJS (o ícone azul) é
composto, na verdade, por dois arquivos de imagem em formato
.png11 e ambos ficam armazenados na pasta 'leaflet/images':
FIGURA 10. MARCADOR PADRÃO

Para compor o “marcador padrão” (que visualizamos em nossas


aplicações), as duas imagens ('marker.png' e 'shadow.png') são
combinadas em um resultado final – já, já entenderemos como isso é
feito.
Para o nosso “marcador customizado” (o novo marcador),
utilizamos dois outros arquivos de imagens, em formato .png, também
11 Portable Network Graphics, veja as referências em http://pt.wikipedia.org/wiki/PNG

501 htarop .h 32
combinados:

FIGURA 11. MARCADOR CUSTOMIZADO

Uma dica: você pode encontrar inúmeros websites para download de icons
(ícones) ou utilizar um software de desenho gráfico, como o Inkscape
(opensource) por exemplo, para produzir seu marcador .png
personalizado.

Então, inserir um marcador customizado é uma tarefa realizada


em duas partes.
A primeira parte corresponde ao ato de definir (i) QUEM é o
seu marcador e definir (ii) COMO ele aparecerá em seu mapa.
(i) QUEM é o seu marcador?

var teatro = L.icon({


iconUrl: 'leaflet/images/teatro.png',
shadowUrl: 'leaflet/images/teatro-sombra.png', (...)

O trecho de código acima nos dá essa resposta, dizendo 'quem'


é o nosso marcador. Ou seja, nosso marcador se chama “teatro” e é
construído a partir de duas imagens: 'teatro.png' e a sua sombra
(shadow) 'teatro-sombra.png'.
Bom, isso é feito a partir da utilização de um construtor
'L.icon(...)', que define quem é nosso marcador e define as imagens
que vamos utilizar. Ele 'liga' nosso ícone principal 'iconUrl:
'leaflet/images/teatro.png' ' e a sua sombra 'shadowUrl:
'leaflet/images/teatro-sombra.png' ', indicando a URL de cada um dos
arquivos de imagem.

501 htarop .h 33
OK! Acabamos de ver como funciona a definição de quem é o
nosso marcador. Mas como ele aparece em nosso mapa? Bem, (ii)
COMO é definido a partir de um conjunto de opções:

iconSize: [80, 80], // que define valores para o tamanho do ícone


(largura, altura)
shadowSize: [80, 46], // que define valores para o tamanho da sombra
(idem)
iconAnchor: [40, 40], // define a ancoragem do centro do ícone em
relação às coordenadas do local do marcador
shadowAnchor: [60, 0], // ponto da sombra que corresponde ao seu
local no mapa
popupAnchor: [0, -35] // ponto da apresentação da âncora da popup,
com relação ao 'iconAnchor'

Todos estes pares de valores acima, referem-se à ancoragem das


figuras do marcador e correspondem ao ato de definir os tamanhos e
as posições das imagens que utilizamos, além de definir as relações
entre elas.
A segunda parte da criação de um marcador customizado
corresponde ao ato de inseri-lo em nosso webmap.
Isto é feito utilizando-se o mesmo procedimento utilizado para
inserir um marcador padrão, com um único detalhe diferente: o
detalhe de “informarmos” que utilizaremos o nosso marcador
customizado: {icon: teatro}, observe:

L.marker([-3.130409,-60.023426],
{icon:teatro}).addTo(map).bindPopup('<center>Teatro Amazonas <br>
inaugurado em 1896.</center>').openPopup();

Simples assim.
Bom, refrescando a memória, logo abaixo retomamos nossa
“receita” para criar marcadores customizados:
• Crie o ícone (e sua sombra) em formato .png;
• Insira as imagens na pasta 'leafletjs/images';
• Crie um marcador customizado por meio da declaração de uma

501 htarop .h 34
variável, a partir do construtor 'L.icon';
• Insira o marcador no mapa, indicando o ícone a ser utilizado (o
nome da variável do marcador customizado).
E é isso!
Bem legal, né?

Bom, para alguns de nós, essa parte foi um pouco mais dura de
apreender. Então, recomendo que você faça uma pequena pausa, respire,
tome um café e pense sobre o assunto. Se a ficha cair, ótimo. Caso a ficha
não caia de primeira, releia, faça testes, seja criativo para aprender! Uma
segunda leitura, com novos olhos sobre o problema, sempre é mais
auspiciosa.

Múltiplos marcadores customizados


...Mão na Massa!
OK! Faça uma cópia do arquivo 'index.html' e renomeie-o para
'index01.html'. Abra-o em seu editor de textos e substitua o código
pré-existente (entre as tags '<script>') pelo seguinte:

var map = L.map('mapa').setView([-3.134635, -60.020704], 15);


L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
attribution: 'Mapas &copy; OpenCycleMap, Dados do Mapa &copy;
contribuidores do OpenStreetMap'
}).addTo(map);
var teatro = L.icon({
iconUrl: 'leaflet/images/teatro.png',
shadowUrl: 'leaflet/images/teatro-sombra.png',
iconSize: [80, 80],
shadowSize: [80, 46],
iconAnchor: [40, 40],
shadowAnchor: [60, 0],
popupAnchor: [0, -35] });
var mercado = L.icon({
iconUrl: 'leaflet/images/mercado.png',

501 htarop .h 35
shadowUrl: 'leaflet/images/teatro-sombra.png',
iconSize: [80, 80],
shadowSize: [80, 46],
iconAnchor: [40, 40],
shadowAnchor: [60, 0],
popupAnchor: [0, -35] });
var palacio = L.icon({
iconUrl: 'leaflet/images/palacio.png',
shadowUrl: 'leaflet/images/teatro-sombra.png',
iconSize: [80, 80],
shadowSize: [80, 46],
iconAnchor: [40, 40],
shadowAnchor: [60, 0],
popupAnchor: [0, -35] });
L.marker([-3.130409,-60.023426], {icon:
teatro}).addTo(map).bindPopup('<center>Teatro Amazonas <br> inaugurado em
1896.</center>').openPopup();
L.marker([-3.139973, -60.023676], {icon:
mercado}).addTo(map).bindPopup('<center>Mercado Municipal Adolpho Lisboa,
<br> inaugurado em 1883.</center>');
L.marker([-3.134978, -60.016863], {icon:
palacio}).addTo(map).bindPopup('<center>Palacio Rio Negro, <br> construido no
fim do seculo XIX.</center>');

Após salvar seu arquivo com as alterações, abra-o em seu


navegador, repetindo nossa operação padrão. Você verá:

501 htarop .h 36
FIGURA 12. ...NUNCA MAIS 'VOILÀ!' (MAIS UMA VEZ)

Você já sabe, vamos seguir...

...Dissecando o código!

Bons e velhos dissecadores de código, vamos lá!


Tudo bem, nós mantivemos o mesmo mapa-base, declarado
pela variável 'var map' (mesmo procedimento que acabamos de
realizar, logo ali, acima...), com alterações da posição inicial do mapa.
E, no fim das contas, o que fizemos foi reproduzir a estrutura
que utilizamos para incluir um único marcador customizado (nossa
primeira conversa neste capítulo, lembra-se?), ou seja, informamos
como o nosso marcador e a sua sombra devem ser apresentados para,
em seguida, utilizarmos essa informação em nosso marcador no
mapa.
O interessante é que podemos “mimetizar” esse tipo de
estrutura de códigos utilizando novos marcadores, indefinidamente: é
exatamente o que fizemos aqui.
As variáveis 'teatro', 'mercado' e 'palacio' remetem aos
diferentes arquivos '.png' (nossos ícones) que serão apresentados no
mapa.
Assim, podemos perceber como é fácil manipular os
marcadores: o destaque fica para os cuidados a se tomar no momento
de “desenhar” nosso mapa e incluir os ícones específicos relacionados

501 htarop .h 37
aos marcadores corretos.
Por fim, utilizamos os mesmos procedimentos para incluir
nossos marcadores ao mapa, por meio do construtor 'L.marker'.
Ei, você conseguiu entender o que eu disse, sem que eu
precisasse ilustrar com trechos de código. Isso é fantástico!
Como sempre, adiante!

Agrupando Marcadores em Camadas


Vamos trabalhar aqui com duas novas técnicas: agrupar
marcadores em camadas (“layers”) e construir um controle para ligar e
desligar essas camadas em nosso mapa. Vamos lá!

...Mão na Massa!
Dentro da pasta 'wm03', faça uma cópia do arquivo 'index.html'
e, após isso, abra o arquivo 'index02.html' em seu editor de textos.
Agora, vamos lá! Nossa meta aqui é criar um webmap que
apresente algumas localizações no mapa, para que um turista que
pretenda ir a Manaus possa conhecer alguns prédios históricos e
verificar a localização de possíveis hotéis, restaurantes, postos de
saúde e delegacias de polícia.
Então, vamos repetir o conhecido procedimento, substituindo o
código entre as tags html '<script>' do seu arquivo 'index02.html',
aberto em seu editor de textos, pelo código apresentado a seguir:

var map = L.map('mapa').setView([-3.134772, -60.020626], 14);


L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
attribution: 'Mapas &copy; OpenCycleMap, Dados do Mapa &copy;
contribuidores do OpenStreetMap'
}).addTo(map);
var predioshistoricos = L.layerGroup([
L.marker([-3.130409,-60.023426]).bindPopup('<center>Teatro Amazonas
<br> inaugurado em 1896.</center>'),
L.marker([-3.139973, -60.023676]).bindPopup('<center>Mercado Municipal
Adolpho Lisboa, <br> inaugurado em 1883.</center>'),

501 htarop .h 38
L.marker([-3.134978, -60.016863]).bindPopup('<center>Palacio Rio Negro,
<br> construido no fim do seculo XIX.</center>')
]).addTo(map);
var hospedagem = L.layerGroup([
L.marker([-3.137795, -60.017667]).bindPopup('Hotel JM'),
L.marker([-3.136092, -60.023020]).bindPopup('Hotel Lord Manaus'),
L.marker([-3.138866, -60.018343]).bindPopup('Hotel Luis XV')
]).addTo(map);
var alimentacao = L.layerGroup([
L.marker([-3.136849, -60.023591]).bindPopup('Casa do Guaraná'),
L.marker([-3.139195, -60.020244]).bindPopup('Restaurante Jangada'),
L.marker([-3.140042, -60.023108]).bindPopup('Restaurante Tempero
Douro')
]).addTo(map);
var saude = L.layerGroup([
L.marker([-3.130700, -60.019329]).bindPopup('Beneficença Portuguesa'),
L.marker([-3.127272, -60.016601]).bindPopup('INCOR'),
L.marker([-3.130507, -60.012176]).bindPopup('Pronto Socorro')
]).addTo(map);

L.control.layers ({}, {
'Prédios Históricos': predioshistoricos,
'Hospedagem': hospedagem,
'Aimentação': alimentacao,
'Saúde': saude
}).addTo(map);

Você já sabe...! Salve o arquivo html e abra-o em seu navegador.


Você deverá ver o seguinte webmap:

501 htarop .h 39
FIGURA 13. ...DIMAIS ESSE TREM, SÔ!'

Note que ali, no canto direito-superior, existe um pequeno


ícone: coloque seu mouse sobre ele e ligue e desligue as camadas.
Interessante, né?
Vamos adiante, ...

...Dissecando o Código!
Muito bom!
A primeira coisa a se dizer é que declaramos coordenadas
diferentes para o início do mapa, com o intuito de ajustar melhor
nosso mapa aos marcadores que são apresentados.
O segundo ponto a ser discutido é “Como agrupamos
marcadores em camadas?”.
Fazemos isso declarando uma variável e utilizando o construtor
'L.layerGroup', utilizando a seguinte estrutura:

var nomedavariavel = L.layerGroup ([ marcadores ]).addTo(map);

Note que, para cada grupo de camadas, nós reaproveitamos a


mesma estrutura de código; investigue o código para entender!
Por último, acrescentamos o construtor 'L.control.layers' e
dizemos quais grupos de camadas queremos apresentar em nosso
mapa, no trecho:

501 htarop .h 40
L.control.layers ({}, {
'Prédios Históricos': predioshistoricos,
'Hospedagem': hospedagem,
'Aimentação': alimentacao,
'Saúde': saude
}).addTo(map);

Beeeem interessante.
Só uma dica: experimente incluir o trecho destacado a seguir
no seu código:

L.control.layers ({}, {
'Prédios Históricos': predioshistoricos,
'Hospedagem': hospedagem,
'Aimentação': alimentacao,
'Saúde': saude
},{collapsed:false}).addTo(map);

Show!

Customizando Popups
Encerrando esse capítulo, vamos rapidamente dar uma olhada em
como customizar as popups de nossos mapas na web, o que pode ser
bem útil no momento de definir um desenho ('design') interessante
para os nossos mapas.

501 htarop .h 41
Mão na Massa!
a. Mudando a cor de fundo
Dentro do seu diretório 'webmaps', faça uma cópia da pasta
'wm02' (atenção!) e renomeie-a para 'wm04'. Dentro desta última
pasta, apague o arquivo 'index01.html' e, logo depois, acesse a pasta
'wm04/leaflet/' e abra o arquivo 'leaflet.css' (atenção!) em seu editor de
textos. Ok!
Encontre, na linha 428 (ou próximo a essa linha), o seguinte
trecho de código:

.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: white;
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
}

Este trecho de código define a cor de fundo (background) da sua


popup. Substitua a palavra “white” pela palavra “black”. Salve o arquivo
'leaflet.css' e abra o arquivo 'index.html' em seu navegador web; você
deverá ver o seguinte:
FIGURA 14. ...ÊITA, QUISTRANHO!'

Muito bom... Com essa simples alteração, você poderá


encontrar inúmeras possibilidades de cores para as suas popups.

501 htarop .h 42
Mas, temos um GRANDE problema! (fui irônico, sabe?!): essa
alteração fez com que o 'background' e a cor do texto ficassem iguais,
impedindo que lêssemos o conteúdo da nossa popup.
E agora?
b. Mudando a Cor dos Caracteres
Bom, essa é uma tarefa muuuiiitttooo complicada (fui irônico, de
novo, não teve graça, mas fui...).
Tudo o que temos a fazer aqui é o seguinte: no trecho de código
que acabamos de utilizar, mostrado acima, apenas inclua a sentença
“color: white;” na linha abaixo de “background: black;” , como
apresentamos a seguir:

.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: black;
color: white; - - - trecho a ser incluído
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
}

Repita nosso bom e velho procedimento, aquele, salvando o


arquivo e clicando com o botão direito sobre 'index.html', abrindo o
arquivo em seu navegador web. Você deverá ver o seguinte:
FIGURA 15. ...BUNITO DIMAIS DA CONTA, SÔ!'

Ok!

501 htarop .h 43
c. Mudando as bordas
Uma última alteração em nossas popups antes de seguirmos
adiante. Dentro do mesmo arquivo 'leaflet.css', na linha 396, faremos
mais uma alteração, no seguinte trecho de código:

.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
border-radius: 12px; - você vai substituir este valor!
}

Em língua inglesa, “border” significa “borda” e “radius” significa


“raio”, logo “border-radius” permite que...alteremos a curvatura do raio
da borda! (Incrível!)12.
Substitua o valor de '12px' por '0px'.
Abra o arquivo em seu navegador e você deverá visualizar:

FIGURA 16. COMEÇO A ME SENTIR PODEROSO...

Note que, no código CSS, há dezenas de outras opções passíveis


de alteração. Experimente! Com cuidado, reservando uma pasta para
os testes, mas experimente!
É isso aí, já chegamos longe, mas ainda vamos adiante!!
12 Fiz essa brincadeira, mas, pensando bem, se você der uma “garibada” no seu inglês, pelo
menos tentando traduzir elementos-chave da Biblioteca LeafletJS, você conseguirá encontrar
com mais facilidade os trechos de código que precisa alterar. #ficaadica

501 htarop .h 44
Desenhando sobre mapas com

Linhas, Círculos e
Polígonos
Preparar um ambiente de desenvolvimento local
Adicionar Camadas Vetoriais - Linhas, Círculos e Retângulos
Aplicar Estilos (espessura, cor, transparência) aos vetores
Entender o funcionamento de serviços arquivos GeoJson
Desenhando Linhas sobre o mapa
Até aqui, conversamos sobre como representar locais ou
eventos pontuais em nossos mapas, explorando algumas das
possibilidades que a biblioteca LeafletJs nos oferece. E isso foi legal!
Mas, e se quisermos representar linhas em nossos mapas interativos?
Trajetos, ruas, falhas geológicas? Bom, precisaremos de linhas
desenhadas sobre os nossos mapas. E como fazer isso? Seguindo
adiante e...
...Preparando um Ambiente de Desenvolvimento
OK! Faça uma cópia da pasta 'wm02' (02, certo?) e renomeie-a
para 'wm05'. Dentro da pasta 'wm05', apague o arquivo 'index01.html'
e abra o arquivo em 'index.html' em seu editor de textos.
Agora...
...Mão na Massa!
Remova todo o código entre as tags '<script
type="text/javascript"></script>'.
Perfeito! Agora, copie e cole, com cuidado!, o seguinte trecho de
código entre as referidas tags:

var map = L.map('mapa').setView([-3.137868, -60.020485], 16);


L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
attribution: 'Mapas &copy; OpenCycleMap, Dados do Mapa &copy;
contribuidores do OpenStreetMap'}).addTo(map);
var linha01 = [{"type": "LineString",
"coordinates": [
[-60.02325922250748,-3.139830489468738],
[-60.02157747745513,-3.1405134258024203],
[-60.01907229423523,-3.134747286576336],
[-60.01666367053985,-3.1347205046200077]
]}
];
var estilodalinha01 = {
"color": "#93131e",
"weight": 3,
"opacity": 1
};
L.geoJson(linha01, {style: estilodalinha01}).addTo(map).bindPopup('Acredite, eu
sou uma linha em um mapa!').openPopup();

Ótimo! Agora salve seu arquivo, vá até a pasta 'wm05' e abra o


arquivo 'index.html' em seu navegador web.
Você deverá ver a seguinte imagem em seu navegador web:

FIGURA 17. '...MÃE, FIZ UM DESENHO!'

- Ei, sem preguiça!


Vamos entender o código!

...Dissecando o código!
Bora lá!
A primeira parte do nosso código, como já vimos anteriormente,
é responsável por trazer o mapa base para o nosso mapa. Fizemos
algumas alterações com relação ao zoom inicial e ao centro do mapa,
um procedimento que você já conhece:
var map = L.map('mapa').setView([-3.137868, -60.020485], 16);
L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
attribution: 'Mapas &copy; OpenCycleMap, Dados do Mapa &copy;
contribuidores do OpenStreetMap'}).addTo(map);
Agora, vamos ao trecho do código responsável pela geometria

501 htarop .h 47
da linha apresentada no mapa.

var linha01 = [{"type": "LineString",


"coordinates": [
[-60.02325922250748,-3.139830489468738],
[-60.02157747745513,-3.1405134258024203],
[-60.01907229423523,-3.134747286576336],
[-60.01666367053985,-3.1347205046200077]
]}
];

OK! Nossa linha é construída mediante a declaração de uma


variável ('var linha01') e de seu 'tipo' (o tipo de variável), ou seja, “a que
se refere essa variável” ('LineString'). Então, o nosso tipo de variável se
refere ao formato de arquivo GeoJson13, conhecido como LineString
(linha).
Logo em seguida, a partir do trecho 'coordinates: [', o que
fazemos é declarar uma série de pares de coordenadas geográficas,
referentes aos vértices da nossa linha; observe a figura a seguir:

13 GeoJson é um formato de arquivo para 'codificar' uma variedade de estruturas de dados


geográficos – pontos, linhas, polígonos, círculos, entre outros). Não se preocupe com isso
agora! Mas se preocupe depois... :)

501 htarop .h 48
FIGURA 18. 'PRECISA DESENHAR?!'

A figura acima apresenta com clareza quais os pares de coordenadas responsáveis


por gerar quais vértices. Interessante esse modo de construir linhas, não?

Isso significa que para desenharmos uma linha em nosso mapa,


utilizamos os pares de coordenadas de seus vértices. Bem fácil, não?
O trecho seguinte do nosso código...

var estilodalinha01 = {
"color": "#93131e",
"weight": 3,
"opacity": 1
};

…faz referência a “como nossa linha deverá aparecer no mapa”,


ou seja, qual o estilo que vamos aplicar a essa linha. Aqui, 'color' é a
cor (em código hexadecimal), 'weight' é o peso, a largura da linha e
'opacity' é a opacidade, que pode ser entendida como a transparência
a ser aplicada (varia de 0 - totalmente transparente - a 1 – totalmente

501 htarop .h 49
opaco). Aproveite para fazer algumas alterações nesses valores e ver o
que acontece!
Por fim, nosso último trecho de código:

L.geoJson(linha01, {style: estilodalinha01}).addTo(map).bindPopup('Acredite,


eu sou uma linha em um mapa!').openPopup();

Você deve ter sentido certa familiaridade com este trecho, não?
Ele é bem parecido com o código utilizado para adicionar
marcadores.
A diferença é que, ao invés de utilizar o construtor 'L.marker',
nós utilizamos o construtor 'L.GeoJson'.
Este construtor, 'L.GeoJson', exige que você declare (i) a variável
anterior, responsável pela geometria ('linha 01') e a variável
responsável pelo estilo a ser aplicado ('estilodalinha').
É importante ressaltar essa “estrutura de pensamento” nos
códigos LeafletJS (e JavaScript, em geral): declaramos variáveis, que
trazem elementos para o nosso código e, depois, utilizamos essas
variáveis em classes, nossos construtores. É como um jogo de armar,
onde você precisa trazer as peças para poder armá-las como quiser.
O restante do trecho de código acima possui as mesmas
funções que vimos anteriormente, utilizado para adicionar
marcadores.
Bem simples, não?

Uma breve retomada, em resumo, para adicionar linhas ao


mapa:
➔ criar uma variável com o tipo de geometria (linha) desejada
e os pares de coordenadas;
➔ criar uma variável com o estilo da geometria (linha) que
deverá ser aplicado;
➔ utilizar o construtor 'L.GeoJson' para inserir a linha e o seu
estilo em nosso mapa.

Muito simples!!

501 htarop .h 50
Desenhando Círculos sobre o mapa
Círculos em um mapa são geralmente utilizados para
representar a área de influência radial de um determinado evento.
Quer dizer, traçar um círculo em nosso mapa nos ajuda a dar
respostas para perguntas como “até quantos metros uma árvore
aumenta a umidade relativa do ar?”, “qual o impacto sonoro de um
alto-falante instalado na praça central da cidade?”. Vamos dar uma boa
olhada em como desenhar círculos sobre os nossos mapas. Arregace
as mangas e...

...Mão na Massa!
Faça uma cópia do arquivo 'index.html', dentro da pasta 'wm05'.
Renomeie-o para 'index01.html'. Abra-o em seu editor de textos.
Agora, apague o código entre as tags '<script
type="text/javascript"><script>', e cole o código abaixo em seu lugar:

var map = L.map('mapa').setView([-3.130409,-60.023426], 16);


L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
attribution: 'Mapas &copy; OpenCycleMap, Dados do Mapa &copy;
contribuidores do OpenStreetMap'
}).addTo(map);
L.circle([-3.130409,-60.023426], 150).addTo(map);

Salve o arquivo 'index01.html' e abra-o em seu navegador. Você


verá a imagem a seguir:

501 htarop .h 51
FIGURA 19. …'DOUTOR, ESTOU VENDO CÍRCULOS EM MAPAS...'

Muito bem, temos um círculo em nosso mapa! Neste caso, ele


está demarcando um raio de 150 metros a partir da localização do
Teatro Amazonas.
Mais uma vez, para o alto e...

...Dissecando o Código!
OK! Novamente, alteramos a localização do ponto central do
mapa e do zoom inicial que aplicamos em nosso mapa base (dê uma
boa olhada em nosso código, a partir de 'var map = L.map', e também
nos capítulos anteriores, caso tenha dúvidas...).
Agora, vamos até a parte (realmente simples) do código, que
nos apresenta como inserir um círculo em nosso mapa:

L.circle([-3.130409,-60.023426], 150).addTo(map);

É, você entendeu bem!


O centro do nosso círculo é dado pelo par de coordenadas '[-
3.130409,-60.023426]' e o raio do nosso círculo é dado pelo valor, em
metros, ', 150'.
É só isso! Muito simples porque é muito legal, muito legal por
que é muito simples!

501 htarop .h 52
Desenhando Polígonos sobre o mapa
...Mão na Massa!
OK! Faça uma cópia do arquivo 'index01.html' e renomeie-o para
'index02.html'. Abra-o em seu editor de textos e substitua o código
preexistente, entre as tags '<script>' pelo seguinte:

var map = L.map('mapa').setView([-3.1399697549534182,-


60.021164417266846], 17);
L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
attribution: 'Mapas &copy; OpenCycleMap, Dados do Mapa &copy;
contribuidores do OpenStreetMap'
}).addTo(map);

L.polygon([
[-3.1408267729119284,-60.02290248870849],
[-3.1389948961706944,-60.02290248870849],
[-3.1389948961706944, -60.019415616989136],
[-3.1408267729119284, -60.019415616989136]
]).addTo(map);

Após salvar seu arquivo com as alterações que acabamos de


realizar, abra-o em seu navegador web. Você deverá ver:

FIGURA 20. 'DOUTOR, AGORA TENHO VISTO POLÍGONOS'

501 htarop .h 53
Em frente! Enfrente e vamos seguir...
...Dissecando o código!
Nós fizemos a “alteração clássica” com relação ao mapa-base, ou
seja, alteramos a posição inicial do mapa e o zoom inicial.
Certo. Agora, a parte do código responsável por 'desenhar' o
polígono no mapa:

L.polygon([
[-3.1408267729119284,-60.02290248870849],
[-3.1389948961706944,-60.02290248870849],
[-3.1389948961706944, -60.019415616989136],
[-3.1408267729119284, -60.019415616989136]
]).addTo(map);

Epa! Nós já não vimos isso antes? Quase... Aqui, vemos a


utilização de um novo construtor, 'L.polygon', que funciona a partir da
declaração de um array, ou seja, um conjunto de valores (em
JavaScript). No nosso caso, este array possui valores de coordenadas
geográficas (pares).
Esses pares de coordenadas geográficas correspondem aos
valores dos vértices do nosso polígono, à semelhança do que vimos
anteriormente com relação às linhas.
Note que as coordenadas apresentam valores que
correspondem, especificamente, a um retângulo! Mas, com o
construtor 'L.polygon' você pode criar outros tipos de polígonos, como
triângulos, hexaedros, dodecaedros etc.

501 htarop .h 54
Apresentando a

Cartografia Temática
em um navegador web
Preparar um ambiente de desenvolvimento local
Adicionar Camadas temáticas ao seu mapa
Aplicar Estilos (espessura, cor, transparência) aos vetores
Criar elementos do mapa: escala, legenda
Desenvolver eventos para os dados do mapa
OK! Vamos dar um 'salto' nesse capítulo.
Um salto até um dos aspectos mais interessantes da cartografia:
a representação temática. E, para isso, vamos elaborar um mapa
coroplético. Tudo pronto? Vamos começar...
...Preparando um Ambiente de Desenvolvimento
Muito bem! Faça uma cópia da pasta 'wm05' e renomeie-a para
'wm06'.
Uma vez dentro da pasta 'wm06', apague todos os arquivos com
nome 'index...', menos o arquivo 'index.html'.
Certo...Agora, faça o download do arquivo 'brasil.js' na seção
'downloads', na página digital do livro14.
Salve esse arquivo dentro da pasta 'wm06/leaflet'.
É isso!

ATENÇÃO!

O tipo de aplicação de mapas que estamos prestes a desenvolver, é uma


tarefa um pouco complicada para nós, que estamos iniciando o
desenvolvimento de mapas com a Biblioteca LeafletJS. Então, vamos
alterar um pouco nosso procedimento de aprendizado pra facilitar as
coisas!

Para o nosso mapa deste capítulo, vamos adotar um conjunto


concatenado de 03 seções “Mão na Massa!” + “Dissecando o código”, ok?
Vamos lá!

14 http://geotecnologias.org/desenvolvendo-webmaps/
...Mão na Massa 01!
Vá até a pasta 'wm06' e abra o arquivo 'index.html' em seu
editor de textos, como você já sabe fazer.
Ótimo! Agora, no código aberto, identifique a tag '<body>' e, na
linha posterior, cole o código abaixo, como destacado a seguir:

<body>
<script type="text/javascript" src="leaflet/brasil.js"></script>
<div id=" (...)

Perfeito, vamos adiante! Remova todo o código entre as tags


'<script type="text/javascript"></script>'.
Copie e cole o trecho de código a seguir, entre as tags '<script>':

var map = L.map('mapa').setView([-14.437473, -57.645811], 4);


L.tileLayer('http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', {
attribution: 'Mapas &copy; OpenCycleMap, Dados do Mapa &copy;
contribuidores do OpenStreetMap'
}).addTo(map);
function getColor(d) {
return d > 1000 ? '#800026' :
d > 500 ? '#BD0026' :
d > 200 ? '#E31A1C' :
d > 100 ? '#FC4E2A' :
d > 50 ? '#FD8D3C' :
d > 20 ? '#FEB24C' :
d > 10 ? '#FED976' :
'#FFEDA0';};
function style(feature) {
return {
weight: 1.5,
opacity: 1,
color: 'white',
dashArray: '2',

501 htarop .h 57
fillOpacity: 0.6,
fillColor: getColor(feature.properties.Densidade)
};
};
L.geoJson(dadosestados, {style: style}).addTo(map);

Seja cuidadoso e certifique-se de que está tudo ok! Salve seu


arquivo e abra-o em seu navegador web. Você deverá ver a seguinte
tela em seu bom e velho navegador:

FIGURA 21. '...QUE DA HORA...'

Muito legal, né? Começo a sentir que você começa a sentir novas
possibilidades logo adiante...Mas, para estas possibilidades se
concretizarem, vamos seguir...

...Dissecando o código 01!


Muito bom!
A primeira parte a ser destacada é o seguinte trecho de código:

<script type="text/javascript" src="leaflet/brasil.js"></script>

O que esse trecho de código faz?


Bom, assim como acontece com a própria biblioteca Leaflet JS,
trazida para o nosso código por meio de um link, esse trecho de

501 htarop .h 58
código acima também é um link.
Esse novo link traz, para o nosso código, o arquivo 'brasil.js',
tornando-o disponível para que seja utilizado em nossa página web.
Por sua vez, o arquivo 'brasil.js' é um arquivo do tipo GeoJson,
“transformado em um arquivo do tipo JavaScript” por meio da
declaração de uma variável.
Se você for curioso e abrir o arquivo 'brasil.js' em seu editor de
textos, verá, antes do início do arquivo GeoJson, o seguinte:

var dadosestados = {
"type": "FeatureCollection",
"crs": { "type": "name", "properties": (...)

Neste trecho de código acima, o que está destacado em laranja


é o arquivo GeoJson “puro”. Então, podemos observar que, antes do
início do arquivo GeoJson puro, inserimos a declaração de uma
variável, chamada “dadosestados”.
Pode parecer um pouco complicado de início, mas analise com
cuidado o que está acontecendo e logo você se familiariza com esse
procedimento.
Agora, vamos adiante, observando o próximo trecho do código:

var map = L.map('mapa').setView([-14.437473, -57.645811], 4);


L.tileLayer('http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', {
attribution: 'Mapas &copy; OpenCycleMap, Dados do Mapa &copy;
contribuidores do OpenStreetMap'
}).addTo(map);

Esse trecho, já bastante conhecido nosso, é responsável por


informar as características do nosso mapa-base. Note que, para tornar
nossa camada temática mais destacada, escolhemos um mapa-base
em tons de cinza.
A última parte desta seção:

501 htarop .h 59
function pegaCor(d) {
return
d > 1000 ? '#800026' :
d > 500 ? '#BD0026' :
d > 200 ? '#E31A1C' :
d > 100 ? '#FC4E2A' :
d > 50 ? '#FD8D3C' :
d > 20 ? '#FEB24C' :
d > 10 ? '#FED976' :
'#FFEDA0';
};
function estilo(feature) {
return {
weight: 1.5,
opacity: 1,
color: 'white',
dashArray: '2',
fillOpacity: 0.6,
fillColor: pegaCor(feature.properties.Densidade)
};
};
L.geoJson(dadosestados, {style: estilo}).addTo(map);

Muito calmamente, vamos pensar sobre esse trecho de código.


Aqui aparecem duas palavras novas para nós: function e return.
Essas duas palavras pertencem ao universo da linguagem JavaScript.
Function, em JavaScript, designa um bloco de código que tem
uma função específica, ou seja, ele é responsável por uma única
tarefa.
Essa função é acionada por 'algum outro trecho do código' e
retorna uma tarefa → return.
Legal, agora vamos falar sobre as tarefas que esses trechos de
código executam.
Bom, a primeira função, chamada 'pegaCor', é responsável por
distribuir valores de cores que serão utilizados sobre o nosso arquivo

501 htarop .h 60
GeoJson ('brasil.js'). Essa função trabalha da seguinte maneira: atribui
um valor padrão (d)15 – pegaCor(d) – e informa os intervalos de cores
que serão utilizados, por exemplo ' d > 10 ? '#FED976' : '.
Note que os valores menores que dez receberão a mesma cor,
tarefa que o simples trecho de código '#FFDEA0;' é responsável por
realizar.
Ok! Esse trecho de código que acabamos de discutir estabelece
uma legenda, uma escala de cores, para cada determinado intervalo
de valores existente no arquivo 'brasil.js'.
A segunda função, chamada 'estilo', é responsável por definir o
estilo (!!!) que será aplicado sobre as linhas e sobre os preenchimentos
do arquivo GeoJson.
O estilo do preenchimento é dado pelo trecho de código:

fillOpacity: 0.6,
fillColor: pegaCor(feature.properties.Densidade)

Em língua inglesa “fill” significa preenchimento. Portanto,


fillOpacity define a transparência do preenchimento, a opacidade (em
valores que variam de 0 a 1 – experimente!).
O preenchimento das cores é dado pelo trecho que nos faz
entender tudo:

fillColor: pegaCor(feature.properties.Densidade)

FillColor é a cor do preenchimento.


A cor do preenchimento é estabelecida pela primeira função
que nós criamos ('pegaCor').
Então, nossa segunda função utiliza a primeira função. Legal!
Agora, perceba que os intervalos definidos por '(d)' são
orientados a acessar o arquivo GeoJson e procurar nas propriedades
do arquivo a coluna Densidade ('feature.properties.Densidade').
Assim, a cor apresentada no mapa, retorna um valor correspondente
aos intervalos definidos pelos intervalos da nossa legenda de cores

15 Ao invés de “d”, poderíamos utilizar qualquer outra letra ou palavra.

501 htarop .h 61
('pegaCor').
Com muito cuidado e paciência, observe a figura a seguir e
pense um pouco nas ligações existentes entre os trechos do nosso
código, isso vai ajudá-lo no entendimento sobre como funcionam as
diferentes partes deste primeiro trecho de código, que é importante
para as próximas seções:

FIGURA 22. RELACIONAMENTO ENTRE FUNÇÕES

Por fim, um trecho de código que também já nos é familiar:

L.geoJson(dadosestados, {style: estilo}).addTo(map);

A novidade está no trecho destacado, posto que a busca pelo


arquivo GeoJson acontece dentro de outro arquivo ('brasil.js'), linkado

501 htarop .h 62
em nosso mapa por meio do trecho:

<script type="text/javascript" src="leaflet/brasil.js"></script>

Lembra-se do nome da variável dentro do arquivo 'brasil.js'?


Pois é, ela está sendo utilizada aqui! ;)
...Mão na Massa 02!
Ufa! Muitas novidades, não? Bom, se você não conseguiu
apreender tudo, não entre em pânico! Dê uma respirada e dê tempo
ao tempo (esforçando-se para o tempo ser seu amigo, claro!).
Agora, vamos seguir adiante!
Faça uma cópia do arquivo 'index.html' (pasta 'wm06') e
renomeie-o para 'index01.html', abrindo-o em seu editor de textos
logo em seguida. Apague o código existente entre as tags '<script>' e
copie e cole o código abaixo em seu lugar:

var map = L.map('mapa').setView([-14.437473, -57.645811], 4);


L.tileLayer('http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', {
attribution: 'Mapas &copy; OpenCycleMap, Dados do Mapa &copy;
contribuidores do OpenStreetMap'}).addTo(map);
function pegaCor(d) {
return d > 100 ? '#800026' :
d > 50 ? '#BD0026' :
d > 40 ? '#E31A1C' :
d > 30 ? '#FC4E2A' :
d > 20 ? '#FD8D3C' :
d > 10 ? '#FEB24C' :
d > 5 ? '#FED976' :
'#FFEDA0';
};
function estilo(feature) {
return {
weight: 1.5,
opacity: 1,

501 htarop .h 63
color: 'white',
dashArray: '2',
fillOpacity: 0.7,
fillColor: pegaCor(feature.properties.Densidade)
};
};
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 3,
color: '#777',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera) {
layer.bringToFront();
}
};
var geojson;
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
};
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
};
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature
});
};
geojson = L.geoJson(dadosestados, {style: estilo, onEachFeature:

501 htarop .h 64
onEachFeature}).addTo(map);

OK! Abra o arquivo em seu navegador web, você deverá ver a


seguinte tela:

FIGURA 23. '...ORRA, MEU...'

Aponte seu mouse sobre o estado de Mato Grosso e clique


sobre ele; alguma coisa aconteceu, certo?
Clique sobre os outros estados e perceba que a mesma coisa
acontece! Muito legal!
Agora, avante!! Sigamos...

...Dissecando o Código 02!


Por partes! Bom, dê uma boa olhada no código e perceba que
existem novas funções sendo utilizadas, além das funções 'pegaCor' e
'estilo'.
Como nós já inserimos funções em nosso código anteriormente,
vimos o que essas funções fazem. Pois bem, agora, vamos dar uma
olhada nas novas funções que trouxemos e vamos entender como elas
atuam em nosso mapa.
Primeiro, vamos falar sobre o seguinte trecho de código e as
funções que nele aparecem:

function highlightFeature(e) {

501 htarop .h 65
var layer = e.target;
layer.setStyle({
weight: 3,
color: '#777',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera) {
layer.bringToFront();
}
};
function resetHighlight(e) {
geojson.resetStyle(e.target);
};
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
};
function emcadaEstado(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature
});
};
var geojson;
geojson = L.geoJson(dadosestados, {style: estilo, onEachFeature:
emcadaEstado}).addTo(map);

Legal! Vamos conversar sobre as três primeiras funções


('highlightFeature(e)', 'resetHighlight(e)' e 'zoomToFeature(e)'). Bom,
essas funções são responsáveis por dizer o que acontecerá em nosso
mapa quando, ao navegar por ele, efetuarmos “cliques”. Essas
respostas que o mapa nos dá são conhecidas como eventos.
Vamos lá! A função 'highlightFeature(e)' é a responsável por

501 htarop .h 66
“iluminar” o limite de cada estado da federação 16 todas as vezes que
posicionarmos nosso mouse sobre seus limites.
Ela faz isso por meio da criação de uma variável ('var layer =
e.target;'), que cria, temporariamente, uma nova camada no mapa,
trazendo-a para frente (feito no trecho 'layer.bringToFront();')17.
A função 'resetHighlight(e)', por sua vez, se responsabiliza por
“apagar” o que a função anterior “iluminou”, todas as vezes em que
retiramos nosso mouse “de cima” dos limites de cada estado da
federação.
Por fim, a função 'zoomToFeature(e)' é quem “dá o zoom”
quando clicamos sobre um estado da federação, ajustando seus
limites (os limites do estado) aos limites da tela do navegador:
OK!

Analise com cuidado como as funções são construídas e observe


que elas obedecem um determinado padrão, falam uma língua. Essa
língua é, na verdade, a linguagem JavaScript.

Bom, voltemos a nossa quarta função. O que ela faz mesmo?


Bom, à semelhança do que acontece com a função 'pegaCor' (visto
anteriormente, que é utilizada pela função 'estilo'), as três funções que
acabamos de ver acima são utilizadas em nossa quarta função
'emcadaEstado' (que é um tipo de função conhecido como
'onEachFetature').
Portanto, nossa quarta função organiza as três funções
anteriores, definindo o que acontecerá qundo realizarmos
movimentos com o nosso mouse (mouseover, mouseout, click).
Legal!
Por fim, nosso último trecho de código traz uma pequena
diferença.
Observe:

var geojson;

16 Cada Estado da Federação é entendido, em nosso código, como uma “Feature”.


17 Observe que os mapas são organizados em camadas (layers).

501 htarop .h 67
geojson = L.geoJson(dadosestados, {style: estilo, onEachFeature:
emcadaEstado}).addTo(map);

A diferença que encontramos aqui é a existência de uma nova


variável, 'var geojson'. Bom, por que ela existe aqui?
Ela existe aqui para que os eventos retornem alterações visíveis
no mapa, ou seja, os eventos utilizam uma “camada temporária”, que
faz uso das geometrias do nosso arquivo GeoJson. Essa “camada de
eventos” atua sobre o nosso arquivo GeoJson, utilizando cada uma das
Features.
Então, precisamos declarar uma variável que acondicione estes
eventos temporários. É isso que a declaração da variável geojson faz.
Note que a função 'zoomToFeature(e)' não aparece aqui: ela
utiliza as geometrias do arquivo GeoJson diretamente!
É isso! Vamos adiante, colocando mais uma vez a...
...Mão na Massa 03!
OK! Lá vamos nós de novo! Na pasta 'wm05', crie uma cópia do
seu arquivo 'index01.html', renomeie-o para 'index02.html'. Mantenha
o arquivo 'index02.html' aberto em seu editor de textos, copie e cole o
código a seguir, após o trecho '<meta charset="utf-8"/>':

<style>
.info {
padding: 6px 8px;
font: 12px/14px Arial, Helvetica, sans-serif;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
}
.info h4 {
font: 20px/22px Arial, Helvetica, sans-serif;
margin: 0 0 5px;
color: #777;

501 htarop .h 68
}
.legend {
text-align: left;
line-height: 18px;
color: #555;
}
.legend i {
width: 18px;
height: 18px;
float: left;
margin-right: 8px;
opacity: 0.7;
}
</style>

Salve o seu arquivo. Agora, antes da tag '<script


type="text/javascript">' (e depois do trecho '(...).addTo(map);' ), próximo
ao final do seu código, copie e cole o trecho a seguir:

var info = L.control();


info.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info');
this.update();
return this._div;
};
info.update = function (props) {
this._div.innerHTML = '<h4>Densidade Demográfica</h4>' +
(props ? '<b>' + props.Estado + '</b><br />' + props.Densidade + ' habitantes /
km<sup>2</sup>' + '</b><br />': 'Aponte o mouse para os Estados da Federação');
};
info.addTo(map);

var legend = L.control({position: 'bottomleft'});


legend.onAdd = function (map) {

501 htarop .h 69
var div = L.DomUtil.create('div', 'info legend'),
grades = [0, 5, 10, 20, 30, 40, 50, 100],
labels = [],
from, to;
for (var i = 0; i < grades.length; i++) {
from = grades[i];
to = grades[i + 1];
labels.push(
'<i style="background:' + pegaCor(from + 1) + '"></i> ' + from + (to ? '&ndash;' + to :
'+'));
}
div.innerHTML = labels.join('<br>');
return div;
};
legend.addTo(map);

Salve o seu arquivo novamente. Vá até a pasta 'wm05' e abra o


arquivo 'index02.html' em seu navegador web. Você deverá ver a
seguinte tela em seu navegador:

FIGURA 24. 'AI QUE LOUCURA!!...'

Explore um pouco o seu último webmap! Há muitas coisas legais


por aqui, hein?!

501 htarop .h 70
Bom, uma vez mais, é hora de seguir...

...Dissecando o Código 03!


Certo!
O primeiro trecho de código que inserimos corresponde à
linguagem CSS e é responsável por aplicar os estilos da legenda (os
trechos iniciados em 'legend') e aplicar os estilos do nosso painel de
informações (os trechos iniciados em 'info').
OK!
O trecho que inserimos no corpo da nossa aplicação é o
responsável por trazer para o nosso webmap a legenda e o painel de
informações.
Como isso é feito?
O trecho de código abaixo...

var info = L.control();


info.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info');
this.update();
return this._div;
};
info.update = function (props) {
this._div.innerHTML = '<h4>Densidade Demográfica</h4>' +
(props ? '<b>' + props.Estado + '</b><br />' + props.Densidade + ' habitantes /
km<sup>2</sup>' + '</b><br />': 'Aponte o mouse para os Estados da Federação');
};
info.addTo(map);

...cria, a partir de uma variável ('var info'), um controle dinâmico


que apresenta o nome do estado da federação ('props.Estado') e a
densidade demográfica correspondente ('props.Densidade').
Os dados são “buscados” em nosso arquivo Geojson ('brasil.js').
Lembre-se que os estilos aplicados (pelo uso da linguagem CSS)
foram definidos anteriormente, na seção '<style>', como vimos mais
acima.

501 htarop .h 71
O próximo trecho de código:

var legend = L.control({position: 'bottomleft'});


legend.onAdd = function (map) {

var div = L.DomUtil.create('div', 'info legend'),


grades = [0, 5, 10, 20, 30, 40, 50, 100],
labels = [],
from, to;
for (var i = 0; i < grades.length; i++) {
from = grades[i];
to = grades[i + 1];
labels.push(
'<i style="background:' + pegaCor(from + 1) + '"></i> ' + from + (to ? '&ndash;' + to :
'+'));
}
div.innerHTML = labels.join('<br>');
return div;
};
legend.addTo(map);

Bom, esse trecho cria outro controle no mapa: a legenda.


A criação é análoga à criação do painel, que acabamos de ver.
Aqui, também se cria, a partir de uma variável, a legenda,
estabelecendo-se os critérios, como destacado em itálico no código
apresentado acima.
Observe que as estruturas são bem similares.

É isso!

501 htarop .h 72
Note que não nos ativemos aos detalhes de criação das funções, quer
dizer, não te explicamos o código linha por linha. Por que fizemos isso?
Bom, esse capítulo já é um pouco extenso e a criação das funções é objeto
da linguagem JavaScript “estrita”.
Na verdade, mesmo essa “linguagem mais pesada” não é assim tão difícil
de entender.

Nós mantivemos o foco na utilização da biblioteca LeafletJS para


evidenciar a sua característica mais interessante: ela funciona como um
“jogo de armar”, ou seja, se conhecermos bem as partes e suas funções,
somos capazes de montar nossos mapas, como um pequeno e simples
quebra-cabeça.

501 htarop .h 73
Expandindo as
funcionalidades do
nosso Mapa
O que são e como utilizar plugins
Leaflet MakiMarkers
Leaflet MarkerCluster

501 htarop .h 74
Até aqui, abordamos os aspectos globais da biblioteca LeafletJS
e pudemos perceber que ela é realmente muito simples de ser
utilizada, apresentando ótimos resultados para as funções mais
comuns da comunicação cartográfica.
E isso foi legal!
Agora, vamos explorar mais algumas funcionalidades da nossa
biblioteca favorita.
E vamos fazer isso utilizando plugins!
O que são e como utilizar plugins
O que são plugins?
Plugins (plug-ins) são pequenos componentes de um software,
desenvolvidos a posteriori (ou separadamente) para acrescentar novas
funcionalidades a um determinado software já existente.
Uma analogia possível, para entendermos com clareza, é um
rádio automotivo: o automóvel continua sendo um automóvel, mas
acresentamos um "plugin" com uma funcionalidade específica (tocar
música), ou seja, nós mantemos a funcionalidade original do
automóvel, mas acrescentamos uma funcionalidade específica.
Muito bem! É uma ideia simples e muito útil, já que novas
funcionalidades podem ser acrescentadas sem termos que reconstruir
um software inteiro.
A biblioteca LeafletJs possui dezenas de plugins muito
interessantes18, desenvolvidos por pessoas do mundo inteiro.
Aqui, trabalharemos com uma pequena lista possível (outras
listas também são possíveis) de plugins bastante úteis, apresentada
mais adiante.
Como utilizar os Plugins?

Regra geral, os plugins, na biblioteca LeafletJS, são incorporados


ao nosso código principal por meio de um hiperlink, tornando o código
JavaScript do plugin disponível para ser utilizado em nosso código
LeafletJS.
Esse procedimento é parecido com o procedimento através do
qual trouxemos o arquivo 'brasil.js' para o nosso código, no capítulo
anterior, lembra-se? Veremos em detalhes mais adiante.
18 A lista completa pode ser vista aqui: http://leafletjs.com/plugins.html
Como dito anteriormente, a biblioteca LeafletJS possui dezenas
de plugins disponíveis para serem utilizados. Por aqui, trabalharemos
com apenas dois plugins diferentes:

• Leaflet.MakiMarkers – incorpora a funcionalidade de


acrescentar marcadores customizados com agilidade19;
• Leaflet.markercluster – incorpora a funcionalidade de
agrupar marcadores, melhorando a "legibilidade" do
mapa.

Legal!
Como você já deve imaginar, é hora de colocar a...

...Mão na Massa!
(Vamos adotar uma estrutura um pouco diferente dos capítulos anteriores por aqui)
Vá até a página do livro e, na seção "Downloads", faça o
download da pasta 'wm07', descompacte-a dentro da pasta
'webmaps'.
Você verá a seguinte estrutura de pastas:

FIGURA 25. ESTRUTURA DAS PASTAS DE PLUGINS

Ok, abra os arquivos 'makimarkers.html' e 'markerclusters.html',


em seu navegador web. Dê uma boa olhada nos mapas que são
apresentados. Você deverá ver as seguintes telas:

19 O plugin traz para o LeafletJS os marcadores Maki da MapBox - https://www.mapbox.com/maki/

501 htarop .h 76
FIGURA 26. CHIMARRÃO WAY OF LIFE!

Leflet.MakiMarkers!

&

FIGURA 27. É GRUPO!

Leflet.MarkerCluster!

Legal, né? Dá para imaginar que, com dezenas de plugins


disponíveis, podemos criar aplicações de mapas bem interessantes.
Agora, seguiremos...

501 htarop .h 77
...Dissecando o Código!
Leaflet.MakiMarkers
Certo, já deu para perceber que o plugin Leafet.MakiMarkers
possui a habilidade de disponibilizar uma série de marcadores
customizados, com maior facilidade.
O primeiro trecho do código é a inserção do link, observe:

<head>
<title>Plugin: MakiMarkers</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="leaflet/leaflet.css" /> - - link padrão
<script src="leaflet/leaflet.js"></script> - - link padrão
<script src="Leaflet.MakiMarkers/Leaflet.MakiMarkers.js"></script>
</head>

Muito bem, é simples assim e esse link traz para o nosso código
as funcionalidades do referido plugin. Agora, vamos observar como
funciona a inserção de um marcador customizado a partir da análise
do seguinte trecho de código:

var gasometro = L.MakiMarkers.icon({


icon: "ferry",
color: "#23b801",
size: "s"
});

L.marker([-30.034142, -51.241201], {icon: gasometro}).addTo(map)


.bindPopup("<img src=leaflet/images/chimas.png><br><strong>Bah, um
chimas no Gasômetro!!</strong>").openPopup();

O procedimento é análogo ao procedimento para criar um


marcador customizado, como vimos anteriormente. Todavia, guarda
algumas facilidades.
Por meio da definição de uma variável ('var gasometro'),

501 htarop .h 78
escolhemos o ícone que utilizaremos dentro do marcador
('icon:ferry')20, a cor do background do marcador ('color: #23b801') e o
tamanho (' size:"s" ')21, para, em seguida, declararmos o tipo de ícone
que utilizaremos em nosso marcador, por meio do construtor
'L.marker' -> '{icon: gasometro}'.
Super simples!
O que há de mais interessante aqui é a quantidade de
marcadores disponibilizados: unindo as possibilidades de cor,
tamanho e ícones, temos centenas de combinações possíveis!

Leaflet.markercluster
Um mapa com dezenas, centenas ou mesmo milhares de
marcadores é bem difícil de "ler". Esse plugin nos ajuda a visualizar a
distribuição dos marcadores, agrupando-os em conjuntos (clusters) e
retornando o valor da quantidade de marcadores que foram
agrupados em cada conjunto.
A primeira parte do código apresenta a inserção dos links:

<head>
<title>Plugins: Leaflet.MarkerCluster</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-
0.7/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="mobile.css" />
<link rel="stylesheet" href="../dist/MarkerCluster.css" />
<link rel="stylesheet" href="../dist/MarkerCluster.Default.css" />
<script src="../dist/leaflet.markercluster-src.js"></script>
<script src="sampressa.js"></script>
</head>

20 Experimente abrir o arquivo 'wm07/Leaflet.MakiMarkers/Leaflet.MakiMarkers.js' em seu editor


de textos para conhecer as outras opções.
21 s – small (pequeno), m – medium (médio) e l – large (grande). Você pode alterar os tamanhos
para cada uma destas definições no arquivo 'Leaflet.MakiMarkers.js'.

501 htarop .h 79
Muitos links, não? E, alguns deles fazem referências a outros
arquivos (por meio de links também).
Note que, além dos códigos do plugin, trouxemos um arquivo
GeoJson, da mesma maneira como fizemos com o arquivo 'brasil.js', no
capítulo anterior. Trata-se do arquivo 'sampressa.js'.
Se você for curioso e abrir este arquivo em seu editor de textos,
verá uma série de pares de coordenadas, responsáveis por indicar a
localização de 106 marcadores diferentes.
OK! Vamos ao nosso próximo trecho de código:

var tiles = L.tileLayer('http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/


{y}.png', {maxZoom: 18, attribution: '&copy; <a
href="http://osm.org/copyright">OpenStreetMap</a> contributors, Points &copy
2012 LINZ'}), latlng = L.latLng(-23.552672, -46.633255);

var map = L.map('map', {center: latlng, zoom: 16, layers: [tiles]});

var markers = L.markerClusterGroup();

for (var i = 0; i < addressPoints.length; i++)


{
var a = addressPoints[i];
var title = a[2];
var marker = L.marker(L.latLng(a[0], a[1]), { title: title });
marker.bindPopup(title);
markers.addLayer(marker);
}

map.addLayer(markers);

Algumas novidades aqui! Bom, note que o mapa-base agora é


trazido para o mapa por meio de uma variável ('var tiles'). Bom, não
entraremos em muitos detalhes, mas isso é feito dessa maneira para
trazer o mapa-base como um layer (uma camada) e está relacionado
com o "desenho do plugin".

501 htarop .h 80
A segunda novidade está na sentença 'for', parte da linguagem
JavaScript. Essa sentença é utilizada para que o código diga "enquanto
uma condição for verdadeira, execute tal e tal coisa".
Então ela cria um efeito de repetição, um "loop".
No nosso caso, ela está dizendo que para uma variável 'i = 0',
sempre que 'i' for menor que a distância 'i++',22 execute a
"clusterização".
É um pouco complicado assim, de sopetão, então, não se
preocupe com isso agora e estude um pouco de JavaScript mais tarde.
Por fim, adicionamos nossos marcadores ao nosso mapa
('map.addLayer(marker)'), o que é feito após as condições definidas
pela sentença 'for' serem realizadas, sempre dinamicamente.
Bom, é isso!
Lembre-se de visitar o website da biblioteca LeafletJs com
frequência e se atualizar com relação a novos plugins e novas versões
dos antigos plugins.
A biblioteca LeafletJS é desenvolvida para fazer o básico, muito
bem feito. Pensada para ser ágil. Os plugins fornecem, como dissemos
antes, dezenas de novas funcionalidades e sugiro uma profunda
investigação sobre eles, suas funcionalidades e seus modos de
utilização.

22 '++' incrementa valores sobre 'i'. Novamente, isso é parte da linguagem de programação que a
biblioteca LeafletJS utiliza: JavaScript.

501 htarop .h 81
Próximos Passos
Bom, chegamos ao fim desta pequena jornada!
Acredito que, a partir de agora, você já domine completamente
os elementos essenciais da Biblioteca LeafletJS, entendendo como
desenvolver mapas interativos para a internet.
Acredito também que você tenha uma ideia de como estender
as funcionalidades dos mapas por meio de plugins.
Ótimo, existem alguns próximos passos para darmos:

Como colocar meu mapa na internet?


Por incrível que pareça, colocar seu mapa na internet não é uma
tarefa muito complicada. Você utilizará a mesma estrutura de pastas
que utilizamos ao longo deste livro, com algumas pequenas
alterações.
Esse processo é bem descrito em um dos anexos, onde há um
texto específico para atravessarmos mais este processo, chamado
"Subindo os mapas para a web!".

Como "desenhar" um bom mapa?


Essa é uma boa questão e, quanto maior a familiaridade com os
códigos, mais essa questão deve ser importante.
Desde já, é bom ter uma ideia na cabeça: simplicidade. Um
mapa é um instrumento para a comunicação e, em comunicação,
quanto mais clara e mais rápida a mensagem é passada, melhor.
Há um outro artigo em um dos anexos orientado a desvendar o
"design de webmaps", chamado "Boas práticas para o Design de
WebMaps ". Visite-o!

Como aprender mais?


Colocando a mão na massa!
Sempre!!
E dissecando os códigos!
Sempre!!!

501 htarop .h 82
Além disso, existem alguns lugares para visitar e entender
melhor como funciona a biblioteca LeafletJs e tirar dúvidas específicas:

• http://leafletjs.com/ - o website da biblioteca;


• https://groups.google.com/forum/#!forum/leaflet-js – o fórum
oficial da biblioteca;
• http://gis.stackexchange.com/ - um fórum para questões
relacionadas às tecnologias da informação geográfica (gis, webmaps,
sensoreametno remoto, etc)

Nunca se esqueça que a curiosidade é o melhor remédio, então,


sempre tenha uma cópia de seus arquivos para fazer testes, tentar
coisas, misturar códigos.
Grandes ideias, muitas vezes, nascem da escassez: a criatividade
é um elemento que tem muito a ver com o exercício de resolver
questões sem saber como, sem conhecer as ferramentas corretas.
Quanto mais informação sobre a biblioteca LeafletJS e sobre a
linguagem JavaScript estiver disponível em seu cérebro, mais questões
você será capaz de resolver.
Se você quer viver, trabalhar e respirar desenvolvendo webmaps,
estude a fundo as linguagens de computador envolvidas: HTML, CSS e
JavaScript. Busque desvendar outras tecnologias.

Obrigado por ler este livro.


Espero que tenha sido uma jornada enriquecedora.
Até a próxima!

501 htarop .h 83