digital-guard / preserv

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

Implementar ingestão de arquivos geojson #104

Open 0e1 opened 2 years ago

0e1 commented 2 years ago

Alguns layers do pacote de dados BR/RJ/RioJaneiro/_pk0078.02 necessitam de suporte a ingestão de arquivos geojson.

Código legado, e provavelmente não funcional, atualmente existente no schema ingest:

0e1 commented 2 years ago

Especificar melhor a tarefa, apontando, por exemplo, quais outras funções existentes podem ser aproveitadas (ou se essa busca faz parte da tarefa), indicar se o objetivo é fazer uma _geojsonload (de maneira semelhante ao que foi feito para _osmload) ou reaproveitar funções de maneira que seja possível utilizar a _anyload. Com isso será possível fazer uma melhor estimativa do tempo necessário para realizar a tarefa.

ppKrauss commented 2 years ago

São previstos dois contextos onde as funções de "load GeoJSON" serão utilizadas:

  1. Workflow de Ingestão Digital-guard: como função do SQL-schema ingest; tanto para trazer dados doados originais como para trazer dados do nosso "backup git" (tipicamente distribuído em multiplos arquivos). Em algum momento, no final do processo, os dados estarão limpos e validados na tabela ingest.feature_asis.

  2. Análise ou ingestão diversa: a Internet está repleta de arquivos GeoJSON para diferentes finalidades, e muitos deles precisam ser examinados por nós, de preferência fazendo uso de nossas ferramentas. Existem também situações onde o GeoJSON precisa ser ingerido como arquivo de interface ou arquivo de configuração, não como fora do workflow usual.

Ingestão

As funções já construídas devem servir meramente como inspiração, já que horas-programador foram investidas e o objetivo que se tinha em vista era mesmo. A reutilização total não é garantida principalmente porque o modelo de dados evoluiu e mudou, mas a ingetsão GeoJSON foi deixada para trás, e talvez não faça mais sentido tentar aproveitar.

A modularização das funções segue o padrão habitual:

Estão corretas as citações ingest.tmp_geojson_feature e ingest.geojson_load, mas não há compromisso de se copiar/colar elas, são apenas inspirações. A PubLib evoluiu nesse meio tempo, deve-se também conferir o que reusar da PubLib (funções menores já prontas ou fáceis de melhorar na própria PubLib).

Análise e entrega de kit

Haverá, como já houve, demanda por analisar arquivos externos sem compromisso de preservação digital, e as tarefas de análise no servidor precisam ser fascilitadas por nosso "kit de ferramentas".

O "kit funções GeoJSON" mais importante todavia será muito similar ao nosso workflow de ingestão, podendo inclusive retornar os dados no formato padronizado da feature_asis, mas justamente em retorno da função, para que o usuário possa fazer por exemplo CREATE TABLE t AS SELECT * FROM f(x) , ao ingerir GeoJSON do nosso CutGeo (ex. preservCutGeo-BR2021). No futuro esse será o "core" da versão PostgreSQL em loadCutGeo-kit. See also site-v2/issues/16.

0e1 commented 2 years ago

A ingestão de geojson foi implementada em https://github.com/digital-guard/preserv/commit/e36e7aa528c143a2aa92feef9ed665a9a70b922b.

Partindo do principio de reaproveitar o máximo possível do código já existente:

O https://github.com/digital-guard/preserv-BR/commit/9cadb3809c3d10db10b78b503f7e3f0186a63951 trás um exemplo de como deve ser feita a ingestão de um layer quando o arquivo for geojson:

  via:
        subtype: full
        method: geojson2sql
        file: 2
        orig_filename: Logradouros
        sql_view: SELECT properties->'COMPLETO' AS via_name, properties->'COD_TRECHO' AS ref, jgeom AS geom FROM $(tabname)

Reparar que utilizar a função geojson_readfile_features_jgeom implica em:

Qualquer teste deve ser feito numa base ingest atualizada.

Exemplo visual dos dados ingestados: Captura de tela de 2022-04-28 21-17-29

Dados em feature_asis:

 file_id | feature_id |                       properties                        |                                                                                                                                                                                                                                                                                                            geom                                                                                                                                                                                                                                                                                                            |  kx_ghs9  
