digital-guard / preserv

Digital Preservation Project
http://git.digital-guard.org/preserv
Apache License 2.0
0 stars 0 forks source link

Corrigir geração de arquivos e acrescentar make audit #82

Closed ppKrauss closed 2 years ago

ppKrauss commented 2 years ago

Houve uma falha na documentação dos requistos, esta issue tenta corrigir a falha, e estabelece as regras para a correção de parâmetros na distribuição das geometrias em vários arquivos GeoJSON.
PS: na publicação de 2022-02 ficou evidente o excesso de arquivos de geometrias diferentes de ponto. Por exemplo bastariam uns 6 arquivos de quadra em BR-AC/_pk0042.01/block, mas foram gerados ~220 arquivos com média de 40 KB.

O objetivo da distribuição dos arquivos não é "pulverizar" mas, pelo contrário, concentrar a carga em poucos arquivos, desde que eles não excedam um certo limite, entre 500Kb e 2Mb. O controle desse limite é feito através do balanceamento de carga entre células Geohash.

Também houve falha na documentação dos requisitos de propriedades a serem inclusas em cada geometria. Abaixo tento corrigir também esta falha, através de uma tabela de layer-propriedades. Por fim está sendo definido um novo requisito, que são os arquivos de listagem de nomes.

Resumo das regras de distribuição das geometrias

  1. A cada layer uma pasta com o nome do respectivo layer. Exemplos: /geoaddress e /via.

  2. Existe um arquivo batizado de geohashes.geojson que contém o "mosaico" do layer.

  3. Todos os demais arquivos possuem como prefixo uma abreviação de geometrytype. Exemplos: layer via é composto de LINEs, portanto o prefixo é lns_; layer geoaddress é composto de POINTs, portanto o prefixo é pts_; demais layers (block, parcel, etc.) que forem POLYGONs, o prefixo é pols_.

  4. Concentrar a carga em poucos arquivos. Mais de um quando exceder 2 MiB. No caso de pontos, por limitação da interface, quando excederem os 2500 pontos por arquivo.

  5. A mediana do tamanho em bytes (size) dos arquivos precisa ser da ordem de 2 MiB ou menos, desde que garantida a concentração em poucos arquivos.

  6. Os valores métricos precisam ser arredondados por round(x,accuracy) conforme pubLib00-general.

Auditoria

Importante incluir no make um targer audit-geojsons . Na falta da mediana usar a média. O make audit-geojsons consiste num relatório com média e a listagem dos maiores e menores arquivos, conforme script abaixo:

ls -lS  *.geojson | awk 'BEGIN {print "-- MÉDIA:"} $5 {n=n+1;s=s+$5;} END {print "\tnum arquivos: " n; print "\ttamanho médio: " s/(1024*n) " KiB" }'
ls -lhS  *.geojson | head | awk 'BEGIN {print "-- MAIORES:"} $5 {print $5 " | " $9;}'
ls -lhSr *.geojson | head | awk 'BEGIN {print "-- MENORES:"} $5 {print $5 " | " $9;}'

(remover o h se for usar o valor em bytes em planilha)

Tabela layer-propriedades

Resumo das propriedades a serem expressas no GeoJSON publicado, conforme tipo de layer.

layer Propriedades por geometria
geoaddress address. Alternativas: via_names, housenumbers.
via name. Opcionais: ref.
nsvia name. Opcionais: ref.
block name. Opcionais: ref.
... ...

Tabela célula-propriedades para o mosaico

layer Propriedades métricas totalizadas por célula
geoaddress n, bytes.
via km, n, bytes.
nsvia km2, n, bytes.
block km2, n, bytes.
... ...

Arquivos CSV de nomes

layer CSV e suas colunas
geoaddress distrib_viaName_ghs.csv: name,ghs_prefix
distrib_ghs_viaName.csv: ghs_prefix,name
via distrib_name_ghs.csv: name,ghs
distrib_ghs_viaName.csv: ghs,name
block distrib_name_ghs.csv: via_name,geohashes
... ....

Ver também issues #28 e #64

