title: IndoorAtlas Android SDK 1.4.2-132: getting the floorplan image/bitmap in fullscreen + with rotation
body: <p>So, apparently I am a newbie in Java, and the following is my story:
  I have been working with the IndoorAtlas (the company that provides Indoor Positioning Solution) Android SDK 1.4.2-132 and I am not getting the results I want when I test the application on my phone.
  Here is my full JAVA code which I mostly got from this link "<a href="https://stackoverflow.com/questions/29911753/show-floorplan-and-get-location-with-indooratlas/29926176#29926176">Show FloorPlan and get Location with IndoorAtlas</a>":</p>
  
  <pre><code>import android.app.Activity;
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import android.graphics.PointF;
  import android.os.Bundle;
  import android.util.Log;
  import android.widget.ImageView;
  
  import com.indooratlas.android.CalibrationState;
  import com.indooratlas.android.FloorPlan;
  import com.indooratlas.android.FutureResult;
  import com.indooratlas.android.ImagePoint;
  import com.indooratlas.android.IndoorAtlas;
  import com.indooratlas.android.IndoorAtlasException;
  import com.indooratlas.android.IndoorAtlasFactory;
  import com.indooratlas.android.ResultCallback;
  import com.indooratlas.android.ServiceState;
  import com.indooratlas.android.IndoorAtlasListener;
  
  import java.io.IOException;
  
  public class FloorPlanLoader extends Activity implements IndoorAtlasListener
  {
      private IndoorAtlas ia;
      private FloorPlan floorPlan; //here it says private field "floorplan" is never assigned.
      private FloorPlan mFloorPlan; // here it says private field "mFloorPlan" is assigned but never accessed.
      private ImageView imageView;
  
      String venueId = "xxx";
      String floorId = "xxx";
      String floorPlanId = "xxx";
      String apiKey = "xxx";
      String apiSecret = "xxx";
  
      @Override
      public void onCreate(Bundle savedInstanceState)
      {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.indoor_positioning);
          initIndoorAtlas();
      }
      public void initIndoorAtlas() //method to initialize indooratlas instance
      {
          try
          {
              ia = IndoorAtlasFactory.createIndoorAtlas(getApplicationContext(), this, apiKey, apiSecret);
          }
          catch (IndoorAtlasException ex)
          {
              Log.e("IndoorAtlas", "initialisation failed", ex);
              log();
          }
          FutureResult&lt;FloorPlan&gt; result = ia.fetchFloorPlan(floorPlanId); //obtains instance of floor plan
          result.setCallback(new ResultCallback&lt;FloorPlan&gt;() {
              @Override
              public void onResult(final FloorPlan result) {
                  mFloorPlan = result;
                  loadFloorPlanImage(result);
              }
  
              @Override
              public void onSystemError(IOException e) {
  
              }
  
              @Override
              public void onApplicationError(IndoorAtlasException e) {
  
              }
          });
      }
      public void loadFloorPlanImage(FloorPlan floorPlan)  //Method to load floor plan from the server
      {
          BitmapFactory.Options options = createBitmapOptions(floorPlan);
          FutureResult&lt;Bitmap&gt; result= ia.fetchFloorPlanImage(floorPlan, options);
          result.setCallback(new ResultCallback&lt;Bitmap&gt;()
          {
              @Override
              public void onResult(final Bitmap result)
              {
                  runOnUiThread(new Runnable()
                  {
                      @Override
                      public void run() {
  
                          imageView = (ImageView) findViewById(R.id.imageView);
                          imageView.setImageBitmap(result);
                      }
                  });
                  updateImageViewInUiThread();
              }
  
              @Override
              public void onSystemError(IOException e)
              {
                  log();
              }
  
              @Override
              public void onApplicationError(IndoorAtlasException e)
              {
                  log();
              }
          });
          try
          {
              ia.startPositioning(venueId, floorId, floorPlanId);
          }
          catch (IndoorAtlasException e)
          {
              log();
          }
      }
  
     private BitmapFactory.Options createBitmapOptions(FloorPlan floorPlan)
     {
         BitmapFactory.Options options = new BitmapFactory.Options();
         int reqWidth = 2048;
         int reqHeight = 2048;
  
         final int width = (int) floorPlan.dimensions[0];
         final int height = (int) floorPlan.dimensions[1];
         int inSampleSize = 1;
  
         if (height &gt; reqHeight || width &gt; reqWidth) {
  
             final int halfHeight = height / 2;
             final int halfWidth = width / 2;
  
             while ((halfHeight / inSampleSize) &gt; reqHeight
                     &amp;&amp; (halfWidth / inSampleSize) &gt; reqWidth) {
                 inSampleSize *= 2;
             }
  
         }
         options.inSampleSize = inSampleSize;
         return options;
     }
  
      public void updateImageViewInUiThread() {}
  
      public void onServiceUpdate(ServiceState state) //method to show blue dot
      {
          int i = state.getImagePoint().getI();
          int j = state.getImagePoint().getJ();
          setImagePoint(state.getImagePoint());
          PointF scaledPoint = new PointF();
          Util.calculateScaledPoint((int) floorPlan.dimensions[0], (int) floorPlan.dimensions[1], i, j, imageView, scaledPoint);
          drawNewPositionInUiThread();
      }
  
      private void setImagePoint(final ImagePoint imgPt) {
  
          runOnUiThread(new Runnable() {
              @Override
              public void run() {
                  ImageView imagePoint = (ImageView) findViewById(R.id.bluedottwo);
                  imagePoint.setX(imgPt.getI());
                  imagePoint.setY(imgPt.getJ());
              }
          });
      }
  
      private void drawNewPositionInUiThread() {
  
      }
      public static class Util {
          public static float calculateScaleFactor(int originalWidth, int originalHeight,
                                                   ImageView imageView) {
              if (imageView.getScaleType() != ImageView.ScaleType.CENTER_INSIDE) {
                  throw new IllegalArgumentException("only scale type of CENTER_INSIDE supported, was: "
                          + imageView.getScaleType());
              }
  
              final int availableX = imageView.getWidth()
                      - (imageView.getPaddingLeft() + imageView.getPaddingRight());
              final int availableY = imageView.getHeight()
                      - (imageView.getPaddingTop() + imageView.getPaddingBottom());
  
              if (originalWidth &gt; availableX || originalHeight &gt; availableY) {
                  // original image would not fit without scaling
                  return originalWidth &gt; availableX
                          ? availableX / (float) originalWidth
                          : availableY / (float) originalHeight;
              } else {
                  return 1f; // no scaling required
              }
  
          }
          public static void calculateScaledPoint(int originalWidth, int originalHeight,
                                                  int x, int y,
                                                  ImageView imageView,
                                                  PointF point) {
  
  
              final float scale = calculateScaleFactor(originalWidth, originalHeight, imageView);
              final float scaledWidth = originalWidth * scale;
              final float scaledHeight = originalHeight * scale;
  
              // when image inside view is smaller than the view itself and image is centered (assumption)
              // there will be some empty space around the image (here offset)
              final float offsetX = Math.max(0, (imageView.getWidth() - scaledWidth) / 2);
              final float offsetY = Math.max(0, (imageView.getHeight() - scaledHeight) / 2);
  
              point.x = offsetX + (x * scale);
              point.y = offsetY + (y * scale);
          }
      }
  
      public void onServiceFailure(int errorCode, String reason)
      {
          log();
      }
  
      @Override
      public void onServiceInitializing()
      {
          log();
      }
  
      @Override
      public void onServiceInitialized()
      {
          log();
      }
  
      @Override
      public void onInitializationFailed(final String reason)
      {
          log();
      }
  
      @Override
      public void onServiceStopped()
      {
          log();
      }
  
      @Override
      public void onCalibrationStatus(CalibrationState calibrationState)
      {
          log();
      }
  
      @Override
      public void onCalibrationReady()
      {
          log();
      }
  
      @Override
      public void onNetworkChangeComplete(boolean success)
      {
      }
  
      @Override
      public void onCalibrationInvalid()
      {
      }
  
      @Override
      public void onCalibrationFailed(String reason)
      {
      }
      private void log()
      {
          runOnUiThread(new Runnable()
          {
              @Override
              public void run()
              {
  
              }
          });
      }
  
  }
  </code></pre>
  
  <p>And here is my complete XML code "indoor_positioning.xml":</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="vertical" android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:weightSum="1"&gt;
  
      &lt;ImageView
          android:id="@+id/imageView"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:contentDescription="@string/idk"
          android:scaleType="fitCenter" /&gt;
      &lt;ImageView
          android:id="@+id/bluedottwo"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:src="@drawable/bluedottwo"
          android:contentDescription="@string/bd"/&gt;--&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>In the Java code, I do not know what to assign and how to access those two variables called "floorPlan" and "mFloorPlan". I am also not sure if my XML code is correct, as I am not sure should I have customView or those two ImageViews? 
  I do not know how to properly use the "Util" class (as it is mainly used for scaling the image/bitmap I guess), and other methods as you can see I have left them empty. The Java code is not complete, and that is why if somebody knows the answers and also knows what is missing inside the codes, that would be great. If you have been working with IndoorAtlas SDk or have worked with this SDK or an expert in using bitmaps, and if you know the answer, then please correct my Java program by pointing out the mistakes and by showing the correct codes.</p>
  
  <p>Here is image link which shows the actual result I am getting on my android phone: "<a href="https://i.imgur.com/ySjBt3T.png" rel="nofollow noreferrer">http://i.imgur.com/ySjBt3T.png</a>"</p>
  
  <p>As you can see in the image that the floor plan is loaded and being shown on the top left hand corner of the screen with the blue dot inside.
  When I run the application on my phone, firstly, the blue dot loads, after that, floor plan bitmap is loaded and the blue dot goes below the floor plan image/bitmap and after that, the blue dot comes inside the floor plan. But I want to see the floor plan image in the full screen, with rotation, and both the floor plan image and the blue dot should be loaded at the same time.  </p>
  
  <p>Many thanks in advance.</p>