O IBGE Geociências disponibiliza as malhas digitais oficiais do Brasil, incluindo limites territoriais de todas as unidades político-administrativas. Esses dados são a referência oficial para:
Limites municipais — polígonos de todos os 5.570 municípios
Limites estaduais — contornos de todas as 27 UFs
Grandes regiões — Norte, Nordeste, Sudeste, Sul, Centro-Oeste
Mesorregiões e microrregiões — divisões geográficas intermediárias
Regiões metropolitanas — agrupamentos de municípios
Setores censitários — menor unidade territorial do Censo
Biomas — Amazônia, Cerrado, Mata Atlântica, Caatinga, Pampa, Pantanal
Regiões imediatas e intermediárias — nova divisão regional do IBGE (2017)
O IBGE oferece uma API REST para servir as malhas em formatos GeoJSON, TopoJSON e SVG, além de disponibilizar shapefiles completos para download.
import requestsimport json# Malha de São Paulo dividida por municípiosurl = ( "https://servicodados.ibge.gov.br/api/v3/malhas/estados/35" "?formato=application/vnd.geo+json&resolucao=2&intrarregiao=municipio")response = requests.get(url)response.raise_for_status()geojson = response.json()print(f"Tipo: {geojson['type']}")print(f"Municípios: {len(geojson['features'])}")# Salvar como arquivo GeoJSONwith open("sp_municipios.geojson", "w") as f: json.dump(geojson, f)print("GeoJSON salvo em sp_municipios.geojson")
import geopandas as gpdimport pandas as pdimport matplotlib.pyplot as plt# Carregar malha de municípios de uma UFurl = ( "https://servicodados.ibge.gov.br/api/v3/malhas/estados/35" "?formato=application/vnd.geo+json&resolucao=2&intrarregiao=municipio")gdf = gpd.read_file(url)print(f"Municípios carregados: {len(gdf)}")# Exemplo: mapa simplesfig, ax = plt.subplots(figsize=(10, 12))gdf.plot(ax=ax, edgecolor="gray", facecolor="lightblue", linewidth=0.3)ax.set_title("Municípios de São Paulo")ax.set_axis_off()plt.tight_layout()plt.savefig("mapa_sp.png", dpi=150)
import requestsimport pandas as pd# API de Localidades — todos os municípiosurl = "https://servicodados.ibge.gov.br/api/v1/localidades/municipios"response = requests.get(url)response.raise_for_status()municipios = response.json()df = pd.DataFrame([ { "id": m["id"], "nome": m["nome"], "uf": m["microrregiao"]["mesorregiao"]["UF"]["sigla"], } for m in municipios])print(f"Total de municípios: {len(df):,}")print(f"\nMunicípios por UF:")print(df["uf"].value_counts().head())