diff --git a/hugin-gopro-fusion/img/2015_01_02T10_10_53_GB120430_centre_de_briis_gopro_gopro_back - 2015_01_02T10_10_53_GF120430_centre_de_briis_gopro_gopro_front.jpg b/hugin-gopro-fusion/img/2015_01_02T10_10_53_GB120430_centre_de_briis_gopro_gopro_back - 2015_01_02T10_10_53_GF120430_centre_de_briis_gopro_gopro_front.jpg deleted file mode 100644 index 81787bf7..00000000 Binary files a/hugin-gopro-fusion/img/2015_01_02T10_10_53_GB120430_centre_de_briis_gopro_gopro_back - 2015_01_02T10_10_53_GF120430_centre_de_briis_gopro_gopro_front.jpg and /dev/null differ diff --git a/hugin-gopro-fusion/img/essai/GB080096.JPG b/hugin-gopro-fusion/img/essai/GB080096.JPG new file mode 100644 index 00000000..a18fdf88 Binary files /dev/null and b/hugin-gopro-fusion/img/essai/GB080096.JPG differ diff --git a/hugin-gopro-fusion/img/essai/GF080096.JPG b/hugin-gopro-fusion/img/essai/GF080096.JPG new file mode 100644 index 00000000..854515c7 Binary files /dev/null and b/hugin-gopro-fusion/img/essai/GF080096.JPG differ diff --git a/hugin-gopro-fusion/main.ts b/hugin-gopro-fusion/main.ts new file mode 100644 index 00000000..9c4ab3aa --- /dev/null +++ b/hugin-gopro-fusion/main.ts @@ -0,0 +1,342 @@ +/** + conversion de données gpx + conversion de données exif + **/ + +// @ts-ignore +import * as fs from 'node:fs'; +// @ts-ignore +import path from "node:path"; +// @ts-ignore +import minimist from 'minimist'; +// @ts-ignore +const moment = require("moment"); + +// configs +let sequence_name: string = '3596977' +let folders_list_txt: any = [ + "3596249", + "3596253", "3596977", + "3675557", "3675577", "3716345", "4456921", "4457241", "4457257", + // "4457273", // à récupérer + "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 just_one_photo_in_folder = false; +let folder = "/home/poule/encrypted/stockage-syncable/photos/imagerie kartaview carto tel/kartaview_export_storage/share2tykayn/" +let folder_photos = folder + "photo" +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 + "test_photo_apply" +let dossier_photo: string = folder_photos +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 exif_commands: any = ['#!/bin/bash', '# apply exif data to photos'] + + +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) + if (elem.length && elem[6]) { + let utc_time = new Date(elem[6] * 1000) + + // console.log('utc_time', utc_time.toISOString()) + track_points = `${track_points} + ${elem[2]} + + +` + }else{ + console.log('!!!!!! makeGpxFromKartaview no good element in gpx', elem) + } + }) + + 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('--------- nombre de photos ', photos_count_in_sequence) + console.log('--------- nombre de points gpx ', gpxData[sequence_name].length) + 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 date_simezone_indicator = ''; // +2:00 + let iso = moment(date).format('YYYY:MM:DD HH:mm:ss') + date_simezone_indicator + + ii = interval * 1 + + let file_photo_name = photo_folders_counter[sequence_name][photo_counter] + + + if (file_photo_name) { + // set exif data + // console.log('file_photo_name to apply exif data', photo_counter, file_photo_name) + + + // -File:ModificationDateTime=="${iso}" \\ + // -File:CreateDate="${iso}" \\ + let exif_command = `\n + exiftool -overwrite_original \\ + -GPSDateTime="${iso}" \\ + -AllDates="${iso}" \\ + -MediaCreateDate="${iso}" \\ + -MediaModifyDate="${iso}" \\ + -TrackCreateDate=="${iso}" \\ + -TrackModifyDate=="${iso}" \\ + -GPSLongitude="${lon}" \\ + -GPSLatitude="${lat}" \\ + "${dossier_photo + '/' + sequence_name + '/' + file_photo_name}" + ` + + // -GPSLongitudeRef="West" \ + // -GPSLatitudeRef="North" \ + // exiftool -overwrite_original '-AllDates { + 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(' makeGpxFromKartaview for sequence ', sequence_name) + 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()) + +/** + * 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); + if (just_one_photo_in_folder) { + filesList = [filesList.shift()] + } + return filesList; + +} + + +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) { + console.log('------- listPhotos dossier_photo', dossier_photo + '/' + sequence_number) + let photo_folder = dossier_photo + '/' + sequence_number; + getAllFilesInFolder(photo_folder) + .then(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.length) + // console.log('listOfFiles', listOfFiles) + listOfFiles.forEach((jpg_file: string) => { + openKartaviewTxtGPX(dossier_gpx_input + '/' + sequence_number + '/' + jpg_file, sequence_number) + }) + }, err => { + throw new Error(err) + }) + + listPhotos(sequence_number) + + +} + +/** + * runs after all sequences have gotten their photo and gpx data + */ +function gather() { + + + // console.log('gpxData', gpxData) + console.log('sequences', folders_list_txt) + folders_list_txt.forEach((sequence: string) => { + + reduceGpxPointsToInterval(sequence) + + }) + +} + +function main() { + + console.log('dossiers à traiter: ', folders_list_txt.length) + folders_list_txt.forEach((elem: string) => { + getGPXAndEnrichExifOfPhotosInFolder(elem).then(r => { + console.log('r', r) + } + ) + }) +} + +// run it all +main() +