osmc:Metodologia/Algoritmo SQL/Lib: mudanças entre as edições

Linha 128: Linha 128:
   grid_l0_cell_idx: 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  fT fP fN
   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.
A entrada é o ponto ''pt''=(''x'',''y''). O primeiro passo é obter as coordenadas ''ij0'' de ''pt'' na cobertura. Temos          dois possíveis algoritmos:


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).
* A função discretizadora <code>ijL0=grid_br.xyS_collapseTo_ijL(x,y)</code>, onde o tamanho de célula ''s0'' é o ''default''.  


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. <!--
* Uma árvore de decisão com 4 nívieis de ''IF''s (análogo a índice BBOX) pode nos fornecer rapidamente o valor ''ijL0''.
 
O que é mais rápido, depende de ''benchmark'' na linguagem adotada (C ou SQL). Por hora ficamos com o primeiro algoritmo.
 
Como ''ijL0'' é um caso muito especial de ''ij'' podemos obter o seu valor num formato mais conveniente. Exemplos:
* <code>ij0 := i::text||j::text</code> poderia usar um objeto JSONb como array associativa, mas não é tão rápido quanto array SQL. Seria algo hardcoded numa função, <code>('{"40":[123,456,"0"],"41":[0,1,"1"],"13":[22,33,"e"]}'::jsonb)->ij0</code>.
 
* <code>i*10+j</code> resulta em array de 44 posições. Seriam ''arrays'' leves; e delas, a partir de  ''ij0'', teremos:
** coordenadas iniciais ''x0'' e ''y0'', por arrays <code>x0_from_ij0</code> e <code>x0_from_ij0</code>; 
** índice ''cbits0'', pela array <code>cbits0_from_ij0</code>.
<!--
* usando 3 bits (0=000, 1=001, 2=010, 3=011, 4=100) 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.
Resulta numa array esparsa de 36 posições. 
select varbit_to_int(b'100000') as "40", varbit_to_int(b'100001') as "41",  
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'100010') as "42", varbit_to_int(b'001011') as "13",
Linha 139: Linha 151:
----+----+----+----+----+----
----+----+----+----+----+----
  32 | 33 | 34 | 11 |  2 | 36
  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>.
Por fim as ''arrays'' podem ser "hardcoded" nas funções usuárias, otimizando a obtenção dos valores desejado.
* í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.
Lembrar que para [https://stackoverflow.com/a/25997497/287948 obter a array the uma multiarray] não é simples em SQL, exemplo de obtenção do indice ''i'': <code>SELECT array(select unnest( ('{{1,2,3},{4,5,6},{7,8,9}}'::int[][])[i:i] ));</code>
Lembrar que para [https://stackoverflow.com/a/25997497/287948 obter a array the uma multiarray] não é simples em SQL, exemplo de obtenção do indice ''i'': <code>SELECT array(select unnest( ('{{1,2,3},{4,5,6},{7,8,9}}'::int[][])[i:i] ));</code>


2 402

edições