Git Product home page Git Product logo

city-codes's Introduction

datasets-br

Describing the datasets-br directives and using this project as point of generic discussions.

Dataset-BR directives

  1. To post qualified datasets in the Datahub.io;
  2. To unify, by curatory process, a set of Wikidata fragments if items, or commom instances of an item;
  3. To unify terminology to express CSV colunm names, table and column semantics (SchemaOrg conventions when possible)
  4. Digital preservation (CSV files and data dumps from original soruces) of the curated datasets;
  5. Monitoring/auditing Wikidata and OpenStreetMap changes, in the context of the curated datasets.

Use as an ecosystem of datasets

Example of use with 2 BR's datasets, state-codes and city-codes.

Operating with pure SQL or SQL-unifier will be easy to merge with other datasets... With PopstgreSQL you can offer datasets in an standard API with PostgreREST (or its descendents pREST and PostGraphile), or plug-and-play with SchemaOrg standards, FrictionlessData standards (and tools), etc.

Documentation

... under construction

Conventions for data provenance and prepare.


  Contents and data of this project are dedicated to

city-codes's People

Contributors

igoreliezer avatar ppkrauss avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

city-codes's Issues

Código TOM do Município

O sistema TOM - Estrutura Organizacional e Jurisdicional no âmbito da RFB e Domínios de Endereçamento é utilizada pelos diversos sistemas da RFB.

O código do município utilizado pela RFB nos dados abertos das empresas brasileiras é o TOM e não o código do IBGE.

A pesquisa do código do município pode ser realizada no endereço:
https://www.tomweb.receita.fazenda.gov.br/TomWeb/SubMenuMunicipios.jsf

Não encontrei nenhuma fonte oficial ou totalmente atualizada com os códigos TOM dos municípios brasileiros, mas acredito que é interessante adicionar um campo com este código no projeto.

Implementar filtro de restrição de itens no dump_wikidata

Para diversas tarefas, tais como #23 e #24, é importante não precisar rodar os ~5500 municípios denovo, é muito mais prático listar os que interessam na linha de comando. Exemplos:

# relatório listando só itens do escopo de interesse
php src/etc/dumpWikidata.php chk  list-ibge 2900702 1700400 5200605
# check-and-dump_wikidata files  só do escopo de interesse
php src/etc/dumpWikidata.php  list-wd Q443583 Q1774430
...

Incluir abreviação de 3 letras de MT

Conforme descrição do órgão em sinfra.mt.gov.br/historia, o SINFRA de MT é o equivalente ao antigo DER de outros estados, portanto é a autoridade competente para criar os códigos de 3 letras dos municípios do Estado do Mato Grosso.

Em documento supostamente oficial de 2017 foi publicada a listagem como "Tabela 1" na sua seção 2.1.3, ver ROTEIRO BÁSICO PARA SISTEMAS RODOVIÁRIOS MUNICIPAIS DO ESTADO DE MATO GROSSO.

A tabela PDF foi convertida em dataset, ver abbrev3-SINFRA-MT.

fundamentação e controle

Trata-se de continuidade das issues #7 e #32.

Incluir coluna de DDD da cidade

A Anatel fornece em texto regularmente compilado (efeticamente marcado com atualizações de 2015 e indicação de revisão de 2017) da Resolução Anatel nº 263, de 8 de junho de 2001. No ANEXO II (PLANO GERAL DE CÓDIGOS NACIONAIS – PGCN) da norma, fornece a listagem completa dos pares cidade-DDD.

Além disso a mesma Anatel em 2013 ofereceu uma das poucas fontes padronizadas de abreviação de 3 letras de nomes de cidade, que se tem conhecimento... Ver issue #7 . Esse material também pode ser incluso em dump.

Sugere-se criar pasta /data/dump_etc com esse material-fonte e depois fazer o casamento com a tabela principal (br-city-codes.csv) via SQL-unifier.

Conferir consistência da Wikidata com código IBGE

O código IBGE tem se mostrado consistente com as fontes primárias utilizadas, de modo que serve também para conferir se houve falha de atribuição do mesmo na Wikidata.

Com relação à completeza na adoção da P1585 foi confirmada: cd data/dump_wikidata grep -r "P1585" . | wc -l resultando em 5514, que em 5570 são ~99%, praticamente completo.

Incluir abreviação de 3 letras de MG

No OSM existem evidências de campo (confirmações por GPS e fotos de placas) que comprovam as siglas oficiais de nomes de estradas municipais, que são as abreviação de 3 letras dos respectivos municípios no Estado de Minas Gerais (MG).

Não é uma listagem sistemática, abbrev3-DER-MG está começando com apenas 20 itens, dos ~800, mas permite conferir por amostragem outras fontes, e portanto a escolha de uma fonte mais confiável em vista da não-disponibilidade de uma listagem oficial.

fundamentação e controle

Trata-se de continuidade das issues #7 e #32.

Ordenação consistente e padronizada

Importante que "Brasil" e "Brasil Novo" venha antes de "Brasilândia" numa listagem por ordem alfabética. Ver solução elegante aqui... Importante que a solução seja padronizada e sempre utilizada para não comprometer o git.

Por hora este é o padrão:

CREATE FUNCTION std_collate(text) RETURNS text AS $f$
     -- SELECT name FROM t ORDER BY std_collate(name), name;
    SELECT regexp_replace($1, E'[ \'\-]', '0', 'g')
$f$ language SQL;

Aplicando a reordenação na copia da tabela,

COPY (
  SELECT *
  FROM dataset.vw2_br_city_codes
  ORDER BY std_collate(name), name, state
) TO '/tmp/test.csv' CSV HEADER;

Criar CONSOLE para automatizar manutenção

O principal processo de manutenção é filtrar o CSV para que se mantenha padronizado.
Portanto automatizar a importação/exportação do CSV é a tarefa mínima que o console precisa realizar.

Outras funções podem ser agregadas para facilitar também a reprodução dos processos originais.

História oficial dos batismos e desmembramentos

Apresentação

Há uma certa confusão entre a "história real" e a "história oficial". O ano de fundação de uma cidade, do ponto de vista histórico (usado pela Wikidata), pode não ter relação alguma com o ano da formalização do território como município — e requer no mínimo uma convenção para se estabelecer a data de inicio do conceito moderno de município, já no Brasil como república. Da mesma forma o nome oficial pode sofrer "rebatismos" ao longo do tempo.

Do ponto de vista geográfico, via de regra a fundação de um município está acoplada ao desmembramento de outro: áreas do Brasil não se criam, apenas se transformam.

Ambas informações, idealmente polígonos associados, podem ser submetidos à preservação digital neste repositório.

Exemplo: Macatuba (até 1944 Bocaiúva) foi fundada em 1900, só mas recebeu status oficial de município pela lei estadual nº. 1.975 de 1 de outubro de 1924 com território desmembrado de Lençóis Paulista (na época: Ubirama).

Sugestão

Revisar com mais cuidado as propriedades Wikidata disponíveis para as informações oficiais, eleger uma ou duas cidades (exemplos de caso) como referência, e criar procedimentos (de preferência automatizados ou semi-automatizados) para se atualizar ou complementar os dados Wikidata de cada município.

Elementos práticos:

  • As colunas com anos de fundação e extinção (creation/extinction de br-city-codes.csv) precisam ser preenchidas de forma sistemática. Isso requer revisão na Wikidata, com bot que leve dados do quadro informativo em português (que na maior parte tem a data de fundação) para a Wikidata.

  • A tabela de sinônimos br-city-synonyms.csv já contempla o histórico de batismos. Resta conferir consistência e fazer a inserção sistemática dos dados de rebatismo oficiais.

  • criar tabela para descrever o histórico de desmembramentos (apenas wdId da cidade-origem, ano de desmembramento/fundação e wdId da cidade-destino). O polígono que descreve a cidade-origem antes do ano de desmembramento é a ST_Union das cidades envolvidas.
    Detalhes: em caso de desmembramento com revisão de status (da divisão surgem duas novas cidades ao invés de permanecer a antiga com o restante), informar o novo wdId resultante; em caso de desmembramento em mais que duas partes, basta ter mais de uma entrada com mesmo ano.

  • preservação digital das delimitações antigas: as delimitações administrativas são abstratas, de modo que atualizações na precisão ou mesmo correções resultantes de negociação de fronteiras podem ser incorporadas retroativamente. Essa "atualização retroativa" é conseguida com o ST_Union por exemplo, de modo que os "mapas antigos" seriam meramente caches das operações com mapas atuais.
    Conforme as convenções adotadas, todavia, ou conforme a data de referência, a atualização retroativa deixa de ser válida, e haverá demanda não apenas pelo cache mas também pela preservação das delimitações históricas (pontos precisos porém não tão fieis a uma fonte original) e/ou do mapa histórico (fonte original porém sem precisão para comparar com o presente).

