Visão geral
MVTEncodeGeom— uma função escalar que projeta uma geometria no espaço de pixels local de um tile de slippy map e a recorta aos limites do tile.MVTEncode— uma função de agregação que reúne as geometrias projetadas de um grupo nos bytes binários de um tile de camada única.
MVTBoundingBox e MVTBoundingBoxMercator, retornam a caixa delimitadora de um tile para que as linhas possam ser
restritas a ela na cláusula WHERE usando um índice.
Há suporte para geometrias de ponto, linha e polígono, incluindo o tipo Geometry e os tipos geo concretos (Point,
LineString, MultiLineString, Ring, Polygon, MultiPolygon).
Os bytes resultantes formam um tile completo que pode ser retornado diretamente pela interface HTTP com FORMAT RawBLOB.
Essas funções seguem o fluxo de trabalho do PostGIS e também estão disponíveis com seus nomes do PostGIS como aliases: ST_AsMVTGeom
para MVTEncodeGeom e ST_AsMVT para MVTEncode.
MVTEncodeGeom
zoom, tile_x e tile_y, recorta-a aos limites do tile, ajusta-a à grade de pixels inteiros
e retorna a geometria no espaço do tile.
A projeção é Web Mercator em toda a faixa de coordenadas UInt32. As coordenadas retornadas têm origem no
canto superior esquerdo do tile, com o eixo y apontando para baixo, que é a convenção de coordenadas do formato Mapbox Vector
Tile, de modo que o resultado pode ser usado diretamente em MVTEncode. As coordenadas são arredondadas para pixels inteiros, portanto agrupar por
MVTEncodeGeom consolida as geometrias que caem na mesma grade em um único cluster.
Quando clip está habilitado (o padrão), a geometria é recortada ao tile expandido em buffer pixels (o intervalo
[-buffer, extent + buffer] em cada eixo); geometrias que caem totalmente fora se tornam NULL. Este é o equivalente ao
PostGIS ST_AsMVTGeom.
O tipo da geometria de saída depende da entrada: um Point retorna um Point; um LineString ou MultiLineString retorna uma
MultiLineString; um Ring, Polygon ou MultiPolygon retorna uma MultiPolygon (o recorte pode dividir uma geometria em
várias partes).
Sintaxe
geometry— Geometria em graus de longitude/latitude. A longitude é limitada a[-180, 180]e a latitude ao intervalo do Web Mercator[-85.05112878, 85.05112878].Point/LineString/MultiLineString/Ring/Polygon/MultiPolygon/Geometry.zoom— Nível de zoom do mapa Slippy, no intervalo[0, 32].UInt8.tile_x— Índice da coluna do tile, no intervalo[0, 2^zoom - 1].UInt32.tile_y— Índice da linha do tile, no intervalo[0, 2^zoom - 1].UInt32.extent— Extensão opcional do tile em pixels por lado, no intervalo[1, 2147483647]. O padrão é4096, valor padrão do Mapbox Vector Tile.UInt32.buffer— Buffer de recorte opcional em pixels, no intervalo[0, 2147483647]. O padrão é1.UInt32.clip— flag opcional; quando diferente de zero (o padrão), a geometria é recortada ao tile mais o buffer.UInt8.
NULL se ela for totalmente excluída pelo recorte. Geometry.
Exemplo
MVTEncode
MVTEncodeGeom. Cada linha de entrada se torna uma feição; há suporte para geometrias de ponto, linha e polígono.
O argumento geometry é um Geometry de coordenadas no espaço do tile, normalmente produzido por MVTEncodeGeom. Linhas cuja
geometria é NULL (por exemplo, recortadas por MVTEncodeGeom) são ignoradas. O argumento opcional properties é uma
tupla nomeada cujos nomes dos elementos se tornam as chaves de atributo da feição e cujos tipos dos elementos determinam os tipos
de valor do tile vetorial.
O resultado são os bytes brutos de um tile de camada única. Um grupo vazio produz um tile vazio. Este é o análogo de
PostGIS ST_AsMVT.
Sintaxe
layer_name— Nome da camada do tile vetorial.String.extent— Extensão do tile, em pixels por lado, no intervalo[1, 2147483647]. O padrão é4096.UInt32.feature_id_name— Nome opcional de um elemento inteiro sem sinal da tuplaproperties, emitido como oidda feição MVT (umUInt64) em vez de como um atributo. Inteiros com sinal são rejeitados. UmidNULLé omitido para essa feição. Os parâmetros são posicionais; portanto, para usarfeature_id_name, é preciso informarextent.String.stringify_unsupported— flag opcional (0/1, padrão0); quando1, tipos de propriedade sem suporte direto (por exemplo, inteiros grandes,UUID,Decimal) são codificados comostring_valuetextual em vez de gerar um erro.UInt8.
geometry— Geometria no espaço do tile, por exemplo, gerada porMVTEncodeGeom.Geometry.properties— Tupla nomeada opcional de atributos da feição. Os nomes dos elementos se tornam chaves de atributo.Tuple.
String.
Tipos de propriedade
Value do Mapbox Vector Tile correspondente ao seu tipo no ClickHouse:
Os tipos podem ser encapsulados em
Nullable e/ou LowCardinality. Um valor NULL omite esse atributo da feição, pois o
formato tile vetorial não tem valor nulo. Qualquer outro tipo de propriedade gera uma exceção, a menos que stringify_unsupported esteja definido, caso em
que ele é codificado como string_value textual.
Valores de propriedade idênticos são internados no pool compartilhado de valores da camada, de modo que um valor que aparece em muitas feições é
armazenado apenas uma vez.
Nomeando a tupla de propriedades
tuple(...) não são propagados para os nomes dos elementos da tupla,
portanto nomeie os elementos com um CAST:
Agrupamento
MVTEncodeGeom arredonda para pixels inteiros, agrupar pela
geometria do pixel mescla geometrias coincidentes; agregue o grupo em uma subconsulta e, em seguida, passe uma linha por agrupamento para
MVTEncode:
Geometry exige allow_suspicious_types_in_group_by = 1, porque o agrupamento pelo tipo Geometry
baseado em Variant é restringido por padrão. Omita o GROUP BY interno (e count()) para gerar uma feição por linha de entrada
em vez de feições agrupadas.
MVTBoundingBox
zoom, tile_x e tile_y como uma tupla
(min_lon, min_lat, max_lon, max_lat) em graus.
Use-a para restringir linhas a um tile enquanto filtra diretamente pelas colunas longitude/latitude — assim, uma chave primária ou
índice nessas colunas pode ser usado — em vez de recalcular a projeção Web Mercator para cada linha. A margin opcional
expande a caixa em todos os lados por essa fração do tamanho do tile; defina-a como buffer / extent para cobrir o buffer de recorte de
MVTEncodeGeom.
Sintaxe
zoom— Nível de zoom do mapa Slippy, no intervalo[0, 32].UInt8.tile_x— Índice da coluna do tile, no intervalo[0, 2^zoom - 1].UInt32.tile_y— Índice da linha do tile, no intervalo[0, 2^zoom - 1].UInt32.margin— Fração opcional do tamanho do tile usada para expandir a caixa em todos os lados. O padrão é0.Float64.
(min_lon, min_lat, max_lon, max_lat) em graus. Tuple(Float64, Float64, Float64, Float64).
Exemplo
MVTBoundingBoxMercator
MVTBoundingBox. Retorna a
caixa delimitadora do tile no espaço completo de coordenadas Web Mercator em UInt32, usado internamente por MVTEncodeGeom, como uma tupla
(min_x, min_y, max_x, max_y). O eixo y cresce para baixo (norte na parte superior). Destina-se a tabelas que materializam
colunas de coordenadas Mercator e criam índices sobre elas, em vez de longitude/latitude.
Sintaxe
MVTBoundingBox.
Valor retornado
Retorna a caixa delimitadora do tile como uma tupla (min_x, min_y, max_x, max_y) em coordenadas Web Mercator. Tuple(Float64, Float64, Float64, Float64).
Exemplo
Restringindo linhas a um tile
WHERE (desempenho), e o recorte feito por MVTEncodeGeom (correção).
O recorte descarta a geometria fora do tile; assim, mesmo um predicado de caixa delimitadora pouco restritivo não deixa vazar geometria de fora do tile para
o resultado.
MVTEncodeGeom. Passe clip => false (o sétimo argumento) para MVTEncodeGeom para desativar o recorte e depender
apenas do predicado WHERE.
Disponibilizando tiles via HTTP
/. Uma URL limpa
/tile/{z}/{x}/{y} é adicionada pelo operador com um handler de consulta predefinida na
configuração do servidor. A url do handler usa a forma regex: para capturar os segmentos do caminho, associá-los aos
parâmetros da consulta e retornar os bytes com FORMAT RawBLOB.
No caso mais simples, a tabela tem uma coluna Geometry e o handler retorna uma feição por linha — MVTEncodeGeom
projeta cada geometria no tile solicitado e a recorta, de modo que as linhas fora do tile são descartadas automaticamente:
shapes é uma tabela com uma coluna geom Geometry (qualquer combinação de pontos, linhas e polígonos). Um GET /tile/10/550/335
retorna o tile codificado.
Para dados de pontos, isso funciona igualmente bem com colunas simples de longitude/latitude, construindo o ponto diretamente com
MVTEncodeGeom((lon, lat)::Point, …). Para agrupar feições coincidentes ou adicionar um pré-filtro de caixa delimitadora com uso de índice
em tabelas grandes, estenda a consulta interna como mostrado em Clustering e
Restricting rows to a tile.
Limitações
-
A projeção Web Mercator limita a latitude a
±85.05112878°e não lida com entradas que cruzam o antimeridiano. -
O recorte de polígonos não garante uma saída MVT válida. O recorte corrige a orientação e o fechamento dos anéis, mas não as autointerseções. Portanto, um anel autointersectante (“gravata-borboleta”) não é reparado: dependendo de como ele intersecta o tile, ele é emitido sem alterações (ainda inválido) ou descartado como
NULL. Por exemplo, uma gravata-borboleta inteiramente dentro do tile é descartada, enquanto os mesmos quatro cantos, organizados como um anel simples, são mantidos:
- Geometry é recortada antes de ser arredondada para a grade de pixels inteiros. O PostGIS primeiro ajusta a geometria à grade de pixels inteiros e depois a recorta;
MVTEncodeGeomprimeiro recorta (nas coordenadas projetadas de ponto flutuante) e depois arredonda. Perto da borda de um tile, isso pode descartar uma coordenada que, de outra forma, seria arredondada para o pixel da borda. Por exemplo, combuffer = 0, um ponto logo a leste da borda do tile é recortado, embora seja arredondado para o pixel da borda4096, que uma abordagem que arredonda primeiro manteria: