Comparação de nomes de ruas OSM x CNEFE

Pessoal,

Usando os dados fornecidos pelo Hermann Pfeifer, fiz um programa em Python pra encontrar ruas com nomes parecidos no CNEFE a partir dos nomes de rua no OSM. O objetivo é ter uma segunda fonte de dados com que comparar.

Mas só cuidado: CNEFE pode estar errado. A idéia é ajudar o mapeador a orientar o seu trabalho, começando por coisas que estão provavelmente erradas. Como é um algoritmo de comparação, ele acaba mostrando também onde o CNEFE está provavelmente errado.

Eu acabei fazendo o seguinte programa em Python:


import Levenshtein
import csv
import sys

filtro_cidades = False
cidades = set([4314902])
arq_saida = 'comparacao_ruas_osm_cnefe.txt'

ruas_cidade_cnefe = {}
comparacao = []

cnefe_file = open('municipio_cep_RUA_CNEFE.txt')
for cidade, cep, rua in csv.reader(cnefe_file, dialect="excel-tab"):
	cidade = int(cidade)
	if cidade not in ruas_cidade_cnefe:
		ruas_cidade_cnefe[cidade] = set([rua])
	else:
		ruas_cidade_cnefe[cidade].add(rua)

print 'Comparando...'
osm_file = open('municipio_rua_RUA_OSM.txt')
for cidade, x, rua_osm in csv.reader(osm_file, dialect="excel-tab"):
	cidade = int(cidade)
	if not filtro_cidades or cidade in cidades:
		menor_distancia = 100000
		opcoes_cnefe = set([])
		for rua_cnefe in ruas_cidade_cnefe[cidade]:	
			distancia = Levenshtein.distance(rua_osm, rua_cnefe)
			if distancia < menor_distancia:
				menor_distancia = distancia
				opcoes_cnefe = set([ rua_cnefe ])
			if distancia == menor_distancia:
				opcoes_cnefe.add(rua_cnefe)
		if menor_distancia > 0:
			comparacao.append( (cidade, menor_distancia, len(opcoes_cnefe), rua_osm, sorted(opcoes_cnefe)) )
			sys.stdout.write('!')
		else:
			sys.stdout.write('.')

print

comparacao.sort()

comparacao_file = open(arq_saida, 'w')
for item in comparacao:
	saida = '\nCidade: {0}\nDist.:  {1}\nOSM:    {2}\n'.format(item[0], item[1], item[3])	
	comparacao_file.write(saida)
	for opcao in item[4]:
		saida = 'CNEFE:  {0}\n'.format(opcao)		
		comparacao_file.write(saida)

comparacao_file.close()

Vou começar com uma autocrítica:

  • foi feito às pressas, então nem pensei em parametrizações (era pra ver se a idéia daria certo e seria útil)
  • o algoritmo é O(n²), o que quer dizer que tem o potencial pra ser muito lento; na prática, roda pros dados do RS em menos de 1 minuto no meu PC

Os dados são ordenados por:

  • cidade; depois
  • distância (do nome num cadastro para o nome no outro); depois
  • número de opções com mesma distância; depois
  • nome da rua

O resultado fica interessante para revisão dos erros. Eis o início do trecho da saída relativo a Porto Alegre:


Cidade: 4314902
Dist.:  1
OSM:    ACESSO 3 A
CNEFE:  ACESSO 3A

Cidade: 4314902
Dist.:  1
OSM:    ACESSO B 4
CNEFE:  ACESSO B4

Cidade: 4314902
Dist.:  1
OSM:    ACESSO DOS FLAMBOYANT
CNEFE:  ACESSO DOS FLAMBOYANS

Cidade: 4314902
Dist.:  1
OSM:    ACESSO POYAMA
CNEFE:  ACESSO TOYAMA

Cidade: 4314902
Dist.:  1
OSM:    AVENIDA ALTOS DO SANTA RITA
CNEFE:  AVENIDA ALTOS DE SANTA RITA

Nessa parte tem um looooongo trecho com pequenos erros ortográficos fáceis de corrigir. Um pouco mais adiante começam a aparecer coisas assim:


Cidade: 4314902
Dist.:  1
OSM:    BECO 2 B
CNEFE:  BECO 2B
CNEFE:  BECO 4 B

Cidade: 4314902
Dist.:  1
OSM:    RUA 2 DE FEVEREIRO
CNEFE:  RUA 25 DE FEVEREIRO
CNEFE:  RUA 6 DE FEVEREIRO

