Autore Topic: Georeferenziare una immagine jpg  (Letto 1814 volte)

Offline systemgvp

  • Nuovo arrivato
  • *
  • Post: 49
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Ideos
  • Play Store ID:
    systemgvp
  • Sistema operativo:
    Windows 7
Georeferenziare una immagine jpg
« il: 12 Febbraio 2012, 11:28:57 CET »
0
Salve,

ho la necessità di georeferenziare un'immagine JPG appena scattata dalla camera. Per scattare la foto e salvarla uso questo codice:

Codice (Java): [Seleziona]
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.provider.MediaStore;
import android.net.Uri;
import android.content.*;
import android.os.Environment;
import java.io.*;
import android.widget.TextView;

public class TestCamera2 extends Activity {
       
        //informazioni sullo scatto
        private static final int TAKE_PHOTO_CODE = 1;
        //contenitore finale
        ImageView FotoCatturata;  
       
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //imposta il contenitore di destinazione
        FotoCatturata = (ImageView)findViewById(R.id.FotoCatturataIMG);
       
    }
   
    public void CatturaFotoOnClick(View button)
    {
        //avvia la camera
        final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(SalvaImmagineScattata(this)) );  
        //imposta il ritorno dei dati
        startActivityForResult(intent, TAKE_PHOTO_CODE);
    }
   
    private File SalvaImmagineScattata(Context context)
    {  
        //crea una cartella in sdcard/ col nome del pacchetto
        final File path = new File( Environment.getExternalStorageDirectory(), context.getPackageName() );  
        if(!path.exists())
        {  
                path.mkdir();  
        }  
        return new File(path, "foto.jpg");  
    }  
         
    @Override  
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {  
        if (resultCode == RESULT_OK)
        {  
                switch(requestCode)
                {  
                case TAKE_PHOTO_CODE:  
                final File file = SalvaImmagineScattata(this);  
                try
                {  
                        //mostra il percorso dell'immagine
                        TextView percorso = (TextView) findViewById(R.id.percorso_TXT);
                                percorso.setText(Uri.fromFile(file).toString());
                        //carica l'immagine
                        Bitmap captureBmp = MediaStore.Images.Media.getBitmap(getContentResolver(), Uri.fromFile(file) );  
                        //mostra l'immagine nell'oggetto  
                        FotoCatturata.setImageBitmap(captureBmp);  
                }
                catch (FileNotFoundException e) { e.printStackTrace(); }
                catch (IOException e) { e.printStackTrace(); }  
              break;  
            }  
        }
       
    }
   
}

ora, supponendo di avare le coordinate latitudine e longitudine di un punto in due variabili ad esempio di tipo string, come georeferenzio la foto? magari direttamente al moemnto in cui la salvo?

Offline Reinhard

  • Utente junior
  • **
  • Post: 85
  • Respect: +16
    • Google+
    • rspisser
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5 Lollipop 5.1
  • Play Store ID:
    rspisser
  • Sistema operativo:
    Windows 7
Re:Georeferenziare una immagine jpg
« Risposta #1 il: 12 Febbraio 2012, 12:16:03 CET »
+1
Ciao,

puoi scrivere le coordinate come tag exif nel immagine. Questo link http://stackoverflow.com/questions/5280479/how-to-save-gps-coordinates-in-exif-data-on-android potrebbe essere utile

Offline systemgvp

  • Nuovo arrivato
  • *
  • Post: 49
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Ideos
  • Play Store ID:
    systemgvp
  • Sistema operativo:
    Windows 7
Re:Georeferenziare una immagine jpg
« Risposta #2 il: 12 Febbraio 2012, 14:17:30 CET »
0
da quell'esempio ho aggiunto questa parte:

Codice (Java): [Seleziona]
//mostra il percorso dell'immagine
                        TextView percorso = (TextView) findViewById(R.id.percorso_TXT);
                                percorso.setText(Uri.fromFile(file).toString());
                                //aggiunge le coordinate
                                try
                                {
                                        //recupera il file
                                        String filename = Uri.fromFile(file).toString();
                            ExifInterface exif = new ExifInterface(filename);
                            //richiama i dati nel formato : dd/1,mm/1,ss/1 : dove 1 indica i decimali
                            String latitudine           = "22/1,21/1,299295/32768";
                            String latitudine_rif       = "N";
                            String longitudine          = "114/1,3/1,207045/4096";
                            String longitudine_rif      = "E";
                           
                            //imposta gli attributi
                            exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, latitudine);
                            exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, latitudine_rif);
                            exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, longitudine);
                            exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, longitudine_rif);
                            //salva gli attributi
                            exif.saveAttributes();               
                        }
                                catch (IOException e) { e.printStackTrace(); }
                        //carica l'immagine
                        Bitmap captureBmp = MediaStore.Images.Media.getBitmap(getContentResolver(), Uri.fromFile(file) );  
                        //mostra l'immagine nell'oggetto  
                        FotoCatturata.setImageBitmap(captureBmp);

il problema ora è che al massimo io ho le coordinate in  DD/MM/SSS.SSS quindi so recuperare la stringa del gradi e dei minuti, ma non quella dei secondi, perchè non capisco come la compone. c'è qualche modo per ottenere direttamente la stringa in quel formato?

