2 384
edições
m (→Issue 05 - Cálculo de dígitos base32: typo) |
|||
(9 revisões intermediárias pelo mesmo usuário não estão sendo mostradas) | |||
Linha 1: | Linha 1: | ||
Issues e discussões conceituais, antes de se partir para a implementação. | Issues e discussões conceituais, antes de se partir para a implementação. Ver também [[Discussão:DNGS/Decisões_soberanas#Issues]], relativas a decisões humanas, sem algoritmo previsto. | ||
== Issue 01 - Uso ótimo do hInt64 == | == Issue 01 - Uso ótimo do hInt64 == | ||
Linha 132: | Linha 132: | ||
<syntaxhighlight lang="sql"> | <syntaxhighlight lang="sql"> | ||
select hlevel, count(*) n_cells, round(sqrt(max(st_area(geom)))/1000.0) side_km, | select hlevel, count(*) n_cells, round(sqrt(max(st_area(geom)))/1000.0) side_km, | ||
round(avg(ST_NPoints(geom))) | round(avg(ST_NPoints(geom))) geom_npts, | ||
round(avg(ST_NPoints(st_simplify(geom4326,0.00000005)))) | round(avg(ST_CharactDiam(geom))) as geom_chdiam, -- relative ref. | ||
round(avg(ST_NPoints(geom4326))) g4326_npts, | |||
round(avg(ST_NPoints(st_simplify(geom4326,0.00000005)))) g4326simpl_npts | |||
-- 0.00000005 is SRID-metric absolute ref | |||
from grid_cm.all_levels | from grid_cm.all_levels | ||
group by 1 order by 1; | group by 1 order by 1; | ||
Linha 160: | Linha 163: | ||
Na resposta da questão quebrar em duas, "general" depois "grids" (exemplificar com níveis inteiros pulando os meios). Nas grades supor que só um eixo precisa de pontos ... Ver eles no QGIS ou pelo menos nos dados de 11 pontos. O segmentize aplicado a uma só direção é complexo, não vale a pena. | Na resposta da questão quebrar em duas, "general" depois "grids" (exemplificar com níveis inteiros pulando os meios). Nas grades supor que só um eixo precisa de pontos ... Ver eles no QGIS ou pelo menos nos dados de 11 pontos. O segmentize aplicado a uma só direção é complexo, não vale a pena. | ||
<syntaxhighlight lang="sql"> | |||
DROP FUNCTION IF EXISTS ST_Transform_Resilient | |||
; | |||
CREATE FUNCTION ST_Transform_Resilient( | |||
g geometry, -- the input geometry | |||
srid integer, -- target SRID, to transform g | |||
size_fraction float DEFAULT 0.05, -- 1/density. Density of points per charactDiam (or negative for absolute fraction). | |||
tolerance float DEFAULT 0 -- E.g. on srid=4326 use 0.00000005. | |||
-- ZERO=0.000000001. Smallest=0.000000005. Start cell with 0.00000002. | |||
) RETURNS geometry | |||
language SQL IMMUTABLE | |||
AS $f$ | |||
SELECT CASE | |||
WHEN COALESCE(size_fraction,0.0)>0.0 AND COALESCE(tolerance,0)>0 THEN | |||
ST_SimplifyPreserveTopology(geom,tolerance) -- ST_Simplify enough for grid cells | |||
ELSE geom | |||
END | |||
FROM ( | |||
SELECT CASE | |||
WHEN size>0.0 THEN ST_Transform( ST_Segmentize(g,size) , srid ) | |||
ELSE ST_Transform(g,srid) | |||
END geom, size | |||
FROM ( | |||
SELECT CASE | |||
WHEN size_fraction IS NULL THEN 0.0 | |||
WHEN size_fraction<0 THEN -size_fraction | |||
ELSE ST_CharactDiam(g) * size_fraction | |||
END | |||
) t1(size) | |||
) t2 | |||
$f$; | |||
COMMENT ON FUNCTION ST_Transform_Resilient IS | |||
'Avoid clothesline-effect. See problem/solution discussed at https://gis.stackexchange.com/q/444441/7505' | |||
; | |||
</syntaxhighlight> | |||
Migrar função para o git oficial! | |||
== Issue 04 - Lib de grades == | |||
Desenvolvendo em [[osmc:Metodologia/Algoritmo SQL/Issue04]]. | |||
== Issue 05 - Cálculo de dígitos base32 == | |||
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''. Já havíamos notado isso ao apresentar a [[osmc:Metodologia/Algoritmo_SQL/Lib#Core|Lib Core]]. | |||
No caso de geocódigo logístico, que requer cobertura municipal, supondo que o nível da grade adotada para cobertura seja ''Lcover'', podemos obter a aproximação ao metro por um múltiplo de 2.5, que é a quantidade de níveis que se sobe a cada 5 bits do dígito da base32. Partindo de <math>1=2^{Lmax - Lcover - N \cdot 2.5}</math> obtemos por <math>log_2(1)=0</math> a fórmula <math>N= (Lmax-Lcover)/2.5</math>, onde ''N'' é o número de dígitos depois do primeiro para se chegar ao metro. Num caso típico a cobertura municipal no Brasil (''Lmax''=20) é de nível ''L7.5'', resultando em ''N''=5, ou seja, com 6 dígitos teremos o metro. Para uma cobertura de resolução menor, ''L7'', o valor já não é exato, ''N''=5.2. O número de dígitos para chegar no metro portanto será <math>Ndig1m = 1+\lceil (Lmax-Lcover)/2.5 \rceil</math>. | |||
<syntaxhighlight lang="sql" style="font-size: 80%;"> | |||
CREATE FUNCTION grid_br.logistic_Ndig1m(intlevel_cover int) RETURNS real[] AS $f$ | |||
SELECT array[ Lcover, ceil(Ndig1m), ceil(Ndig1m)-Ndig1m, | |||
2^(Lmax-Lcover-ceil(Ndig1m)*2.5), | |||
CASE WHEN ceil(Ndig1m)-Ndig1m=0 THEN NULL ELSE 2^(Lmax-Lcover-floor(Ndig1m)*2.5) END ] | |||
FROM ( | |||
SELECT *, (Lmax-Lcover)/2.5 as Ndig1m | |||
FROM (SELECT 20 as Lmax, intlevel_cover/10.0 as Lcover) t1 | |||
) t2 | |||
$f$ language SQL IMMUTABLE; | |||
-- gerando a tabela do Brasil: | |||
select x[1] as level_cover, x[2] as Ndigits_for_1m, round(x[4],2) as side_size, | |||
round(x[5],2) as size_before | |||
from ( | |||
select grid_br.logistic_Ndig1m(intLevel) as x | |||
from generate_series(40,90,5) t1(intLevel) | |||
) t2; | |||
</syntaxhighlight> | |||
A escolha de nivel ''Lcover'' de cada município no caso do Brasil vai ter o seguinte perfil dado pela função <code>logistic_Ndig1m()</code>. Como o metro é a maior resolução significativa, é interesante não permitir resoluções finais inferiores a meio metro: por exemplo quando a cobertura ótima ''Lcover'' for 4 ou 4.5, usar no máximo 6 dígitos ao invés de 7, já que 2 metros e 1.4 metros são resoluções razoáveis para endereços. Idem ''Lcover''6.5 e 7 etc. | |||
{| class="wikitable" | |||
|+ Número de dígitos base32 para se chegar no metro, conforme ''Lcover'' do município | |||
|- | |||
|''Lcover'' || Ndigits for 1m || ''side_size'' || ''size_before'' | |||
|- | |||
| 4 || 7 || 0.35 || 2.00 | |||
|- | |||
| 4.5 || 7 || 0.25 || 1.41 | |||
|- | |||
| 5 || 6 || 1.00 || | |||
|- | |||
| 5.5 || 6 || 0.71 || 4.00 | |||
|- | |||
| 6 || 6 || 0.50 || 2.83 | |||
|- | |||
| 6.5 || 6 || 0.35 || 2.00 | |||
|- | |||
| 7 || 6 || 0.25 || 1.41 | |||
|- | |||
| 7.5 || 5 || 1.00 || | |||
|- | |||
| 8 || 5 || 0.71 || 4.00 | |||
|- | |||
| 8.5 || 5 || 0.50 || 2.83 | |||
|- | |||
| 9 || 5 || 0.35 || 2.00 | |||
|} |
edições