web-dev-qa-db-fra.com

Comment économiser des coordonnées GPS dans les données EXIF ​​sur Android?

J'écris des coordonnées GPS sur mon image JPEG et les coordonnées sont correctes (comme illustrée par ma sortie LOGCAT), mais il semble qu'il est corrompu d'une manière ou d'une autre. Lire les données EXIF ​​entraîne des valeurs NULL ou, dans le cas de mon GPS: 512.976698 degrees, 512.976698 degrees. Quelqu'un peut-il jeter un peu de lumière sur ce problème?

l'écrire:

        try {
            ExifInterface exif = new ExifInterface(filename);
            exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, latitude);
            exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, longitude);
            exif.saveAttributes();
            Log.e("LATITUDE: ", latitude);
            Log.e("LONGITUDE: ", longitude);


        } catch (IOException e) {
            e.printStackTrace();
        }

et le lire:

        try {
            ExifInterface exif = new ExifInterface("/sdcard/globetrotter/mytags/"+ TAGS[position]);
            Log.e("LATITUDE EXTRACTED", exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
            Log.e("LONGITUDE EXTRACTED", exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
        } catch (IOException e) {
            e.printStackTrace();
        }

Il va dans (par exemple) 37.715183, -117.260489 et sort 33619970/65540, 14811136/3368550, 33619970/65540, 14811136/3368550. Est-ce que je le fais mal?

ÉDITER:

Donc, le problème est que je ne le codule pas dans le format correctement défini, qui est quelque chose comme vous voyez ici:

enter image description here

Quelqu'un peut-il expliquer ce que ce format est? Évidemment, le premier nombre est de 22/1 = 22 degrés, mais je ne peux pas comprendre comment calculer la décimale là-bas.

24
Brian D

Voici un code que j'ai fait pour geotag mes photos. Ce n'est pas encore fortement testé, mais il semble être correct (Editeur JOSM et Emplacement de lecture d'une lecture rapide).

ExifInterface exif = new ExifInterface(filePath.getAbsolutePath());
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, GPS.convert(latitude));
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, GPS.latitudeRef(latitude));
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, GPS.convert(longitude));
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, GPS.longitudeRef(longitude));
exif.saveAttributes();

Et le GPS de classe est ici. (La méthode pourrait être plus courte, mais elle est lisible au moins)

/*
 * @author fabien
 */
public class GPS {
    private static StringBuilder sb = new StringBuilder(20);

    /**
     * returns ref for latitude which is S or N.
     * @param latitude
     * @return S or N
     */
    public static String latitudeRef(double latitude) {
        return latitude<0.0d?"S":"N";
    }

    /**
     * returns ref for latitude which is S or N.
     * @param latitude
     * @return S or N
     */
    public static String longitudeRef(double longitude) {
        return longitude<0.0d?"W":"E";
    }

    /**
     * convert latitude into DMS (degree minute second) format. For instance<br/>
     * -79.948862 becomes<br/>
     *  79/1,56/1,55903/1000<br/>
     * It works for latitude and longitude<br/>
     * @param latitude could be longitude.
     * @return
     */
    synchronized public static final String convert(double latitude) {
        latitude=Math.abs(latitude);
        int degree = (int) latitude;
        latitude *= 60;
        latitude -= (degree * 60.0d);
        int minute = (int) latitude;
        latitude *= 60;
        latitude -= (minute * 60.0d);
        int second = (int) (latitude*1000.0d);

        sb.setLength(0);
        sb.append(degree);
        sb.append("/1,");
        sb.append(minute);
        sb.append("/1,");
        sb.append(second);
        sb.append("/1000");
        return sb.toString();
    }
}
13
Fabyen

Autres réponses livraison Belle informations de fond et même un exemple. Ce n'est pas une réponse directe à la question mais j'aimerais ajouter un exemple encore plus simple sans avoir besoin de faire des mathématiques. La classe emplacement offre une fonction Nice Convert :

public String getLonGeoCoordinates(Location location) {

    if (location == null) return "0/1,0/1,0/1000";
    // You can adapt this to latitude very easily by passing location.getLatitude()
    String[] degMinSec = Location.convert(location.getLongitude(), Location.FORMAT_SECONDS).split(":");
    return degMinSec[0] + "/1," + degMinSec[1] + "/1," + degMinSec[2] + "/1000";
}

J'ai enregistré la valeur de retour dans mon image et la balise est bien analysée. Vous pouvez vérifier votre image et les géocœuds à l'intérieur ici: http://regex.info/exif.cgi

Éditer

@Ratanas Commentaire Traduit au code:

public boolean storeGeoCoordsToImage(File imagePath, Location location) {

    // Avoid NullPointer
    if (imagePath == null || location == null) return false;

    // If we use Location.convert(), we do not have to worry about absolute values.

    try {
        // c&p and adapted from @Fabyen (sorry for being lazy)
        ExifInterface exif = new ExifInterface(imagePath.getAbsolutePath());
        exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, getLatGeoCoordinates(location));
        exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, location.getLatitude() < 0 ? "S" : "N");
        exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, getLonGeoCoordinates(location));
        exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, location.getLongitude() < 0 ? "W" : "E");
        exif.saveAttributes();
    } catch (IOException e) {
        // do something
        return false;
    }

    // Data was likely written. For sure no NullPointer. 
    return true;
}

Voici un bon convertisseur LATLONG: LatLong.net

4
aProgger
ExifInterface exif = new ExifInterface(compressedImage.getPath());
        exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE,gpsTracker.dec2DMS(gpsTracker.getLatitude()));
        exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE,gpsTracker.dec2DMS(gpsTracker.getLongitude()));

Convertisseur double en chaîne

 String dec2DMS(double coord) {
    coord = coord > 0 ? coord : -coord;  
    String sOut = Integer.toString((int)coord) + "/1,";   
    coord = (coord % 1) * 60;         
    sOut = sOut + Integer.toString((int)coord) + "/1,";   
    coord = (coord % 1) * 60000;             
    sOut = sOut + Integer.toString((int)coord) + "/1000";   
    return sOut;
}
0
Ibrahim Sušić