Talk:Brazil/Grade Estatística Oficial
Grade continua
Em algumas aplicações fica mais simples estabelecer uma BBOX da projeção Albers que tenha exatamente a mesma origem que o quadrante id90, ou seja, o extremo norte mais à esquerda. Como precisa ser múltiplo das quadrículas de 1km,
select MIN( st_x((dp).geom) )
from (
select ST_DumpPoints(geom) dp
from grade_id80
where id_unico=nome_1km
) t; -- -70.2284083467678
select MIN( st_y((dp).geom) ) as Y_geo, MIN( ST_Y(ST_Transform((dp).geom, 952019)) )
from (
select ST_DumpPoints(geom) dp
from grade_id92
where id_unico=nome_1km
) t; -- 4.77930246683542
SELECT ST_Y(g) y_albers, ST_X(g) x_albers
FROM (
SELECT ST_Transform(GeomFromEWKT('SRID=4326;POINT(-70.2284083467678 4.77930246683542)'),952019) g
) t; -- y_albers=11804092.6977587 | x_albers = 3152628.94021703
Conclusão, a menos de um pequeno múltiplo da largura das células de 1km (sabemos que a amostragem não cobre todo quadrante), a origem estará na latitude 4.77930246683542 e longitude -70.2284083467678. Em Alberts corresponde a aproximadamente (3152628,11804092).
Para fazer uso exclusivo da aritmética Bigint, pode-se adotar a convenção de truncar na oitava casa:
SELECT ((11804092.6977587::numeric)*(10^8)::numeric)::bigint -- 1180409269775870
e daí em diante operações bitstring ou bigint na opção do Geohash generalizado do tipo Morton.
reproducao da grade
CREATE TABLE grade_merge AS
with grade_merge AS (
SELECT nome_1km, geom FROM grade_id25
UNION
SELECT nome_1km, geom FROM grade_id80
UNION
SELECT nome_1km, geom FROM grade_id92
)
SELECT nome_1km , ST_UNION(geom) geom
FROM grade_merge
GROUP BY nome_1km
;
-- confere select count(nome_1km) from grade_merge; -- 222377
WITH difs AS (
SELECT ST_area(geom,true) - 1000000 as dif
FROM grade_merge
) SELECT AVG(dif) media, stddev_pop(dif) desvpad,
PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY dif) mediana,
max(dif), min(dif)
FROM difs;
media | desvpad | mediana | max | min ---------------------+--------------------+---------------------+-------------------+-------------------- 0.00130266795514652 | 0.0375740681069435 | 0.00116920471191406 | 0.149886131286621 | -0.146883487701416
Usando mais quadrantes (grades id04, id39, id50, id58, id60 e id68) das extremidades da cobertura,
media | desvpad | mediana | max | min ---------------------+--------------------+---------------------+------------------+-------------------- 0.00183955961357377 | 0.0392693123154169 | 0.00174212455749512 | 0.16294264793396 | -0.162288308143616
Conferindo por Albers (SRID 952019), usando centroides e conferindo a distância entre centroides nos pares com aproximadamente 1km de distância.
CREATE TABLE grade_merge_albers AS
WITH xy AS (
SELECT st_y(acgeom) ylat, st_x(acgeom) xlon, geohash
FROM (
SELECT ST_Transform(ST_Centroid(geom),952019) as acgeom,
ST_geohash( ST_Centroid(geom), 8 ) as geohash
FROM grade_merge
) t
) SELECT row_number() over () as id, *
FROM (
SELECT ylat, xlon, geohash
FROM xy
ORDER BY geohash
) t2
; -- select count(*) n, count(distinct substr(geohash,1,7)) ng
-- from grade_merge_albers; -- both 727559
WITH diflist AS (
SELECT id, ylat, ylat - (LAG(ylat) OVER ()) AS dif
FROM grade_merge_albers
) SELECT count(*) n, AVG(dif) media, stddev_pop(dif) desvpad,
PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY dif) mediana,
max(dif), min(dif)
FROM diflist
WHERE dif>1 AND dif < 1999 -- expected round(dif) IN (0, 1000, 2000, etc)
;
WITH diflist AS (
SELECT id, xlon, xlon - (LAG(xlon) OVER ()) AS dif
FROM grade_merge_albers
) SELECT count(*) n, AVG(dif) media, stddev_pop(dif) desvpad,
PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY dif) mediana,
max(dif), min(dif)
FROM diflist
WHERE dif>1 AND dif < 1999
;
ylat: ~36% of the 727559 samples n | media | desvpad | mediana | max | min --------+------------------+----------------------+------------------+------------------+------------------ 267943 | 1000.00000380891 | 0.000516816766942634 | 1000.00000338256 | 1000.00292785466 | 999 xlon: ~58% of the 727559 samples n | media | desvpad | mediana | max | min --------+------------------+---------+------------------+------------------+------------------ 423691 | 1000.00000010661 | 0 | 1000.00000004005 | 1000.00047563575 | 999.999503661878
BBOX na projeção Albers, contendo todos os centroides amostrados:
SELECT count(*) n, max(ylat) ymax, min(ylat) ymin, max(xlon) xmax, min(xlon) xmin,
max(geohash) geohash_max, min(geohash) geohash_min
FROM grade_merge_albers;
n | ymax | ymin | xmax | xmin | geohash_max(y) | geohash_min(y) --------+------------------+-----------------+------------------+------------------+----------------+------------- 727559 | 11920500.0072049 | 7599499.9921196 | 7620499.99998593 | 2809499.99947599 | d8vnzt3s | 6cczcfzu
Tendo em vista os desvios-padrão em y podemos usar ymin = 7599499.9925
, ymax = 11920500.0070
. Considerando-se todavia que a projeção Albers está em metros e a nossa precisão máxima é de metro, e usando o fato de que o valor ymax-ymin deveria resultar em exatos 4321000, o resíduto 0.0145 representa da ordem 28*y_desvpad, podemos diluir esse resíduo se somarmos ou subtrairmos a metade em cada extremidade: 14*y_desvpad = 0.007235
. Portanto é lícito supor:
ymin = 7599500 ≈ 7599499.9921196 + 0.007235
;ymax = 11920500 ≈ 11920500.0072049 - 0.007235
.
No caso de xmin e xmax o desvio é zero e a discrepância só ocorre na quarta casa decimal, podendo ser atribuída integralmente às falhas no ponto flutuante do cálculo da transformação Albers, sendo lícito arredondar:
xmin = 2809500
;xmax = 7620500
.
Por fim, lembrando que basta ser múltiplo de 1km, podemos eleger como extremos na projeção Albers:
ymin = 7590000
;ymax = 12000000
; xmin = 2800000;xmax = 7630000
.