scripts/kartaview_exif_mapper/main.ts

343 lines
11 KiB
TypeScript

/**
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}<trkpt lat="${elem[0]}" lon="${elem[1]}">
<ele>${elem[2]}</ele>
<time>${utc_time.toISOString()}</time>
</trkpt>
`
}else{
console.log('!!!!!! makeGpxFromKartaview no good element in gpx', elem)
}
})
let content = `<?xml version='1.0' encoding='UTF-8'?>
<gpx version="1.1" creator="JOSM GPX export" xmlns="http://www.topografix.com/GPX/1/1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<metadata>
<desc>trace_gpx_de_demo</desc>
<author>
<name>somebody</name>
</author>
<copyright author="somebody">
<year>2023</year>
<license>https://creativecommons.org/licenses/by-sa/2.5</license>
</copyright>
<keywords>nada</keywords>
</metadata>
<trk>
<trkseg>
${track_points}
</trkseg>
</trk>
</gpx>`
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<gpsdatetime' "${dossier_photo+'/'+sequence_name+'/'+file_photo_name}"
exif_commands.push(exif_command)
}
photo_counter++
}
})
exif_commands.push(`geovisio upload --api-url https://panoramax.openstreetmap.fr "${dossier_photo}/${sequence_name}"`)
let exif_bash_file = exif_commands.join('\n')
writeFile(`_exif_commmand_sequence_${sequence_name}.sh`, exif_bash_file)
console.log('\n ----- apply exif data:', `\n bash ${dossier_gpx}/${exif_bash_file}`)
console.log('\n\nDONE for sequence_name', sequence_name)
}
function openKartaviewTxtGPX(filepath: any, sequence_name: string) {
console.log('openKartaviewTxtGPX filepath', filepath)
let boom = filepath.split('/')
let fileName = boom[boom.length - 1]
console.log('openKartaviewTxtGPX 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(' 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()