2013-01-14 4 views
19

Google지도 앱을 열면 화면의 오른쪽 상단에 버튼을 눌러 현재 위치에지도를 중앙에 배치 할 수 있습니다. 그런 다음 버튼의 아이콘이 변경됩니다. 같은 버튼을 다시 누르면지도가 나침반의 머리글을 기준으로 자동 회전합니다. 다른 말로하면,지도는 자기 중심적이된다 (AKA가 항상 북쪽에있다).android maps automatically-rotate

Google은 최근 Android 용지도 API V2를 출시했으며 이전 버전보다 더 좋아할 것입니다. 기본적으로 Android지도 V2에는 '위치 중심'버튼이 포함됩니다. 그러나 두 번 이상 누르면 자동 회전이 활성화되지 않습니다. 그것은 단지 당신의 위치에지도를 다시 중심에 두려고합니다.

Google지도 앱처럼지도 API v2를 사용하여지도를 자동 회전하는 방법을 아는 사람이 있습니까? 이 기능을 직접 구현해야합니까, 아니면 API에 있습니까? 나는 모든 도움에 감사한다.

+0

... 난 심지어 그 기능에 대한 감사를 몰랐 :

가 onSensorChanged에 의해 처리되는 데이터의 양을 제어하기 위해, 나는 다음과 같은 구현을 제안한다. 나에게 잘 작동한다. (v7) –

+0

그는 똑같은 일을하고 싶다. –

답변

22

확인에 하나 일 것 sensor managercamera

으로 직접 구현해야합니다 여기에 1 년 후에해야한다고 생각합니다. 문제를 발견하면 저를 시정하십시오.

다음 코드의 대부분은 좌표계 간의 불일치를 다룹니다. 회전 벡터 센서를 사용하고 있습니다. 문서에서 : Y is tangential to the ground at the device's current location and points towards magnetic north. 반면에 Google지도에서 베어링은 북쪽을 가리키는 것처럼 보입니다. this page shows how the conversion is done

1) 편각 및 자기 북쪽에서 베어링 계산) 현재의 GPS 위치

@Override 
public void onLocationChanged(Location location) { 
    GeomagneticField field = new GeomagneticField(
      (float)location.getLatitude(), 
      (float)location.getLongitude(), 
      (float)location.getAltitude(), 
      System.currentTimeMillis() 
     ); 

    // getDeclination returns degrees 
    mDeclination = field.getDeclination(); 
} 

2에서 현재의 편차를 얻을 수

@Override 
public void onSensorChanged(SensorEvent event) { 
    if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { 
     SensorManager.getRotationMatrixFromVector(
       mRotationMatrix , event.values); 
     float[] orientation = new float[3]; 
     SensorManager.getOrientation(mRotationMatrix, orientation); 
     float bearing = Math.toDegrees(orientation[0]) + mDeclination; 
     updateCamera(bearing); 
    } 
} 

3) 업데이트는

private void updateCamera(float bearing) { 
    CameraPosition oldPos = mMap.getCameraPosition(); 

    CameraPosition pos = CameraPosition.builder(oldPos).bearing(bearing).build(); 
      mMap.moveCamera(CameraUpdateFactory.newCameraPosition(pos)); 
} 
+1

mRotationMatrix? – Anthone

+1

'private float [] mRotationMatrix = new float [16];' 'getRotationMatrixFromVector'는 이벤트의 값에 따라'mRotationMatrix'를 채울 것입니다. –

+0

이것은 맵에서 깜빡 거리는 효과를 만듭니다. 어떻게 회전을 제한 할 수 있습니까? – Bytecode

0

죄송합니다, 당신은 그 기능은지도 API를 V2 사용할 수 있다면 그들은 확실히 GoogleMap 또는 UiSettings

1

매핑 응용 프로그램을 센서 리스너에 등록하면 onSensorChanged 내에서 방향을 지정하고 실제 북쪽을 기준으로 각도를 가져 와서 그에 따라 카메라를 업데이트합니다. 베어링에 각도를 사용할 수 있습니다. 나는 성공적으로 솔루션을 aleph_null 구현 한

Instead of using Sensor.TYPE_ORIENTATION try using getOrinetation api. Sensor.TYPE_ORIENTATION 
has been deprecated. 

@Override 
protected void onResume() { 
    // TODO Auto-generated method stub 
    super.onResume(); 
    if (sensorManager != null) 
     sensorManager.registerListener(this, 
       sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), 
       SensorManager.SENSOR_DELAY_GAME); 
} 

public void onSensorChanged(SensorEvent event) { 

    float degree = Math.round(event.values[0]); 

    Log.d(TAG, "Degree ---------- " + degree); 

    updateCamera(degree); 

} 

private void updateCamera(float bearing) { 
    CameraPosition oldPos = googleMap.getCameraPosition(); 

    CameraPosition pos = CameraPosition.builder(oldPos).bearing(bearing) 
      .build(); 

    googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(pos)); 

} 
5

여기에 내가 허용 솔루션에 언급되지 않은 몇 가지 세부 사항 추가합니다 : 다음 코드를 사용할 수 있습니다 구현해야 작동하려면 위의 솔루션을

을 android.hardware.SensorEventListener 인터페이스입니다.

당신은 다음과 같은 onResume과 onPause 방법에 SensorEventListener에 등록하는 것이 필요합니다, 깜박임을 방지하기 위해, 샘플링 기간 동안 SensorManager 뭔가를 낮은 값을 사용

@Override 
    protected void onResume() { 
    super.onResume(); 
    mSensorManager.registerListener(this, 
      mRotVectSensor, 
      SensorManager.SENSOR_STATUS_ACCURACY_LOW); 
    } 

@Override 
protected void onPause() { 
    // unregister listener 
    super.onPause(); 
    mSensorManager.unregisterListener(this); 
} 

참고 "@Bytecode" .SENSOR_STATUS_ACCURACY_LOW.

나는 센서가 장치가 처리 할 수있는 것보다 더 많은 데이터를 보내고 결과적으로지도 카메라가 이상한 방향으로 움직이기 시작한다는 것을 알아 차렸다.도움이되었다

@Override 
public void onSensorChanged(SensorEvent event) { 
    if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { 
     SensorManager.getRotationMatrixFromVector(
       mRotationMatrix, event.values); 
     float[] orientation = new float[3]; 
     SensorManager.getOrientation(mRotationMatrix, orientation); 
     if (Math.abs(Math.toDegrees(orientation[0]) - angle) > 0.8) { 
      float bearing = (float) Math.toDegrees(orientation[0]) + mDeclination; 
      updateCamera(bearing); 
     } 
     angle = Math.toDegrees(orientation[0]); 
    } 
} 
+0

'mRotVectSensor'? – theapache64

+0

각도가 정의 된 위치 – suulisin