---------+------------+---------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------
       1 |          1 | {"ref": 55403, "via_name": "Avenida Presidente Vargas"} | 0102000020E6100000030000001D1F2DCE189845C0B8ACC26680E736C0C3B645990D9845C0094E7D2079E736C0CEDF8442049845C0A758350873E736C0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | 75cm9nrt2
       1 |          2 | {"ref": 116564, "via_name": "Rua Capitão Cruz"}         | 0102000020E61000000400000047904AB1A3A745C0DB4FC6F830D336C0DB4E5B2382A745C04513286211D336C04E0D349F73A745C07B6B60AB04D336C06C26DF6C73A745C099840B7904D336C0                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | 75cnnkzte
       1 |          3 | {"ref": 68363, "via_name": "Faixada da Servidão"}       | 0102000020E6100000120000001FA2D11DC4C445C0946DE00ED4E936C0A180ED60C4C445C02FA86F99D3E936C0959EE925C6C445C0D107CBD8D0E936C0BB61DBA2CCC445C04CA4349BC7E936C05F7AFB73D1C445C068D0D03FC1E936C09A44BDE0D3C445C08751103CBEE936C099107349D5C445C03AE8120EBDE936C04582A966D6C445C0171230BABCE936C02635B401D8C445C05801BEDBBCE936C026016A6AD9C445C03AE8120EBDE936C007B47405DBC445C05EBEF561BDE936C0E275FD82DDC445C06938656EBEE936C0DC847B65DEC445C0CEFDD5E3BEE936C0D593F947DFC445C074B2D47ABFE936C0FE261422E0C445C0FD4D2844C0E936C05019FF3EE3C445C0598638D6C5E936C042CF66D5E7C445C01FD95C35CFE936C0C345EEE9EAC445C0459C4EB2D5E936C0 | 75cj9kb9y
(3 rows)

Saída completa de ingestão:

------------------------------------------
------ BR-RJ-RioJaneiro  ------
------ Layer tipo via_full  ------
-- Incluindo dados do arquivo-2 do package-7600007802201 na base ingest66 --
 Nome-hash do arquivo-2: cbf1efdbbdbc96f0c012556ff36040d8314564d300f9c53aaef8b49f0b8000c9.zip
 Tabela do layer: pk7600007802201_p2_via
 Sub-arquivos do arquivo-2 com o conteúdo alvo: *Logradouros*
 Tema dos sub-arquivos: Logradouros
Run with tmux and sudo! (DANGER: seems not idempotent on psql)
claiton
Above user is root? If not, you have permissions for all paths?
psql postgres://postgres@localhost/ingest66 -c "DROP TABLE IF EXISTS pk7600007802201_p2_via CASCADE"
DROP TABLE
Extracting ....
cd /tmp/sandbox/_pkBR782_001; 7z  x -y /var/www/preserv.addressforall.org/download/cbf1efdbbdbc96f0c012556ff36040d8314564d300f9c53aaef8b49f0b8000c9.zip "*Logradouros*" ; chmod -R a+rwx . > /dev/null

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=C.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs DO-Regular (306F2),ASM,AES-NI)

Scanning the drive for archives:
1 file, 33511987 bytes (32 MiB)

Extracting archive: /var/www/preserv.addressforall.org/download/cbf1efdbbdbc96f0c012556ff36040d8314564d300f9c53aaef8b49f0b8000c9.zip
--
Path = /var/www/preserv.addressforall.org/download/cbf1efdbbdbc96f0c012556ff36040d8314564d300f9c53aaef8b49f0b8000c9.zip
Type = zip
Physical Size = 33511987

Everything is Ok

Size:       152849087
Compressed: 33511987
Conferindo se SRID 31983 está configurado:
 srid  |                                    proj4text                                     
-------+----------------------------------------------------------------------------------
 31983 | +proj=utm +zone=23 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
(1 row)

Executando geojson2sql ...
psql postgres://postgres@localhost/ingest66 -c "DROP TABLE IF EXISTS pk7600007802201_p2_via"
DROP TABLE
psql postgres://postgres@localhost/ingest66 -c "CREATE TABLE pk7600007802201_p2_via AS SELECT * FROM geojson_readfile_features_jgeom('/tmp/sandbox/_pkBR782_001/Logradouros.geojson',null)"
SELECT 144735
psql postgres://postgres@localhost/ingest66 -c "CREATE VIEW vw2_pk7600007802201_p2_via AS SELECT properties->'COMPLETO' AS via_name, properties->'COD_TRECHO' AS ref, jgeom AS geom FROM pk7600007802201_p2_via"
CREATE VIEW
psql postgres://postgres@localhost/ingest66 -c "SELECT ingest.any_load('geojson2sql','/tmp/sandbox/_pkBR782_001/Logradouros.geojson','via_full','vw2_pk7600007802201_p2_via','7600007802201','cbf1efdbbdbc96f0c012556ff36040d8314564d300f9c53aaef8b49f0b8000c9.zip',array[]::text[],5,1)"
                               any_load                                
