Códigos postais

Documentando o que descobri depois de uma discussão que se iniciou no Telegram do RS.

As seguintes coisas funcionam hoje com o nosso principal geocoder, o Nominatim:

Código postal para elementos específicos

Onde não há outras alternativas, o Nominatim tem atribuído o código postal pela proximidade de elementos com addr:postcode. Então se você mapear um café com addr:postcode e do lado mapear um banco sem addr:postcode, ele atribuirá o CEP do banco automaticamente por estar próximo do café, que é um ponto com CEP conhecido. Quase sempre isso funciona bem.

addr:postcode também tem precedência sobre as abordagens a seguir, então pode ser usado para mapear CEPs excepcionais (ex.: agências dos Correios costumam ter CEP diferente do lugar onde se encontram).

Quando levantei essa questão na lista tagging, algumas respostas sugeriram sim usar addr:postcode em tudo, mesmo que isso replique o dado. Daria bastante trabalho fazer manutenção nisso.

Uma possível ideia seria não atribuir os CEPs aos pontos de interesse (amenity=, leisure=, etc.) e sim aos endereços, caso as duas coisas sejam desacopladas (ex.: onde se estiver mapeando com interpoladores ou seguindo a filosofia de um elemento diferente para cada coisa).

Mesmo código postal para uma localidade inteira

Uma “localidade” para os Correios tipicamente é um município ou um distrito, mas talvez inclua outras áreas.

A relação boundary=postal_code nos permite fazer isso sem precisar adicionar addr:postcode a cada elemento da área.

A grande maioria dos municípios brasileiros têm população pequena e apenas um código postal para todo o município. Nesse caso, basta criar uma relação com as etiquetas:

  • type=boundary

  • boundary=postal_code

  • postal_code=[CEP do município]

  • (opcional) postal_code_level=8

  • (opcional) note=[CEP do município] [nome do município]

Se eventualmente algum elemento ainda tiver CEP próprio, basta adicionar addr:postcode ao elemento. Testei isso em Mariana Pimentel com um caso típico e um caso atípico.

O único inconveniente é que isso essencialmente duplica as relações dos municípios e as duas coisas podem perder sincronia com o tempo. Mas quem mantém as relações de municípios geralmente usa o JOSM, que torna isso bem evidente, então acho que o risco de acidentes é pequeno.

Tudo isso também vale para distritos ou outras localidades conforme a definição dos Correios.

Código postal igual dos dois lados da rua

postal_code em trechos da rua nos permite fazer isso sem precisar adicionar addr:postcode a cada elemento da rua.

Isso é comum nos municípios maiores. Em algumas ruas, o código pode inclusive mudar por trecho. Nesse caso, é necessário quebrar a rua no trecho e atribuir um código diferente para cada um. Testei isso na avenida Bahia em Porto Alegre, que tem três trechos com códigos postais diferentes. Um exemplo em cada trecho: primeiro trecho, segundo trecho, terceiro trecho.

Como o geocoder tenta atribuir pela distância do elemento à rua, às vezes o cálculo dá errado, o que é mais comum nas esquinas. Nesses casos, ainda seria possível adicionar addr:postcode ao elemento para forçar a atribuição correta do CEP.

Código postal diferente em cada lado da rua

O que mais se aproxima disso seriam as etiquetas tiger:zip_left e tiger:zip_right em trechos da rua. Mas temos dois problemas.

Primeiro, não funciona direito. Testei isso na avenida Pátria em Porto Alegre. Depois de atribuir as etiquetas às vias, adicionei um ponto de interesse no lado esquerdo, cujo CEP foi corretamente atribuído pelo lado. Então, adicionei outro do lado direito, e ao invés de atribuir conforme o lado, o Nominatim atribuiu pela proximidade com o elemento mais próximo com CEP (o elemento que eu adicionei anteriormente). Resultado: ambos acabaram com o CEP de um único lado da rua.

Segundo, essas etiquetas foram definidas para a importação TIGER nos Estados Unidos, e portanto não se generalizam para o resto do mundo. Nota-se que muitas vias lá têm o mesmo CEP dos dois lados da via, o que pode significar que o problema anterior passou despercebido pelos desenvolvedores do Nominatim.

Conforme o TagInfo, zip_left e zip_right são relativamente bem usadas também, muito mais do que postal_code:left, postal_code:right, postal_code:side:odd e postal_code:side:even, mas nenhuma destas é atualmente suportada.

Uma alternativa seria realmente mapear as áreas dos códigos postais. Dessa forma o resultado é exato mas dá bastante trabalho, embora bem menos do que adicionar o CEP pra cada elemento. A Wikipedia cita que esse desenho é a interpretação correta, mas acho que deveríamos discutir se é mesmo.

Sugestão: refinamento progressivo

Em todos os municípios com CEP único, já podemos criar as relações boundary=postal_code e remover postal_code das vias e addr:postcode dos elementos (contanto que sejam iguais aos do município). Isso por si só cobre a maior parte da área do país. Como citado pelo @santamarisene, há várias outras localidades (partes de municípios) onde isso também poderia ser feito.

Nos demais lugares, postal_code pode ser atribuído às vias num primeiro momento. Onde for diferente de cada lado, usa-se addr:postcode nos elementos e/ou nos endereços. Num segundo momento, o postal_code das vias e o addr:postcode dos elementos podem ser convertidos em relações boundary=postal_code para garantir a exatidão da informação. Naturalmente, se alguém quiser já pode ir mapeando da forma final.

Nota: a introdução/alteração de postal_code no código postal leva dias para se refletir no Nominatim (não consegui descobrir bem quantos). Então, um ponto de interesse que você adicionou, ao qual ele atribuiu um código postal, digamos, pela proximidade com outro elemento, pode levar dias para ter o seu código postal atualizado. Curiosamente, isso não acontece com boundary=postal_code, cujas alterações se refletem quase imediatamente. Isso meio que sugere que a relação boundary=postal_code é o mapeamento mais desejável em todas as situações.

Ah, e talvez pudéssemos pensar numa colaboração com este projeto.

