2015-11-10 77 views
1

所以,顯然我是Java的新手,以下是我的故事: 我一直在與IndoorAtlas(the提供室內定位解決方案的公司)Android SDK 1.4.2-132,當我在手機上測試應用程序時,我沒有收到我想要的結果。 這裏是我完整的Java代碼,我主要是從這個鏈接 「Show FloorPlan and get Location with IndoorAtlas」 了:IndoorAtlas Android SDK 1.4.2-132:獲取全屏的平面圖像/位圖+旋轉

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<FloorPlan> result = ia.fetchFloorPlan(floorPlanId); //obtains instance of floor plan 
     result.setCallback(new ResultCallback<FloorPlan>() { 
      @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<Bitmap> result= ia.fetchFloorPlanImage(floorPlan, options); 
     result.setCallback(new ResultCallback<Bitmap>() 
     { 
      @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 > reqHeight || width > reqWidth) { 

      final int halfHeight = height/2; 
      final int halfWidth = width/2; 

      while ((halfHeight/inSampleSize) > reqHeight 
        && (halfWidth/inSampleSize) > 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 > availableX || originalHeight > availableY) { 
       // original image would not fit without scaling 
       return originalWidth > 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() 
      { 

      } 
     }); 
    } 

} 

這裏是我的完整XML代碼 「indoor_positioning.xml」:

<?xml version="1.0" encoding="utf-8"?> 
<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"> 

    <ImageView 
     android:id="@+id/imageView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:contentDescription="@string/idk" 
     android:scaleType="fitCenter" /> 
    <ImageView 
     android:id="@+id/bluedottwo" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@drawable/bluedottwo" 
     android:contentDescription="@string/bd"/>--> 

</LinearLayout> 

在Java代碼中,我不知道要分配什麼以及如何訪問稱爲「floorPlan」和「mFloorPlan」的這兩個變量。我也不確定我的XML代碼是否正確,因爲我不確定我是否應該有customView或這兩個ImageViews? 我不知道如何正確使用「Util」類(因爲它主要用於縮放圖像/位圖,我猜)和其他方法,你可以看到我已經把它們留空了。 Java代碼並不完整,這就是爲什麼如果有人知道答案,並且知道代碼內部缺少什麼,那就太好了。如果您一直在使用IndoorAtlas SDk,或者使用過此SDK或使用位圖的專家,並且如果您知道答案,請通過指出錯誤並顯示正確的代碼來糾正我的Java程序。

這裏是圖像鏈接,顯示了實際的結果我我的Android手機上得到:「http://i.imgur.com/ySjBt3T.png

正如你可以在平面圖被加載並在左上角被顯示的圖片中看到屏幕裏面有藍點。 當我跑我的手機上的應用程序,首先,藍點的負載,在那之後,平面圖的位圖加載藍點去的樓層平面圖像/位圖的下方,之後,藍點自帶的平面圖內。但是我想在全屏幕中看到平面圖像,並旋轉,並且平面圖像和藍點都應該同時加載。

非常感謝提前。

+0

如果你正在開發一個新的開發項目,我會推薦使用2.0版本的SDK,因爲它在GitHub中有完整的示例代碼(閱讀更多:http://docs.indooratlas.com/android/),它更容易反正使用。 –

+0

我已經在我的應用程序中實施了新的SDK,並且它更容易實現,但是,當我打開應用程序時,它會顯示已刪除的平面圖(我從IndoorAtlas帳戶中測試並刪除的平面圖)。我一直在與IndoorAtlas的支持聯繫,他們告訴我,開發團隊很快就會進行緩存清理,所以在那之前我必須在舊SDK上工作,因爲我想在自己的應用程序中看到正確的平面圖,而不是刪除一個。 – Neel0507

回答

0

要回答你的第一個問題:做什麼用的變量floorPlanmFloorPlan?這個IAFloorPlan對象包含平面圖的元數據。例如。它的像素尺寸和信息如何將度量位置轉換爲像素位置等。您只需要一個,以便刪除floorPlan變量。其次,當你在你的圖像上繪製位置時,你需要在屏幕上縮放圖像點的相對於你的圖像點。例如:如果服務返回像素位置1024,1024,該位置相對於原來的平面圖位圖(即2048,2048),則您的位置位於地圖的中心。如果應用程序的用戶界面中的位圖具有尺寸1024×1024(原來的一半)的,你不能畫由服務(1024,1024)返回相同的座標,但你需要的規模在這裏是0.5來算,因此座標繪製成將成爲:

x = 1024(originalX) * 0.5(scale) => 512 
y = 1024(orginalY) * 0.5(scale) => 512 

你也應該確保平面圖的原始寬高比始終保留。此外,在計算X & Y在哪裏繪製時,請考慮可能的填充,並且如果圖像的視圖畫布較小,則需要檢查它的位置(例如居中)。

但正如我在評論你的問題補充:我會建議使用IndoorAtlas Android SDK中的2.0版提供更好的文檔和例子。此處的文檔:http://docs.indooratlas.com/android/,示例:https://github.com/IndoorAtlas/android-sdk-examples