opendatasicilia / tansignari

"T'ansignari e t'appeddiri"
http://tansignari.opendatasicilia.it
Creative Commons Attribution 4.0 International
18 stars 10 forks source link

[script] estrarre testo da un elenco #242

Closed pigreco closed 1 year ago

pigreco commented 1 year ago

Grazie a ogrinfo è possibile estrarre - da un FileGDB - la lista dei layer presenti:

ogrinfo -so DBGT_10K_22_V01.gdb
INFO: Open of `DBGT_10K_22_V01.gdb'
      using driver `OpenFileGDB' successful.
Layer: SP_ACQ_SP_ACQ_NOM_T (None)
Layer: ARGINE (None)
Layer: GZ_FER_GZ_FER_TY (None)
Layer: INVASO_INVASO_NOM_T (None)
Layer: GZ_CIC_GZ_CIC_TY (None)
Layer: CS_MAR_CS_MAR_LIN_CS_MAR_NOM_T (None)
Layer: ND_GAS_ND_GAS_TY (None)
Layer: SV_FER_SV_FER_FUN (None)
Layer: SV_FER_SV_FER_NOM_T (None)
...
Group SARDEGNA_DBGT:
  Layer: CANALE_CANALE_BSU_L (3D Measured Multi Line String)
  Layer: AR_VRD_AR_VRD_SUP_L (3D Measured Multi Line String)
  Layer: CANALE_CANALE_PER (3D Measured Multi Line String)
  Layer: AC_CIC_AC_CIC_SUP_SR (3D Multi Polygon)
  Layer: AR_VRD_AR_VRD_SUP (3D Multi Polygon)
  ...
Group SIMBOLOGIA:
  Layer: SIMBOLOGIA_ARC (3D Measured Multi Line String)
  Layer: SIMBOLOGIA_PLG (3D Measured Multi Polygon)
  Layer: SIMBOLOGIA_PTS (3D Measured Point)

dalla lista si nota che ci sono quattro tipologie di oggetti:

  1. None;
  2. Line;
  3. Point;
  4. Polygon.

lista.txt

Per estrarre solo i nomi dei layer, senza la parte iniziale Layer: e la parte finale tra le parentesi tonde, ho usato il seguente script:

#!/bin/bash

set -x
set -e
set -u
set -o pipefail

# lista valori::
# ogrinfo -so "D:\GitHub\ESRI_FileGeodatabase_GDAL\dati\DBGT_10K_22_V01.gdb"

# crea cartella di output
mkdir -p ./output2

# per ogni oggetto
for i in None Line Point Polygon; do
<lista.txt grep $i | sed -E 's/ {0,}//' | sed -E 's/Layer: (.+) \(.+$/\1/'>output2/classi_$i.txt
done

Spettacolare!

aborruso commented 1 year ago

Ottimo @pigreco

Con la recente novità di avere l'output in JSON, diventa tutto molto più facile e diretto, perché il JSON è testo strutturato ed estrai quindi in modo diretto quello che vuoi.

aborruso commented 1 year ago

Dovrebbe essere qualcosa come

ogrinfo -so -json input.gdb | jq -r '.layers[].name'
pigreco commented 1 year ago

@aborruso

il JSON è testo strutturato ed estrai quindi in modo diretto quello che vuoi.

ma occorrerebbe sempre un loop per estrarre i 4 file descritti sopra?

aborruso commented 1 year ago

Totò non ho idea, avrei bisogno del file.

Volevo soltanto sottolineare che con il JSON come output, è tutto più semplice

pigreco commented 1 year ago

Usando il formato json e questo costrutto:

ogrinfo -so -json "D:\GitHub\ESRI_FileGeodatabase_GDAL\dati\DBGT_10K_22_V01.gdb" | jq -c ".layers[]|{name:.name,geom_type:.geometryFields[].type}" |  mlr --ijsonl --ocsv unsparsify

ottengo:

CS_MAR_CS_MAR_LIN_SG,MultiLineStringZ
META,MultiPolygon
MN_CON_MN_CON_SUP_SR,MultiPolygonZ
PALO,PointZ
ARGINE_ARGN_SUP_SR,MultiPolygonZ
CV_LIV,MultiLineStringZ
SCR_CR_POINTXSCR,Point
CONDOT,MultiLineStringZ
.....

ma non prende tutte le tabelle che NON hanno geometry, ovvero, non esiste questo oggetto geom_type:.geometryFields[].type

ovvero per i layer senza geometry sono così:

{
      "name":"CANALE_CS_ACQ_NOM_T",
      "metadata":{
      },
      "geometryFields":[
      ],
      "featureCount":3006,
      "fidColumnName":"OBJECTID",

quelli con geometry è così:

{
      "name":"AR_VRD_AR_VRD_SUP_L",
      "metadata":{
      },
      "geometryFields":[
        {
          "name":"Shape",
          "type":"MultiLineStringZM",
          "nullable":true,
          "extent":[
            431766.13599999994,
            4304316.3300000001,
            568452.46200000029,
            4563953.5470000003
          ],

allego output di ogrinfo -so -json "D:\GitHub\ESRI_FileGeodatabase_GDAL\dati\DBGT_10K_22_V01.gdb"

out.zip

aborruso commented 1 year ago

Ciao @pigreco , devi mettere in questo caso una condizione if in jq

Qualcosa come

<out.json jq  -c '.layers[]|{name:.name,geom_type:(if (.geometryFields|length) > 0 then .geometryFields[].type else "none" end) }' |  mlr --ijsonl --ocsv unsparsify

che verifica la "lunghezza" del campo geometryFields. Quando è > 0 estrae il tipo, altrimenti gli assegna none

pigreco commented 1 year ago

restituisce un errore:

image

aborruso commented 1 year ago

@pigreco apri una shell linux nella cartella in cui hai il file JSON e prova

<out.json jq  -c '.layers[]|{name:.name,geom_type:(if (.geometryFields|length) > 0 then .geometryFields[].type else "none" end) }' |  mlr --ijsonl --ocsv unsparsify
pigreco commented 1 year ago

@aborruso in bash è ok image

aborruso commented 1 year ago

@aborruso in bash è ok

ok e allora passalo da batch al jq di wsl, tramite wsl.

Non ho installato jq e Miller su win, quindi non posso fare subito prove

pigreco commented 1 year ago

ricetta fatta e pubblicata

https://tansignari.opendatasicilia.it/ricette/bash/estrarre_nomi_organizzare_layer_da_filegdb/