Atualizar até setembro de 2019

Revisar qual a melhor ordem de atualização, provavelmente os geoJSONs seriam os ultimos. Devido a isso, conferir se não houve falha a incluir os seguintes poligonos:
Sugere-se reiniciar com tabela oficial do IBGE revisada.

GeoJSONs atualizados

Além das ~100 de atualizações de arquivos geojson (ver commit), os seguntes arquivos novos foram inclusos, conforme git status

	data/dump_osm/RJ/CasimiroAbreu.geojson
	data/dump_osm/SP/Florinea.geojson
	data/dump_osm/SP/SaoLuizParaitinga.geojson

Apenas uma mensagem de erro em php src/dumpOsm.php geo, após todas as atualizações: "ERROR, no osmId or P402 for MG-Chiador / empty json for MG-Chiador".

Wikidatas atualizados

Passo-a-passo realizado:

  1. php src/etc/dumpWikidata.php chk
  2. php src/etc/dumpWikidata.php
  3. ... revisar erros e pegar dados oficiais nas planilhas novas do IBGE .. rodando tudo novamente.

-- Generating backups of JSON-Wikidata --

 USANDO CHECK WIKIDATA /opt/datasets-br/city-codes/data/dump_wikidata/../br-city-codes.csv
 -- Error-type-4, sem DDD em Q1940492 (IBGE 2200400)
 -- Error-type-4, sem DDD em Q2007777 (IBGE 3102209)
 -- Error-type-4, sem DDD em Q2102493 (IBGE 1700707)
 -- Error-type-4, sem DDD em Q2094729 (IBGE 2200509)
 -- Error-type-4, sem DDD em Q1784392 (IBGE 4200903)
 -- Error-type-4, sem DDD em Q1750770 (IBGE 4201109)
 -- Error-type-4, sem DDD em Q1805349 (IBGE 3102902)
 -- Error-type-4, sem DDD em Q1797156 (IBGE 5001003)
 -- Error-type-4, sem DDD em Q22063188 (IBGE 2902104)
 -- Error-type-4, sem DDD em Q1804949 (IBGE 3104205)
 -- Error-type-4, sem DDD em Q1805369 (IBGE 3107109)
 -- Error-type-4, sem DDD em Q1805722 (IBGE 3108107)
 -- Error-type-7, atribuição Q2844 (ao IBGE 5300108) não é município-BR!
 -- Error-type-4, sem DDD em Q1799538 (IBGE 3108602)
 -- Error-type-4, sem DDD em Q1815606 (IBGE 3109501)
 -- Error-type-4, sem DDD em Q2077925 (IBGE 3109808)
 -- Error-type-4, sem DDD em Q2007990 (IBGE 3110301)
 -- Error-type-4, sem DDD em Q1957976 (IBGE 3110806)
 -- Error-type-4, sem DDD em Q2077804 (IBGE 3111002)
 -- Error-type-4, sem DDD em Q1805812 (IBGE 3111804)
 -- Error-type-4, sem DDD em Q2064920 (IBGE 3112059)
 -- Error-type-4, sem DDD em Q2007691 (IBGE 3114204)
 -- Error-type-4, sem DDD em Q2347628 (IBGE 2303600)
 -- Error-type-4, sem DDD em Q251350 (IBGE 2303956)
 -- Error-type-4, sem DDD em Q2007621 (IBGE 3116605)
 -- Error-type-4, sem DDD em Q2063933 (IBGE 3116704)
 -- Error-type-4, sem DDD em Q2007414 (IBGE 3118205)
 -- Error-type-4, sem DDD em Q2008000 (IBGE 3119104)
 -- Error-type-4, sem DDD em Q1805792 (IBGE 3119302)
 -- Error-type-4, sem DDD em Q986510 (IBGE 2304251)
 -- Error-type-4, sem DDD em Q1805738 (IBGE 3121258)
 -- Error-type-4, sem DDD em Q1805786 (IBGE 3124302)
 -- Error-type-4, sem DDD em Q1900550 (IBGE 3125200)
 -- Error-type-7, atribuição Q175057 (ao IBGE 2605459) não é município-BR!
 -- Error-type-4, sem DDD em Q2101396 (IBGE 3127602)
 -- Error-type-4, sem DDD em Q2135472 (IBGE 2305233)
 -- Error-type-4, sem DDD em Q2050036 (IBGE 3130101)
 -- Error-type-4, sem DDD em Q1805773 (IBGE 3130705)
 -- Error-type-4, sem DDD em Q2007732 (IBGE 3133600)
 -- Error-type-4, sem DDD em Q1805374 (IBGE 3135209)
 -- Error-type-4, sem DDD em Q1804893 (IBGE 3137304)
 -- Error-type-4, sem DDD em Q2007758 (IBGE 3137536)
 -- Error-type-4, sem DDD em Q985575 (IBGE 4311304)
 -- Error-type-4, sem DDD em Q1805333 (IBGE 3138500)
 -- Error-type-4, sem DDD em Q2357138 (IBGE 3138658)
 -- Error-type-4, sem DDD em Q2289962 (IBGE 2307809)
 -- Error-type-4, sem DDD em Q2104166 (IBGE 3141405)
 -- Error-type-4, sem DDD em Q2079721 (IBGE 2804201)
 -- Error-type-4, sem DDD em Q1877935 (IBGE 3143104)
 -- Error-type-4, sem DDD em Q2063943 (IBGE 3143450)
 -- Error-type-4, sem DDD em Q2028310 (IBGE 2308906)
 -- Error-type-4, sem DDD em Q2289857 (IBGE 2309102)
 -- Error-type-4, sem DDD em Q2014499 (IBGE 2804508)
 -- Error-type-4, sem DDD em Q1924777 (IBGE 2804607)
 -- Error-type-4, sem DDD em Q2661298 (IBGE 3136603)
 -- Error-type-4, sem DDD em Q2028019 (IBGE 2309409)
 -- Error-type-4, sem DDD em Q2007609 (IBGE 3145901)
 -- Error-type-4, sem DDD em Q2014476 (IBGE 2805505)
 -- Error-type-4, sem DDD em Q1815988 (IBGE 3152808)
 -- Error-type-4, sem DDD em Q2078413 (IBGE 2805802)
 -- Error-type-4, sem DDD em Q1809966 (IBGE 3155504)
 -- Error-type-4, sem DDD em Q1804734 (IBGE 3155702)
 -- Error-type-4, sem DDD em Q1804907 (IBGE 3155801)
 -- Error-type-4, sem DDD em Q1886752 (IBGE 3157203)
 -- Error-type-4, sem DDD em Q2021424 (IBGE 2708204)
 -- Error-type-4, sem DDD em Q1904163 (IBGE 3161106)
 -- Error-type-4, sem DDD em Q578627 (IBGE 4318200)
 -- Error-type-4, sem DDD em Q1805400 (IBGE 3162807)
 -- Error-type-4, sem DDD em Q2078623 (IBGE 1720903)
 -- Error-type-4, sem DDD em Q921105 (IBGE 4217907)
 -- Error-type-4, sem DDD em Q22062867 (IBGE 2931004)
 -- Error-type-4, sem DDD em Q2105955 (IBGE 4126801)
 -- Error-type-4, sem DDD em Q22062864 (IBGE 2931202)
 -- Error-type-4, sem DDD em Q22062863 (IBGE 2931301)
 -- Error-type-4, sem DDD em Q2079737 (IBGE 2807303)
 -- Error-type-4, sem DDD em Q1804982 (IBGE 5008008)
 -- Error-type-4, sem DDD em Q22062856 (IBGE 2931707)
 -- Error-type-4, sem DDD em Q2104252 (IBGE 4127403)
 -- Error-type-4, sem DDD em Q2013156 (IBGE 2807402)
 -- Error-type-4, sem DDD em Q615936 (IBGE 2807501)
 -- Error-type-4, sem DDD em Q22060578 (IBGE 2931806)
 -- Error-type-4, sem DDD em Q22064399 (IBGE 3554805)
 -- Error-type-4, sem DDD em Q1784369 (IBGE 4218301)
 -- Error-type-4, sem DDD em Q22062855 (IBGE 2931905)
 -- Error-type-4, sem DDD em Q2445520 (IBGE 1508084)
 -- Error-type-4, sem DDD em Q1962454 (IBGE 3169703)
 -- Error-type-4, sem DDD em Q22062854 (IBGE 2932002)
 -- Error-type-4, sem DDD em Q22062853 (IBGE 2932101)
 -- Error-type-4, sem DDD em Q22062851 (IBGE 2932309)
 -- Error-type-4, sem DDD em Q1807390 (IBGE 2807600)
 -- Error-type-4, sem DDD em Q22060576 (IBGE 2932507)
 -- Error-type-4, sem DDD em Q13109246 (IBGE 3555901)
 -- Error-type-4, sem DDD em Q1793345 (IBGE 5221601)
 -- Error-type-4, sem DDD em Q1794037 (IBGE 5221700)
 -- Error-type-4, sem DDD em Q22062848 (IBGE 2932705)
 -- Error-type-4, sem DDD em Q2104841 (IBGE 2211209)
 -- Error-type-4, sem DDD em Q22062847 (IBGE 2932804)
 -- Error-type-4, sem DDD em Q730382 (IBGE 2211308)
 -- Error-type-4, sem DDD em Q22062845 (IBGE 2933000)
 -- Error-type-4, sem DDD em Q13109251 (IBGE 3556305)
 -- Error-type-4, sem DDD em Q2011987 (IBGE 4219150)
 -- Error-type-4, sem DDD em Q2233145 (IBGE 2211407)
 -- Error-type-4, sem DDD em Q22062840 (IBGE 2933208)
 -- Error-type-4, sem DDD em Q22066862 (IBGE 3556602)
 -- Error-type-4, sem DDD em Q986271 (IBGE 5222005)
 -- Error-type-4, sem DDD em Q2026896 (IBGE 2709400)
 -- Error-type-4, sem DDD em Q22062838 (IBGE 2933406)