-----------------------------------------------------------------------
 From file_id=1 inserted type=via_full.                               +
                                                                      +
         Statistics:                                                  +
 .                                                                    +
         Before deduplication:                                        +
                                                                      +
         Originals: 144735 items.                                     +
                                                                      +
         Not Intersecs: 3 items.                                      +
                                                                      +
         Invalid: 0 items.                                            +
                                                                      +
         Not simple: 179 items.                                       +
                                                                      +
         Empty: 47 items.                                             +
                                                                      +
         Small: 1163 items.                                           +
                                                                      +
         Null: 0 items.                                               +
                                                                      +
         Invalid geometry type: 0 items.                              +
                                                                      +
         Not closed: 0 items.                                         +
                                                                      +
         Large: 0 items.                                              +
                                                                      +
         Inserted in feature_asis: 143390 items.                      +
                                                                      +
         Inserted in feature_asis_discarded: 1345 items.              +
                                                                      +
                                                                      +
         After deduplication:                                         +
                                                                      +
         Removed duplicates from feature_asis: 24916 items.           +
                                                                      +
         Inserted in feature_asis_discarded (duplicates): 24916 items.+
                                                                      +
         Inserted in feature_asis (aggregated duplicates): 9698 items.+
                                                                      +
         Resulting in feature_asis: 128172                            +

(1 row)

psql postgres://postgres@localhost/ingest66 -c "DROP VIEW vw2_pk7600007802201_p2_via"
DROP VIEW
Confira os resultados nas tabelas ingest.donated_packcomponent e ingest.feature_asis.
FIM.
0e1 commented 2 years ago

Problemas relatados:

  1. Geojson menor que 1GB (600MB) e geojson_readfile_features_jgeom consumindo muita memória, e rapidamente derrubando o banco. _pg_readfile consegue ler o arquivo. https://github.com/digital-guard/preserv-BR/issues/85
  2. Geojson maior que 1GB e _pg_readfile não consegue ler o arquivo. Se conseguisse, teríamos o problema 1. https://github.com/digital-guard/preserv-BR/issues/86
0e1 commented 2 years ago
  1. Geojson menor que 1GB (600MB) e geojson_readfile_features_jgeom consumindo muita memória, e rapidamente derrubando o banco. _pg_readfile consegue ler o arquivo.

O consumo de memória excede a do servidor no momento do cast para jsonb: SELECT pg_read_file('Quadras_(2013).geojson')::JSONb.

0e1 commented 2 years ago

O commit https://github.com/digital-guard/preserv/commit/4495cdf5fa1e55b880dcd87047ca658d43a9c5b0 implementa o fatiamento de geojson, para contornar o grande consumo de memória durante o cast em pg_read_file('Quadras_(2013).geojson')::JSONb e evitar a leitura de arquivos maiores que 1 GB pela _pg_readfile.

Foi definido que arquivos maiores que 157286400 bytes terão suas features distribuídas em arquivos com no máximo 20 mil features. Esse processo de divisão aumenta o tempo de ingestão. Por exemplo, os arquivos referentes a parcel e block de Rio de Janeiro levaram cerca de 1 hora para serem divididos utilizando o jq.

A seguir exemplo contendo o resumo da ingestão de parcel de RJ, cerca de 1 milhão de feições em um arquivo de 1GB:


                               any_load                                
-----------------------------------------------------------------------
 From file_id=5 inserted type=parcel_full.                            +
                                                                      +
         Statistics:                                                  +
 .                                                                    +
         Before deduplication:                                        +
                                                                      +
         Originals: 1000830 items.                                    +
                                                                      +
         Not Intersecs: 738 items.                                    +
                                                                      +
         Invalid: 64 items.                                           +
                                                                      +
         Not simple: 0 items.                                         +
                                                                      +
         Empty: 307 items.                                            +
                                                                      +
         Small: 2814 items.                                           +
                                                                      +
         Null: 0 items.                                               +
                                                                      +
         Invalid geometry type: 0 items.                              +
                                                                      +
         Not closed: 1 items.                                         +
                                                                      +
         Large: 0 items.                                              +
                                                                      +
         Inserted in feature_asis: 997213 items.                      +
                                                                      +
         Inserted in feature_asis_discarded: 3617 items.              +
                                                                      +
                                                                      +
         After deduplication:                                         +
                                                                      +
         Removed duplicates from feature_asis: 13157 items.           +
                                                                      +
         Inserted in feature_asis_discarded (duplicates): 13157 items.+
                                                                      +
         Inserted in feature_asis (aggregated duplicates): 6575 items.+
                                                                      +
         Resulting in feature_asis: 990631                            +

(1 row)

psql postgres://postgres@localhost/ingest99 -c "DROP VIEW vw3_pk7600007802301_p3_parcel"
DROP VIEW
Confira os resultados nas tabelas ingest.donated_packcomponent e ingest.feature_asis.
FIM.
``