Cidade: 4314902
Dist.:  1
OSM:    RUA 2066
CNEFE:  RUA 2006
CNEFE:  RUA 2096

Cidade: 4314902
Dist.:  1
OSM:    RUA 2067
CNEFE:  RUA 2007
CNEFE:  RUA 2017

Cidade: 4314902
Dist.:  1
OSM:    RUA 3 A
CNEFE:  RUA 1 A
CNEFE:  RUA 2 A

Cidade: 4314902
Dist.:  1
OSM:    RUA 5029
CNEFE:  RUA 5027
CNEFE:  RUA 7029

Hm pelo visto o OSM tem coisas que o CNEFE não tem. Desnecessário desmerecer um ou outro, o CNEFE tem uma lista muito maior de nomes, mas potencialmente desatualizados, como aqui:


Cidade: 4314902
Dist.:  5
OSM:    AVENIDA DA SERRARIA
CNEFE:  ESTRADA DA SERRARIA

De fato, como moro perto, sei que o lugar deixou de se chamar “estrada” faz algum tempo, o que sugere que o CNEFE tem alguns anos de idade na minha região.

Quanto maior a distância do nome de um cadastro para o outro, maior a chance de encontrar coisas desse tipo:


Cidade: 4314902
Dist.:  8
OSM:    ESTRADA MORRO AGUDO
CNEFE:  ESTRADA ARACAJU
CNEFE:  ESTRADA CAMPO NOVO
CNEFE:  ESTRADA CANTA GALO
CNEFE:  ESTRADA COSTA GAMA
CNEFE:  ESTRADA DO ESPIGAO
CNEFE:  ESTRADA DO RINCAO
CNEFE:  ESTRADA DOS ALPES
CNEFE:  ESTRADA JOAO ANTONIO
CNEFE:  ESTRADA JOAO PASSUELO
CNEFE:  ESTRADA MARIA ALTINA
CNEFE:  ESTRADA SERRARIA
CNEFE:  RUA MORRO ALTO

Aqui, o revisor teria que descobrir se o CNEFE simplesmente não conhece a estrada Morro Agudo, ou se é um erro no OSM. Não tem jeito, tem que buscar outras fontes, como dados da prefeitura, outros mapas, etc. Como isso dá muito trabalho, uma sugestão pra organizar o trabalho é:

  • baixar o arquivo das diferenças
  • extrair dele uma cópia da cidade com que se quer trabalhar (é um conjunto sequencial de registros, só precisa encontrar o primeiro e o último)
  • ir removendo dele os problemas que já foram tratados (os casos fáceis) e ir deixando pra depois os difíceis

Dá até pra fazer isso diretamente com o wiki, caso tenha mais de uma pessoa trabalhando nessa informação.

Mesmo nos casos aparentemente mais simples, é bom usar informações confiáveis (não só um simples dicionário ou a intuição) pra confirmar qual dos nomes é o mais correto. Afinal, foi usando a intuição que os cadastros acabaram errados. Em último caso, o que vale é o nome na placa.

A comparação completa para o RS se encontra aqui.

Atualizando com um critério mais inteligente de ordenação (que prioriza nomes de ruas longos com distâncias pequenas, onde há mais chance de ser só um pequeno erro ortográfico):


import Levenshtein
import csv
import sys

filtro_cidades = False
cidades = set([4314902])
arq_saida = 'comparacao_ruas_osm_cnefe.txt'

ruas_cidade_cnefe = {}
comparacao = []

cnefe_file = open('municipio_cep_RUA_CNEFE.txt')
for cidade, cep, rua in csv.reader(cnefe_file, dialect="excel-tab"):
	cidade = int(cidade)
	if cidade not in ruas_cidade_cnefe:
		ruas_cidade_cnefe[cidade] = set([rua])
	else:
		ruas_cidade_cnefe[cidade].add(rua)

print 'Comparando...'
osm_file = open('municipio_rua_RUA_OSM.txt')
for cidade, x, rua_osm in csv.reader(osm_file, dialect="excel-tab"):
	cidade = int(cidade)
	if not filtro_cidades or cidade in cidades:
		menor_distancia = 100000
		opcoes_cnefe = set([])
		for rua_cnefe in ruas_cidade_cnefe[cidade]:	
			distancia = Levenshtein.distance(rua_osm, rua_cnefe)
			if distancia < menor_distancia:
				menor_distancia = distancia
				opcoes_cnefe = set([ rua_cnefe ])
			if distancia == menor_distancia:
				opcoes_cnefe.add(rua_cnefe)
		if menor_distancia > 0:
			comparacao.append( (cidade, float(menor_distancia) / float(len(rua_osm)), menor_distancia, len(opcoes_cnefe), rua_osm, sorted(opcoes_cnefe)) )
			sys.stdout.write('!')
		else:
			sys.stdout.write('.')

print

comparacao.sort()

comparacao_file = open(arq_saida, 'w')
for item in comparacao:
	saida = '\nCidade: {0}\nDist.:  {1}\nOSM:    {2}\n'.format(item[0], item[2], item[4])
	comparacao_file.write(saida)
	for opcao in item[5]:
		saida = 'CNEFE:  {0}\n'.format(opcao)		
		comparacao_file.write(saida)

comparacao_file.close()

Ainda não atualizei na fonte acima (posso fazer sob solicitação). Antes, acho mais interessante comparar com os primeiros resultados que o novo critério traz:


Cidade: 4314902
Dist.:  1
OSM:    RUA PROFESSORA LUIZINHA WIEDMANN BORGES FORTES
CNEFE:  RUA PROFESSORA LUIZINHA WILDMANN BORGES FORTES

Cidade: 4314902
Dist.:  1
OSM:    AVENIDA CORONEL GASTAO HASSLOCHER MAZERON
CNEFE:  AVENIDA CORONEL GASTAO HASLOCHER MAZERON

Cidade: 4314902
Dist.:  1
OSM:    AVENIDA VEREADOR ROBERTO LANDELL DE MOURA
CNEFE:  AVENIDA VEREADOR ROBERTO LANDEL DE MOURA

Cidade: 4314902
Dist.:  1
OSM:    RUA MARECHAL FRANCISCO ANTONIO BITENCOURT
CNEFE:  RUA MARECHAL FRANCISCO ANTONIO BITTENCOURT

Cidade: 4314902
Dist.:  1
OSM:    RUA MAJOR PM ANTONIO POMPILO DA FONSECA
CNEFE:  RUA MAJOR PM ANTONIO POMPILIO DA FONSECA

Cidade: 4314902
Dist.:  1
OSM:    RUA ENGENHEIRO ALBERTO HENRIQUE KRUSE
CNEFE:  RUA ENGENHEIRO ALBERTO HENRIQUE KRUS

Cidade: 4314902
Dist.:  1
OSM:    RUA PROFESSORA CECY CORDEIRO THOFEHRM
CNEFE:  RUA PROFESSORA CECY CORDEIRO THOFEHRN

Cidade: 4314902
Dist.:  1
OSM:    RUA OSORIO TUYUTY DE OLIVEIRA FREITAS
CNEFE:  RUA OSORIO TUIUTY DE OLIVEIRA FREITAS
CNEFE:  RUA OSORIO TUYUTI DE OLIVEIRA FREITAS

É também uma longa lista de casos assim, até que começam a aparecer coisas do tipo:


Cidade: 4314902
Dist.:  1
OSM:    TRAVESSA ITAPERUNA
CNEFE:  TRAVESSIA ITAPERUNA

Cidade: 4314902
Dist.:  1
OSM:    RUA 2 DE FEVEREIRO
CNEFE:  RUA 25 DE FEVEREIRO
CNEFE:  RUA 6 DE FEVEREIRO

Cidade: 4314902
Dist.:  1
OSM:    RUA 19 DE SETEMBRO
CNEFE:  RUA 1 DE SETEMBRO
CNEFE:  RUA 13 DE SETEMBRO
CNEFE:  RUA 18 DE SETEMBRO

Cidade: 4314902
Dist.:  1
OSM:    RUA 1O DE SETEMBRO
CNEFE:  RUA 1 DE SETEMBRO
CNEFE:  RUA 13 DE SETEMBRO
CNEFE:  RUA 18 DE SETEMBRO

Só lá pela metade que aparecem os primeiros casos complicados:


Cidade: 4314902
Dist.:  3
OSM:    RUA MARTIM FERREIRA DE CARVALHO
CNEFE:  RUA MARTIM FERREIRA CARVALHO

Cidade: 4314902
Dist.:  1
OSM:    ACESSO 3 A
CNEFE:  ACESSO 3A

Cidade: 4314902
Dist.:  1
OSM:    ACESSO B 4
CNEFE:  ACESSO B4

Cidade: 4314902
Dist.:  1
OSM:    RUA BECO 3
CNEFE:  RUA BECO E

Cidade: 4314902
Dist.:  1
OSM:    RUA BECO C
CNEFE:  RUA BECO E

Cidade: 4314902
Dist.:  1
OSM:    RUA BECO D
CNEFE:  RUA BECO E

Cidade: 4314902
Dist.:  1
OSM:    RUA DAKOTA
CNEFE:  RUA DACOTA

Cidade: 4314902
Dist.:  1
OSM:    RUA RIVERA
CNEFE:  RUA RIVEIRA

Cidade: 4314902
Dist.:  1
OSM:    ACESSO B 3
CNEFE:  ACESSO B3
CNEFE:  ACESSO I 3

Cidade: 4314902
Dist.:  1
OSM:    ACESSO B 7
CNEFE:  ACESSO B7
CNEFE:  ACESSO P 7

Cidade: 4314902
Dist.:  1
OSM:    ACESSO H M
CNEFE:  ACESSO H 1
CNEFE:  ACESSO H 2

Cidade: 4314902
Dist.:  1
OSM:    ACESSO B 1
CNEFE:  ACESSO B1
CNEFE:  ACESSO F 1
CNEFE:  ACESSO G 1
CNEFE:  ACESSO H 1
CNEFE:  ACESSO I 1
CNEFE:  ACESSO M 1
CNEFE:  ACESSO N 1
CNEFE:  ACESSO Q 1

Mais pro final, eles começam a se alternar com casos fáceis, como aqui:


Cidade: 4314902
Dist.:  8
OSM:    AVENIDA CORONEL PEDRO AUGUSTO BITTENCOURT
CNEFE:  AVENIDA CORONEL PEDRO BITTENCOURT

Cidade: 4314902
Dist.:  1
OSM:    BECOS
CNEFE:  BECO S

Cidade: 4314902
Dist.:  1
OSM:    RUA W
CNEFE:  RUA 1
CNEFE:  RUA 2
CNEFE:  RUA 3
CNEFE:  RUA 4
CNEFE:  RUA 5
CNEFE:  RUA 6
CNEFE:  RUA 7
CNEFE:  RUA 8
CNEFE:  RUA 9
CNEFE:  RUA A
CNEFE:  RUA B
CNEFE:  RUA C
CNEFE:  RUA D
CNEFE:  RUA E
CNEFE:  RUA F
CNEFE:  RUA G
CNEFE:  RUA H
CNEFE:  RUA I
CNEFE:  RUA J
CNEFE:  RUA K
CNEFE:  RUA L
CNEFE:  RUA M
CNEFE:  RUA N
CNEFE:  RUA O
CNEFE:  RUA P
CNEFE:  RUA Q
CNEFE:  RUA R
CNEFE:  RUA S
CNEFE:  RUA T
CNEFE:  RUA U
CNEFE:  RUA V
CNEFE:  RUA X
CNEFE:  RUA Y
CNEFE:  RUA Z

Conclusão: há prós e contras nas duas formas de ordenar o resultado. A abordagem anterior tende a agrupar erros parecidos (como a falta de 1 letra), mas alternando grupos parecidos (como onde o nome é curto, numérico, e só tem 1 número mesmo - como “rua 1”). A nova abordagem traz pro começo nomes com maior probabilidade de conserto fácil, ao custo de quebrar o quase-agrupamento (talvez mais natural pro revisor) da abordagem anterior.

Eu sugiro que você encaminhe isso como projeto no GitHub, usando branches distintos. Se ainda não sabe usar git, dicas encontradas em “Descobrindo os passos para contribuir com CSS” podem lhe ajudar a aprender.

Provavelmente, se houvesse espaço para isso, eu submeteria pull request de um parsing completo modelando os endereços em objetos, segundo as especificações encontradas no Layout.zip.

Calma, nem sabemos se alguém vai se interessar nessa abordagem. :stuck_out_tongue:

Se for pro GitHub, eu ainda faria o seguinte:

  • parametrizar o script (tratar de argumentos na linha de comando; é fácil, mas eu só estou fazendo brainstorming)
  • desenvolver de uma forma tal que permita comparar quaisquer dois cadastros (podemos achar outros interessantes no futuro)
  • cuidar pra que funcione igualmente bem em Windows e em Linux