---- ERROS BY TYPE:
	Error-type-4, faltou DDD: 105
	Error-type-7, erros primários de WD: 2

Itens com falha por respectivo código IBGE= ('2200400','3102209','1700707','2200509','4200903','4201109','3102902','5001003','2902104','3104205','3107109','3108107','5300108','3108602','3109501','3109808','3110301','3110806','3111002','3111804','3112059','3114204','2303600','2303956','3116605','3116704','3118205','3119104','3119302','2304251','3121258','3124302','3125200','2605459','3127602','2305233','3130101','3130705','3133600','3135209','3137304','3137536','4311304','3138500','3138658','2307809','3141405','2804201','3143104','3143450','2308906','2309102','2804508','2804607','3136603','2309409','3145901','2805505','3152808','2805802','3155504','3155702','3155801','3157203','2708204','3161106','4318200','3162807','1720903','4217907','2931004','4126801','2931202','2931301','2807303','5008008','2931707','4127403','2807402','2807501','2931806','3554805','4218301','2931905','1508084','3169703','2932002','2932101','2932309','2807600','2932507','3555901','5221601','5221700','2932705','2211209','2932804','2211308','2933000','3556305','4219150','2211407','2933208','3556602','5222005','2709400','2933406')

Itens com falha mais grave = ('')
--- FIM ----

git diff > /tmp/city-codes-diff.osm.txt
git add 
git commit 
#####

git diff data/br-city-codes.csv
# nenhuma alteração

php src/etc/dumpWikidata.php
-- Generating backups of JSON-Wikidata --
 USANDO   city-codes/data/br-city-codes.csv
	(1 of 5570) GO-AbadiaGoias: saved (6184 bytes) with fresh Q304652
	(2 of 5570) MG-AbadiaDourados: saved (6202 bytes) with fresh Q582223
...
	(227 of 5570) BA-Andarai: PHP Notice:  Undefined index: datavalue in dumpWikidata.php on line 144
saved (6573 bytes) with fresh Q490022
	(228 of 5570) PR-Andira: saved (6025 bytes) with fresh Q1804315
...
	(532 of 5570) SE-BarraCoqueiros: PHP Notice:  Undefined index: datavalue
saved (6478 bytes) with fresh Q1784872
	(533 of 5570) RS-BarraFunda: saved (4363 bytes) with fresh Q584762
...
	(655 of 5570) AM-BocaAcre: PHP Notice:  Undefined index: datavalue 
saved (4816 bytes) with fresh Q1793334
	(656 of 5570) PI-Bocaina: saved (3790 bytes) with fresh Q2097681
...
	(1212 of 5570) CE-Cedro: saved (4124 bytes) with fresh Q2027857
	(1213 of 5570) PE-Cedro: PHP Notice:  Undefined index: datavalue 
saved (3578 bytes) with fresh Q716874
	(1214 of 5570) SE-CedroSaoJoao: saved (4639 bytes) with fresh Q2013083
...
	(1715 of 5570) MG-Estiva: saved (5919 bytes) with fresh Q1790777
	(1716 of 5570) SP-EstivaGerbi: PHP Notice:  Undefined index: datavalue 
saved (5069 bytes) with fresh Q738934
	(1717 of 5570) MA-Estreito: saved (4323 bytes) with fresh Q2068863
...
	(5569 of 5570) MA-ZeDoca: saved (4452 bytes) with fresh Q1806488
	(5570 of 5570) SC-Zortea: saved (4016 bytes) with fresh Q1648503
 ----------- ERRORS ---------
 * ERROR, empty json for PR-Cambira.

git diff > /tmp/city-codes.gitDiff.wikidata.txt
git status > /tmp/city-codes.gitStatus.wikidata.txt
git add 

Estimativas:

  • praticamente todos os 5570 arquivos, conforme wc -l city-codes.gitStatus.wikidata.txt, sofreram alguma atualização
  • houveram 21290 inclusoes ou modificacoes de propriedades P, conforme grep '+ "P' city-codes.gitDiff.wikidata.txt | wc -l
  • houeram 370 modificacoes ou deleções, conforme grep '\- "P' city-codes.gitDiff.wikidata.txt | wc -l
  • as inclusoes foram relativas a 98 propriedades, conforme sort lix | uniq | wc -l (resta destacar as mais frequentes).
  • as mais frequentes (maior quantidade de ocorrências na listagem) podem ser obtidas por grep '+ "P' city-codes.gitDiff.wikidata.txt | sort | uniq -c | sort

Inclusões com mais de 1000 itens (lembrando que o total é ~5570), mais importantes com nome em negrito:

Quantidade Propriedade Wikidata Nome da propriedade
1046 http://wikidata.org/entity/P41 imagem da bandeira
1175 http://wikidata.org/entity/P94 imagem do brasão
1804 http://wikidata.org/entity/P1296 identificador na Gran Enciclopèdia Catalana
2232 http://wikidata.org/entity/P856 página inicial oficial
5542 http://wikidata.org/entity/P6766 Who's on First ID
5569 http://wikidata.org/entity/P6555 Identificador de Unidade Eleitoral brasileira

Corrigir erros de atribuição Wikidata

Conforme #23 temos

novo wdId ref idIBGE nota
Q22062859 2931400 Teodoro Sampaio/BA
Q13109202 3554300 Teodoro Sampaio/SP

e também foram detectados na Wikidata erros de atribuição:

qid P1585 nome qid_correto
Q818261 2900702 Alagoinhas/BA Q22050101
Q975677 4201208 Antônio Carlos/SC Q22063985
Q608983 5201504 Aporé/GO Q22067258
Q624997 5201702 Aragarças/GO Q22067256

Código IBGE de brasília

O DF não é um município, apesar de ter simultaneamente propriedades de município por compor o mesmo mosaico, sendo eleito como item deste dataset. Correção já realizada na Wikidata (Q2844): código IBGE é 53, e OSM_ID=421151. A relation 2758138 (com admin_level=8 usual de município) corresponde ao "RA I", administração do Plano Piloto,

Problema: código IBGE de state-codes e de city-codes será o mesmo, ideal usar algo como 53000001 se existir... Ver como o IBGE convencionou, ou se melhor ficar como 53.


Solução paliativa

UPDATE brcodes_city SET ibge_id=53 WHERE wikidata_id=2844;

Reordenar sinônimos

Devido à previsão de mudanças mais frequentes e de grandes quantidades de dados na br-city-synonyms.csv, ordenar por tipo, criando via algoritmo grandes grupos:

  • grupo 1: sinônimos canônicos e oficiais, de fato o mais importantes.
  • grupo 5: sinônimos referenciados, com caso de uso minimamente documentado.
  • grupo 8: demais "sinônimos corretivos" (contemplando erro ortográfico do usuário e outros), tipicamente aqueles gerados automaticamente por algoritmo.

O mais simples é redefinindo a função de ordenação std_collate(), acrescentando o parâmetro de type de tipo de sinônimo com seu respectivo default para gerar

  • grupo 0: para uso da função com city-codes.csv (não-sinônimos).

Fazendo uso de tais considerações e já copiando/colando o regexp_replace() da função original temos:

CREATE FUNCTION std_collate(
   p_name text, p_syn_type text DEFAULT NULL
) RETURNS text AS $f$
    SELECT CASE 
      WHEN p_syn_type IS NULL THEN '0'
      WHEN p_syn_type='alt canonico' OR $2='alt oficial' THEN '1'
      WHEN substr(p_syn_type,1,3)='err' THEN '8'
      ELSE '5' 
    END ||  regexp_replace(p_name, E'[ \'\-]', '0', 'g')
