Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

macOS Sierra, visualiser la direction d'une photo sur une carte ?

54 réponses
Avatar
Une Bévue
avec l'iPhone 6, les données GPS incluent la direction de prise de vue
(compas), existe t'il un logiciel permettant de montrer cette direction
(et donc pas seulement le point d'où a été prsie la photo) ?

exemple :
$ exiftool '/Users/yt/Downloads/IMG_3130.JPG'
ExifTool Version Number : 10.20

[...]

Make : Apple
Camera Model Name : iPhone 6

[...]

GPS Latitude Ref : North
GPS Longitude Ref : West
GPS Altitude Ref : Above Sea Level
GPS Time Stamp : 07:11:21
GPS Speed Ref : km/h
GPS Speed : 0
GPS Img Direction Ref : True North
GPS Img Direction : 312.9102564
GPS Dest Bearing Ref : True North
GPS Dest Bearing : 312.9102564
GPS Date Stamp : 2016:12:06
GPS Horizontal Positioning Error: 65 m

[...]

GPS Altitude : 26.6 m Above Sea Level
GPS Date/Time : 2016:12:06 07:11:21Z
GPS Latitude : 55 deg 55' 15.39" N
GPS Longitude : 4 deg 28' 44.01" W
GPS Position : 55 deg 55' 15.39" N, 4 deg 28' 44.01" W

[...]

4 réponses

2 3 4 5 6
Avatar
freedom
Une Bévue wrote:
Le 28/12/2016 à 06:50, Une Bévue a écrit : > avec l'iPhone 6, les données
GPS incluent la direction de prise de vue > (compas), existe t'il un
logiciel permettant de montrer cette direction > (et donc pas seulement le
point d'où a été prsie la photo) ?
ça roule avec OpenLayers3, fastoche à implémenter, résutat :
<http://www.cjoint.com/doc/17_01/GAcoVFoizkg_17-01-02-15-46-14-OpenLayers3
-direction-on-mbp.png>
--------------------------------------------------------------------------
------ iconStyle = new ol.style.Style({ image: new ol.style.Icon(({
rotateWithView: true, rotation: deg2rad(center.direction), anchor: [0.5,
22], anchorXUnits: 'fraction', anchorYUnits: 'pixels', size: [27, 27],
opacity: 0.75, src: '/OpenLayers3/icons/direction_27x27.png' })) });
--------------------------------------------------------------------------
------ center.direction est en degrés (ici environ 312 / Nord) qu'il faut
convertir en radians...

C'est génial, ce truc, bien que je ne comprenne pas du tout comment tu
arrives au beau résultat de droite, j'aimerais pouvoir sortir ça dans
Photos !!! et secondairement aller petitdéjeuner à Glasgow ;-)
Avatar
Une Bévue
Le 02/01/2017 à 22:00, Boudu a écrit :
C'est génial, ce truc, bien que je ne comprenne pas du tout comment tu
arrives au beau résultat de droite, j'aimerais pouvoir sortir ça dans
Photos !!! et secondairement aller petitdéjeuner à Glasgow ;-)

