Um País Inteiro em Voxels: Pipeline de Dados Geoespaciais
Como um pipeline de voxels transformou dados abertos da Suíça em um mundo 1:1 no Minecraft, com lições sobre tiles, LOD e streaming espacial.

Em algum lugar do portal de dados abertos do governo suíço existe um heightmap da face norte do Eiger, amostrado com detalhe suficiente para dar para sentir a rocha. Um desenvolvedor alimentou arquivos como esse em um pipeline de voxels e lançou o resultado como produto jogável: a Suíça inteira como um mundo 1:1 no Minecraft, onde cada bloco equivale a um metro e o Matterhorn tem exatamente a altura e a inclinação do original. O download tem 24 GB compactados, e a região gratuita de amostra sozinha cobre cerca de 2.400 km². A engenharia por trás — tiling, níveis de detalhe, geração preguiçosa — é uma aula de como mover conjuntos de dados espaciais enormes sem que tudo pegue fogo.
O Problema: Um País em Voxels Não Cabe na Memória
Vamos fazer a conta juntos. A Suíça tem 41.285 km². Com um bloco por metro quadrado, são 41,3 bilhões de colunas de superfície antes de você cavar um único buraco. Dê a cada coluna uma profundidade modesta de 100 blocos — pedra, terra, leito de lago — e você chega a quatro trilhões de blocos. Mesmo com um byte por bloco, são quatro terabytes de geometria bruta. Ainda assim, o mundo final é um download de 24 GB, o que mostra algo importante: quase nada dessa geometria é armazenado como geometria. Ela é armazenada como uma receita.
O eixo vertical também quebra tudo. O Minecraft original limita o mundo a 384 blocos de altura. A Suíça vai de 193 m acima do nível do mar, no Lago Maggiore, até 4.634 m no Dufourspitze — um vão de 4.441 m, mais de onze vezes o limite original, antes de alguém cavar uma mina. Por isso o mundo precisa do Cubic Chunks, um mod que substitui o armazenamento em colunas do Minecraft por cubos de 16×16×16 empilhados na altura necessária. Esse mod só roda de forma estável no Minecraft Java 1.12.2, e é por isso que um projeto lançado hoje fixa uma versão do jogo de anos atrás.
A memória é a terceira parede. Construir blocos a partir dos dados de origem na primeira vez que um jogador visita uma área consome muito processamento: o projeto pede no mínimo 16 GB de RAM e é testado em máquinas como um Ryzen 7 7800X3D com 32 GB. Quem já lutou com orçamentos de streaming em jogos ou em GIS vai reconhecer a forma do problema. É a mesma triagem que você faz quando sua GPU fica sem VRAM — você não consegue segurar tudo, então fica muito bom em decidir o que segurar agora.
Primeira Tentativa Falha: Gerar o Mundo Inteiro de Antemão
A abordagem óbvia é um grande job offline: ler os dados geográficos, emitir os arquivos de região do Minecraft — o formato Anvil guarda o mundo em regiões de 512×512 blocos —, compactar o resultado e distribuir. A Dinamarca fez algo parecido em 2014, quando a agência de geodados dinamarquesa liberou o país inteiro como um mapa do Minecraft. Foi uma demonstração marcante de dados abertos e provou que um mapa do tamanho de um país era possível. Então, por que não fazer assim?
Porque pré-gerar tem custos estruturais que crescem com a ambição. Cada bloco de cada região precisa ser gerado, gravado e compactado antes de alguém jogar, o que transforma cada atualização de dados em uma reconstrução completa mais um novo envio de dezenas de gigabytes. Cada jogador baixa montanhas de terreno que nunca vai visitar — e a maior parte dos 41.000 km² nunca será visitada por ninguém. Pior ainda: um mundo pré-gerado congela no snapshot dos dados no momento em que você publica. É um artefato de escrita única. Ele não melhora a menos que você regenere e redistribua tudo, e seus usuários baixam o planeta de novo.
Segunda Tentativa Falha: Um Heightmap, Uma Resolução
A segunda tentação é a normalização: converter todas as entradas em um único raster global com uma única resolução, para que o pipeline tenha exatamente um caminho de código. Dentro da Suíça você tem o swissALTI3D, um modelo de terreno de alta resolução. Além da fronteira, há o Copernicus GLO-30 DEM — um ponto de elevação a cada 30 metros. Reduzir tudo para 30 m por uniformidade transforma a face norte do Eiger em um monte de areia em degraus. Aumentar tudo para a resolução mais fina disponível faz o armazenamento e o processamento explodirem, enquanto as regiões de fronteira continuam sem dados reais — você apenas amostrou a sua ignorância.
A heterogeneidade afeta a semântica tanto quanto a elevação. O swissBUILDINGS3D cobre a Suíça, então o gerador pode erguer prédios de voxels simplificados sobre pegadas reais — mas só dentro do país. Cruzando a fronteira perto de Genebra, não existe camada de construções, então o pipeline faz o único fallback sensato: planta árvores onde deveriam estar as casas. A água precisa de uma fonte própria (o swissBATHY3D para os fundos de lagos), assim como as geleiras, as florestas e os vinhedos. Não existe um único arquivo de entrada. Em geodados, nunca existe.
A lição vai muito além do Minecraft: a resolução é um metadado por tile, não uma constante global. Um pipeline que assume entradas uniformes ou desperdiça fidelidade ou inventa fidelidade — e a fidelidade inventada é pior que a granularidade honesta, porque ninguém consegue perceber a diferença por dentro.