Outra: se você quiser, pode colocar no GitHub e começar a trabalhar nessas coisas. Não tem direitos autorais, nem precisa mencionar o autor. :smiley:

Fernando, eu sei que várias pessoas discordam da maneira que estou propondo “publicar software livre” (imaturo). Eu estou propondo colocar a “semente” no GitHub. O crescimento do projeto seria gerenciado todo por lá, nos branches e nas issues, com a facilidade dos diffs visuais, etc. O trabalho distribuído e articulado, conversado, de quem se interessasse, seja lá por qual aspecto do projeto, iria naturalmente enriquecendo o projeto. As próprias instruções sobre o funcionamento em Windows e Linux seriam encontradas através de alguma(s) issue(s). Mas essa “semente” já teria uma licença declarada, claro.

  • Issue 1: “Parametrizar o script”

  • Issue 2: “Desenvolver uma forma de comparar quaisquer dois cadastros”

  • Issue 3: “Breve manual de utilização para Windows”

  • Issue 4: “Breve manual de utilização para Linux”

  • Issue 5: “Parsing de endereços orientado a objetos”

Mas eu não tenho interesse de estar à frente desse projeto. Por isso não o coloco lá no GitHub.

Olha, entre simplesmente copiar um trecho de código no fórum e perguntar se há interesse no resultado, e fazer tudo isso que você sugere (que me custaria talvez mais tempo do que me custou desenvolver o próprio script), eu prefiro a primeira opção. :smiley: Vou pra segunda quando sentir que há interesse. Mas obrigado pela boa intenção, vou te consultar caso a idéia dê frutos. :smiley:

E se eu fizer, e depois de implantando no Github, com as issues 1, 4 e 5 closed (resolvidas), eu transferir para você, você aceitará? Se sim, qual seria a licença?

Aceitaria sim, mas faz diferença com quem fica? (…)

A licença será a mais próxima que eu encontrar de “domínio público” (ou “public domain”). Talvez uma Unlicense. Eu realmente nem pensei a respeito (tipo, tô quase gastando mais tempo discutindo sobre isso do que gastei pra escrever e depurar o código - que me custou só uns 20 minutos).

Mas há um problema: os primeiros commits ficariam autorados por mim.

Sim, faz diferença. Eu estou dizendo que me afastaria do comprometimento com o projeto. A não ser que eu visse novas oportunidades de submeter pull requests ou responder issues, você não me veria mais por lá. Você ficaria o dono definitivo do repositório, o contato principal, o gerente, o responsável, e quem decide.

Por favor, se você continuar com o aceite após esta minha mensagem, diga-me a licença. Eu devo começar com ela.

Alexandre, obrigado pela disposição, mas por que não deixar o código fora do GitHub então? Já anunciei na lista que está aqui, o Google vai encontrá-lo. O canal não importa, o que importa é o conhecimento sobre o método.

Se eu quisesse ser o dono do código ou ganhar algo com ele, não seria prudente divulgá-lo, não importa por qual veículo.

Mesmo que eu fosse o gerente do projeto no GitHub, poderia simplesmente ignorar tentativas de interação (como acontece em tantos outros projetos lá). Ou seja, no fim das contas, se eu não estivesse com tempo para administrar, tanto faz colocar no GitHub ou não. A diferença maior é se outras pessoas têm acesso ao código - e pra isso, tanto faz o GitHub ou o fórum.

(Agora sim estou gastanto mais tempo com essa discussão do que fazendo o script. :P)

Mas caso ainda ache que deve, eis a licença (que é uma não-licença :P): http://unlicense.org/

Nesse caso, eu me preocupo muito pouco com a licença porque é um programa muito simples (e pouco pensado). O único “pulo do gato” realmente é usar a distância de Levenshtein, mas sob uma licença restritiva bastaria mudar o algoritmo pra qualquer outro parecido (existem vários) para que a licença já não tivesse mais efeito. Além disso, o algoritmo não resolve o problema automaticamente: ele simplesmente produz uma saída mais útil ao processo de revisão manual.

Quando eu falo “dono” nesse contexto, não é no sentido de “privatizar” o código. Mas no sentido do projeto ter uma orientação. Para ele ter, é necessário ao menos uma pessoa. Ela também viabiliza o ponto de encontro dos interessados em expandir o projeto.

Quando eu me preocupo em comentar sobre a autoria dos commits, não é, nesse contexto, sobre você ter exclusividade de utilização do código ou coisa que o valha. É preocupação com o devido crédito autoral. Você teve a iniciativa de programar essas linhas. Dispendeu tempo nisso. Seria muito chato se todo mundo ficasse achando que o mérito foi do alexandre-mbm por causa da assinatura nos commits.

