2 544
edições
m (→Seletor de jurisdição e L0: nota tecnica para aplicativos locais) |
m (→Tratamento das configurações: fT fP fN) |
||
(10 revisões intermediárias por 2 usuários não estão sendo mostradas) | |||
Linha 12: | Linha 12: | ||
Os parâmetros principais do YAML da Colômbia, por exemplo, são: | Os parâmetros principais do YAML da Colômbia, por exemplo, são: | ||
<pre> | <pre> | ||
dngsCode_definition: | |||
srid: 102022 | srid: 102022 | ||
grid_xy_origin: 3678500 970000 | grid_xy_origin: 3678500 970000 | ||
Linha 19: | Linha 19: | ||
grid_l0_cell_idxb16: 8 a 1 3 9 b 4 6 c e 5 7 d 0 2 f | grid_l0_cell_idxb16: 8 a 1 3 9 b 4 6 c e 5 7 d 0 2 f | ||
</pre> | </pre> | ||
onde [https://postgis.net/docs/using_postgis_dbmanagement.html#spatial_ref_sys ''srid''] é a projeção igual-area do país; ''grid_xy_origin'' é a origem no plano projetado; ''grid_cell_side'' é o tamanho (potência de 2) da célula ''L0'' adotada; ''grid_l0_cell'' a lista de coordenadas ''ij'' da matriz de células, indicando aquelas selecionados para a cobertura; | onde: | ||
* [https://postgis.net/docs/using_postgis_dbmanagement.html#spatial_ref_sys ''srid''] é a projeção igual-area do país; | |||
* ''grid_xy_origin'': é a origem no plano projetado; | |||
* ''grid_cell_side'': é o tamanho (potência de 2) da célula ''L0'' adotada; | |||
* ''grid_l0_cell'': a lista de coordenadas ''ij'' da matriz de células, indicando aquelas selecionados para a cobertura; | |||
* ''grid_l0_cell_idxb16'': a sua correspondente indexação, já expressa em base16. | |||
A parametrização YAML poderia ser lida diretamente do arquivo (pendente implementar essa estratégia); todavia, atualmente, seus parâmetros | A parametrização YAML poderia ser lida diretamente do arquivo (pendente implementar essa estratégia); todavia, atualmente, seus parâmetros estão embutidos na função wrapper <code>[https://github.com/osm-codes/GGeohash/blob/main/src/step04def-ini.sql#L67-L82 osmc.L0cover_upsert]</code>. | ||
A configuração é efetivada pela chamada com o país específico, por exemplo Brasil <code>SELECT osmc.L0cover_upsert('BR');</code> | A configuração é efetivada pela chamada com o país específico, por exemplo Brasil <code>SELECT osmc.L0cover_upsert('BR');</code> | ||
A função <code>L0_upsert()</code> atualiza a tabela ''osmc.coverage'' com linhas ''is_country'' e sem popular as colunas ''cindex'', ''is_overlay'' ou ''kx_prefix'' (utilizadas apenas por coberturas municipais). A tabela abaixo, gerada pelo relatório ''v001_osmc_coverage_l0_list'' apresentado em seguida, ilustra os casos típicos do Brasil, Camarões e Colômbia: | A função <code>osmc.L0_upsert()</code> atualiza a tabela ''osmc.coverage'' com linhas ''is_country'' e sem popular as colunas ''cindex'', ''is_overlay'' ou ''kx_prefix'' (utilizadas apenas por coberturas municipais). A tabela abaixo, gerada pelo relatório ''osmc_report.v001_osmc_coverage_l0_list'' apresentado em seguida, ilustra os casos típicos do Brasil, Camarões e Colômbia: | ||
{| class="wikitable" | {| class="wikitable" | ||
! pais !! is_contained !! cbits !! b16 !! area_km2 | ! pais !! is_contained !! cbits !! b16 !! area_km2 | ||
|- | |- | ||
| BR = | | BR = 1 = 00000001 || f || 00000001.00000000 || 00 || 275241 | ||
|- | |- | ||
| BR = | | BR = 1 = 00000001 || f || 00000001.00000001 || 01 || 757637 | ||
|- | |- | ||
| BR = | | BR = 1 = 00000001 || f || 00000001.00000010 || 02 || 645014 | ||
|- | |- | ||
| | | ... | ||
|- | |- | ||
|. | | BR = 1 = 00000001 || f || 00000001.00010000 || 10 || 1519 | ||
|- | |- | ||
| BR = | | BR = 1 = 00000001 || f || 00000001.00010001 || 11 || 3618 | ||
|- | |- | ||
| BR = | | BR = 1 = 00000001 || t || 00000001.00000110 || 06 || 1099512 | ||
|- | |- | ||
| | | CM = 3 = 00000011 || f || 00000011.0001 || 1 || 16259 | ||
|- | |- | ||
| | | CM = 3 = 00000011 || f || 00000011.0010 || 2 || 1261 | ||
|- | |- | ||
| CM = | | CM = 3 = 00000011 || f || 00000011.0011 || 3 || 43764 | ||
|- | |- | ||
| | | ... | ||
|- | |- | ||
| CM = | | CM = 3 = 00000011 || f || 00000011.1110 || e || 49039 | ||
|- | |- | ||
|. | | CM = 3 = 00000011 || f || 00000011.1111 || f || 14919 | ||
|- | |- | ||
| CM = | | CM = 3 = 00000011 || t || 00000011.1010 || a || 68719 | ||
|- | |- | ||
| | | CO = 2 = 00000010 || f || 00000010.0000 || 0 || 8083 | ||
|- | |- | ||
| CO = | | CO = 2 = 00000010 || f || 00000010.0001 || 1 || 230987 | ||
|- | |- | ||
| CO = | | CO = 2 = 00000010 || f || 00000010.0010 || 2 || 57590 | ||
|- | |- | ||
| | | ... | ||
|- | |- | ||
|. | | CO = 2 = 00000010 || f || 00000010.1101 || d || 196017 | ||
|- | |- | ||
| CO = | | CO = 2 = 00000010 || f || 00000010.1110 || e || 84471 | ||
|- | |- | ||
| CO = | | CO = 2 = 00000010 || f || 00000010.1111 || f || 61264 | ||
|} | |} | ||
Linha 79: | Linha 81: | ||
A coluna ''cbits'' é composta de duas partes, o código do país e o código da sua célula ''L0''. O código é traduzido em hexadecimal (base16) na coluna ''b16'', e suas células formam a cobertura do país, ou seja, a grade de nível zero. Nos [[osmc:Convenções/Grade científica multifinalitária|geocódigos de notação científica]] apare cerão sempre como primeiro dígito. | A coluna ''cbits'' é composta de duas partes, o código do país e o código da sua célula ''L0''. O código é traduzido em hexadecimal (base16) na coluna ''b16'', e suas células formam a cobertura do país, ou seja, a grade de nível zero. Nos [[osmc:Convenções/Grade científica multifinalitária|geocódigos de notação científica]] apare cerão sempre como primeiro dígito. | ||
Os códigos de | Os códigos dos países são números inteiros de 8 bits (atualmente, sem compromisso com códigos ISO de 10 bits), garantindo melhor ocupação nos 57 bits (56 bits para acomodar 14 dígitos hexadecimais) disponíveis de geocódigo [[Código_Natural/Representação_interna#hInt|hInt64]] (essa representação alternativa é mais eficiente e versátil do que o tipo de dado ''varbit'' (bit string) do PostgreSQL. | ||
A interseção da geometria da célula com o polígono do país tem a sua área indicada pela coluna ''area_km2''. A coluna ''is_contained'' é um flag, verdadeiro quando a célula | A interseção da geometria da célula com o polígono do país tem a sua área indicada pela coluna ''area_km2''. A coluna ''is_contained'' é um flag, verdadeiro quando a célula está contida no polígono do país. Ver [[osmc:Metodologia/Algoritmo_SQL/Issues#Issue_02_-_Função_estimadora_de_cobertura_interior_e_quadrado_envolvente|Issue 02 para detalhes sobre a dedução do caso cheio pela área]]. | ||
<syntaxhighlight lang="sql"> | <syntaxhighlight lang="sql"> | ||
Linha 117: | Linha 119: | ||
O valor ''cbits_l0'' é o identificador de célula ''L0'' do país correto, e o identificador de país é seu prefixo. A partir do ponto ''pt'' (com geometria já no SRID do país) e ''cbits_l0'' obtemos por algoritmo GGeohash o valor ''cbits_pt'' da célula pontual, <code>cbits_pt=encode(pt,cbits_l0)</code>. | O valor ''cbits_l0'' é o identificador de célula ''L0'' do país correto, e o identificador de país é seu prefixo. A partir do ponto ''pt'' (com geometria já no SRID do país) e ''cbits_l0'' obtemos por algoritmo GGeohash o valor ''cbits_pt'' da célula pontual, <code>cbits_pt=encode(pt,cbits_l0)</code>. | ||
NOTA. Em aplicações que não partem de um cenário global, ou de pontos que não precisam ser selecionados como interiores ou não ao território nacional, pode-se adotar um seletor mais simples: | '''NOTA'''. Em aplicações que não partem de um cenário global, ou de pontos que não precisam ser selecionados como interiores ou não ao território nacional, pode-se adotar um seletor mais simples: <code>grid_br.xyS_collapseTo_ijS(pt)</code> por default retorna as coordenadas IJ de L0. | ||
: <code>SELECT cbits as cbits_l0 FROM osmc.coverage <br/>WHERE srid=$srid AND pt && geom</code> | : <code>SELECT cbits as cbits_l0 FROM osmc.coverage <br/>WHERE srid=$srid AND pt && geom</code> | ||
: indexação prévia com <br/><code>CREATE INDEX osmc_coverage_idx1<br/>ON osmc.coverage(srid,geom) <br/>USING GIST (geom)</code> | : indexação prévia com <br/><code>CREATE INDEX osmc_coverage_idx1<br/>ON osmc.coverage(srid,geom) <br/>USING GIST (geom)</code> | ||
Por fim, como o país não pode ter mais do que 16 células L0, uma cadeia de condições IF ou CASE é suficiente e provavelmente mais rápido do que consultar o banco de dados. Usando <code>ST_X(pt)</code> e <code>ST_Y(pt)</code> e os valores de BBOX, podemos otimizar o processo de escolha de ''L0'' e ''encode'' do ponto. | |||
=== Tratamento das configurações === | |||
Usando o exemplo do Brasil, "grid_lc" indica que a cobertura é uma matriz de 5x5 (linhas por colunas), e "grid_l0_cell" quais são as células IJ selecionadas pelo índice "grid_l0_cell_idx": | |||
<pre> | |||
grid_lc: 5 5 | |||
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 | |||
</pre> | |||
As configurações podem ser reescritas com auxilio de uma query: | |||
<syntaxhighlight lang="sql" style="font-size: 80%;"> | |||
WITH m AS ( -- background matrix | |||
select i,j from generate_series(0,4) t1(i), generate_series(0,4) t2(j) | |||
), c AS ( -- cover cells | |||
select i,j, (natcod.baseh_to_vbit('{0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,fT,fP,fN}'::text[],16))[(p+2)/3] as cbits | |||
from ( | |||
select i,j, strpos('40 41 42 43 30 31 32 33 34 21 22 23 11 12 13 02 44 24', i::text||j::text)::float as p | |||
from m | |||
) tt where p>0 | |||
) SELECT array_agg(a order by i) -- IJ_to_cover matrix | |||
FROM ( | |||
SELECT m.i, array_agg( c.cbits order by m.j) a | |||
FROM c RIGHT JOIN m ON c.i=m.i AND c.j=m.j | |||
GROUP BY 1 ORDER BY 1 | |||
) t4 | |||
; | |||
</syntaxhighlight> | |||
A matriz resultante <code>IJ_to_cover={{NULL,NULL,1111101,NULL,NULL}, ..., {0000,0001,0010,0011,1111011}}</code> é a indexadora de ''L0'', a ser utilizada nas funções de encode. Conforme o tipo de resolução é possível ignorar as fantasmas (tamanho maior que 4 bits) ou utilizá-las como as demais, com o cuidado de não subdividir antes do nível ''L1.5''. | |||
:<small>'''NOTA TÉCNICA'''. A rigor, por terem duas células de cobertura associadas ao quadrante ''IJ=02'', a resolução seria em duas etapas: usando "{0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,.,.,.}" na cobertura, o resultado seria <code>IJ_to_cover={{NULL,NULL,"",NULL,NULL}, ...,{0000,0001,0010,0011,""}}</code>, com NULLs e bit strings vazias, "". Estabelecendo com "" a condição para resolução secundária, mas isso traria maior complexidade, mais fácil por hora ignorar a célula "fY" do mar territorial. </small> <!-- Os NULLs indicam que a célula da matriz não é usada. Os valores "" indicam que a resolução será por ''grid_l0_ghost'': é a condição para a verificação secundária, esses quadrantes no nível ''L0'' não possuem uma resolução direta, apenas no nível ''L1.5''. --> | |||
Temos por fim a seguinte '''função de resolução ''L0''''': | |||
<syntaxhighlight lang="sql" style="font-size: 80%;"> | |||
DROP FUNCTION grid_br.IJ0_to_L0(int,int,boolean) | |||
; | |||
DROP FUNCTION grid_br.IJ0_to_L0(int[],boolean) | |||
; | |||
CREATE FUNCTION grid_br.IJ0_to_L0(i int, j int, ignore_ghost boolean default true) RETURNS varbit AS $f$ | |||
SELECT CASE WHEN ignore_ghost AND bit_length(cbits)>4 THEN NULL ELSE cbits END | |||
FROM ( | |||
SELECT ('{{NULL,NULL,1111101,NULL,NULL},{NULL,1100,1101,1110,NULL},{NULL,1001,1010,1011,1111010},{0100,0101,0110,0111,1000},{0000,0001,0010,0011,1111011}}'::varbit[])[i+1][j+1] | |||
) t(cbits) | |||
$f$ LANGUAGE SQL IMMUTABLE; | |||
CREATE FUNCTION grid_br.IJ0_to_L0(ij int[], ignore_ghost boolean default true) RETURNS varbit AS $wrap$ | |||
SELECT grid_br.IJ0_to_L0($1[1], $1[2], $2) | |||
$wrap$ LANGUAGE SQL IMMUTABLE; | |||
</syntaxhighlight> | |||
Portanto <code>grid_br.IJ0_to_L0( grid_br.xyS_collapseTo_ijS(x,y) )</code> determina a cobertura L0. Com ''cbits'' determinamos quais valores Xmax e Ymax subtrair [[osmc:Metodologia/Algoritmo SQL/Issue04|cálculo GGeohash de uma célula de nível superior a zero]]. | |||
<!-- | <!-- | ||
Situações: | Situações: | ||
Linha 132: | Linha 187: | ||
== Gerando a grade L0 de cobertura do país == | == Gerando a grade L0 de cobertura do país == | ||
Existem duas possibilidades de trabalho com a grade: | |||
# Com seletores e algoritmos de ''encode''/''decode''. | |||
# Com geometria das grades de células maiores, partindo de ''L0'', e depois, acima de certo nível, usando funções de geração de grade virtual. | |||
Como vimos, as configurações são transferidas para as mesmas tabelas onde foram geradas e arquivadas as geometrias L0. Podemos simplesmente recuperá-las. Tabela atual ''osmc.coverage'': | Como vimos, as configurações são transferidas para as mesmas tabelas onde foram geradas e arquivadas as geometrias L0. Podemos simplesmente recuperá-las. Tabela atual ''osmc.coverage'': | ||
Linha 137: | Linha 196: | ||
Column | Type | Collation | Nullable | Default | Column | Type | Collation | Nullable | Default | ||
---------------+-------------+-----------+----------+--------- | ---------------+-------------+-----------+----------+--------- | ||
cbits | bit varying | | | | |||
isolabel_ext | text | | | | isolabel_ext | text | | | | ||
cindex | text | | | | cindex | text | | | | ||
Linha 172: | Linha 231: | ||
[[Arquivo:BRgrid-L0-QGISv1.png|centro|semmoldura|620px]] | [[Arquivo:BRgrid-L0-QGISv1.png|centro|semmoldura|620px]] | ||
Funções ''osmc.decode_scientific_absolute_geoms'' e ''osmc.L0cover_br_geoms'' em https://github.com/osm-codes/GGeohash/blob/main/src/step03def-lib.sql#L1520 | |||
===Recorte L1 scientifica === | ===Recorte L1 scientifica === | ||
Linha 398: | Linha 315: | ||
==Ver também== | ==Ver também== | ||
* [[osmc:Metodologia/Algoritmo SQL/Lib]] | |||
* Países e respectivos SQLs: [[osmc:BR]]/[[osmc:BR/SQL|SQL]], [[osmc:CO]]/[[osmc:CO/SQL|SQL]], [[osmc:CM]]/[[osmc:CM/SQL|SQL]]. | |||
* [[osmc:Metodologia/Algoritmo SQL/Issues]] | |||
* DNGS - [[Discrete National Grid Systems/pt]] | * DNGS - [[Discrete National Grid Systems/pt]] | ||
* [[osmc:Api]] | * [[osmc:Api]] | ||
------ | ------ |
edições