0e1 commented 2 years ago

Avanços:

  1. A cada layer uma pasta com o nome do respectivo layer. Exemplos: /geoaddress e /via.

Agora, arquivos estão sendo escritos no respectivo CutGeo em /var/gits.

3. Todos os demais arquivos possuem como prefixo uma abreviação de geometrytype. Exemplos: layer via é composto de LINEs, portanto o prefixo é lns_; layer geoaddress é composto de POINTs, portanto o prefixo é pts_; demais layers (block, parcel, etc.) que forem POLYGONs, o prefixo é pols_.

Implantado. Agora, prefixo está de acordo com tipo da geometria.

6. Os valores métricos precisam ser arredondados por round(x,accuracy) conforme pubLib00-general.

Valores estão sendo arredondados para duas casas decimais.

Auditoria

Target implementado: make audit-geojsons_<nome do layer> (na raíz do pacote de dados.)

0e1 commented 2 years ago

Tabela célula-propriedades para o mosaico

layer Propriedades métricas totalizadas por célula geoaddress n, bytes. via km, n, bytes. nsvia km2, n, bytes. block km2, n, bytes. ... ...

Implantado. mosaico agora possui os valores idicados acima. Ver common008_publicating_geojsons.mustache. Notar que tudo está sendo feito após a geração da distribuição e antes dos arquivos serem escritos no filesystem. Notar também que para geometrias diferentes de pontos, ghs_distrib_mosaic é atualizado (gerando um proc_step=6). No caso de pontos, apenas proc_step=6.

Exemplo de propriedades de uma célula, no caso de pontos: "properties":{"ghs":"6f6erg","val":970,"lghs":6,"bytes":54114,"area_km2":0.63,"val_density_km2":1529.94}

Exemplo de propriedades de uma célula, no caso de vias: "properties":{"ghs":"6qpz0","val":613,"lghs":5,"size":186.43,"bytes":120531,"area_km2":23.42,"val_density_km2":26.17}}

0e1 commented 2 years ago

Deixando registrado que as propriedade por geometria não serão mais acrescentadas. Código permanece, porém está comentado.

Dessa issue, falta ainda gerar os arquivos csv.

ppKrauss commented 2 years ago

Em https://github.com/digital-guard/preservCutGeo-BR2021/blob/main/data/AC/RioBranco/_pk0042.01/via/lns_6qpz.geojson remover propriedade bytes.

ppKrauss commented 2 years ago

Balanceamento ainda errado

As quadras de Rio Branco, e todas as demais cidades, estão distribuídas por arquivos com muito menos de 2Mb. O requisito do software é que concentre tudo em um arquivo só caso seja leve. Pode-se concentrar em 1, 2 ou máximo 3 arquivos menores, mas não podemos permitir mais que isso.

0e1 commented 2 years ago

Balanceamento ainda errado

As quadras de Rio Branco, e todas as demais cidades, estão distribuídas por arquivos com muito menos de 2Mb. O requisito do software é que concentre tudo em um arquivo só caso seja leve. Pode-se concentrar em 1, 2 ou máximo 3 arquivos menores, mas não podemos permitir mais que isso.

É fruto de como é atualmente a função hcode_distribution_reduce_recursive_raw.

Essa é uma situação onde me pergunto:

  1. existe um conjunto de parâmetros para hcode_distribution_reduce_recursive_raw que satisfaça o requisito para um caso em particular?

  2. existe um conjunto de parâmetros para hcode_distribution_reduce_recursive_raw que satisfaça o requisito (ou próximo dele) e que possa ser usado como default para qualquer layer?

E meu entendimento é que a função não é capaz de atender tal requisito. E acho isso porque não estamos agrupando dados em arquivos. Estamos agrupando geohashes. E quando se reduz em uma unidade o tamanho do geohash, talvez não seja possivel agrupar, pelos limites dados pelos parâmetros.

ppKrauss commented 2 years ago

meu entendimento é que a função não é capaz de atender tal requisito