Sobre esse tempo que estamos “gastando”. Pelo contrário, é um dos poucos casos em que me vejo “investindo” tempo na cadeira. Eu entendo que estamos tendo uma conversa importante. Tanto para esclarecer sobre nossas pessoas (e registrar isso) como para possivelmente influenciarmos as opiniões ideológicas um do outro. Está me parecendo que você está achando que estou trazendo um espírito de software privativo. Eu estou tentando lhe dizer que não, mas que me preocupo com alguns dos direitos autorais. É injusto um “Marcos” sair por aí dizendo — ou deixando as pessoas inferirem erroneamente e quase inevitavelmente — que foi ele o criador do kernel Linux. Todos sabemos que foi o Linus…

O software pode crescer. Por isso eu me preocupo com a licença. Parece que você está olhando somente para o que já está criado, e não para o que será ou pode ser ainda criado. Como quero ser apenas um colaborador, vou tentar seguir sua linha de licenciamento também para algum módulo (outra funcionalidade) que eu venha a escrever. Apesar de eu ter muita vontade de pensar melhor o licenciamento do software que eu publico. Pode ser que lhe incomode ter o parsing dos arquivos em outra licença no mesmo repositório, não é?

Mas eu estou lendo sobre a unlicense e entendendo seu espírito de economia de tempo… apesar de não concordar com ele no geral, posso aceitá-lo em alguns casos.

Bem, nesse caso, vamos pruma licença BSD ou MIT ou algo do gênero.

Eu só não pensei na licença ainda porque estamos em fase de brainstorm, e nessa fase eu não quero interromper o fluxo das idéias pra aprender a usar o Git :D. Que aliás, até já sei usar, 95%. :stuck_out_tongue:

Por exemplo, já estou programando outra alteração a partir do feedback que está vindo da talk-br.

Entendo e compreendo suas motivações.

Eu li brevemente MIT License, BSD licenses e ISC license. Faz parte de leituras que eu já tinha feito no decorrer de anos mas que precisam sempre ser refrescadas.

No contexto em que estamos, simpatizei com University of Illinois/NCSA Open Source License e mais ainda com a simplicidade (que, é verdade, pode ser problemática, mas vamos lá) da Expat License. Resumindo: esta é permissiva mas pede um “respeito” ao aviso de copyright nos fontes.

Também cheguei novamente à página “Various Licenses and Comments about Them” da Free Software Foundation e, só para constar: lá eu tive um olhar especial para a Expat License (#Expat) seguida da Apache License, Version 2.0 (#apache2) — proteção contra patentes é algo que valorizo.

Em geral, sinto falta de uma proibição à propaganda com os nomes dos autores. Mas vamos de Expat License?

Consigo imaginar que essa conversa está perto de lhe aborrecer ou já lhe aborreceu. Mas, se você parar para pensar, verá que ela é importante. Quer dizer… eu espero que isso aconteça :wink: Estou torcendo por isso! :smiley:

Não que eu esteja aborrecido, Alexandre, mas é que acho cedo demais pra se preocupar com isso. Se eu fizer amanhã ou depois de amanhã (quando o brainstorm já estiver mais finalizado), será bem melhor (pra mim).

Eu acho interessante o aspecto de “versionar” controladamente as ideias (implementações). Fique a vontade. Não vou mais lhe atrapalhar, então.

Além das outras possibilidades de expansão já citadas, quero lembrar a todos os interessados a existência da Consulta da base de CEP dos Correios.

A propósito, Fernando. Ontem mesmo eu conheci awnist/distance (Coffeescript). Ele é UNLICENSED. Suponho que seria o tipo de projeto no qual você estava pensando. Como eu não estou ocupado com as linhas código, fico a imaginar o crescimento disso que você começou no sentido das aplicações concretas ao OpenStreetMap. Na minha opinião, seria melhor a comunidade tender a ter UM único ponto de reunião de esforços, se estes esforços podem ser somados para alcançar um mesmo resultado lá na frente.

Olá, post muito interessante. Estou com idéias parecidas de cruzar o CNEFE e o OSM. Como não é exatamente a mesma coisa, abri em um outro tópico:
http://forum.openstreetmap.org/viewtopic.php?pid=409082#p409082
talvez te interesse