Offline systemgvp

  • Nuovo arrivato
  • *
  • Post: 49
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Ideos
  • Play Store ID:
    systemgvp
  • Sistema operativo:
    Windows 7
Re:Georeferenziare una immagine jpg
« Risposta #3 il: 12 Febbraio 2012, 14:21:24 CET »
0
so che il procedimento è questo:

Latitude (TAG_GPS_LATITUDE)
= 22/1,16/1,5935883/125557
= 22/1 + 16/(1*60) + 5935883/(125557*3600)
= 22 + 0.266666666667 + 0.0131323334333
= 22.2797990001
if TAG_GPS_LATITUDE_REF == "N", it's positive; otherwise it's negative.

ma non so da dove sbuca il 5935883/125557 ?

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Georeferenziare una immagine jpg
« Risposta #4 il: 12 Febbraio 2012, 15:19:40 CET »
0
La documentazione sul valore di ritorno:

ExifInterface | Android Developers

sono 3 numeri razionali (rapporto tra due interi), rappresentano rispettivamente "gradi, primi, secondi", il valore di primi e secondi sono in sessagesimali (modulo 60).

In pratica se restituisce la stringa "num1/denom1,num2/denom2,num3/denom3" devi fare questo calcolo in floating point:

Codice: [Seleziona]
num1/denom1 + num2/(denom2 * 60) + num3/(denom3 * 3600)
dove 3600 = 60*60. Dipende poi dal riferimento se il risultato finale è positivo o negativo.
adb logcat | tee /tmp/logcat | grep TAG

Offline systemgvp

  • Nuovo arrivato
  • *
  • Post: 49
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Ideos
  • Play Store ID:
    systemgvp
  • Sistema operativo:
    Windows 7
Re:Georeferenziare una immagine jpg
« Risposta #5 il: 12 Febbraio 2012, 23:03:59 CET »
0
si questo lo sapevo, il problema era capire come impostare denom3, ma ho risolto con:

Codice (Java): [Seleziona]
String longitudine = "38:34:46.414524";
                            String latitudine  = "15:56:36.294936";                        
                            //converte la coordinata nel formato exif : dd/1,mm/1,ss/1 : dove 1 indica i decimali
                            String[] location_lon = longitudine.split(":",3); // 0 : gradi, 1 : minuti, 2 : secondi
                            location_lon[2] = Integer.toString((int)(Double.parseDouble(location_lon[2])*10000000));
                            String longitudine_cod = String.format("%s/1,%s/1,%s/10000000", location_lon[0], location_lon[1], location_lon[2]);                            
                            String[] location_lat = latitudine.split(":",3); // 0 : gradi, 1 : minuti, 2 : secondi
                            location_lat[2] = Integer.toString((int)(Double.parseDouble(location_lat[2])*10000000));
                            String latitudine_cod = String.format("%s/1,%s/1,%s/10000000", location_lat[0], location_lat[1], location_lat[2]);
                            String latitudine_rif       = "N";
                            String longitudine_rif      = "E";

il problema ora è che mi dice che l'operazione è andata a buon fine, ma se poi vado a controllare il file, anche riavviando il cell o copiandolo sul pc, mi da come lat e long 0,0 o mi dice che non sono presenti i tag per la georeferenziazione.

Offline systemgvp

  • Nuovo arrivato
  • *
  • Post: 49
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Ideos
  • Play Store ID:
    systemgvp
  • Sistema operativo:
    Windows 7
Re:Georeferenziare una immagine jpg
« Risposta #6 il: 12 Febbraio 2012, 23:28:57 CET »
0
ho risolto, bisognava solo cambiare la stringa di destinazione con:

//recupera il file
ExifInterface exif = new ExifInterface(file.toString());

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Georeferenziare una immagine jpg
« Risposta #7 il: 14 Febbraio 2012, 20:56:00 CET »
0
Ho capito, vuoi fare la conversione inversa. Quei due numeri "5935883/125557" è una delle tante approssimazioni di un numero reale "47.27640035999585845472..." in un razionale.

Questo semplice codice converte un double in un array di 2 interi che rappresentano il numeratore e denominatore con un errore massimo EPSILON:

Codice (Java): [Seleziona]
static int[] doubleToRational(final double value) {

            final int MAXLOOP = 200;
            final double EPSILON = 1.E-10;
       
            final int rational[] = new int[2];

            double r0 = value;
            int a0 = (int) Math.floor(r0);

            if (Math.abs(a0 - value) < EPSILON) {

                rational[0] = a0;
                rational[1] = 1;

                return rational;
            }

            int p0 = 1;
            int q0 = 0;
            int p1 = a0;
            int q1 = 1;

            int p2 = 0;
            int q2 = 1;

            for (int n = 0; n < MAXLOOP; ++n) {
           
                double r1 = 1.0 / (r0 - a0);
                int a1 = (int) Math.floor(r1);
                p2 = (a1 * p1) + p0;
                q2 = (a1 * q1) + q0;

                double convergent = (double) p2 / (double) q2;

                if (Math.abs(convergent - value) < EPSILON)  {
                    break;
                }

                p0 = p1;
                p1 = p2;
                q0 = q1;
                q1 = q2;
                a0 = a1;
                r0 = r1;
            }
               
            rational[0] = p2;
            rational[1] = q2;

            return rational;
        }
adb logcat | tee /tmp/logcat | grep TAG