2 585
edições
m (→Issue 05 - Cálculo de dígitos base32: typo) |
|||
(6 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 165: | Linha 165: | ||
<syntaxhighlight lang="sql"> | <syntaxhighlight lang="sql"> | ||
DROP FUNCTION IF EXISTS | DROP FUNCTION IF EXISTS ST_Transform_Resilient | ||
; | ; | ||
CREATE FUNCTION | CREATE FUNCTION ST_Transform_Resilient( | ||
g geometry, | g geometry, -- the input geometry | ||
srid integer, -- target SRID, to transform g | srid integer, -- target SRID, to transform g | ||
size_fraction float DEFAULT 0.05, -- 1/density | size_fraction float DEFAULT 0.05, -- 1/density. Density of points per charactDiam (or negative for absolute fraction). | ||
tolerance float DEFAULT 0 -- | tolerance float DEFAULT 0 -- E.g. on srid=4326 use 0.00000005. | ||
) RETURNS | -- ZERO=0.000000001. Smallest=0.000000005. Start cell with 0.00000002. | ||
) RETURNS geometry | |||
language SQL IMMUTABLE | |||
AS $f$ | AS $f$ | ||
SELECT CASE | SELECT CASE | ||
WHEN COALESCE(size_fraction,0.0)>0.0 AND COALESCE(tolerance,0)>0 THEN | 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 | ELSE geom | ||
END | END | ||
FROM ( | FROM ( | ||
SELECT CASE | SELECT CASE | ||
WHEN size>0.0 THEN ST_Transform( ST_Segmentize(g,size) , srid ) | WHEN size>0.0 THEN ST_Transform( ST_Segmentize(g,size) , srid ) | ||
Linha 195: | Linha 195: | ||
) t2 | ) t2 | ||
$f$; | $f$; | ||
COMMENT ON FUNCTION ST_Transform_Resilient IS | |||
'Avoid clothesline-effect. See problem/solution discussed at https://gis.stackexchange.com/q/444441/7505' | |||
; | |||
</syntaxhighlight> | </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