mirror of
https://github.com/Alex38Lyon/Synthese-PSM_LARRA.git
synced 2026-06-01 13:59:13 +00:00
Debug pyCreateTh
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -199,10 +199,10 @@ def load_config(args, configIni="config.ini"):
|
|||||||
|
|
||||||
survey_keys = {
|
survey_keys = {
|
||||||
'Author': 'Author',
|
'Author': 'Author',
|
||||||
'Copyright1': None,
|
'Copyright1': 'Copyright',
|
||||||
'Copyright2': None,
|
'Copyright2': 'Copyright',
|
||||||
'Copyright3': None,
|
'Copyright3': 'Copyright',
|
||||||
'Copyright_Short': 'CopyrightShort',
|
'Copyright_Short': None,
|
||||||
'map_comment': 'mapComment',
|
'map_comment': 'mapComment',
|
||||||
'club': 'club',
|
'club': 'club',
|
||||||
'thanksto': 'thanksto',
|
'thanksto': 'thanksto',
|
||||||
@@ -221,6 +221,7 @@ def load_config(args, configIni="config.ini"):
|
|||||||
config['Survey_Data']['Copyright2'],
|
config['Survey_Data']['Copyright2'],
|
||||||
config['Survey_Data']['Copyright3']
|
config['Survey_Data']['Copyright3']
|
||||||
])
|
])
|
||||||
|
global_data.CopyrightShort = config['Survey_Data']['Copyright_Short']
|
||||||
elif attr:
|
elif attr:
|
||||||
setattr(global_data, attr, config['Survey_Data'][key])
|
setattr(global_data, attr, config['Survey_Data'][key])
|
||||||
|
|
||||||
@@ -232,7 +233,8 @@ def load_config(args, configIni="config.ini"):
|
|||||||
'survey_prefix_name': 'SurveyPrefixName',
|
'survey_prefix_name': 'SurveyPrefixName',
|
||||||
'shot_lines_in_th2_files': ('linesInTh2', lambda x: x.lower() == 'true'),
|
'shot_lines_in_th2_files': ('linesInTh2', lambda x: x.lower() == 'true'),
|
||||||
'station_name_in_th2_files': ('stationNamesInTh2', lambda x: x.lower() == 'true'),
|
'station_name_in_th2_files': ('stationNamesInTh2', lambda x: x.lower() == 'true'),
|
||||||
'kSmooth': ('kSmooth', float),
|
'wall_lines_in_th2_files': ('wallLinesInTh2', lambda x: x.lower() == 'true'),
|
||||||
|
'kSmooth': ('kSmooth', float)
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, value in app_keys.items():
|
for key, value in app_keys.items():
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ error_count = 0 # Compteur d'erreurs
|
|||||||
|
|
||||||
## [Survey_Data] default values
|
## [Survey_Data] default values
|
||||||
Author = "Created by pyCreateTh.py"
|
Author = "Created by pyCreateTh.py"
|
||||||
Copyright = "# Copyright (C) pyCreateTh.py"
|
Copyright = "# Copyright(C) pyCreateTh.py"
|
||||||
CopyrightShort = "Licence (C) pyCreateTh.py"
|
CopyrightShort = "Licence(C) pyCreateTh.py"
|
||||||
mapComment = "Created by pyCreateTh.py"
|
mapComment = "Created by pyCreateTh.py"
|
||||||
cs = "UTM30"
|
cs = "UTM30"
|
||||||
club = "Therion"
|
club = "Therion"
|
||||||
@@ -28,7 +28,7 @@ therionPath = "C:/Therion/therion.exe"
|
|||||||
SurveyPrefixName = f"Survey_"
|
SurveyPrefixName = f"Survey_"
|
||||||
linesInTh2 = True
|
linesInTh2 = True
|
||||||
stationNamesInTh2 = True
|
stationNamesInTh2 = True
|
||||||
wallLineInTh2 = True
|
wallLinesInTh2 = True
|
||||||
kSmooth = 0.5
|
kSmooth = 0.5
|
||||||
XVIScale = 100
|
XVIScale = 100
|
||||||
|
|
||||||
@@ -100,6 +100,7 @@ th2File = """
|
|||||||
##XTHERION## xth_me_image_insert {insert_XVI}
|
##XTHERION## xth_me_image_insert {insert_XVI}
|
||||||
|
|
||||||
{Copyright}
|
{Copyright}
|
||||||
|
|
||||||
# File generated by pyCreateTh.py version {version} date: {date}
|
# File generated by pyCreateTh.py version {version} date: {date}
|
||||||
|
|
||||||
# x_min: {X_Min}, x_max: {X_Max} ecart : {X_Max_X_Min}
|
# x_min: {X_Min}, x_max: {X_Max} ecart : {X_Max_X_Min}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ therion_path = C:\Program Files\Therion\therion.exe
|
|||||||
# Survey prefix name use tu create Survey folders
|
# Survey prefix name use tu create Survey folders
|
||||||
survey_prefix_name = Explo_
|
survey_prefix_name = Explo_
|
||||||
|
|
||||||
# Options for Th2 files
|
# Options for th2 files
|
||||||
shot_lines_in_th2_files = False
|
shot_lines_in_th2_files = False
|
||||||
station_name_in_th2_files = False
|
station_name_in_th2_files = False
|
||||||
wall_lines_in_th2_files = False
|
wall_lines_in_th2_files = False
|
||||||
|
|||||||
@@ -986,8 +986,8 @@ def create_th_folders(ENTRY_FILE,
|
|||||||
df_splays = df_splays.drop(columns="is_zero_length")
|
df_splays = df_splays.drop(columns="is_zero_length")
|
||||||
|
|
||||||
th2_walls = []
|
th2_walls = []
|
||||||
|
|
||||||
if globalData.wallLineInTh2 :
|
if globalData.wallLinesInTh2 :
|
||||||
th2_walls, x_min, x_max, y_min, y_max = wall_construction_smoothed(df_lines, df_splays, x_min, x_max, y_min, y_max)
|
th2_walls, x_min, x_max, y_min, y_max = wall_construction_smoothed(df_lines, df_splays, x_min, x_max, y_min, y_max)
|
||||||
|
|
||||||
|
|
||||||
@@ -1044,7 +1044,7 @@ def create_th_folders(ENTRY_FILE,
|
|||||||
Copyright_Short = globalData.CopyrightShort,
|
Copyright_Short = globalData.CopyrightShort,
|
||||||
points="\n".join(th2_points),
|
points="\n".join(th2_points),
|
||||||
lines="\n".join(th2_lines) if globalData.linesInTh2 else "",
|
lines="\n".join(th2_lines) if globalData.linesInTh2 else "",
|
||||||
walls="\n".join(th2_walls) if globalData.wallLineInTh2 else "",
|
walls="\n".join(th2_walls) if globalData.wallLinesInTh2 else "",
|
||||||
names="\n".join(th2_names) if globalData.stationNamesInTh2 else "",
|
names="\n".join(th2_names) if globalData.stationNamesInTh2 else "",
|
||||||
projection="plan",
|
projection="plan",
|
||||||
projection_short="P",
|
projection_short="P",
|
||||||
@@ -1115,7 +1115,7 @@ def create_th_folders(ENTRY_FILE,
|
|||||||
|
|
||||||
th2_walls = []
|
th2_walls = []
|
||||||
|
|
||||||
if globalData.wallLineInTh2 :
|
if globalData.wallLinesInTh2 :
|
||||||
th2_walls, x_min, x_max, y_min, y_max, = wall_construction_smoothed(df_lines, df_splays, x_min, x_max, y_min, y_max)
|
th2_walls, x_min, x_max, y_min, y_max, = wall_construction_smoothed(df_lines, df_splays, x_min, x_max, y_min, y_max)
|
||||||
|
|
||||||
|
|
||||||
@@ -1171,7 +1171,7 @@ def create_th_folders(ENTRY_FILE,
|
|||||||
Copyright_Short = globalData.CopyrightShort,
|
Copyright_Short = globalData.CopyrightShort,
|
||||||
points="\n".join(th2_points),
|
points="\n".join(th2_points),
|
||||||
lines="\n".join(th2_lines) if globalData.linesInTh2 else "",
|
lines="\n".join(th2_lines) if globalData.linesInTh2 else "",
|
||||||
walls="\n".join(th2_walls) if globalData.wallLineInTh2 else "",
|
walls="\n".join(th2_walls) if globalData.wallLinesInTh2 else "",
|
||||||
names="\n".join(th2_names) if globalData.stationNamesInTh2 else "",
|
names="\n".join(th2_names) if globalData.stationNamesInTh2 else "",
|
||||||
projection="extended",
|
projection="extended",
|
||||||
projection_short="C",
|
projection_short="C",
|
||||||
@@ -2917,7 +2917,7 @@ if __name__ == u'__main__':
|
|||||||
# Reading config.ini #
|
# Reading config.ini #
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
config_file = load_config(args)
|
config_file = load_config(args)
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
# titre #
|
# titre #
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
# Configuration values for pyCreate_th2.ph
|
|
||||||
[Survey_Data]
|
|
||||||
Author = Alexandre Pont
|
|
||||||
Copyright1 = # Copyright (C) ARSIP 2025
|
|
||||||
Copyright2 = # This work is under the Creative Commons Attribution-NonCommercial-NoDerivatives License:
|
|
||||||
Copyright3 = # <http://creativecommons.org/licenses/by-nc-nd/4.0/>
|
|
||||||
Copyright_Short = Licence CC by-nc-nd : http://creativecommons.org/licenses/by-nc-nd/4.0/
|
|
||||||
map_comment = Massif de la Pierre Saint Martin - Larra
|
|
||||||
club = ARSIP
|
|
||||||
thanksto = Merçi à tout le monde
|
|
||||||
datat = https://github.com/Alex38Lyon/Synthese-PSM_LARRA
|
|
||||||
wpage = https://www.arsip.fr/
|
|
||||||
cs = UTM30
|
|
||||||
|
|
||||||
|
|
||||||
[Application_Data]
|
|
||||||
template_path = ./template
|
|
||||||
station_by_scrap = 30
|
|
||||||
final_therion_exe = True
|
|
||||||
therion_path = C:\Program Files\Therion\therion.exe
|
|
||||||
shot_lines_in_th2_files = False
|
|
||||||
station_name_in_th2_files = False
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,307 +0,0 @@
|
|||||||
from dataclasses import dataclass,field
|
|
||||||
from enum import Enum
|
|
||||||
import pandas as pd
|
|
||||||
import numpy as np
|
|
||||||
from os.path import abspath, exists
|
|
||||||
|
|
||||||
from helpers.geo import *
|
|
||||||
#from geo import *
|
|
||||||
from subprocess import check_output, CalledProcessError
|
|
||||||
|
|
||||||
class Expedition(str, Enum):
|
|
||||||
"""A class to represent the different expeditions"""
|
|
||||||
|
|
||||||
UP2006 = "UP2006"
|
|
||||||
UP2008 = "UP2008"
|
|
||||||
UP2010 = "UP2010"
|
|
||||||
UP2014 = "UP2014"
|
|
||||||
UP2017 = "UP2017"
|
|
||||||
UP2019 = "UP2019"
|
|
||||||
UP2023 = "UP2023"
|
|
||||||
ENG08 = "ENG08"
|
|
||||||
ITA08 = "ITA08"
|
|
||||||
unknown = "unknown"
|
|
||||||
|
|
||||||
def assignExpedition(name: str) -> Expedition:
|
|
||||||
"""Assign the correct expedition given a date"""
|
|
||||||
target = Expedition.unknown
|
|
||||||
|
|
||||||
for expedition in Expedition:
|
|
||||||
if expedition.name.__contains__(name):
|
|
||||||
target = expedition
|
|
||||||
|
|
||||||
return target
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Cave:
|
|
||||||
"""A class that contains the information about a specific cavity"""
|
|
||||||
cadnum : str
|
|
||||||
exped : Expedition
|
|
||||||
comment : str
|
|
||||||
altitude : str
|
|
||||||
carto : str
|
|
||||||
explo_status : int
|
|
||||||
_index : int
|
|
||||||
coordinates : coordinatePairUTM = coordinatePairUTM(x=-999.,y=-999.)
|
|
||||||
name : str = "undefined"
|
|
||||||
length: float = 0
|
|
||||||
depth : float = 0
|
|
||||||
complete_name: str = "undefined"
|
|
||||||
explorers : str = "undefined"
|
|
||||||
_search_string : str = field(init=False)
|
|
||||||
_folder_path : str = field(init=False)
|
|
||||||
_sector_folder_path : str = field(init=False)
|
|
||||||
|
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
|
||||||
self._search_string=f"{self.cadnum} {self.name}"
|
|
||||||
|
|
||||||
# set the local folder path for the caves
|
|
||||||
|
|
||||||
def add_coordinates(self, coords : coordinatePairUTM) -> None:
|
|
||||||
"""A method for adding coordinates to the Cave entry"""
|
|
||||||
self.coordinates = coordinatePairUTM(coords.x,coords.y)
|
|
||||||
self.coordinates.add_lat_long_from_xy()
|
|
||||||
self.coordinates.add_sector()
|
|
||||||
self._folder_path = f"../therion/data/{self.cadnum[:-3]}/{self.name}"
|
|
||||||
self._sector_folder_path = f"../therion/data/{self.cadnum[:-3]}/{self.cadnum[:-3]}.th"
|
|
||||||
|
|
||||||
|
|
||||||
def makeTheriontemplate(self) -> str:
|
|
||||||
""" Generate an empty therion file using the cave data"""
|
|
||||||
|
|
||||||
TEMPLATE = f"""survey {self.name} -title '{self.complete_name}' \\
|
|
||||||
-attr cadnum {self.cadnum} \\
|
|
||||||
-attr exped {self.exped}\n
|
|
||||||
|
|
||||||
\tcentreline
|
|
||||||
\t\tcs epsg:32718
|
|
||||||
\t\t#fix ENT {self.coordinates.x} {self.coordinates.y} {self.altitude}
|
|
||||||
|
|
||||||
\t#explo-date {self.exped}
|
|
||||||
\t#team "{self.explorers}"
|
|
||||||
|
|
||||||
\tunits length meters
|
|
||||||
\t units compass clino degrees
|
|
||||||
\tdata normal from to tape compass clino
|
|
||||||
\t#<RENSEIGNER LES DONNEES ICI>
|
|
||||||
|
|
||||||
\tendcentreline
|
|
||||||
|
|
||||||
endsurvey
|
|
||||||
"""
|
|
||||||
|
|
||||||
return TEMPLATE
|
|
||||||
|
|
||||||
|
|
||||||
def make_folder(self) -> None:
|
|
||||||
"""A method which creates an empty folder for the cave of interest."""
|
|
||||||
filepath = abspath(self._folder_path).strip('\n')
|
|
||||||
print(filepath)
|
|
||||||
|
|
||||||
try:
|
|
||||||
check_output(f'mkdir {filepath}', shell=True)
|
|
||||||
cavename = self.name.strip("\n").strip(' ')
|
|
||||||
TH_FILE = f'{filepath}/{cavename}.th'
|
|
||||||
print("Name of the filepath",TH_FILE)
|
|
||||||
MD_FILE = f"{filepath}/NOTES.md"
|
|
||||||
|
|
||||||
if not exists(TH_FILE):
|
|
||||||
with open(TH_FILE, 'w+') as th_file:
|
|
||||||
th_file.write(self.makeTheriontemplate())
|
|
||||||
with open(MD_FILE, 'w+') as md_file:
|
|
||||||
md_file.write(self.comment)
|
|
||||||
|
|
||||||
except CalledProcessError:
|
|
||||||
TH_FILE = f"{filepath}/{self.name}.th"
|
|
||||||
MD_FILE = f"{filepath}/NOTES.md"
|
|
||||||
|
|
||||||
if not exists(TH_FILE):
|
|
||||||
|
|
||||||
with open(TH_FILE, 'w+') as th_file:
|
|
||||||
th_file.write(self.makeTheriontemplate())
|
|
||||||
with open(MD_FILE, 'w+') as md_file:
|
|
||||||
md_file.write(self.comment)
|
|
||||||
pass
|
|
||||||
|
|
||||||
def make_entry_in_sector_file(self) -> None:
|
|
||||||
"""adds an entry line to the sector .th file"""
|
|
||||||
with open(self._sector_folder_path, "r+") as f:
|
|
||||||
lines = f.readlines()
|
|
||||||
|
|
||||||
startindex = [x for x,line in enumerate(lines) if ("centreline" in line) or ("centerline" in line)]
|
|
||||||
formatted = f"""
|
|
||||||
#input {self.name}/{self.name}.th
|
|
||||||
"""
|
|
||||||
lines.insert(startindex[0]-1,formatted)
|
|
||||||
f.seek(0)
|
|
||||||
endindex = [x for x,line in enumerate(lines) if ("endcentreline" in line) or ("endcenterline" in line)]
|
|
||||||
name_as = f'"{self.complete_name}"'
|
|
||||||
formatted = f"""
|
|
||||||
fix ENT_{self.cadnum} {self.coordinates.x} {self.coordinates.y} {self.altitude}
|
|
||||||
station ENT_{self.cadnum} {name_as}
|
|
||||||
#equate ENT_{self.cadnum} 0@{self.name}
|
|
||||||
|
|
||||||
"""
|
|
||||||
lines.insert(endindex[0],formatted)
|
|
||||||
f.seek(0)
|
|
||||||
f.writelines(lines)
|
|
||||||
|
|
||||||
class CaveExistsError(Exception):
|
|
||||||
pass
|
|
||||||
class CadasterNotLoadedError(Exception):
|
|
||||||
pass
|
|
||||||
class CaveNotFoundError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class MoreCavesFoundError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class CaveCadaster:
|
|
||||||
"""A class that expects a list of caves and contains methods for reporting info about these caves"""
|
|
||||||
caves : list[Cave] = field(default_factory=list)
|
|
||||||
|
|
||||||
def add_entry(self, cave: Cave) -> None:
|
|
||||||
"""Enter an instance of a Cave to the database"""
|
|
||||||
self.caves.append(cave)
|
|
||||||
|
|
||||||
def check_existing(self, cave: Cave) -> None:
|
|
||||||
"""Check from a cave's coodinates that it does not already exist in the cadaster"""
|
|
||||||
|
|
||||||
for existing_cave in self.caves:
|
|
||||||
if cave.coordinates.x != float('nan'):
|
|
||||||
dist = np.sqrt((cave.coordinates.x - existing_cave.coordinates.x)**2 + (cave.coordinates.y - existing_cave.coordinates.y)**2)
|
|
||||||
if dist < 1:
|
|
||||||
raise CaveExistsError("the cave exists already")
|
|
||||||
|
|
||||||
def find_cave(self,search_string: str) -> list[Cave]:
|
|
||||||
"""Return a Cave instance given a cadastral number"""
|
|
||||||
|
|
||||||
targets = []
|
|
||||||
for cave in self.caves:
|
|
||||||
if cave._search_string.lower().__contains__(search_string.lower()):
|
|
||||||
targets.append(cave)
|
|
||||||
|
|
||||||
if len(targets)>=1:
|
|
||||||
return targets
|
|
||||||
else:
|
|
||||||
raise CaveNotFoundError("there is no cave with this cadastral number")
|
|
||||||
|
|
||||||
def delete_cave(self, search_string: str) -> None:
|
|
||||||
cave = self.find_cave(search_string)
|
|
||||||
|
|
||||||
proceed = input("Are you sure you want to delete this cave entry? Type <y/n> to proceed.")
|
|
||||||
if proceed == 'y':
|
|
||||||
self.caves.remove(cave)
|
|
||||||
print(f"Deleting the cave '{cave.name}' from the database")
|
|
||||||
else:
|
|
||||||
print(f"keeping the cave '{cave.name}' in the database")
|
|
||||||
|
|
||||||
def generate_dataframe(self) -> pd.DataFrame:
|
|
||||||
"""A method which generates a pandas.DataFrame out of the list of caves objects"""
|
|
||||||
lines = []
|
|
||||||
for cave in self.caves:
|
|
||||||
line = [cave.cadnum,
|
|
||||||
cave.coordinates.sector_name,
|
|
||||||
cave.complete_name,
|
|
||||||
f'{cave.name}',
|
|
||||||
cave.comment,
|
|
||||||
cave.coordinates.x,
|
|
||||||
cave.coordinates.y,
|
|
||||||
cave.altitude,
|
|
||||||
cave.length,
|
|
||||||
cave.depth,
|
|
||||||
cave.explorers,
|
|
||||||
cave.exped,
|
|
||||||
f"{cave.coordinates._orig_lat:.7f}",
|
|
||||||
f"{cave.coordinates._orig_long:.7f}",
|
|
||||||
cave.carto,
|
|
||||||
cave.explo_status
|
|
||||||
]
|
|
||||||
|
|
||||||
lines.append(line)
|
|
||||||
|
|
||||||
cols = ['cadnum',
|
|
||||||
'secteur',
|
|
||||||
'complete_name',
|
|
||||||
'name',
|
|
||||||
'comment',
|
|
||||||
'X_UTM18S',
|
|
||||||
'Y_UTM18S',
|
|
||||||
'altitude',
|
|
||||||
'length',
|
|
||||||
'depth',
|
|
||||||
'explorers',
|
|
||||||
'exped',
|
|
||||||
'latitude',
|
|
||||||
'longitude',
|
|
||||||
'carto',
|
|
||||||
'explo_status'
|
|
||||||
]
|
|
||||||
|
|
||||||
return pd.DataFrame(lines,columns=cols)
|
|
||||||
|
|
||||||
def write_to_file(self, output_path: str)-> None:
|
|
||||||
"""Writing the pandas.DataFrame to a file formatted exactly as expected for rereading into cave cadaster"""
|
|
||||||
df = self.generate_dataframe()
|
|
||||||
#df.sort_values(by='cadnum', inplace =True)
|
|
||||||
df.to_csv(output_path)
|
|
||||||
|
|
||||||
def generate_entry_from_file(df: pd.DataFrame, row: int) -> Cave:
|
|
||||||
"""A function to generate an entry from a specific line of a formatted dataframe"""
|
|
||||||
line = df.loc[row]
|
|
||||||
|
|
||||||
coords = coordinatePairUTM(x=line.X_UTM18S,y=line.Y_UTM18S)
|
|
||||||
coords.add_lat_long(lat=line.latitude,long=line.longitude)
|
|
||||||
coords.add_sector()
|
|
||||||
|
|
||||||
cave = Cave(
|
|
||||||
cadnum=line.cadnum,
|
|
||||||
exped= assignExpedition(str(line.exped)),
|
|
||||||
comment=line.comment,
|
|
||||||
altitude= line.altitude,
|
|
||||||
coordinates=coords,
|
|
||||||
name= line['name'],
|
|
||||||
complete_name= line.complete_name,
|
|
||||||
explorers= line.explorers,
|
|
||||||
length= line.length,
|
|
||||||
depth= line.depth,
|
|
||||||
carto=line.carto,
|
|
||||||
explo_status=line.explo_status,
|
|
||||||
_index = row
|
|
||||||
) # type: ignore
|
|
||||||
return cave
|
|
||||||
|
|
||||||
def initialise_database(filepath : str) -> CaveCadaster:
|
|
||||||
"""Reads a csv file containing the cave data into a CaveCadaster object"""
|
|
||||||
df = pd.read_csv(filepath)
|
|
||||||
cadaster = CaveCadaster()
|
|
||||||
|
|
||||||
for row in range(len(df)):
|
|
||||||
cadaster.add_entry(generate_entry_from_file(df,row))
|
|
||||||
|
|
||||||
return cadaster
|
|
||||||
|
|
||||||
# play with a subclass for the different sectors of cave exploration.
|
|
||||||
@dataclass
|
|
||||||
class CadasterSector(CaveCadaster):
|
|
||||||
"""A cave cadaster subclass"""
|
|
||||||
|
|
||||||
parent : CaveCadaster = CaveCadaster()
|
|
||||||
name : str = 'undefined'
|
|
||||||
root_cadnum : int = 999
|
|
||||||
caves: list[Cave] = field(init = False, default_factory=list)
|
|
||||||
next_cad_num : int = field(init=False)
|
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
|
||||||
self.caves = [cave for cave in self.parent.caves if str(cave.cadnum)[:3].__contains__(str(self.root_cadnum))]
|
|
||||||
self.next_cad_num = self.root_cadnum*1000+len(self.caves)+1
|
|
||||||
|
|
||||||
def add_entry(self, cave: Cave) -> None:
|
|
||||||
self.next_cad_num +=1
|
|
||||||
return super().add_entry(cave)
|
|
||||||
|
|
||||||
|
|
||||||
## test
|
|
||||||
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
from dataclasses import dataclass, field
|
|
||||||
from typing import Tuple
|
|
||||||
from shapely.geometry import shape, Point
|
|
||||||
import fiona
|
|
||||||
import pyproj as proj
|
|
||||||
from os.path import abspath
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class coordinatePairUTM:
|
|
||||||
"""A class that expects two floats"""
|
|
||||||
x : float
|
|
||||||
y : float
|
|
||||||
cadnum_root : str = field(init=False)
|
|
||||||
sector_name : str = field(init=False)
|
|
||||||
_orig_lat : float = field(init=False)
|
|
||||||
_orig_long : float = field(init=False)
|
|
||||||
|
|
||||||
def add_lat_long(self,lat,long) -> None:
|
|
||||||
"""Attributes exploration zone to the cave"""
|
|
||||||
self._orig_lat,self._orig_long = lat,long
|
|
||||||
|
|
||||||
def add_lat_long_from_xy(self) -> None:
|
|
||||||
self._orig_lat,self._orig_long = transformer(crs_in='epsg:32718',crs_out='epsg:4326').transform(self.x,self.y)
|
|
||||||
|
|
||||||
def add_sector(self) -> None:
|
|
||||||
pt = Point(self._orig_long,self._orig_lat)
|
|
||||||
fp = abspath("../therion/data/gis/secteurs.shp")
|
|
||||||
multipolygons = read_multipolygons(fp)
|
|
||||||
intersects = [(pt.within(poly),properties) for poly,properties in multipolygons]
|
|
||||||
|
|
||||||
self.cadnum_root = "undefined"
|
|
||||||
self.sector_name = "undefined"
|
|
||||||
for intersect,property in intersects:
|
|
||||||
if intersect:
|
|
||||||
self.cadnum_root = property["Cadastre_I"]
|
|
||||||
self.sector_name = property["Nom"]
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class coordinatePairLatLong:
|
|
||||||
"""A class containing Latitude and Longitude values"""
|
|
||||||
lat : str
|
|
||||||
long : str
|
|
||||||
hemisphere : tuple = field(init=False, default_factory=tuple)
|
|
||||||
lat_asfloat : float = field(init=False)
|
|
||||||
long_asfloat : float = field(init=False)
|
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
|
||||||
"""convert however the latitude and longitude are given to decimal format."""
|
|
||||||
|
|
||||||
self.parse_hemisphere()
|
|
||||||
if (self.lat.__contains__('°')) and (self.lat.__contains__("'")) and (self.lat.__contains__("''")):
|
|
||||||
self.parse_degree_minutes_seconds()
|
|
||||||
elif(self.lat.__contains__('°')) and (self.lat.__contains__("'")):
|
|
||||||
self.parse_degree_decimal_minutes()
|
|
||||||
else:
|
|
||||||
self.parse_decimal_degrees()
|
|
||||||
|
|
||||||
def parse_hemisphere(self) -> None:
|
|
||||||
"""Parses the lat/long coordinates given and determines in which hemisphere to go"""
|
|
||||||
if self.lat.__contains__('N'):
|
|
||||||
NH = 1
|
|
||||||
else:
|
|
||||||
NH = -1
|
|
||||||
|
|
||||||
if self.long.__contains__('E'):
|
|
||||||
EH = 1
|
|
||||||
else:
|
|
||||||
EH = -1
|
|
||||||
self.hemisphere = (NH,EH)
|
|
||||||
|
|
||||||
def parse_decimal_degrees(self) -> None:
|
|
||||||
"""Parses lat/long coordinates to a decimal float"""
|
|
||||||
self.lat_asfloat = self.hemisphere[0] * float(self.lat.strip('N').strip('S').split('°')[0])
|
|
||||||
self.long_asfloat = self.hemisphere[1] * float(self.long.strip('E').strip('W').split('°')[0])
|
|
||||||
|
|
||||||
def parse_degree_decimal_minutes(self) -> None:
|
|
||||||
"""Parses lat/long coordinates to a decimal float"""
|
|
||||||
|
|
||||||
lat_split = self.lat.strip('N').strip('S').split('°')
|
|
||||||
long_split = self.long.strip('E').strip('W').split('°')
|
|
||||||
lat_degree = float(lat_split[0])
|
|
||||||
long_degree = float(long_split[0])
|
|
||||||
lat_mins = float(lat_split[1].split("'")[0])
|
|
||||||
long_mins = float(long_split[1].split("'")[0])
|
|
||||||
self.lat_asfloat = self.hemisphere[0] * (lat_degree + lat_mins/60)
|
|
||||||
self.long_asfloat = self.hemisphere[1] * (long_degree + long_mins/60)
|
|
||||||
|
|
||||||
def parse_degree_minutes_seconds(self) -> None:
|
|
||||||
"""Parses lat/long coordinates to a decimal float"""
|
|
||||||
|
|
||||||
lat_split = self.lat.strip('N').strip('S').split('°')
|
|
||||||
long_split = self.long.strip('E').strip('W').split('°')
|
|
||||||
lat_degree = float(lat_split[0])
|
|
||||||
long_degree = float(long_split[0])
|
|
||||||
lat_mins = float(lat_split[1].split("'")[0])
|
|
||||||
long_mins = float(long_split[1].split("'")[0])
|
|
||||||
lat_secs = float(lat_split[1].split("'")[1])
|
|
||||||
long_secs = float(long_split[1].split("'")[1])
|
|
||||||
|
|
||||||
self.lat_asfloat = self.hemisphere[0] * (lat_degree + lat_mins/60 + lat_secs/3600)
|
|
||||||
self.long_asfloat = self.hemisphere[1] * (long_degree + long_mins/60 + long_secs/3600)
|
|
||||||
|
|
||||||
def read_multipolygons(filepath: str) -> list:
|
|
||||||
"""Reads a shapefile of exploration zones and makes a list of polygons"""
|
|
||||||
dataset = fiona.open(filepath)
|
|
||||||
multipolygons = [(shape(poly["geometry"]), poly["properties"]) for poly in dataset] # type: ignore
|
|
||||||
|
|
||||||
return multipolygons
|
|
||||||
|
|
||||||
def transformer(crs_out: str ,crs_in: str) -> proj.Transformer:
|
|
||||||
"""A function returning a transformer instance based on crs codes"""
|
|
||||||
return proj.Transformer.from_crs(crs_in, crs_out)
|
|
||||||
|
|
||||||
TRANSFORMER_LATLONG = transformer(crs_in="epsg:4326", crs_out="epsg:32718")
|
|
||||||
|
|
||||||
def convert_coords(coord : coordinatePairLatLong) -> coordinatePairUTM:
|
|
||||||
"""Convert from lat-long to UTM18S"""
|
|
||||||
|
|
||||||
X,Y = TRANSFORMER_LATLONG.transform(coord.lat_asfloat,coord.long_asfloat)
|
|
||||||
return coordinatePairUTM(x=X,y=Y)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import profile
|
|
||||||
import pstats
|
|
||||||
profile = profile.Profile()
|
|
||||||
|
|
||||||
#profile.runcall(convert_coords)
|
|
||||||
ps = pstats.Stats(profile)
|
|
||||||
ps.print_stats()
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
import pandas as pd
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
# 2010-01-04T23:37:42Z
|
|
||||||
timenow = time.localtime()
|
|
||||||
timestamp = f"{timenow.tm_year}-{timenow.tm_mon}-{timenow.tm_mday}T{timenow.tm_hour}:{timenow.tm_min}:{timenow.tm_sec}Z"
|
|
||||||
|
|
||||||
|
|
||||||
TEMPLATE = """<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<gpx
|
|
||||||
version="1.0"
|
|
||||||
creator="Centre Terre"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns="http://www.topografix.com/GPX/1/0"
|
|
||||||
xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
|
|
||||||
<time>'{time}'</time>
|
|
||||||
<bounds minlat="-52" minlon="-72" maxlat="49" maxlon="-70"/>
|
|
||||||
{data}
|
|
||||||
</gpx>"""
|
|
||||||
|
|
||||||
WPT_TEMPLATE = """
|
|
||||||
<wpt lat="{latitude}" lon="{longitude}">
|
|
||||||
<ele>{elevation}</ele>
|
|
||||||
<name>{name}</name>
|
|
||||||
<cmt>{comment}</cmt>
|
|
||||||
<desc>{description}</desc>
|
|
||||||
<sym>{symbol}</sym>
|
|
||||||
</wpt>"""
|
|
||||||
|
|
||||||
def pyToGPX(fp):
|
|
||||||
|
|
||||||
# "../../therion/data/SYNTHESE_POINTAGES.csv"
|
|
||||||
data = pd.read_csv(fp)
|
|
||||||
|
|
||||||
waypoints = ""
|
|
||||||
|
|
||||||
for index,line in data.iterrows():
|
|
||||||
|
|
||||||
if ("camp" in line.complete_name) or ("Camp" in line.complete_name):
|
|
||||||
symbol= "Lodging"
|
|
||||||
else:
|
|
||||||
symbol = "Waypoint"
|
|
||||||
|
|
||||||
formatted = WPT_TEMPLATE.format(
|
|
||||||
|
|
||||||
latitude= line.latitude,
|
|
||||||
longitude= line.longitude,
|
|
||||||
elevation= line.altitude,
|
|
||||||
comment= line.cadnum,
|
|
||||||
name= line.complete_name,
|
|
||||||
description= line.comment,
|
|
||||||
symbol= symbol
|
|
||||||
)
|
|
||||||
|
|
||||||
if "inf" not in formatted:
|
|
||||||
waypoints+=formatted
|
|
||||||
|
|
||||||
with open(fp.strip("csv") + "gpx", "w+") as f:
|
|
||||||
f.write(TEMPLATE.format(data=waypoints,time = timestamp))
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import pandas as pd
|
|
||||||
|
|
||||||
data = pd.read_csv("../therion/data/SYNTHESE_POINTAGES.csv")
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
LANG = {
|
|
||||||
"main_menu" : {
|
|
||||||
"title" : {
|
|
||||||
"fr" : "Menu Principal",
|
|
||||||
"en" : "Main Menu",
|
|
||||||
"es" : "Menu principal"
|
|
||||||
},
|
|
||||||
"savebutton" : {
|
|
||||||
"fr" : "Sauvegarder",
|
|
||||||
"en" : "Save",
|
|
||||||
"es" : "Salvar"
|
|
||||||
},
|
|
||||||
"selectfile" : {
|
|
||||||
"fr" : "Selectionner un fichier",
|
|
||||||
"en" : "Select a file",
|
|
||||||
"es" : "Selectionar una fila"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
matplotlib
|
|
||||||
pandas
|
|
||||||
Shapely
|
|
||||||
Fiona
|
|
||||||
pyproj
|
|
||||||
scipy
|
|
||||||
netCDF4
|
|
||||||
xarray
|
|
||||||
joblib
|
|
||||||
geopandas
|
|
||||||
motionless
|
|
||||||
salem
|
|
||||||
configparser
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
conda create --name ultima2 python==3.9
|
|
||||||
y
|
|
||||||
conda activate ultima2
|
|
||||||
conda install matplotlib==3.5.3 pandas==1.5.2 Shapely==1.8.4
|
|
||||||
Fiona==1.8.13.post1 pyproj==2.6.1.post1 scipy==1.9.3 netCDF4==1.5.7
|
|
||||||
xarray==2022.11.0 joblib==1.1.1 geopandas==0.9.0
|
|
||||||
y
|
|
||||||
pip install motionless==1.3.3
|
|
||||||
pip install salem==0.3.8
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
from dataclasses import dataclass, field
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
from salem import GoogleVisibleMap, Map, transform_geopandas
|
|
||||||
import geopandas as gpd
|
|
||||||
import pandas as pd
|
|
||||||
from shapely.geometry import Point, MultiPoint
|
|
||||||
|
|
||||||
from helpers.geo import coordinatePairUTM
|
|
||||||
from helpers.cadaster import CaveCadaster,Cave, Expedition
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class SatelliteMapPlot:
|
|
||||||
# Configure image aspect
|
|
||||||
size_x : int
|
|
||||||
size_y : int
|
|
||||||
dpi : int
|
|
||||||
scale : float = 0.013988764
|
|
||||||
points : list[coordinatePairUTM] = field(init = False)
|
|
||||||
point_names : list[str] = field(init=False)
|
|
||||||
new_x : float = field(init = False)
|
|
||||||
new_y : float = field(init=False)
|
|
||||||
|
|
||||||
def add_points(self, cadaster : CaveCadaster) -> None:
|
|
||||||
self.points = [cave.coordinates for cave in cadaster.caves]
|
|
||||||
self.point_names = [cave.name for cave in cadaster.caves]
|
|
||||||
|
|
||||||
def add_point_to_plot(self, x: float, y: float) -> None:
|
|
||||||
self.new_x = x
|
|
||||||
self.new_y = y
|
|
||||||
|
|
||||||
def plot_map(self):
|
|
||||||
# Get the Google Static image
|
|
||||||
g = GoogleVisibleMap(y=[self.new_y-0.64*self.scale, self.new_y+0.64*self.scale], x=[self.new_x-1.5*self.scale, self.new_x+1.5*self.scale],
|
|
||||||
scale=2, # scale is for more details
|
|
||||||
maptype='satellite',
|
|
||||||
size_x=self.size_x, size_y=self.size_y
|
|
||||||
)
|
|
||||||
|
|
||||||
# the google static image is a standard rgb image
|
|
||||||
ggl_img = g.get_vardata()
|
|
||||||
|
|
||||||
sm = Map(g.grid, nx=self.size_x, factor=1)
|
|
||||||
|
|
||||||
sm.set_rgb(ggl_img) # add the background rgb image
|
|
||||||
|
|
||||||
# prepare the figure
|
|
||||||
fig, ax = plt.subplots(figsize=(self.size_x/self.dpi,self.size_y/self.dpi), dpi=self.dpi)
|
|
||||||
|
|
||||||
# plot 1
|
|
||||||
x, y = sm.grid.transform([self.new_x],[self.new_y])
|
|
||||||
xi, yi = sm.grid.transform([p._orig_long for p in self.points],[p._orig_lat for p in self.points])
|
|
||||||
ax.scatter(x, y, zorder= 100, s=5,color="blue", marker = "d") # type:ignore
|
|
||||||
ax.scatter(xi, yi, zorder= 100, s=3,color="red", marker = "d") # type:ignore
|
|
||||||
for name,x,y in zip(self.point_names,xi,yi):
|
|
||||||
ax.text(x+.0001,y+.0001,name,fontsize=5,color = "red")
|
|
||||||
|
|
||||||
sm.plot(ax=ax)
|
|
||||||
fig.patch.set_facecolor('black') # type:ignore
|
|
||||||
return fig,ax
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import tkinter as tk
|
|
||||||
|
|
||||||
class ScrollbarFrame(tk.Frame):
|
|
||||||
"""
|
|
||||||
Extends class tk.Frame to support a scrollable Frame
|
|
||||||
This class is independent from the widgets to be scrolled and
|
|
||||||
can be used to replace a standard tk.Frame
|
|
||||||
"""
|
|
||||||
def __init__(self, parent, **kwargs):
|
|
||||||
tk.Frame.__init__(self, parent, **kwargs)
|
|
||||||
|
|
||||||
# The Scrollbar, layout to the right
|
|
||||||
vsb = tk.Scrollbar(self, orient="vertical")
|
|
||||||
vsb.pack(side="right", fill="y")
|
|
||||||
|
|
||||||
# The Canvas which supports the Scrollbar Interface, layout to the left
|
|
||||||
self.canvas = tk.Canvas(self, borderwidth=0, background="#ffffff")
|
|
||||||
self.canvas.pack(side="left", fill="both", expand=True)
|
|
||||||
|
|
||||||
# Bind the Scrollbar to the self.canvas Scrollbar Interface
|
|
||||||
self.canvas.configure(yscrollcommand=vsb.set)
|
|
||||||
vsb.configure(command=self.canvas.yview)
|
|
||||||
|
|
||||||
# The Frame to be scrolled, layout into the canvas
|
|
||||||
# All widgets to be scrolled have to use this Frame as parent
|
|
||||||
self.scrolled_frame = tk.Frame(self.canvas, background=self.canvas.cget('bg'))
|
|
||||||
self.canvas.create_window((4, 4), window=self.scrolled_frame, anchor="nw")
|
|
||||||
|
|
||||||
# Configures the scrollregion of the Canvas dynamically
|
|
||||||
self.scrolled_frame.bind("<Configure>", self.on_configure)
|
|
||||||
|
|
||||||
def on_configure(self, event):
|
|
||||||
"""Set the scroll region to encompass the scrolled frame"""
|
|
||||||
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
|
|
||||||
@@ -1,243 +0,0 @@
|
|||||||
import re
|
|
||||||
from os.path import dirname, abspath, join, splitext, basename
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
file_path_reg = r"(?:\n|^)\s*###filepath:(.*)"
|
|
||||||
input_reg = r"(?:\n|^)\s*(?:input|source)\s+\"?([^\s\"]+)?"
|
|
||||||
survey_reg = r"(?:\n|^)\s*survey\s+(\S+)"
|
|
||||||
end_survey_reg = r"(?:\n|^)\s*endsurvey"
|
|
||||||
scrap_reg = r"(?:\n|^)\s*scrap\s+(\S+)"
|
|
||||||
end_scrap_reg = r"(?:\n|^)\s*endscrap"
|
|
||||||
projection_reg = r"(?:\n|^).*-projection\s+(\S+)"
|
|
||||||
drawnre = re.compile(r".*line wall")
|
|
||||||
drawnexemptre = re.compile(r".*NODRAW")
|
|
||||||
drawnexemptplanre = re.compile(r".*NODRAW PLAN")
|
|
||||||
drawnexemptextendedre = re.compile(r".*NODRAW EE")
|
|
||||||
|
|
||||||
|
|
||||||
class NoSurveysFoundException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class MultipleSurveyFoundException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Scrap:
|
|
||||||
id = None
|
|
||||||
projection = None
|
|
||||||
data = None
|
|
||||||
parent = None
|
|
||||||
|
|
||||||
def __init__(self, id, parent, projection):
|
|
||||||
self.id = id
|
|
||||||
self.projection = projection
|
|
||||||
self.parent = parent
|
|
||||||
|
|
||||||
def is_drawn(self):
|
|
||||||
if not self.data:
|
|
||||||
return False
|
|
||||||
for line in self.data:
|
|
||||||
match = drawnre.match(line)
|
|
||||||
if match:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class Survey:
|
|
||||||
parent = None
|
|
||||||
file_path = None
|
|
||||||
id = None
|
|
||||||
children = []
|
|
||||||
data = None
|
|
||||||
scraps = []
|
|
||||||
plan_drawn_override = False
|
|
||||||
extended_drawn_override = False
|
|
||||||
|
|
||||||
def __init__(self, id, parent, file_path):
|
|
||||||
self.id = id
|
|
||||||
self.parent = parent
|
|
||||||
self.file_path = file_path
|
|
||||||
|
|
||||||
@property
|
|
||||||
def therion_id(self):
|
|
||||||
if len(self.id) == 1:
|
|
||||||
return self.id[0]
|
|
||||||
return "{}@{}".format(self.name, self.namespace)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
return self.id[-1]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def namespace(self):
|
|
||||||
return ".".join(list(reversed(self.id[0:-1])))
|
|
||||||
|
|
||||||
def data(self, data):
|
|
||||||
self._data = data
|
|
||||||
self.scraps = Survey.parse(self)
|
|
||||||
|
|
||||||
def parse(self):
|
|
||||||
scraps = []
|
|
||||||
scrap = None
|
|
||||||
data = []
|
|
||||||
for index, line in enumerate(self.data):
|
|
||||||
match = re.match(scrap_reg, line)
|
|
||||||
if match:
|
|
||||||
id = self.id + [match.group(1)]
|
|
||||||
projection = "plan"
|
|
||||||
match = re.match(projection_reg, line)
|
|
||||||
if match:
|
|
||||||
projection = match.group(1)
|
|
||||||
scrap = Scrap(id[:], self, projection)
|
|
||||||
scraps = scraps + [scrap]
|
|
||||||
|
|
||||||
data = [line]
|
|
||||||
continue
|
|
||||||
match = re.match(end_scrap_reg, line)
|
|
||||||
if match:
|
|
||||||
id = self.id
|
|
||||||
data = data + [line]
|
|
||||||
scrap.data = data[:]
|
|
||||||
data = []
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Exempt drawing
|
|
||||||
match = drawnexemptplanre.match(line)
|
|
||||||
if match:
|
|
||||||
self.plan_drawn_override = True
|
|
||||||
match = drawnexemptextendedre.match(line)
|
|
||||||
if match:
|
|
||||||
self.extended_drawn_override = True
|
|
||||||
match = drawnexemptre.match(line)
|
|
||||||
if match:
|
|
||||||
self.plan_drawn_override = True
|
|
||||||
self.extended_drawn_override = True
|
|
||||||
|
|
||||||
data = data + [line]
|
|
||||||
self.scraps = scraps
|
|
||||||
|
|
||||||
|
|
||||||
class SurveyLoader:
|
|
||||||
_data = None
|
|
||||||
survey = None
|
|
||||||
surveys = {}
|
|
||||||
|
|
||||||
@property
|
|
||||||
def surveys_list(self):
|
|
||||||
return list(self.surveys.values())
|
|
||||||
|
|
||||||
@property
|
|
||||||
def base_surveys(self):
|
|
||||||
return [s for s in self.surveys_list if len(s.children) == 0]
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def load(file_path):
|
|
||||||
with open(file_path, "r", encoding="utf-8") as f:
|
|
||||||
data = f.read()
|
|
||||||
lines = []
|
|
||||||
for line in data.splitlines():
|
|
||||||
if not line.strip():
|
|
||||||
continue
|
|
||||||
# if line.lstrip().startswith("#"):
|
|
||||||
# continue
|
|
||||||
match = re.match(input_reg, line)
|
|
||||||
if match:
|
|
||||||
new_file_path = abspath(join(dirname(file_path), match.group(1)))
|
|
||||||
lines = lines + ["###filepath:{}".format(new_file_path)]
|
|
||||||
lines = lines + ["\t{}".format(l) for l in SurveyLoader.load(new_file_path)]
|
|
||||||
lines = lines + ["###filepath:{}".format(file_path)]
|
|
||||||
else:
|
|
||||||
lines.append(line.strip())
|
|
||||||
return lines
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def parse(lines, orig_file_path=None):
|
|
||||||
surveys = {}
|
|
||||||
id = []
|
|
||||||
file_path = orig_file_path
|
|
||||||
parent = None
|
|
||||||
survey = None
|
|
||||||
data = []
|
|
||||||
|
|
||||||
for index, line in enumerate(lines):
|
|
||||||
match = re.match(file_path_reg, line)
|
|
||||||
if match:
|
|
||||||
file_path = match.group(1)
|
|
||||||
continue
|
|
||||||
|
|
||||||
match = re.match(survey_reg, line)
|
|
||||||
if match:
|
|
||||||
id = id + [match.group(1)]
|
|
||||||
parent = survey
|
|
||||||
survey = Survey(id[:], parent, file_path)
|
|
||||||
surveys[".".join(id[:])] = survey
|
|
||||||
if parent:
|
|
||||||
parent.data = data[:]
|
|
||||||
parent.children = parent.children + [survey]
|
|
||||||
data = [line]
|
|
||||||
continue
|
|
||||||
|
|
||||||
match = re.match(end_survey_reg, line)
|
|
||||||
if match:
|
|
||||||
popped = id.pop()
|
|
||||||
data = data + [line]
|
|
||||||
survey.data = data[:]
|
|
||||||
if len(survey.children) == 0:
|
|
||||||
survey.parse()
|
|
||||||
if not survey.parent:
|
|
||||||
return survey, surveys
|
|
||||||
parent.data = parent.data + data
|
|
||||||
data = parent.data[:]
|
|
||||||
parent = survey.parent
|
|
||||||
survey = parent
|
|
||||||
|
|
||||||
continue
|
|
||||||
|
|
||||||
data = data + [line]
|
|
||||||
return parent, surveys
|
|
||||||
|
|
||||||
def __init__(self, file_path):
|
|
||||||
# print(f"\033[32mDebug SurveyLoader.load : \033[0m {file_path}")
|
|
||||||
self._data = SurveyLoader.load(file_path)
|
|
||||||
survey, surveys = SurveyLoader.parse(self._data, file_path)
|
|
||||||
self.survey = survey
|
|
||||||
self.surveys = surveys
|
|
||||||
|
|
||||||
def get_survey_by_id(self, therion_id):
|
|
||||||
id = []
|
|
||||||
if "@" in therion_id:
|
|
||||||
parts = therion_id.split("@")
|
|
||||||
id = list(reversed(parts[1].split("."))) + [parts[0]]
|
|
||||||
else:
|
|
||||||
id = list(reversed(therion_id.split(".")))
|
|
||||||
key = ".".join(id)
|
|
||||||
if key in self.surveys:
|
|
||||||
return self.surveys[key]
|
|
||||||
else:
|
|
||||||
potential_key = [k for k in self.surveys.keys() if k.endswith(".{}".format(key))]
|
|
||||||
if len(potential_key) == 1:
|
|
||||||
return self.surveys[potential_key[0]]
|
|
||||||
potential_keys = [k for k in self.surveys.keys() if key in k]
|
|
||||||
if len(potential_keys) == 1:
|
|
||||||
return self.surveys[potential_keys[0]]
|
|
||||||
elif len(potential_keys) > 1:
|
|
||||||
raise MultipleSurveyFoundException("Multiple surveys were found with that key:\n\t{}".format("\n\t".join(potential_keys)))
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
parser = argparse.ArgumentParser(description="Parse a survey")
|
|
||||||
parser.add_argument(
|
|
||||||
"survey_file",
|
|
||||||
help='The survey file (*.th) to work from. e.g. "data/system_migovec.th"',
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"survey_selector",
|
|
||||||
help='The selector for the survey to produce a scrap for. e.g. "roundpond@vrtnarija.vrtnarija_vilinska.system_migovec"',
|
|
||||||
)
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
entrypoint = abspath(args.survey_file)
|
|
||||||
loader = SurveyLoader(entrypoint)
|
|
||||||
print(loader.get_survey_by_id(args.survey_selector))
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import numpy as np
|
|
||||||
|
|
||||||
a = np.array([1,2,3,4,5])
|
|
||||||
|
|
||||||
print(a)
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
import tempfile
|
|
||||||
import shutil
|
|
||||||
import os
|
|
||||||
from os.path import join
|
|
||||||
import subprocess
|
|
||||||
import re
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
# Codes de couleur ANSI
|
|
||||||
class Colors:
|
|
||||||
BLACK = '\033[90m'
|
|
||||||
RED = '\033[91m'
|
|
||||||
GREEN = '\033[92m'
|
|
||||||
YELLOW = '\033[93m'
|
|
||||||
BLUE = '\033[94m'
|
|
||||||
MAGENTA = '\033[95m'
|
|
||||||
CYAN = '\033[96m'
|
|
||||||
WHITE = '\033[97m'
|
|
||||||
|
|
||||||
ERROR = '\033[91m'
|
|
||||||
WARNING = '\033[95m'
|
|
||||||
HEADER = '\033[96m'
|
|
||||||
|
|
||||||
ENDC = '\033[0m'
|
|
||||||
BOLD = '\033[1m'
|
|
||||||
UNDERLINE = '\033[4m'
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def compile_template(template, template_args, **kwargs):
|
|
||||||
try:
|
|
||||||
log = ""
|
|
||||||
tmpdir = tempfile.mkdtemp()
|
|
||||||
config = template.format(**template_args, tmpdir=tmpdir.replace("\\", "/"))
|
|
||||||
|
|
||||||
print(f"{Colors.YELLOW}{config}{Colors.ENDC}\n")
|
|
||||||
|
|
||||||
config_file = join(tmpdir, "config.thconfig")
|
|
||||||
log_file = join(tmpdir, "log.log")
|
|
||||||
therion_path = kwargs["therion_path"] if "therion_path" in kwargs else "therion"
|
|
||||||
with open(config_file, mode="w+", encoding="utf-8") as tmp:
|
|
||||||
with open(log_file, mode="w+") as tmp2:
|
|
||||||
tmp.write(config)
|
|
||||||
tmp.flush()
|
|
||||||
subprocess.check_output('''"{}" "{}" -l "{}"'''.format(therion_path, config_file, log_file), shell=True, )
|
|
||||||
tmp2.flush()
|
|
||||||
log = tmp2.read()
|
|
||||||
if kwargs["cleanup"]:
|
|
||||||
shutil.rmtree(tmpdir)
|
|
||||||
print("\n" )
|
|
||||||
return log, tmpdir
|
|
||||||
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{Colors.ERROR}Error: Therion template compilation error: {Colors.ENDC}{e}")
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def compile_file(filename, **kwargs):
|
|
||||||
try:
|
|
||||||
tmpdir = os.path.dirname(filename)
|
|
||||||
log_file = join(tmpdir, "log.log").replace("\\", "/")
|
|
||||||
therion_path = kwargs["therion_path"] if "therion_path" in kwargs else "therion"
|
|
||||||
|
|
||||||
# print(f"{Colors.BLUE}therion_path: {Colors.ENDC}{therion_path}")
|
|
||||||
# print(f"{Colors.BLUE}filename: {Colors.ENDC}{filename}")
|
|
||||||
# print(f"{Colors.BLUE}log_file: {Colors.ENDC}{log_file}")
|
|
||||||
|
|
||||||
# subprocess.check_output('''"{}" "{}" -l "{}"'''.format(therion_path, filename, log_file), shell=True, )
|
|
||||||
result = subprocess.run(
|
|
||||||
[therion_path, filename, "-l", log_file],
|
|
||||||
stdout=subprocess.PIPE, # Capture de la sortie standard
|
|
||||||
stderr=subprocess.PIPE, # Capture des erreurs
|
|
||||||
shell=True
|
|
||||||
)
|
|
||||||
|
|
||||||
stdout_with_tabs = "\n".join("\t" + line for line in result.stdout.decode().splitlines())
|
|
||||||
|
|
||||||
# Si la commande échoue, result.returncode sera non nul
|
|
||||||
if result.returncode != 0:
|
|
||||||
# Affichage des erreurs et de la sortie standard
|
|
||||||
print(f"{Colors.ERROR}Error during Therion compilation:{Colors.ENDC}")
|
|
||||||
print(f"{Colors.WARNING}stdout: {Colors.YELLOW}{stdout_with_tabs}{Colors.ENDC}")
|
|
||||||
print(f"{Colors.ERROR}stderr: \n{result.stderr.decode()}{Colors.ENDC}")
|
|
||||||
else:
|
|
||||||
# Si la commande réussit, affichez la sortie standard
|
|
||||||
print(f"{Colors.GREEN}Therion compilation succeeded.\n{Colors.YELLOW}{stdout_with_tabs}{Colors.ENDC}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{Colors.ERROR}Error: Therion file {Colors.ENDC}{filename}{Colors.ERROR} compilation error: {Colors.ENDC}{e}")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def compile_file_th(filepath, **kwargs):
|
|
||||||
template = """source {filepath}
|
|
||||||
layout test
|
|
||||||
scale 1 500
|
|
||||||
endlayout
|
|
||||||
"""
|
|
||||||
template_args = {"filepath": filepath}
|
|
||||||
logs, _ = compile_template(template, template_args, cleanup=True, **kwargs)
|
|
||||||
return logs
|
|
||||||
|
|
||||||
|
|
||||||
lengthre = re.compile(r".*Total length of survey legs =\s*(\S+)m")
|
|
||||||
depthre = re.compile(r".*Vertical range =\s*(\S+)m")
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def get_stats_from_log(log):
|
|
||||||
lenmatch = lengthre.findall(log)
|
|
||||||
depmatch = depthre.findall(log)
|
|
||||||
if len(lenmatch) == 1 and len(depmatch) == 1:
|
|
||||||
return {"length": lenmatch[0], "depth": depmatch[0]}
|
|
||||||
return {"length": 0, "depth": 0}
|
|
||||||
@@ -1,460 +0,0 @@
|
|||||||
from dataclasses import dataclass, field
|
|
||||||
import re
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Date:
|
|
||||||
"""A class which represents a string formatted date"""
|
|
||||||
year : int = 2000
|
|
||||||
month : int = 1
|
|
||||||
day : int = 1
|
|
||||||
date_string : str = field(init = False)
|
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
|
||||||
self.date_string = f"{self.year}.{self.month:02d}.{self.day:02d}"
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class StationWithComment:
|
|
||||||
name : str
|
|
||||||
comment : str
|
|
||||||
command : str = field(init=False)
|
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
|
||||||
self.command = f'station {self.name} "{self.comment}"'
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class LineLRUD:
|
|
||||||
from_station : str
|
|
||||||
left : float
|
|
||||||
right : float
|
|
||||||
up : float
|
|
||||||
down : float
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class DataLine:
|
|
||||||
from_station : str
|
|
||||||
to_station : str
|
|
||||||
tape : float
|
|
||||||
compass : float
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class NormalDataLine(DataLine):
|
|
||||||
clino : float
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class DivingDataLine(DataLine):
|
|
||||||
to_depth : float
|
|
||||||
from_depth : float
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Centreline:
|
|
||||||
|
|
||||||
explo_date : Date = Date()
|
|
||||||
explorers : list[str] = field(init= False, default_factory= list)
|
|
||||||
type : str = "normal"
|
|
||||||
data_header : list[str] = field(init= False, default_factory= list)
|
|
||||||
units_length : dict[str, str] = field(default_factory=lambda: {"units length" : "meters"})
|
|
||||||
units_compass_clino : dict[str, str] = field(default_factory=lambda: {"units compass clino": "degrees"})
|
|
||||||
lrud_reader : list[str] = field(default_factory=lambda: ["data", "dimensions", "station", "left", "right", "up", "down"])
|
|
||||||
data : list[DataLine] = field(init=False, default_factory= list)
|
|
||||||
lrud_data : list[LineLRUD] = field(init=False, default_factory= list)
|
|
||||||
commented_stations : list[StationWithComment] = field(init=False, default_factory=list)
|
|
||||||
_string_repr : str = field(init=False, default_factory= str)
|
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
|
||||||
if self.type == 'normal':
|
|
||||||
self.data_header = ["data", "normal", "from", "to", "tape", "compass", "clino"]
|
|
||||||
elif self.type == "normal_backclino":
|
|
||||||
self.data_header = ["data", "normal", "from", "to", "tape", "compass", "backclino"]
|
|
||||||
elif self.type == "normal_backcompass":
|
|
||||||
self.data_header = ["data", "normal", "from", "to", "tape", "backcompass", "clino"]
|
|
||||||
elif self.type == "normal_backcompass_backclino":
|
|
||||||
self.data_header = ["data", "normal", "from", "to", "tape", "backcompass", "backclino"]
|
|
||||||
elif self.type == "diving":
|
|
||||||
self.data_header = ["data", "diving", "from", "fromdepth","to", "todepth", "tape", "compass"]
|
|
||||||
elif self.type == "diving_backcompass":
|
|
||||||
self.data_header = ["data", "diving", "from", "fromdepth","to", "todepth", "tape", "backcompass"]
|
|
||||||
|
|
||||||
def add_explorers(self, explorers : list[str]) -> None:
|
|
||||||
self.explorers += explorers
|
|
||||||
|
|
||||||
def add_dataline(self, line: DataLine) -> None:
|
|
||||||
self.data+= [line]
|
|
||||||
|
|
||||||
def add_station_line(self, station : StationWithComment) -> None:
|
|
||||||
self.commented_stations.append(station)
|
|
||||||
|
|
||||||
def add_LRUDdataline(self, line: LineLRUD) -> None:
|
|
||||||
self.lrud_data+= [line]
|
|
||||||
|
|
||||||
def add_Date(self, date: str) -> None:
|
|
||||||
DATE = date.split(".")
|
|
||||||
self.date = Date(year=int(DATE[0]),month=int(DATE[0]),day=int(DATE[2]))
|
|
||||||
self.explo_date = Date(year=int(DATE[0]),month=int(DATE[1]),day=int(DATE[2]))
|
|
||||||
|
|
||||||
def update_type(self, type: str):
|
|
||||||
self.type = type
|
|
||||||
self.__post_init__()
|
|
||||||
|
|
||||||
def add_string_repr(self) -> None:
|
|
||||||
|
|
||||||
explorers = ""
|
|
||||||
for explorer in self.explorers:
|
|
||||||
explorers += f"explo-team {explorer}\n\t"
|
|
||||||
|
|
||||||
formatted_data : str = ""
|
|
||||||
formatted_lrud : str = ""
|
|
||||||
formatted_comments : str = ""
|
|
||||||
|
|
||||||
|
|
||||||
for line,lrud_line in zip(self.data,self.lrud_data):
|
|
||||||
if "clino" in self.data_header:
|
|
||||||
formatted_data += f"""
|
|
||||||
{line.from_station}\t{line.to_station}\t{line.tape}\t{line.compass}\t{line.clino}\t""" # type: ignore
|
|
||||||
formatted_lrud += f"""
|
|
||||||
{lrud_line.from_station}\t{lrud_line.left}\t{lrud_line.right}\t{lrud_line.up}\t{lrud_line.down}\t"""
|
|
||||||
|
|
||||||
elif "todepth" in self.data_header:
|
|
||||||
formatted_data += f"""
|
|
||||||
{line.from_station}\t{line.from_depth}\t{line.to_station}\t{line.to_depth}\t{line.tape}\t{line.compass}\t""" # type: ignore
|
|
||||||
formatted_lrud += f"""
|
|
||||||
{lrud_line.from_station}\t{lrud_line.left}\t{lrud_line.right}\t{lrud_line.up}\t{lrud_line.down}\t"""
|
|
||||||
|
|
||||||
for comment in self.commented_stations:
|
|
||||||
formatted_comments += f"""
|
|
||||||
{comment.command}"""
|
|
||||||
|
|
||||||
self._string_repr = f"""
|
|
||||||
centreline
|
|
||||||
|
|
||||||
explo-date {self.explo_date.date_string}
|
|
||||||
date {self.explo_date.date_string}
|
|
||||||
|
|
||||||
{explorers}
|
|
||||||
{join(self.data_header)}
|
|
||||||
{formatted_data}
|
|
||||||
|
|
||||||
{join(self.lrud_reader)}
|
|
||||||
{formatted_lrud}
|
|
||||||
|
|
||||||
{formatted_comments}
|
|
||||||
|
|
||||||
endcentreline"""
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Survey:
|
|
||||||
name : str
|
|
||||||
entrance : str = field(init= False, default_factory= str)
|
|
||||||
centrelines : list[Centreline] = field(init= False, default_factory= list)
|
|
||||||
_string_repr : str = field(init=False, default_factory= str)
|
|
||||||
|
|
||||||
|
|
||||||
def add_centrelines(self, centrelines: list[Centreline]) -> None:
|
|
||||||
self.centrelines += centrelines
|
|
||||||
|
|
||||||
def add_entrance(self, entrance : str) -> None:
|
|
||||||
self.entrance = entrance
|
|
||||||
|
|
||||||
def add_string_repr(self) -> None:
|
|
||||||
|
|
||||||
centrelines = ""
|
|
||||||
for centreline in self.centrelines:
|
|
||||||
centrelines += f"{centreline._string_repr}\n"
|
|
||||||
|
|
||||||
self._string_repr = f"""
|
|
||||||
## a survey compiled from Visual Topo Data using the visual_therion.py script
|
|
||||||
|
|
||||||
survey "{self.name}" -entrance {self.entrance}
|
|
||||||
{centrelines}
|
|
||||||
endsurvey
|
|
||||||
"""
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class StrategyParser:
|
|
||||||
input_str : str
|
|
||||||
compass : str = "normal"
|
|
||||||
clino : str = "normal"
|
|
||||||
strategy_name: str = "normal"
|
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
|
||||||
if "Dir,Dir,Inv" in self.input_str:
|
|
||||||
self.clino = "back"
|
|
||||||
self.strategy_name = "normal_backclino"
|
|
||||||
|
|
||||||
elif "Inv,Inv,Dir" in self.input_str or "Inv,Dir,Dir" in self.input_str:
|
|
||||||
self.compass = "back"
|
|
||||||
if "Prof" in self.input_str:
|
|
||||||
self.strategy_name = "diving_backcompass"
|
|
||||||
else:
|
|
||||||
self.strategy_name = "normal_backcompass"
|
|
||||||
|
|
||||||
elif "Inv,Inv,Inv" in self.input_str:
|
|
||||||
self.compass = "back"
|
|
||||||
self.clino = "back"
|
|
||||||
self.strategy_name = "normal_backcompass_backclino"
|
|
||||||
|
|
||||||
elif ("Dir Dir Dir" in self.input_str) and ("Prof") in self.input_str:
|
|
||||||
self.strategy_name = "diving"
|
|
||||||
|
|
||||||
|
|
||||||
def join(l : list[str])-> str:
|
|
||||||
newstr = ""
|
|
||||||
|
|
||||||
for elem in l:
|
|
||||||
newstr += f"{elem} "
|
|
||||||
|
|
||||||
return newstr
|
|
||||||
|
|
||||||
def find_entrance_stn(data: list[str], format : str) -> str:
|
|
||||||
if format == "tro":
|
|
||||||
"""Search the visual topo file for the entrance station"""
|
|
||||||
for c,l in enumerate(data):
|
|
||||||
if 'Entree' in l:
|
|
||||||
entrance_stations = re.findall(r"(?<=Entree\s).+",l)
|
|
||||||
else:
|
|
||||||
for c,l in enumerate(data):
|
|
||||||
if '<Entree>' in l:
|
|
||||||
entrance_stations = re.findall(r"(?<=<Entree>)[0-9a-z]+",l)
|
|
||||||
|
|
||||||
return entrance_stations[0] # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
def return_centreline_params(data: list[str], fmt: str):
|
|
||||||
if fmt == "tro":
|
|
||||||
return return_centreline_params_tro(data)
|
|
||||||
else:
|
|
||||||
return return_centreline_params_trox(data)
|
|
||||||
|
|
||||||
def return_centreline_params_trox(data):
|
|
||||||
start,end = [],[]
|
|
||||||
survey_dates = []
|
|
||||||
surveyor_groups = []
|
|
||||||
|
|
||||||
for c,l in enumerate(data):
|
|
||||||
if ('Param' in l) and ('/Param' not in l):
|
|
||||||
if 'Comment' in data[c+1]:
|
|
||||||
if len(start) >= 1:
|
|
||||||
end.append(c-1)
|
|
||||||
start.append(c+2)
|
|
||||||
else:
|
|
||||||
if len(start) >= 1:
|
|
||||||
end.append(c-1)
|
|
||||||
start.append(c+1)
|
|
||||||
|
|
||||||
reg_explodate = re.findall(r'(?<=Date\=")\d\d\/\d\d\/\d\d\d\d', l)
|
|
||||||
reg_explodate = [elem for elem in reg_explodate[0].split("/")]
|
|
||||||
explodate = "{yyyy}.{mm}.{dd}".format(yyyy =reg_explodate[2], mm =reg_explodate[1], dd = reg_explodate[0])
|
|
||||||
if len(explodate) == 0:
|
|
||||||
survey_dates.append('')
|
|
||||||
else:
|
|
||||||
survey_dates.append(re.sub(r"/",".",explodate))
|
|
||||||
tp = re.findall(r"(?<=Topo réalisée par )[\w+\s]*",l)
|
|
||||||
if len(tp) == 0:
|
|
||||||
surveyor_groups.append('')
|
|
||||||
else:
|
|
||||||
surveyor_groups.append(tp[0].split(' '))
|
|
||||||
elif 'Configuration' in l:
|
|
||||||
end.append(c-1)
|
|
||||||
|
|
||||||
return surveyor_groups,survey_dates,start,end
|
|
||||||
|
|
||||||
|
|
||||||
def return_centreline_params_tro(data):
|
|
||||||
# find the parameters of the file.
|
|
||||||
start,end = [],[]
|
|
||||||
survey_dates = []
|
|
||||||
surveyor_groups = []
|
|
||||||
|
|
||||||
for c,l in enumerate(data):
|
|
||||||
if 'Param' in l:
|
|
||||||
if len(start) >= 1:
|
|
||||||
end.append(c-1)
|
|
||||||
start.append(c+1)
|
|
||||||
|
|
||||||
|
|
||||||
explodate = re.findall(r"\d\d.\d\d.\d\d", l)
|
|
||||||
if len(explodate) == 0:
|
|
||||||
survey_dates.append('')
|
|
||||||
else:
|
|
||||||
survey_dates.append(re.sub(r"-",".",explodate[0]))
|
|
||||||
tp = re.findall(r"(?<=Topo réalisée par )[\w+\s]*",l)
|
|
||||||
if len(tp) == 0:
|
|
||||||
surveyor_groups.append('')
|
|
||||||
else:
|
|
||||||
surveyor_groups.append(tp[0].split(' '))
|
|
||||||
elif 'Configuration' in l:
|
|
||||||
end.append(c-1)
|
|
||||||
|
|
||||||
return surveyor_groups,survey_dates,start,end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def parseFloat(x: str) -> float:
|
|
||||||
try:
|
|
||||||
X = float(x)
|
|
||||||
return X
|
|
||||||
except ValueError:
|
|
||||||
X = 0.
|
|
||||||
return X
|
|
||||||
|
|
||||||
|
|
||||||
def parse_CommentedStations(lines : list[str]) -> list[StationWithComment]:
|
|
||||||
parsed_lines = [[elem for elem in line.split(";") if elem != ""] for line in lines[1:]]
|
|
||||||
stations_list = []
|
|
||||||
for line in parsed_lines:
|
|
||||||
if len(line) > 1:
|
|
||||||
stn_name = [elem for elem in line[0].split(" ") if elem != ""][0]
|
|
||||||
comment = line[1]
|
|
||||||
station = StationWithComment(stn_name,comment)
|
|
||||||
stations_list.append(station)
|
|
||||||
return stations_list
|
|
||||||
|
|
||||||
def parse_LRUDS(lines: list[str], format : str) -> list[LineLRUD]:
|
|
||||||
if format == "tro":
|
|
||||||
LRUDlines = [[elem for elem in line.split(" ") if elem != ""] for line in lines[:]]
|
|
||||||
elif format == "trox":
|
|
||||||
print("parsing a trox file")
|
|
||||||
LRUDlines = []
|
|
||||||
LRUDlines.append([elem.split("=")[-1].strip('"') for elem in lines[0].split(" ")[1:] if elem != ""])
|
|
||||||
LRUDlines = LRUDlines + [["*"]+[elem.split("=")[-1].strip('"') for elem in line.split(" ")[1:] if elem != ""] for line in lines[:]]
|
|
||||||
else:
|
|
||||||
LRUDlines = [[]]
|
|
||||||
lrud_lines = []
|
|
||||||
|
|
||||||
|
|
||||||
for c,line in enumerate(LRUDlines):
|
|
||||||
if "*" in line[0] and len(line) >=9:
|
|
||||||
LRUDline =LineLRUD(LRUDlines[c][1],parseFloat(line[5]),parseFloat(line[6]),parseFloat(line[7]),parseFloat(line[8]))
|
|
||||||
elif len(line) >=9:
|
|
||||||
LRUDline =LineLRUD(line[1],parseFloat(line[5]),parseFloat(line[6]),parseFloat(line[7]),parseFloat(line[8]))
|
|
||||||
else:
|
|
||||||
print("skipping empty line {}".format(c))
|
|
||||||
if len(line) >=9:
|
|
||||||
if line[0] != line[1]:
|
|
||||||
#check there is no asterisk
|
|
||||||
lrud_lines.append(LRUDline) # type:ignore
|
|
||||||
|
|
||||||
return lrud_lines
|
|
||||||
|
|
||||||
def parse_normal_data(lines: list[str], format: str ) -> list[NormalDataLine]:
|
|
||||||
|
|
||||||
if format == "tro":
|
|
||||||
datalines = [[elem for elem in line.split(" ") if elem != ""] for line in lines[1:]]
|
|
||||||
elif format == "trox":
|
|
||||||
print("parsing a trox file")
|
|
||||||
datalines: list = []
|
|
||||||
datalines.append([elem.split("=")[-1].strip('"') for elem in lines[0].split(" ")[1:] if elem != ""])
|
|
||||||
|
|
||||||
for line in lines[1:]:
|
|
||||||
if "Dep=" in line:
|
|
||||||
datalines.append([elem.split("=")[-1].strip('"') for elem in line.split(" ")[1:] if elem != ""])
|
|
||||||
else:
|
|
||||||
datalines.append(["*"]+[elem.split("=")[-1].strip('"') for elem in line.split(" ")[1:] if elem != ""])
|
|
||||||
else:
|
|
||||||
datalines = [[]]
|
|
||||||
|
|
||||||
dataLines = []
|
|
||||||
|
|
||||||
for c,line in enumerate(datalines):
|
|
||||||
if "*" in line[0] and len(line) >=9:
|
|
||||||
dataLine = NormalDataLine(datalines[c-1][1],line[1],float(line[2]),float(line[3]),float(line[4]))
|
|
||||||
print(line)
|
|
||||||
elif len(line) >=9:
|
|
||||||
dataLine = NormalDataLine(line[0],line[1],float(line[2]),float(line[3]),float(line[4]))
|
|
||||||
else:
|
|
||||||
print("skipping empty line {}".format(c))
|
|
||||||
if dataLine.tape != 0: # type:ignore
|
|
||||||
dataLines.append(dataLine) # type:ignore
|
|
||||||
|
|
||||||
return dataLines
|
|
||||||
|
|
||||||
def parse_diving_data(lines: list[str], format: str) -> list[DivingDataLine]:
|
|
||||||
|
|
||||||
if format == "tro":
|
|
||||||
datalines = [[elem for elem in line.split(" ") if elem != ""] for line in lines[1:]]
|
|
||||||
elif format == "trox":
|
|
||||||
print("parsing a trox file")
|
|
||||||
datalines = []
|
|
||||||
datalines.append([elem.split("=")[-1].strip('"') for elem in lines[0].split(" ")[1:] if elem != ""])
|
|
||||||
datalines = datalines + [["*"]+[elem.split("=")[-1].strip('"') for elem in line.split(" ")[1:] if elem != ""] for line in lines[1:]]
|
|
||||||
else:
|
|
||||||
print("oops empty")
|
|
||||||
datalines = [[]]
|
|
||||||
|
|
||||||
|
|
||||||
dataLines = []
|
|
||||||
|
|
||||||
for c,line in enumerate(datalines[:]): # keep and index and ignore the first one.
|
|
||||||
if len(line) >=9:
|
|
||||||
if "*" in line and len(datalines[c-1]) > 9:
|
|
||||||
dataLine = DivingDataLine(from_depth= float(datalines[c][4]),
|
|
||||||
from_station= datalines[c-1][1],
|
|
||||||
to_depth= float(line[4]),
|
|
||||||
to_station=line[1],
|
|
||||||
tape= float(line[2]),
|
|
||||||
compass =float(line[3]))
|
|
||||||
else:
|
|
||||||
dataLine = DivingDataLine(from_depth= float(datalines[c][4]),
|
|
||||||
from_station= line[0],
|
|
||||||
to_depth= float(line[4]),
|
|
||||||
to_station=line[1],
|
|
||||||
tape= float(line[2]),
|
|
||||||
compass =float(line[3]))
|
|
||||||
|
|
||||||
if dataLine.tape != 0:
|
|
||||||
dataLines.append(dataLine)
|
|
||||||
|
|
||||||
return dataLines
|
|
||||||
|
|
||||||
def make_centrelines_list(data : list[str], format: str ) -> list[Centreline]:
|
|
||||||
|
|
||||||
surveyor_groups,survey_dates,starts,ends = return_centreline_params(data, fmt= format) # type:ignore
|
|
||||||
|
|
||||||
centrelines : list[Centreline] = []
|
|
||||||
|
|
||||||
for start,end,date in zip(starts,ends,survey_dates):
|
|
||||||
newCentreline = Centreline()
|
|
||||||
newCentreline.add_Date(date)
|
|
||||||
if format == "tro":
|
|
||||||
header = data[start-1]
|
|
||||||
else:
|
|
||||||
if "Comment" in data[start-1]:
|
|
||||||
header = ""
|
|
||||||
for elem in data[start-2].split(" ")[1:]:
|
|
||||||
header += elem.split("=")[-1].strip('"')+" "
|
|
||||||
else:
|
|
||||||
header = ""
|
|
||||||
for elem in data[start-1].split(" ")[1:]:
|
|
||||||
header += elem.split("=")[-1].strip('"')+" "
|
|
||||||
|
|
||||||
print("data header: ", newCentreline.data_header)
|
|
||||||
strategy = StrategyParser(header)
|
|
||||||
|
|
||||||
newCentreline.update_type(strategy.strategy_name)
|
|
||||||
station_lines = parse_CommentedStations(data[start:end])
|
|
||||||
|
|
||||||
if "normal" in strategy.strategy_name:
|
|
||||||
lrudLines = parse_LRUDS(data[start:end], format = format)
|
|
||||||
dataLines = parse_normal_data(data[start:end], format= format)
|
|
||||||
|
|
||||||
for dataLine,lrudLine in zip(dataLines,lrudLines):
|
|
||||||
newCentreline.add_dataline(dataLine)
|
|
||||||
newCentreline.add_LRUDdataline(lrudLine)
|
|
||||||
|
|
||||||
|
|
||||||
elif "diving" in strategy.strategy_name:
|
|
||||||
lrudLines = parse_LRUDS(data[start:end], format = format)
|
|
||||||
dataLines = parse_diving_data(data[start:end], format = format)
|
|
||||||
|
|
||||||
for dataLine,lrudLine in zip(dataLines,lrudLines):
|
|
||||||
newCentreline.add_dataline(dataLine)
|
|
||||||
newCentreline.add_LRUDdataline(lrudLine)
|
|
||||||
|
|
||||||
for line in station_lines:
|
|
||||||
newCentreline.add_station_line(line)
|
|
||||||
|
|
||||||
newCentreline.add_string_repr()
|
|
||||||
centrelines.append(newCentreline)
|
|
||||||
|
|
||||||
return centrelines
|
|
||||||
|
|
||||||
@@ -1,993 +0,0 @@
|
|||||||
|
|
||||||
"""
|
|
||||||
#############################################################################################
|
|
||||||
# #
|
|
||||||
# Script pour automatiser la création des dossiers et fichiers pour un fichier .th #
|
|
||||||
# #
|
|
||||||
# By Alexandre PONT (alexandre_pont@yahoo.fr) #
|
|
||||||
# #
|
|
||||||
# Définir les différentes variables dans fichier config.ini #
|
|
||||||
# Création des dossiers nécessaires d'après dossier 'template' #
|
|
||||||
# Création des fichiers nécessaires : th, th2, -tot.th #
|
|
||||||
# Création des scrap avec stations topo #
|
|
||||||
# #
|
|
||||||
# usage : python pyCreate_th2.py #
|
|
||||||
# #
|
|
||||||
#############################################################################################
|
|
||||||
|
|
||||||
Création Alex the 2024 12 16 :
|
|
||||||
Thank's too
|
|
||||||
- Tanguy Racine for the script https://github.com/tr1813
|
|
||||||
- Xavier Robert for the main principes https://github.com/robertxa
|
|
||||||
- Benoit Urruty https://github.com/BenoitURRUTY
|
|
||||||
|
|
||||||
Version 2025 03 21 : Création mode --update th2
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
Version ="2025.03.21"
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
#################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
|
||||||
from os.path import isfile, join, abspath
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
import unicodedata
|
|
||||||
import argparse
|
|
||||||
import shutil
|
|
||||||
from datetime import datetime
|
|
||||||
import configparser
|
|
||||||
import tkinter as tk
|
|
||||||
from tkinter import filedialog
|
|
||||||
|
|
||||||
from helpers.survey import SurveyLoader, NoSurveysFoundException
|
|
||||||
from helpers.therion import compile_template, Colors, compile_file
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
|
|
||||||
## [Survey_Data] default values
|
|
||||||
Author = "Created by pyCreate_th2.py"
|
|
||||||
Copyright = "# Copyright (C) pyCreate_th2.py"
|
|
||||||
Copyright_Short = "Licence (C) pyCreate_th2.py"
|
|
||||||
map_comment = "Created by pyCreate_th2.py"
|
|
||||||
cs = "UTM30"
|
|
||||||
club = "Therion"
|
|
||||||
thanksto = "Therion"
|
|
||||||
datat = "https://therion.speleo.sk/"
|
|
||||||
wpage = "https://therion.speleo.sk/"
|
|
||||||
|
|
||||||
## [Application_data] default values
|
|
||||||
template_path = "./template"
|
|
||||||
station_by_scrap = 20
|
|
||||||
final_therion_exe = True
|
|
||||||
therion_path = "C:/Therion/therion.exe"
|
|
||||||
LINES = -1
|
|
||||||
NAMES = -1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
# # Codes de couleur ANSI
|
|
||||||
# class Colors:
|
|
||||||
# BLACK = '\033[90m'
|
|
||||||
# RED = '\033[91m'
|
|
||||||
# GREEN = '\033[92m'
|
|
||||||
# YELLOW = '\033[93m'
|
|
||||||
# BLUE = '\033[94m'
|
|
||||||
# MAGENTA = '\033[95m'
|
|
||||||
# CYAN = '\033[96m'
|
|
||||||
# WHITE = '\033[97m'
|
|
||||||
|
|
||||||
# ERROR = '\033[91m'
|
|
||||||
# WARNING = '\033[95m'
|
|
||||||
# HEADER = '\033[96m'
|
|
||||||
|
|
||||||
# ENDC = '\033[0m'
|
|
||||||
# BOLD = '\033[1m'
|
|
||||||
# UNDERLINE = '\033[4m'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def sanitize_filename(th_name):
|
|
||||||
"""
|
|
||||||
Cleans a string to make it compatible with filenames on Windows, Linux, and macOS.
|
|
||||||
Replaces special and accented characters with compatible characters.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
th_name (str): The filename to clean.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The cleaned and compatible string.
|
|
||||||
"""
|
|
||||||
# Unicode normalization to replace accented characters with their non-accented equivalents
|
|
||||||
th_name = unicodedata.normalize('NFKD', th_name).encode('ASCII', 'ignore').decode('ASCII')
|
|
||||||
|
|
||||||
# Replace illegal characters with an underscore (_)
|
|
||||||
th_name = re.sub(r'[<>:"/\\|?*\']', '_', th_name) # Characters not allowed on Windows
|
|
||||||
th_name = re.sub(r'[\s]', '_', th_name) # Replace spaces with underscores
|
|
||||||
th_name = re.sub(r'[^a-zA-Z0-9._-]', '_', th_name) # Keep letters, digits, . _ -
|
|
||||||
|
|
||||||
# Ensure the name is not empty or just underscores
|
|
||||||
return th_name.strip('_') or "default_filename"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def colored_help(parser):
|
|
||||||
# Captures the help output
|
|
||||||
help_text = parser.format_help()
|
|
||||||
|
|
||||||
# Coloration des différentes parties
|
|
||||||
colored_help_text = help_text.replace(
|
|
||||||
'usage:', f'{Colors.ERROR}usage:{Colors.ENDC}'
|
|
||||||
).replace(
|
|
||||||
'options:', f'{Colors.GREEN}options:{Colors.ENDC}'
|
|
||||||
).replace('positional arguments:', f'{Colors.BLUE}positional arguments:{Colors.ENDC}')
|
|
||||||
|
|
||||||
# Surligner les arguments
|
|
||||||
for action in parser._actions:
|
|
||||||
if action.option_strings:
|
|
||||||
# Colorer les options (--xyz)
|
|
||||||
for opt in action.option_strings:
|
|
||||||
colored_help_text = colored_help_text.replace(opt, f'{Colors.BLUE}{opt}{Colors.ENDC}')
|
|
||||||
|
|
||||||
# Imprimer le texte coloré
|
|
||||||
print(colored_help_text)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def read_config(config_file):
|
|
||||||
global Author
|
|
||||||
global Copyright
|
|
||||||
global Copyright_Short
|
|
||||||
global map_comment
|
|
||||||
global club
|
|
||||||
global thanksto
|
|
||||||
global datat
|
|
||||||
global wpage
|
|
||||||
global cs
|
|
||||||
global template_path
|
|
||||||
global station_by_scrap
|
|
||||||
global final_therion_exe
|
|
||||||
global therion_path
|
|
||||||
global LINES
|
|
||||||
global NAMES
|
|
||||||
|
|
||||||
|
|
||||||
# Initialize the configparser to read .ini files
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config.read(config_file, encoding="utf-8")
|
|
||||||
|
|
||||||
if 'Survey_Data' in config and 'Author' in config['Survey_Data']:
|
|
||||||
Author = config['Survey_Data']['Author']
|
|
||||||
|
|
||||||
if 'Survey_Data' in config and 'Copyright1' in config['Survey_Data']:
|
|
||||||
Copyright = config['Survey_Data']['Copyright1'] + "\n" + config['Survey_Data']['Copyright2'] + "\n" + config['Survey_Data']['Copyright3'] + "\n"
|
|
||||||
|
|
||||||
if 'Survey_Data' in config and 'Copyright_Short' in config['Survey_Data']:
|
|
||||||
Copyright_Short = config['Survey_Data']['Copyright_Short']
|
|
||||||
|
|
||||||
if 'Survey_Data' in config and 'map_comment' in config['Survey_Data']:
|
|
||||||
map_comment = config['Survey_Data']['map_comment']
|
|
||||||
|
|
||||||
if 'Survey_Data' in config and 'club' in config['Survey_Data']:
|
|
||||||
club = config['Survey_Data']['club']
|
|
||||||
|
|
||||||
if 'Survey_Data' in config and 'thanksto' in config['Survey_Data']:
|
|
||||||
thanksto = config['Survey_Data']['thanksto']
|
|
||||||
|
|
||||||
if 'Survey_Data' in config and 'datat' in config['Survey_Data']:
|
|
||||||
datat = config['Survey_Data']['datat']
|
|
||||||
|
|
||||||
if 'Survey_Data' in config and 'wpage' in config['Survey_Data']:
|
|
||||||
wpage = config['Survey_Data']['wpage']
|
|
||||||
|
|
||||||
if 'Survey_Data' in config and 'cs' in config['Survey_Data']:
|
|
||||||
cs = config['Survey_Data']['cs']
|
|
||||||
|
|
||||||
if 'Application_Data' in config and 'template_path' in config['Application_Data']:
|
|
||||||
template_path = config['Application_Data']['template_path']
|
|
||||||
|
|
||||||
if 'Application_Data' in config and 'station_by_scrap' in config['Application_Data']:
|
|
||||||
station_by_scrap = int(config['Application_Data']['station_by_scrap'])
|
|
||||||
|
|
||||||
if 'Application_Data' in config and 'final_therion_exe' in config['Application_Data']:
|
|
||||||
final_therion_exe = bool(config['Application_Data']['final_therion_exe'])
|
|
||||||
|
|
||||||
if 'Application_Data' in config and 'therion_path' in config['Application_Data']:
|
|
||||||
therion_path = config['Application_Data']['therion_path']
|
|
||||||
|
|
||||||
if LINES == -1 :
|
|
||||||
if 'Application_Data' in config and 'shot_lines_in_th2_files' in config['Application_Data']:
|
|
||||||
LINES = 0 if config['Application_Data']['shot_lines_in_th2_files'] == "False" else 1
|
|
||||||
|
|
||||||
if NAMES == -1 :
|
|
||||||
if 'Application_Data' in config and 'station_name_in_th2_files' in config['Application_Data']:
|
|
||||||
NAMES = 0 if config['Application_Data']['station_name_in_th2_files'] == "False" else 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def copy_template_if_not_exists(template_path, destination_path):
|
|
||||||
# Check if the destination folder exists
|
|
||||||
try:
|
|
||||||
if not os.path.exists(destination_path):
|
|
||||||
# If the destination folder does not exist, copy the template
|
|
||||||
shutil.copytree(template_path, destination_path)
|
|
||||||
print(f"{Colors.GREEN}The folder '{Colors.GREEN}{template_path}{Colors.ENDC}' has been copied to '{Colors.ENDC}{destination_path}{Colors.GREEN}'{Colors.ENDC}")
|
|
||||||
else:
|
|
||||||
print(f"{Colors.WARNING}Warning: The folder '{Colors.ENDC}{destination_path}{Colors.WARNING}' already exists. No files were copied.{Colors.ENDC}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{Colors.ERROR}Copy template error: {Colors.ENDC}{e}")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def add_copyright_header(file_path, copyright_text):
|
|
||||||
# Lire le contenu du fichier
|
|
||||||
with open(file_path, 'r') as file:
|
|
||||||
content = file.readlines()
|
|
||||||
|
|
||||||
# Vérifier si le copyright est déjà présent
|
|
||||||
if not any("copyright" in line.lower() for line in content):
|
|
||||||
# Ajouter le copyright en en-tête
|
|
||||||
content.insert(0, f"{copyright_text}\n")
|
|
||||||
|
|
||||||
# Réécrire le fichier avec le copyright ajouté
|
|
||||||
with open(file_path, 'w') as file:
|
|
||||||
file.writelines(content)
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def copy_file_with_copyright(th_file, destination_path, copyright_text):
|
|
||||||
# Vérifier si le fichier existe
|
|
||||||
if os.path.exists(th_file):
|
|
||||||
# Créer le dossier de destination s'il n'existe pas
|
|
||||||
os.makedirs(destination_path, exist_ok=True)
|
|
||||||
|
|
||||||
# Copier le fichier vers le dossier de destination
|
|
||||||
dest_file = os.path.join(destination_path, os.path.basename(th_file))
|
|
||||||
shutil.copy(th_file, dest_file)
|
|
||||||
|
|
||||||
# Ajouter le copyright dans l'en-tête si nécessaire
|
|
||||||
add_copyright_header(dest_file, copyright_text)
|
|
||||||
|
|
||||||
# print(f"{Colors.GREEN}File '{Colors.ENDC}{th_file}{Colors.GREEN}' has been copied to '{Colors.ENDC}{destination_path}{Colors.GREEN}' with the copyright header added.{Colors.ENDC}")
|
|
||||||
else:
|
|
||||||
print(f"{Colors.ERROR}Error: The file .th does not exist {Colors.ENDC}{th_file}")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def process_template(template_path, variables, output_path):
|
|
||||||
"""
|
|
||||||
Process a Therion template file by replacing variables.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
template_path (str): Path to the original template file
|
|
||||||
variables (dict): Dictionary of variables to replace
|
|
||||||
output_path (str): Path for the new configuration file
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# Read the content of the template file
|
|
||||||
with open(template_path, 'r', encoding='utf-8') as file:
|
|
||||||
content = file.read()
|
|
||||||
|
|
||||||
# Replace variables
|
|
||||||
for var, value in variables.items():
|
|
||||||
# Use regex to replace {variable} with its value
|
|
||||||
pattern = r'\{' + re.escape(var) + r'\}'
|
|
||||||
content = re.sub(pattern, str(value), content)
|
|
||||||
|
|
||||||
# Write the new file
|
|
||||||
with open(output_path, 'w', encoding='utf-8') as file:
|
|
||||||
file.write(content)
|
|
||||||
|
|
||||||
print(f"{Colors.GREEN}Update template successfully: {Colors.ENDC}{output_path}")
|
|
||||||
|
|
||||||
# Delete the original template file
|
|
||||||
os.remove(template_path)
|
|
||||||
|
|
||||||
except FileNotFoundError:
|
|
||||||
print(f"{Colors.WARNING}Warning: Template file {Colors.ENDC}{template_path}{Colors.WARNING} not found.{Colors.ENDC}")
|
|
||||||
except PermissionError:
|
|
||||||
print(f"{Colors.ERROR}Error: Insufficient permissions to write the file.{Colors.ENDC}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{Colors.ERROR}An error occurred: {Colors.ENDC}{e}")
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def parse_therion_surveys(file_path):
|
|
||||||
"""
|
|
||||||
Reads a Therion file and extracts survey names.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
file_path (str): Path to the Therion file to parse
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list: List of survey names
|
|
||||||
"""
|
|
||||||
survey_names = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(file_path, 'r', encoding='utf-8') as file:
|
|
||||||
# Read all lines from the file
|
|
||||||
lines = file.readlines()
|
|
||||||
|
|
||||||
for line in lines:
|
|
||||||
# Look for lines starting with survey
|
|
||||||
line = line.strip()
|
|
||||||
if line.startswith('survey ') and ' -title ' in line:
|
|
||||||
# Split the line and extract the survey name
|
|
||||||
start_index = line.find('survey ') + len('survey ')
|
|
||||||
end_index = line.find(' -title ')
|
|
||||||
|
|
||||||
survey_name = line[start_index:end_index].strip()
|
|
||||||
survey_names.append(survey_name)
|
|
||||||
|
|
||||||
except FileNotFoundError:
|
|
||||||
print(f"{Colors.WARNING}Warning: File {Colors.ENDC}{file_path}{Colors.WARNING} not found.{Colors.ENDC}")
|
|
||||||
except PermissionError:
|
|
||||||
print(f"{Colors.ERROR}Error: Insufficient permissions to read {Colors.ENDC}{file_path}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{Colors.ERROR}An error occurred: {Colors.ENDC}{e}")
|
|
||||||
|
|
||||||
return survey_names
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def str_to_bool(value):
|
|
||||||
"""
|
|
||||||
Function to convert string to boolean
|
|
||||||
"""
|
|
||||||
if isinstance(value, bool):
|
|
||||||
return value
|
|
||||||
if value.lower() in ('true', '1', 'yes', 'y'):
|
|
||||||
return True
|
|
||||||
elif value.lower() in ('false', '0', 'no', 'n'):
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
raise argparse.ArgumentTypeError(f"{Colors.ERROR}Error: Invalid boolean value: {Colors.ENDC}{value}")
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
def select_file():
|
|
||||||
# Créer une instance de la fenêtre tkinter
|
|
||||||
root = tk.Tk()
|
|
||||||
# Cacher la fenêtre principale
|
|
||||||
root.withdraw()
|
|
||||||
# Afficher la boîte de dialogue de sélection de fichier
|
|
||||||
file_path = filedialog.askopenfilename(title="Sélectionnez un fichier")
|
|
||||||
# Retourner le chemin complet du fichier sélectionné
|
|
||||||
return file_path
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
# main function #
|
|
||||||
#################################################################################################
|
|
||||||
if __name__ == u'__main__':
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
# Parse arguments #
|
|
||||||
#################################################################################################
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description=f"{Colors.HEADER}Create a skeleton folder and th2 files with scraps from a .th Therion file\nVersion: {Colors.ENDC}{Version}\n",
|
|
||||||
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
||||||
parser.print_help = colored_help.__get__(parser)
|
|
||||||
parser.add_argument("--survey_file", help="The survey file (*.th) to perform e.g. './Therion_file.th'", default="")
|
|
||||||
parser.add_argument("--survey_name", help="Scrap name (if different from 'survey_file' name)", default="None")
|
|
||||||
#parser.add_argument("--proj", choices=['plan', 'elevation', 'extended', 'none'], help="The scrap projection to produce", default="plan")
|
|
||||||
#parser.add_argument("--format", choices=['th2', 'plt'], help="Output format. Either th2 for producing skeleton for drawing or plt for visualizing in aven/loch", default="th2")
|
|
||||||
parser.add_argument("--output", default="./", help="Output folder path")
|
|
||||||
# parser.add_argument("--therion-path", help="Path to therion binary", default="therion")
|
|
||||||
parser.add_argument("--scale", help="Scale for the exports", default="500")
|
|
||||||
parser.add_argument("--lines", type=str_to_bool, help="Shot lines in th2 files", default=-1)
|
|
||||||
parser.add_argument("--names", type=str_to_bool, help="Stations names in th2 files", default=-1)
|
|
||||||
parser.add_argument("--update", help="Mode update, option th2", default="")
|
|
||||||
|
|
||||||
parser.epilog = (
|
|
||||||
f"{Colors.GREEN}Please, complete {Colors.RED}config.ini{Colors.GREEN} file for personal configuration{Colors.ENDC}\n"
|
|
||||||
f"{Colors.GREEN}If no argument :{Colors.RED} files selection windows\n{Colors.ENDC}\n"
|
|
||||||
f"{Colors.BLUE}Examples:{Colors.ENDC}\n"
|
|
||||||
f"\t> python pyCreate_th2.py ./test/Entree.th --survey_name Geophysicaya_01_entree --output ./test/ --scale 1000\n"
|
|
||||||
f"\t> python pyCreate_th2.py Entree.th\n"
|
|
||||||
f"\t> python pyCreate_th2.py\n\n")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# print("args.survey_file : " + args.survey_file )
|
|
||||||
# print("args.update : " + args.update )
|
|
||||||
|
|
||||||
if args.survey_file == "":
|
|
||||||
args.survey_file = select_file()
|
|
||||||
print(f"Selected file : {args.survey_file}")
|
|
||||||
|
|
||||||
ENTRY_FILE = abspath(args.survey_file)
|
|
||||||
# PROJECTION = args.proj.capitalize()
|
|
||||||
PROJECTION = "Plan"
|
|
||||||
TARGET = args.survey_name
|
|
||||||
OUTPUT = args.output
|
|
||||||
#FORMAT = args.format
|
|
||||||
FORMAT = "th2"
|
|
||||||
SCALE = args.scale
|
|
||||||
LINES = args.lines
|
|
||||||
NAMES = args.names
|
|
||||||
# TH_NAME = args.survey_file.split("/")[-1].strip(".th")
|
|
||||||
TH_NAME = sanitize_filename(os.path.splitext(os.path.basename(args.survey_file))[0])
|
|
||||||
DEST_PATH = os.path.dirname(args.survey_file) + "/" + TH_NAME
|
|
||||||
#DEST_PATH = args.output + TH_NAME.split("/")[-1].strip(".th")
|
|
||||||
#ABS_PATH = ENTRY_FILE.strip(args.survey_file)
|
|
||||||
ABS_PATH = os.path.dirname(ENTRY_FILE)
|
|
||||||
|
|
||||||
# print("args.survey_file : " + args.survey_file )
|
|
||||||
# print("ENTRY_FILE: " + ENTRY_FILE )
|
|
||||||
# print("PROJECTION: " + PROJECTION )
|
|
||||||
# print("TARGET: " + TARGET )
|
|
||||||
# print("OUTPUT: " + OUTPUT )
|
|
||||||
# print("FORMAT: " + FORMAT )
|
|
||||||
# print("SCALE: " + SCALE )
|
|
||||||
# print("TH_NAME: " + TH_NAME )
|
|
||||||
# print("DEST_PATH: " + DEST_PATH )
|
|
||||||
# print("ABS_PATH: " + ABS_PATH )
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
# Reading config.ini #
|
|
||||||
#################################################################################################
|
|
||||||
try:
|
|
||||||
# Load the 'database' section from the configuration file
|
|
||||||
read_config("config.ini")
|
|
||||||
# print("Auteur: " + Author)
|
|
||||||
# print(f"Copyright: \n{Copyright}")
|
|
||||||
|
|
||||||
except ValueError as e:
|
|
||||||
# Handle errors if the section is missing
|
|
||||||
print(f"{Colors.ERROR}Error: read_config:{Colors.ERROR}", e)
|
|
||||||
|
|
||||||
if PROJECTION.lower() != "plan" :
|
|
||||||
print(f"{Colors.ERROR}Error: Sorry, projection '{Colors.ENDC}{PROJECTION}{Colors.ERROR}' not yet implemented{Colors.ENDC}")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
if not os.path.isfile(ENTRY_FILE):
|
|
||||||
print(f"{Colors.ERROR}Error: The Therion file didn't exist: {Colors.ENDC} {ENTRY_FILE}")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
if FORMAT not in ["th2", "plt"]:
|
|
||||||
print(f"{Colors.ERROR}Error: Please choose a supported format: th2, plt{Colors.ENDC}")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
# Normalise name, namespace, key, file path
|
|
||||||
print(f"{Colors.GREEN}Parsing survey entry file:\t{Colors.ENDC} {args.survey_file}")
|
|
||||||
|
|
||||||
survey_list = parse_therion_surveys(ENTRY_FILE)
|
|
||||||
# print(survey_list)
|
|
||||||
|
|
||||||
if TARGET == "None" :
|
|
||||||
if len(survey_list) > 1 :
|
|
||||||
print(f"{Colors.ERROR}Error: Multiple surveys were found, not yet implemented{Colors.ENDC}")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
TARGET = sanitize_filename(survey_list[0])
|
|
||||||
|
|
||||||
print(f"{Colors.GREEN}Parsing survey target: \t{Colors.ENDC} {TARGET}")
|
|
||||||
|
|
||||||
loader = SurveyLoader(ENTRY_FILE)
|
|
||||||
survey = loader.get_survey_by_id(survey_list[0])
|
|
||||||
|
|
||||||
# print(survey.name)
|
|
||||||
|
|
||||||
if not survey:
|
|
||||||
raise NoSurveysFoundException(f"{Colors.ERROR}Error: No survey found with that selector{Colors.ENDC}")
|
|
||||||
|
|
||||||
|
|
||||||
if args.update == "th2":
|
|
||||||
print(f"{Colors.GREEN} Update th2 files {Colors.ENDC}")
|
|
||||||
print(f"\t{Colors.BLUE}survey_file : {Colors.ENDC} {args.survey_file}")
|
|
||||||
print(f"\t{Colors.BLUE}ENTRY_FILE: {Colors.ENDC} {ENTRY_FILE}")
|
|
||||||
print(f"\t{Colors.BLUE}PROJECTION: {Colors.ENDC} {PROJECTION}")
|
|
||||||
print(f"\t{Colors.BLUE}TARGET: {Colors.ENDC} {TARGET}")
|
|
||||||
print(f"\t{Colors.BLUE}OUTPUT: {Colors.ENDC} {OUTPUT}")
|
|
||||||
print(f"\t{Colors.BLUE}FORMAT: {Colors.ENDC} {FORMAT}")
|
|
||||||
print(f"\t{Colors.BLUE}SCALE: {Colors.ENDC} {SCALE}")
|
|
||||||
print(f"\t{Colors.BLUE}TH_NAME: {Colors.ENDC} {TH_NAME}")
|
|
||||||
DEST_PATH = os.path.dirname(args.survey_file)
|
|
||||||
print(f"\t{Colors.BLUE}DEST_PATH: {Colors.ENDC} {DEST_PATH}")
|
|
||||||
print(f"\t{Colors.BLUE}ABS_PATH: {Colors.ENDC} {ABS_PATH}")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
# Copy template folders #
|
|
||||||
#################################################################################################
|
|
||||||
|
|
||||||
if args.update == "":
|
|
||||||
# print(f"{Colors.GREEN}Copy template folder and adapte it{Colors.ENDC}")
|
|
||||||
copy_template_if_not_exists(template_path, DEST_PATH)
|
|
||||||
copy_file_with_copyright(ENTRY_FILE, DEST_PATH + "/Data", Copyright)
|
|
||||||
|
|
||||||
# Adapte templates
|
|
||||||
config_vars = {
|
|
||||||
'fileName': TH_NAME,
|
|
||||||
'cavename': TH_NAME.replace("_", " "),
|
|
||||||
'Author': Author,
|
|
||||||
'Copyright': Copyright,
|
|
||||||
'Scale' : SCALE,
|
|
||||||
'Target' : TARGET,
|
|
||||||
'map_comment' : map_comment,
|
|
||||||
'club' : club,
|
|
||||||
'thanksto' : thanksto.replace("_", r"\_"),
|
|
||||||
'datat' : datat.replace("_", r"\_"),
|
|
||||||
'wpage' : wpage.replace("_", r"\_"),
|
|
||||||
'cs' : cs,
|
|
||||||
'other_scraps_plan' : "",
|
|
||||||
'file_info' : f'# File generated by pyCreate_th2.py (version {Version}) date: {datetime.now().strftime("%Y.%m.%d %H:%M:%S")}',
|
|
||||||
}
|
|
||||||
|
|
||||||
process_template(DEST_PATH + '/template.thconfig', config_vars, DEST_PATH + '/' + TH_NAME + '.thconfig')
|
|
||||||
process_template(DEST_PATH + '/template-tot.th', config_vars, DEST_PATH + '/' + TH_NAME + '-tot.th')
|
|
||||||
process_template(DEST_PATH + '/template-readme.md', config_vars, DEST_PATH + '/readme.md')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
# Produce the parsable XVI file #
|
|
||||||
#################################################################################################
|
|
||||||
|
|
||||||
print(f"{Colors.GREEN}Compiling 2D XVI file: \t{Colors.ENDC} {TH_NAME}")
|
|
||||||
|
|
||||||
template = """source "{th_file}"
|
|
||||||
layout minimal
|
|
||||||
scale 1 {scale}
|
|
||||||
endlayout
|
|
||||||
|
|
||||||
select {selector}
|
|
||||||
|
|
||||||
export model -o "{th_name}.lox"
|
|
||||||
export map -projection plan -o "{th_name}-Plan.xvi" -layout minimal -layout-debug station-names
|
|
||||||
export map -projection extended -o "{th_name}-Extended.xvi" -layout minimal -layout-debug station-names
|
|
||||||
"""
|
|
||||||
|
|
||||||
if args.update == "th2":
|
|
||||||
template_args = {
|
|
||||||
"th_file": DEST_PATH + "/" + TH_NAME + ".th",
|
|
||||||
"selector": survey.therion_id,
|
|
||||||
"th_name": DEST_PATH + "/" + TH_NAME,
|
|
||||||
"scale": SCALE,
|
|
||||||
}
|
|
||||||
|
|
||||||
else :
|
|
||||||
template_args = {
|
|
||||||
"th_file": DEST_PATH + "/Data/" + TH_NAME + ".th",
|
|
||||||
"selector": survey.therion_id,
|
|
||||||
"th_name": DEST_PATH + "/Data/" + TH_NAME,
|
|
||||||
"scale": SCALE,
|
|
||||||
}
|
|
||||||
|
|
||||||
log, tmpdir = compile_template(template, template_args, cleanup=False, therion_path=therion_path)
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
# Parse the Plan XVI file #
|
|
||||||
#################################################################################################
|
|
||||||
|
|
||||||
if args.update == "th2":
|
|
||||||
th_name_xvi = DEST_PATH + "/" + TH_NAME + "-Plan.xvi"
|
|
||||||
else :
|
|
||||||
th_name_xvi = DEST_PATH + "/Data/" + TH_NAME + "-Plan.xvi"
|
|
||||||
|
|
||||||
print(f"{Colors.GREEN}Parsing plan XVI file:\t{Colors.ENDC}{th_name_xvi}")
|
|
||||||
|
|
||||||
stations = {}
|
|
||||||
lines = []
|
|
||||||
|
|
||||||
with open(join(th_name_xvi), "r", encoding="utf-8") as f:
|
|
||||||
xvi_content = f.read()
|
|
||||||
xvi_stations, xvi_shots = xvi_content.split("XVIshots")
|
|
||||||
|
|
||||||
# Extract all the stations
|
|
||||||
for line in xvi_stations.split("\n"):
|
|
||||||
match = re.search(r"{\s*(-?\d+\.\d+)\s*(-?\d+\.\d+)\s([^@]+)(?:@([^\s}]*))?\s*}", line)
|
|
||||||
if match:
|
|
||||||
x = match.groups()[0]
|
|
||||||
y = match.groups()[1]
|
|
||||||
station_number = match.groups()[2]
|
|
||||||
namespace = match.groups()[3]
|
|
||||||
namespace_array = namespace.split(".") if namespace else []
|
|
||||||
station = station_number
|
|
||||||
if len(namespace_array) > 1:
|
|
||||||
station = "{}@{}".format(station_number, ".".join(namespace_array[0:-1]))
|
|
||||||
stations["{}.{}".format(x, y)] = [x, y, station]
|
|
||||||
|
|
||||||
# Extraire les valeurs x et y à partir des listes dans stations
|
|
||||||
x_values = [float(value[0]) for value in stations.values()]
|
|
||||||
y_values = [float(value[1]) for value in stations.values()]
|
|
||||||
|
|
||||||
# Trouver les min et max de x
|
|
||||||
x_min = float(min(x_values))
|
|
||||||
x_max = float(max(x_values))
|
|
||||||
|
|
||||||
# Trouver les min et max de y
|
|
||||||
y_min = float(min(y_values))
|
|
||||||
y_max = float(max(y_values))
|
|
||||||
|
|
||||||
x_ecart = x_max - x_min
|
|
||||||
y_ecart = y_max - y_min
|
|
||||||
|
|
||||||
# Afficher les résultats
|
|
||||||
# print("x_min:", x_min, "x_max:", x_max)
|
|
||||||
# print("y_min:", y_min, "y_max:", y_max)
|
|
||||||
# print("Écart max-min pour x:", x_ecart)
|
|
||||||
# print("Écart max-min pour y:", y_ecart)
|
|
||||||
|
|
||||||
# Extract all the lines
|
|
||||||
for line in xvi_shots.split("\n"):
|
|
||||||
match = re.search(r"^\s*{\s*(-?\d+\.\d+)\s*(-?\d+\.\d+)\s*(-?\d+\.\d+)\s*(-?\d+\.\d+)\s*.*}", line )
|
|
||||||
if match:
|
|
||||||
x1 = match.groups()[0]
|
|
||||||
y1 = match.groups()[1]
|
|
||||||
x2 = match.groups()[2]
|
|
||||||
y2 = match.groups()[3]
|
|
||||||
key1 = "{}.{}".format(x1, y1)
|
|
||||||
key2 = "{}.{}".format(x2, y2)
|
|
||||||
# Splays won't have stations
|
|
||||||
station1 = stations[key1][2] if key1 in stations else None
|
|
||||||
station2 = stations[key2][2] if key2 in stations else None
|
|
||||||
lines.append([x1, y1, x2, y2, station1, station2])
|
|
||||||
# shutil.rmtree(tmpdir)
|
|
||||||
if args.update == "th2":
|
|
||||||
th2_name = DEST_PATH + "/" + TH_NAME
|
|
||||||
else :
|
|
||||||
th2_name = DEST_PATH + "/Data/" + TH_NAME
|
|
||||||
output_path = f'{th2_name}-{PROJECTION}.{FORMAT}'
|
|
||||||
|
|
||||||
scrap_to_add = int(len(stations)/station_by_scrap)-1
|
|
||||||
|
|
||||||
# print(stations)
|
|
||||||
|
|
||||||
print(f"{Colors.GREEN}Writing output to:\t{Colors.ENDC}{output_path}")
|
|
||||||
|
|
||||||
# Write TH2
|
|
||||||
if FORMAT == "th2":
|
|
||||||
th2_file_header = """encoding utf-8"""
|
|
||||||
|
|
||||||
th2_file = """
|
|
||||||
##XTHERION## xth_me_area_adjust {X_Min} {Y_Min} {X_Max} {Y_Max}
|
|
||||||
##XTHERION## xth_me_area_zoom_to 100
|
|
||||||
##XTHERION## xth_me_image_insert {insert_XVI}
|
|
||||||
|
|
||||||
{Copyright}
|
|
||||||
# File generated by pyCreate_th2.py version {version} date: {date}
|
|
||||||
|
|
||||||
# x_min: {X_Min}, x_max: {X_Max} ecart : {X_Max_X_Min}
|
|
||||||
# y_min: {Y_Min}, y_max: {Y_Max} ecart : {Y_Max_Y_Min}
|
|
||||||
|
|
||||||
scrap S{projection_short}-{name}_01 -station-names "" "@{name}" -projection {projection} -author {year} "{author}" -copyright {year} "{Copyright_Short}"
|
|
||||||
|
|
||||||
{points}
|
|
||||||
|
|
||||||
{names}
|
|
||||||
|
|
||||||
{lines}
|
|
||||||
|
|
||||||
endscrap"""
|
|
||||||
|
|
||||||
th2_point = """ point {x} {y} station -name {station}"""
|
|
||||||
th2_name = """ point {x} {y} station-name -align tr -scale xs -text {station}"""
|
|
||||||
|
|
||||||
th2_line = """ line u:Shot_Survey
|
|
||||||
{x1} {y1}
|
|
||||||
{x2} {y2}
|
|
||||||
|
|
||||||
endline"""
|
|
||||||
|
|
||||||
seen = set()
|
|
||||||
th2_lines = []
|
|
||||||
th2_points = []
|
|
||||||
th2_names = []
|
|
||||||
other_scraps_plan = ""
|
|
||||||
|
|
||||||
for line in lines:
|
|
||||||
th2_lines.append(th2_line.format(x1=line[0], y1=line[1], x2=line[2], y2=line[3]))
|
|
||||||
coords1 = "{}.{}".format(line[0], line[1])
|
|
||||||
|
|
||||||
if coords1 not in seen:
|
|
||||||
seen.add(coords1)
|
|
||||||
th2_points.append(th2_point.format(x=line[0], y=line[1], station=line[4]))
|
|
||||||
th2_names.append(th2_name.format(x=line[0], y=line[1], station=line[4]))
|
|
||||||
coords2 = "{}.{}".format(line[2], line[3])
|
|
||||||
|
|
||||||
if "{}.{}".format(line[2], line[3]) not in seen:
|
|
||||||
seen.add(coords2)
|
|
||||||
if line[5] != None:
|
|
||||||
th2_points.append(th2_point.format(x=line[2], y=line[3], station=line[5]))
|
|
||||||
th2_names.append(th2_name.format(x=line[2], y=line[3], station=line[5]))
|
|
||||||
|
|
||||||
|
|
||||||
if isfile(output_path):
|
|
||||||
print(f"{Colors.WARNING}Warning: {Colors.ENDC}{os.path.basename(output_path)}{Colors.WARNING} file already exists - nothing done{Colors.ENDC}")
|
|
||||||
|
|
||||||
else :
|
|
||||||
name = TARGET,
|
|
||||||
# print(f"{Colors.GREEN}Therion output path :\t{Colors.ENDC}{output_path}")
|
|
||||||
|
|
||||||
with open(str(output_path), "w+") as f:
|
|
||||||
f.write(th2_file_header)
|
|
||||||
f.write(th2_file.format(
|
|
||||||
name = name[0],
|
|
||||||
Copyright = Copyright,
|
|
||||||
Copyright_Short = Copyright_Short,
|
|
||||||
points="\n".join(th2_points),
|
|
||||||
lines="\n".join(th2_lines) if LINES else "",
|
|
||||||
names="\n".join(th2_names) if NAMES else "",
|
|
||||||
projection=PROJECTION.lower(),
|
|
||||||
projection_short=PROJECTION[0].upper(),
|
|
||||||
author=Author,
|
|
||||||
year=datetime.now().year,
|
|
||||||
version = Version,
|
|
||||||
date=datetime.now().strftime("%Y.%m.%d-%H:%M:%S"),
|
|
||||||
X_Min=x_min*1.2,
|
|
||||||
X_Max=x_max*1.2,
|
|
||||||
Y_Min=y_min*1.2,
|
|
||||||
Y_Max=y_max*1.2,
|
|
||||||
X_Max_X_Min =x_ecart,
|
|
||||||
Y_Max_Y_Min =y_ecart,
|
|
||||||
insert_XVI = "{" + stations[next(iter(stations))][0] + "1 1.0} {"
|
|
||||||
+ stations[next(iter(stations))][1] + " "
|
|
||||||
+ stations[next(iter(stations))][2] +"} "
|
|
||||||
+ os.path.basename(th_name_xvi) + " 0 {}",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if scrap_to_add >= 1 :
|
|
||||||
for i in range(scrap_to_add):
|
|
||||||
other_scraps_plan = other_scraps_plan + f"\tbreak\n\tS{PROJECTION[0].upper()}-{name[0]}_{i+2:02}\n"
|
|
||||||
th2_scrap = """
|
|
||||||
|
|
||||||
scrap S{projection_short}-{name}_{num:02} -station-names "" "@{name}" -projection {projection} -author {year} "{author}" -copyright {year} "{Copyright_Short}"
|
|
||||||
|
|
||||||
endscrap
|
|
||||||
|
|
||||||
"""
|
|
||||||
f.write(th2_scrap.format(
|
|
||||||
name=name[0],
|
|
||||||
projection=PROJECTION.lower(),
|
|
||||||
projection_short=PROJECTION[0].upper(),
|
|
||||||
author=Author,
|
|
||||||
year=datetime.now().year,
|
|
||||||
Copyright_Short = Copyright_Short,
|
|
||||||
num=f"{i+2:02}",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
# Parse the Extended XVI file #
|
|
||||||
#################################################################################################
|
|
||||||
if args.update == "th2":
|
|
||||||
th_name_xvi = DEST_PATH + "/" + TH_NAME + "-Extended.xvi"
|
|
||||||
else :
|
|
||||||
th_name_xvi = DEST_PATH + "/Data/" + TH_NAME + "-Extended.xvi"
|
|
||||||
|
|
||||||
print(f"{Colors.GREEN}Parsing extended XVI file:\t{Colors.ENDC}{th_name_xvi}")
|
|
||||||
|
|
||||||
# Parse the Extended XVI file
|
|
||||||
stations = {}
|
|
||||||
lines = []
|
|
||||||
|
|
||||||
with open(join(th_name_xvi), "r", encoding="utf-8") as f:
|
|
||||||
xvi_content = f.read()
|
|
||||||
xvi_stations, xvi_shots = xvi_content.split("XVIshots")
|
|
||||||
|
|
||||||
# Extract all the stations
|
|
||||||
for line in xvi_stations.split("\n"):
|
|
||||||
match = re.search(r"{\s*(-?\d+\.\d+)\s*(-?\d+\.\d+)\s([^@]+)(?:@([^\s}]*))?\s*}", line)
|
|
||||||
if match:
|
|
||||||
x = match.groups()[0]
|
|
||||||
y = match.groups()[1]
|
|
||||||
station_number = match.groups()[2]
|
|
||||||
namespace = match.groups()[3]
|
|
||||||
namespace_array = namespace.split(".") if namespace else []
|
|
||||||
station = station_number
|
|
||||||
if len(namespace_array) > 1:
|
|
||||||
station = "{}@{}".format(station_number, ".".join(namespace_array[0:-1]))
|
|
||||||
stations["{}.{}".format(x, y)] = [x, y, station]
|
|
||||||
|
|
||||||
# Extraire les valeurs x et y à partir des listes dans stations
|
|
||||||
x_values = [float(value[0]) for value in stations.values()]
|
|
||||||
y_values = [float(value[1]) for value in stations.values()]
|
|
||||||
|
|
||||||
# Trouver les min et max de x
|
|
||||||
x_min = float(min(x_values))
|
|
||||||
x_max = float(max(x_values))
|
|
||||||
|
|
||||||
# Trouver les min et max de y
|
|
||||||
y_min = float(min(y_values))
|
|
||||||
y_max = float(max(y_values))
|
|
||||||
|
|
||||||
x_ecart = x_max - x_min
|
|
||||||
y_ecart = y_max - y_min
|
|
||||||
|
|
||||||
# Afficher les résultats
|
|
||||||
# print("x_min:", x_min, "x_max:", x_max)
|
|
||||||
# print("y_min:", y_min, "y_max:", y_max)
|
|
||||||
# print("Écart max-min pour x:", x_ecart)
|
|
||||||
# print("Écart max-min pour y:", y_ecart)
|
|
||||||
|
|
||||||
# Extract all the lines
|
|
||||||
for line in xvi_shots.split("\n"):
|
|
||||||
match = re.search(r"^\s*{\s*(-?\d+\.\d+)\s*(-?\d+\.\d+)\s*(-?\d+\.\d+)\s*(-?\d+\.\d+)\s*.*}", line )
|
|
||||||
if match:
|
|
||||||
x1 = match.groups()[0]
|
|
||||||
y1 = match.groups()[1]
|
|
||||||
x2 = match.groups()[2]
|
|
||||||
y2 = match.groups()[3]
|
|
||||||
key1 = "{}.{}".format(x1, y1)
|
|
||||||
key2 = "{}.{}".format(x2, y2)
|
|
||||||
# Splays won't have stations
|
|
||||||
station1 = stations[key1][2] if key1 in stations else None
|
|
||||||
station2 = stations[key2][2] if key2 in stations else None
|
|
||||||
lines.append([x1, y1, x2, y2, station1, station2])
|
|
||||||
shutil.rmtree(tmpdir)
|
|
||||||
|
|
||||||
if args.update == "th2":
|
|
||||||
th2_name = DEST_PATH + "/" + TH_NAME
|
|
||||||
else :
|
|
||||||
th2_name = DEST_PATH + "/Data/" + TH_NAME
|
|
||||||
output_path = f'{th2_name}-Extended.{FORMAT}'
|
|
||||||
|
|
||||||
print(f"{Colors.GREEN}Writing output to:\t\t{Colors.ENDC}{output_path}")
|
|
||||||
|
|
||||||
# Write TH2
|
|
||||||
if FORMAT == "th2":
|
|
||||||
th2_file_header = """encoding utf-8"""
|
|
||||||
|
|
||||||
th2_file = """
|
|
||||||
##XTHERION## xth_me_area_adjust {X_Min} {Y_Min} {X_Max} {Y_Max}
|
|
||||||
##XTHERION## xth_me_area_zoom_to 100
|
|
||||||
##XTHERION## xth_me_image_insert {insert_XVI}
|
|
||||||
|
|
||||||
{Copyright}
|
|
||||||
# File generated by pyCreate_th2.py version {version} date: {date}
|
|
||||||
|
|
||||||
# x_min: {X_Min}, x_max: {X_Max} ecart : {X_Max_X_Min}
|
|
||||||
# y_min: {Y_Min}, y_max: {Y_Max} ecart : {Y_Max_Y_Min}
|
|
||||||
|
|
||||||
scrap SC-{name}_01 -station-names "" "@{name}" -projection extended -author {year} "{author}" -copyright {year} "{Copyright_Short}"
|
|
||||||
|
|
||||||
{points}
|
|
||||||
|
|
||||||
{names}
|
|
||||||
|
|
||||||
{lines}
|
|
||||||
|
|
||||||
endscrap"""
|
|
||||||
|
|
||||||
th2_point = """ point {x} {y} station -name {station}"""
|
|
||||||
th2_name = """ point {x} {y} station-name -align tr -scale xs -text {station}"""
|
|
||||||
|
|
||||||
th2_line = """ line u:Shot_Survey
|
|
||||||
{x1} {y1}
|
|
||||||
{x2} {y2}
|
|
||||||
endline
|
|
||||||
"""
|
|
||||||
|
|
||||||
seen = set()
|
|
||||||
th2_lines = []
|
|
||||||
th2_points = []
|
|
||||||
th2_names = []
|
|
||||||
other_scraps_extended = ""
|
|
||||||
|
|
||||||
for line in lines:
|
|
||||||
th2_lines.append(th2_line.format(x1=line[0], y1=line[1], x2=line[2], y2=line[3]))
|
|
||||||
coords1 = "{}.{}".format(line[0], line[1])
|
|
||||||
|
|
||||||
if coords1 not in seen:
|
|
||||||
seen.add(coords1)
|
|
||||||
th2_points.append(th2_point.format(x=line[0], y=line[1], station=line[4]))
|
|
||||||
th2_names.append(th2_name.format(x=line[0], y=line[1], station=line[4]))
|
|
||||||
coords2 = "{}.{}".format(line[2], line[3])
|
|
||||||
|
|
||||||
if "{}.{}".format(line[2], line[3]) not in seen:
|
|
||||||
seen.add(coords2)
|
|
||||||
if line[5] != None:
|
|
||||||
th2_points.append(th2_point.format(x=line[2], y=line[3], station=line[5]))
|
|
||||||
th2_names.append(th2_name.format(x=line[2], y=line[3], station=line[5]))
|
|
||||||
|
|
||||||
|
|
||||||
if isfile(output_path):
|
|
||||||
print(f"{Colors.WARNING}Warning: {Colors.ENDC}{os.path.basename(output_path)}{Colors.WARNING} file already exists - nothing done{Colors.ENDC}")
|
|
||||||
else :
|
|
||||||
name = TARGET,
|
|
||||||
# print(f"{Colors.GREEN}Therion output path :\t{Colors.ENDC}{output_path}")
|
|
||||||
|
|
||||||
with open(str(output_path), "w+") as f:
|
|
||||||
f.write(th2_file_header)
|
|
||||||
f.write(th2_file.format(
|
|
||||||
name = name[0],
|
|
||||||
Copyright = Copyright,
|
|
||||||
Copyright_Short = Copyright_Short,
|
|
||||||
points="\n".join(th2_points),
|
|
||||||
lines="\n".join(th2_lines) if LINES else "",
|
|
||||||
names="\n".join(th2_names) if NAMES else "",
|
|
||||||
projection="extended",
|
|
||||||
projection_short="C",
|
|
||||||
author=Author,
|
|
||||||
year=datetime.now().year,
|
|
||||||
version = Version,
|
|
||||||
date=datetime.now().strftime("%Y.%m.%d-%H:%M:%S"),
|
|
||||||
X_Min=x_min*1.2,
|
|
||||||
X_Max=x_max*1.2,
|
|
||||||
Y_Min=y_min*1.2,
|
|
||||||
Y_Max=y_max*1.2,
|
|
||||||
X_Max_X_Min =x_ecart,
|
|
||||||
Y_Max_Y_Min =y_ecart,
|
|
||||||
insert_XVI = "{" + stations[next(iter(stations))][0] + "1 1.0} {"
|
|
||||||
+ stations[next(iter(stations))][1] + " "
|
|
||||||
+ stations[next(iter(stations))][2] +"} "
|
|
||||||
+ os.path.basename(th_name_xvi) + " 0 {}",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if scrap_to_add >= 1 :
|
|
||||||
for i in range(scrap_to_add):
|
|
||||||
other_scraps_extended = other_scraps_extended + f"\tbreak\n\tSC-{name[0]}_{i+2:02}\n"
|
|
||||||
th2_scrap = """
|
|
||||||
|
|
||||||
scrap SC-{name}_{num:02} -station-names "" "@{name}" -projection extended -author {year} "{author}" -copyright {year} "{Copyright_Short}"
|
|
||||||
|
|
||||||
endscrap
|
|
||||||
|
|
||||||
"""
|
|
||||||
f.write(th2_scrap.format(
|
|
||||||
name=name[0],
|
|
||||||
author=Author,
|
|
||||||
Copyright_Short = Copyright_Short,
|
|
||||||
year=datetime.now().year,
|
|
||||||
num=f"{i+2:02}",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
# Update -maps files #
|
|
||||||
#################################################################################################
|
|
||||||
if args.update == "":
|
|
||||||
config_vars = {
|
|
||||||
'fileName': TH_NAME,
|
|
||||||
'Author': Author,
|
|
||||||
'Copyright': Copyright,
|
|
||||||
'Scale' : SCALE,
|
|
||||||
'Target' : TARGET,
|
|
||||||
'map_comment' : map_comment,
|
|
||||||
'club' : club,
|
|
||||||
'thanksto' : thanksto,
|
|
||||||
'datat' : datat,
|
|
||||||
'wpage' : wpage,
|
|
||||||
'cs' : cs,
|
|
||||||
'other_scraps_plan' : other_scraps_plan,
|
|
||||||
'other_scraps_extended' : other_scraps_extended,
|
|
||||||
'file_info' : f"# File generated by pyCreate_th2.py version {Version} date: {datetime.now().strftime("%Y.%m.%d-%H:%M:%S")}",
|
|
||||||
}
|
|
||||||
|
|
||||||
process_template(DEST_PATH + '/template-maps.th', config_vars, DEST_PATH + '/' + TH_NAME + '-maps.th')
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################
|
|
||||||
# Final therion compilation #
|
|
||||||
#################################################################################################
|
|
||||||
|
|
||||||
if args.update == "":
|
|
||||||
if final_therion_exe == True:
|
|
||||||
print(f"{Colors.GREEN}Final therion compilation{Colors.ENDC}")
|
|
||||||
PATH = os.path.dirname(args.survey_file) + "/" + TH_NAME + "/" + TH_NAME + ".thconfig"
|
|
||||||
|
|
||||||
compile_file(PATH, therion_path=therion_path)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"folders": [
|
|
||||||
{
|
|
||||||
"path": "."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cSpell.words": [
|
|
||||||
"datat",
|
|
||||||
"ecart",
|
|
||||||
"ENDC",
|
|
||||||
"endlayout",
|
|
||||||
"endscrap",
|
|
||||||
"thanksto",
|
|
||||||
"thconfig",
|
|
||||||
"therion",
|
|
||||||
"wpage"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
numpy
|
|
||||||
ttkthemes
|
|
||||||
matplotlib
|
|
||||||
pandas
|
|
||||||
Shapely
|
|
||||||
Fiona
|
|
||||||
pyproj
|
|
||||||
scipy
|
|
||||||
netCDF4
|
|
||||||
xarray
|
|
||||||
joblib
|
|
||||||
geopandas
|
|
||||||
motionless
|
|
||||||
salem
|
|
||||||
configparser
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Folder where Therion outputs are exported
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,18 +0,0 @@
|
|||||||
#Template for pyCreate_th2.py
|
|
||||||
encoding utf-8
|
|
||||||
|
|
||||||
{Copyright}
|
|
||||||
|
|
||||||
{file_info}
|
|
||||||
|
|
||||||
map MP-{fileName}-Plan-tot -title "{fileName}"
|
|
||||||
SP-{Target}_01
|
|
||||||
{other_scraps_plan} break
|
|
||||||
endmap
|
|
||||||
|
|
||||||
map MC-{fileName}-Extended-tot -title "{fileName}"
|
|
||||||
SC-{Target}_01
|
|
||||||
{other_scraps_extended} break
|
|
||||||
endmap
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#Template for pyCreate_th2.py
|
|
||||||
encoding utf-8
|
|
||||||
|
|
||||||
{Copyright}
|
|
||||||
|
|
||||||
{file_info}
|
|
||||||
|
|
||||||
to add this survey in a main survey add in your -tot.th file:
|
|
||||||
|
|
||||||
input Data/{fileName}/{fileName}-tot.th
|
|
||||||
equate
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#Template for pyCreate_th2.py
|
|
||||||
encoding utf-8
|
|
||||||
|
|
||||||
{Copyright}
|
|
||||||
|
|
||||||
{file_info}
|
|
||||||
|
|
||||||
survey {fileName} -title "{fileName}"
|
|
||||||
input Data/{fileName}.th
|
|
||||||
|
|
||||||
## Pour le plan
|
|
||||||
input Data/{fileName}-Plan.th2
|
|
||||||
|
|
||||||
## Pour la coupe développée
|
|
||||||
input Data/{fileName}-Extended.th2
|
|
||||||
|
|
||||||
## Appel des maps
|
|
||||||
input {fileName}-maps.th
|
|
||||||
|
|
||||||
endsurvey
|
|
||||||
@@ -1,389 +0,0 @@
|
|||||||
#Template for pyCreate_th2.py
|
|
||||||
encoding utf-8
|
|
||||||
|
|
||||||
###############################################################################################
|
|
||||||
|
|
||||||
{Copyright}
|
|
||||||
{file_info}
|
|
||||||
###############################################################################################
|
|
||||||
|
|
||||||
## INTRO
|
|
||||||
|
|
||||||
## Le signe "#" en début de ligne signifie que la ligne est commentée. Elle ne
|
|
||||||
## sera donc pas lue lors de la compilation.
|
|
||||||
|
|
||||||
## Dans ce fichier on met les specifications generales, à savoir
|
|
||||||
## dans quel fichier sont les donnees topo, l'aspect que l'on veut
|
|
||||||
## donner aux topos imprimées (layout) et ce que l'on
|
|
||||||
## veut comme résultat : map, ou atlas ou 3D ou donnees en format SQL
|
|
||||||
|
|
||||||
## Alors, on peut fractionner ce fichier en trois parts:
|
|
||||||
## - source, pour specifier les fichiers ou sont les données topo/dessin
|
|
||||||
## - layout, pour specifier la composition du document à imprimer
|
|
||||||
## - export: map, atlas, etc
|
|
||||||
|
|
||||||
###############################################################################################
|
|
||||||
## 1-SOURCES
|
|
||||||
###############################################################################################
|
|
||||||
## La ligne source spécifie le fichier ou sont les donnees topo
|
|
||||||
## jb.th". (Au fichier "jb.th" il faudra avoir une ligne
|
|
||||||
## "input "nomducavite.th2" pour specifier le fichier ou se trouvent
|
|
||||||
## les donnees du dessin, comme ça, ce fichier thconfig appellera
|
|
||||||
## "jb.th" et a leur tour, "jb.th" appellera
|
|
||||||
## "jb-dessin.th2")
|
|
||||||
|
|
||||||
source {fileName}-tot.th
|
|
||||||
|
|
||||||
## Add config file
|
|
||||||
input config.thc
|
|
||||||
|
|
||||||
###############################################################################################
|
|
||||||
## 2-LAYOUT
|
|
||||||
###############################################################################################
|
|
||||||
## Ici, on peut specifier des choses comme les symboles à utiliser (UIS, etc)
|
|
||||||
## ou imprimer des explications des symboles
|
|
||||||
|
|
||||||
## Début de la définition du Layout "xviexport"
|
|
||||||
layout xviexport
|
|
||||||
#cs UTM32
|
|
||||||
## echelle à laquelle on veut dessiner la topo
|
|
||||||
scale 1 {Scale}
|
|
||||||
#scale 1 1000
|
|
||||||
## taille de la grille
|
|
||||||
grid-size 2 2 2 m
|
|
||||||
## mettre la grille en arrière plan
|
|
||||||
grid bottom
|
|
||||||
endlayout
|
|
||||||
## fin de la définition du layout "xviexport"
|
|
||||||
|
|
||||||
## Début de la définition du layout "Layout-Plan"
|
|
||||||
layout layout-Plan
|
|
||||||
## Call the config settings (Layout config inside the config.thc file)
|
|
||||||
copy fonts_1000
|
|
||||||
copy drawingconfig
|
|
||||||
#copy layoutcontinuation # Pour afficher le label des continuations
|
|
||||||
copy headerl
|
|
||||||
copy langue-fr
|
|
||||||
|
|
||||||
## Définition du système de projection du plan
|
|
||||||
cs {cs}
|
|
||||||
|
|
||||||
## La ligne base-scale spécifie l'échelle auquel nous avons dessiné nos croquis.
|
|
||||||
## Par défaut, Therion pense que c'est une échelle 1:200. Si on a utilisé une autre échelle,
|
|
||||||
## il faut enlever le "#" et spécifier l'échelle vraiment employée, comme c'est le cas
|
|
||||||
## après avoir dessiné la topo sur un cheminement exporté avec le layout "xviexport".
|
|
||||||
## Jouer avec le ration base-scale/scale permet de jouer globalement sur les tailles
|
|
||||||
## des caractères et des traits.
|
|
||||||
base-scale 1 {Scale}
|
|
||||||
|
|
||||||
## Maintenant on va mettre une ligne "scale" pour specifier l'échelle pour imprimer la topo.
|
|
||||||
## La combination entre scale et base-scale contrôle l'épaisseur des lignes, rotation, etc, convenable
|
|
||||||
## pour faire l'ampliation-réduction entre dessin et le résultat de l'imprimante
|
|
||||||
## C'est tres important s'assurer que la configuration de l'imprimante ne spécifie pas l'option "Fit in page"
|
|
||||||
## ou similaire, sinon, l'échelle sera changée pendant l'impression!
|
|
||||||
scale 1 {Scale}
|
|
||||||
|
|
||||||
## Echelle graphique 100 m ampleur (Généralement, le choix scale/10 est plutôt pas mal)
|
|
||||||
scale-bar 100 m
|
|
||||||
|
|
||||||
## Voici une ligne pour specifier qu'il faut imprimer une grille au dessous de la topo
|
|
||||||
grid bottom
|
|
||||||
|
|
||||||
## Défini la rotation de la topographie
|
|
||||||
#rotate -65
|
|
||||||
|
|
||||||
## Une ligne pour specifier que la grille est 1000x1000x1000 m
|
|
||||||
## (Trois dimensions, oui, ça sert pour la coupe aussi)
|
|
||||||
grid-size 50 50 50 m
|
|
||||||
|
|
||||||
## la topo est transparente (on peut voir les galeries en dessous)
|
|
||||||
## C'est on par défaut, donc, pas vraiment besoin de specifier
|
|
||||||
transparency on
|
|
||||||
|
|
||||||
## Couleurs de la topographie
|
|
||||||
#colour map-bg [70 90 70]
|
|
||||||
#colour map-fg [100 100 80]
|
|
||||||
#colour map-fg altitude
|
|
||||||
#colour map-fg explo-date
|
|
||||||
#colour map-fg topo-date
|
|
||||||
#colour map-fg map
|
|
||||||
#colour map-fg scrap
|
|
||||||
#colour-legend off
|
|
||||||
colour map-fg 90
|
|
||||||
|
|
||||||
## ça marche seulement si transparency est "on" 90% blanc= 10% noir
|
|
||||||
opacity 75
|
|
||||||
#surface bottom
|
|
||||||
#surface-opacity 100
|
|
||||||
|
|
||||||
## Auteur
|
|
||||||
doc-author "{Author}"
|
|
||||||
## Titre
|
|
||||||
doc-title "{cavename} Plan - 1:{Scale}"
|
|
||||||
doc-subject "{cavename}, topographie en plan"
|
|
||||||
doc-keywords "Cave, Survey, {cavename}, Pierre saint Martin - Larra, {map_comment}"
|
|
||||||
|
|
||||||
## Maintenant on spécifie la position de la manchette, dont l'intérieur est occupé par le titre, auteurs, etc.
|
|
||||||
## Nous pouvons indiquer les cordonnées du point de la topo ou l'on veut la manchette :
|
|
||||||
## 0 0, c'est en bas, à gauche, 100 100, c'est en haut, à droite
|
|
||||||
## La manchette a des "points cardinaux" autour : n, s, ne, sw, etc.
|
|
||||||
## Il faut specifier un de ces points comme ce que sera placé sur les cordonnées.
|
|
||||||
## Alors nous pouvons specifier que le sud-ouest de la manchette soit placé en bas, a gauche,
|
|
||||||
## ou une autre combination...
|
|
||||||
map-header 2 98 nw
|
|
||||||
|
|
||||||
## arrière plan de la manchette
|
|
||||||
map-header-bg on
|
|
||||||
## Légende pour expliciter les symboles. "on" imprimera seulement la légende des symboles dessinés
|
|
||||||
## sur la topo. Si l'on veut pour tous les symboles, utilisés ou pas, il faut indiquer "all".
|
|
||||||
## "legend off" = pas de légende
|
|
||||||
legend on
|
|
||||||
## Par défaut, la légende est de 14 cm de largeur
|
|
||||||
legend-width 15 cm
|
|
||||||
legend-columns 2
|
|
||||||
## Un commentaire à ajouter au titre, on pourrait indiquer ici la mairie où est placée la cavité
|
|
||||||
## dont le nom est probablement le titre de la topo.
|
|
||||||
map-comment "{map_comment}"
|
|
||||||
#map-comment "{map_comment}<br>Coordonnées : ({cs}/WGS84) xxx.xxx xxxx.xxx, Alt.: xxxx m"
|
|
||||||
|
|
||||||
## Afficher les statistiques d'explo/topo par équipe/nom. C'est lourd
|
|
||||||
## si la cavité est importante et qu'il y a beaucoup d'explorateurs/topographes.
|
|
||||||
statistics explo-length off
|
|
||||||
statistics topo-length off
|
|
||||||
|
|
||||||
## Afficher un copyright
|
|
||||||
statistics copyright 2
|
|
||||||
|
|
||||||
## Dessin ou pas du cheminement topo
|
|
||||||
#symbol-hide point station
|
|
||||||
#symbol-hide line survey
|
|
||||||
#symbol-hide group
|
|
||||||
#symbol-show line wall
|
|
||||||
#symbol-hide point station-name
|
|
||||||
#symbol-hide point u:symbol_plan
|
|
||||||
#symbol-hide point u:symbol_extend
|
|
||||||
#debug scrap-names
|
|
||||||
#debug station-names
|
|
||||||
|
|
||||||
layers on
|
|
||||||
|
|
||||||
overlap 2 cm
|
|
||||||
|
|
||||||
code tex-map
|
|
||||||
\legendwidth=15cm
|
|
||||||
\legendtextsize={\size[12]}
|
|
||||||
\legendtextheadersize={\size[28]} %%% Taille du titre
|
|
||||||
\legendtextsectionsize={\size[14]} %%% Taille du titre
|
|
||||||
%\legendtextcolor={\color[0 0 110]} %# RGB values 0--100
|
|
||||||
% Output map title as determined by Therion is stored in cavename, défini par la une Map.
|
|
||||||
% It will be empty if there are multiple maps selected for any one projection
|
|
||||||
% AND there are multiple source surveys identified in the thconfig file
|
|
||||||
% ie Therion can not infer a unique title from the input data given.
|
|
||||||
% This code allows you to define an output map title {cavename} if it happens to be empty
|
|
||||||
\edef\temp{\the\cavename} % cavename from Therion
|
|
||||||
\edef\nostring{} % empty string
|
|
||||||
\ifx\temp\nostring % test if cavename is empty
|
|
||||||
% if empty
|
|
||||||
reassign cavename to describe selected maps as a group
|
|
||||||
\else % if not empty keep the value set by therion, or assign an override cavename here
|
|
||||||
\fi
|
|
||||||
\cavename={{cavename}, Plan 1:{Scale}} % Note Alex : Bug avec certains fichiers ?
|
|
||||||
\newtoks\club \club={{club}}
|
|
||||||
%\newtoks\thanksto \thanksto={{thanksto}}
|
|
||||||
\newtoks\wpage \wpage={{wpage}}
|
|
||||||
\newtoks\datat \datat={{datat}}
|
|
||||||
\newtoks\synth \synth={{Author}}
|
|
||||||
\framethickness=0.5mm
|
|
||||||
endcode
|
|
||||||
|
|
||||||
endlayout
|
|
||||||
|
|
||||||
##debut de la definition du layout "layout-Extended"
|
|
||||||
layout layout-Extended
|
|
||||||
## Call the config settings (Layout config inside the config.thc file)
|
|
||||||
copy drawingconfig
|
|
||||||
#copy layoutcontinuation # Pour afficher le label des continuations
|
|
||||||
copy header_coupe
|
|
||||||
#copy headerl
|
|
||||||
#copy header_coupe_vert-auto
|
|
||||||
#copy header_coupe_vert-to-place
|
|
||||||
copy langue-fr
|
|
||||||
|
|
||||||
## Définition du système de projection du plan
|
|
||||||
cs {cs}
|
|
||||||
|
|
||||||
## La ligne base-scale spécifie l'échelle auquel nous avons dessiné nos croquis.
|
|
||||||
## Par défaut, Therion pense que c'est une échelle 1:200. Si on a utilisé une autre échelle,
|
|
||||||
## il faut enlever le "#" et spécifier l'échelle vraiment employée, comme c'est le cas
|
|
||||||
## après avoir dessiné la topo sur un cheminement exporté avec le layout "xviexport".
|
|
||||||
## Jouer avec le ration base-scale/scale permet de jouer globalement sur les tailles
|
|
||||||
## des caractères et des traits.
|
|
||||||
base-scale 1 {Scale}
|
|
||||||
|
|
||||||
## Maintenant on va mettre une ligne "scale" pour specifier l'échelle pour imprimer la topo.
|
|
||||||
## La combination entre scale et base-scale contrôle l'épaisseur des lignes, rotation, etc, convenable
|
|
||||||
## pour faire l'ampliation-réduction entre dessin et le résultat de l'imprimante
|
|
||||||
## C'est tres important s'assurer que la configuration de l'imprimante ne spécifie pas l'option "Fit in page"
|
|
||||||
## ou similaire, sinon, l'échelle sera changée pendant l'impression!
|
|
||||||
scale 1 {Scale}
|
|
||||||
|
|
||||||
## Echelle graphique 100 m ampleur (Généralement, le choix scale/10 est plutôt pas mal)
|
|
||||||
scale-bar 40 m
|
|
||||||
|
|
||||||
## Voici une ligne pour specifier qu'il faut imprimer une grille au dessous de la topo
|
|
||||||
#grid bottom
|
|
||||||
grid off
|
|
||||||
## Une ligne pour specifier que la grille est 1000x1000x1000 m
|
|
||||||
## (Trois dimensions, oui, ça sert pour la coupe aussi)
|
|
||||||
#grid-size 250 250 250 m
|
|
||||||
|
|
||||||
## la topo est transparente (on peut voir les galeries inférieurs)
|
|
||||||
## C'est on par défaut, donc, pas vraiment besoin de specifier
|
|
||||||
transparency on
|
|
||||||
|
|
||||||
## Couleurs de la topographie
|
|
||||||
#colour map-bg [70 90 70]
|
|
||||||
#colour map-fg [100 100 80]
|
|
||||||
#colour map-fg altitude
|
|
||||||
#colour map-fg explo-date
|
|
||||||
#colour map-fg topo-date
|
|
||||||
#colour map-fg map
|
|
||||||
#colour map-fg scrap
|
|
||||||
#colour-legend off
|
|
||||||
colour map-fg 90
|
|
||||||
|
|
||||||
## ça marche seulement si transparency est "on" 90% blanc= 10% noir
|
|
||||||
opacity 75
|
|
||||||
#surface bottom
|
|
||||||
#surface-opacity 100
|
|
||||||
|
|
||||||
## Auteur
|
|
||||||
doc-author "{Author}"
|
|
||||||
## Titre
|
|
||||||
doc-title "{cavename} Coupe développée - 1:{Scale}"
|
|
||||||
|
|
||||||
doc-subject "{cavename}, topographie en coupe développée"
|
|
||||||
doc-keywords "Cave, Survey, {cavename}, Pierre saint Martin - Larra, Coupe développée, {map_comment}"
|
|
||||||
|
|
||||||
## Maintenant on spécifie la position de la manchette, dont l'intérieur est occupé par le titre, auteurs, etc.
|
|
||||||
## Nous pouvons indiquer les cordonnées du point de la topo ou l'on veut la manchette :
|
|
||||||
## 0 0, c'est en bas, à gauche, 100 100, c'est en haut, à droite
|
|
||||||
## La manchette a des "points cardinaux" autour : n, s, ne, sw, etc.
|
|
||||||
## Il faut specifier un de ces points comme ce que sera placé sur les cordonnées.
|
|
||||||
## Alors nous pouvons specifier que le sud-ouest de la manchette soit placé en bas, a gauche,
|
|
||||||
## ou une autre combination...
|
|
||||||
map-header 98 98 ne
|
|
||||||
## arrière plan de la manchette
|
|
||||||
map-header-bg on
|
|
||||||
## Légende pour expliciter les symboles. "on" imprimera seulement la légende des symboles dessinés
|
|
||||||
## sur la topo. Si l'on veut pour tous les symboles, utilisés ou pas, il faut indiquer "all".
|
|
||||||
## "legend off" = pas de légende
|
|
||||||
legend on
|
|
||||||
## Par défaut, la légende est de 14 cm de largeur
|
|
||||||
legend-width 15 cm
|
|
||||||
legend-columns 2
|
|
||||||
## Un commentaire à ajouter au titre, on pourrait indiquer ici la mairie où est placée la cavité
|
|
||||||
## dont le nom est probablement le titre de la topo.
|
|
||||||
map-comment "{map_comment}"
|
|
||||||
#map-comment "{map_comment}<br>Coordonnées : ({cs}/WGS84) xxx.xxx xxxx.xxx, Alt.: xxxx m"
|
|
||||||
|
|
||||||
## Afficher les statistiques d'explo/topo par équipe/nom. C'est lourd
|
|
||||||
## si la cavité est importante et qu'il y a beaucoup d'explorateurs/topographes.
|
|
||||||
statistics explo-length off
|
|
||||||
statistics topo-length off
|
|
||||||
|
|
||||||
## Afficher un copyright
|
|
||||||
statistics copyright 2
|
|
||||||
|
|
||||||
## Dessin ou pas du cheminement topo
|
|
||||||
#symbol-hide point station
|
|
||||||
#symbol-hide line survey
|
|
||||||
#symbol-hide group
|
|
||||||
#symbol-show line wall
|
|
||||||
#symbol-hide point u:symbol_plan
|
|
||||||
#symbol-hide point u:symbol_extend
|
|
||||||
#debug scrap-names
|
|
||||||
#debug station-names
|
|
||||||
|
|
||||||
layers on
|
|
||||||
|
|
||||||
overlap 2 cm
|
|
||||||
|
|
||||||
## Modification du Titre de la topo
|
|
||||||
code tex-map
|
|
||||||
\legendwidth=15cm
|
|
||||||
\legendtextsize={\size[12]}
|
|
||||||
\legendtextheadersize={\size[28]} %%% Taille du titre
|
|
||||||
\legendtextsectionsize={\size[14]} %%% Taille du titre
|
|
||||||
%\legendtextcolor={\color[0 0 110]} %# RGB values 0--100
|
|
||||||
% Output map title as determined by Therion is stored in cavename, défini par la une Map.
|
|
||||||
% It will be empty if there are multiple maps selected for any one projection
|
|
||||||
% AND there are multiple source surveys identified in the thconfig file
|
|
||||||
% ie Therion can not infer a unique title from the input data given.
|
|
||||||
% This code allows you to define an output map title {cavename} if it happens to be empty
|
|
||||||
\edef\temp{\the\cavename} % cavename from Therion
|
|
||||||
\edef\nostring{} % empty string
|
|
||||||
\ifx\temp\nostring % test if cavename is empty
|
|
||||||
% if empty
|
|
||||||
reassign cavename to describe selected maps as a group
|
|
||||||
\else % if not empty keep the value set by therion, or assign an override cavename here
|
|
||||||
\fi
|
|
||||||
\cavename={{cavename}, Coupe développée 1:{Scale}} % Note Alex : Bug avec certains fichiers ?
|
|
||||||
\newtoks\club \club={{club}}
|
|
||||||
%\newtoks\thanksto \thanksto={{thanksto}}
|
|
||||||
\newtoks\wpage \wpage={{wpage}}
|
|
||||||
\newtoks\datat \datat={{datat}}
|
|
||||||
\newtoks\synth \synth={{Author}}
|
|
||||||
\framethickness=0.5mm
|
|
||||||
endcode
|
|
||||||
|
|
||||||
endlayout
|
|
||||||
## Fin de la definition du Layout "normal"
|
|
||||||
|
|
||||||
layout layout-kml
|
|
||||||
## Définition du système de projection du plan
|
|
||||||
cs EPSG:2154
|
|
||||||
## Couleur de la topographie
|
|
||||||
## Rouge-Orange = 255,69,0 -->
|
|
||||||
## Orange = 255,165,0 -->
|
|
||||||
## Orange Sombre = 255,140,0 -->
|
|
||||||
## Bleu --> 0, 0 255
|
|
||||||
color map-fg [0 0 100]
|
|
||||||
endlayout
|
|
||||||
|
|
||||||
###############################################################################################
|
|
||||||
# 3-EXPORT
|
|
||||||
###############################################################################################
|
|
||||||
|
|
||||||
## Export des xvi pour le dessin si besoin
|
|
||||||
export map -proj plan -layout xviexport -fmt xvi -o Data/{fileName}-Plan.xvi
|
|
||||||
export map -proj extended -layout xviexport -fmt xvi -o Data/{fileName}-Extended.xvi
|
|
||||||
|
|
||||||
## Selection des Maps à exporter
|
|
||||||
select MP-{fileName}-Plan-tot@{fileName}
|
|
||||||
select MC-{fileName}-Extended-tot@{fileName}
|
|
||||||
|
|
||||||
## Export des fichiers pdf, plan et coupe.
|
|
||||||
## ATTENTION, la topo étant énorme, il faut mettre l'option ne traçant pas la centerline !
|
|
||||||
|
|
||||||
export map -projection plan -fmt pdf -layout layout-Plan -o Outputs/{fileName}-Plan.pdf
|
|
||||||
export map -projection extended -fmt pdf -layout layout-Extended -o Outputs/{fileName}-Extended.pdf
|
|
||||||
|
|
||||||
## Export du fichier 3d pour Loch
|
|
||||||
export model -enable all -o Outputs/{fileName}.lox
|
|
||||||
export model -enable all -o Outputs/{fileName}.kml
|
|
||||||
|
|
||||||
## Export des fichiers ESRI
|
|
||||||
#export map -proj plan -fmt esri -o Outputs/{fileName}
|
|
||||||
|
|
||||||
## Export des fichiers kml
|
|
||||||
#export map -proj plan -fmt kml -o Outputs/{fileName}.kml -layout layout-kml
|
|
||||||
#export model -fmt kml -o Outputs/{fileName}-model.kml -enable all
|
|
||||||
#export model -enable all -o Outputs/{fileName}-3D.kml
|
|
||||||
export cave-list -location on -o Outputs/{fileName}-Cave-list.html
|
|
||||||
export survey-list -location on -o Outputs/{fileName}-Surveys.html
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################################
|
|
||||||
## END
|
|
||||||
###############################################################################################
|
|
||||||
@@ -1,810 +0,0 @@
|
|||||||
# 2024.04.12 created by TopoDroid v 5.1.40
|
|
||||||
|
|
||||||
|
|
||||||
# This work is under the Creative Commons Attribution-ShareAlike-NonCommecial License:
|
|
||||||
# <http://creativecommons.org/licenses/by-nc-sa/4.0/>
|
|
||||||
|
|
||||||
survey Geophysicaya_01_entree -title "Geophysicalskaya 01 entree"
|
|
||||||
# depart pt fr24 A00
|
|
||||||
|
|
||||||
|
|
||||||
centerline
|
|
||||||
date 2024.04.12
|
|
||||||
team "Alexandre Pont"
|
|
||||||
team "Jean-Philippe Grandcolas"
|
|
||||||
team "Gaël Cazes"
|
|
||||||
|
|
||||||
#cs long-lat
|
|
||||||
#fix PTR_FR24_A00_Geophysicalskaya 66.394767 37.673152 856 # Alt from Google Earth
|
|
||||||
cs UTM42
|
|
||||||
fix PTR_FR24_A00_Geophysicalskaya 0270251 4172755 870 # gps alex / Altitude PhA
|
|
||||||
station PTR_FR24_A00_Geophysicalskaya "Geophysicalskaya" entrance air-draught
|
|
||||||
|
|
||||||
|
|
||||||
#explo-date 19??
|
|
||||||
#explo-team " "
|
|
||||||
#explo-date 1972
|
|
||||||
#explo-team "Groupe AVEN"
|
|
||||||
|
|
||||||
units length meters
|
|
||||||
units compass clino degrees
|
|
||||||
data normal from to length compass clino
|
|
||||||
# extend auto
|
|
||||||
PTR_FR24_A00_Geophysicalskaya . 0.77 171.9 -42.1
|
|
||||||
PTR_FR24_A00_Geophysicalskaya . 0.59 345.7 -42.1
|
|
||||||
PTR_FR24_A00_Geophysicalskaya . 1.07 280.3 -83.5
|
|
||||||
PTR_FR24_A00_Geophysicalskaya . 0.17 77.9 54.4
|
|
||||||
extend right
|
|
||||||
|
|
||||||
PTR_FR24_A00_Geophysicalskaya 1 1.16 155.5 -59.6 # PTR_FR24_A00
|
|
||||||
# extend auto
|
|
||||||
1 . 0.87 1.2 3.5
|
|
||||||
1 . 1.07 23.9 2.8
|
|
||||||
1 . 0.31 19.8 -43.1
|
|
||||||
1 . 1.25 51.5 -14.6
|
|
||||||
1 . 0.68 111.1 0.1
|
|
||||||
1 . 1.60 79.2 -1.7
|
|
||||||
1 . 1.28 30.6 0.9
|
|
||||||
extend right
|
|
||||||
1 2 2.94 69.9 5.4
|
|
||||||
# extend auto
|
|
||||||
2 . 1.15 251.7 -12.0
|
|
||||||
2 . 0.94 232.5 -35.4
|
|
||||||
2 . 0.66 215.5 -45.5
|
|
||||||
2 . 1.12 264.4 3.9
|
|
||||||
2 . 0.62 276.1 24.2
|
|
||||||
2 . 0.54 237.2 50.1
|
|
||||||
2 . 1.70 313.3 -1.9
|
|
||||||
2 . 1.24 332.6 0.8
|
|
||||||
2 . 0.51 224.5 60.7
|
|
||||||
2 . 0.84 261.0 -49.5
|
|
||||||
2 . 1.55 171.2 -80.3
|
|
||||||
extend vertical
|
|
||||||
2 3 1.50 179.0 -57.3
|
|
||||||
# extend auto
|
|
||||||
3 . 2.59 62.1 15.4
|
|
||||||
3 . 2.72 85.4 4.2
|
|
||||||
3 . 1.29 124.2 -6.9
|
|
||||||
3 . 0.99 147.5 -9.4
|
|
||||||
3 . 1.76 179.1 -6.3
|
|
||||||
3 . 1.80 207.9 -0.5
|
|
||||||
3 . 0.97 237.3 1.0
|
|
||||||
3 . 0.90 274.2 16.6
|
|
||||||
3 . 0.56 339.4 68.3
|
|
||||||
3 . 0.80 199.3 73.4
|
|
||||||
3 . 0.70 172.9 25.6
|
|
||||||
3 . 0.75 159.0 -44.1
|
|
||||||
extend vertical
|
|
||||||
3 4 1.76 189.9 -14.9
|
|
||||||
# extend auto
|
|
||||||
4 . 1.05 44.5 -4.3
|
|
||||||
4 . 0.97 76.9 -5.0
|
|
||||||
4 . 0.73 42.8 42.7
|
|
||||||
4 . 1.00 66.1 -61.5
|
|
||||||
4 . 1.44 74.5 -48.2
|
|
||||||
extend right
|
|
||||||
4 5 1.40 85.5 -40.9
|
|
||||||
# extend auto
|
|
||||||
5 . 0.81 6.9 0.7
|
|
||||||
5 . 0.71 27.4 -2.1
|
|
||||||
5 . 0.53 167.6 23.1
|
|
||||||
5 . 0.65 132.1 31.3
|
|
||||||
5 . 0.44 62.0 64.9
|
|
||||||
5 . 1.01 64.7 5.2
|
|
||||||
5 . 0.44 168.0 -6.4
|
|
||||||
extend right
|
|
||||||
5 6 2.38 87.9 -41.5
|
|
||||||
# extend auto
|
|
||||||
6 . 1.44 15.0 35.4
|
|
||||||
6 . 2.17 37.6 29.2
|
|
||||||
6 . 1.52 158.1 9.7
|
|
||||||
6 . 1.90 217.0 16.6
|
|
||||||
6 . 0.35 200.8 -51.1
|
|
||||||
6 . 0.92 207.6 56.8
|
|
||||||
6 . 1.74 114.8 30.9
|
|
||||||
6 . 3.32 100.0 3.8
|
|
||||||
extend right
|
|
||||||
6 7 7.07 91.7 -15.0
|
|
||||||
# extend auto
|
|
||||||
7 . 6.16 334.1 28.8
|
|
||||||
7 . 7.14 1.2 22.1
|
|
||||||
7 . 8.14 37.3 7.9
|
|
||||||
7 . 9.31 97.1 -2.5
|
|
||||||
7 . 13.25 121.4 -3.4
|
|
||||||
7 . 1.63 133.8 62.7
|
|
||||||
7 . 0.89 120.0 -58.0
|
|
||||||
7 . 10.93 240.5 4.6
|
|
||||||
7 . 11.74 219.7 -1.8
|
|
||||||
7 . 2.04 201.6 42.7
|
|
||||||
7 . 4.65 171.2 18.7
|
|
||||||
7 . 12.10 165.1 1.7
|
|
||||||
7 . 7.11 160.3 -24.2
|
|
||||||
extend right
|
|
||||||
7 8 8.55 29.2 8.0
|
|
||||||
extend vertical
|
|
||||||
7 9 9.73 170.9 -20.0
|
|
||||||
# extend auto
|
|
||||||
9 . 10.71 91.8 8.0
|
|
||||||
9 . 15.71 255.1 -5.7
|
|
||||||
9 . 15.41 240.0 -11.6
|
|
||||||
9 . 16.44 209.0 -19.0
|
|
||||||
9 . 1.28 159.3 -40.3
|
|
||||||
9 . 5.37 162.4 -26.3
|
|
||||||
9 . 4.72 168.9 4.0
|
|
||||||
9 . 11.77 164.8 -4.8
|
|
||||||
extend ignore
|
|
||||||
9 10 12.21 150.7 -17.3
|
|
||||||
# extend auto
|
|
||||||
10 . 10.35 44.2 19.0
|
|
||||||
10 . 12.19 67.8 12.0
|
|
||||||
10 . 15.37 87.8 8.0
|
|
||||||
10 . 16.74 174.0 -15.4
|
|
||||||
10 . 19.62 149.0 -12.4
|
|
||||||
10 . 13.94 243.2 -9.9
|
|
||||||
10 . 3.13 143.3 -33.1
|
|
||||||
10 . 3.51 152.5 71.2
|
|
||||||
10 . 3.97 127.8 42.1
|
|
||||||
10 . 13.50 128.0 13.8
|
|
||||||
extend right
|
|
||||||
10 11 12.27 146.2 -10.7
|
|
||||||
# extend auto
|
|
||||||
11 . 7.08 162.3 -17.0
|
|
||||||
11 . 9.80 130.5 -7.6
|
|
||||||
11 . 3.62 100.9 40.2
|
|
||||||
11 . 10.67 102.6 20.2
|
|
||||||
11 . 2.07 130.7 -41.8
|
|
||||||
11 . 6.76 109.7 -20.5
|
|
||||||
extend right
|
|
||||||
11 12 12.24 114.3 -8.3
|
|
||||||
# extend auto
|
|
||||||
12 . 8.54 37.7 5.2
|
|
||||||
12 . 1.68 158.4 -1.0
|
|
||||||
12 . 4.09 135.3 -19.6
|
|
||||||
12 . 4.71 88.5 30.3
|
|
||||||
12 . 6.41 114.8 -33.4
|
|
||||||
12 . 2.42 77.4 -31.4
|
|
||||||
extend right
|
|
||||||
12 13 6.78 114.0 -18.5
|
|
||||||
# extend auto
|
|
||||||
13 . 3.87 34.7 9.8
|
|
||||||
13 . 1.37 324.4 -82.3
|
|
||||||
13 . 3.24 88.5 -60.6
|
|
||||||
extend right
|
|
||||||
13 14 4.88 89.5 -28.4
|
|
||||||
# extend auto
|
|
||||||
14 . 1.90 229.0 13.3
|
|
||||||
14 . 1.16 206.0 9.9
|
|
||||||
14 . 1.71 137.9 -8.0
|
|
||||||
14 . 0.96 64.1 -6.7
|
|
||||||
14 . 1.00 174.3 71.3
|
|
||||||
14 . 1.33 1.1 42.9
|
|
||||||
14 . 1.88 315.2 -2.0
|
|
||||||
14 . 3.96 336.6 -12.0
|
|
||||||
extend vertical
|
|
||||||
14 15 4.25 9.4 -26.4
|
|
||||||
# extend auto
|
|
||||||
15 . 1.96 165.5 -35.4
|
|
||||||
15 . 1.56 220.7 -35.0
|
|
||||||
15 . 1.72 230.2 -62.6
|
|
||||||
15 . 2.42 329.3 1.0
|
|
||||||
extend right
|
|
||||||
15 16 1.98 107.9 -85.5
|
|
||||||
# extend auto
|
|
||||||
16 . 2.24 54.5 -56.7
|
|
||||||
16 . 1.39 80.2 22.8
|
|
||||||
16 . 1.11 81.6 57.5
|
|
||||||
extend right
|
|
||||||
16 17 9.21 105.0 -24.3
|
|
||||||
# extend auto
|
|
||||||
17 . 5.24 201.1 0.5
|
|
||||||
17 . 10.15 142.2 2.4
|
|
||||||
17 . 3.50 281.7 51.8
|
|
||||||
17 . 2.97 146.8 71.6
|
|
||||||
17 . 4.22 74.9 41.0
|
|
||||||
17 . 5.82 76.1 12.2
|
|
||||||
17 . 11.16 25.7 0.7
|
|
||||||
17 . 6.69 8.9 11.3
|
|
||||||
17 . 19.90 41.3 -3.3
|
|
||||||
17 . 5.72 76.6 -23.9
|
|
||||||
17 . 9.74 70.1 -23.9
|
|
||||||
extend right
|
|
||||||
17 18 8.45 75.9 -21.0
|
|
||||||
# extend auto
|
|
||||||
18 . 10.52 10.4 10.7
|
|
||||||
18 . 14.54 42.0 7.9
|
|
||||||
18 . 10.86 162.9 15.0
|
|
||||||
18 . 19.17 144.0 9.3
|
|
||||||
18 . 4.55 87.6 -27.3
|
|
||||||
18 . 8.61 87.7 -19.4
|
|
||||||
18 . 4.40 115.4 64.5
|
|
||||||
18 . 11.46 97.3 30.4
|
|
||||||
extend right
|
|
||||||
|
|
||||||
18 PTR_FR24_A01_19 19.59 100.6 -1.2 # 19 : PTR_FR24_A01_ depart rg
|
|
||||||
# extend auto
|
|
||||||
PTR_FR24_A01_19 . 14.69 214.8 8.8
|
|
||||||
PTR_FR24_A01_19 . 10.74 18.1 -12.8
|
|
||||||
PTR_FR24_A01_19 . 15.31 359.0 -19.2
|
|
||||||
PTR_FR24_A01_19 . 15.06 15.0 -27.2
|
|
||||||
PTR_FR24_A01_19 . 6.51 15.4 -41.7
|
|
||||||
PTR_FR24_A01_19 . 12.68 59.4 -17.0
|
|
||||||
PTR_FR24_A01_19 . 14.74 79.6 -5.3
|
|
||||||
PTR_FR24_A01_19 . 6.13 55.5 71.4
|
|
||||||
PTR_FR24_A01_19 . 27.16 160.6 16.8
|
|
||||||
PTR_FR24_A01_19 . 9.64 120.5 -5.5
|
|
||||||
PTR_FR24_A01_19 . 18.68 120.1 1.9
|
|
||||||
PTR_FR24_A01_19 . 11.54 133.9 6.1
|
|
||||||
extend right
|
|
||||||
PTR_FR24_A01_19 20 21.34 131.3 7.9
|
|
||||||
# extend auto
|
|
||||||
20 . 11.72 60.1 -2.3
|
|
||||||
20 . 24.25 83.3 -1.4
|
|
||||||
20 . 8.41 145.3 64.6
|
|
||||||
20 . 15.97 129.9 40.0
|
|
||||||
20 . 12.64 231.9 15.9
|
|
||||||
20 . 14.12 200.4 21.2
|
|
||||||
20 . 1.81 55.9 -34.2
|
|
||||||
20 . 8.24 91.6 -16.3
|
|
||||||
extend right
|
|
||||||
20 21 13.25 120.2 6.1
|
|
||||||
# extend auto
|
|
||||||
21 . 21.20 79.1 3.5
|
|
||||||
21 . 27.03 99.6 3.0
|
|
||||||
21 . 13.82 216.3 7.0
|
|
||||||
21 . 19.89 184.8 5.7
|
|
||||||
21 . 9.16 133.2 57.8
|
|
||||||
21 . 18.70 139.3 28.9
|
|
||||||
21 . 6.14 146.7 -11.8
|
|
||||||
21 . 14.14 141.3 -4.8
|
|
||||||
extend right
|
|
||||||
21 22 24.07 137.6 0.7
|
|
||||||
# extend auto
|
|
||||||
22 . 12.50 88.5 1.2
|
|
||||||
22 . 17.53 116.7 -3.7
|
|
||||||
22 . 19.99 127.7 -5.0
|
|
||||||
22 . 16.46 244.5 7.0
|
|
||||||
22 . 19.33 215.1 2.6
|
|
||||||
22 . 7.32 196.2 44.9
|
|
||||||
22 . 20.67 160.7 10.9
|
|
||||||
22 . 10.38 191.9 -19.2
|
|
||||||
22 . 14.93 152.8 -17.5
|
|
||||||
22 . 7.97 144.4 70.7
|
|
||||||
extend right
|
|
||||||
22 23 21.01 155.1 -13.1
|
|
||||||
# extend auto
|
|
||||||
23 . 17.29 237.9 6.0
|
|
||||||
23 . 23.42 201.3 0.9
|
|
||||||
23 . 35.04 176.1 -0.8
|
|
||||||
23 . 8.90 201.5 63.0
|
|
||||||
23 . 13.84 158.5 49.6
|
|
||||||
23 . 11.95 47.7 8.8
|
|
||||||
23 . 11.29 75.3 6.2
|
|
||||||
23 . 2.26 22.3 -23.8
|
|
||||||
23 . 4.76 140.1 -33.2
|
|
||||||
23 . 12.10 142.3 -15.0
|
|
||||||
extend right
|
|
||||||
|
|
||||||
23 PTR_FR24_A02_24 24.18 162.8 -5.1 # PTR_FR24_A02
|
|
||||||
# extend auto
|
|
||||||
PTR_FR24_A02_24 . 25.81 49.0 1.5
|
|
||||||
PTR_FR24_A02_24 . 10.69 64.4 48.5
|
|
||||||
PTR_FR24_A02_24 . 12.91 82.2 35.5
|
|
||||||
PTR_FR24_A02_24 . 13.66 130.4 -8.2
|
|
||||||
PTR_FR24_A02_24 . 20.98 109.3 -6.0
|
|
||||||
PTR_FR24_A02_24 . 3.75 92.4 -27.6
|
|
||||||
PTR_FR24_A02_24 . 14.87 96.4 -16.9
|
|
||||||
PTR_FR24_A02_24 . 17.48 214.8 1.9
|
|
||||||
PTR_FR24_A02_24 . 11.90 199.5 48.4
|
|
||||||
extend left
|
|
||||||
PTR_FR24_A02_24 25 12.58 197.1 -14.8
|
|
||||||
# extend auto
|
|
||||||
25 . 12.47 15.4 15.8
|
|
||||||
25 . 7.94 103.2 2.4
|
|
||||||
25 . 4.98 152.3 -2.1
|
|
||||||
25 . 9.92 262.7 3.9
|
|
||||||
25 . 10.09 239.2 -10.3
|
|
||||||
25 . 4.68 243.1 57.1
|
|
||||||
25 . 5.95 207.1 21.9
|
|
||||||
25 . 8.39 201.3 -11.5
|
|
||||||
25 . 2.38 278.8 -19.9
|
|
||||||
25 . 6.27 228.3 -31.6
|
|
||||||
extend left
|
|
||||||
25 26 8.73 195.3 -32.9
|
|
||||||
# extend auto
|
|
||||||
26 . 1.39 81.4 -17.5
|
|
||||||
26 . 1.95 103.6 -26.9
|
|
||||||
26 . 3.44 235.8 -6.6
|
|
||||||
26 . 1.22 165.5 51.8
|
|
||||||
26 . 1.11 159.7 1.3
|
|
||||||
26 . 3.32 174.8 -51.6
|
|
||||||
26 . 4.14 157.0 -49.3
|
|
||||||
extend right
|
|
||||||
26 27 7.92 164.8 -40.9
|
|
||||||
# extend auto
|
|
||||||
27 . 4.69 253.0 5.1
|
|
||||||
27 . 10.44 232.5 -8.4
|
|
||||||
27 . 1.05 285.8 56.5
|
|
||||||
27 . 1.55 165.3 20.1
|
|
||||||
27 . 1.74 163.9 -30.9
|
|
||||||
27 . 4.38 36.4 10.5
|
|
||||||
27 . 9.30 95.3 -14.0
|
|
||||||
27 . 10.56 106.6 -17.1
|
|
||||||
27 . 8.66 145.4 -24.0
|
|
||||||
extend right
|
|
||||||
27 28 11.40 156.3 -21.1
|
|
||||||
# extend auto
|
|
||||||
28 . 9.43 59.0 -5.6
|
|
||||||
28 . 7.54 103.6 -3.7
|
|
||||||
28 . 6.01 344.5 46.6
|
|
||||||
28 . 3.38 165.1 64.7
|
|
||||||
28 . 1.33 166.7 -35.5
|
|
||||||
28 . 15.04 276.5 4.6
|
|
||||||
28 . 18.01 248.3 1.6
|
|
||||||
28 . 25.17 216.7 2.3
|
|
||||||
28 . 6.82 205.2 -16.5
|
|
||||||
28 . 12.45 181.1 -11.1
|
|
||||||
28 . 7.15 173.8 20.1
|
|
||||||
extend right
|
|
||||||
28 29 30.02 156.5 -2.9
|
|
||||||
# extend auto
|
|
||||||
29 . 15.48 47.8 6.9
|
|
||||||
29 . 19.97 76.7 8.9
|
|
||||||
29 . 15.77 242.5 12.9
|
|
||||||
29 . 17.79 194.6 8.3
|
|
||||||
29 . 8.31 323.1 36.7
|
|
||||||
29 . 5.53 36.7 69.3
|
|
||||||
29 . 11.26 104.2 29.5
|
|
||||||
29 . 2.37 130.2 -36.2
|
|
||||||
29 . 6.88 120.7 -16.1
|
|
||||||
29 . 4.33 335.1 -31.8
|
|
||||||
29 . 10.90 327.5 -7.4
|
|
||||||
extend right
|
|
||||||
|
|
||||||
29 PTR_FR24_A03_30 14.82 114.9 -3.8 # PTR_FR24_A03
|
|
||||||
# extend auto
|
|
||||||
PTR_FR24_A03_30 . 14.79 9.8 13.2
|
|
||||||
PTR_FR24_A03_30 . 13.04 38.2 11.4
|
|
||||||
PTR_FR24_A03_30 . 9.91 114.8 5.8
|
|
||||||
PTR_FR24_A03_30 . 11.98 121.5 5.2
|
|
||||||
PTR_FR24_A03_30 . 12.15 102.6 5.5
|
|
||||||
PTR_FR24_A03_30 . 19.22 141.5 4.7
|
|
||||||
PTR_FR24_A03_30 . 17.68 214.5 7.3
|
|
||||||
PTR_FR24_A03_30 . 22.98 243.0 9.9
|
|
||||||
PTR_FR24_A03_30 . 7.73 229.7 50.4
|
|
||||||
PTR_FR24_A03_30 . 6.25 170.5 71.2
|
|
||||||
PTR_FR24_A03_30 . 8.19 87.4 56.2
|
|
||||||
PTR_FR24_A03_30 . 3.64 77.5 -8.7
|
|
||||||
PTR_FR24_A03_30 . 9.72 85.5 35.9
|
|
||||||
extend right
|
|
||||||
PTR_FR24_A03_30 31 13.97 82.1 5.2
|
|
||||||
# extend auto
|
|
||||||
31 . 1.66 48.2 24.6
|
|
||||||
31 . 3.63 200.3 3.0
|
|
||||||
31 . 5.22 162.9 1.8
|
|
||||||
31 . 3.62 173.0 -21.9
|
|
||||||
31 . 6.84 124.0 24.9
|
|
||||||
extend vertical
|
|
||||||
PTR_FR24_A03_30 32 19.55 186.9 -3.7
|
|
||||||
# extend auto
|
|
||||||
32 . 12.52 93.1 14.6
|
|
||||||
32 . 6.09 266.3 6.0
|
|
||||||
32 . 5.85 161.2 88.6
|
|
||||||
32 . 1.43 237.3 -81.9
|
|
||||||
32 . 9.73 186.5 5.2
|
|
||||||
32 . 16.59 51.4 9.3
|
|
||||||
32 . 10.56 300.8 12.6
|
|
||||||
extend right
|
|
||||||
32 33 16.05 159.4 -13.4
|
|
||||||
# extend auto
|
|
||||||
33 . 6.78 79.1 18.5
|
|
||||||
33 . 7.28 261.6 22.0
|
|
||||||
33 . 3.68 152.9 86.4
|
|
||||||
33 . 1.56 276.4 -79.5
|
|
||||||
33 . 11.85 153.0 14.7
|
|
||||||
33 . 9.07 49.4 27.8
|
|
||||||
33 . 9.20 315.8 34.4
|
|
||||||
33 . 9.92 218.7 11.6
|
|
||||||
extend left
|
|
||||||
33 34 11.85 199.8 1.5
|
|
||||||
# extend auto
|
|
||||||
34 . 3.22 305.0 10.7
|
|
||||||
34 . 8.37 103.7 9.0
|
|
||||||
34 . 3.09 351.7 86.2
|
|
||||||
34 . 1.53 45.9 -65.0
|
|
||||||
34 . 13.94 55.2 5.8
|
|
||||||
34 . 6.44 341.0 12.6
|
|
||||||
34 . 6.04 266.4 12.2
|
|
||||||
34 . 9.82 137.4 23.0
|
|
||||||
extend left
|
|
||||||
34 35 8.67 207.7 10.2
|
|
||||||
# extend auto
|
|
||||||
35 . 10.92 78.6 10.6
|
|
||||||
35 . 2.43 145.9 89.0
|
|
||||||
35 . 8.63 238.7 12.7
|
|
||||||
35 . 1.65 183.4 -85.5
|
|
||||||
35 . 14.95 112.3 14.2
|
|
||||||
35 . 13.10 169.4 8.3
|
|
||||||
35 . 5.74 335.5 2.9
|
|
||||||
extend left
|
|
||||||
35 36 8.78 247.8 10.0
|
|
||||||
# extend auto
|
|
||||||
36 . 8.67 172.9 5.4
|
|
||||||
36 . 11.41 172.7 5.7
|
|
||||||
extend vertical
|
|
||||||
|
|
||||||
35 PTR_FR24_A05_37 8.69 172.9 5.3 # PTR_FR24_A05_ sur bite gypse
|
|
||||||
# extend auto
|
|
||||||
PTR_FR24_A05_37 . 3.24 244.8 23.0
|
|
||||||
PTR_FR24_A05_37 . 12.43 53.8 9.2
|
|
||||||
PTR_FR24_A05_37 . 1.84 131.1 88.3
|
|
||||||
PTR_FR24_A05_37 . 1.57 30.9 -68.2
|
|
||||||
PTR_FR24_A05_37 . 5.17 144.4 13.6
|
|
||||||
PTR_FR24_A05_37 . 9.93 317.7 7.3
|
|
||||||
PTR_FR24_A05_37 . 14.47 40.0 8.2
|
|
||||||
extend right
|
|
||||||
PTR_FR24_A05_37 38 6.07 93.8 4.6
|
|
||||||
# extend auto
|
|
||||||
38 . 6.91 74.6 13.8
|
|
||||||
38 . 5.24 227.8 9.0
|
|
||||||
38 . 1.88 174.7 84.5
|
|
||||||
38 . 1.45 284.8 -79.0
|
|
||||||
extend right
|
|
||||||
38 39 8.85 167.0 -12.8
|
|
||||||
# extend auto
|
|
||||||
39 . 4.91 275.0 13.4
|
|
||||||
39 . 9.05 50.0 15.8
|
|
||||||
39 . 2.46 176.7 80.6
|
|
||||||
39 . 1.53 270.8 -79.1
|
|
||||||
39 . 11.08 162.1 6.6
|
|
||||||
extend left
|
|
||||||
39 40 7.84 201.4 2.0
|
|
||||||
# extend auto
|
|
||||||
40 . 5.54 161.6 7.0
|
|
||||||
40 . 4.78 330.3 14.9
|
|
||||||
40 . 1.81 225.3 82.6
|
|
||||||
40 . 1.41 334.7 -75.2
|
|
||||||
40 . 6.94 104.0 8.2
|
|
||||||
40 . 6.83 298.6 8.6
|
|
||||||
extend left
|
|
||||||
40 41 10.61 248.7 3.2
|
|
||||||
# extend auto
|
|
||||||
41 . 7.60 125.4 -2.9
|
|
||||||
41 . 9.91 177.4 0.9
|
|
||||||
41 . 5.06 349.4 3.7
|
|
||||||
41 . 1.17 212.9 87.7
|
|
||||||
41 . 1.91 211.4 -84.2
|
|
||||||
extend left
|
|
||||||
41 42 13.83 266.1 -4.4
|
|
||||||
# extend auto
|
|
||||||
42 . 5.93 349.8 22.7
|
|
||||||
42 . 5.17 176.3 0.7
|
|
||||||
42 . 1.62 170.9 82.3
|
|
||||||
42 . 0.87 93.4 -86.0
|
|
||||||
42 . 6.30 23.3 14.7
|
|
||||||
42 . 8.51 261.2 5.3
|
|
||||||
extend left
|
|
||||||
42 43 6.06 256.2 -1.4
|
|
||||||
# extend auto
|
|
||||||
43 . 1.38 205.9 5.4
|
|
||||||
43 . 3.94 26.6 26.9
|
|
||||||
43 . 1.68 332.7 83.5
|
|
||||||
43 . 1.20 236.7 -54.7
|
|
||||||
extend left
|
|
||||||
43 44 4.52 310.2 2.9
|
|
||||||
# extend auto
|
|
||||||
44 . 2.95 226.3 -24.4
|
|
||||||
44 . 13.10 48.2 38.4
|
|
||||||
44 . 9.24 293.2 1.2
|
|
||||||
44 . 2.88 156.7 26.1
|
|
||||||
44 . 1.30 70.9 -78.2
|
|
||||||
44 . 1.09 325.4 88.0
|
|
||||||
extend left
|
|
||||||
44 45 7.07 311.1 -8.8
|
|
||||||
# extend auto
|
|
||||||
45 . 3.71 168.8 4.8
|
|
||||||
45 . 4.46 311.2 4.7
|
|
||||||
45 . 4.81 291.7 80.5
|
|
||||||
45 . 1.26 249.1 -77.8
|
|
||||||
extend left
|
|
||||||
45 46 12.62 275.8 -24.3
|
|
||||||
# extend auto
|
|
||||||
46 . 2.61 352.6 3.1
|
|
||||||
46 . 6.04 170.3 10.9
|
|
||||||
46 . 2.45 335.9 82.8
|
|
||||||
46 . 1.46 119.6 -84.4
|
|
||||||
46 . 5.22 219.0 5.2
|
|
||||||
46 . 4.03 84.6 8.5
|
|
||||||
extend left
|
|
||||||
46 47 12.85 242.1 -2.5
|
|
||||||
# extend auto
|
|
||||||
47 . 1.22 150.2 -0.6
|
|
||||||
47 . 2.17 304.4 8.3
|
|
||||||
47 . 1.52 358.0 88.3
|
|
||||||
47 . 0.86 333.6 -89.5
|
|
||||||
47 . 1.96 106.6 4.6
|
|
||||||
47 . 2.83 11.8 0.8
|
|
||||||
47 . 4.13 248.9 9.4
|
|
||||||
extend left
|
|
||||||
47 PTR_FR24_A06_48 4.78 245.3 2.3 # PTR_FR24_A06_
|
|
||||||
# extend auto
|
|
||||||
PTR_FR24_A06_48 . 1.19 107.7 2.8
|
|
||||||
PTR_FR24_A06_48 . 1.31 301.2 0.8
|
|
||||||
PTR_FR24_A06_48 . 0.96 5.6 85.7
|
|
||||||
PTR_FR24_A06_48 . 1.39 244.8 -84.8
|
|
||||||
extend vertical
|
|
||||||
PTR_FR24_A06_48 49 2.32 182.0 -33.1
|
|
||||||
# extend auto
|
|
||||||
49 . 1.22 157.0 13.6
|
|
||||||
49 . 1.47 325.7 18.8
|
|
||||||
49 . 0.43 241.9 78.5
|
|
||||||
49 . 0.38 134.1 -76.3
|
|
||||||
extend left
|
|
||||||
49 50 5.87 234.0 -3.0 # laminoire a suivre...
|
|
||||||
45 51 10.31 349.4 22.5
|
|
||||||
# extend auto
|
|
||||||
51 . 0.61 284.6 2.3
|
|
||||||
51 . 18.47 134.2 8.0
|
|
||||||
51 . 0.85 149.6 80.7
|
|
||||||
51 . 1.19 104.7 -70.1
|
|
||||||
extend right
|
|
||||||
51 52 9.88 83.0 6.3
|
|
||||||
# extend auto
|
|
||||||
52 . 12.11 146.7 25.2
|
|
||||||
52 . 10.12 194.2 12.5
|
|
||||||
52 . 2.64 351.8 -7.1
|
|
||||||
52 . 1.09 235.2 85.3
|
|
||||||
52 . 1.83 356.1 -84.6
|
|
||||||
extend right
|
|
||||||
52 53 14.63 93.9 15.2
|
|
||||||
# extend auto
|
|
||||||
53 . 7.84 182.3 4.1
|
|
||||||
53 . 6.10 11.3 3.4
|
|
||||||
53 . 2.69 207.3 80.8
|
|
||||||
53 . 3.04 241.0 -64.2
|
|
||||||
53 . 15.74 219.1 -1.3
|
|
||||||
53 . 19.02 245.7 -1.8
|
|
||||||
53 . 10.01 266.9 -0.9
|
|
||||||
53 . 5.30 326.9 -1.3
|
|
||||||
53 . 10.98 128.2 -0.3
|
|
||||||
53 . 6.92 76.7 2.3
|
|
||||||
53 . 12.49 87.6 1.9
|
|
||||||
extend right
|
|
||||||
|
|
||||||
53 54 10.80 87.7 -12.5 # 54 pt topo 2023 35
|
|
||||||
# extend auto
|
|
||||||
54 . 2.39 101.4 12.5
|
|
||||||
54 . 4.68 303.6 7.3
|
|
||||||
54 . 1.73 58.8 10.0
|
|
||||||
54 . 1.36 172.9 -79.4
|
|
||||||
54 . 3.95 205.3 85.0
|
|
||||||
extend vertical
|
|
||||||
# bouclage pt 37
|
|
||||||
54 PTR_FR24_A05_37 5.29 2.7 -33.4
|
|
||||||
extend right
|
|
||||||
31 55 4.93 146.6 -17.1
|
|
||||||
# extend auto
|
|
||||||
55 . 2.42 5.0 7.4
|
|
||||||
55 . 1.27 190.1 19.0
|
|
||||||
55 . 3.78 80.2 84.2
|
|
||||||
55 . 3.44 24.9 46.1
|
|
||||||
55 . 0.88 75.0 -80.7
|
|
||||||
55 . 7.00 73.4 -4.9
|
|
||||||
55 . 4.33 110.6 1.0
|
|
||||||
extend right
|
|
||||||
55 56 10.18 93.9 -13.6
|
|
||||||
# extend auto
|
|
||||||
56 . 4.07 201.2 12.0
|
|
||||||
56 . 3.09 351.6 12.8
|
|
||||||
56 . 4.81 144.5 84.5
|
|
||||||
56 . 1.12 221.7 -86.5
|
|
||||||
56 . 6.05 155.1 7.6
|
|
||||||
56 . 8.48 58.1 11.5
|
|
||||||
56 . 3.87 318.5 7.1
|
|
||||||
extend right
|
|
||||||
56 57 10.94 104.5 6.3
|
|
||||||
# extend auto
|
|
||||||
57 . 6.10 200.7 2.4
|
|
||||||
57 . 7.67 24.3 3.6
|
|
||||||
57 . 8.37 326.4 2.4
|
|
||||||
57 . 14.02 82.6 9.0
|
|
||||||
57 . 10.30 150.9 9.9
|
|
||||||
57 . 2.11 124.2 86.8
|
|
||||||
57 . 2.77 211.2 -74.8
|
|
||||||
extend right
|
|
||||||
57 58 17.08 121.9 12.1
|
|
||||||
# extend auto
|
|
||||||
58 . 5.52 39.9 6.2
|
|
||||||
58 . 2.32 214.2 -6.6
|
|
||||||
58 . 1.30 110.9 85.1
|
|
||||||
58 . 1.68 214.4 -86.9
|
|
||||||
58 . 9.81 93.9 5.8
|
|
||||||
extend right
|
|
||||||
58 59 12.74 122.3 2.7
|
|
||||||
# extend auto
|
|
||||||
59 . 10.93 50.2 -2.3
|
|
||||||
59 . 5.96 214.6 -0.5
|
|
||||||
59 . 1.84 268.1 85.4
|
|
||||||
59 . 2.49 255.9 -78.7
|
|
||||||
59 . 7.94 146.5 -0.1
|
|
||||||
59 . 14.86 358.7 0.9
|
|
||||||
59 . 12.57 120.6 -0.2
|
|
||||||
59 . 14.29 120.7 -0.2
|
|
||||||
extend right
|
|
||||||
|
|
||||||
59 PTR_FR24_A07_60 12.55 120.7 -0.2 # PTR_FR24_A07_
|
|
||||||
# extend auto
|
|
||||||
PTR_FR24_A07_60 . 2.52 58.6 13.3
|
|
||||||
PTR_FR24_A07_60 . 2.35 223.8 -4.8
|
|
||||||
PTR_FR24_A07_60 . 0.99 125.8 85.3
|
|
||||||
PTR_FR24_A07_60 . 1.70 218.9 -78.5
|
|
||||||
extend left
|
|
||||||
PTR_FR24_A07_60 61 4.83 250.4 -37.7
|
|
||||||
# extend auto
|
|
||||||
61 . 3.45 254.0 2.6
|
|
||||||
61 . 1.18 104.3 12.3
|
|
||||||
61 . 0.78 259.3 85.4
|
|
||||||
61 . 1.53 149.1 -78.0
|
|
||||||
extend right
|
|
||||||
|
|
||||||
61 62 5.21 135.6 6.7 # non marqué, etroiture dans gypse
|
|
||||||
|
|
||||||
57 63 6.36 15.5 -2.8
|
|
||||||
# extend auto
|
|
||||||
63 . 9.55 276.4 5.7
|
|
||||||
63 . 4.16 93.3 12.7
|
|
||||||
63 . 2.46 266.1 86.3
|
|
||||||
63 . 1.05 94.3 -84.5
|
|
||||||
63 . 19.59 5.7 -6.9
|
|
||||||
63 . 13.22 185.6 10.5
|
|
||||||
63 . 8.38 286.2 -8.9
|
|
||||||
extend right
|
|
||||||
63 64 9.58 30.7 -8.4
|
|
||||||
# extend auto
|
|
||||||
64 . 8.81 35.5 -2.2
|
|
||||||
64 . 9.83 116.7 4.0
|
|
||||||
64 . 8.26 198.9 5.0
|
|
||||||
64 . 15.67 259.1 -3.3
|
|
||||||
64 . 19.65 280.3 -2.1
|
|
||||||
64 . 1.56 325.3 84.6
|
|
||||||
64 . 1.12 160.8 -84.0
|
|
||||||
extend left
|
|
||||||
64 65 9.67 324.1 -4.7
|
|
||||||
# extend auto
|
|
||||||
65 . 9.73 2.3 4.8
|
|
||||||
65 . 15.44 218.1 2.2
|
|
||||||
65 . 13.76 111.4 5.6
|
|
||||||
65 . 10.17 334.2 4.7
|
|
||||||
65 . 17.78 281.5 0.3
|
|
||||||
65 . 1.56 219.4 87.6
|
|
||||||
65 . 1.54 352.4 -88.9
|
|
||||||
extend left
|
|
||||||
65 66 21.63 297.4 -0.1
|
|
||||||
# extend auto
|
|
||||||
66 . 3.71 25.2 7.0
|
|
||||||
66 . 1.93 206.0 1.0
|
|
||||||
66 . 0.57 271.5 77.6
|
|
||||||
66 . 1.04 185.3 -87.3
|
|
||||||
extend left
|
|
||||||
# arret etroiture
|
|
||||||
66 67 10.91 307.6 -0.9
|
|
||||||
# extend auto
|
|
||||||
67 . 0.49 190.2 -3.8
|
|
||||||
67 . 0.64 10.0 1.8
|
|
||||||
67 . 0.54 8.3 -74.5
|
|
||||||
67 . 0.27 295.2 68.0
|
|
||||||
extend right
|
|
||||||
65 68 10.62 16.4 5.9
|
|
||||||
# extend auto
|
|
||||||
68 . 2.69 79.6 -3.1
|
|
||||||
68 . 0.44 266.3 1.3
|
|
||||||
68 . 0.69 352.1 84.2
|
|
||||||
68 . 1.01 4.1 -82.3
|
|
||||||
extend vertical
|
|
||||||
68 69 3.07 4.0 18.7
|
|
||||||
# extend auto
|
|
||||||
69 . 6.43 84.1 10.2
|
|
||||||
69 . 8.88 250.5 8.4
|
|
||||||
69 . 3.56 340.6 73.8
|
|
||||||
69 . 1.39 247.8 -75.6
|
|
||||||
69 . 21.08 0.8 12.5
|
|
||||||
69 . 25.84 49.5 4.3
|
|
||||||
69 . 22.31 278.6 1.0
|
|
||||||
69 . 22.91 286.3 2.6
|
|
||||||
69 . 4.16 101.9 -0.2
|
|
||||||
69 . 2.16 158.4 0.4
|
|
||||||
extend left
|
|
||||||
69 70 10.37 320.9 12.9
|
|
||||||
# extend auto
|
|
||||||
70 . 19.22 342.6 26.8
|
|
||||||
70 . 10.19 205.4 5.1
|
|
||||||
70 . 21.67 46.9 12.3
|
|
||||||
70 . 15.46 86.4 7.8
|
|
||||||
70 . 13.80 109.1 0.8
|
|
||||||
70 . 1.95 197.2 -79.6
|
|
||||||
70 . 1.70 213.8 81.6
|
|
||||||
70 . 6.20 330.6 75.3
|
|
||||||
extend left
|
|
||||||
70 71 17.68 261.0 -3.7
|
|
||||||
# extend auto
|
|
||||||
71 . 1.08 188.6 -1.8
|
|
||||||
71 . 1.20 30.5 4.7
|
|
||||||
71 . 0.89 270.8 80.4
|
|
||||||
71 . 1.30 312.9 -83.8
|
|
||||||
extend left
|
|
||||||
71 72 10.98 332.5 16.7
|
|
||||||
# extend auto
|
|
||||||
72 . 16.22 350.3 22.6
|
|
||||||
72 . 9.66 128.1 12.8
|
|
||||||
72 . 25.59 63.1 11.2
|
|
||||||
72 . 3.55 206.1 -2.0
|
|
||||||
72 . 5.55 186.6 89.6
|
|
||||||
72 . 1.24 111.2 -69.5
|
|
||||||
extend right
|
|
||||||
|
|
||||||
72 PTR_FR24_A04_73 15.82 68.9 10.2 # PTR_FR24_A04_
|
|
||||||
# extend auto
|
|
||||||
PTR_FR24_A04_73 . 15.77 63.7 12.6
|
|
||||||
PTR_FR24_A04_73 . 16.28 230.0 -4.7
|
|
||||||
PTR_FR24_A04_73 . 11.77 179.7 -1.8
|
|
||||||
PTR_FR24_A04_73 . 25.50 115.7 -3.1
|
|
||||||
PTR_FR24_A04_73 . 0.16 323.7 4.2
|
|
||||||
PTR_FR24_A04_73 . 5.18 215.9 80.5
|
|
||||||
PTR_FR24_A04_73 . 2.37 127.6 -86.7
|
|
||||||
extend right
|
|
||||||
PTR_FR24_A04_73 74 7.12 128.1 -2.5
|
|
||||||
# extend auto
|
|
||||||
74 . 8.44 213.7 2.6
|
|
||||||
74 . 7.51 27.5 14.8
|
|
||||||
74 . 4.81 166.1 80.9
|
|
||||||
74 . 2.13 55.6 -83.3
|
|
||||||
74 . 7.31 179.1 -0.3
|
|
||||||
74 . 16.99 103.5 0.8
|
|
||||||
74 . 18.71 67.3 -0.2
|
|
||||||
extend right
|
|
||||||
# boucle
|
|
||||||
74 70 9.14 165.7 -24.0
|
|
||||||
|
|
||||||
70 75 16.58 70.3 -0.5
|
|
||||||
# extend auto
|
|
||||||
75 . 10.00 7.4 14.2
|
|
||||||
75 . 0.34 159.5 -1.0
|
|
||||||
75 . 3.82 50.7 78.9
|
|
||||||
75 . 1.36 56.9 -81.4
|
|
||||||
75 . 10.89 68.1 6.4
|
|
||||||
75 . 13.26 308.8 16.6
|
|
||||||
extend right
|
|
||||||
75 76 10.72 88.7 -11.3
|
|
||||||
# extend auto
|
|
||||||
76 . 9.39 30.2 1.7
|
|
||||||
76 . 5.90 177.9 -6.0
|
|
||||||
76 . 1.18 12.4 83.8
|
|
||||||
76 . 1.44 94.0 -88.2
|
|
||||||
76 . 3.71 357.8 31.7
|
|
||||||
76 . 9.77 343.8 26.0
|
|
||||||
76 . 2.34 215.8 10.0
|
|
||||||
extend right
|
|
||||||
|
|
||||||
76 PTR_FR24_A08_77 22.34 88.2 5.6 # PTR_FR24_A08
|
|
||||||
# extend auto
|
|
||||||
PTR_FR24_A08_77 . 0.71 354.7 5.3
|
|
||||||
PTR_FR24_A08_77 . 0.95 174.6 1.2
|
|
||||||
PTR_FR24_A08_77 . 1.00 5.7 81.4
|
|
||||||
PTR_FR24_A08_77 . 0.52 173.3 -79.4
|
|
||||||
extend right
|
|
||||||
# arret etr
|
|
||||||
PTR_FR24_A08_77 78 5.38 89.6 13.8
|
|
||||||
extend left
|
|
||||||
|
|
||||||
PTR_FR24_A04_73 79 19.38 314.8 9.8
|
|
||||||
# extend auto
|
|
||||||
79 . 4.59 214.6 2.4
|
|
||||||
79 . 4.98 35.5 8.8
|
|
||||||
79 . 4.73 290.3 67.0
|
|
||||||
79 . 0.97 206.0 -81.0
|
|
||||||
extend left
|
|
||||||
|
|
||||||
79 PTR_FR24_A09_80 4.80 307.5 39.3 # PTR_FR24_A09 jonction equipe audra pt 2
|
|
||||||
|
|
||||||
endcenterline
|
|
||||||
|
|
||||||
endsurvey
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
|||||||
therion 6.3.1 (2024-11-22)
|
|
||||||
- using Proj 9.4.1, compiled against 9.4.1
|
|
||||||
initialization file: C:\Program Files\Therion/therion.ini
|
|
||||||
reading ... done
|
|
||||||
C:\Program Files\Therion\therion.exe: error -- can't open file for input -- B3_Amonts.thconfig
|
|
||||||
Press ENTER to exit!
|
|
||||||
Reference in New Issue
Block a user