O que vamos construir?
Reuniremos um aplicativo de mapeamento que usa uma API que contém estatísticas recentes do Coronavirus e mapeia os locais e o impacto que cada país está enfrentando.
No mapa, mostraremos um marcador para cada país com o número de casos confirmados. Ademais, incluiremos uma pequena dica de ferramenta pop-up que mostra informações mais detalhadas.
O mapa que construiremos terá a aparência acima, mas um pouco mais simples. Utilizaremos o servidor público lado a lado do OpenStreetMap em vez de usar um servidor personalizado Mapbox
Para começar, vamos usar isso Folheto Gatsby Starter Eu criei para tornar a configuração inicial um pouco mais suave. Com nosso aplicativo inicializado, buscaremos nossos dados e adicionaremos marcadores ao mapa com nossos dados.
Woah, um aplicativo de mapeamento?
Sim. Se você nunca jogou mapas antes, não desanime! Não é tão ruim quanto você provavelmente pensa. Se você preferir começar com o básico do mapeamento, pode leia mais sobre como o mapeamento funciona primeiro.
Do que precisamos antes de começar?
Se você acompanhou meus tutoriais anteriores para construindo um rastreador do Papai Noel ou criando um mapa de viagem por estrada no verão, você pode seguir as mesmas etapas para começar. Caso contrário, queremos ter certeza de que temos o seguinte configurado:
- nó ou fio – Vou usar fio, mas você pode substituir por npm, quando apropriado
- CLI de Gatsby –
yarn global add gatsby-cli
Se você não tem certeza sobre um dos itens acima, tente verificar o início meu tutorial anterior.
Também queremos criar uma base para o nosso mapa. Podemos fazer isso utilizando o Leaflet Gatsby Starter que montei que nos fornece uma configuração básica com Folheto e Reagir folheto.
gatsby new my-coronavirus-map https://github.com/colbyfayock/gatsby-starter-leaflet
Após a conclusão da execução, você pode navegar para o diretório de projeto recém-criado e iniciar o servidor de desenvolvimento local:
cd my-coronavirus-mapyarn develop
Se tudo correr como planejado, seu servidor deverá iniciar e agora você poderá ver seu aplicativo de mapeamento básico no seu navegador!
Etapa 1: Limpar algum código desnecessário
O Gatsby Starter que estamos usando para criar este aplicativo vem com algum código de demonstração que não precisamos aqui. Queremos fazer todas as alterações abaixo no arquivo src/pages/index.js
, que é a página inicial do nosso aplicativo.
Primeiro, vamos remover tudo do mapEffect
função. Esta função é usada para executar o código que é acionado quando o mapa é renderizado.
// In src/pages/index.jsasync function mapEffect({ leafletElement } = {}) { // Get rid of everything in here}
Também mudaremos o nome da variável do nosso leafletElement
simplesmente por entender mais facilmente o código enquanto o escrevemos.
async function mapEffect({ leafletElement: map } = {}) {}
Em seguida, não queremos um marcador desta vez, então vamos remover o
Agora que temos essas peças limpas, podemos remover todas as seguintes importações e variáveis da parte superior do nosso arquivo:
- useRef
- Marcador
- promessaParaPara
- getCurrentLocation
- gatsby_astronaut
- timeToZoom
- timeToOpenPopupAfterZoom
- timeToUpdatePopupAfterZoom
- AMPLIAÇÃO
- popupContentHello
- popupContentGatsby
- markerRef
Depois, nosso mapa ainda deve funcionar, mas não faz nada.
Etapa 2: Buscando os dados do Coronavirus
Para nosso aplicativo, vamos usar o API NovelCOVID. Particularmente, vamos usar o endpoint de países para buscar a lista de nossos países e as estatísticas associadas a eles.
Para fazer solicitações, eu pessoalmente gosto de usar axios pois possui uma API agradável de usar. Se você quiser usar buscar ou sua própria biblioteca de solicitações favorita, substitua-a nesta etapa.
Começaremos instalando axios:
yarn add axios
Uma vez instalado, lembre-se de reiniciar o servidor.
Importe o pacote axios para o topo da nossa pages/index.js
Arquivo:
import axios from ‘axios’;
Em seguida, faremos nosso pedido. Dentro da nossa mapEffect
, tente fazer uma solicitação para o endpoint da API:
async function mapEffect({ leafletElement: map } = {}) { let response; try { response = await axios.get(‘https://corona.lmao.ninja/countries’); } catch(e) { console.log(`Failed to fetch countries: ${e.message}`, e); return; } const { data = [] } = response;}
Neste snippet, estamos fazendo o seguinte:
- Configurando um
response
variável que nos permitirá armazenar a resposta - Adicionando um
try/catch
bloco que detectará qualquer erro de API se a solicitação falhar - Se a solicitação for bem-sucedida, armazenamos a resposta no diretório
response
variável - Se a solicitação falhar, o console efetuará logout do erro e retornaremos à função para não continuarmos a executar o código com uma solicitação com falha
- Uma vez que tenhamos nossa resposta, podemos desestruturar
data
da resposta e defina o valor padrão para uma matriz vazia, pois esse será o tipo de dados que precisamos
Após a configuração, podemos consolar o logout do data
objeto e veremos nossos dados buscados com sucesso!
Etapa 3: Transforme os dados do Coronavírus em um formato de dados geográficos
Agora que temos nossos dados, podemos transformá-los em um formato de dados geográficos, particularmente GeoJSON, isso nos permitirá interagir com o Leaflet.
Vamos começar adicionando este bloco de código:
const { data = [] } = response;const hasData = Array.isArray(data) && data.length > 0;if ( !hasData ) return;const geoJson = { type: ‘FeatureCollection’, features: data.map((country = {}) => { const { countryInfo = {} } = country; const { lat, long: lng } = countryInfo; return { type: ‘Feature’, properties: { …country, }, geometry: { type: ‘Point’, coordinates: [ lng, lat ] } } })}
Então o que estamos fazendo aqui?
- Criamos uma nova constante chamada
hasData
que verifica se o nossodata
variável é uma matriz e possui dados - Se não temos dados, queremos retornar à função, pois não queremos tentar adicionar dados que não temos
- Nós criamos um
geoJson
objeto que será nosso documento GeoJSON - Nosso documento é do tipo
FeatureCollection
e como nossofeatures
percorremos nosso conjunto de dados - Para cada país em nossos dados, obtemos o
lat
elng
para criar um ponto para o nosso mapa - Ademais, adicionamos os dados de nossos países como propriedades para que possamos acessá-los em nossas APIs de mapeamento
Se vocês console.log
este objeto for no seu navegador e copie o conteúdo, você pode colá-lo no geojson.io e ver os dados do local aparecerem corretamente.
Com este documento GeoJSON, agora poderemos adicioná-lo ao nosso mapa.
Etapa 4: adicionando os dados do Coronavirus ao mapa
Temos nosso documento GeoJSON com nossos dados de localização, então vamos adicioná-lo ao mapa.
Vamos começar com este bloco de código. É longo, mas vamos dividir por partes:
const geoJsonLayers = new L.GeoJSON(geoJson, { pointToLayer: (feature = {}, latlng) => { const { properties = {} } = feature; let updatedFormatted; let casesString; const { country, updated, cases, deaths, recovered } = properties casesString = `${cases}`; if ( cases > 1000 ) { casesString = `${casesString.slice(0, -3)}k+` } if ( updated ) { updatedFormatted = new Date(updated).toLocaleString(); } const html = ` ${country}
- Confirmed: ${cases}
- Deaths: ${deaths}
- Recovered: ${recovered}
- Last Update: ${updatedFormatted}
${ casesString } `; return L.marker( latlng, { icon: L.divIcon({ className: ‘icon’, html }), riseOnHover: true }); }});
Então o que estamos fazendo aqui?
- Criamos uma nova instância de
L.GeoJSON
que transformará nosso documento GeoJSON em algo que o Leaflet entenderá - Dentro dessa instância, definimos um costume
pointToLayer
função. Isso nos permite personalizar a camada do mapa que o Leaflet cria para o nosso mapa - Em nossa função, atribuímos e criamos nossos pontos de dados que queremos. A maior parte é desestruturada, mas formatamos os casos para mostrar
1k+
ao invés de1000
e uma data formatada em vez do carimbo de data e hora - Criamos um bloco de string HTML que é usado para definir nosso marcador de mapa que será adicionado ao mapa. Isso também inclui o HTML da dica de ferramenta que será exibida ao passar o mouse sobre um marcador
- Nós voltamos
L.marker
com nossa configuração personalizada que inclui uma classe deicon
para o contêiner e nosso HTML personalizado. - Ademais, adicionamos o
riseOnHover
propriedade, portanto, ao passar o mouse sobre um marcador, ele aparece acima dos outros marcadores no mapa
Também queremos adicionar um pouco de CSS aqui para garantir que nossos marcadores apareçam no mapa e sejam utilizáveis. Vamos adicionar esse trecho ao nosso assets/stylesheets/components/_map.scss
Arquivo:
.icon-marker { display: flex; position: relative; justify-content: center; align-items: center; color: white; width: 3.6em; height: 3.6em; font-size: .7em; font-weight: bold; background-color: $red-800; border-radius: 100%; box-shadow: 0 2px 5px rgba(black, .9); &:hover { .icon-marker-tooltip { display: block; } }}.icon-marker-tooltip { display: none; position: absolute; bottom: 100%; width: 16em; font-size: 1.4em; padding: 1em; background-color: $blue-grey-900; border-radius: .4em; margin-bottom: 1em; box-shadow: 0 3px 5px rgba(black, .9); &:before { display: block; position: absolute; bottom: -.6em; left: 50%; content: ‘’; width: 1.4em; height: 1.4em; background-color: $blue-grey-900; transform: rotate(45deg); margin-left: -.7em; } h2 { font-size: 1.5em; line-height: 1.2; margin-bottom: .1em; margin-top: 0; } h3 { font-size: 1.2em; margin: .1em 0; font-weight: normal; color: $blue-grey-100; } ul, p { font-weight: normal; } ul { list-style: none; padding: 0; margin: .6em 0 0; }}
O que estamos fazendo:
- Criamos nossos marcadores redondos usando o
.icon-marker
classe e configurar nossa.icon-marker-tooltip
classe para aparecer quando pairou sobre - Nosso
.icon-marker-tooltip
a classe está oculta por padrão, pois é a nossa dica de ferramenta, mas posicionamos absolutamente para aparecer por cima do marcador e formatadas da maneira que queremos.
E, finalmente, quando tivermos nosso geoJsonLayers
criado com nosso estilo adicionado, podemos adicioná-lo ao mapa!
geoJsonLayers.addTo(map)
Agora você pode estar se perguntando por que não parece estar centralizado corretamente. Vá em frente e mude o LOCATION
variável na parte superior do index.js
arquivo para:
const LOCATION = { lat: 0, lng: 0};
Uma vez definido, quando a página for recarregada, o mapa deverá estar centralizado no meio do mundo!
Sim, nós conseguimos! 🎉
Se você seguiu em frente, agora criou o seu próprio painel de mapas do Coronavirus, que fornece estatísticas rápidas sobre os casos em todo o mundo.
Pegue o que aprendeu e corra com ele. Você pode aplicar isso a qualquer outro tipo de dados que possa imaginar.
O que mais podemos fazer?
Adicione mais estilos e um mapa base personalizado
Na minha demonstração original, configurei um mapa base personalizado usando Mapbox isso me permite ter um fundo escuro, facilitando a visualização dos marcadores.
O Mapbox é excelente e possui um bom nível gratuito, se você estiver interessado em começar.
Depois de ter uma conta no Mapbox, você pode até copie o estilo Eu usei e faça você mesmo.
Para aprender como integrá-lo, você pode tentar verificar o código-fonte do minha demo original:
https://github.com/colbyfayock/coronavirus-map-dashboard
Adicionar estatísticas gerais do painel
Painéis com mapas como o Johns Hopkins University app nos permite ver mais do que uma olhada no mapa, mas um vislumbre de estatísticas rápidas sobre os casos em todo o mundo.
o API NovelCOVID tem mais pontos de extremidade como /all
que fornecem algumas estatísticas globais.
Esteja seguro e mantenha-se informado
Quero reiterar que você deve se manter atualizado usando fontes oficiais de informações, como o painel da Johns Hopkins University. Embora os dados devam ser confiáveis, também devem ser considerados uma prova de conceito para a construção de um mapa e referência, mas não devem ser considerados para nenhum tipo de análise estatística.
Por favor, cuide-se durante esses tempos. Estamos juntos nessa! ❤️
Deseja saber mais sobre mapas?
Você pode conferir alguns dos meus outros recursos para começar: