
Na primavera, adicionamos o recurso "Geocodificação reversa" à API DaData.ru, também chamada de "
Endereço por coordenadas ". O nome sugere: o método pega geocoordenadas e fornece dados sobre o endereço.
Um produto sólido com a mesma funcionalidade oferece o Yandex - é chamado de
geocoder . Mas o serviço Yandex é gratuito apenas para projetos não comerciais abertos. A tarifa padrão - de 120.000 ₽ por ano - não é adequada para todos.
Nós pensamos - se você fizer uma alternativa gratuita ou barata ao "Geocoder", os desenvolvedores provavelmente agradecerão. E eles fizeram. No artigo, mostrarei como a estrutura "Endereço por coordenadas" funciona: como configuramos a pesquisa, reunimos um diretório e o empacotamos em um método pronto.
Onde obtemos os dados e como procuramos o endereço
Ao abordar a tarefa, estudamos soluções prontas: onde obter o diretório de coordenadas com endereços e como procurar objetos geográficos nesse diretório. Aconteceu que você nem precisa ir muito longe pelas ferramentas certas.
Pegamos os objetos de endereço no FIAS -
Federal Information Address System . Este é o mais abrangente dos diretórios de endereços abertos e oficiais.
Já escrevemos sobre isso em detalhes em
Habré , e agora quatro fatos são importantes:
- O FIAS armazena todos os objetos endereçáveis do país, de regiões e abaixo - a edifícios e territórios adicionais;
- o diretório está disponível gratuitamente nos formatos DBF e XML;
- O FIAS não é perfeito - falta dezenas de milhares de casas e muitas ruas, especialmente novas;
- Cada objeto de endereço no diretório corresponde a um código ID - FIAS exclusivo. Às vezes, o código do objeto é alterado, mas para o nosso artigo isso não é tão importante.
Objetos de endereço baixados do FIAS juntamente com o ID são a base do nosso diretório para geocodificação reversa.
Faça o download das coordenadas do OpenStreetMap (OSM). OSM é um projeto com uma licença gratuita: entusiastas coletam as coordenadas de vários objetos e as publicam para todos.
Em termos simples, o OSM é um conjunto de pontos, linhas e polígonos em um mapa. Cada objeto tem sua própria descrição, tipo e conjunto de coordenadas. Os dados do OSM para a Rússia estão localizados em
needgeo.com ,
osm.sbin.ru/osm_dump/ e
osmosis.svimik.com/latest/ .
A lista de fontes é publicada em uma página especial no “Wiki” do projetoO descarregamento consiste em arquivos PBF - esse formato é usado em vez de XML como um formato mais compacto. Transformar PBF em XML OSM não custa nada,
muitos utilitários aprovados pela comunidade podem lidar com isso.
Para nosso próprio diretório, pegamos os objetos de endereço do FIAS e, em seguida, procuramos suas coordenadas no OSM. Se encontrado, salve os dados combinados. Acontece uma interseção entre FIAS e OSM.
E tudo isso é maravilhoso, mas há um problema: as coisas não são fáceis com a qualidade dos dados no OSM. As coordenadas dos objetos geralmente não correspondem à realidade. Por exemplo, polígonos para regiões e distritos são adequados. Mas para cidades e abaixo - nem tanto.
Polígonos são polígonos que delimitam áreas em um mapa. Eles consistem em um conjunto de pontos vinculados com coordenadas. Os polígonos indicam os limites de regiões, distritos, cidades e até edifíciosO trabalho principal, e por uma ampla margem, é coletar dados adequados do OSM e eliminar o casamento. A tarefa é tão volumosa que dediquei uma seção separada a ela no artigo.
Também baixamos casas que não estão no FIAS do OSM. Como eu disse acima, existem dezenas de milhares de casas no FIAS. Isso nem é um problema, mas simplesmente uma realidade, um pano de fundo. Portanto, reabastecemos nosso diretório com casas do OSM. Mas apenas aqueles para os quais existe uma rua no FIAS. Os edifícios que vieram do OSM não têm um ID FIAS, portanto, identificamos-os como o
código FIAS dos
pais + número da casa .
No diretório que procuramos, com a ajuda da bela Lucene - nossa assistente de longo prazo. Obrigado pela dica, a um indiano versado que escreveu o post
Indexando dados geográficos com Lucene (uma boa adição é o material
Anúncio espacial em algoritmos de pesquisa espacial - sobre as árvores-kd nas quais o
algoritmo de pesquisa é construído).
Assim que descobrimos sobre Lucene, o problema de pesquisa foi resolvido quase por si só. Restos de negócios - escolha uma lixa.
- Carregamos no Lucene seu diretório de coordenadas e endereços, obtivemos um índice de pesquisa. Para facilitar, quase tudo foi removido, deixando apenas os IDs de endereço e coordenadas.
- Montamos uma pesquisa por índice: entrada - coordenadas, saída - ID dos objetos de endereço encontrados. A pesquisa não retorna outras informações, pois o índice foi totalmente reduzido.
- Satisfez a emissão, carregando dados do FIAS "grande" pelos IDs encontrados. Adicionamos muito de tudo, desde o endereço que todos precisam em uma linha até o sinal da capital regional das cidades.
- Nós descobrimos como classificar e fornecer os objetos recebidos.
Até agora, tudo parece simples, mas isso é apenas uma pequena parte do trabalho. Nenhuma pesquisa pelo endereço por coordenadas teria funcionado se não tivéssemos compilado um diretório decente.
Como coletar a base de coordenadas e endereços
Para começar, vou arrumar a bagagem: depois de ler o artigo, rapidamente fazer um manual desse tipo não funciona. Nós o colecionamos desde 2014, complementando-o constantemente. Eu vou falar sobre esse maldito longo caminho.
A parte mais difícil ao compilar um diretório é classificar as coordenadas que vieram do OSM. No início, as verificamos da melhor maneira possível, inclusive com as mãos. O objetivo principal era obter pontos de referência nas grandes cidades e fazer deles um guia de referência. Agora que existem muitos desses pontos, quase não há necessidade de verificar manualmente se há novos dados. Por vez, adicionamos 200.000 a 300.000 endereços com coordenadas ao diretório de referência, e aqui está como o fazemos.
Formamos endereços completos de tags OSM. Nos uploads do OSM, as partes componentes dos endereços são espalhadas por diferentes tags:
- endereço: cidade - vila Bulatnikovo ;
- endereço: rua - rua central ;
- addr: housenumber - 103 .
Percorremos as etiquetas e coletamos o endereço completo delas:
vila Bulatnikovo, 103 Central Street .
Executamos cada novo endereço por meio da API de padronização Dadat . O serviço converte endereços em um único formato "Like in FIAS":
- corrige erros de digitação;
- decodifica abreviações como "NiNo" e "Msk";
- altera nomes antigos para novos;
- encontra a cidade ausente no endereço por índice;
- define um código FIAS.
Os endereços da API estão limpos, embora agora eles estejam enviando uma carta ou um pacote.
Armazenamos casas, ruas e assentamentos padronizados como um ponto. Para a rua e a vila, este ponto é o centro. Como resultado, todos os objetos de endereço estão na mesma tabela, dentro - o endereço, ID do FIAS, latitude e longitude.
Analisamos endereços que o Dadata não padronizou. Os endereços que não puderam ser correspondidos com o FIAS estão marcados com um sinalizador pelo serviço. Nós os verificamos manualmente, existem várias opções.
- O endereço não veio nas tags de upload adequadas do OSM, mas o diabo sabe onde. Etiquetas de endereço preenchidas e não preenchidas, cidade na rua e muito mais.
- No OSM, encontra-se um objeto exótico, como um playground, campo de futebol da faculdade ou mesmo um cemitério. Não existe nada parecido no FIAS e, para nossos propósitos, esses resultados não são adequados. Tais objetos são simplesmente filtrados.
- Um erro - e não um erro. Por exemplo, um distrito de uma cidade que não existe no FIAS veio do OSM. Ou no OSM, o objeto está localizado em um assentamento, mas no FIAS esse assentamento foi anexado à cidade e removido. Em seguida, finalizamos o algoritmo para os dados carregados e os executamos novamente.
Analisar descarga, e aí - confusão em tagsVerificamos quão adequadas são as coordenadas carregadas. Para fazer isso, examinamos com um utilitário especial se as coordenadas do novo objeto se enquadram no polígono da região ou distrito pai. Se o endereço informar que o objeto está localizado na região de Omsk, tenha a gentileza de entrar no aterro. A entrada na cidade não é necessária - nem todas as cidades são cobertas com precisão no OSM; para muitos, os dados não são atualizados.
Carregamos polígonos de referência do OSM e os armazenamos como estão - no formato
GeoJSON . Para escolher qual polígono tentar em um ponto, procure em uma tabela separada. Nele, comparamos os prefixos dos códigos CLADR e os IDs dos polígonos: você encontra o código CLADR para o endereço e vê qual polígono escolher.
O código KLADR é um identificador exclusivo usado antes do FIAS. Um milhão de serviços pode encontrar esse código para um endereçoO utilitário permite que o objeto fique a 1.700 metros do aterro. Essa regra foi adicionada por causa das rodovias que frequentemente ultrapassam as fronteiras da região. Mas uma distância superior a 1.700 metros é um sinal de erro, dizem as estatísticas.
Neste caso para cidades e ruas, a verificação termina.
Mais uma vez, mais rigorosamente, verificamos as coordenadas carregadas das casas. O utilitário mencionado novamente entra em jogo, e é isso que ele faz.
- Ele pega o endereço da nova casa e encontra vizinhos para ele no diretório de referência.
- Segundo as coordenadas, considera a distância entre a nova casa não verificada e os vizinhos confiáveis.
É fácil encontrar vizinhos: 1. Tomamos uma nova casa e encontramos o ID do FIAS dos pais. 2. Selecionamos no diretório de referência casas cujos pais têm o mesmo ID FIASA inspeção é realizada apenas em casa, a menos de 150 metros de colegas confiáveis. Além disso, consideramos cada nova casa aprovada ao analisar o seguinte. Aqui está como isso funciona.
Suponha que, no guia de referência, as casas
nºs 1, 2 e 3 sejam armazenadas
na rua Kommunarov . Nos novos dados vieram as casas
5, 6 e 7 na mesma rua. A julgar pelas coordenadas, as novas casas estão próximas. O utilitário vê que o
número da casa
5 fica ao lado dos
números 1, 2 e 3 e o adiciona ao diretório de referência. Assim, as casas
número 6 e 7 também
estão sendo testadas.
E então o destino dos dados que vieram do OSM é decidido:
- casas que passaram nas duas verificações: para aterros e para vizinhos, adicionamos ao diretório de referência;
- se o objeto não cair no polígono, os novos dados não serão adequados. O mesmo se a distância entre a casa e os vizinhos for muito grande;
- casas que não têm vizinhos, estamos adiando. Eles estão em um banco de dados separado, um dia iremos analisar.
Dividimos os objetos testados em duas partes. Eles irão para diferentes placas do nosso manual de referência.
Na primeira tabela - todos os objetos com FIAS ID para casas: regiões, assentamentos, ruas. No segundo - em casa e um link para o pai da primeira tabelaSão necessárias duas tabelas para atribuir chaves às residências ausentes do FIAS. Eles não têm seu próprio código FIAS, então veja como:
- coletamos objetos de endereço para a casa em uma tabela, cada um deles com seu próprio código FIAS;
- no segundo - apenas em casa, enquanto se refere ao pai na primeira tabela.
Como resultado de um edifício sem um código FIAS, identificamos o
ID pai + número da casa pela chave
FIAS .
A referência está pronta, resta testar. Executamos um serviço de teste funcional durante a noite e testamos o desempenho. Verificamos a velocidade em Moscou, solicitando todas as casas em um raio de três quilômetros. Para ter certeza. Claro, eles cobriram tudo com autotestes.
O principal após a atualização é não piorar.
Geocodificação reversa através dos olhos do usuário
O método de entrada usa três parâmetros: coordenadas, número de resultados e raio da pesquisa. O raio padrão é 100 metros, o máximo é um quilômetro. O valor exato é definido nas configurações.
curl -X POST \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "Authorization: Token ${API_KEY}" \ -d '{ "lat": 55.878, "lon": 37.653, "radius_meters": 50 }' \ https:
O método retorna os objetos encontrados: casas, ruas e assentamentos. Classifica-os em ordem decrescente de precisão.
- Em casa
- As ruas.
- Assentamentos.
- Cidades
Então ele classifica novamente - pela distância das coordenadas fornecidas. Se o método encontrou quatro casas e uma rua, as casas ficarão primeiro na ordem da distância de um determinado ponto. Atrás deles é a rua.
Depois de todos esses castelos, o método finalmente retorna os objetos que encontrou.
{ "suggestions": [ { "value": " , , 11", "unrestricted_value": " , , 11", "data": {...} }, { "value": " , , 11", "unrestricted_value": " , , 11", "data": {...} } ] }
Dentro - muitas coisas diferentes sobre os objetos encontrados: linhas com o endereço completo e abreviado, nomes atuais e desatualizados, CEP, código FIAS do objeto pai e assim por diante.
Todos os dados que o método fornece estão na documentaçãoA cobertura por coordenadas para diferentes regiões é diferente, assim com casas:
- Moscou - 96%,
- São Petersburgo - 88%,
- outras milhões de cidades - 74%,
- o resto da Rússia é de 47%.
E aqui está - cobrindo as ruas:
- Moscovo - 92%
- São Petersburgo - 79%,
- outras cidades milionárias - 75%,
- o resto da Rússia é de 67%.
Eles não consideravam as cidades - na escala da Rússia, até o fato de pertencer ao orgulhoso título da cidade era instável. Por exemplo, a
região de Yaroslavl, distrito de Poshekhonsky, s / o Fedorkovsky é uma cidade, de acordo com o diretório oficial do FIAS. Mas, de fato, e no endereço - o distrito rural. Fisicamente, o distrito rural se assemelha à união de várias aldeias em uma grande mancha. É difícil não apenas determinar o centro, mas até encontrar o assentamento no mapa.
Já estamos pensando no que adicionar ao método: permita a filtragem por tipo de objeto, retorne a distância a um determinado ponto, outra coisa. Monitoramos a demanda e decidimos se devemos investir.
Caso contrário, tudo já está no prod. Até 10.000 solicitações por dia - gratuitamente, mais - por assinatura, a partir de 5.000 ₽ por ano. Se você precisar de endereços por coordenadas para um projeto comercial e o geocoder for muito caro, tente
a API do Dadati .
O artigo original é publicado no blog HFLabs .