Se for o caso precisaremos refazer a função ... A principio aumentando o número de recursões conseguimos elevar a concentração... Aguardando parecer final sobre o tema.

ppKrauss commented 2 years ago

Requisitos finais dos algoritmos de mosaico e distribuição

  1. A raíz da distribuição é dada cover0_list = geohash_cover_list( ST_Collect(geom) ), ou seja, não pode ter menos dígitos nem estar fora desta lista. (ver exemplo abaixo).
    PS: para o caso de pontos, devido à equivalência, a análise geométrica pode ser substituída por uma função otimizada. Linhas e polígonos por outro lado requerem a geometria justamente para garantir que a interface de mosaico mantenha a mesma abrangência de área, independente da concentração ou não dos centroides.

  2. Nenhuma outra função de distribuição faz uso da geometria, a linhagem de dados de distribuição tem origem no atributo kx_ghs9 da tabela ingest.feature_asis.

  3. A função de distribuição tem como meta balancear o tamanho dos arquivos GeoJSON, garantindo que o número de arquivos seja mínimo e seu tamanho máximo. Esse ajuste pode ser revisto ano a ano conforme avaliação da utilização e evolução do hardware dos usuários e do Github.
    O algoritmo de distribuição inicia portanto no teste das células de cover0_list, e vai segmentando em menores apenas quando a célula "estoura" o máximo permitido. A cada segmentação, em caso de "poieira" (arquivos muito pequenos), ela deve ser agregada à "célula mãe".
    Em 2022 ficou estabelecido que os arquivos não podem ter muito mais que ~3 MB, nem menos que 100 kB.

  4. A apresentação da distribuição final na forma de mosaico deve ser realizada pela função geohash_GeomsMosaic(distrib_list,mask), usando o município (ou seu buffer) como máscara. As densidades das células do mosaico são relativas às geometrias do mosaico.
    Caso a interseção de cover0_list com o município tenha área inferior ao muncípio, o mosaico também terá área inferior, ou seja, restarão "buracos" (de densidade zero) no mosaico.

SELECT file_id, geohash_cover_list( ST_Collect(geom) ) AS root_list, count(*) n
FROM ingest.feature_asis GROUP BY 1 ORDER BY 1;
 -- file_id |  geom |   n    
 --     1 | {6qp}   |   3123
 --     3 | {6qp}   |    129
 --     5 | {7h7}   |   5432
 --     6 | {7h7}   |     92
 --    54 | {6pxbm} |   4720
 --    55 | {6,7,d,e} |  92132

Nota de performance

Discussão para implementações futuras, depois que a experiência do usuário for avaliada com a primeira versão.

Para casos onde a raiz cover0_list tem cardinalidade 1 e ainda contém o município, vale conferir se cover1_list tem poucos itens (estima-se que no máximo 10), de modo a ser mais satisfatória como raiz.

O algoritmo abaixo tem performance muito baixa, portanto seu uso ainda não é recomendado:

WITH t0 AS (
  SELECT file_id, ST_Collect(geom) cgeom, count(*) n
  FROM ingest.feature_asis
  GROUP BY 1 ORDER BY 1
) 
  SELECT t1.*
         ,CASE
            WHEN cardinality(t1.cover0_list)=1 THEN geohash_cover_list( t0.cgeom , t1.cover0_list[1]) 
            ELSE cover0_list
          END AS cover1_list 
         ,t0.n  
  FROM (
     SELECT file_id, geohash_cover_list( cgeom ) AS cover0_list
     FROM t0 LIMIT 2  -- sem limitar não termina!
  ) t1 LEFT JOIN t0 
  ON t0.file_id=t1.file_id AND ST_IsValid(cgeom) -- não deveriam existir inválidos!
;
-- file_id | cover0_list |   cover1_list         |  n   
--       1 | {6qp}       | {6qpx,6qpy,6qpz}      | 3123
--       2 | {6qp}       | {6qpr,6qpx,6qpy,6qpz} | 4864

PS: pendente também resolver bug pg_pubLib/9.

0e1 commented 2 years ago

Considero o assunto concluído.