/* @file CalibCoeffDialog.java
*
* @author marco corvi
* @date nov 2011
*
* @brief TopoDroid DistoX calibration coefficients display dialog
* --------------------------------------------------------
* Copyright This sowftare is distributed under GPL-3.0 or later
* See the file COPYING.
* --------------------------------------------------------
*/
package com.topodroid.DistoX;
import java.util.Locale;
import android.app.Dialog;
import android.os.Bundle;
import android.content.Context;
import android.widget.TextView;
import android.widget.Button;
import android.widget.ImageView;
import android.view.View;
import android.view.View.OnClickListener;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.util.Log;
public class CalibCoeffDialog extends MyDialog
implements View.OnClickListener
{
private TopoDroidApp mApp;
private static final int WIDTH = 200;
private static final int HEIGHT = 100;
private ImageView mImage; // error histogram
private Bitmap mBitmap = null;
private TextView mTextBG;
private TextView mTextAGx;
private TextView mTextAGy;
private TextView mTextAGz;
private TextView mTextBM;
private TextView mTextAMx;
private TextView mTextAMy;
private TextView mTextAMz;
private TextView mTextNL;
private TextView mTextDelta;
private TextView mTextDelta2;
private TextView mTextMaxError;
private TextView mTextIter;
private Button mButtonWrite;
// private Button mButtonBack;
private String bg0;
private String agx;
private String agy;
private String agz;
private String bm0;
private String amx;
private String amy;
private String amz;
private String nlx;
private String delta0;
private String delta02;
private String error0;
private String iter0;
private byte[] mCoeff;
public CalibCoeffDialog( Context context, TopoDroidApp app,
Vector bg, Matrix ag, Vector bm, Matrix am, Vector nl, float[] errors,
float delta, float delta2, float error, long iter, byte[] coeff )
{
super( context, R.string.CalibCoeffDialog );
mApp = app;
mCoeff = coeff;
bg0 = String.format(Locale.US, "bG %8.4f %8.4f %8.4f", bg.x, bg.y, bg.z );
agx = String.format(Locale.US, "aGx %8.4f %8.4f %8.4f", ag.x.x, ag.x.y, ag.x.z );
agy = String.format(Locale.US, "aGy %8.4f %8.4f %8.4f", ag.y.x, ag.y.y, ag.y.z );
agz = String.format(Locale.US, "aGz %8.4f %8.4f %8.4f", ag.z.x, ag.z.y, ag.z.z );
bm0 = String.format(Locale.US, "bM %8.4f %8.4f %8.4f", bm.x, bm.y, bm.z );
amx = String.format(Locale.US, "aMx %8.4f %8.4f %8.4f", am.x.x, am.x.y, am.x.z );
amy = String.format(Locale.US, "aMy %8.4f %8.4f %8.4f", am.y.x, am.y.y, am.y.z );
amz = String.format(Locale.US, "aMz %8.4f %8.4f %8.4f", am.z.x, am.z.y, am.z.z );
if ( nl != null ) {
nlx = String.format(Locale.US, "nL %8.4f %8.4f %8.4f", nl.x, nl.y, nl.z );
} else {
nlx = new String("");
}
delta0 = String.format( mContext.getResources().getString( R.string.calib_error ), delta );
delta02 = String.format( mContext.getResources().getString( R.string.calib_stddev ), delta2 );
error0 = String.format( mContext.getResources().getString( R.string.calib_max_error ), error );
iter0 = String.format( mContext.getResources().getString( R.string.calib_iter ), iter );
if ( errors != null ) {
mBitmap = makeHistogramBitmap( errors, WIDTH, HEIGHT, 20, 5, 0xff6699ff );
}
}
static Bitmap makeHistogramBitmap( float[] error, int width, int height, int bin, int step, int col )
{
Bitmap bitmap = Bitmap.createBitmap( width+20, height+20, Bitmap.Config.ARGB_8888 );
int ww = bitmap.getWidth();
int hh = bitmap.getHeight();
for ( int j=0; j<hh; ++j ) {
for ( int i=0; i<ww; ++i ) bitmap.setPixel( i, j, 0 );
}
int[] hist = new int[bin];
for ( int k=0; k<bin; ++k ) hist[k] = 0;
if ( error != null ) {
for ( int k=0; k < error.length; ++ k ) {
int i = (int)( error[k]*10*TDMath.RAD2GRAD );
if ( i < bin && i >= 0 ) ++ hist[i];
}
}
int red = 0xffffffff;
int top = red;
int joff = hh-10;
int ioff = 10;
int dx = (int)( ww / bin );
if ( dx*20 >= ww ) dx --;
int x, y;
for ( int k=0; k<bin; ++ k ) {
int h = step * hist[k];
if ( h > joff ) {
h = joff;
top = col;
} else {
top = red;
}
x = ioff + dx * k;
for ( y=joff-h; y <= joff; ++y ) bitmap.setPixel( x, y, red );
int x2 = x + dx-1;
for ( ++x; x < x2; ++ x ) {
y = joff-h;
bitmap.setPixel( x, y, red );
for ( ++y; y < joff; ++y ) bitmap.setPixel( x, y, col );
bitmap.setPixel( x, y, top );
}
for ( y=joff-h; y <= joff; ++y ) bitmap.setPixel( x, y, red );
}
for ( y = 0; y < hh; ++y ) bitmap.setPixel( ioff, y, red );
for ( x = 0; x < ww; ++x ) bitmap.setPixel( x, joff, red );
for ( int k = 5; k <= bin; k+=5 ) {
x = ioff + dx * k;
int yy = hh - ( ((k%10) == 0 )? 0 : 5 );
for ( y = joff; y < yy; ++y ) bitmap.setPixel( x, y, red );
}
if ( 5 <= bin ) {
x = ioff + dx * 5;
for ( y = 0; y < joff; ++y ) bitmap.setPixel( x, y, 0xffffff00 );
}
if ( 10 <= bin ) {
x = ioff + dx * 10;
for ( y = 0; y < joff; ++y ) bitmap.setPixel( x, y, 0xffff0000 );
}
for ( int k = 10; ; k += 10 ) {
y = joff - step * k;
if ( y < 0 ) break;
for ( x = 5; x < ioff; ++x ) bitmap.setPixel( x, y, red );
}
// Log.v("DistoX", "fill image done");
return bitmap;
}
// -------------------------------------------------------------------
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
initLayout( R.layout.calib_coeff_dialog, R.string.title_coeff );
mTextBG = (TextView) findViewById(R.id.coeff_bg);
mTextAGx = (TextView) findViewById(R.id.coeff_agx);
mTextAGy = (TextView) findViewById(R.id.coeff_agy);
mTextAGz = (TextView) findViewById(R.id.coeff_agz);
mTextBM = (TextView) findViewById(R.id.coeff_bm);
mTextAMx = (TextView) findViewById(R.id.coeff_amx);
mTextAMy = (TextView) findViewById(R.id.coeff_amy);
mTextAMz = (TextView) findViewById(R.id.coeff_amz);
mTextNL = (TextView) findViewById(R.id.coeff_nl);
mImage = (ImageView) findViewById( R.id.histogram );
mTextDelta = (TextView) findViewById(R.id.coeff_delta);
mTextDelta2 = (TextView) findViewById(R.id.coeff_delta2);
mTextMaxError = (TextView) findViewById(R.id.coeff_max_error);
mTextIter = (TextView) findViewById(R.id.coeff_iter);
mButtonWrite = (Button) findViewById( R.id.button_coeff_write );
mTextBG.setText( bg0 );
mTextAGx.setText( agx );
mTextAGy.setText( agy );
mTextAGz.setText( agz );
mTextBM.setText( bm0 );
mTextAMx.setText( amx );
mTextAMy.setText( amy );
mTextNL.setText( nlx );
mTextAMz.setText( amz );
if ( mBitmap != null ) {
mImage.setImageBitmap( mBitmap );
mTextDelta.setText( delta0 );
mTextDelta2.setText( delta02 );
mTextMaxError.setText( error0 );
mTextIter.setText( iter0 );
mButtonWrite.setOnClickListener( this );
mButtonWrite.setEnabled( mCoeff != null );
// mButtonBack = (Button) findViewById( R.id.button_coeff_back );
// mButtonBack.setOnClickListener( this );
} else {
mImage.setVisibility( View.GONE );
mTextDelta.setVisibility( View.GONE );
mTextDelta2.setVisibility( View.GONE );
mTextMaxError.setVisibility( View.GONE );
mTextIter.setVisibility( View.GONE );
mButtonWrite.setVisibility( View.GONE );
}
}
@Override
public void onClick(View v)
{
Button b = (Button)v;
if ( b == mButtonWrite ) {
mApp.uploadCalibCoeff( mContext, mCoeff, true );
} else {
dismiss();
}
}
}