######!/usr/bin/env python # -*- coding: utf-8 -*- # coding: utf8 # Copyright (c) 2020 Xavier Robert # SPDX-License-Identifier: GPL-3.0-or-later # Modifié Alex 2025 07 01 """ Functions to work on vtopo data to be able to write them in the Therion format By Xavier Robert Lima, 2016.06.21 USAGE : - They are normally used by other scripts INPUTS: The inputs are in the script file, in the "# Define data to analysis" section. The different arguments are described. """ ###### To DO : ####### # - Take in account the 'I' (extended elevation) inverse option in vtopo file --> set extend right/left ###### End To DO ####### from __future__ import division # This to be sure that the result of the division of integers is a real, not an integer #from __future__ import unicode_literals # Import modules import sys, os ############################################################################ def read_vtopo_header(lines): """ Function to read header from vtopofile INPUTS: lines: file .tro read by the fonction lines = readlines(file_vtopo) OUTPUTS (all are strings): cavename : Name of the cave coordinates : Entrance coordinates coordsyst : Coordinates system to set the entrance coordinates club : Name of the group that explored the cave entrance : Entrance of the cave versionfle : Vtopo version that has been used to produce the vtopofile USAGE: cavename, coordinates, coordsyst, club, entrance, versionfle = read_vtopo_header(lines) Author: Xavier Robert, Lima 2016/06/27 License: CCby-nc """ # coord_dict: French Lambert system. To find number of your system, see extern/proj4/nad/epsg # file in the therion source distribution. You can add your own lines/systems # [Note alex: ajout des systèmes compatibles VTopo] coord_dict = { u'SWISS' : u'EPSG:21780', u'LT72' : u'EPSG:31300', u'LT93' : u'EPSG:2154', u'LT1' : u'EPSG:27571', u'LT2' : u'EPSG:27572', u'LT2E' : u'EPSG:27572', u'LT3' : u'EPSG:27573', u'LT4' : u'EPSG:27574', u'UTM30' : u'EPSG:32630', u'UTM31' : u'EPSG:32631', u'UTM32' : u'EPSG:32632', u'UTM42' : u'EPSG:32642', u'UTM30E' : u'EPSG:23030', u'UTM31E' : u'EPSG:23031', u'UTM32E' : u'EPSG:23032' } cavename = '' club = '' coordtro = '' coordinates = ["0.0", "0.0", "0.0"] for line in lines: if u"Version" in line: versionfle = line[1].replace(u'\n', u'').rstrip(u'\n\r').split(' ') if u'Trou' in line: # read Trou (cavename, xcoord, ycoord, alt, coordtro) = line[5:].replace(u'\n', u'').rstrip(u'\n\r').split(u',') coordinates = [xcoord, ycoord, alt] # read club if u'Club' in line: club = line[5:].replace(u'\n', u'') # read entrance name if u'Entree' in line : entrance = line[7:].replace(u'\n', u'') if coordtro in coord_dict: # Rewrite the coordinate system to be read by Therion # French Lambert system. To find number of your system, see extern/proj4/nad/epsg file in the therion source distribution. You can add you own lines/systems coordsyst = coord_dict[coordtro] else: coordsyst = None return cavename, coordinates, coordsyst, club, entrance, versionfle ############################################################################ def read_settings(line): """ Function to read the line that define the settings of the survey session : intruments, directions, units, calibrations,... INPUTS: line : string extractd from the .tro file that contains the information on the survey session OUTPUTS: settings : list of strings with all the measurments settings comments : string that correspond to the end of the string "Line" that do not correspond to the settings USAGE: settings, comments = read_settings(line) Author: Xavier Robert, Lima 2016/06/27 License: CCby-nc """ # Question: Do we have to update the code in function of the vtopo version number? param = line[6:].rstrip(u'\n\r').split(u' ') k = 9 #k = 6 if 'Topof' in param[:k]: k = k + 1 if 'Prof' in param[:k] or 'Deniv' in param[:k]: k = k - 1 # Transformation de l'avant-dernier champ s'il correspond à une date jj/mm/aaaa if '/' in param[k-1] : try: jj, mm, aaaa = param[k-1].split('/') param[k-1] = f"{aaaa} {mm} {jj}" except ValueError: pass # ne rien faire si la date est mal formée settings = param[:k] #commentst = param[k+2:] commentst = param[k:] comments = " ".join(str(elem) for elem in commentst) #ucomments=comments.decode('us-ascii', errors = 'replace') #print ucomments return settings, comments#.encode('utf-8', errors = "replace") ############################################################################ def read_data(lines, settings, j, iline): """ Function to read the data from the line INPUTS: lines : file .tro read by the fonction lines = readlines(file_vtopo) settings : list of strings with all the measurments settings; output of the function read_settings j : number of the line that corresponds to the settings line in the list "lines" iline : list of line numbers that correspond to the different settings line in the list "lines" OUTPUTS: data : list of lists of data (string format) USAGE: data = read_data(lines, settings, j, iline) Author: Xavier Robert, Lima 2016/06/27 License: CCby-nc """ data = [] # check if we are at the end of the iline file or not ! if iline.index(j) < len(iline)-1: for i in range(j+1, iline[iline.index(j)+1]): datal = [x for x in lines[i].replace(u'\n', u'').rstrip(u'\n\r').split(u' ') if x != u''] data.append(datal) else: i = j+1 while 1: if 'Configuration' in lines[i]: break else: datal = [x for x in lines[i].replace(u'\n', u'').rstrip('\n\r').split(u' ') if x != u''] data.append(datal) i+=1 # remove white lines in datao data = [x for x in data if x != []] return data ############################################################################ def convert_text(lines): """ Fonction to convert characters encoding... The problem is that .tro files are encode with strange Windows settings, and the accentuation is not well understood by other systems Bug, that is not working well INPUTS: lines : OUTPUTS: USAGE: lines = convert_text(lines) Author: Xavier Robert, Lima 2016/06/27 License: CCby-nc """ dictcaract ={'\xe8' : u'è', '\xe0' : u'à', '\xe9' : u'é', '\xe0' : u'à', '\xf9' : u'ù', '\xea' : u'ê', '\xeb' : u'ë', '\xf1' : u'ñ', '\xfb' : u'û', '\xee' : u'î', '\xef' : u'ï'} for line in lines: #for line in lines.decode('cp1252'): #line = line.decode('cp1252') # windows = latin-1 ? cp-1252 ? cp1252 ? mbcs ? for elem in dictcaract: #print line if elem in line: line = line.replace(elem, dictcaract[elem]) return lines ############################################################################ if __name__ == u"__main__": """ Function to test sub-functions """ from datathwritetools import writeheader_th, writecenterlineheader, writedata fle_tro_fnme = u'Test.tro' fle_th_fnme = u'test.th' icomments = True thlang = u'fr' cavename = u'cave' # open tro file fle_tro = open(fle_tro_fnme, u'rU') # open new th file fle_th = open(cavename.replace(u' ', u'_') + '/Data/' + fle_th_fnme, u'w') # read the tro file lines = fle_tro.readlines() lines = convert_text(lines) # read the header #cavename, coordinates, coordtro, club, entrance = read_vtopo_header(fle_tro) cavename, coordinates, coordsyst, club, entrance, versionfle = read_vtopo_header(lines) writeheader_th(fle_th, cavename, entrance) # read line to line and find the Param i = 0 iline = [] dataold = [] # get line numbers of the lines beginning with 'Param' for line in lines: #print i #print i, line.replace('\n', '') if u'Param' in line: iline.append(i) i+=1 for j in iline: # read the settings of the survey settings, comments = read_settings(lines[j].replace(u'\n', u'')) data = read_data(lines, settings, j, iline) # write centerline header writecenterlineheader(fle_th, entrance, settings, comments, data, coordsyst, coordinates, club, icomments, thlang) # write the data to the .th file writedata(fle_th, settings, data, dataold) fle_th.write(u'\n\tendcenterline\n') dataold = data fle_th.write(u'\nendsurvey\n') fle_tro.close fle_th.close