Pour le déjeuner à Glasgow, c'est pas difficile, il suffit de travailler
pour une boite qui t'envoie là-bas.
En fait c'est un "private joke" de mon jeune fils chez qui j'avais mangé
du "Miam Ô fruit" au petit dej'.
Il faut un script php "read-exif.php" pour récupérer les données exif
d'une photo :
--------------------------------------------------------------------------------
<?php
date_default_timezone_set('Europe/Paris');
setlocale(LC_CTYPE, 'fr_FR');
//header('Content-Type: text/html;charset=utf-8');
header('Content-Type: application/json');
//error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
error_reporting(E_ALL);
$LONG_INFOS = array();
$LONG_INFOS['File'] = explode(' ', 'FileName Directory FileSize
ImageWidth ImageHeight');
$LONG_INFOS['XMP'] = explode(' ', 'Lens');
$LONG_INFOS['EXIF'] = explode(' ', 'Make Model Orientation
XResolution YResolution ExposureTime FNumber ISO CreateDate FocalLength
UserComment ExposureMode WhiteBalance GPSVersionID GPSLatitudeRef
GPSLatitude GPSLongitudeRef GPSLongitude GPSAltitudeRef GPSAltitude
GPSImgDirectionRef GPSImgDirection GPSDestBearingRef GPSDestBearing
GPSDateStamp');
$LONG_INFOS['MakerNotes'] = explode(' ', 'ImageBoundary Timezone
DaylightSavings LensType Lens FlashMode ShootingMode');
$exif = array();
$options = '-s -c "%.8f" ';
foreach($LONG_INFOS as $key => $fields) {
foreach($fields as $field) {
$options .= "-$key:$field ";
}
}
$exif['options'] = $options;
$EXIFTOOL = '/usr/local/bin/exiftool';
$file = '/Users/yt/Sites/Photo_compass/photos/IMG_3130.JPG';
$exif['output_exec'] = array();
$exif['exitstatus'] = '';
exec("$EXIFTOOL $options $file", $exif['output_exec'],
$exif['exitstatus']);
$exif['output'] = array();
foreach($exif['output_exec'] as $line) {
$fields = explode(':', $line, 2);
$exif['output'][trim($fields[0])] = trim($fields[1]);
}
unset($exif['output_exec']);
echo json_encode($exif);
?>
--------------------------------------------------------------------------------
une page "index.html" de contenu :
--------------------------------------------------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<!--
http://on-air.hiseo.fr/html5/encodage-caracteres-declaration-html5/ -->
<meta charset="UTF-8" />
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>Photo - OL3</title>
<link rel="stylesheet"
href="https://openlayers.org/en/v3.20.1/css/ol.css" type="text/css">
<link href="css/styles.css" rel="stylesheet" type="text/css"
charset="utf-8" />
<script src="https://openlayers.org/en/v3.20.1/build/ol.js"
charset="UTF-8"></script>
<script src="js/xhr.js"></script>
<!-- script src="js/GeoMapService.js"></script -->
<script src="js/openlayers3.js"></script>
<script src="js/controller.js"></script>
</head>
<body>
<pre id="exif"></pre>
<div id="map" class="map"></div>
</body>
</html>
--------------------------------------------------------------------------------
un fichier "styles.css" :
--------------------------------------------------------------------------------
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
display: grid;
grid-template-columns: 50% 50%;
background: transparent
url(http://mbp.local/global/backgrounds/flocon-russe-tique.png)
no-repeat center center fixed;
background-size: cover;
}
pre {
grid-column: 1;
color: rgba(227, 227, 227, 0.75);
background-color: rgba(27, 27, 27, 0.75);
background-image:
url(http://mbp.local/OpenLayers3/photos/IMG_3130.JPG);
background-position: center center;
padding: 16px;
background-repeat: no-repeat;
background-size: cover;
}
.map {
grid-column: 2;
background-color: aquamarine;
height: 500px;
width: 100%;
}
--------------------------------------------------------------------------------
où il y a un lien "en dur" "http://mbp.local/global/backgrounds" soit
avoir autre chose à lui substituer soit supprimer la ligne "background:
url(...
un premier fichier JavaScript pour appeller le fichier php + hat "xhr.js" :
--------------------------------------------------------------------------------
'use strict';
var XHRService;
XHRService = function () {
var errorCallback, init, service, successCallback, url;
service = {};
url = void 0;
successCallback = void 0;
errorCallback = void 0;
init = function (_url, _successCallback, _errorCallback) {
var xhr;
service = {};
url = _url;
successCallback = _successCallback;
errorCallback = _errorCallback;
xhr = new XMLHttpRequest ();
xhr.open('get', url, true);
xhr.responseType = 'json';
xhr.onload = function () {
var status;
status = xhr.status;
if (status === 200) {
successCallback && successCallback(xhr.response);
} else {
errorCallback && errorCallback(status);
}
};
xhr.send();
};
service.init = init;
return service;
};
--------------------------------------------------------------------------------
lequel envoie le résultat sur une fonction "_successCallback" en cas de
succès ou "_errorCallback" en cas d'erreur, si ces fonctions sont
implémentées.
un second JavaScript "openlayers3.js" qui gère disons l'instanciation
d'une carte OpenLayers3 avec comme pinmark une image orientée :
--------------------------------------------------------------------------------
'use strict';
var OpenLayers3Service;
OpenLayers3Service = function(_map_id, _center, _zoom, _vectorLayer) {
var service = {};
var map_id = _map_id;
var center = _center;
var zoom = _zoom;
var vectorLayer = _vectorLayer;
var map;
var init = function() {
map = new ol.Map({
target: map_id,
layers: [new ol.layer.Tile({ source: new ol.source.OSM() }),
vectorLayer],
view: new ol.View({
center: ol.proj.fromLonLat([center.location.lng,
center.location.lat]),
zoom: zoom
})
});
}
service.init = init;
service.map = map;
return service;
}
--------------------------------------------------------------------------------
et enfin le dernier JS "controller.js" qui ordonne tout le toutim :
--------------------------------------------------------------------------------
'use strict';
var xhr, exifElt, ol3s, center, zoom;
function hash2txt(hash) {
var txt = '';
for (var field in hash) {
if (hash.hasOwnProperty(field)) {
if (typeof hash[field] == 'object') {
txt += field + ':n' + JSON.stringify(hash[field],
null, 2) + "n";
} else {
txt += field + ': ' + hash[field] + "n";
}
}
}
return txt;
}
function deg2rad(deg) {
if (deg < 0) {
deg += 360;
}
if (deg > 360) {
deg -= 360;
}
return 2.0 * Math.PI * deg / 360.0;
}
function readExifSuccessCallback(exif) {
var field, txt, iconFeature, vectorSource, iconStyle, vectorLayer;
center = {};
center.location = {};
center.direction = 0;
txt = '';
if (exif.exitstatus === 0) {
txt = 'output:n';
txt += hash2txt(exif.output);
txt += 'ncenter:n';
center.location.lat =
parseFloat(exif.output.GPSLatitude.replace(/^"(.*)"$/, '$1'));
if (exif.output.GPSLatitudeRef === 'South' &&
center.location.lat > 0) {
center.location.lat = -center.location.lat;
}
center.location.lng =
parseFloat(exif.output.GPSLongitude.replace(/^"(.*)"$/, '$1'));
if (exif.output.GPSLongitudeRef === 'West' &&
center.location.lng > 0) {
center.location.lng = -center.location.lng;
}
center.direction = parseFloat(exif.output.GPSImgDirection);
txt += hash2txt(center);
//txt += 'ndirection: ' + + 'n';
}
// stackoverflow :: how to add markers with OpenLayers 3
//
http://stackoverflow.com/questions/24315801/how-to-add-markers-with-openlayers-3
// http://jsfiddle.net/6RS2z/356/
vectorSource = new ol.source.Vector({
//create empty vector
});
iconFeature = new ol.Feature({
geometry: new
ol.geom.Point(ol.proj.transform([center.location.lng,
center.location.lat], 'EPSG:4326', 'EPSG:3857')),
name: 'Null Island ' + 0,
population: 4000,
rainfall: 500
});
vectorSource.addFeature(iconFeature);
// The Book of OpenLayers3 [Code samples]
// Icon styling
//
http://www.acuriousanimal.com/thebookofopenlayers3/chapter04_05_icons.html
iconStyle = new ol.style.Style({
image: new ol.style.Icon(({
rotateWithView: true,
rotation: deg2rad(center.direction),
anchor: [0.5, 22],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
size: [27, 27],
opacity: 0.75,
src: '/OpenLayers3/icons/direction_27x27.png'
}))
});
vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: iconStyle
});
//function(_map_id, _center, _zoom, _vectorLayer)
ol3s = new OpenLayers3Service('map', center, zoom, vectorLayer);
ol3s.init();
exifElt.innerHTML = txt;
exifElt.backgroundImage =
'url(http://mbp.local/OpenLayers3/photos/IMG_3130.JPG)';
}
function readExifErrorCallback(error) {
console.info("readExifErrorCallback(error)");
}
function successBackgroundCallback(data) {
if (!!data) {
document.body.style.background = data.background;
document.body.style.backgroundSize = data.backgroundSize;
}
}
function errorBackgroundCallback(data) {
console.info("errorBackgroundCallback(data) data:n" +
JSON.stringify(data, null, 2) + "n");
}
function getBackgroundImage() {
xhr.init("http://mbp.local/php/background-json.php",
successBackgroundCallback, errorBackgroundCallback);
}
function start() {
xhr = new XHRService ();
setInterval(getBackgroundImage, 30 * 1000);
xhr.init("http://mbp.local/php/read-exif.php",
readExifSuccessCallback, readExifErrorCallback);
exifElt = document.getElementById ('exif');
center = {};
center.location = {};
center.location.lng = 37.41;
center.location.lat = 8.82;
zoom = 15;
}
window.addEventListener('DOMContentLoaded', start, false);
--------------------------------------------------------------------------------
là, l'image "/OpenLayers3/icons/direction_27x27.png" est l'appareil
photo avec un point rouge qui me sert de pinmark sur la carte.
Il est orienté par la ligne :
rotation: deg2rad(center.direction),
la function deg2rad est immédiatement compréhensible,
et "center.direction" lui-même obtenu par :
center.direction = parseFloat(exif.output.GPSImgDirection);
"GPSImgDirection" étant une propriété retournée par le script php vu
plus haut.
ATTENTION ceci n'est qu'un simple test qui m'a permis juste de vérifier
que je parviens à orienter la petite icône "pinmark" en fonction de la
direction de la prise de vue.
bien sûr il ne faudrait pas coder en dur le PATH de cette photo, et
aussi vérifier que la propriété "GPSImgDirection" est bien présente.
Avatar
freedom
Une Bévue wrote:
Le 02/01/2017 à 22:00, Boudu a écrit : > C'est génial, ce truc, bien que
je ne comprenne pas du tout comment tu > arrives au beau résultat de
droite, j'aimerais pouvoir sortir ça dans > Photos !!! et secondairement
aller petitdéjeuner à Glasgow ;-)
Pour le déjeuner à Glasgow, c'est pas difficile, il suffit de travailler
pour une boite qui t'envoie là-bas. En fait c'est un "private joke" de mon
jeune fils chez qui j'avais mangé du "Miam Ô fruit" au petit dej'.

..........
ATTENTION ceci n'est qu'un simple test qui m'a permis juste de vérifier
que je parviens à orienter la petite icône "pinmark" en fonction de la
direction de la prise de vue.
bien sûr il ne faudrait pas coder en dur le PATH de cette photo, et aussi
vérifier que la propriété "GPSImgDirection" est bien présente.

J'en ai pour un bon bout de temps à comprendre tout ça, ne faisant pas
partie des geeks qui ont participé à ce fil; mais le résultat est si
intéressant que je vais essayer de me lancer, avec l'aide d'un ou deux
copains. En tout cas merci beaucoup pour le détail de l'opération. PM
Avatar
Une Bévue
Le 04/01/2017 à 12:25, Boudu a écrit :
J'en ai pour un bon bout de temps à comprendre tout ça, ne faisant pas
partie des geeks qui ont participé à ce fil; mais le résultat est si
intéressant que je vais essayer de me lancer, avec l'aide d'un ou deux
copains. En tout cas merci beaucoup pour le détail de l'opération. PM

De rien.
2 3 4 5 6