[ qgis ] - [ csv ] - creazione di layer puntuale con coordinate gms (dms)

Ciao,
alcuni Discenti mi hanno chiesto come gestire (o, meglio, come importare in QGIS) un CSV contenente coordinate LAT/LON espresse in GMS (DMS).

La tabella presenta le colonne:

  • 45°26’41.2"N (coordinata Y)
  • 8°38’35.7"E (coordinata X)

Mi pare di ricordare che QGIS (Aggiungi layer delimitato) preferisca un qualcosa del genere:

  • N 45 26 41.2 (coordinata Y)
  • E 8 38 35.7 (coordinata X)

Ho pensato di usare le “regular expression” per facilitare la lettura (l’interpretazione e la “riscrittura”) delle coordinate in modo che QGIS riesca a usarle:

‘N’||’ ’ ||regexp_substr( “COORD_Y”, ‘(\d+)°’)||’ ‘|| regexp_substr( “COORD”, ‘(\d+)’’‘)||’ '||
regexp_substr( “COORD”, ‘(\d…)"’)

‘E’||’ ’ ||regexp_substr( “COORD_x”, ‘(\d+)°’)||’ ‘|| regexp_substr( “COORD”, ‘(\d+)’’‘)||’ '||
regexp_substr( “COORD”, ‘(\d…)"’)

Mi pare che le due regexp, da applicare (via “Calcolatore dei campi”) creando due nuove colonne, “funzionino” ma temo non siano così “eleganti”.

Avete suggerimenti per migliorarle?

Grazie, a presto e… Buona Giornata!

È importante la formattazione, l’errore è legato SOLO al doppio apice, deve essere una successione di due apici semplici.

provare questo:

ID,coordinataY,coordinataX
1,45°26'41.2''N,8°38'35.7''E

a me funziona.

Per sistemarlo, una probabile soluzione è:

replace ("Field", ' " ', ' '' ')

saluti

1 Like

Ciao,
visto che non è una lista dedicata soltanto a QGIS aggiungo alternativa, non richiesta, ma magari utile.

In presenza di un TSV così fatto

8°38'35.7"E	45°26'41.2"N
7°36'5.7"E	42°21'40.2"N

Si può usare il grandioso cs2cs (disponibile per ogni ambiente) e lanciare

cs2cs +proj=latlong +to +proj=latlong -f "%.6f"<input.txt

In output un TSV, con X, Y e Z (pari a zero, perché qui non viene usata):

8.643250	45.444778 0.000000
7.601583	42.361167 0.000000

Alcune note:

  • si imposta il formato di input. Quello atteso è long e lat di DDMMSS;
  • si imposta quello di output specificando che lo si vuole come floating con 6 decimali

Saluti

Ho approfondito un po’ anche con l’aiuto di @andyborruso. (QGIS 3.34.6 LTR Prizren su Win 11)

La formattazione delle coordinate di sopra sono errate limitatamente ai primi e secondi ", perché usano caratteri errati (o meglio, caratteri che non piacciono a QGIS se usato da Aggiungi Testo delimitato).

QGIS vuole:

  • per i minute il simbolo prime ovvero che per QGIS è ascii('′') = 8242; che possiamo generare con char (8242);
  • per i second simbolo dei double prime ovvero che per QGIS è ascii('″') = 8243; che possiamo generare con char (8243);

quindi utilizzando il Field Calc possiamo risolvere:

replace ('45°26’41.2"N', map('’',char(8242),'"',char(8243)))

che restituisce:

'45°26′41.2″N'

riferimenti:
https://www.piliapp.com/symbols/prime/

Saluti

PS: allego un file generato con QGIS (ho estratto i centroidi delle 20 regioni istat e generato le coordinate long e lat usando to_dms( $x,'x',1) to_dms( $y,'y',1)

file di esempio

Ciao @ffierm ,
in QGIS, puoi usare le opzioni disponibili pronte per il tuo caso d’uso.

C’è da fare soltanto attenzione ad avere un CSV corretto, o sapere come gestire un CSV non full compliant a rfc 4180.

In questo caso, è importante fare caso al carattere " che è speciale per un CSV. Nella cella in cui è contenuto bisogna farne l’escape sempre con ", e la cella deve essere chiusa tra ".

Così è ad esempio corretto

pkuid,long,lat
1,"7°26'20.5""E","45°8'41.3""N"
2,"8°12'33.1""E","45°31'31.0""N"
3,"8°33'14.1""E","45°33'48.6""N"

E ti basta fare attenzione a queste impostazioni e avrai i tuoi pallini in mappa

Se il CSV non ha il corretto escape, la cosa non è ottimale in termini generali, ma lo puoi gestire ugualmente. Se ad esempio è così

pkuid,long,lat
1,7°26'20.5"E,45°8'41.3"N
2,8°12'33.1"E,45°31'31.0"N
3,8°33'14.1"E,45°33'48.6"N

Dovrai però dirgli che è custom e impostare come sotto

Sono note sintetizzate grazie alle note di @agiudiceandrea qui e allo scambio che ne è scaturito.

1 Like

Ciao,
visto che mi piace risolvere quasi tutto con lo scripting e abbiamo da poco gestito problematiche simili a lezione, propongo anche la soluzione scripting, che e’ facilmente adattabile a qualunque situazione limite (e cosi’ provo anche la nuova interfaccia discourse) :slight_smile:

In questo caso ho immaginato il dato come quello proposto da Andrea:

pkuid,long,lat
1,7°26'20.5"E,45°8'41.3"N"
2,8°12'33.1"E,45°31'31.0"N"
3,8°33'14.1"E,45°33'48.6"N"

Per lo script ho utilizzato queste estensioni: pyqgis-scripting-ext · PyPI
che semplificano un po’ lo scripting di QGIS (cosa che si era resa necessaria per le lezioni)… sia mai che qualcuno ci voglia contribuire o aiutare a mantenerne la compatibilita’ con le versioni di QGIS :slight_smile:

Una volta installate (vedi il readme in fondo al link), apri l’editor python di QGIS e incolla:

import re
from pyqgis_scripting_ext.core import *

csvPath = "/home/hydrologis/TMP/csvimport.csv"
gpkgPath = "/home/hydrologis/TMP/csvimport.gpkg"

with open(csvPath, 'r') as file:
    lines = file.readlines()

pattern = r'\d+\.?\d*'

# create a new memory layer
fields = {
    "pkuid": "int",
    "lat": "double",
    "lon": "double"
}
csvLayer = HVectorLayer.new("csvimport", "Point", "EPSG:4326", fields)

# convert csv to features
for line in lines[1:]:
    line = line.strip()
    
    lineSplit = line.split(",")
    id = int(lineSplit[0])
    lonString = lineSplit[1]
    latString = lineSplit[2]
    
    lonMinSec = re.findall(pattern, lonString)
    latMinSec = re.findall(pattern, latString)
    
    lon = float(lonMinSec[0]) + float(lonMinSec[1])/60 + float(lonMinSec[2])/3600
    lat = float(latMinSec[0]) + float(latMinSec[1])/60 + float(latMinSec[2])/3600
    
    csvLayer.add_feature(HPoint(lon, lat), [id])

# add memory layer to current map
HMap.add_layer(csvLayer)

# optional dump to geopackage
error = csvLayer.dump_to_gpkg(gpkgPath, overwrite=True)
if(error):
    print(error)

Ti verra’ generato un piano in memoria + il geopackage.

Ciao,
Andrea

1 Like