2 585
edições
m (Peter moveu osmc:Metodologia/Algoritmo SQL/Issue04 para osmc:Metodologia/Algoritmo SQL/Lib: Promover issue e separar algoritmo principal de explicação da Lib) |
(Geração do sistema de grades) |
||
Linha 1: | Linha 1: | ||
Biblioteca para simplificar a geração do sistema de grades de um país. Exemplificando implementação dentro do ''schema'' <code>grid_br</code> das grades do Brasil. | |||
Lembretes: | |||
* Convencionou-se em GGeohash usar YX no lugar de XY. | |||
* ... | |||
A seguir avaliando o uso ''default'' de XYref no lugar de XYcenter, para o desenho da célula. Algumas funções de flexibilização precisam ser agrupadas como "helper functions", enquanto as demais como "core functions". Por exemplo as convenções de array de inteiros baseadas em nível (xyL e ijL) são ''core'', enquanto as baseadas em size-side (xyS e ijS) são ''helper''. | A seguir avaliando o uso ''default'' de XYref no lugar de XYcenter, para o desenho da célula. Algumas funções de flexibilização precisam ser agrupadas como "helper functions", enquanto as demais como "core functions". Por exemplo as convenções de array de inteiros baseadas em nível (xyL e ijL) são ''core'', enquanto as baseadas em size-side (xyS e ijS) são ''helper''. | ||
== Core == | |||
'''Quantizadores''': transformam as coordenadas contínuas YX, de posição no plano projetado, em coordenadas discretas IJ, de localização na grade hierárquica. Quem amarra a posição hierárquica — ''grid hierarchical level'' do sistema de grades — com localização YX é o tamanho de lado ''S'' (''side size'') da célula de nível ''L''. Por imposição do [[Discrete National Grid Systems/pt|padrão DNGS]] temos <math>S_{L}=2^{Lmax-L}</math>. No caso do Brasil ''Lmax''=20, no caso de Camarões ''Lmax=18''. | '''Quantizadores''': transformam as coordenadas contínuas YX, de posição no plano projetado, em coordenadas discretas IJ, de localização na grade hierárquica. Quem amarra a posição hierárquica — ''grid hierarchical level'' do sistema de grades — com localização YX é o tamanho de lado ''S'' (''side size'') da célula de nível ''L''. Por imposição do [[Discrete National Grid Systems/pt|padrão DNGS]] temos <math>S_{L}=2^{Lmax-L}</math>. No caso do Brasil ''Lmax''=20, no caso de Camarões ''Lmax=18''. | ||
Linha 54: | Linha 56: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Construtor do identificador cbits == | |||
[[File:Zcurve45bits.png|thumb|280px|A curva de Morton emerge do entrelaçamento dos bits. Exemplo: <br> <code> ints_to_interleavedbits(47,19,6)</code>.]] | [[File:Zcurve45bits.png|thumb|280px|A curva de Morton emerge do entrelaçamento dos bits. Exemplo: <br> <code> ints_to_interleavedbits(47,19,6)</code>.]] | ||
Existem várias formas de obter o identificador baseado em curva de morton. O identificador IJ da célula, como vimos, é fácil de ser obtido no GGeohash. | Existem várias formas de obter o identificador baseado em curva de morton. O identificador IJ da célula, como vimos, é fácil de ser obtido no GGeohash. | ||
Linha 111: | Linha 113: | ||
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). | ||
== Algoritmo e funções finais de resolução == | |||
Algoritmo principal: | Algoritmo principal: | ||
Linha 154: | Linha 156: | ||
No caso especial de fronteira nacional, como as células "0" ou "3", onde não existem "células contíguas", o dono é o país estrangeiro, portanto, a rigor, a linha não existe na grade. | No caso especial de fronteira nacional, como as células "0" ou "3", onde não existem "células contíguas", o dono é o país estrangeiro, portanto, a rigor, a linha não existe na grade. | ||
=== Geração do sistema de grades === | |||
A persistência do sistema de grades tem um custo muito alto, mas em geral, mesmo sem geometria, a lista de identificadores de célula terá um papel importante como chave-primária de conjuntos de atributos, no que consiste o sistema de informação. Existem duas estratégias para se persistir informações: | |||
* [[wikipedia:Field (geography)|''geo-field'']]: atributos armazenados em todas as células, na grade inteira, eventualmente limitada pela resolução. Geocampos de alta resolução podem ser armazenados de forma separada, como [https://postgis.net/docs/raster.html raster] ou [https://postgis.net/docs/geomval.html geomvals]. | |||
* ''geo-objects'': pontos, linhas ou areas, cada tipo tem seu tratamento dimensional distinto. Uma célula de área pode ser usada como cobertura, a mesma célula se considerada ponto terá a sua área considerada apenas como incerteza em torno do centro. | |||
O sistema completo de grades é mais importante no caso de ''geo-fields''. Os primeiros níveis podem ser geo-fields orientadores, para descobrir onde se encontram geo-objects de interesse. Municípios, devido ao interesse por gestão polcal podem formarmar seus geofields locais, um só banco de dados para a getão municipal (não o país inteiro), viabilizando o armazenamento, que requer capacidade exponencial de disco em função do nível. | |||
Algorítmo genérico, para gerar grades nacionais ou municipais. O algoritmo de <code>grid_br.parents_to_children_cuting</code> é simples, pode ser expresso como recorência: | |||
# Gera células-filhas da cobertura. | |||
# Remove filhas que ficaram fora da interseção da geometria do país (ou município). | |||
# Assume filhas como cobetura e volta ao 1. | |||
<syntaxhighlight lang="sql" style="font-size: 80%;"> | |||
-- primeiro esboço da função | |||
CREATE or replace FUNCTION grid_br.parents_to_children_cuting( | |||
p_intlevel int, -- Target level, where level=intlevel/10.0. Use parent as levelZero? no: grid_br level. | |||
p_parent_list varbit[], -- Natcod parents. A list of distinct grid-cell IDs. | |||
p_cutBy_geom geometry -- when noT null | |||
-- decidir se faz cut de fato ou se apenas confere interseção | |||
) RETURNS setof table_name | |||
language SQL VOLATILE | |||
AS $f$ | |||
with maioria da cobertura me dá o nivel corrente | |||
WITH generated AS ( | |||
SELECT *, | |||
CASE WHEN p_cutBy_geom IS NULL THEN true ELSE ST_Contains(p_cutBy_geom,geom) END | |||
AS is_contained | |||
FROM ( | |||
SELECT cbits, null as geom -- se foi cortado e st_area() é a area do nível, entao está contido. | |||
FROM (select cbits FROM unnest(p_parent_list)) t1 | |||
WHERE p_parent_list IS NOT NULL -- guard, for stop when null | |||
) t2 | |||
), | |||
cut AS ( | |||
SELECT * FROM ( | |||
SELECT cbits, is_contained, | |||
CASE | |||
WHEN is_contained OR p_cutBy_geom IS NULL THEN geom | |||
ELSE ST_Intersection(p_cutBy_geom,geom) | |||
END AS geom | |||
FROM generated | |||
) t3 | |||
WHERE geom IS NOT NULL | |||
) | |||
SELECT * FROM cut | |||
UNION ALL | |||
SELECT * FROM grid_br.parents_to_children_cuting( | |||
$1, | |||
CASE WHEN bit_length(cbits) p_intlevel+1>20 THEN NULL ELSE (SELECT array_agg(cbits) FROM cut) END, | |||
$3 | |||
) t4 | |||
$f$; | |||
</syntaxhighlight> | |||
== Helper lib == | == Helper lib == |
edições