Todo painel de logística, listagem imobiliária e aplicativo de entrega de alimentos tem uma coisa em comum: um mapa. Se seu site ainda não tem um, você está deixando contexto sobre a mesa. Contexto que ajuda os usuários a entender localização, proximidade e relações espaciais à primeira vista.
Este tutorial o guia através da adição de um mapa totalmente interativo a qualquer projeto JavaScript. Você começará com um mapa renderizado, adicionará marcadores e popups, integrará a busca de endereço com a API de Geocodificação e terminará com um componente React pronto para produção que se integra perfeitamente ao Next.js.
Aqui está o que você construirá ao final:
- Um mapa vetorial ao vivo autenticado com sua chave de API
- Marcadores clicáveis com conteúdo de popup personalizado
- Uma função de busca de endereço alimentada por geocodificação
- Um componente React reutilizável com limpeza adequada e tratamento Next.js SSR
- Uma lista de otimizações de desempenho para produção
Pré-requisitos
Antes de começar, certifique-se de que tem:
- Uma chave de API MapAtlas (inscrever-se gratuitamente, sem cartão de crédito necessário). Esta chave única autentica todos os serviços MapAtlas: tiles, geocodificação e roteamento.
- Um projeto JavaScript. HTML simples, React, Vue ou Svelte funcionam todos.
- Node.js 18+ se estiver instalando via npm.
Passo 1: Instalar o SDK MapAtlas
Puxe o SDK para seu projeto com npm:
npm install @mapmetrics/mapmetrics-gl
Se estiver trabalhando com uma página HTML simples, coloque os links CDN em seu <head>:
<link rel="stylesheet" href="https://unpkg.com/@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.css" />
<script src="https://unpkg.com/@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.js"></script>
Não pule a importação CSS. Sem ele, os controles do mapa e popups são renderizados sem estilo. Funcional, mas visualmente quebrado.
Passo 2: Criar um Contêiner de Mapa
O SDK preenche qualquer elemento para o qual você o aponte, portanto você precisa de um <div> com altura explícita. Este é o erro de configuração mais comum: se o contêiner tiver height: 0, o mapa é inicializado mas permanece invisível.
<div id="map" style="width: 100%; height: 500px;"></div>
Um valor de pixel fixo ou unidade de visualização (100vh, 50vh) funcionam. Alturas percentuais funcionam apenas se o elemento pai também tiver uma altura definida.
Passo 3: Renderizar Seu Primeiro Mapa Interativo
Três linhas de configuração são tudo o que é necessário: um contêiner, uma URL de estilo com sua chave de API e uma posição inicial.
import mapmetricsgl from '@mapmetrics/mapmetrics-gl';
import '@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.css';
const map = new mapmetricsgl.Map({
container: 'map',
style: 'https://tiles.mapatlas.eu/styles/basic/style.json?key=YOUR_API_KEY',
center: [4.9041, 52.3676],
zoom: 12,
});
Abra a página e você verá um mapa vetorial que pode arrastar, rolar e beliscar para navegar. Os tiles são carregados sob demanda dos servidores MapAtlas, portanto não há download pesado antecipado.
Escolher um Estilo de Mapa
Troque o segmento de caminho na URL de estilo para mudar completamente a aparência:
| Estilo | Caminho de URL | Melhor para |
|---|---|---|
| Basic | /styles/basic/style.json | Aplicativos de propósito geral |
| Bright | /styles/bright/style.json | Sobreposições de visualização de dados |
| Dark | /styles/dark/style.json | Painéis, modo noturno, análise |
Ganho rápido: Use o estilo Dark para painéis de administração e ferramentas usadas em ambientes com pouca luz. Reduz a fadiga ocular e faz com que camadas de dados como mapas de calor e linhas de rota apareçam visualmente contra o fundo.
Passo 4: Adicionar Marcadores e Popups ao Seu Mapa
Um mapa sem marcadores é apenas uma imagem de fundo. Os marcadores transformam uma vista estática em algo com o que os usuários podem interagir.
Marcador Único com um Popup
const popup = new mapmetricsgl.Popup().setHTML(`
<strong>Amsterdam Central</strong>
<p>Stationsplein, 1012 AB Amsterdam</p>
`);
new mapmetricsgl.Marker({ color: '#97C70A' })
.setLngLat([4.9001, 52.3791])
.setPopup(popup)
.addTo(map);
Clique no marcador e o popup abre. Você pode colocar qualquer HTML dentro: endereços, miniaturas, botões CTA, o que sua UI exigir.
Plotando Múltiplos Marcadores a partir de Dados
A maioria dos aplicativos do mundo real precisa de mais de um pino. Faça um loop sobre um array e crie um marcador para cada entrada:
const locations = [
{ name: 'Amsterdam', coords: [4.9041, 52.3676] },
{ name: 'Rotterdam', coords: [4.4777, 51.9244] },
{ name: 'Utrecht', coords: [5.1214, 52.0907] },
];
locations.forEach(({ name, coords }) => {
const popup = new mapmetricsgl.Popup().setHTML(`<strong>${name}</strong>`);
new mapmetricsgl.Marker({ color: '#97C70A' })
.setLngLat(coords)
.setPopup(popup)
.addTo(map);
});
Nota de desempenho: Uma vez que você exceder aproximadamente 100 a 200 marcadores, a renderização desacelera notavelmente em visualizações afastadas. Ative o clustering de fonte GeoJSON (suportado nativamente pelo SDK) para agrupar marcadores próximos em níveis de zoom baixos. Confira a documentação do SDK para configuração de clustering.
Passo 5: Adicionar Busca de Endereço com a API de Geocodificação
A API de Geocodificação transforma uma consulta de texto (um endereço de rua, nome de cidade ou ponto de referência) em coordenadas que você pode navegar, marcar ou alimentar em uma solicitação de roteamento.
async function searchAddress(query) {
const url = new URL('https://api.mapatlas.eu/geocoding/v1/search');
url.searchParams.set('text', query);
url.searchParams.set('key', 'YOUR_API_KEY');
const res = await fetch(url);
const data = await res.json();
if (!data.features.length) return;
const [lng, lat] = data.features[0].geometry.coordinates;
const label = data.features[0].properties.label;
map.flyTo({ center: [lng, lat], zoom: 14 });
new mapmetricsgl.Marker({ color: '#97C70A' })
.setLngLat([lng, lat])
.setPopup(new mapmetricsgl.Popup().setHTML(`<strong>${label}</strong>`))
.addTo(map);
}
searchAddress('Rijksmuseum, Amsterdam');
Os resultados voltam como recursos GeoJSON, portanto se conectam diretamente a qualquer camada compatível com GeoJSON, tabela de dados ou chamada de API a jusante.
Construa uma barra de busca ao vivo em menos de 30 linhas: Anexe
searchAddressao eventoinputde um campo de texto, rebote por 300ms, e você tem busca de mapa estilo autocompletar sem dependências extras.
Integrando Mapas Interativos com React
Um Componente de Mapa Reutilizável
Envolva a inicialização do mapa em useEffect para que seja executada após a montagem do DOM e retorne uma função de limpeza para evitar vazamentos de memória ao desmontar:
import { useEffect, useRef } from 'react';
import mapmetricsgl from '@mapmetrics/mapmetrics-gl';
import '@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.css';
export function MapAtlasMap({ apiKey, center = [4.9041, 52.3676], zoom = 12 }) {
const containerRef = useRef(null);
useEffect(() => {
const map = new mapmetricsgl.Map({
container: containerRef.current,
style: `https://tiles.mapatlas.eu/styles/basic/style.json?key=${apiKey}`,
center, zoom,
});
return () => map.remove();
}, [apiKey]);
return <div ref={containerRef} style={{ width: '100%', height: '500px' }} />;
}
Use em qualquer lugar em sua árvore de componentes:
<MapAtlasMap apiKey={process.env.NEXT_PUBLIC_MAPATLAS_KEY} center={[4.9041, 52.3676]} zoom={13} />
Tratando a Renderização do Lado do Servidor do Next.js
O SDK do mapa depende de APIs do navegador (window, document) que não existem durante SSR. Importe o componente dinamicamente com SSR desabilitado:
import dynamic from 'next/dynamic';
const MapAtlasMap = dynamic(
() => import('./MapAtlasMap').then(m => m.MapAtlasMap),
{ ssr: false, loading: () => (<div style={{ height: 500, background: '#f0f1f3', borderRadius: 12 }} />) }
);
O espaço reservado loading mantém seu layout estável enquanto o pacote de mapa é baixado, evitando mudança de layout cumulativa (CLS), que importa tanto para a experiência do usuário quanto para Core Web Vitals.
Lista de Verificação de Desempenho de Produção
Antes de enviar, execute estas otimizações:
- Carregamento lento de mapas abaixo da dobra. Use
IntersectionObserverpara inicializar o mapa apenas quando seu contêiner rola para a visualização. Isto adia ~200 KB de JavaScript do carregamento da página inicial. - Fique com tiles vetoriais. Tiles vetoriais escalam perfeitamente para qualquer densidade de tela, carregam mais rápido do que imagens raster e podem ser redesenhados no cliente sem solicitações de servidor adicionais. MapAtlas fornece tiles vetoriais por padrão.
- Agrupe grandes conjuntos de marcadores. Além de 100 a 200 marcadores, a renderização sem cluster em uma visualização afastada causa queda notável de quadros. O clustering resolve isso completamente.
- Mantenha sua chave de API no lado do servidor. Nunca confirme chaves em um repositório público. Use variáveis de ambiente (
NEXT_PUBLIC_MAPATLAS_KEYno Next.js) ou proxie solicitações através de seu backend para operações sensíveis. - Defina
maxBoundspara aplicativos regionais. Se seus usuários se importam apenas com uma geografia, restrinja a janela de visualização para que tiles fora dessa área nunca sejam solicitados. Menos chamadas de rede, carregamento mais rápido.
O Que Construir a Seguir
Você tem um mapa que renderiza, mostra marcadores, busca endereços e se integra com React. Aqui está para onde ir daí:
- Routing API: Solicite instruções passo a passo entre duas coordenadas. Retorna uma polilinha de rota, distância total e tempo de viagem estimado.
- Isochrone API: Gere um polígono cobrindo cada ponto acessível em n minutos. Usado para zonas de entrega, mapas de cobertura de serviço e análise de área de captura.
- Matrix API: Calcule tempo de viagem e distância entre múltiplas origens e destinos em uma única solicitação. Essencial para despacho de frota e otimização de logística.
Referência completa do SDK, documentação de estilo e guias de API estão disponíveis em docs.mapatlas.xyz.
Perguntas Frequentes
Posso adicionar mapas interativos ao meu site gratuitamente?
Sim. MapAtlas oferece um nível gratuito sem cartão de crédito necessário no inscrição. Inclui renderização de tiles vetoriais, a API de Geocodificação e a API de Roteamento. Isso é suficiente para desenvolvimento e uso de produção em pequena escala.
Como faço para incorporar um mapa em um aplicativo React ou Next.js?
Envolva a inicialização do mapa em um hook useEffect para que seja executada após a montagem do DOM. No Next.js, use dynamic() com ssr: false para evitar erros de renderização no lado do servidor. Ambas as abordagens são cobertas com exemplos copiar-colar neste tutorial.
O que são tiles vetoriais e por que devo usá-los em vez de raster?
Tiles vetoriais descrevem recursos do mapa (estradas, edifícios, rótulos) como geometria matemática em vez de imagens de pixels pré-renderizadas. Eles escalam nitidamente para qualquer resolução, baixam mais rápido e podem ser completamente redesenhados no cliente sem rodadas de servidor adicionais.
Quantos marcadores posso adicionar antes do desempenho cair?
A renderização normalmente se degrada além de 100 a 200 marcadores em níveis de zoom baixos. A correção é clustering: o SDK MapAtlas suporta clustering de fonte GeoJSON nativamente, agrupando marcadores próximos em zoom baixo e expandindo-os conforme o usuário faz zoom.
Preciso de experiência GIS para usar MapAtlas?
Não. O SDK foi projetado para desenvolvedores web, não para especialistas em GIS. Você inicializa um mapa com coordenadas e um nível de zoom, adiciona marcadores com pares longitude/latitude e chama a API de Geocodificação com texto simples. Sem bancos de dados espaciais ou ferramentas GIS necessárias.
