geocodebr 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- geocodebr-0.1.0/.gitignore +32 -0
- geocodebr-0.1.0/CHANGELOG.md +73 -0
- geocodebr-0.1.0/LICENSE.txt +21 -0
- geocodebr-0.1.0/PKG-INFO +436 -0
- geocodebr-0.1.0/README.md +396 -0
- geocodebr-0.1.0/benchmarks/benchmark_sample.py +240 -0
- geocodebr-0.1.0/benchmarks/probe_compat_layer.log +30 -0
- geocodebr-0.1.0/benchmarks/resultados_benchmark.csv +4 -0
- geocodebr-0.1.0/benchmarks/resultados_benchmark.md +291 -0
- geocodebr-0.1.0/benchmarks/verifica_deterioracao.py +216 -0
- geocodebr-0.1.0/benchmarks/verifica_segment_heap.py +52 -0
- geocodebr-0.1.0/benchmarks/verifica_segment_heap_compat.py +262 -0
- geocodebr-0.1.0/benchmarks/verifica_segment_heap_geocode.py +99 -0
- geocodebr-0.1.0/benchmarks/verifica_sweep_threads.py +204 -0
- geocodebr-0.1.0/exemplos/busca_por_cep.py +23 -0
- geocodebr-0.1.0/exemplos/enderecos.csv +6 -0
- geocodebr-0.1.0/exemplos/geocode_enderecos.py +47 -0
- geocodebr-0.1.0/exemplos/geocode_reverso.py +26 -0
- geocodebr-0.1.0/geocodebr/__init__.py +26 -0
- geocodebr-0.1.0/geocodebr/_heap.py +119 -0
- geocodebr-0.1.0/geocodebr/_heap_patch.py +130 -0
- geocodebr-0.1.0/geocodebr/cache.py +159 -0
- geocodebr-0.1.0/geocodebr/cep.py +117 -0
- geocodebr-0.1.0/geocodebr/constants.py +21 -0
- geocodebr-0.1.0/geocodebr/db.py +89 -0
- geocodebr-0.1.0/geocodebr/download_cnefe.py +108 -0
- geocodebr-0.1.0/geocodebr/errors.py +11 -0
- geocodebr-0.1.0/geocodebr/fields.py +136 -0
- geocodebr-0.1.0/geocodebr/geo.py +61 -0
- geocodebr-0.1.0/geocodebr/geocode.py +362 -0
- geocodebr-0.1.0/geocodebr/match_types.py +140 -0
- geocodebr-0.1.0/geocodebr/matching.py +838 -0
- geocodebr-0.1.0/geocodebr/messages.py +47 -0
- geocodebr-0.1.0/geocodebr/py.typed +0 -0
- geocodebr-0.1.0/geocodebr/reverse.py +253 -0
- geocodebr-0.1.0/geocodebr/standardize.py +237 -0
- geocodebr-0.1.0/geocodebr/string_dist.py +54 -0
- geocodebr-0.1.0/geocodebr/tables.py +101 -0
- geocodebr-0.1.0/geocodebr/utils.py +51 -0
- geocodebr-0.1.0/pyproject.toml +74 -0
- geocodebr-0.1.0/tests/conftest.py +163 -0
- geocodebr-0.1.0/tests/test_busca_por_cep.py +56 -0
- geocodebr-0.1.0/tests/test_cache.py +76 -0
- geocodebr-0.1.0/tests/test_db.py +68 -0
- geocodebr-0.1.0/tests/test_download_cnefe.py +97 -0
- geocodebr-0.1.0/tests/test_errors.py +13 -0
- geocodebr-0.1.0/tests/test_fields.py +48 -0
- geocodebr-0.1.0/tests/test_geo.py +24 -0
- geocodebr-0.1.0/tests/test_geocode.py +195 -0
- geocodebr-0.1.0/tests/test_geocode_reverso.py +159 -0
- geocodebr-0.1.0/tests/test_heap.py +316 -0
- geocodebr-0.1.0/tests/test_matching.py +364 -0
- geocodebr-0.1.0/tests/test_messages.py +37 -0
- geocodebr-0.1.0/tests/test_r_python_parity.py +838 -0
- geocodebr-0.1.0/tests/test_regression_news_port.py +371 -0
- geocodebr-0.1.0/tests/test_regression_news_port_2.py +347 -0
- geocodebr-0.1.0/tests/test_resultado_gpd.py +116 -0
- geocodebr-0.1.0/tests/test_standardize.py +123 -0
- geocodebr-0.1.0/tests/test_utils.py +229 -0
- geocodebr-0.1.0/uv.lock +1308 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
*.Rcheck/
|
|
2
|
+
.Rproj.user
|
|
3
|
+
.Rhistory
|
|
4
|
+
.RData
|
|
5
|
+
.Ruserdata
|
|
6
|
+
censobr_*.tar.gz
|
|
7
|
+
r-package/vignettes/*.html
|
|
8
|
+
.parquet
|
|
9
|
+
.tmp
|
|
10
|
+
*.o
|
|
11
|
+
*.so
|
|
12
|
+
*.swp
|
|
13
|
+
*.dll
|
|
14
|
+
docs
|
|
15
|
+
/data_prep/data/*
|
|
16
|
+
/data_prep/data_raw/*
|
|
17
|
+
*.pyc
|
|
18
|
+
__pycache__/
|
|
19
|
+
.venv/
|
|
20
|
+
# artefatos locais de pytest/coverage (Python)
|
|
21
|
+
.coverage
|
|
22
|
+
coverage.xml
|
|
23
|
+
.pytest_cache/
|
|
24
|
+
geocodebr.Rproj
|
|
25
|
+
|
|
26
|
+
# Sample de benchmark com microdados (hospedada em repo privada, não commitar)
|
|
27
|
+
data/
|
|
28
|
+
python-package/benchmarks/data/
|
|
29
|
+
.cnefe-cache/
|
|
30
|
+
|
|
31
|
+
# Claude Code — config local de máquina (não versionada)
|
|
32
|
+
.claude/settings.local.json
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
## [0.1.0] - 2026-09-22
|
|
6
|
+
|
|
7
|
+
Primeira versão pública do pacote Python `geocodebr`, um porte do pacote R
|
|
8
|
+
[{geocodebr}](https://github.com/ipeaGIT/geocodebr) (v0.6.4/desenvolvimento).
|
|
9
|
+
Preserva a dinâmica de uso do R, incluindo os nomes de funções em português e a
|
|
10
|
+
taxonomia de `precisao` / `tipo_resultado`, usando DuckDB como motor principal
|
|
11
|
+
de dados.
|
|
12
|
+
|
|
13
|
+
### Adicionado
|
|
14
|
+
|
|
15
|
+
- `geocode()`: geolocaliza endereços brasileiros a partir de uma tabela na qual
|
|
16
|
+
cada coluna descreve um campo do endereço (logradouro, número, CEP, etc.). O
|
|
17
|
+
resultado preserva as colunas originais e adiciona `lat`, `lon`, `precisao`,
|
|
18
|
+
`tipo_resultado`, `desvio_metros` e `endereco_encontrado` (e, com
|
|
19
|
+
`resultado_completo=True`, também `cod_setor`, `contagem_cnefe`, `empate` e as
|
|
20
|
+
colunas `*_encontrado`/`*_encontrada`). Aceita `pyarrow.Table`,
|
|
21
|
+
`polars.DataFrame`, `pandas.DataFrame` ou o caminho de um arquivo `.csv` ou
|
|
22
|
+
`.parquet`.
|
|
23
|
+
- `geocode_reverso()`: busca o endereço mais próximo de pontos de um
|
|
24
|
+
`geopandas.GeoDataFrame` dentro de `dist_max` metros, devolvendo o próprio
|
|
25
|
+
`GeoDataFrame` de input acrescido do endereço encontrado e da coluna
|
|
26
|
+
`distancia_metros`.
|
|
27
|
+
- `busca_por_cep()`: retorna os endereços e coordenadas associados a um ou mais
|
|
28
|
+
CEPs.
|
|
29
|
+
- `definir_campos()`: monta o dicionário de correspondência entre os campos do
|
|
30
|
+
endereço e as colunas da tabela de input. `estado` e `municipio` são
|
|
31
|
+
obrigatórios.
|
|
32
|
+
- `download_cnefe()`: baixa uma ou mais tabelas da versão pré-processada e
|
|
33
|
+
enriquecida do CNEFE usada pelo pacote.
|
|
34
|
+
- `definir_pasta_cache()`, `listar_pasta_cache()`, `listar_dados_cache()` e
|
|
35
|
+
`deletar_pasta_cache()`: gerenciamento da pasta de cache local dos dados do
|
|
36
|
+
CNEFE, persistente entre sessões.
|
|
37
|
+
- `enderecobr_padronizar_enderecos()`: padronização dos campos de endereço,
|
|
38
|
+
espelhando `enderecobr::padronizar_enderecos` do R.
|
|
39
|
+
|
|
40
|
+
### Detalhes de implementação e diferenças em relação ao R
|
|
41
|
+
|
|
42
|
+
- **Retorno padrão em `pyarrow.Table`.** As três funções principais retornam um
|
|
43
|
+
`pyarrow.Table` por padrão. Com `resultado_gpd=True`, o retorno é um
|
|
44
|
+
`geopandas.GeoDataFrame` de pontos no CRS SIRGAS 2000 (EPSG 4674),
|
|
45
|
+
equivalente ao `sf` do R. Esse retorno exige o extra `geo`
|
|
46
|
+
(`pip install geocodebr[geo]`).
|
|
47
|
+
- **Pipeline DuckDB-first.** O fluxo interno registra as entradas no DuckDB,
|
|
48
|
+
executa joins, filtros e matches em SQL e só materializa o resultado no final.
|
|
49
|
+
A padronização de endereços é a única etapa fora do DuckDB, feita em `polars`.
|
|
50
|
+
- **Ciclo de vida da conexão DuckDB.** `geocode()`, `geocode_reverso()` e
|
|
51
|
+
`busca_por_cep()` fecham a conexão com o banco ao final da execução, inclusive
|
|
52
|
+
quando interrompidas por um erro no meio do caminho (bloco `finally`).
|
|
53
|
+
Diferentemente do pacote R, o `geocode()` roda no próprio processo do usuário
|
|
54
|
+
(sem subprocesso equivalente ao `callr::r()`).
|
|
55
|
+
- **Paralelismo configurável.** `geocode()` e `geocode_reverso()` aceitam
|
|
56
|
+
`n_cores`.
|
|
57
|
+
- **Mitigação no Windows.** Sem Segment Heap, o `geocode()` limita
|
|
58
|
+
automaticamente o DuckDB a `min(4, núcleos)` threads e emite um aviso uma vez
|
|
59
|
+
por sessão. A criação opcional de uma cópia do interpretador com Segment Heap
|
|
60
|
+
(`python -m geocodebr._heap_patch`) chega a reduzir o tempo de uma carga de 10
|
|
61
|
+
milhões de endereços de ~11:47 para ~3:08 (benchmarks internos).
|
|
62
|
+
- **Suíte de testes de paridade R vs Python.** Testes comparam a saída do
|
|
63
|
+
Python com a do pacote R nos arquivos de exemplo, marcados com `r_parity` e
|
|
64
|
+
pulados automaticamente quando `Rscript` não está disponível.
|
|
65
|
+
|
|
66
|
+
### Validação de paridade com o R
|
|
67
|
+
|
|
68
|
+
- Em uma carga real de **43,9 milhões de endereços**, o
|
|
69
|
+
`geocode()` retornou resultado **idêntico** ao do pacote R em todas as linhas,
|
|
70
|
+
comparadas uma a uma: mesmas categorias (`tipo_resultado`, `precisao`), mesmo
|
|
71
|
+
endereço encontrado, mesmos `desvio_metros`, `cod_setor` e `contagem_cnefe`, e
|
|
72
|
+
mesmas coordenadas. As duas saídas foram geradas a partir do **mesmo arquivo de
|
|
73
|
+
input**.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Institute for Applied Economic Research (Ipea)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
geocodebr-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: geocodebr
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Geolocalização de endereços brasileiros com DuckDB
|
|
5
|
+
Project-URL: Repository, https://github.com/ipea/geocodebr
|
|
6
|
+
Project-URL: Issues, https://github.com/ipea/geocodebr/issues
|
|
7
|
+
Author: Gabriel Garcia de Almeida
|
|
8
|
+
Author-email: "Rafael H. M. Pereira" <rafa.pereira.br@gmail.com>, Daniel Herszenhut <dhersz@gmail.com>
|
|
9
|
+
Maintainer: Camila Gonçalves de Brito, Jefferson Silva dos Anjos
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE.txt
|
|
12
|
+
Keywords: brasil,cnefe,duckdb,enderecos,geocoding,geolocation,ibge
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Natural Language :: Portuguese (Brazilian)
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
26
|
+
Requires-Python: >=3.10
|
|
27
|
+
Requires-Dist: duckdb>=1.0.0
|
|
28
|
+
Requires-Dist: enderecobr>=0.3.0
|
|
29
|
+
Requires-Dist: h3>=4.0.0
|
|
30
|
+
Requires-Dist: numpy>=1.26.0
|
|
31
|
+
Requires-Dist: pandas>=2.0
|
|
32
|
+
Requires-Dist: platformdirs>=4.0.0
|
|
33
|
+
Requires-Dist: polars>=1.0
|
|
34
|
+
Requires-Dist: pyarrow>=15.0.0
|
|
35
|
+
Requires-Dist: requests>=2.31.0
|
|
36
|
+
Requires-Dist: tqdm>=4.66.0
|
|
37
|
+
Provides-Extra: geo
|
|
38
|
+
Requires-Dist: geopandas>=0.14.0; extra == 'geo'
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
|
|
41
|
+
# geocodebr Python: Geolocalização de Endereços Brasileiros <img align="right" src="../r-package/man/figures/logo.svg" alt="" width="180">
|
|
42
|
+
|
|
43
|
+
[]()
|
|
44
|
+
[](https://github.com/ipea/geocodebr/actions/workflows/python-check.yaml)
|
|
45
|
+
[](https://github.com/ipea/geocodebr/actions/workflows/python-parity.yaml)
|
|
46
|
+
[](https://app.codecov.io/gh/ipea/geocodebr/tree/python_test?flags%5B0%5D=python)
|
|
48
|
+
|
|
49
|
+
Versão Python do `geocodebr`, usando DuckDB como motor tabular principal.
|
|
50
|
+
A proposta é preservar a dinâmica de uso do pacote R, incluindo nomes
|
|
51
|
+
de funções em português, mantendo o processamento interno em SQL/DuckDB para
|
|
52
|
+
boa performance e menor uso de memória.
|
|
53
|
+
|
|
54
|
+
O pacote geolocaliza endereços brasileiros sem limite de número de consultas,
|
|
55
|
+
com base em dados abertos do CNEFE (Cadastro Nacional de Endereços para Fins
|
|
56
|
+
Estatísticos), publicado pelo IBGE.
|
|
57
|
+
|
|
58
|
+
## Instalação
|
|
59
|
+
|
|
60
|
+
No momento, esta versão Python ainda está em desenvolvimento dentro deste
|
|
61
|
+
repositório (a publicação no PyPI está planejada). Para instalar localmente:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
cd python-package
|
|
65
|
+
python -m pip install -e .
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Dependências principais:
|
|
69
|
+
|
|
70
|
+
- `duckdb`: motor principal de dados e SQL.
|
|
71
|
+
- `pyarrow`: formato padrão de retorno e interoperabilidade com Parquet.
|
|
72
|
+
- `enderecobr`: padronização dos endereços, garantindo paridade com o pacote R.
|
|
73
|
+
- `polars`: processamento tabular interno, usado para integrar o `enderecobr`.
|
|
74
|
+
- `requests`: download dos dados do CNEFE.
|
|
75
|
+
- `h3`: criação opcional de células H3.
|
|
76
|
+
|
|
77
|
+
## Utilização
|
|
78
|
+
|
|
79
|
+
O pacote possui três funções principais:
|
|
80
|
+
|
|
81
|
+
1. `geocode()`
|
|
82
|
+
2. `geocode_reverso()`
|
|
83
|
+
3. `busca_por_cep()`
|
|
84
|
+
|
|
85
|
+
As funções retornam, por padrão, um `pyarrow.Table`. Caso precise converter para
|
|
86
|
+
`pandas`, use `.to_pandas()` no resultado final. Passando `resultado_gpd=True`, o
|
|
87
|
+
retorno é um `geopandas.GeoDataFrame` de pontos no CRS SIRGAS 2000 (EPSG 4674),
|
|
88
|
+
equivalente ao `sf` do pacote R. Esse retorno exige o extra `geo` na instalação
|
|
89
|
+
(`python -m pip install geocodebr[geo]`).
|
|
90
|
+
|
|
91
|
+
### 1. Geolocalização: de endereços para coordenadas
|
|
92
|
+
|
|
93
|
+
Primeiro, indique quais colunas da sua tabela representam cada campo do
|
|
94
|
+
endereço usando `definir_campos()`. Depois, chame `geocode()`.
|
|
95
|
+
|
|
96
|
+
Por padrão, os endereços são padronizados internamente pela função
|
|
97
|
+
`enderecobr_padronizar_enderecos()`, o que é essencial para uma
|
|
98
|
+
geolocalização correta. O primeiro uso pode baixar os dados do CNEFE para o
|
|
99
|
+
cache local.
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
import polars as pl
|
|
103
|
+
|
|
104
|
+
from geocodebr import definir_campos, geocode
|
|
105
|
+
|
|
106
|
+
enderecos = pl.DataFrame({
|
|
107
|
+
"logradouro": ["RUA PRESIDENTE VARGAS", "AVENIDA PAULISTA"],
|
|
108
|
+
"numero": [123, 1000],
|
|
109
|
+
"cep": ["20080-901", "01310-100"],
|
|
110
|
+
"localidade": ["Centro", "Bela Vista"],
|
|
111
|
+
"municipio": ["RIO DE JANEIRO", "SAO PAULO"],
|
|
112
|
+
"estado": ["RJ", "SP"],
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
campos = definir_campos(
|
|
116
|
+
logradouro="logradouro",
|
|
117
|
+
numero="numero",
|
|
118
|
+
cep="cep",
|
|
119
|
+
localidade="localidade",
|
|
120
|
+
municipio="municipio",
|
|
121
|
+
estado="estado",
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
resultado = geocode(
|
|
125
|
+
enderecos=enderecos,
|
|
126
|
+
campos_endereco=campos,
|
|
127
|
+
resultado_completo=False,
|
|
128
|
+
resolver_empates=True,
|
|
129
|
+
h3_res=[8, 10],
|
|
130
|
+
verboso=False,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
print(resultado.schema.names)
|
|
134
|
+
print(resultado.to_pandas().head())
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Também é possível passar diretamente um caminho para arquivo `.csv` ou `.parquet`:
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
resultado = geocode(
|
|
141
|
+
enderecos="caminho/para/enderecos.csv",
|
|
142
|
+
campos_endereco=campos,
|
|
143
|
+
verboso=False,
|
|
144
|
+
)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
O resultado preserva as colunas originais e adiciona, entre outras:
|
|
148
|
+
|
|
149
|
+
- `lat`
|
|
150
|
+
- `lon`
|
|
151
|
+
- `precisao`
|
|
152
|
+
- `tipo_resultado`
|
|
153
|
+
- `desvio_metros`
|
|
154
|
+
- `endereco_encontrado`
|
|
155
|
+
|
|
156
|
+
Com `resultado_completo=True`, também retorna campos encontrados no CNEFE, como
|
|
157
|
+
`logradouro_encontrado`, `numero_encontrado`, `cep_encontrado`,
|
|
158
|
+
`localidade_encontrada`, `municipio_encontrado`, `estado_encontrado`,
|
|
159
|
+
`similaridade_logradouro`, `contagem_cnefe`, `empate` e `cod_setor`.
|
|
160
|
+
|
|
161
|
+
### 2. Geolocalização reversa: de coordenadas para endereços
|
|
162
|
+
|
|
163
|
+
`geocode_reverso()` busca o endereço mais próximo de cada ponto dentro de uma
|
|
164
|
+
distância máxima em metros. Assim como no R, a entrada deve ser um
|
|
165
|
+
`GeoDataFrame` de pontos no CRS SIRGAS 2000 (`EPSG:4674`), e o retorno é o
|
|
166
|
+
próprio `GeoDataFrame` de input acrescido dos campos do endereço encontrado e
|
|
167
|
+
da coluna `distancia_metros`. Esta função requer o extra `geo`
|
|
168
|
+
(`pip install geocodebr[geo]`).
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
import geopandas as gpd
|
|
172
|
+
|
|
173
|
+
from geocodebr import geocode_reverso
|
|
174
|
+
|
|
175
|
+
pontos = gpd.GeoDataFrame(
|
|
176
|
+
{"id": [1, 2]},
|
|
177
|
+
geometry=gpd.points_from_xy([-47.9001, -43.2001], [-15.8001, -22.9001]),
|
|
178
|
+
crs="EPSG:4674",
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
enderecos_proximos = geocode_reverso(
|
|
182
|
+
pontos=pontos,
|
|
183
|
+
dist_max=1000,
|
|
184
|
+
verboso=False,
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
print(enderecos_proximos)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
O resultado inclui os campos do endereço encontrado e a coluna
|
|
191
|
+
`distancia_metros`.
|
|
192
|
+
|
|
193
|
+
### 3. Busca por CEP
|
|
194
|
+
|
|
195
|
+
`busca_por_cep()` retorna os endereços associados a um ou mais CEPs.
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from geocodebr import busca_por_cep
|
|
199
|
+
|
|
200
|
+
ceps = ["70390-025", "20071-001", "99999-999"]
|
|
201
|
+
|
|
202
|
+
resultado_cep = busca_por_cep(
|
|
203
|
+
cep=ceps,
|
|
204
|
+
h3_res=10,
|
|
205
|
+
verboso=False,
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
print(resultado_cep.to_pandas())
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
O resultado inclui:
|
|
212
|
+
|
|
213
|
+
- `cep`
|
|
214
|
+
- `estado`
|
|
215
|
+
- `municipio`
|
|
216
|
+
- `logradouro`
|
|
217
|
+
- `localidade`
|
|
218
|
+
- `lon`
|
|
219
|
+
- `lat`
|
|
220
|
+
|
|
221
|
+
Se `h3_res` for informado, o pacote adiciona colunas como `h3_08` ou `h3_10`.
|
|
222
|
+
|
|
223
|
+
### Padronização de endereços
|
|
224
|
+
|
|
225
|
+
A função `enderecobr_padronizar_enderecos()` também está disponível
|
|
226
|
+
publicamente, para padronizar os endereços antes da geolocalização (ou usá-la
|
|
227
|
+
de forma independente). Ela recebe um `polars.DataFrame` e o dicionário criado
|
|
228
|
+
com `definir_campos()`, e adiciona as colunas `*_padr`:
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
from geocodebr import enderecobr_padronizar_enderecos
|
|
232
|
+
|
|
233
|
+
enderecos_padrao = enderecobr_padronizar_enderecos(
|
|
234
|
+
enderecos=enderecos,
|
|
235
|
+
campos_do_endereco=campos,
|
|
236
|
+
formato_estados="sigla",
|
|
237
|
+
formato_numeros="integer",
|
|
238
|
+
manter_cols_extras=True,
|
|
239
|
+
)
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Se os seus dados já estiverem padronizados (ou seja, já contiverem as colunas
|
|
243
|
+
`*_padr`), chame `geocode(..., padronizar_enderecos=False)` para pular essa
|
|
244
|
+
etapa.
|
|
245
|
+
|
|
246
|
+
## Precisão dos resultados
|
|
247
|
+
|
|
248
|
+
Os resultados do `geocode()` são classificados em seis categorias de
|
|
249
|
+
`precisao` ("numero", "numero_aproximado", "logradouro", "cep", "localidade" e
|
|
250
|
+
"municipio"), desagregadas em códigos de `tipo_resultado` (e.g. `dn01`,
|
|
251
|
+
`pa03`), e incluem a coluna `desvio_metros`, com uma estimativa da incerteza
|
|
252
|
+
da localização encontrada. A interpretação dessas colunas, o significado de
|
|
253
|
+
cada código e as regras de resolução de empates estão documentadas na
|
|
254
|
+
[**vignette "geocode"**](https://ipea.github.io/geocodebr/articles/geocode.html).
|
|
255
|
+
|
|
256
|
+
## Cache dos dados do CNEFE
|
|
257
|
+
|
|
258
|
+
Na primeira execução, o pacote baixa arquivos Parquet do release do CNEFE usado
|
|
259
|
+
pelo `geocodebr`. Esses arquivos ficam em cache local para acelerar chamadas
|
|
260
|
+
futuras.
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
from geocodebr import (
|
|
264
|
+
definir_pasta_cache,
|
|
265
|
+
listar_pasta_cache,
|
|
266
|
+
listar_dados_cache,
|
|
267
|
+
deletar_pasta_cache,
|
|
268
|
+
download_cnefe,
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
print(listar_pasta_cache())
|
|
272
|
+
|
|
273
|
+
download_cnefe(tabela="municipio_logradouro_cep_localidade", verboso=True)
|
|
274
|
+
|
|
275
|
+
arquivos = listar_dados_cache()
|
|
276
|
+
print(arquivos)
|
|
277
|
+
|
|
278
|
+
# definir uma pasta de cache específica
|
|
279
|
+
definir_pasta_cache("D:/dados/geocodebr-cache", verboso=True)
|
|
280
|
+
|
|
281
|
+
# apagar cache configurado
|
|
282
|
+
# deletar_pasta_cache()
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## Processamento interno (DuckDB-first)
|
|
286
|
+
|
|
287
|
+
Esta versão evita usar `pandas` no pipeline interno. O fluxo principal registra
|
|
288
|
+
as entradas no DuckDB, executa joins/filtros/matches em SQL e só materializa o
|
|
289
|
+
resultado no final como `pyarrow.Table`.
|
|
290
|
+
|
|
291
|
+
A padronização dos endereços é a única etapa fora do DuckDB: é feita em
|
|
292
|
+
`polars`, fazendo a ponte com os bindings Python do `enderecobr`, sem
|
|
293
|
+
materializar `pandas` em nenhum momento.
|
|
294
|
+
|
|
295
|
+
Isso facilita a paridade com o pacote R, que também usa DuckDB para o motor de
|
|
296
|
+
geocodificação, e ajuda em bases maiores.
|
|
297
|
+
|
|
298
|
+
## Windows e performance
|
|
299
|
+
|
|
300
|
+
No Windows, o `python.exe` roda por padrão no heap NT legacy e não no mais
|
|
301
|
+
moderno e eficaz Segment Heap. O heap legado degrada sob alocação multithread
|
|
302
|
+
intensa do DuckDB: o `geocode()` fica mais lento e piora a cada chamada na
|
|
303
|
+
mesma sessão (contexto em
|
|
304
|
+
[duckdb/duckdb#24027](https://github.com/duckdb/duckdb/issues/24027) e no
|
|
305
|
+
[relatório de diagnóstico do pacote](../quality_reports/diagnoses/2026-09-04_geocode-deterioracao-python-diagnostico.md)).
|
|
306
|
+
|
|
307
|
+
O pacote mitiga o problema de duas formas:
|
|
308
|
+
|
|
309
|
+
1. **Limitação automática de threads** — no Windows sem Segment Heap, se
|
|
310
|
+
`n_cores` não for definido, o `geocode()` limita o DuckDB a
|
|
311
|
+
`min(4, núcleos da máquina)` threads
|
|
312
|
+
(mínimo da curva tempo x threads no heap legacy, confirmado por sweep com o
|
|
313
|
+
workload canônico do duckdb#24027 — `benchmarks/verifica_sweep_threads.py`;
|
|
314
|
+
bacia plana entre 3 e 6 threads) e emite um aviso uma vez
|
|
315
|
+
por sessão. Um `n_cores` passado de forma explícita é respeitado.
|
|
316
|
+
|
|
317
|
+
2. **Interpretador com Segment Heap (recomendado)** — usuário pode gerar uma
|
|
318
|
+
cópia do interpretador Python com o manifesto patcheado com o Segment Heap
|
|
319
|
+
e rodar o `geocode()` a partir dele. Para criar a cópia, basta rodar:
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
python -m geocodebr._heap_patch
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
O comando cria o arquivo `python-geocodebr-sh.exe` ao lado do interpretador
|
|
326
|
+
base (`python.exe`), sem alterar o original. Inicie a sessão pela cópia para
|
|
327
|
+
que o DuckDB use o Segment Heap.
|
|
328
|
+
|
|
329
|
+
**Em benchmarks internos com 10 milhões de endereços, o tempo total do
|
|
330
|
+
`geocode()` caiu de 11:47 minutos para 3:08 minutos**.
|
|
331
|
+
|
|
332
|
+
Limitações conhecidas das soluções apresentadas para uso do `geocodebr` no Windows:
|
|
333
|
+
|
|
334
|
+
- Interpretador com Segment Heap requer Windows 10 (build 19041) ou superior.
|
|
335
|
+
- Não existe configuração do Windows (variável de ambiente ou registro) que
|
|
336
|
+
ligue o Segment Heap por processo. A camada de compatibilidade — via
|
|
337
|
+
`__COMPAT_LAYER=SEGMENTHEAP` ou persistida no registro
|
|
338
|
+
(`AppCompatFlags\Layers` / `Image File Execution Options`) — não alcança o
|
|
339
|
+
heap criado no startup, por onde passam as alocações do DuckDB.
|
|
340
|
+
- O ganho vale apenas para sessões iniciadas pela cópia
|
|
341
|
+
(`python-geocodebr-sh.exe`); Jupyter/IDEs que lançam outro interpretador não
|
|
342
|
+
se beneficiam.
|
|
343
|
+
- A cópia é criada na pasta do interpretador base; se ela não for gravável
|
|
344
|
+
(ex.: `Program Files`), execute o terminal como administrador ou use uma
|
|
345
|
+
instalação por usuário (ex.: `uv`, `pyenv`).
|
|
346
|
+
- A cópia usa os pacotes do ambiente base. Com geocodebr instalado em venv,
|
|
347
|
+
aponte `PYTHONPATH` para o `site-packages` da venv. Exemplo em PowerShell:
|
|
348
|
+
|
|
349
|
+
```powershell
|
|
350
|
+
$env:PYTHONPATH = "C:\caminho\para\.venv\Lib\site-packages"; & "C:\caminho\para\python-geocodebr-sh.exe" "C:\caminho\para\seu_script.py"
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
- A limitação de threads reduz a contenção do heap, mas não elimina a
|
|
354
|
+
deterioração entre chamadas sucessivas na mesma sessão; a cópia com Segment
|
|
355
|
+
Heap resolve os dois problemas.
|
|
356
|
+
|
|
357
|
+
## Desenvolvimento e testes
|
|
358
|
+
|
|
359
|
+
Para rodar a suíte de testes:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
uv run pytest -q -m "not r_parity"
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Esse comando roda apenas os testes unitários, com
|
|
366
|
+
Parquets sintéticos, sem baixar dados do CNEFE.
|
|
367
|
+
|
|
368
|
+
### Testes de paridade R vs Python
|
|
369
|
+
|
|
370
|
+
O pacote também inclui testes que comparam a saída do Python com a saída do
|
|
371
|
+
pacote R usando os dados de exemplo `inst/extdata/small_sample.csv` e
|
|
372
|
+
`inst/extdata/large_sample.parquet`.
|
|
373
|
+
|
|
374
|
+
Esses testes exigem `Rscript` no `PATH`, instalam o pacote R localmente em uma
|
|
375
|
+
biblioteca temporária e podem baixar dados do CNEFE. Se `Rscript` não estiver
|
|
376
|
+
disponível, eles são pulados automaticamente.
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
uv run pytest -m r_parity -q
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Exemplos
|
|
383
|
+
|
|
384
|
+
A pasta `exemplos/` contém scripts simples usando as funções principais da
|
|
385
|
+
versão Python:
|
|
386
|
+
|
|
387
|
+
- `geocode_enderecos.py`: busca coordenadas a partir de endereços.
|
|
388
|
+
- `busca_por_cep.py`: busca endereços/coordenadas a partir de CEPs.
|
|
389
|
+
- `geocode_reverso.py`: busca endereço próximo a coordenadas.
|
|
390
|
+
|
|
391
|
+
Execute os exemplos a partir da raiz do repositório:
|
|
392
|
+
|
|
393
|
+
```bash
|
|
394
|
+
uv run python exemplos/geocode_enderecos.py
|
|
395
|
+
uv run python exemplos/busca_por_cep.py
|
|
396
|
+
uv run python exemplos/geocode_reverso.py
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## Nota <a href="https://www.ipea.gov.br"><img src="../r-package/man/figures/ipea_logo.png" alt="IPEA" align="right" width="300"/></a>
|
|
400
|
+
|
|
401
|
+
Os dados originais do CNEFE são coletados pelo Instituto Brasileiro de
|
|
402
|
+
Geografia e Estatística (IBGE). O **{geocodebr}** foi desenvolvido por
|
|
403
|
+
uma equipe do Instituto de Pesquisa Econômica Aplicada (Ipea), e conta
|
|
404
|
+
com apoio do Instituto Todos pela Saúde (ITpS).
|
|
405
|
+
|
|
406
|
+
## Instituições utilizando o {geocodebr}
|
|
407
|
+
|
|
408
|
+
Além de diversos pesquisadores e empresas que utilizam o {geocodebr}, o
|
|
409
|
+
pacote também tem sido utilizado por algumas instituições públicas no
|
|
410
|
+
planejamento e avaliação de políticas públicas. Entre elas:
|
|
411
|
+
|
|
412
|
+
- Instituto Brasileiro de Geografia e Estatistica (IBGE)
|
|
413
|
+
- Banco Central do Brasil (BCB)
|
|
414
|
+
- Ministério do Desenvolvimento Social e Combate à Fome (MDS)
|
|
415
|
+
|
|
416
|
+
## Projetos relacionados
|
|
417
|
+
|
|
418
|
+
Existem diversos pacotes de geolocalização disponíveis, muitos dos quais
|
|
419
|
+
podem ser utilizados em Python (listados abaixo). A maioria dessas
|
|
420
|
+
alternativas depende de softwares e conjuntos de dados comerciais,
|
|
421
|
+
geralmente impondo limites de número de consultas gratuitas. Em
|
|
422
|
+
contraste, as principais vantagens do `geocodebr` são que o pacote:
|
|
423
|
+
(a) é completamente gratuito, permitindo consultas ilimitadas sem nenhum
|
|
424
|
+
custo; (b) opera com alta velocidade e escalabilidade eficiente,
|
|
425
|
+
permitindo geocodificar milhões de endereços em apenas alguns minutos,
|
|
426
|
+
sem a necessidade de infraestrutura computacional avançada ou de alto
|
|
427
|
+
desempenho.
|
|
428
|
+
|
|
429
|
+
- [geopy](https://pypi.org/project/geopy/): cliente para diversos
|
|
430
|
+
serviços de geocodificação (Nominatim/OSM, Google, ArcGIS, Photon etc.)
|
|
431
|
+
- [googlemaps](https://pypi.org/project/googlemaps/): interface para a
|
|
432
|
+
API do Google Maps
|
|
433
|
+
- [ArcGIS API for Python](https://pypi.org/project/arcgis/): utiliza o
|
|
434
|
+
serviço de geocodificação do ArcGIS
|
|
435
|
+
- [opencage](https://pypi.org/project/opencage/): cliente do serviço
|
|
436
|
+
OpenCage
|