Merge branch 'master' into search-pin

search-pin
Mathis FRAMIT 3 months ago
commit f01fb82c3c

7
package-lock.json generated

@ -16,6 +16,7 @@
"@angular/platform-browser": "^19.0.0",
"@angular/platform-browser-dynamic": "^19.0.0",
"@angular/router": "^19.0.0",
"exifr": "^7.1.3",
"flowbite": "^2.5.2",
"leaflet": "^1.9.4",
"rxjs": "~7.8.0",
@ -6890,6 +6891,12 @@
"node": ">=0.8.x"
}
},
"node_modules/exifr": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/exifr/-/exifr-7.1.3.tgz",
"integrity": "sha512-g/aje2noHivrRSLbAUtBPWFbxKdKhgj/xr1vATDdUXPOFYJlQ62Ft0oy+72V6XLIpDJfHs6gXLbBLAolqOXYRw==",
"license": "MIT"
},
"node_modules/exponential-backoff": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz",

@ -18,6 +18,7 @@
"@angular/platform-browser": "^19.0.0",
"@angular/platform-browser-dynamic": "^19.0.0",
"@angular/router": "^19.0.0",
"exifr": "^7.1.3",
"flowbite": "^2.5.2",
"leaflet": "^1.9.4",
"rxjs": "~7.8.0",

@ -16,6 +16,7 @@ import {
import { AutocompleteService } from '../../services/auto-complete.service';
import { PinService } from '../../services/pin.service';
import { DragDropComponent } from '../drag-drop/drag-drop.component';
import { ExifService } from '../../exif.service';
@Component({
selector: 'app-add-pin-popup',
@ -34,7 +35,8 @@ export class AddPinPopupComponent implements OnInit {
constructor(
private fb: FormBuilder,
private autocompleteService: AutocompleteService,
private pinService: PinService
private pinService: PinService,
private exifService: ExifService
) {
this.form = this.fb.group({
title: new FormControl(''),
@ -85,8 +87,24 @@ export class AddPinPopupComponent implements OnInit {
this.suggestions = [];
}
onFilesReceived(files: FileList): void {
async onFilesReceived(files: FileList): Promise<void> {
this.files = Array.from(files);
for (let i = 0; i < this.files.length; i++) {
try {
const data = await this.exifService.getLocation(this.files[i]);
if (data.latitude !== undefined && data.longitude !== undefined) {
const address = await this.autocompleteService.getAddressFromCoordinates(data.latitude, data.longitude).toPromise();
if (address) {
console.error("Data : " + JSON.stringify(address));
this.form.get('location')?.setValue(address.display_name);
break;
}
}
} catch (error) {
console.error("Error : " + error);
}
}
}
submitForm(): void {

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { ExifService } from './exif.service';
describe('ExifService', () => {
let service: ExifService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ExifService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

@ -0,0 +1,87 @@
import { Injectable } from '@angular/core';
import exifr from 'exifr';
@Injectable({
providedIn: 'root'
})
export class ExifService {
private getExifData(file: File): Promise<any> {
// console.log('getExifData(file)');
// return new Promise((resolve, reject) => {
// console.log('getExifData(file) -> Promise');
// const reader = new FileReader();
// console.log('getExifData(file) -> Promise -> reader');
// reader.onload = (event: any) => {
// console.log('getExifData(file) -> Promise -> reader -> onload');
// EXIF.getData(event.target.result, function() {
// console.log('getExifData(file) -> Promise -> reader -> onload -> EXIF.getData');
// const allExifData = EXIF.getAllTags(this);
// console.log('getExifData(file) -> Promise -> reader -> onload -> EXIF.getData -> getAllTags');
// resolve(allExifData);
// });
// };
// reader.onerror = (error) => reject(error);
// reader.readAsArrayBuffer(file);
// });
return exifr.parse(file);
}
async getAllExifData(file: File): Promise<any> {
try {
return await this.getExifData(file);
} catch (error) {
console.error('Error reading EXIF data:', error);
return
}
}
async getOrientation(file: File): Promise<number | undefined> {
try {
const exifData = await this.getExifData(file);
return exifData.Orientation;
} catch (error) {
console.error('Error reading EXIF data:', error);
return undefined;
}
}
async getDeviceModel(file: File): Promise<string | undefined> {
try {
const exifData = await this.getExifData(file);
return exifData.Model;
} catch (error) {
console.error('Error reading EXIF data:', error);
return undefined;
}
}
async getLocation(file: File): Promise<{ latitude?: number; longitude?: number }> {
try {
const exifData = await this.getExifData(file);
return {
latitude: exifData.GPSLatitude ? this.convertToDecimal(exifData.GPSLatitude, exifData.GPSLatitudeRef) : undefined,
longitude: exifData.GPSLongitude ? this.convertToDecimal(exifData.GPSLongitude, exifData.GPSLongitudeRef) : undefined
};
} catch (error) {
console.error('Error reading EXIF data:', error);
return {};
}
}
async getDateTime(file: File): Promise<string | boolean> {
try {
const exifData = await this.getExifData(file);
return exifData.DateTime;
} catch (error) {
console.error('Error reading EXIF data:', error);
return false;
}
}
private convertToDecimal(coordinate: number[], direction: string): number {
if (!coordinate || coordinate.length !== 3) return NaN;
const decimal = coordinate[0] + coordinate[1] / 60 + coordinate[2] / 3600;
return (direction === 'S' || direction === 'W') ? -decimal : decimal;
}
}

@ -31,4 +31,16 @@ export class AutocompleteService {
},
});
}
getAddressFromCoordinates(lat: number, lon: number): Observable<any> {
return this.http.get(this.apiUrl + '/reverse', {
params: {
lat: lat.toString(),
lon: lon.toString(),
format: 'json',
addressdetails: '1',
},
});
}
}

Loading…
Cancel
Save