Creio que não.
Clica em “Colaborar” (http://cepaberto.com/ceps/verify) e olha o que usam para geocodificação, georreferenciamento, etc.

A ideia deles foi boa, mas pecaram ao usar o Google.

Para não criar mais uma relação e cuidar para que ela se mantenha com área sempre igual ao município que abrange, acho que vale a pena investir na defesa de usar postal_code junto da própria relação do município (boundary=administrative).

Alguns pontos sobre os Correios:

  • Os CEPs são por localidades. Onde cada localidade pode ser referir a um município inteiro, a um distrito inteiro ou a um povoado, variando de município para município.

Santa Maria por ser um município misto de rural e urbano ilustra bem isso. O Correios considera cada um dos 10 distritos do município como sendo 1 localidade (mais comumente chamada de cidade). A Sede (Santa Maria) tem CEP por logradouros, os demais distritos são como municípios pequenos onde cada distrito tem um único CEP e existe um CEP para a unidade dos Correios local de cada um deles.

Nem todos os distritos tem CEPs. Alguns podem usar um geral para todo o município. Em alguns casos os CEPs de fato não batem com a delimitação administrativa fazendo-se necessário ter uma relação boundary=postal_code de fato.

Em relação a estruturação dos dados, é viável termos em separado postal_code ora com boundary=postal_code, ora com boundary=admin_level. Sim? Não? É algo a ser pensado.

Proposta de correção de texto, @ftrebien, onde diz-se município, muda-se para localidade e abre como subitem explanação que localidade pode ser município ou distrito ou “?algo mais específico?”. Uso do termo “localidade” pelos correios: http://www.buscacep.correios.com.br/sistemas/buscacep/buscaCep.cfm

Em localidades onde o CEP é por logradouros, poderíamos definir a faixa de ceps (http://www.buscacep.correios.com.br/sistemas/buscacep/resultadoBuscaFaixaCEP.cfm) numa relaçao boundary. Seria de alguma forma útil?

Temos ainda o problema com o uso dos dados direto do site dos Correios, até onde eu saiba não podemos. Li que o CEP 5 (de 5 dígitos utilizado antigamente) agora está liberado para uso e podemos usar aqui no OSM. O mais recente, CEP 8, não tem a mesma licença, de modo que não podemos usar no OSM. Porém, nas localidade de CEP não por logradouro, seria só pegar o CEP 5 e concatenar 000 ao final deles. Outra fonte possível, mas que já vi erros, seria usar o CNEFE.

Fui ver como ficaria o mapeamento de CEPs diferentes por rua/lado usando boundary=postal_code. Foi tão trabalhoso que acho que seria mais fácil usar addr:postcode nos elementos com endereço.

Na avenida Amazonas em Porto Alegre, o CEP é o mesmo dos dois lados, mas diferente em três trechos. Esta foi a única relação que eu ajustei ao contorno dos lotes. Em particular, na esquina com a avenida São Pedro, há lotes com endereços diferentes em cada face - são prédios residenciais (uma face, um endereço) com comércio numa das fachadas (outra face, outro endereço). Teoricamente, o código postal é diferente pra cada um. Nesse casos, não ajustei o contorno ao lote. Intervalos de CEP: primeiro, segundo, terceiro

Os próximos casos são duas ruas paralelas com CEP diferente em cada lado. Nessas não ajustei o contorno do CEP, exceto no encontro com a avenida Amazonas.

E o editor iD não sabe interpretar a relação boundary=postal_code.

Concordo, mas pode levar um certo tempo. Vou sondar.

+1 Corrigi na minha postagem original.

Acho que ambos os tipos de limites serão mantidos por usuários do JOSM, e no JOSM fica relativamente fácil saber se há um limite administrativo com postal_code, ou se há um limite de código postal, ou nenhum deles. Então acho que é viável. Só resta a questão do suporte no Nominatim.

Isso na verdade seria uma defesa do mapeamento usando addr:postcode em cada elemento. Geralmente os donos de comércios e de residências compartilham o CEP nas suas informações de contato, e eu acho que é legítimo que nós copiemos essa informação quando fornecida por essa via. Por outro lado, às vezes está errada porque essas mesmas pessoas pegam num cadastro antigo, ou no Google Maps, ou no Facebook, etc.

Até termos certeza de algo, claro que não podemos copiar. Mas abrindo o assunto em off-topic: sendo os Correios uma empresa pública, será que eles realmente têm o direito de cobrar por essa informação? Não estaria afetada pela LAI? Pelo visto alguém já seguiu por esse raciocínio. Um post interessante referenciando pareceres favoráveis da CGU. E pelo visto os Correios não estão sozinhos na iniciativa de restringir o acesso a informações públicas.

Acho que a questão se desdobra em pelo menos duas: se os Correios podem cobrar para fornecer uma cópia integral da base de dados, e se os dados fornecidos pela consulta pública dos Correios podem ou não ser reproduzidos e comercializados sem atribuição. Para nós, interessa mais a segunda questão. A primeira parece já ter sido respondida: podem cobrar. À segunda, o post disse que CGU respondeu ao primeiro pedido (cujo texto não está mais disponível na Internet) da seguinte forma:

O fato de o texto do pedido não estar mais disponível é um tanto suspeito. Creio que poderíamos solicitar uma cópia. Usando a busca de precedentes do portal de Acesso à Informação do Governo Federal, encontrei alguns documentos que citam esses dois trechos.

O esquema chutômetro da Wikipédia não fica legal. Melhor seria então usar uma relação do type=street para cada lado da rua. Como neste exemplo (https://www.openstreetmap.org/relation/7308672) só que com 2 relações, sendo uma para cada lado da rua.

+1 Bem melhor mesmo.

Uma coisa que me chamou a atenção foi encontrar em diversos lugares (inclusive num dos links que acabei de postar) uma resposta padrão do presidente dos Correios dizendo que eles patentearam a base de CEP na Alemanha. Pois eu fui conferir e me parece que foi rejeitada em 2016. Joguei a questão pra lista legal-talk.

Realmente não é uma boa ideia atualmente já que o usuário está essencialmente traçando sobre as imagens de satélite do Google. Mas quem sabe se eles trocassem por um slippy map do OSM, consumissem os nossos dados e sugerissem que os colaboradores editassem o OSM?

Estive observando ontem que Manaus AM tá com CEP na sua relação (https://www.openstreetmap.org/relation/332493), e este CEP está se aplicando a tudo por lá, exceto os objetos dentro dele que tem mapeado os CEPs, como por exemplo, algumas ruas. O que leva a crer que não se faz necessário ter uma relação exclusiva a a ele. Ao menos o Nominatin responde bem.

Agora que li https://wiki.openstreetmap.org/wiki/Tag:boundary=postal_code, vi que tá explícito que se pode usar postal_code junto com boundary=administrative.

Dito isto, precisamos definir se vamos colocar o CEP nos municípios ou nos distritos, ou se isso vai depender de cada município.

Localidades que tem CEPs por logradouros, ainda assim, (preciso confirmar para ter certeza) tem um CEP geral para toda a localidade, ou talvez para todo o município. Na hipótese de se mapear o CEP geral daquela área, todos os objetos terão aquele CEP, exceto os que tiverem CEPs específicos por logradouro. Isso também seria interessante em municípios onde parece que alguns distritos não tem CEPs específicos, como é o caso de São Gabriel / RS, onde todos os distritos herdariam o CEP do município, exceto os que teriam CEP próprio. Neste último caso, se fosse colocado CEPs apenas nos distritos, alguns deles teriam CEPs repetidos, e não sei se isso seria legal.

Diante do exposto acima, acredito que algo nesse sentido seja a solução:

  • Adicionar CEP (geral) em todos os municípios (admin_level=8)
  • Se um distrito tiver CEP específico, que não for o mesmo do município, se adiciona o CEP no distrito (admin_level=9)

Casos excepcionais, se criaria relação boundary específica, e de preferência se documentaria na wiki.

Isso certamente vai evitar que se tenha que cuidar a sincronicidade de áreas de municípios/distritos com o de postal_code, além de se evitar criação “desnecessária” de relação.

Certa feita também fui informado pelos Correios que apenas localidades com mais de 50 mil habitantes pode requerer CEP por logradouro, então, já podemos inferir quais municípios tem e quais não tem CEP por logradouro, com uma baixa margem de erro. No RS, mais exatamente, de Cruz Alta (62825 habitantes) para cima tem CEPs por logradouro.

A herança de CEP pode ser um problema. Tem coisas que tem CEP especifico, mesmo em localidades sem CEP por logradouros. Um exemplo delas, são as agencias de correios.
Daí, se uma dessas coisas não tiver seu CEP especifico mapeado, vai herdar o CEP do maior admin_level em que ela estiver contida.

E sem acesso a base de CEP, não temos como saber todos os casos específicos que podem ocorrem.

Poderia dar um exemplo prático? Eu sei que existe Caixa Postal com CEP dedicado, mas de qualquer maneira, chegando nos Correios da Cidade de destino com CEP geral, e tendo endereço, eles fazem o redirecionamento, e vai chegar no endereço de destino do mesmo modo. Nesse caso seria como não querer aplicar CEP da rua nas casas, porque alguma delas pode ter uma Caixa Postal, para receber as correspondências, com CEP diferente. No final das contas, com o CEP geral ou com um dedicado/específico, as correspondências tendem a chegar pelo menos até a sede dos correios da cidade de destino.

O que essa frase está dizendo é que, se uma linha for membro de relações dos dois tipos diferentes de limite (boundary=administrative e boundary=postal_code), então você pode colocar a etiqueta boundary=administrative na linha. Não diz que você pode colocar a etiqueta postal_code na relação boundary=administrative e eliminar a relação boundary=postal_code. Se bem me lembro (já faz um tempo), testei isso e não funcionou no nosso ecossistema atual, e acho que foi por isso que sugeri a criação dessas relações no final do meu post original. Também não há nada no wiki que sugira que a etiqueta postal_code em relações boundary=administrative deve ser suportada pelas aplicações. Mas vale a pena testar essa combinação novamente pra ver se o comportamento continua o mesmo.

Então, esta frase está um tanto estranha, também achei que poderia ser lida assim, mas deduzi que o mais correto seria lê-la como way/relation do tipo type=boundary. Será que ela é da época que os limites eram feitos colocando-se tags nas divisas ao invés de nas relações? Até porque boundary=administrative, até onde eu saiba, só seria aplicável a área administrativa, e não às linhas membros de divisa.
De qualquer maneira, além de testes, seria bom sanar esta dúvida no tagging-list e esclarecer isso no wiki.

Por bastante tempo os renderizadores não procuravam a etiqueta boundary=administrative na relação, então era necessário adicioná-la às linhas pra que os limites fossem renderizados. Deve ser sim uma herança dessa época. Isso inclusive ainda é suportado pelos renderizadores e pelos editores JOSM e iD. Se não me engano, o Potlatch ainda só suporta essa forma de mapear os limites, e não suporta a etiqueta só na relação.

Oi gente, existe algo tag para intervalo de CEP, algo como postal_code_range?

Quanto à base de CEP dos Correios, eu concordo que deveria ser pública. Por outro lado, essa informação é pouco interessante, principalmente para o OSM, porque não é georreferenciada e (ao que parece) não contém sequer endereços individuais. Muito mais interessante (apesar de alguns problemas) é o CNEFE, que possui 80 milhões de endereços, com CEP, localizados ao nível da quadra. E está disponível para download no https://openaddresses.io/.