OpenStreetMap Part Medium: Visualização de Dados Ocultos

Todos nós estamos acostumados a olhar para os substratos de base clássicos na Internet, ver os assentamentos, estradas e seus nomes, casas com seu número. Mas mesmo esses objetos de propriedade têm mais do que apenas um nome ou número. Para edifícios, este é um número de andares, para estradas há várias faixas e, para cidades, vários habitantes. Mas esta é apenas a ponta do iceberg - o OpenStreetMap é tão rico em uma variedade de dados espaciais que você simplesmente nunca viu alguns deles. E sem renderizações especializadas, você nunca verá, a menos que esteja interessado em editar quais dados são essa linha com tags estranhas. Hoje faremos uma renderização ultra-especializada para mostrar bairros florestais.


Bairros da floresta


Etapa 1. Pesquisas.
É claro que você pode adivinhar com o dedo no céu como eles podem ser indicados, mas é mais seguro ir para o wiki-osm. E aí podemos encontrar o seguinte: boundary = forest_compartment


Portanto, os blocos florestais são designados por polígonos com a marca boundary=forest_compartment . É verdade que há um esclarecimento de que inicialmente ele foi designado como boundary=forestry_compartment , mas era menos alfabetizado. E como o número de usos com a designação antiga é significativo (de acordo com o taginfo cerca de 4 mil vezes), não o descontaremos.


Etapa 2. Dados.
Pegue os dados da Geofabrik . Faça o download de um arquivo para toda a Rússia - russia-latest.osm.pbf . Usando osmconvert obtemos os dados no formato o5m para a filtragem subsequente.


 osmconvert russia-latest.osm.pbf -o=russia-latest.o5m 

Agora filtramos apenas os dados que precisamos com o osmfilter


 osmfilter russia-latest.o5m --keep="boundary=forest_compartment =forestry_compartment" -o=forest_compartment-local.o5m 

Etapa 3. Vector telhas.
Um pouco de teoria breve. A abordagem antiga é solicitar alguns dados de um banco de dados grande, obter uma imagem deles, salvá-los para entregá-los ao cliente no futuro. No novo, em um banco de dados grande, solicite um pouco de dados e salve-o para transmissão subsequente ao cliente. E deixe o cliente transformá-los em uma imagem. Lucro, por assim dizer, no rosto - transferimos o ônus de renderizar a imagem para os ombros do cliente. Das desvantagens - na cafeteira, talvez você não consiga ver o mapa, você precisa de suporte WebGL.


E assim o Mapbox propôs um formato para blocos vetoriais e um contêiner para eles na forma de um banco de dados sqlite. Portanto, agora não é uma dispersão de arquivos em pastas, mas um arquivo solitário puro. Um bloco vetorial contém camadas lógicas (casas, estradas etc.) que consistem em geometria e atributos.


Aqui vamos prepará-los para nossos bairros florestais. Vou usar a ferramenta TileMaker . Ele recebe dados OSM no formato pbf como entrada, portanto, após a filtragem, precisamos converter novamente para esse formato.


 osmconvert forest_compartment-local.o5m -o=forest_compartment-local.pbf 

Agora precisamos explicar ao TileMaker quais camadas e com quais atributos precisamos, de acordo com a documentação .


Etapa 4. Camadas?
E de que camadas precisamos? E isso depende do que mostramos. I.e. Antes de tudo, devemos de alguma forma imaginar a parte visual. E como isso pode ser alcançado a partir dos dados disponíveis. A partir dos dados do OSM, temos uma grade de polígonos e seus atributos. Os atributos têm o nome da silvicultura e o número do trimestre.


Dados brutos do OSM


A partir disso, a maneira mais fácil é exibir o trimestre e assiná-lo com seu número. I.e. precisamos de uma camada de polígono, no centro do polígono exibiremos uma inscrição com seu número.
E então o primeiro recurso dos blocos de vetor é exibido. Quando um polígono de origem grande cai em blocos diferentes, apenas suas partes caem nos blocos. E ao renderizar, são dois polígonos diferentes, respectivamente, para eles, haverá duas assinaturas no centro de suas metades.



Portanto, para blocos vetoriais, é preparada uma camada separada com inscrições, quando ainda há todas as informações necessárias sobre a geometria.


Conclusão: precisamos de duas camadas, polígono para preenchimento e ponto para assinatura. Crie o arquivo config.json .


 { "layers": { }, "settings": { "minzoom": 11, "maxzoom": 11, "basezoom": 14, "include_ids": false, "author": "freeExec", "name": "Forest Compartment RUS", "license": "ODbL 1.0", "version": "0.1", "description": "Forest compartment from OpenStreetMap", "compress": "gzip", "metadata": { "attribution": "<a href=\"http://www.openstreetmap.org/copyright/\" target=\"_blank\">&copy;  OpenStreetMap</a>", "json": { "vector_layers": [ ] } } } } 

Na seção de camadas, especifique o que precisamos


  "layers": { "forest_compartment": { "minzoom": 11, "maxzoom": 11 }, "forest_compartment_label": { "minzoom": 11, "maxzoom": 11 } }, 

Os nomes das camadas são indicados e em que escala os mostraremos.


  "json": { "vector_layers": [ { "id": "forest_compartment", "description": "Compartment", "fields": {}}, { "id": "forest_compartment_label", "description": "Compartment", "fields": {"ref":"String"}} ] } 