$f$ language SQL;

Esta issue afeta as decisões da issue #11.

Falta incluir intervalo de CEP de 20 cidades

Faixas de CEP oficiais podem ser rapidamente verificadas no buscacep.correios.com.br, e atualizadas nesta planilha colaborativa.

Por questões de compatibilidade de nomes ficaram pendentes na importação original os CEPs de 20 municípios, são eles:

name state wdId idIBGE lexLabel
Arês RN Q928712 2401206 ares
Boa Saúde RN Q1802783 2405306 boa.saude
Bom Jesus de Goiás GO Q891725 5203500 bom.jesus.goias
Brazópolis MG Q1749826 3108909 brazopolis
Dona Eusébia MG Q1756805 3122900 dona.eusebia
Espigão D'Oeste RO Q616498 1100098 espigao.d.oeste
Governador Edison Lobão MA Q2012559 2104552 governador.edison.lobao
Gracho Cardoso SE Q647366 2802601 gracho.cardoso
Iguaracy PE Q2010845 2606903 iguaracy
Paraty RJ Q926729 3303807 paraty
Sant'Ana do Livramento RS Q917693 4317103 sant.ana.livramento
Santa Izabel do Pará PA Q2008554 1506500 santa.izabel.para
Santa Teresinha BA Q1795259 2928505 santa.teresinha
Santo Amaro do Maranhão MA Q665255 2110278 santo.amaro.maranhao
São Domingos PB Q224967 2513968 sao.domingos
São Luís do Paraitinga SP Q1646919 3550001 sao.luis.paraitinga
São Valério da Natividade TO Q1801542 1720499 sao.valerio.natividade
Senador La Rocque MA Q1967899 2111763 senador.la.rocque
Trajano de Moraes RJ Q1803189 3305901 trajano.moraes
Campo Grande RN Q1802671 2401305 campo.grande

Basta incluir manualmente, o refazer a importação com base nos sinônimos. Na tabela acima os links para Wikidata ajudam a confirmar o primeiro item do intervalo (ou ajude a Wikidata caso não tenha sido incluso o statement P281).

Incluir sinônimos auto-gerados

Ver grupo 8 dos "sinônimos corretivos" da #13, onde já se prevê a inclusão de sinônimos gerados por algoritmo.

Justificativas adicionais

Nomes oficiais tratados de forma reduzida em documentos oficiais — por exemplo na resolução Anatel 263, adotada a partir da issue #10, reduz-se Embu das Artes/SP para "Embu" e Bom Jesus de Goiás/GO para "Bom Jesus" —, e trocas de convenção ortográfica frequentes (ex. trocar "Terezinha" por "Teresinha" ou "Iguassu" por "Iguaçu"), podem ser tratadas por algoritmo.

Viabilidade do algoritmo

Ver discussão já em curso, registrada em /src/Synonyms generation for multi-word names.

Fixar conjunto reduzido de propriedades ou excluir P18

A P18 acrescenta referência ao nome de arquivo de uma imagem de ilustração do município... Por variar com frequência e não corresponder a um metadado de caracterização relevante do município.

Talvez seja o momento de estabelecer um padrão inicial de conjunto de propriedades, satisfeito pela maioria dos municípios.


Aparentemente a propriedade P18 foi a mais frequentemente atualizada entre as selecionadas, neste período (~2 meses). git diff | grep "P18\"" | wc -l = 293, git diff | grep P402 | wc -l=186, etc.

garantir LF

Quando usuário Windows colabora, há risco de gerar modificação não-intencional sistemática nos arquivos, por inclusão do CRLF. Medidas para evitar o problema:

  1. Convenção global do datasets-br, usar LF (Unix end-o-line)
  2. Boa prática no git, git config --global core.autocrlf input
  3. (mais importante!) mudar o .gitattributes

Convenção:

# Plase configure your git as Linux to properly handle line endings
#  git config --global core.autocrlf input

# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto

# Declare files that will always have LF line endings (Linux mode) on checkout.
* text eol=lf

# Denote all files that are truly binary and should not be modified.
*.pdf binary
*.png binary
*.jpg binary
*.zip binary

Incluir abreviação de 3 letras por uf

O código de 3 letras da Anatel parece que não chegou a ser adotado, talvez justamente por sua abrangência (todos os ~5500 municípios) inviabilizando a geração de códigos de 3 letras (frequência de colisão os códigos mais mnemonicos segue a mesma probabilidade que colisão de hash de 3 letras).

Temporariamente denominar abrev3_uf as siglas de nome de cidade válidas para o namespace estadual. No caso de SP é o primeiro estado com aparente disponibilidade de código oficial de 3 letras do estado. Está prevista a sua utilização na identificação das vias municipais do Estado. Diversas já existem inclusive em placas: por exemplo PIR-033 é denominação de estrada de Piracicaba SP.

Incluir mapa OSM de cada município

Tal como em state-codes, a versão GeoJSON do mapa OSM é adequada como dado de apoio ao dataset. Exemplo: data/dump_osm/AC.geojson.

Quanto à disponibilidade e completeza, um rápido grep mostra que a meta será atingida.

