2015-11-10 25 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