2015-01-01 2 views
0

Я просматриваю интернет, пытаясь найти то, что было бы полезно в моем приложении для Android. У меня есть местоположение GPS и несколько маркеров, добавленных в Google Map. Когда я поворачиваюсь, стрелка местоположения указывает, где я столкнулся. Меня беспокоит, есть ли способ определить, на каком маркере я указываю? Я сделал фотографию, чтобы прояснить это.Определить направление компаса

enter image description here

Я полагаю, я могу получить азимут, используя метод getRotationMatrix(), но как я могу определить угол между местоположением и маркером?

+0

как же определить, какой маркер, вы направляете? Я совершенно потерял –

ответ

5

заказ Compass класс в этом проекте: https://github.com/iutinvg/compass

Я использовал его succsesfully в этом приложении: https://play.google.com/store/apps/details?id=com.gps.build

С уважением.

UPDATE:

После прочтения вашего вопроса еще раз, я понял, что я не дал вам достаточно деталей для «указывая на маркер» части. Пожалуйста, проверьте полный класс ниже. Чтобы вычислить направление указаний, мы начинаем использовать методы Bearing и stopBearing.

Обратите внимание, что степени подшипника изменяются при вращении устройства в классе BringMeBack с помощью метода setBearingDegrees. Это не то, что вам нужно, поэтому вам просто нужно удалить locationManager и поставить статическую координату подшипника. И вызовите этот метод только один раз.

Расширенный класс компас:

package com.gps.bitlab; 

import android.content.Context; 
import android.hardware.Sensor; 
import android.hardware.SensorEvent; 
import android.hardware.SensorEventListener; 
import android.hardware.SensorManager; 
import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.util.Log; 
import android.view.animation.Animation; 
import android.view.animation.RotateAnimation; 
import android.widget.ImageView; 

import com.gps.bitlab.fragment.MessageDialogFragment; 
import com.gps.bitlab.util.Utility; 

public class Compass implements SensorEventListener { 
    private static final String TAG = "Compass"; 

    private SensorManager sensorManager; 
    private Sensor gsensor; 
    private Sensor msensor; 
    private float[] mGravity = new float[3]; 
    private float[] mGeomagnetic = new float[3]; 
    private float azimuth = 0f; 
    private float currectAzimuth = 0; 

    private boolean bearing = false; 
    private float bearingDegrees = -1; 

    // compass arrow to rotate 
    public ImageView arrowView = null; 

    FragmentActivity activity; 

    public Compass(FragmentActivity activity) { 

     this.activity = activity; 

     sensorManager = (SensorManager) activity.getApplicationContext() 
       .getSystemService(Context.SENSOR_SERVICE); 
     gsensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
     msensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); 
    } 

    public void start() { 

     boolean deviceSensorCompatible = true; 

     if(!sensorManager.registerListener(this, gsensor, SensorManager.SENSOR_DELAY_GAME)) 
      deviceSensorCompatible = false; 

     if(!sensorManager.registerListener(this, msensor, SensorManager.SENSOR_DELAY_GAME)) 
      deviceSensorCompatible = false; 

     if(!deviceSensorCompatible) { 
      Utility.ShowMessage(activity, activity.getString(R.string.erroroccured), activity.getString(R.string.deviceIncompatible), 1); 
      stop(); 
     } 
    } 

    public void startBearing() 
    { 
     bearing = true; 
     start(); 
    } 

    public void setBearingDegrees(float bearingDegrees) 
    { 
     this.bearingDegrees = bearingDegrees; 
    } 

    public void stop() { 
     sensorManager.unregisterListener(this); 
    } 

    public void stopBearing() 
    { 
     bearing = false; 
     stop(); 
    } 

    private void adjustArrow() { 
     if (arrowView == null) { 
      Log.i(TAG, "arrow view is not set"); 
      return; 
     } 

     Animation an = new RotateAnimation(-currectAzimuth, -azimuth, 
       Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 
       0.5f); 
     currectAzimuth = azimuth; 

     an.setDuration(250); 
     an.setRepeatCount(0); 
     an.setFillAfter(true); 

     arrowView.startAnimation(an); 
    } 

    @Override 
    public void onSensorChanged(SensorEvent event) { 
     final float alpha = 0.97f; 

     synchronized (this) { 
      if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 

       mGravity[0] = alpha * mGravity[0] + (1 - alpha) 
         * event.values[0]; 
       mGravity[1] = alpha * mGravity[1] + (1 - alpha) 
         * event.values[1]; 
       mGravity[2] = alpha * mGravity[2] + (1 - alpha) 
         * event.values[2]; 

       // mGravity = event.values; 

       // Log.e(TAG, Float.toString(mGravity[0])); 
      } 

      if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { 
       // mGeomagnetic = event.values; 

       mGeomagnetic[0] = alpha * mGeomagnetic[0] + (1 - alpha) 
         * event.values[0]; 
       mGeomagnetic[1] = alpha * mGeomagnetic[1] + (1 - alpha) 
         * event.values[1]; 
       mGeomagnetic[2] = alpha * mGeomagnetic[2] + (1 - alpha) 
         * event.values[2]; 
       // Log.e(TAG, Float.toString(event.values[0])); 

      } 

      float R[] = new float[9]; 
      float I[] = new float[9]; 
      boolean success = SensorManager.getRotationMatrix(R, I, mGravity, 
        mGeomagnetic); 
      if (success) { 
       float orientation[] = new float[3]; 
       SensorManager.getOrientation(R, orientation); 
       // Log.d(TAG, "azimuth (rad): " + azimuth); 
       azimuth = (float) Math.toDegrees(orientation[0]); // orientation 
       azimuth = (azimuth + 360) % 360; 

       if(bearing) { 
        if(bearingDegrees != -1) { 
         azimuth -= bearingDegrees; 
         adjustArrow(); 
        } 
       } 
       else 
        adjustArrow(); 

       // Log.d(TAG, "azimuth (deg): " + azimuth); 

      } 
     } 
    } 

    @Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 
    } 
} 

