Mapa e tiles: guia de introdução
Este guia apresenta a camada de mapa do projeto para quem chega sem conhecer o tema. Ele cobre os conceitos básicos, os formatos de dado, a cadeia que gera o brasil.mbtiles e um glossário. As decisões de arquitetura e as medições ficam no deploy.md e nos READMEs dos repositórios de código.
A leitura é independente de código. Para operar a geração, o caminho é o README de scripts/tiles do repo mvp-api. Para entender o consumo no app, a seção do mapa no README do mvp-web.
O que é um mapa digital
Seção intitulada “O que é um mapa digital”Um mapa em aplicação web é uma composição de imagens ou de geometrias posicionadas por coordenadas. Existem duas famílias:
- Raster: grade de pixels pronta, como as fotos de satélite. O navegador só posiciona as imagens. Trocar a cor de uma via ou esconder um elemento exige gerar outra imagem no servidor.
- Vetor: o servidor entrega geometria e atributos. O navegador desenha a rua, o prédio e o rótulo na hora. O mesmo dado serve para qualquer estilo, fica nítido em qualquer zoom e ocupa menos banda.
O projeto usa vetor self-hosted nas camadas “ruas” e “escuro”. A camada de satélite continua raster (Esri). O raster do OpenStreetMap existe apenas como fallback quando a camada vetorial falha.
Tiles e zoom
Seção intitulada “Tiles e zoom”Mapas digitais não carregam o mundo inteiro de uma vez. O território é cortado em quadrados chamados tiles, organizados por três números: z/x/y.
zé o zoom. Quanto maior, mais perto.xeylocalizam o tile na grade daquele zoom.
Cada nível de zoom dobra a resolução. O conjunto dos tiles de todos os zooms forma uma pirâmide. minzoom e maxzoom definem o topo e a base dessa pirâmide no tileset.
O tileset do projeto vai do zoom 0 ao 16. O 16 é o teto do Planetiler. Acima disso o app usa overzoom: o MapLibre estica o tile 16 para os zooms 17 a 19. Como o dado é vetor, a geometria é redesenhada e não vira pixel borrado.
Um tileset é descrito por um TileJSON, um JSON com bounds, minzoom, maxzoom e os endereços dos tiles.
Formatos de dado
Seção intitulada “Formatos de dado”Cada etapa da cadeia usa o formato que lhe é natural.
| Formato | O que é | Onde aparece na cadeia |
|---|---|---|
.osm.pbf |
Formato binário do OpenStreetMap, em protobuf comprimido. Guarda nodes, ways e relations com tags | Extrato do Geofabrik e PBF enriquecido que entra no Planetiler |
| GeoJSON / GeoJSONL | JSON de feições geográficas. No GeoJSONL, também chamado GeoJSONSeq, cada linha é uma feição | Saída do filtro do DuckDB para prédios e verde |
csv.gz com JSON por linha |
Partições compactadas, uma feição por linha, indexadas por quadkey | Download dos footprints da Microsoft |
| Parquet | Formato colunar comprimido, bom para leitura analítica | Tema base.land_cover da Overture |
| Shapefile | Formato clássico de SIG, com vários arquivos por conjunto | Seed do IBGE e fontes auxiliares do Planetiler |
| MVT | Mapbox Vector Tile. O tile vetorial em protobuf, com camadas e feições | O que o martin serve em /brasil/{z}/{x}/{y} |
| MBTiles | Arquivo SQLite com todos os tiles e os metadados dentro | O brasil.mbtiles gerado e servido |
| PMTiles | Arquivo único pensado para leitura direta de object storage por HTTP range | Alternativa futura ao MBTiles no projeto |
Os dois sentidos de PBF
Seção intitulada “Os dois sentidos de PBF”A extensão .pbf aparece em dois papéis diferentes:
.osm.pbf: base de dados do OpenStreetMap. É a entrada da geração..pbfde tile: um MVT, o recorte já pronto para o navegador desenhar.
Os dois usam protobuf, mas são formatos diferentes. Um .osm.pbf descreve o território em elementos OSM. Um MVT descreve um quadrado do mapa em camadas prontas para render.
A cadeia do projeto
Seção intitulada “A cadeia do projeto”A camada base combina o extrato do OpenStreetMap com dois enriquecimentos por IA e termina em um único arquivo de tiles.
- Extrato do OSM:
brazil-latest.osm.pbfdo Geofabrik, atualizado diariamente, com checksum.md5. Licença ODbL. - Prédios por IA: footprints da Microsoft GlobalMLBuildingFootprints, em partições
.csv.gzcom JSON por linha, indexadas por quadkey. Licença CDLA-Permissive-2.0. - Cobertura vegetal: tema
base.land_coverda Overture Maps, em Parquet. Licença ODbL, derivada do ESA WorldCover.
O DuckDB faz o trabalho de ETL. Ele lê os formatos das fontes e as feições do OSM extraídas pelo osmium, cruza prédios e verde com os dados do OSM por interseção espacial, descarta sobreposição, simplifica geometria e aplica limites de tamanho. A saída é GeoJSONL. O DuckDB não gera tiles e não serve mapa.
O pyosmium e o osmium convertem esse GeoJSONL para o modelo OSM e mesclam tudo no extrato, gerando um único brasil-com-edificios-verde.osm.pbf. As fontes convergem antes da geração.
O Planetiler lê esse PBF único e escreve o brasil.mbtiles completo, do zoom 0 ao 16. Ele aplica o profile OpenMapTiles, separa as feições por camada, simplifica por zoom e codifica cada tile em MVT. Duas propriedades importantes:
- Ele não junta fontes. Quem junta é o DuckDB, na limpeza, e o osmium, no merge.
- Ele não anexa zoom a arquivo existente. Mudou o maxzoom ou o extrato, a geração roda de novo por inteiro.
O martin lê o MBTiles e serve os tiles por HTTP. O app pede /brasil/{z}/{x}/{y}, recebe MVT e o MapLibre desenha. O service worker guarda os tiles para uso offline.
A cadeia roda fora da VPS, na máquina de geração, e é idempotente. O registro de cada execução fica em arquivos na pasta data/, ignorada pelo Git.
Cobertura de contexto
Seção intitulada “Cobertura de contexto”O tileset cobre duas áreas no mesmo arquivo:
- Brasil (z0–16): gerado do PBF enriquecido com prédios da Microsoft e cobertura vegetal da Overture.
- Vizinhos da América do Sul (z0–16): gerados do extrato
south-america-latest.osm.pbfda Geofabrik, recortado para excluir o polígono do Brasil e limitado ao polígono de terra. Sem prédios e sem verde da Overture: o estilo só exibe prédios a partir do z16 e a vegetação é um enriquecimento do Brasil.
A cadeia roda uma vez por área e termina com a fusão dos tiles por feição. Onde só um lado tem dado, o tile passa direto; onde os dois têm, as camadas são unidas por (camada, id) e a feição do Brasil prevalece. O z0–7 permanece como veio da cobertura de contexto anterior e a fusão atua no z8–16: 1.157.206 tiles fundidos e 27.366.149 tiles inseridos. O arquivo final tem cerca de 24,3 GiB e 87.868.933 tiles. O extrato único cobre o continente inteiro, incluindo Guiana Francesa e Malvinas, que não têm mais extrato próprio na Geofabrik.
Fora da América do Sul, o web embarca o contexto mundial do Natural Earth 50m (src/lib/map/mundo/ no repo mvp-web): terra, água, fronteiras e rótulos de país, desenhados do z0 ao z7, com a América do Sul fora das fronteiras e dos rótulos do Natural Earth. Quando o martin responde 204 ou corpo vazio, o app registra mapa.tile_ausente; quando a viewport fica sem feições do source brasil, o watchdog de 15 s troca a camada pelo raster do OpenStreetMap.
Licenças e atribuições
Seção intitulada “Licenças e atribuições”| Componente | Licença | Atribuição |
|---|---|---|
| Dados do OpenStreetMap | ODbL | © OpenStreetMap contributors |
| Esquema de camadas OpenMapTiles | CC-BY | © OpenMapTiles |
| Prédios Microsoft | CDLA-Permissive-2.0 | Microsoft Building Footprints |
| Cobertura vegetal Overture | ODbL | Overture Maps Foundation e ESA WorldCover / Copernicus |
| Contexto mundial Natural Earth | Domínio público | Natural Earth |
| Código do projeto | AGPL-3.0 | Rede Cívica |
A ODbL tem cláusula de compartilhamento pela mesma licença. O brasil.mbtiles derivado do OSM é disponibilizado sob a mesma licença, em forma legível por máquina.
Glossário
Seção intitulada “Glossário”| Termo | O que é |
|---|---|
| DuckDB | Banco de dados analítico embutido, usado no ETL. Com a extensão Spatial, faz junções e limpeza geoespacial. Não gera nem serve tiles |
| Extrato | Recorte do OpenStreetMap de uma região, publicado por terceiros como o Geofabrik |
| Geofabrik | Provedor de extratos diários do OpenStreetMap por país e região |
| GeoJSON | Formato JSON para geometrias e atributos geográficos. No GeoJSONL, cada linha é uma feição |
| Glyphs | Arquivos de fonte em protobuf usados pelo estilo para desenhar rótulos. O projeto usa Noto Sans, licença OFL |
| martin | Servidor de tiles da MapLibre Organization. Lê MBTiles e responde por HTTP |
| MBTiles | Arquivo SQLite com os tiles e os metadados de um tileset |
| MVT | Mapbox Vector Tile. Especificação do tile vetorial em protobuf |
| Nodes, ways e relations | Os três elementos do modelo de dados do OpenStreetMap. Nodes são pontos, ways são linhas ou polígonos e relations combinam elementos |
| ODbL | Licença dos dados do OpenStreetMap, com compartilhamento pela mesma licença |
| osmium / pyosmium | Ferramentas de manipulação de OSM. Filtram tags, montam ways e mesclam arquivos |
| OSM | OpenStreetMap. Base cartográfica colaborativa e aberta |
| Overzoom | Reescalar um tile do maxzoom para zooms maiores no cliente. Possível em vetor sem perda de nitidez |
| Parquet | Formato colunar comprimido, eficiente para leitura analítica |
| PBF | Protocol Buffers. No projeto aparece como .osm.pbf, os dados do OSM, e como o tile vetorial MVT, também .pbf |
| Pirâmide | Conjunto dos tiles de todos os zooms de um tileset |
| Planetiler | Gerador de tiles em Java. Lê um .osm.pbf, aplica um profile e escreve um MBTiles ou PMTiles |
| PMTiles | Formato de arquivo único que pode ser lido direto de object storage por HTTP range |
| Profile | Conjunto de regras do Planetiler que define quais tags do OSM viram quais camadas do tileset. O projeto usa o profile OpenMapTiles |
| Quadkey | Chave de partição espacial usada pela Microsoft para dividir os footprints em arquivos |
| Raster | Tile de imagem, uma grade de pixels. Usado no satélite e no fallback do OSM |
| Shapefile | Formato clássico de SIG, com vários arquivos por conjunto (.shp, .dbf, .shx, .prj) |
| Source-layer | Nome da camada dentro de um tile vetorial. O estilo aponta para ele, por exemplo building e roads |
| Style JSON | Arquivo do MapLibre que define cores, ordem, zoom e rótulos de cada camada |
| Tile | Quadrado do mapa em um zoom, identificado por z/x/y |
| TileJSON | Metadado JSON que descreve um tileset: bounds, zooms e URLs |
| Tileset | Conjunto completo de tiles de um mapa |
| Vetor | Tile de geometria e atributos, desenhado pelo cliente. Base das camadas ruas e escuro |
| z/x/y | Coordenadas de um tile: zoom, coluna e linha |
Por onde continuar
Seção intitulada “Por onde continuar”- Geração e operação: scripts/tiles no repo
mvp-api. - Consumo no app: seção do mapa no README do mvp-web.
- Deploy do serviço de tiles: deploy.md, seção
tiles (martin). - Fontes oficiais: OpenStreetMap Wiki, Planetiler, martin, MapLibre, Geofabrik, Overture Maps, PMTiles, especificação do MVT e especificação do MBTiles.
Este guia acompanha a cadeia. Mudou o pipeline, o arquivo servido ou uma licença, atualize aqui, no deploy.md e nos READMEs de código na mesma leva.