grep P402 data/dump_wikidata/*/* | wc -l
# 5569

~5569 em 5570 é 100%, esta completo completo.

Usando php src/dumpOsm.php geo


Cuidado a falha datasets-br/state-codes/issues/18 no servidor GeoJSON em uso, convém revisar antes de sobrecarregar este git.


Resultados, apenas 3 falhas:

  • ERROR, invalid OSM structure for RJ-CasimiroAbreu.
  • ERROR, no osmId or P402 for MG-Chiador.
  • ERROR, empty json for MG-Chiador.

Gravar backup do JSON Wikidata

O presente repositório, a principio, é apenas um cache para os dados da Wikidata: é a nossa principal fonte de dados depois que nomes e códigos estão devidamente homologados.

Sendo assim, o ideal é trazer e controlar as atualizações destes dados. Tendo tudo num só lugar fica também mais fácil rodar algoritmos de consistência e auditoria das atualizações realizadas na Wikidata.

Incluir os backups em /data/wikidata como arquivos nomeCidade.json. Obter o nomeCidade por maiúsculas e eliminação do ponto do lexLabel, ou seja,

function lex2filename($s) {
	$s=ucwords( str_replace('.',' ',$s) );
	return str_replace(' ','',$s);
}

manter o atualizador de backups como city-codes/src/etc/dumpWikidata.php.

Em seguida verificar o JSON-path dos campos pendentes, tais como data de fundação da cidade.


Utilização

  • Ano de fundação.

  • LatLong

  • O "ano do último batismo" será sempre igual ou maior do que a data de fundação. Conferir se pode transformar o último batismo (ou a lista de anos de mudança de nome) em um dado Wikidata, senão será controlado exclusivamente por este repositório.

  • ...

Lagoa dos Patos na contabilidade de áreas municipais

Usando como verificação as áreas de
ftp://geoftp.ibge.gov.br/organizacao_do_territorio/estrutura_territorial/areas_territoriais/2017/AR_BR_RG_UF_MES_MIC_MUN_2017.ods. Nelas, além dos 5570 municípios, aparecem dois itens a mais, que são as lagoas de RS. Como estão registradas na forma de códigos de municípios, e fazem parte da totalização de "áreas do Brasil", convém incluir no dataset. A rigor não é código de município.


Consultas

SELECT count(distinct  geocodigo) n FROM ibge_lim_munic_2017_area; --  5572 
SELECT i.* 
FROM ibge_lim_munic_2017_area i left join brcodes_city b 
   ON b.ibge_id::text=i.geocodigo 
WHERE b.ibge_id is null;
 geocodigo | uf |      nome       |   area    
-----------+----+-----------------+-----------
 4300001   | RS | LAGOA MIRIM     |  2832.194
 4300002   | RS | LAGOA DOS PATOS | 10152.408

Incluir coluna de prefixo ou máscara de CEP

Apesar de ser um conversão simples da coluna de postalCode_ranges, o prefixo será o dado padronizado utilizado com mais frequência nas aplicações simples e por projetos como OSMBrasil/CRP ou CLP.

PS: esta é uma demanda também na Wikidata, que idealmente deveria apresentar uma "máscara de CEP" baseada no prefixo. Assim ao invés de P281 os municípios brasileiros seriam marcados pela máscara. Por exemplo São Luiz do Paraitinga/SP (Q1646919) tem indicado apenas o CEP inicial 12140-000 mas o correto seria o prefixo, 121**-*** (ou 121[456].-...) relativo ao intervalo [12140-000 12169-999].

A remoção do prefixo ajuda a dar uma ordem de grandeza do número de vias de uma cidade, e para o número de dígitos necessários para se endereçar diretamente as vias.

Municípios pequenos como Abadia de Goiás/GO com CEPs [75345-000 75349-999] (portanto prefixo 7534) e Acaiaca/MG com CEPs [35438-000 35438-999] (portanto prefixo 35438), podem ter o código de rua integralmente baseado no CEP, e reduzido a no máximo 5 e 3 dígitos respectivamente. Na maioria dos casos, como a convenção de "código de via baseado em CEP" é relativa ao menor CEP atribuído à via (em estudo a convenção de removendo-se os zeros da direita), o número de dígitos pode ser ainda menor.

Nas maiores cidades os prefixos são menores devido ao adensamento maior (São Paulo por exemplo tem prefixo de tamanho 1). São por volta de 90 municípios com prefixo de "tamanho 2 ou 1". Todos os demais ~5460 apresentam em média prefixo tamanho 4, levando portanto a códigos de via urbana de 4 dígitos (8-4), comprovando a sua viabilidade como "código opcional oficial da via municipal" no projeto CLP.

CREATE VIEW citybr_poprefix AS
  SELECT state, "lexLabel", 
                extract_common_prefix(x[1],x[2]) cep_prefix, 
                (x[2]::bigint-x[1]::bigint)::int as cep_diff,
                "postalCode_ranges"
  FROM (
    SELECT state, "lexLabel", "postalCode_ranges",
        regexp_split_to_array(  regexp_replace("postalCode_ranges",'[\[\]\-]','','g')  , ' ') x
    FROM citybr where not("postalCode_ranges" like '%] [%' or "postalCode_ranges" is null)
  ) t
;
SELECT avg(length(cep_prefix)) as tamed, stddev_pop(length(cep_prefix)) as tamed_err, 
              avg(cep_diff) as avgdiff, stddev_pop(cep_diff) as avgdiff_err,
            count(*) as n
FROM citybr_poprefix WHERE length(cep_prefix)>2; 
-- 3.9 | 0.4 | ...| 5461

Mais precisamente 4652 apresentam tamanho 4 ou 5.
PS: nestes a média da cep_diff é de ~5640 ± 3200, ou seja, foram reservados de 2400 a 9000 CEPs para a grande maioria dos municípios brasileiros (mesmo as exceções ficam entre min. 499 e máx. 9999). O número de códigos será da ordem de 1/10 ou menos que isso (pode-se confirmar também por amostragem no OpenStreetMap).

Exemplos:

state lexLabel cep_prefix postalCode_ranges
GO abadia.goias 7534 [75345-000 75349-999]
MG abadia.dourados 3854 [38540-000 38549-999]
GO abadiania 729 [72940-000 72959-999]
... ... ... ...
BA alagoinhas 48 [48000-001 48107-999]
PA ananindeua 67 [67000-001 67199-999]
SP bauru 17 [17000-001 17119-999]
MG belo.horizonte 3 [30000-001 31999-999]
... ... ... ...

Corrigindo consistência na Wikidata

A partir da gestão dos resultados da melhora proposta pela issue #23 ficou evidente a necessidade de se também efetuar ações a partir deste projeto na Wikidata.

Casos de erro de atribuição

Não tem como descobrir, e por isso a validação com o idIBGE é tão importante. Uma vez detectada a suspeita deve-se proceder à verificação humana. As suspeitas tem sido geradas com sucesso pelo php src/etc/dumpWikidata.php chk, que por sua vez permite listar com SQL e gerar um CSV. O procedimento completo seria:

  1. Gera lista dos suspeitos em CSV (exemplo SQL abaixo).

  2. Converte CSV em planilha Google ou interface similar para testar links, exemplo.

  3. Converte dados apurados em SQL (UPDATE em função do idIBGE, final abaixo).

COPY ( 
  SELECT "idIBGE",name||'/'||state as cidade_nome, '' as "WIKIDATA_correctConfirmed",
       concat('https://www.google.com.br/search?q=',replace("lexLabel",'.','+'),'+',upper(state),'+wikipedia+município') as "click_and_check"
  FROM io.citybr 
  WHERE "idIBGE" IN  (   
      '1700400','5200605','1500859','5000708','....','2616308','2933307'
  )
) to '/tmp/buscarWikidataCorreto.csv' HEADER CSV;

---- depois da verificação humana
UPDATE io.citybr set "wdId"='Q22060165' WHERE "idIBGE"='1700400';
UPDATE io.citybr set "wdId"='Q22060523' WHERE "idIBGE"='5200605';
UPDATE io.citybr set "wdId"='Q22060315' WHERE "idIBGE"='1500859';
UPDATE io.citybr set "wdId"='Q22067433' WHERE "idIBGE"='5000708';
...

Demanda por merge na Wikidata

Ao subir as ~50 correções e conferir páginas Wikidata, ficou mais evidente o problema da duplicação de conceitos na Wikidata (!), tipicamente entidades mais antigas sendo mantidos como verdadeiras, apesar da Wikipedia apontar para duplicada mais nova.

.... Uma solução que ajuda a destacar os problemáticos é criando um atributo no nosso dump que list o número de links Wikipedia e destaque o link para a Wikipedia Português, que é a "fonte fiável" de auditoria do conceito.

Outras dicas e confirmações de que ter a referência idIBGE é a melhor saída antes do merge.

Correções, atualizar nomes antigos e incluir item

Verificando nomes ausentes da lista oficial do IBGE de 2015, conforme lexml-vocabulary/issues/7:

  • br;paraiba;campo.santana (Campo de Santana - PB)
  • br;paraiba;santarem (Santarém - PB)
  • br;paraiba;serido (Seridó - PB)
  • br;rio.grande.norte;boa.saude (Boa Saúde - RN)
  • br;tocantins;sao.valerio.natividade (São Valério da Natividade - TO)

  • br;paraiba;campo.santana [1996..2009-12-22] é sinônimo de
    br;paraiba;tacima [1959-04-30..1996, 2009-12-23..].
    "(...) A Lei Municipal n. 28 de 1996 mudou o nome do município para Campo de Santana. Pela lei municipal nº 15, de 23 de dezembro de 2009, o município de Campo de Santana voltou a denominar-se Tacima", pt.wikipedia.org/wiki/Tacima.

  • br;paraiba;santarem [1994-04-29..2010-12-27) é sinônimo de
    br;paraiba;joca.claudino [2010-12-27..).Na Wikipedia o nome foi redireiconado para Joca Claudino.
    "... recebeu o status de município com a denominação de Santarém pela lei estadual nº 5.909 de 29 abril de 1994. Em 27 de dezembro de 2010 a Câmara municipal aprovou uma lei que modificou o nome do município para Joca Claudino".

  • br;paraiba;serido é sinônimo popular de br;paraiba;sao.vicente.serido .

  • br;rio.grande.norte;boa.saude é o nome corrente e canônico para Boa Saúde, que já foi januario.cicco de 1953 a 1991-02-01.

  • br;tocantins;sao.valerio.natividade é o nome correto: no site oficial da prefeitura e no vocabulário LexML é grafada como São Valério da Natividade (TO). Na base IBGE está como "São Valério" (código 1720499).
    História: "o município foi criado em 1º de janeiro de 1988 e instalado em 1º de janeiro de 1989. O povoado era conhecido como Goianorte e foi desmembrado de Natividade". É uma cidade nova.

Conclusão

2 bugs a serem corrigidos e 3 sinônimos a serem inclusos.

Garantir formatação padrão no CSV

Diferentes editores e aplicações estabelecem diferentes formatos finais para o CSV, em particular quanto ao uso de aspas em números inteiros grandes e em datas. Sugere-se fixar um aplicativo leve Unix (Perl, Node ou PHP) que seria sempre disparado antes dos commits. Conferir também se ferramentas associdas ao Goodtables já não fazem isso (!).

Continuação da issue #5.

Sigla de 3 letras da cidade no namespace do estado

Abreviações de 3 letras dos nomes de cidade foram consagradas pelo uso em aeroportos. São também bem difundidas as abreviações ISO de 3 letras de nomes de países. Abreviar nomes de cidades brasileiras não deveria ser problema, mas atualmente não existe nem um "algoritmo oficial" das abreviações de nome em 3 letras.

Poderíamos usar uma tabela de abreviaturas já fixada por um órgão do governo, e de fato existe ou existiu, é a tabela da ANATEL. Ela todavia não chega a ser muito superior que a convenção da issue #6 , o código compacto (4 caracteres) do identificador IBGE, e não é uma convenção "por estado", é para todo o Brasil... A presente proposta se justifica pela impossibilidade teórica de conseguir bons resultados com uma proporção tão grande se comparada ao número de combinações possíveis com as 3 letras (ver nota tecnica abaixo).

Classificando o algoritmo

É como uma função hash u=H(x), onde x é uma string de entrada (um nome), e o "digest" resultante na saída, u, é uma string de tamanho fixo, com 3 letras. Mas certamente não é um hash criptográfico, é muito mais um "hash de semelhança" (entradas parecidas podem resultar em hashes iguais).

Em funções hash especializadas podemos também restringir o domínio, portanto classificando também o tipo de entrada: são topônimos da língua portuguesa. Um conjunto T de topônimos, com a restrição de que seu tamanho |T| não exceda em 5% o número de elementos do contra-domínio de H, ou seja, o número de combinações possíveis com 3 letras, que é 26^3=17576.

Por fim, a característica que diferencia ou torna ainda mais especializada essa função H, quando comparada com hashes usuais. Como são previstas colisões, essa função deve também suprir estratégias para lidar com as colisões: a função muda o algoritmo em função de parâmetros q de qualidade e i de "i-ésima tentativa" dentro de certa qualidade, H(x,q,i). O uso do parâmetro q seria então vinculado ao contexto de colisão:

  • use H(x,0) para resultados de "primeira classe" (máxima qualidade) enquanto não houverem colisões;

  • depois da primeira colisão, testar H(x,1,i), um resultado de "segunda classe";

  • depois tentar H(x,2,i) o resultado de pior qualidade.

Examplos:

  • H("Hello",0) é "HEL", H("Hello",2,i) é "HLL" ou "HLO", e H("Hello",3,i) é "LLO" ou "LLH".

  • quando x="Hello My Friend", H(x,0) é "HMF", H(x,1) é "HLF" ou "HFR", e H(x,2) é "MFR" ou "MFD".

Agrupamento e sequência

Com mais de 1% do ...

Outros critérios de qualidade

A qualidade da sigla deve ser avaliada em termos de:

  • simplicidade e popularidade da regra: se perguntamos para 100 pessoas "como você abreviaria o nome x para 3 letras?", esta vai ser a resposta mais frequente. Mas como vimos existem pelo menos dois tipos de nome, os simples e os compostos.

  • semelhança: siglas de três letras serão consideradas 40% parecidas se apenas a primeira letra for igual e 70% parecidas se além da primeira uma das demais letras for também igual. Quando apenas as duas últimas forem iguais será considerada semelhança de 50%.
    É esperado que a média de um índice de semelhança aplicado aos pares de nomes com 70% de semelhança nas suas siglas seja preservada.

  • diferenciação preservando a popularidade: fazer uso inteligente de regras de diferenciação do português. Por exemplo, plural/singular se diferenciam pelo "s" no final (ver Varginha ); os dígrafos com som de uma letra só, "RR", "SS", "CH", ... podem ser reduzidos, garantidos maior taxa de diferenciação sem perda de agrupamento dos semelhantes.

NOTA TÉCNICA - CRITÉRIO DE ABUSO

A chance de colisão deve ser intendida como probabilidade P de dois nomes calharem de ficar com a mesma abreviação de 3 letras.

Recapitulando o que temos para poder estimar P: a sigla de 3 letras faz o papel de um digest de hash, e neste sentido vale a relação clássica de chance de colisão... Como temos 26^3=17576 combinações com 3 letras, esse é o tamanho c do contra-domínio de H.

Para efeitos de análise teórica das chances de colisão podemos aproximar grosseiramente 17576 para a potencia de 2 mais próxima, que é 16383, ou seja, 14 bits. Se o conjunto de entrada T tem 50 elementos, a chance de colisão em uma hash com c de 14 bits, será da ordem de 7,2%. Com 100 elementos já salta para 26%, com 500 para 99,90% (saturação).

O estado mais pobre em número de municípios é o MS, com 79, que fica na primeira faixa (17% de chance). O recordista é MG, com 99,999% de chance.

Como no processo de atribuição de siglas, a cada colisão oferecemos uma opção diferente de sigla, e essas opções vão se deteriorando em termos de qualidade... Podemos supor que lá pela quarta ou quinta tentativa já não há mais qualidade. Assim um bom chute de chance de preservação da qualidade é P/5 (chance não colidir ou na primeira, ou na segunda, ou .. na quinta tentativa). Voltando aos valores estimados acima teremos ~1% para MS e ~10% para MG.

Outro parâmetro simples é o número médio o de opções de abreviação por nome: MG tem o=17576/853=20, SP tem o=17576/645=27, ..., MS tem o=17576/79=222. Com mais opções haverão maiores chances de eleger uma de melhor qualidade. O então, para traduzir em termos percentuais precisamos imaginar qual o número mínimo de opções aleatórias de 3 letras. Conhecemos o resultado da Anatel que consideramos ruim, que foi de apenas 3,2 opções (o=17576/5500 ~ 3,2). Chutamos que dez opções seja o mínimo, o_min=10.

Critério de "qualidade máxima esperada", por abuso ou não do número de itens a abreviar com 3 letras:

  • Sem chance de qualidade: o<10
  • Garantia de boa qualidade: P<1% e o>50

Referências

  • Cidades brasileiras com aeroportos: aparentemente todas elas deveriam ter abreviações IATA, mas não encontrei uma listagem sistemática do Brasil (não confundir com aeroportos)... Alguns exemplos mas não sei se são oficiais: ANS Anápolis-GO, PTM Patos de Minas-MG, PTS Patos-PB, URA Uberaba-MG, UDI Uberlândia-MG... e os mais exóticos, BSB Brasília-DF, GYN Goiânia-GO, ...

  • Abreviações Anatel: só em PDF e parece ser (Date HTTP header) de 2013.

  • Abreviações do CDHU/SP: não possuem 3 letras, mas são todas palavras simples e reduzidas, simplificando bastante o trabalho do algoritmo. Ajudaria como "referência oficial" se não houver outra de ponto de partida... Só está disponível em PDF e parece ser de 2005.

  • Dados das cidades, por estado, etc. Wikidata. Como fazer queries SparQL pode ser chato, algumas tabelas como a de São Paulo já se encontram prontas, e um dataset homologado também pode ser utilizado.


Cálculo de semelhança de nomes: pode-se reduzir o nome aplicando o metaphone (reduzindo a 4 caracteres) à primeira e última palavra, e as demais preservando apenas iniciais; em seguida aplicando um índice como Levenshtein.

novos sinônimos oficiais

Durante empreitada da #16 descobriu-se que haviam novos "sinônimos oficiais", tendo em vista a adoção dos nomes pelos Correios:

nome Sinônimo-CEP UF WdID
Bom Jesus de Goiás Bom Jesus GO Q891725
Dona Eusébia Dona Euzébia MG Q1756805
Espigão D'Oeste Espigão do Oeste RO Q616498
Gracho Cardoso Graccho Cardoso SE Q647366
Iguaracy Iguaraci PE Q2010845
Sant'Ana do Livramento Santana do Livramento RS Q917693

incluir coluna de abreviações ANATEL2013

Mesmo não sendo um conjunto integral de abreviações, ir usando como recurso demonstrativo e para discussão de padrão definitivo.


Processo realizado:

	  CREATE FOREIGN TABLE tmpcsv_br_city_codes (
		name text,
		state text,
		"wdId" text,
		"idIBGE" text,
		"lexLabel" text,
		creation integer,
		extinction integer,
		"postalCode_ranges" text,
		ddd integer,
		notes text
	  ) SERVER files OPTIONS ( 
	     filename '/tmp/br_city_codes.csv', 
	     format 'csv', 
	     header 'true'
	  );
CREATE TABLE br_city_codes AS SELECT * FROM  tmpcsv_br_city_codes;
ALTER TABLE br_city_codes ADD COLUMN abbrev3 text;

UPDATE br_city_codes SET abbrev3=abbrev FROM tmpcsv_anatel2013_abrevs3 a 
WHERE a.state=br_city_codes.state AND a.ddd=br_city_codes.ddd 
               AND name2lex(unaccent(lower(a.name)))=br_city_codes."lexLabel"
; -- 4423 rows

-- Copy back to CSV:
COPY (
  select name, state, "wdId", "idIBGE", "lexLabel", creation, extinction,
     "postalCode_ranges", ddd, abbrev3, notes  
   from br_city_codes ORDER BY std_collate(name), name, state 
) to '/tmp/atualizacao.csv' CSV HEADER

Modificar o datapackage.json

Incluir código compacto do município, base34btc do IBGE

Identificadores curtos são constantemente solicitados, pelos mais diversos motivos. A representação de qualquer número inteiro em base36 já é um grande ganho. Mair ainda em base64.

Como os códigos de cidade são utilizados também em transcrições humanas, URLs, nomes de arquivo, etc. cabe evitar risco de confusão. base64 introduz pontuação, e na leitura humana há confusão entre "0" e "O" ou entre "1" e "I". A solução mais popular para se resolver o problema da base64 é a base58 Bitcoin, abreviada base58btc. Quando queremos também evitar ambiguidade ou risco de mudança entre maiúsculas e minúsculas, seu equivalente seria a base34 com alfabeto Bitcoin (base34btc), ou seja, trocando as letras "I" por "W" e "O" por "Z".

Os 2 primeiros dígitos do código IBGE (coluna idIBGE) são totalmente redundantes, podem ser eliminados, resultando num número inteiro de 6 dígitos. Exemplos: Abadiânia é o número 5200100 que fica como 00100, Zacarias (SP) é o número 3557154 que fica como 57154. Seguindo a convenção da base34btc, temos 001U e 1FF0 respectivamente como códigos compactos de cidade.

Como o IBGE se preocupa também com a ordenação dos números, faz uso de número inteiro é esparso (pula de 100 em 100), por isso mesmo na base34 ainda apresenta mais do que 3 caracteres. Apesar disso, não compensa criar toda uma nova padronização de números sequenciais apenas para se ganhar um caractere. A alternativa, neste caso é o uso da tabela 3 letras da Anatel, mas ela perde a informação relativa ao código IBGE, que foi preservada na base34btc.

Inventário das alterações toponímicas e territoriais

As mudanças toponímicas são captadas automaticamente pela gestão de banco de dados (exemplo recente). As mudanças territoriais podem ser rastreadas automaticamente no Projeto OSM-Stable BR, por verificação de mudança de área acima do erro de edição dos polígonos de município.

Alterações na listagem de códigos IBGE (insersão ou deleção) destacam automaticamente o desmembramento ou fusão de municípios.

Todas essas potenciais mudanças precisam ter origem em leis federais ou estaduais, ou seja, depois de detectar a mudança, é necessário buscar a lei, ou vice-versa, se Wikidata por exemplo apresentar o dado, verifica-se o novo polígono ou mudança no IBGE.

Sugestão de tabela de movimentação: registra tipo de mudança, partes afetadas e leis associadas.


Exemplos

Exemplo de fonte oficial dos dados de criação e movimentação:

Exemplo de município com mudança recente:

Exemplo de histórico de TO (link acima), eventualmente cobrindo datas para além do escopo do city-codes:

  • A Lei nº 644, de 28 de julho de 1919 (D.O. de 16-08-1919), eleva a muincípio o distrito de Couto Magalhães, compreendendo os povoados de Santa Maria do Araguaia e Pau d'Arco (desmembrados do município de Pedro Afonso), cuja instalação se deu a 20 de maio de 1920.

  • Por força do Decreto nº 860, de 18 de março de 1931 (D.O. de 21-03-1931), foi a sede de Couto Magalhães transferida para a povoação de Santa Maria, que foi elevada a Vila, conservando, porém, o mesmo nome.

  • Pelo Decreto - Lei nº 557, de 30 de março de 1938 (C.O. de 18-05-1938), passou a denominar-se Santa Maria do Araguaia. O Decreto - Lei nº 8.305, de 31 de dezembro de 1943 (D.O. de 31-12-1943 e D.O. de 09-11-1944), mudou seu nome para Araguacema.

Falha na fonte de GeoJSON

Vem sendo usado o http://polygons.openstreetmap.fr/get_geojson.py?id={relation_id} como fornecedor das geometrias simplificadas em GeoJSON. Falhas da própria simplificação já foram apresentadas antes no state-codes/issues/18, que podem ser ambos, falta de atualização e falha de simplificação.

Sugestão resumida

  • Armazenar no city-codes ou no dump_osm do city-codes apenas area, centroide e BBOX precisos.
  • avaliar se vale "trocar de fornecedor do GeoJSON" ou, mais correto, baixar o Planet para fazer o tratamento adequado... Opção de remover o dump_osm.
  • remover o dump_osm de GeoJSON, ficar com com BBOX, Center, etc. e migrar a preservação de GeoJSON para a OSM-BR. Junto sugerir o uso de três tipos de backup:
    1. Separado o backup full (pouco usado e disponível nos backups de planet)
    2. GeoJSON de geometria simplificada, conforme critérios adequados, para que forneça área, perímetro, etc. razoáveis.
    3. TopoJSON (ver PostGIS/AsTopoJSON parece funcionar bem).

Avaliação

Como estão apresentando bug e já se mostraram simplificadas demais para por exemplo medidas de área, parece ser o momento de trazer originais do Planet e estabelecer um algoritmo local para obtenção das medidas (area, perimetro, bbox, centroid) e simplificação satisfatório (com algoritmos lentos e usando dilatação-erosão dentro do intervalo de erro estimado na obtenção dos dados).

As geometrias exatas de coastLine precisam ser adquiridas em separado e fornecerão resultados distintos.


As mensagens de erro podem ser obtidas com o script abaixo,

CREATE TABLE test_city AS
 SELECT *,  st_area(geom,true) aprox_area, 
     ST_Envelope(geom) geom_bbox,  ST_PointOnSurface(geom) geom_center 
 FROM (
	 SELECT *, ST_SetSRID( ST_GeomFromGeoJSON( read_geojson(path)), 4326) as geom 
	 FROM (
	   select state||'/'||lib.initcap_sep("lexLabel",true) as path,*
	   from io.citybr
	 ) t
 ) t2
 WHERE  ST_IsValid(geom)
;
SELECT state,name,  "idIBGE" from io.citybr 
WHERE "idIBGE" NOT IN (SELECT "idIBGE" FROM test_city);
NOTICE:  Nested shells at or near point -51.504055899999997 -29.400515200000001
NOTICE:  Nested shells at or near point -57.613555699999999 -18.999119400000001
NOTICE:  Self-intersection at or near point -49.415139578296895 -17.692605747287082
NOTICE:  Nested shells at or near point -52.491542099999997 -31.457800899999999
NOTICE:  Nested shells at or near point -55.7061761 -22.552483200000001
NOTICE:  Nested shells at or near point -47.875667300000003 -22.590384400000001
NOTICE:  Self-intersection at or near point -56.423870703139137 -4.7442622930554128
SELECT 5559

Foram ao todo 11 municípios sem geometria avaliada:

state name idIBGE
GO Morrinhos 5213806
MG Chiador 3116209
MS Corumbá 5003207
MS Ponta Porã 5006606
PA Trairão 1508050
RJ Casimiro de Abreu 3301306
RS Barão 4301651
RS Pelotas 4314407
SP Florínea 3516101
SP São Luiz do Paraitinga 3550001
SP São Pedro 3550407

Lembretes sobre simplificação

  • morphology/Dilation = positive buffer, morphology/Erosion = negative buffer

  • ST_RemoveRepeatedPoints — Returns a version of the given geometry with duplicated points removed.

  • ST_Simplify — Returns a "simplified" version of the given geometry using the Douglas-Peucker algorithm.

  • ST_SimplifyPreserveTopology — Returns a "simplified" version of the given geometry using the Douglas-Peucker algorithm. Will avoid creating derived geometries (polygons in particular) that are invalid.

  • ST_SimplifyVW — Returns a "simplified" version of the given geometry using the Visvalingam-Whyatt algorithm

Conferir e substituir suspeitos de erro ou duplicidade na Wikidata

Atualmente a Wikidata sofre com um "robot attack" do robô de construção das Wikipedias ceb e sv... Abaixo os casos: a maioria causou confusão também por se tratar de não-validade do código Wikidata mais antigo.

Com "*" as linhas onde a suspeita se confirma e com "r" onde um redirecionamento já foi providenciado (mas ainda assim convém mudar no registro).

state lexlabel Suspeito TalvezCorreto
BA * alagoinhas http://wikidata.org/entity/Q818261 http://wikidata.org/entity/Q22050101
BA r alcobaca http://wikidata.org/entity/Q1800783 http://wikidata.org/entity/Q22063205
BA r antas http://wikidata.org/entity/Q2014732 http://wikidata.org/entity/Q22063195
BA r araci http://wikidata.org/entity/Q682336 http://wikidata.org/entity/Q22063188
BA r tanhacu http://wikidata.org/entity/Q1794964 http://wikidata.org/entity/Q22062867
BA r taperoa http://wikidata.org/entity/Q2021109 http://wikidata.org/entity/Q22062864
BA r tapiramuta http://wikidata.org/entity/Q646894 http://wikidata.org/entity/Q22062863
BA * teodoro.sampaio http://wikidata.org/entity/Q1760393 http://wikidata.org/entity/Q22062859
BA r terra.nova http://wikidata.org/entity/Q1808357 http://wikidata.org/entity/Q22062856
BA r tremedal http://wikidata.org/entity/Q1795094 http://wikidata.org/entity/Q22060578
BA r tucano http://wikidata.org/entity/Q598704 http://wikidata.org/entity/Q22062855
BA r uaua http://wikidata.org/entity/Q1795209 http://wikidata.org/entity/Q22062854
BA r ubaira http://wikidata.org/entity/Q1793911 http://wikidata.org/entity/Q22062853
BA r ubata http://wikidata.org/entity/Q746419 http://wikidata.org/entity/Q22062851
BA r una http://wikidata.org/entity/Q1794007 http://wikidata.org/entity/Q22060576
BA r urucuca http://wikidata.org/entity/Q1772617 http://wikidata.org/entity/Q22062848
BA r utinga http://wikidata.org/entity/Q1772640 http://wikidata.org/entity/Q22062847
BA r valente http://wikidata.org/entity/Q1806997 http://wikidata.org/entity/Q22062845
BA r vera.cruz http://wikidata.org/entity/Q1794349 http://wikidata.org/entity/Q22062840
BA r wagner http://wikidata.org/entity/Q1793811 http://wikidata.org/entity/Q22062838
SP * anhumas http://wikidata.org/entity/Q1774430 http://wikidata.org/entity/Q22066885
SP * tabatinga http://wikidata.org/entity/Q1815939 http://wikidata.org/entity/Q22064419
SP * taciba http://wikidata.org/entity/Q1760336 http://wikidata.org/entity/Q22064418
SP * tapirai http://wikidata.org/entity/Q1800743 http://wikidata.org/entity/Q22064413
SP * taquaral http://wikidata.org/entity/Q1796324 http://wikidata.org/entity/Q22064411
SP * tarabai http://wikidata.org/entity/Q1798813 http://wikidata.org/entity/Q22064407
SP * trabiju http://wikidata.org/entity/Q1761480 http://wikidata.org/entity/Q22064400
SP r tremembe http://wikidata.org/entity/Q1772599 http://wikidata.org/entity/Q22064399
SP * tuiuti http://wikidata.org/entity/Q1760934 http://wikidata.org/entity/Q22064397
SP * turiuba http://wikidata.org/entity/Q1761124 http://wikidata.org/entity/Q22064394
SP r uru http://wikidata.org/entity/Q1795600 http://wikidata.org/entity/Q13109246
SP r valparaiso http://wikidata.org/entity/Q1763552 http://wikidata.org/entity/Q13109251
SP r vera.cruz http://wikidata.org/entity/Q1808155 http://wikidata.org/entity/Q22066862

Além deste problema com o ataque robot, foram detectados, conforme listados abaixo, com "c" erro conceitual (ex. suspeito usa conceito de rio para "Rio das Contas" ao invés do conceito de município), e com "3o" quando havia ainda um terceiro item a ser contemplado.

state lexlabel Suspeito TalvezCorreto
BA c rio.contas http://wikidata.org/entity/Q5244330 http://wikidata.org/entity/Q1649466
MA c morros http://wikidata.org/entity/Q54050 http://wikidata.org/entity/Q301700
MA c presidente.sarney http://wikidata.org/entity/Q244997 http://wikidata.org/entity/Q2013023
SP c moncoes http://wikidata.org/entity/Q42967 http://wikidata.org/entity/Q1774484
SP 3o teodoro.sampaio http://wikidata.org/entity/Q2027342 not Q13109202 (BA), use https://www.wikidata.org/wiki/Q13109202

Adicionar CEP via array de intervalos

Intervalos SQL, por exemplo de números inteiros, são expressos por colchetes: [123,456]. A sintaxe é bem conhecida e padronizada, por exemplo seu uso no PostgreSQL como rangetypes e range functions. O mesmo vale para array of ranges.

Num arquivo CSV não há padronização para esse tipo de dado... Mas podemos criar uma sintaxe simples baseada na padronização SQL e na simplicidade, ou seja, removendo virgulas para não demandar aspas:

  • Intervalo de inteiros: [123 456]
  • Array de intervalos de inteiros: [123 456] [555 777]

A conversão de ida e volta pode ser conseguida pelas seguintes funções, no caso de inteiros:

CREATE FUNCTION csvranges_to_int4ranges(
  p_range text
) RETURNS int4range[] AS $f$
   SELECT ('{'|| 
      regexp_replace( translate($1,' -',',') , '\[(\d+),(\d+)\]', '"[\1,\2]"', 'g') 
   || '}')::int4range[];
$f$ LANGUAGE SQL IMMUTABLE;

CREATE or replace FUNCTION int4ranges_to_csvranges(
  p_range int4range[]
) RETURNS text AS $f$
   SELECT translate($1::text,',{}"',' ');
$f$ LANGUAGE SQL IMMUTABLE;

Para verificar se um valor está contido em uma array de intervalos, basta usar a função abaixo

CREATE FUNCTION checkRange(p_val int, p_range anyarray) RETURNS boolean AS $f$
     SELECT bool_or(p_val <@ r) FROM unnest(p_range) t(r);
$f$ LANGUAGE SQL IMMUTABLE;
CREATE FUNCTION checkRange(p_val bigint, p_range anyarray) RETURNS boolean AS $f$
     SELECT bool_or(p_val <@ r) FROM unnest(p_range) t(r);
$f$ LANGUAGE SQL IMMUTABLE;

Por exemplo em a consulta abaixo retorna a linha relativa ao município de são paulo,

   SELECT * FROM tmpcsv_br_city_codes 
   WHERE checkrange( 04560010, csvranges_to_int4ranges(postalcode_ranges) );

acertar o novo script

Ao rodar sh src/makeIO.sh surge erro provavelmente devido à falta da extension unaccent.
Como foi inclusa a restrição de UNIQUE("postalCode_ranges") surgiu o bug de dados a ser também corrigido, o CEP correto de Almadina/BA é "45640-000 a 45640-999".

usar versao nova do lexLabel

Sugestão de v1.1.X perdendo a compatibilidade com o (LexML 2018 ainda que não hajam registros no LexML que demandem alguma revisao).

Originalmente o LexML cometia a inconsistência de remover preposições mas preservar preposição cotraída... O que preserva os problemas de comparação de nomes e erros de digitação.

Alguns nomes como Florínea (antes Florínia) ou São Luiz do Paraitinga (antes ausente) também serão atualizados para o correto. São ao todo 48 registros com a diferença.
A nova função name2lex() já absorveu a nova convenção, resta apenas:

UPDATE io.citybr  set  "lexLabel"=name2lex(name) ;

Nomes afetados: Alta Floresta D'Oeste, Alvorada D'Oeste, Aparecida d'Oeste, Barra D'Alcântara, Conquista D'Oeste, Diamante D'Oeste, Dias d'Ávila, Espigão D'Oeste, Estrela d'Oeste, Figueirópolis D'Oeste, Florínea, Glória D'Oeste, Guarani d'Oeste, Herval d'Oeste, Itapejara d'Oeste, Itaporanga d'Ajuda, Lagoa d'Anta, Lambari D'Oeste, Machadinho D'Oeste, Mãe d'Água, Mirassol d'Oeste, Nova Brasilândia D'Oeste, Olho d'Água, Olho d'Água das Cunhãs, Olho d'Água das Flores, Olho-d'Água do Borges, Olho d'Água do Casado, Olho D'Água do Piauí, Olho d'Água Grande, Olhos-d'Água, Palmeira d'Oeste, Pau D'Arco, Pau D'Arco, Pau D'Arco do Piauí, Pérola d'Oeste, Pingo-d'Água, Rancho Alegre D'Oeste, Santa Bárbara d'Oeste, Santa Clara d'Oeste, Santa Luzia D'Oeste, Estrela d'Oeste, Figueirópolis D'Oeste, Florínea, Glória D'Oeste, Guarani d'Oeste, Herval d'Oeste, Itapejara d'Oeste, Itaporanga d'Ajuda, Lagoa d'Anta, Lambari D'Oeste, Machadinho D'Oeste, Mãe d'Água, Mirassol d'Oeste, Nova Brasilândia D'Oeste, Olho d'Água, Olho d'Água das Cunhãs, Olho d'Água das Flores, Olho-d'Água do Borges, Olho d'Água do Casado, Olho D'Água do Piauí, Olho d'Água Grande, Olhos-d'Água, Palmeira d'Oeste, Pau D'Arco, Pau D'Arco, Pau D'Arco do Piauí, Pérola d'Oeste, Pingo-d'Água, Rancho Alegre D'Oeste, Santa Bárbara d'Oeste, Santa Clara d'Oeste, Santa Luzia D'Oeste, Santa Rita d'Oeste, São Felipe D'Oeste, São João d'Aliança, São João do Pau d'Alho, São Jorge d'Oeste, São Luiz do Paraitinga, Sítio d'Abadia, Tanque d'Arca.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.