/** conversion de données gpx conversion de données exif **/ import * as fs from 'node:fs'; // @ts-ignore import path from "node:path"; // @ts-ignore import minimist from 'minimist'; // configs let sequence_name: string = '3596977' let folders_list_txt: any = [ // "3596249", // "3596253", "3596977", // "3675557", "3675577", "3716345", "4456921", "4457241", "4457257", "4457273", "4457289", "4457689", "4457705", "4539913", "4539929", "4539945", "4559529", // "4559545", "4559561", "4559577", "4559593", "4559609", "4559625", "4559641", "4559657", "4559673", "4559689", "4559705", "4559721", "4559737", "4559753", // "4559769", "4559785", "4559801", "4559817", "4559833", "4559849", "4559865", "4904153", "4904233", "4904249", "4904265", "4904281", "4904297", "4904313", // "4904329", "4904345", "4904361", "4904377", "4904393", "5192937", "5193161", "5193177", "5193193", "5193209", "5193225", "5193321", "5193337", "5193417", // "5193433", "5193449", "5201385", "5213385", "5213481", "5213529", "5234665", "5234857", "5234889", "5235001", "5324265", "5775977", "5775993", "5776009", // "5776025", "6081417", "6081433", "6081449", "6081465", "6081689", "6081705", "6092281", "6092313", "6101305", "6102457", "6102473", "6102489", "6102521", // "6102537", "6102569", "6127433", "6133465", "6242729", "6329129", "6329177", "6329241", "6329305", "6329321", "6738633", "6738809", "6738953", "6752761", // "6752889", // "6752905", "6752921", "6752937", // "6752953", "6760985", "6761049", "6761289", "6794633", "7325929", "7326457", "7328265", "7330009", "7330025", // "7330041", // "7330057" ] let enable_write_gpx_file = true; let folder = "/home/poule/encrypted/stockage-syncable/photos/imagerie kartaview carto tel/kartaview_export_storage/share2tykayn/" let dossier_gpx: string = "./output_gpx" let file_gpx: string = "3596249_d875a_60a0f9bf38f99.txt" let mini_arguments: any = minimist(process.argv.slice(2)) console.log('mini_arguments', mini_arguments) if (mini_arguments['sequence']) { sequence_name = mini_arguments['sequence'] } if (mini_arguments['folder']) { folder = mini_arguments['folder'] } if (mini_arguments['gpx-output']) { dossier_gpx = mini_arguments['gpx-output'] } if (mini_arguments['gpx-input']) { file_gpx = mini_arguments['gpx-input'] } let dossier_photo: string = folder + "photo" let dossier_gpx_input: string = folder + "metadata_file" let path_gpx_input: string = dossier_gpx_input + "/" + sequence_name + "/" + file_gpx if (mini_arguments['gpx-input-path']) { path_gpx_input = mini_arguments['gpx-input-path'] } let gpxData: any = {} let tableKartaviewTrace: any = [] function makeGpxFromKartaview(tableKartaviewTrace: any) { console.log('make gpx') let track_points: string = ''; tableKartaviewTrace.forEach((elem: any) => { // console.log('elem', elem) // console.log('elem', elem[6] *1000) let utc_time = new Date(elem[6] * 1000) // console.log('utc_time', utc_time.toISOString()) track_points = `${track_points} ${elem[2]} ` }) let content = ` trace_gpx_de_demo somebody 2023 https://creativecommons.org/licenses/by-sa/2.5 nada ${track_points} ` return content; } function reduceGpxPointsToInterval(sequence_name: any) { let photos_count_in_sequence = photo_folders_counter[sequence_name].length let interval = Math.round(gpxData[sequence_name].length / photos_count_in_sequence) let ii = 1; console.log('--------- sequence_name', sequence_name) console.log('--------- interval: prendre une donnée gps tous les ', interval, 'points de la trace de séquence') let jj=0 let photo_counter = 0 gpxData[sequence_name].forEach((elem: any) => { // only work on an interval of files to assign gps coordinates jj++ ii-- if(ii<=0){ // set the gps coordinates to the picture in sequence let timestamp = elem[6] * 1000 let lat = elem[0] let lon = elem[1] let date = new Date(timestamp) let iso = date.toISOString() console.log('* point de trace n°', jj) console.log('* lat, lon', lat,lon) console.log('* date iso', iso) ii =interval*1 photo_counter++ let file_photo_name = photo_folders_counter[sequence_name][photo_counter] console.log('file_photo_name to apply exif data', file_photo_name) } }) console.log('DONE for sequence_name', sequence_name) } function openKartaviewTxtGPX(filepath: any, sequence_name: string) { console.log('filepath', filepath) let boom = filepath.split('/') let fileName = boom[boom.length - 1] console.log('fileName', fileName) fs.readFile(filepath, 'utf8', (err, data) => { if (err) { throw err; } const gpx_content = data; let lines = gpx_content.split('\n') console.log('lines.length', lines.length) let tableKartaviewTrace: any = []; // loop on all lines, only take the lines that contain :g: lines.forEach((elem: any) => { if (elem.indexOf(":g:") > -1) { // do stuff on gpxData to enrich it let boom = elem.split(':') let timestamp = boom[0] let gpsmodel = boom[2] let gps = gpsmodel.split(';') gps.push(timestamp) tableKartaviewTrace.push(gps) // let date = new Date(boom[0] * 1000) // console.log('*', date, gps[0], gps[1]) } }) gpxData[sequence_name] = [...tableKartaviewTrace] // console.log('gpxData', gpxData) let content_gpx = makeGpxFromKartaview(tableKartaviewTrace) if (enable_write_gpx_file) { writeFile('' + fileName + '_trace.gpx', content_gpx) } if(Object.keys(gpxData).length === folders_list_txt.length){ gather() } // console.log('gpx_content', gpx_content) }) } let cwd = path.dirname(process.cwd()) + '/' + path.basename(process.cwd()) let expandedFileList: any = [] /** * get a list of all files in a path * @param folderPath */ async function getAllFilesInFolder(folderPath: string) { let filesList: any = [] console.log('reading folder ', folderPath) filesList = fs.readdirSync(folderPath); // console.log('readSubdirectories - files', folderPath, filesList.length) // filesList.forEach((subDirOrFile:any) => { // const newFullPath = cwd + '/' + subDirOrFile // // if (fs.existsSync(newFullPath)) { // const s = fs.statSync(newFullPath) // // if (s.isFile()) { // expandedFileList.push(cwd + '/' + subDirOrFile) // console.log('add file', cwd + '/' + subDirOrFile) // } // } // }) return filesList; } function mapExifDataOnListOfFilesFromGpxData(listOfFiles: any, gpxData: any) { listOfFiles.forEach((elem: any) => { // find corresponding timestamp // add exif info // save file }) } function writeFile(fileName: string, fileContent: any) { console.log('write file', fileName) return fs.writeFile( `${dossier_gpx}/${fileName}`, fileContent, 'utf8', (err) => { if (err) { console.log(`Error writing file: ${err}`) } } ) } let photo_folders_counter: any = {} function listPhotos(sequence_number: string) { let photo_folder = dossier_photo + '/' + sequence_number; let gps_points = gpxData[sequence_number] // console.log('gps_points', gps_points) // pour réconcilier les données, on divise la trace en part égales du nombre de photos présentes dans la séquence. getAllFilesInFolder(photo_folder) .then(listOfFiles => { // console.log('listOfFiles', listOfFiles) photo_folders_counter[sequence_number] = listOfFiles }) } async function getGPXAndEnrichExifOfPhotosInFolder(sequence_number: string) { // get metadata txt file in metadata folder getAllFilesInFolder(dossier_gpx_input + '/' + sequence_number) .then(listOfFiles => { console.log('listOfFiles', listOfFiles) listOfFiles?.forEach((file: string) => { openKartaviewTxtGPX(dossier_gpx_input + '/' + sequence_number + '/' + file, sequence_number) }) }, err => { throw new Error(err) }) listPhotos(sequence_number) } console.log('dossiers à traiter: ', folders_list_txt.length) folders_list_txt.forEach((elem: string) => { getGPXAndEnrichExifOfPhotosInFolder(elem).then(r => { console.log('r', r) } ) }) function gather() { // console.log('gpxData', gpxData) console.log('sequences', folders_list_txt) folders_list_txt.forEach((sequence: string) => { reduceGpxPointsToInterval(sequence) }) }