2 402
edições
Sem resumo de edição |
|||
(2 revisões intermediárias pelo mesmo usuário não estão sendo mostradas) | |||
Linha 119: | Linha 119: | ||
A degeneração geométrica, de quadrado para retângulo, é relativa ao segundo argumento de <code>vbit_interleave(x,y)</code>. Como a função é sempre chamada com a mesma ordem dos argumentos, sempre teremos ou só retangulos orizontais (XY) ou só verticais (YX). | A degeneração geométrica, de quadrado para retângulo, é relativa ao segundo argumento de <code>vbit_interleave(x,y)</code>. Como a função é sempre chamada com a mesma ordem dos argumentos, sempre teremos ou só retangulos orizontais (XY) ou só verticais (YX). | ||
=== Otimização do cálculo de cobertura === | |||
Ver [[osmc:Metodologia/Algoritmo_SQL#Tratamento_das_configurações|Tratamento das configurações]] onde já foi discutido e solucionado o tema. Aqui retomando para questões de otimização. | |||
A definição nacional, no caso do Brasil é | |||
grid_l0_cell: 40 41 42 43 30 31 32 33 34 21 22 23 11 12 13 02 44 24 | |||
grid_l0_cell_idx: 0 1 2 3 4 5 6 7 8 9 a b c d e fT fP fN | |||
A entrada é o ponto ''pt'' na projeção do Brasil, ou seja, com coordenadas planas ''x'' e ''y''. O primeiro passo é obter as coordenadas ''ij0'' do ponto na cobertura. | |||
O tamanho de célula ''s0'' da cobertura nacional é o ''default'' em <code>ij0=grid_br.xyS_collapseTo_ijS(x,y)</code>. Alternativamente uma cadeia de ''IF''s (árvore de decisão BBOX) pode nos fornecer rapidamente o valor. O que é mais rápido, depende de ''benchmark'' em cada linguagem (C ou SQL). | |||
Como ij0 é um caso muito especial de ''ij'' podemos obter o seu valor num formato mais conveniente, por exemplo usando 3 bits (0=000, 1=001, 2=010, 3=011, 4=100, 5=101) e concatenando os valores de ''i'' e ''j'': 40=b'100000'=32 41=b'100001'=33 42=b'100010'=34 ... 13=b'001011'=11 02=b'000010'=2 44=b'100100'=36 24=b'010100'=20. <!-- | |||
select varbit_to_int(b'100000') as "40", varbit_to_int(b'100001') as "41", | |||
varbit_to_int(b'100010') as "42", varbit_to_int(b'001011') as "13", | |||
varbit_to_int(b'000010') as "02", varbit_to_int(b'100100') as "44"; | |||
40 | 41 | 42 | 13 | 02 | 44 | |||
----+----+----+----+----+---- | |||
32 | 33 | 34 | 11 | 2 | 36 | |||
--> Resulta numa array esparsa de 40 posições. Teremos: | |||
* coordenadas iniciais ''x0'' e ''y0'' dadas por ''arrays'' <code>x0_from_ij0</code> e <code>x0_from_ij0</code>. | |||
* índice cbits0 dado por ''array'' <code>cbits0_from_ij0</code>. | |||
Por fim as 'arrays'' podem ser "hardcoded" nas funções usuárias, otimizando a obtenção dos valores desejado. | |||
=== Algoritmo e funções finais de resolução === | === Algoritmo e funções finais de resolução === | ||
Algoritmo principal: | Algoritmo principal, tendo como entradas: ''pt'' e nível ''L''. Ponto ''pt'' em coordenadas planas, portanto ''x'' e ''y''. | ||
# Célula da cobertura nacional: | |||
#* <code>ij0=grid_br.xyS_collapseTo_ijS(x,y);</code> com ''s0'' é default, ou função otimizada. | |||
# <code>ij0=grid_br.xyS_collapseTo_ijS(x,y); | #* <code>x0=x0_from_ij0[ij0]; y0=y0_from_ij0[ij0];</code> ou função de ij0 retorando xy0. | ||
# <code> | #* <code>cbits0 = grid_br.IJ0_to_vbitL0( ij0, false )</code> | ||
# <code>cbits = cbits0 || ints_to_interleavedbits( | # Código ''cbits'' e geometria da célula do nível ''L'': | ||
#* <code>ijL=grid_br.xyL_collapseTo_ijL(x-xy0[1], y-xy0[2], L);</code> | |||
#* <code>cbits = cbits0 || ints_to_interleavedbits(ijL)</code> | |||
#* <code>grid_br.xyS_draw_anycell( grid_br.ijL_to_xyL(ijL) )</code> | |||
Com um passo a mais para contemplar os casos de pontos sobre cobertura fantasma. Existe uma condição de validade e um ajuste do ponto ao nível: | |||
:<code>SE lenght(cbits0)>4 e level_desejado<1.5 THEN NULL; ELSE recalcula xy0 dentro da célula.</code> | :<code>SE lenght(cbits0)>4 e level_desejado<1.5 THEN NULL; ELSE recalcula xy0 dentro da célula especial.</code> | ||
<syntaxhighlight lang="sql" style="font-size: 80%;"> | <syntaxhighlight lang="sql" style="font-size: 80%;"> | ||
drop FUNCTION if exists grid_br.xyS_to_cbits(int,int,int,boolean) | drop FUNCTION if exists grid_br.xyS_to_cbits(int,int,int,boolean) | ||
; | ; | ||
-- | -- revisar se é YX! | ||
CREATE FUNCTION grid_br.xyS_to_cbits( | CREATE FUNCTION grid_br.xyS_to_cbits( | ||
y int, | y int, | ||
Linha 143: | Linha 170: | ||
-- falta conferir se lenght(cbits0)>4 AND s<3 | -- falta conferir se lenght(cbits0)>4 AND s<3 | ||
SELECT CASE WHEN use_country_prefix THEN b'0001001100' ELSE b'' END | SELECT CASE WHEN use_country_prefix THEN b'0001001100' ELSE b'' END | ||
|| cbits0 || ints_to_interleavedbits(x-xy0[1], y-xy0[2], | || cbits0 || ints_to_interleavedbits( grid_br.xyS_collapseTo_ijL(x-xy0[1], y-xy0[2], S) ) | ||
FROM ( | FROM ( | ||
SELECT grid_br.ijS_to_xySref(ij0) as xy0, grid_br.IJ0_to_L0(ij0,false) as cbits0 | SELECT grid_br.ijS_to_xySref(ij0) as xy0, grid_br.IJ0_to_L0(ij0,false) as cbits0 |
edições