O Que Funciona de Verdade: Um Pipeline em Tiles com Geração Preguiçosa
O projeto suíço funciona porque inverte o instinto de gerar tudo. Você não baixa um mundo pronto; baixa um pacote de mundo — geodados pré-processados mais um gerador customizado — e o jogo constrói os blocos na primeira vez que você visita um lugar. Uma primeira visita a uma área nova leva alguns minutos de processamento; depois disso, ela vira chunks em cache como qualquer outro mundo do Minecraft. O custo de computação é pago por visita, em vez de antecipadamente, e você nunca gera terreno que ninguém pisa. O tile é a unidade de tudo: armazenamento, cache, geração e falhas.
O tiling é ancorado no LV95, o sistema oficial de coordenadas de levantamento da Suíça. Cada tile registra quais datasets o cobrem e em qual resolução, e converter coordenadas de levantamento em coordenadas de blocos é uma transformação afim pura. O projeto até publica a fórmula, para que você pegue coordenadas no visualizador de mapas nacional e se teletransporte para o ponto correspondente no jogo:
def lv95_to_block(east: float, north: float, height: float) -> tuple[int, int, int]:
"""Convert Swiss LV95 survey coordinates to Minecraft block coordinates."""
x = int(east - 2_480_000) # strip the LV95 easting offset
z = int(1_300_000 - north) # Minecraft's z axis grows southward
y = int(height) # one block = one meter above sea level
return x, y, z
# The summit of the Jungfrau, 4,158 m:
print(lv95_to_block(2_640_188, 1_154_072, 4158))
# -> (160188, 4158, 145928)
# x and z match the in-game teleport command exactly; the game just
# drops you a few meters higher so you land on the summit, not in it.
Sobre a grade em tiles, a geração é uma pilha de camadas avaliada coluna por coluna. A altura base vem do swissALTI3D. A cobertura da superfície — água, floresta, estradas, linhas férreas, barragens, barreiras contra avalanches — vem do swissTLM3D. Os fundos de lagos vêm do swissBATHY3D, as alturas das árvores do swissSURFACE3D, os contornos das geleiras dos inventários da GLAMOS desde 1850, e a espessura do gelo de um dataset da ETH Zürich, então a geleira de Aletsch é realmente gelo esculpido, e não uma textura branca estendida sobre a rocha. Prados, detritos e vinhedos vêm do mapa federal de habitats; até as árvores de rua de Zürich vêm do cadastro de árvores da própria cidade. Ao todo, são cerca de quinze datasets abertos, todos livres para uso — a swisstopo abriu seus dados, inclusive para uso comercial, em 2021.
Um mundo de voxels não é uma foto do terreno. É um cache de milhões de pequenas decisões que o seu pipeline tomou, uma por metro quadrado — e a qualidade do mundo é exatamente a qualidade dessas decisões.
Níveis de Detalhe São um Problema de Dados, Não um Truque de Renderização
A distância de renderização padrão do Minecraft mostra algumas centenas de metros. As capturas do projeto mostram a geleira de Aletsch se curvando por quilômetros — essa visão distante ("Fernsicht") é uma representação separada, de fidelidade reduzida, que o jogo constrói uma vez no primeiro início. É um nível de detalhe clássico, mas a decisão importante é onde o LOD vive: ele é calculado a partir dos dados de origem na ingestão, e não improvisado pelo renderizador em tempo real.
Se você já construiu pirâmides de tiles de mapa, conhece a matemática. Cada nível de zoom reduz a resolução pela metade nos dois eixos, então uma pirâmide completa custa 1 + 1/4 + 1/16 + … ≈ 4/3 da camada base — um custo extra de 33% de armazenamento em troca de um comportamento suave em todas as escalas. O LOD de terreno em voxels é a mesma pirâmide posta de pé: o terreno distante é o nível de zoom grosseiro, o terreno próximo é o fino, e a verdadeira arte está em escolher um esquema de chaves que permita buscar a célula certa rapidamente. Enfrentamos as mesmas questões em os trade-offs entre geohashes e índices espaciais de verdade — a escolha da chave define o custo de busca em tudo o que vem depois.
Minha decisão de LOD favorita nem é visual. O download gratuito é uma fatia de 2.400 km² — a região Patrimônio Mundial da UNESCO Jungfrau-Aletsch: Eiger, Mönch, Jungfrau e a maior geleira dos Alpes — rodando exatamente o mesmo pipeline do país inteiro pago. Isso é um lançamento canário como funcionalidade de produto. São 1,1 GB em vez de 24, não exige cadastro, e se roda na sua máquina, o mapa completo também vai rodar. Se você lança produtos com dados grandes, copie isso sem culpa: sua camada gratuita deve ser uma fatia representativa do seu terreno mais difícil, não uma demo capenga do seu caso mais fácil.

Streaming de Tiles Espaciais no Navegador
A mesma disciplina aparece na página web discreta do projeto. Seu mapa de visão geral tem um slider que permite comparar o mundo de voxels com a fotografia aérea real — e as imagens nem vêm dos servidores do projeto. O navegador busca os tiles do SWISSIMAGE diretamente no serviço da própria swisstopo, e só depois que você move o slider. Preguiçoso, direto da origem, amigável ao cache: a banda pesada é servida por uma infraestrutura pública que existe justamente para isso, e a conta de hospedagem do projeto fica perto de zero.
O endereçamento de tiles na web é um problema resolvido, e vale conhecê-lo de cor se você tocar em trabalho geoespacial:
import math
def latlon_to_tile(lat: float, lon: float, zoom: int) -> tuple[int, int]:
"""Standard slippy-map (XYZ) tile addressing used by OSM and most WMTS fronts."""
n = 2 ** zoom
x = int((lon + 180.0) / 360.0 * n)
lat_rad = math.radians(lat)
y = int((1.0 - math.asinh(math.tan(lat_rad)) / math.pi) / 2.0 * n)
return x, y
# At zoom 15, any point on Earth lands in one of 1,073,741,824 tiles.
# Fetch the few that intersect the viewport. Skip the other billion.
Dois detalhes importam mais que a fórmula. Primeiro, a requisição só acontece quando a intenção do usuário fica inequívoca — o slider de fato se move —, o que é ao mesmo tempo uma otimização de banda e uma gentileza com um serviço público gratuito mantido com dinheiro público. Segundo, a procedência viaja junto com os tiles: a página credita SWISSIMAGE, swissBOUNDARIES3D e swissNAMES3D bem no mapa. Quando seu produto é uma obra derivada de dados abertos, a atribuição no ponto de exibição não é enfeite. É a licença funcionando como deveria.
O Que Copiar do Pipeline da Suíça
Primeiro os contrapontos, porque os praticantes levantaram bons argumentos. Esforços feitos à mão, como o Build the Earth, puseram milhares de voluntários para modelar prédios reais, e nenhum pipeline automatizado chega a essa fidelidade — uma pegada do swissBUILDINGS3D voxelizada é uma aproximação grosseira, e se arquitetura é o que te interessa, um export só de terreno é talvez o artefato mais limpo. Justo. Mas cobertura e fidelidade se trocam diretamente: a automação entrega 41.285 km² hoje, a construção manual entrega um centro histórico lindíssimo, um dia. Minha posição: para um produto de dados, a geração automatizada com procedência publicada vence, e os marcos curados à mão podem ser sobrepostos onde importam.
E a procedência é a parte que todo mundo pula. Este projeto publica uma lista de defeitos conhecidos: lacunas perto das fronteiras onde só a grade de 30 m do Copernicus alcança, regiões irregulares ou planas demais, pontes e estradas erradas ou ausentes, e um QA feito por amostragem, e não metro a metro. Essa lista faz um trabalho real — transforma relatórios do tipo “seu mundo está errado aqui” em documentação do tipo “sim, aquele dataset termina ali”. Todo produto de dados derivados deveria publicar sua matriz de procedência e sua lista de problemas conhecidos. Os que não fazem isso não são mais precisos; são apenas menos honestos.
- Trate tudo em tiles. O tile é sua unidade de armazenamento, cache, geração e falha. Monólitos não degradam com elegância.
- Nunca reduza a resolução na ingestão. Mantenha a resolução nativa de cada fonte e reamostre na renderização.
- Gere de forma preguiçosa. Quando o mundo é maior que qualquer tempo de jogo, computar por visita vence pré-gerar.
- Construa a pirâmide de LOD na ingestão. Oriente-se pelo overhead de ~33% e compre escala suave em todas as distâncias.
- Lance uma fatia canário. Um pedaço gratuito e representativo dos seus dados mais difíceis vale mais que qualquer ficha técnica.
- Publique procedência e defeitos conhecidos. Fazem parte do produto, não são um pedido de desculpas por ele.
O país inteiro custa 15 CHF com todas as versões futuras incluídas — e só para residentes suíços, por razões legais, o que é uma restrição curiosamente charmosa para um bem puramente digital. Mas o produto de verdade não é o mapa. É a demonstração de que uma pessoa sozinha, com dados públicos, um pipeline em tiles e documentação honesta, consegue entregar mais do que a infraestrutura geoespacial de muitas equipes. Seu conjunto de dados provavelmente não tem 41.285 km². As suas desculpas também são menores.
