Académique Documents
Professionnel Documents
Culture Documents
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
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 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!
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.
➔ 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'
➔ Notepad++ (Windows)
http://notepad-plusplus.org/download/v6.5.3.html
➔ Vim (Linux)
http://www.vim.org/
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.
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:
501 htarop .h 10
FIGURA 01. ESTRUTURA DE PASTAS
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 © OpenCycleMap, Dados do Mapa ©
contribuidores do OpenStreetMap'
}).addTo(map);
</script>
</body>
</html>
501 htarop .h 12
FIGURA 02. VOILÀ!
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 © OpenCycleMap, Dados do Mapa ©
contribuidores do OpenStreetMap'}).addTo(map);
13. </script>
14. </body>
15. </html>
LEGENDA:
501 htarop .h 14
descobrir o que elas fazem no momento em que visualizamos nosso
primeiro mapa na web?
Vamos lá!
1. <!DOCTYPE HTML>
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>
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>':
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 © OpenCycleMap, dados do mapa
© contribuidores do OpenStreetMap'
}).addTo(map);
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: 25%; left: 25%; margin: 0; width: 50%;
height:50%;"></div>
501 htarop .h 18
FIGURA 04. AHHH.....
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
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:
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">
L.tileLayer('http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
}).addTo(map);
L.marker([-3.130409,-60.023426]).addTo(map)
.bindPopup('<center>Teatro Amazonas <br> inaugurado em
1896.</center>').openPopup();
</script>
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();
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:
501 htarop .h 26
FIGURA 08. ...'VOILÀ! III, O RETORNO DA MISSÃO'
<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:
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!
501 htarop .h 29
Tudo o que você sempre quis saber sobre
Marcadores e Popups
mas não tinha coragem de perguntar...
...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
501 htarop .h 32
combinados:
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.
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:
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.
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>');
501 htarop .h 36
FIGURA 12. ...NUNCA MAIS 'VOILÀ!' (MAIS UMA VEZ)
...Dissecando o código!
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!
...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:
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);
501 htarop .h 39
FIGURA 13. ...DIMAIS ESSE TREM, SÔ!'
...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:
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);
}
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);
}
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!
}
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:
...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 © OpenCycleMap, Dados do Mapa ©
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.
501 htarop .h 48
FIGURA 18. 'PRECISA DESENHAR?!'
var estilodalinha01 = {
"color": "#93131e",
"weight": 3,
"opacity": 1
};
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:
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?
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:
501 htarop .h 51
FIGURA 19. …'DOUTOR, ESTOU VENDO CÍRCULOS EM MAPAS...'
...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);
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:
L.polygon([
[-3.1408267729119284,-60.02290248870849],
[-3.1389948961706944,-60.02290248870849],
[-3.1389948961706944, -60.019415616989136],
[-3.1408267729119284, -60.019415616989136]
]).addTo(map);
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);
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!
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=" (...)
501 htarop .h 57
fillOpacity: 0.6,
fillColor: getColor(feature.properties.Densidade)
};
};
L.geoJson(dadosestados, {style: style}).addTo(map);
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...
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": (...)
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);
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)
fillColor: pegaCor(feature.properties.Densidade)
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:
501 htarop .h 62
em nosso mapa por meio do trecho:
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);
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);
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!
var geojson;
501 htarop .h 67
geojson = L.geoJson(dadosestados, {style: estilo, onEachFeature:
emcadaEstado}).addTo(map);
<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>
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 ? '–' + to :
'+'));
}
div.innerHTML = labels.join('<br>');
return div;
};
legend.addTo(map);
501 htarop .h 70
Bom, uma vez mais, é hora de seguir...
501 htarop .h 71
O próximo trecho de código:
É 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.
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?
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:
501 htarop .h 76
FIGURA 26. CHIMARRÃO WAY OF LIFE!
Leflet.MakiMarkers!
&
Leflet.MarkerCluster!
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:
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>
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:
map.addLayer(markers);
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:
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:
501 htarop .h 83