класса, которые используют указывающие на функциональность расположения:

package com.gps.bitlab; 

import android.content.Intent; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.WindowManager; 
import android.widget.FrameLayout; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 

import com.gps.bitlab.R; 
import com.gps.bitlab.fragment.OnDialogClickListener; 
import com.gps.bitlab.util.Utility; 

public class BringMeBack extends ActionBarActivity implements LocationListener, OnDialogClickListener { 

    LocationManager locMng; 

    Location location; 
    double lat; 
    double lon; 
    double alt; 
    String name; 
    Compass compass; 

    FrameLayout bearingParentLayout; 
    LinearLayout BaseLayout; 
    ImageView arrow; 

    boolean layoutReplaced = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Utility.SetLocalization(this); 
     setContentView(R.layout.activity_bring_me_back); 

     getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
     getActionBar().setDisplayHomeAsUpEnabled(true); 

     bearingParentLayout = (FrameLayout)findViewById(R.id.bearingParentLayout); 
     BaseLayout = Utility.GetLoadingView(getLayoutInflater(), getString(R.string.waitingForLocation)); 

     if(savedInstanceState != null) 
     { 
      lat = savedInstanceState.getDouble("lat"); 
      lon = savedInstanceState.getDouble("lon"); 
      alt = savedInstanceState.getDouble("alt"); 
      name = savedInstanceState.getString("name"); 
     } 
     else { 
      lat = getIntent().getExtras().getDouble("lat"); 
      lon = getIntent().getExtras().getDouble("lon"); 
      alt = getIntent().getExtras().getDouble("alt"); 
      name = getIntent().getExtras().getString("name"); 
     } 

     if(name != null && !name.equals("")) 
      getActionBar().setTitle(name); 

     locMng = (LocationManager)getSystemService(LOCATION_SERVICE); 
     location = new Location(LocationManager.GPS_PROVIDER); 
     location.setLongitude(lon); 
     location.setLatitude(lat); 
     location.setAltitude(alt); 


     arrow = (ImageView)findViewById(R.id.bearingArrow); 
     compass = new Compass(this); 
     compass.arrowView = arrow; 

     arrow.setVisibility(View.GONE); 
     bearingParentLayout.addView(BaseLayout); 
    } 



    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 
     if (id == android.R.id.home) { 
      BringMeBack.this.finish(); 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     compass.stopBearing(); 
     locMng.removeUpdates(this); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     compass.startBearing(); 
     RequestLocationUpdates(); 
    } 


    @Override 
    public void onLocationChanged(Location currentLocation) { 

     float bearing = currentLocation.bearingTo(location); 
     Log.d("Location bearing", String.valueOf(bearing)); 
     compass.setBearingDegrees(bearing); 

     if(!layoutReplaced) { 
      bearingParentLayout.removeView(BaseLayout); 
      arrow.setVisibility(View.VISIBLE); 
      layoutReplaced = true; 
     } 
    } 

    @Override 
    public void onStatusChanged(String s, int i, Bundle bundle) { 

    } 

    @Override 
    public void onProviderEnabled(String s) { 
     Log.d("GPS", "Service enabled"); 
     RequestLocationUpdates(); 
    } 

    @Override 
    public void onProviderDisabled(String s) { 
     locMng.removeUpdates(this); 
     Utility.ShowMessage(BringMeBack.this, getString(R.string.locationServiceDisabledMessage), getString(R.string.locationServiceDisabled), 0); 
    } 

    @Override 
    public void OnPositiveClick(int key, Object... args) { 
     startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS)); 
    } 

    @Override 
    public void OnNegativeClick(int key, Object... args) { 

    } 

    private void RequestLocationUpdates() 
    { 
     if(!locMng.isProviderEnabled(LocationManager.GPS_PROVIDER)) 
      Utility.ShowMessage(BringMeBack.this, getString(R.string.locationServiceDisabledMessage), getString(R.string.locationServiceDisabled), 0); 
     else 
      locMng.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 0, this); 
    } 
} 
+0

Приветствия. Что такое альфа? – user2847238

+0

Ну, я использовал код «как есть», не копая много. Он швыряет, что он пытается снизить изменения в «считывании сенсора», чтобы стрелка не перескакивала. Если для альфа установлено значение 0, значения mGravity и mMagnetic устанавливаются на значения текущих событий, поэтому любое изменение значения приведет к перемещению стрелок. – bajicdusko

+0

Пожалуйста, проверьте ОБНОВЛЕНИЕ, которое я сделал с моим ответом. Для указания на функциональность местоположения мне пришлось расширять класс Compass и запускать и останавливать опору (указывая на местоположение) там, где я хочу. Мой выбор состоял в том, чтобы начать запись в onResume и остановить его в onPause. – bajicdusko

Смежные вопросы