O LibPostal é uma biblioteca C para analisar/normalizar endereços de rua em todo o mundo usando PNL estatística e dados abertos. O objetivo deste projeto é entender as seqüências baseadas em localização em todos os idiomas, em todos os lugares. Para uma visão geral mais abrangente da pesquisa por trás da LibPostal, verifique as postagens (longas) introdutórias do blog:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
Os endereços e os locais que eles representam são essenciais para qualquer aplicativo que lide com mapas (pesquisa, transporte, transporte sob demanda/entrega, check-ins, revisões). No entanto, mesmo os endereços mais simples são repletos de convenções locais, abreviações e contexto, dificultando a indexação/consulta efetivamente com os mecanismos de pesquisa de texto completo tradicionais. Esta biblioteca ajuda a converter os endereços de forma livre que os humanos usam em formulários normalizados limpos adequados para comparação de máquinas e indexação de texto completo. Embora o LibPostal não seja um geocoder completo, ele pode ser usado como uma etapa de pré -processamento para tornar qualquer aplicativo de geocodificação mais inteligente, mais simples e mais consistente internacionalmente.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
A biblioteca principal é escrita em ligações de idioma puro de C. para python, ruby, go, java, php e nodejs são oficialmente suportados e é fácil escrever ligações em outros idiomas.
Se sua empresa estiver usando o LibPostal, considere pedir à sua organização que patrocine o projeto. Interpretar o que os humanos significam quando se referem a locais está longe de ser um problema resolvido, e os patrocínios nos ajudam a perseguir novas fronteiras na PNL geoespacial. Como patrocinador, o logotipo da sua empresa aparecerá com destaque na página de repositório do GitHub, juntamente com um link para o seu site. Informações sobre patrocínio
Usuários individuais também podem ajudar a oferecer suporte à pesquisa aberta geográfica, fazendo uma doação mensal:
Antes de instalar, verifique se você possui os seguintes pré -requisitos:
No Ubuntu/Debian
sudo apt-get install curl autoconf automake libtool pkg-config
Em Centos/Rhel
sudo yum install curl autoconf automake libtool pkgconfig
No Mac OSX
brew install curl autoconf automake libtool pkg-config
Então, para instalar a biblioteca C:
Se você estiver usando um M1 Mac, adicione --disable-sse2 ao comando ./configure . Isso resultará em um desempenho mais fraco, mas a construção terá sucesso.
git clone https://github.com/openvenues/libpostal
cd libpostal
./bootstrap.sh
./configure --datadir=[...some dir with a few GB of space...]
make -j4
sudo make install
# On Linux it's probably a good idea to run
sudo ldconfig
O LibPostal tem suporte para PKG-Config, para que você possa usar o PKG-Config para imprimir as bandeiras necessárias para vincular seu programa contra ele:
pkg-config --cflags libpostal # print compiler flags
pkg-config --libs libpostal # print linker flags
pkg-config --cflags --libs libpostal # print both
Por exemplo, se você escrever um programa chamado App.c, poderá compilá -lo assim:
gcc app.c `pkg-config --cflags --libs libpostal`
Msys2/mingw
Para Windows, o procedimento de construção atualmente requer MSYS2 e MINGW. Isso pode ser baixado em http://msys2.org. Siga as instruções no site do MSYS2 para instalação.
Verifique se o MSYS2 está atualizado ao executar:
pacman -Syu
Instale os seguintes pré -requisitos:
pacman -S autoconf automake curl git make libtool gcc mingw-w64-x86_64-gcc
Então, para construir a biblioteca C:
git clone https://github.com/openvenues/libpostal
cd libpostal
cp -rf windows/* ./
./bootstrap.sh
./configure --datadir=[...some dir with a few GB of space...]
make -j4
make install
Notas: Ao definir o datadir, a unidade C: seria inserida como /c . O script de compilação libpostal adiciona automaticamente libpostal no final do caminho, para que '/c' se tornasse C:libpostal no Windows.
O .dll compilado estará no src/.libs/ diretório e deve ser chamado de libpostal-1.dll .
Se você precisar de uma biblioteca de importação .lib para vincular isso ao seu aplicativo. Você pode gerar um usando a ferramenta Visual Studio lib.exe e o arquivo de definição libpostal.def :
lib.exe /def:libpostal.def /out:libpostal.lib /machine:x64
Um modelo de dados alternativo está disponível para o LibPostal. É criado pela Senzing Inc. para melhorar os endereços dos EUA, Reino Unido e Cingapura e melhorar o manuseio de endereços de rota rural dos EUA. Para ativar isso, add MODEL=senzing na linha de conigure durante a instalação:
./configure --datadir=[...some dir with a few GB of space...] MODEL=senzing
Os dados deste modelo são obtidos do OpenAddress, OpenStreetMap e dados gerados pelo Senzing com base no feedback do cliente (algumas centenas de registros), um total de cerca de 1,2 bilhão de registros de dados de mais de 230 países, em mais de 100 idiomas. Os dados do OpenStreetMap e do OpenDress são bons, mas não são perfeitos, portanto o conjunto de dados foi modificado filtrando endereços mal formados, corrigindo os tokens de endereço classificados e removendo tokens que não pertencem aos endereços, sempre que essas condições eram encontradas.
A Senzing criou um conjunto de dados de 12950 endereços de 89 países que ele usa para testar e verificar a qualidade de seus modelos. O conjunto de dados foi gerado usando endereços aleatórios do OSM, no mínimo 50 por país. Os endereços difíceis de parse foram obtidos com a equipe de apoio à Senzing e os clientes e da página LibPostal Github e adicionados a esse conjunto. O modelo senzing obteve resultados de análise 4,3% melhores que o modelo padrão, usando esse conjunto de testes.
O tamanho desse modelo é de cerca de 2,2 GB em comparação com 1,8 GB para o modelo padrão, portanto, lembre -se disso se o espaço das armazenamentos for importante.
Mais informações sobre esse modelo de dados podem ser encontradas em: https://github.com/senzing/libpostal-data se você tiver algum problema com esse modelo, se eles têm a ver com parses, instalação ou outros problemas, denuncie-os em https://github.com/senzing/libPostal-Data
O Addresser International do LibPostal usa aprendizado de máquina (campos aleatórios condicionais) e é treinado em mais de 1 bilhão de endereços em todos os países habitados da Terra. Utilizamos o OpenStreetMap e o OpenAddresses como fontes de endereços estruturados, e os modelos de formato de endereço do OpenCage em: https://github.com/opencagedata/address-formatting para construir os dados de treinamento, suplementar o conteúdo de polígonos e gerar componentes como comprovação. Também adicionamos abreviações, eliminamos componentes aleatoriamente, etc. para tornar o analisador o mais robusto possível para a entrada bagunçada do mundo real.
Esses resultados de análise de exemplo são obtidos do programa interativo endereço_parser que se constrói com o LibPostal quando você é make . Observe que o analisador pode lidar com vírgulas vs. sem vírgulas, bem como várias cartuchos e permutações de componentes (se a entrada for, por exemplo, apenas cidade ou apenas cidade/código postal).
O analisador atinge uma precisão muito alta nos dados de retirada, atualmente 99,45% corretos pares completos (o que significa 1 no numerador para obter todos os token no endereço correto).
Aqui está um exemplo da API do analisador usando as ligações do Python:
from postal . parser import parse_address
parse_address ( 'The Book Club 100-106 Leonard St Shoreditch London EC2A 4RH, United Kingdom' )E um exemplo com a API C:
#include <stdio.h>
#include <stdlib.h>
#include <libpostal/libpostal.h>
int main ( int argc , char * * argv ) {
// Setup (only called once at the beginning of your program)
if (! libpostal_setup () || ! libpostal_setup_parser ()) {
exit ( EXIT_FAILURE );
}
libpostal_address_parser_options_t options = libpostal_get_address_parser_default_options ();
libpostal_address_parser_response_t * parsed = libpostal_parse_address ( "781 Franklin Ave Crown Heights Brooklyn NYC NY 11216 USA" , options );
for ( size_t i = 0 ; i < parsed -> num_components ; i ++ ) {
printf ( "%s: %sn" , parsed -> labels [ i ], parsed -> components [ i ]);
}
// Free parse result
libpostal_address_parser_response_destroy ( parsed );
// Teardown (only called once at the end of your program)
libpostal_teardown ();
libpostal_teardown_parser ();
}O Address Parser pode tecnicamente usar os rótulos de string definidos nos dados de treinamento, mas esses são os atualmente definidos, com base nos campos definidos na biblioteca de formatação de endereços da OpenCage, bem como alguns adicionados pela LibPostal para lidar com padrões específicos:
A API expand_address converte endereços bagunçados do mundo real em equivalentes normalizados adequados para indexação de pesquisa, hash etc.
Aqui está um exemplo interativo usando a ligação do Python:
O LibPostal contém um classificador de idioma treinado por OSM para detectar quais idiomas são usados em um determinado endereço para que possa aplicar as normalizações apropriadas. A única entrada necessária é a sequência de endereço bruto. Aqui está uma pequena lista de algumas normalizações menos diretas em vários idiomas.
| Entrada | Saída (pode ser múltiplo no LibPostal) |
|---|---|
| Cento e vinte e 96th st | 120 East 96th Street |
| C/ ocho, pi 4 | Calle 8 Polígono Industrial 4 |
| V xx Settembre, 20 | Via 20 SettEmbre 20 |
| Quatre Vingt Douze R. de L'Eglise | 92 Rue de L eglise |
| л каретный р д, 4, строение 7 | você |
| л каретный р д, 4, строение 7 | ulitsa karetnyy ryad dom 4 stroyeniye 7 |
| Marktsstraße 14 | Markt Strasse 14 |
Atualmente, a LibPostal suporta esses tipos de normalizações em mais de 60 idiomas e você pode adicionar mais (sem precisar escrever nenhum C).
Para leitura adicional e alguns casos de arestas bizarros, consulte: Os programadores de falsidades acreditam sobre endereços.
Aqui está um exemplo usando as ligações do Python para sucinta (a maioria das ligações de idiomas de nível superior é semelhante):
from postal . expand import expand_address
expansions = expand_address ( 'Quatre-vingt-douze Ave des Champs-Élysées' )
assert '92 avenue des champs-elysees' in set ( expansions )O equivalente da API C é mais algumas linhas, mas ainda é bastante simples:
#include <stdio.h>
#include <stdlib.h>
#include <libpostal/libpostal.h>
int main ( int argc , char * * argv ) {
// Setup (only called once at the beginning of your program)
if (! libpostal_setup () || ! libpostal_setup_language_classifier ()) {
exit ( EXIT_FAILURE );
}
size_t num_expansions ;
libpostal_normalize_options_t options = libpostal_get_default_options ();
char * * expansions = libpostal_expand_address ( "Quatre-vingt-douze Ave des Champs-Élysées" , options , & num_expansions );
for ( size_t i = 0 ; i < num_expansions ; i ++ ) {
printf ( "%sn" , expansions [ i ]);
}
// Free expansions
libpostal_expansion_array_destroy ( expansions , num_expansions );
// Teardown (only called once at the end of your program)
libpostal_teardown ();
libpostal_teardown_language_classifier ();
}Depois de construir LibPostal:
cd src/
./libpostal "Quatre vingt douze Ave des Champs-Élysées"
Se você tiver um arquivo de texto ou fluxo com um endereço por linha, a interface da linha de comando também aceita a entrada do stdin:
cat some_file | ./libpostal --json
Depois de construir LibPostal:
cd src/
./address_parser
endereço_parser é um shell interativo. Basta digitar endereços e libpostal os analisarão e imprimirão o resultado.
O LibPostal foi projetado para ser usado por idiomas de nível superior. Se você não vê seu idioma de escolha ou se estiver escrevendo um idioma vinculativo, informe -nos!
Ligações de idiomas oficialmente apoiadas
Ligações não oficiais da linguagem
Extensões de banco de dados
API de descanso não oficial
Docker de descanso libpostal
LibPostal Zeromq Docker
O LibPostal usa o melhor para testes automatizados. Para executar os testes, use:
make check
Adicionar casos de teste é fácil, mesmo que seu C seja enferrujado/inexistente e adoraríamos contribuições. Utilizamos principalmente testes funcionais, verificando a entrada da string na saída da string.
O LibPostal também é testado periodicamente a milhões de endereços do OSM (limpo), bem como consultas anonimizadas de um geocoder de produção (não tão limpo). Durante esse processo, usamos Valgrind para verificar se há vazamentos de memória e outros erros.
O LibPostal precisa baixar alguns arquivos de dados do S3. Os arquivos básicos são representações no disco das estruturas de dados necessárias para executar a expansão. Para análise de endereço, como o treinamento do modelo leva alguns dias, publicamos o modelo totalmente treinado para o S3 e o atualizamos automaticamente à medida que novos endereços são adicionados ao OSM, OpenAddresses, etc. O mesmo vale para o modelo de classificador de idiomas.
Os arquivos de dados são baixados automaticamente quando você é executado. Para verificar e fazer o download de novos arquivos de dados, você pode executar make ou executar:
libpostal_data download all $YOUR_DATA_DIR/libpostal
E substitua $ your_data_dir por tudo o que você passou para configurar durante a instalação.
O LibPostal contém vários dicionários por língua que influenciam a expansão, o classificador do idioma e o analisador. Para explorar os dicionários ou contribuir com abreviações/frases em seu idioma, consulte Recursos/Dicionários.
No aprendizado de máquina, grandes quantidades de dados de treinamento geralmente são essenciais para obter bons resultados. Muitos projetos de aprendizado de máquina de código aberto liberam apenas o código do modelo (resultados reproduzíveis se e somente se você for Google) ou um modelo pré-cozido onde as condições de treinamento são desconhecidas.
O LibPostal é um pouco diferente porque é treinado em dados abertos que estão disponíveis para todos, por isso lançamos todo o pipeline de treinamento (o pacote geodata neste repositório), bem como os próprios dados de treinamento resultantes no arquivo da Internet. É mais de 100 GB desconfiado.
Os dados de treinamento são armazenados no Archive.org na data em que foram criados. Há também um arquivo armazenado no diretório principal deste repo chamado current_parser_training_set , que armazena a data do conjunto de treinamento criado recentemente. Para sempre apontar para os dados mais recentes, tente algo como: latest=$(cat current_parser_training_set) e use essa variável no lugar da data.
Todos os arquivos podem ser encontrados em https://archive.org/download/libpostal-parser-tring-data-yyyymmdd/$file como arquivos de valores separados por guia (TSV) Gzip'd (TSV) formatados como: languagetcountrytaddress .
Se o analisador não tiver um desempenho tão bom quanto você esperava em um tipo específico de endereço, o melhor recurso é usar o Grep/Awk para examinar os dados de treinamento e tentar determinar se há algum padrão/estilo de endereço que não está sendo capturado.
Expansão da abreviação : por exemplo, expandindo "rd" => "estrada", mas para quase qualquer idioma. A libpostal suporta> 50 idiomas e é fácil adicionar novos idiomas ou expandir os dicionários atuais. As linguagens ideográficas (não separadas pelo espaço em branco, por exemplo, chinês) são suportadas, assim como os idiomas germânicos onde os tipos de via são concatenados no final da corda e podem opcionalmente ser separados para que Rosenstraße e Rosen Straße sejam equivalentes.
Endereço Internacional Parsing : Campo aleatório condicional que analisa "123 Main Street New York New York" em {"house_number": 123, "Road": "Main Street", "City": "New York", "State": "New York"}. O analisador trabalha para uma ampla variedade de países e idiomas, não apenas nós/inglês. O modelo é treinado em mais de 1 bilhão de endereços e cordas semelhantes a endereços, usando os modelos no repositório de formatação de endereços OpenCage para construir exemplos formatados e marcados para todos os países habitados do mundo. Muitos tipos de normalizações são realizados para tornar os dados de treinamento que se assemelham à entrada de geocoder bagunçada real o mais próximo possível.
Classificação do idioma : Regressão logística multinomial treinada (usando o método FTRL-Proximal para induzir a esparsidade) em todas as maneiras OpenStreetMap, ADDR:* Tags, topoônimos e endereços formatados. Os rótulos são derivados usando testes de ponto em polígono para países do OSM e idiomas oficiais/regionais para países e limites do Admin 1, respectivamente. Assim, por exemplo, o espanhol é o idioma padrão na Espanha, mas em diferentes regiões, por exemplo, catalunia, Galiza, região basca, os respectivos idiomas regionais são o padrão. A desambiguação baseada no dicionário é empregada nos casos em que o idioma regional é não padrão, por exemplo, galês, Breton, Occitan. Os dicionários também são usados para abreviar frases canônicas como "calle" => "c/" (executado no classificador de idiomas e nos conjuntos de treinamento do analisador de endereço)
Parsing de expressão numérica ("Vinte primeiro" => 21st, "quatre-svingt-duze" => 92, novamente usando os dados fornecidos no cldr), suporta> 30 idiomas. Lida com idiomas com expressões concatenadas, por exemplo, Milleottocento => 1800. Opcionalmente normaliza algarismos romanos, independentemente do idioma (ix => 9) que ocorrem nos nomes de muitos monarcas, papas, etc.
Tokenização / Lexing rápida e precisa : Clock em> 1m Tokens / s, implementa a especificação TR-29 para a segmentação de palavras UTF8, tokeniza as línguas do leste asiático Chracter por caractere em vez de no espaço em branco.
UTF8 Normalização : opcionalmente decompõe o formulário de normalização do UTF8 para NFD, marcas de sotaques do STRIPS, por exemplo, => a e/ou aplica a transliteração latina-ascii.
Transliteração : por exemplo, você => ulica ou ulitsa. Usa todas as transformadas de CLD, exatamente os mesmos dados de origem usados pela UTI, embora o LibPostal não exija puxar toda a UTI (pode entrar em conflito com a versão do seu sistema). NOTA: Alguns idiomas, particularmente hebraico, árabe e tailandês, podem não incluir vogais e, portanto, muitas vezes não combinam com uma transliteração feita por um humano. Pode ser possível implementar transliteradores estatísticos para alguns desses idiomas.
Detecção de script : detecta qual script uma determinada string usa (pode ser múltipla por exemplo, um endereço de Hong Kong ou Macau de forma livre pode usar scripts Han e Latin no mesmo endereço). Na transliteração, podemos usar todos os transliteradores aplicáveis para um determinado script Unicode (o grego pode, por exemplo, ser transliterado com latina grega, grego-latina-bgn e grego-latina-ungegn).
O LibPostal foi criado originalmente como parte do projeto OpenVenues para resolver o problema da dedução do local. Nos pontos de abertura, temos um conjunto de dados de milhões de locais derivados de terabytes de páginas da web do rastreamento comum. O rastreamento comum é publicado mensalmente e, portanto, mesclando os resultados de dois rastreamentos produz duplicatas significativas.
A dedução é um campo relativamente bem estudado e, para documentos de texto, como páginas da web, artigos acadêmicos, etc. Existem métodos de similaridade aproximada bastante decente, como o minhash.
No entanto, para endereços físicos, o uso frequente de abreviações convencionais como Road == RD, Califórnia == CA ou Nova York == NYC complica um pouco as coisas. Mesmo usando uma técnica como o minhash, que é adequado para correspondências aproximadas e equivalente à similaridade de Jaccard de dois conjuntos, precisamos trabalhar com textos muito curtos e geralmente é o caso de dois endereços equivalentes, um abreviado e um totalmente especificado, não se aproximará muito em termos de conjunto de n-gram. Em scripts não de latina, digamos um endereço russo e seu equivalente transliterado, é concebível que dois endereços referentes ao mesmo local possam não corresponder a um único caractere.
Como um exemplo motivador, considere as duas maneiras equivalentes a seguir, de escrever um discurso de rua em Manhattan com convenções variadas e graus de verbosidade:
Obviamente '30 W 26th St FL #7! = '30 West Vigésimo Six. Plano da rua número 7 'em um sentido de comparação de cordas, mas um humano pode se divertir que esses dois endereços se referem à mesma localização física.
A LibPostal visa criar strings geográficos normalizados, analisados em componentes, de modo que possamos raciocinar com mais eficácia sobre como dois endereços realmente correspondem e tomam decisões automatizadas do lado do servidor sobre DUPEs.
Se o exposto acima parecer muito parecido com a geocodificação, isso é porque, de certa forma, apenas no caso OpenVenues, temos que geocodificar sem uma interface do usuário ou um usuário para selecionar o endereço correto em um suspensão autocompleto. Dado um banco de dados de endereços de origem, como OpenAddresses ou OpenStreetMap (ou todos os itens acima), o LibPostal pode ser usado para implementar coisas como a dedução e a geocodificação do lote do servidor em configurações como MapReduce ou Stream Processing.
Agora, em vez de tentar assar convenções específicas de endereços em mecanismos de pesquisa de documentos tradicionais, como o Elasticsearch, usando arquivos gigantes de sinônimos, scripts, analisadores personalizados, tokenizers e similares, o geocodificação pode ser assim:
Dessa forma, o LibPostal pode executar a correspondência de endereços difusos em tempo constante em relação ao tamanho do conjunto de dados.
LibPostal está escrito em C por três razões (em ordem de importância):
A portabilidade/onipresença : a libpostal tem como alvo idiomas de nível superior que as pessoas realmente usam diariamente: python, vá, rubi, nodejs, etc. A beleza de C é que praticamente qualquer linguagem de programação pode se vincular a ele e os compiladores estão em todos os lugares, por isso, para que seja uma pessoa que se separe, e você pode usar o LIBPostal. Suportamos o Mac/Linux (o Windows não é uma prioridade, mas felizes em aceitar patches), possui uma construção padrão do AutoTools e um formato de arquivo agnóstico do Endianness para os arquivos de dados. As ligações do Python são mantidas como parte desse repositório, pois são necessárias para construir os dados de treinamento.
Eficiência de memória : O LibPostal foi projetado para ser executado em uma configuração MapReduce, onde podemos estar limitados a <1 GB de RAM por processo, dependendo da configuração da máquina. Tanto quanto possível, o LibPostal usa matrizes contíguas, tentativas (construídas com matrizes contíguas), filtros de flores e matrizes esparsas compactadas para manter o uso da memória baixo. É possível usar a libpostal em um dispositivo móvel com modelos treinados em um único país ou em um punhado de países.
Desempenho : isso é o último na lista por um motivo. A maioria das otimizações no LibPostal é para uso de memória e não desempenho. LibPostal é bastante rápido, dada a quantidade de trabalho que faz. Ele pode processar 10 a 30k endereços / segundo em um único thread / processo nas plataformas que testamos (isso significa processar todos os endereços no Planet OSM em pouco mais de uma hora). Confira o programa de referência simples para testar seu ambiente e vários tipos de entrada. Na configuração do MapReduce, o desempenho por núcleo não é tão importante porque tudo está sendo feito em paralelo, mas existem alguns aplicativos de ingestão de streaming no Mapzen, onde isso precisa ser executado em processo.
O LibPostal está escrito em C99 moderno, legível e usa as seguintes convenções:
O pacote Geodata Python no repositório LibPostal contém o pipeline para pré -processamento dos vários conjuntos de dados GEO e dados de treinamento de construção para os modelos C. Este pacote não deve ser necessário para a maioria dos usuários, mas para aqueles interessados em gerar novos tipos de endereços ou melhorar os dados de treinamento da LibPostal, é para onde procurar.
Nos dados de teste retirados (o que significa que o Roteled Parses não viu antes), o analisador de endereço atinge 99,45% de precisão de análise completa.
Para algumas tarefas como o reconhecimento de entidade nomeado, é preferível usar algo como uma pontuação ou variantes de F1, principalmente porque há um problema de viés de classe (a maioria das palavras é não-entidades e um sistema que simplesmente previa a não entidade para cada token seria realmente bem em termos de precisão). Esse não é o caso da análise de endereço. Todo token tem um rótulo e há milhões de exemplos de cada classe nos dados de treinamento, portanto, a precisão é preferível, pois é uma medida de desempenho limpa, simples e intuitiva.
Aqui usamos a precisão completa da análise, o que significa que apenas damos ao analisador um "ponto" no numerador se ele obtiver cada token no endereço correto. Essa deve ser uma medida melhor do que simplesmente olhar se cada token estava correto.
Embora o analisador atual funcione muito bem para a maioria dos endereços padrão, ainda há espaço para melhorias, principalmente para garantir que os dados de treinamento que usamos sejam o mais próximo possível de endereços na natureza. Existem duas maneiras principais de o endereço que o analisador pode ser melhorado ainda mais (em ordem de dificuldade):
Relatórios de bugs, problemas e solicitações de tração são bem -vindos. Leia o guia contribuinte antes de enviar seu problema, relatório de bug ou solicitação de puxar.
Envie questões em: https://github.com/openvenues/libpostal/issues.
Agradecimentos especiais ao @benk10 pelo Build inicial do Windows e @Aeroxuk por integrá -lo perfeitamente ao projeto e configurar uma compilação de aplicativos.
O software está disponível como código aberto nos termos da licença do MIT.