Nos metadados, informamos ao visualizador futuro quais atributos estão disponíveis conosco. Para a camada de tags, teremos o número do trimestre na ref .


Etapa 5. Processamento de Dados.
Para esse fim, é usado um script na linguagem lua , que decide quais objetos dos dados OSM precisamos, em qual camada os enviar e com quais atributos.


Vamos começar com o modelo de arquivo process.lua .


 -- Nodes will only be processed if one of these keys is present node_keys = { } -- Initialize Lua logic function init_function() end -- Finalize Lua logic() function exit_function() end -- Assign nodes to a layer, and set attributes, based on OSM tags function node_function(node) end -- Similarly for ways function way_function(way) end 

O que temos aqui:


node_keys - existem muitos pontos nos dados do OSM; se cada um deles cutucar esse script, o processamento levará muito tempo. Este é um filtro que nos diz em quais pontos principais estamos interessados.


função node_function (node) - a função será chamada em todos os pontos interessantes para nós do parágrafo anterior. Aqui devemos decidir o que fazer com isso.


function way_function (way) - uma função que será chamada em qualquer linha e nas relações com os tipos multipolígono e de limite, porque eles são considerados objetos reais.


Começamos a escrever código. Antes de tudo, indicamos quais pontos precisamos:


 node_keys = { "boundary" } 

Agora escrevemos a função para processá-los:


 function node_function(node) local boundary = node:Find("boundary") if boundary == "forestry_compartment" or boundary == "forest_compartment" then local ref = node:Find("ref") if ref ~= "" then node:Layer("forest_compartment_label", false) node:Attribute("ref", ref) end end end 

O que acontece aqui: lemos o valor da chave de boundary através do node:Find("") . Se esse for forest_compartment , leia o número do trimestre na tag ref . Se não estiver vazio, esse objeto será adicionado à nossa camada com rótulos, através da Layer("_", ___) . No atributo da camada ref , salvamos o número do quarto.
Quase tão simples para blocos quadrados:


 function way_function(way) local boundary = way:Find("boundary") if way:IsClosed() and ( boundary == "forestry_compartment" or boundary == "forest_compartment" ) then way:Layer("forest_compartment", true) way:AttributeNumeric("nomerge", way:Id()) local ref = way:Find("ref") if ref ~= "" then way:LayerAsCentroid("forest_compartment_label", false) way:Attribute("ref", ref) end end end 

Aqui também verificamos se a linha está fechada, porque acontece que as tags estão presentes simplesmente em segmentos. Vale ressaltar que a camada forest_compartment area (portanto, o segundo argumento para a função Layer("", true)) , e substituímos o local por assinatura como o centro da LayerAsCentroid .


Também vale a pena prestar atenção no atributo que estamos adicionando, embora não o tenhamos especificado no config - nomerge . É necessário derrotar outro recurso, desta vez já o conversor TileMaker (embora o parâmetro para desativá-lo tenha aparecido na nova versão).


A peculiaridade é que, para otimização, quando existem muitos objetos com os mesmos atributos em uma camada, o conversor para eles combina as geometrias em uma. Por exemplo, temos uma rua que consiste em três segmentos separados, que, como resultado, serão enviados três vezes para renderizar. Isso é mais longo, em comparação com o fato de enviarmos um objeto à renderização, mas com uma geometria um pouco mais complexa (unindo todos eles).


No nosso caso, todos os quartos adjacentes seriam unidos em um polígono grande, mas não precisamos disso. Portanto, adicionamos o número do objeto para que sejam diferentes e não combinados.


Agora é hora de iniciar o processo de criação de blocos vetoriais.


 tilemaker forest_compartment-local.pbf --output forest_compartment-local.mbtiles 

Como resultado, devemos ter o arquivo forest_compartment-local.mbtiles


Etapa 6. Crie um estilo.
Criamos uma conta no mapbox.com . No Mapbox Studio, na seção Tileset, crie um novo tileet arrastando o arquivo criado anteriormente para a janela de download. Dentro de um minuto, ele deve ser processado e adicionado à lista.


Agora vamos para a seção Estilos e criamos um novo com base na luz finalizada, para que possamos ver os principais elementos do mapa, como estradas, assentamentos etc. Partimos para Cheboksary porque foram vistos blocos florestais.


Descemos para o nível 11 da escala (criamos apenas peças para ele) e clicamos no botão Adicionar camada. Na guia fonte de dados, encontramos nossa fonte de dados forest_compartment-local-XXXXX , onde selecionamos a camada de polígono. Deve ser destacado em verde à direita.


Adicionar camada


Em seguida, na guia estilo, defina a cor de preenchimento para verde e o traçado para marrom.


Ajuste de cor


Agora resta adicionar a assinatura. Adicione uma nova camada, só que desta vez selecionamos forest_compartment_label nos dados e selecionamos o symbol tipo, os números devem aparecer à direita.


Adicione camada de etiqueta.


Na guia estilo, especifique que precisamos exibir nosso atributo ref .


Atributo para assinatura


É assim que é, clique no lado direito da tela de publicação e podemos compartilhar o link para que outros possam ver nossa criação. MAS a exibição de cartões não é gratuita, como em outros lugares, por isso não darei o meu link para não cair no efeito habr.


PS: Talvez em um artigo adicional eu lhe conte como consegui a localização da assinatura com o nome da silvicultura em um grupo de blocos incluídos nela.

Source: https://habr.com/ru/post/pt441296/


All Articles