2016-09-28 1 views
-1

こんにちは私はマップボックスを使用してアンドロイドの地図を表示しています。私は、ユーザーが見ることのできる地図の半径を取得する必要がある状況に陥っています。ユーザーがズームインまたはズームアウトすると、マップの半径が変化します。誰が私にこのことをどうやって教えてくれるのか、これに関する参考リンクを教えてもらえますかMapbox touchlistner

+0

http://stackoverflow.com/questions/38473515/building-custom-overlay-specifically-circle-with-radiuscolored-in-android-mapbは、このスタックのブログを参照してください、あなたはいくつかのアイデアを得るでしょうかもしれません。 –

答えて

0

マップスケールが変更されたときを検出するには、リスナーをMapboxMapに追加する必要があります。 MapViewを拡張して、地図がズームまたはパンされると動的にサイズ変更される下部にスケールバーを追加するクラスの例を次に示します(パンでは距離のスケールは変更されますが、度合いは変更されません)。

example of scale bar on Mapbox

ポイントのカップル:MapViewからMapboxMapを取得する唯一の方法は、非同期的にそれを要求することです。マップをホストしているアクティビティーまたはフラグメントがそれを行う必要があります。このクラスはをオーバーライドしてMapboxMapへの参照も取得できるようにしますが、ホストのアクティビティでもそのメソッドを呼び出す必要があります。

カメラチェンジイベントはリスナーに報告され、MapboxMapでは1つしか設定できません。したがって、ホスティングアクティビティにリスナーがある場合は、そのリスナーの同様の名前のメソッドでScaledMapView#onCameraChange()を呼び出す必要があります。

MapView自体は、縮尺表示を追加できるようにFrameLayoutに含まれている必要があります。

もちろん、同じ基本コードをアクティビティやフラグメントに組み込んで、プログラムで追加するのではなくレイアウトにスケールTextViewを含めることもできます。

拡張クラス:

package com.controlj.test; 

import android.content.Context; 
import android.location.Location; 
import android.support.annotation.NonNull; 
import android.support.annotation.Nullable; 
import android.util.AttributeSet; 
import android.view.Gravity; 
import android.view.ViewGroup; 
import android.view.ViewParent; 
import android.widget.FrameLayout; 
import android.widget.TextView; 

import com.mapbox.mapboxsdk.camera.CameraPosition; 
import com.mapbox.mapboxsdk.geometry.LatLngBounds; 
import com.mapbox.mapboxsdk.maps.MapView; 
import com.mapbox.mapboxsdk.maps.MapboxMap; 
import com.mapbox.mapboxsdk.maps.MapboxMapOptions; 
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; 

import java.util.Locale; 

/** 
* Created by clyde on 2/10/2016. 
* This class extends the Mapbox Mapview to add a scale at the bottom 
*/ 

public class ScaledMapview extends MapView implements MapboxMap.OnCameraChangeListener, OnMapReadyCallback { 
    private TextView scaleText; 
    private MapboxMap mapboxMap; 
    private OnMapReadyCallback callback; 
    private ScaleUnit scaleUnit = ScaleUnit.KM; 
    private float labelWidth = 0.33f; 

    public float getLabelWidth() { 
     return labelWidth; 
    } 

    public void setLabelWidth(float labelWidth) { 
     if(labelWidth > 1f) 
      labelWidth = 1f; 
     else if(labelWidth < 0.1f) 
      labelWidth = 0.1f; 
     this.labelWidth = labelWidth; 
    } 

    public ScaleUnit getScaleUnit() { 
     return scaleUnit; 
    } 

    public void setScaleUnit(ScaleUnit scaleUnit) { 
     this.scaleUnit = scaleUnit; 
    } 

    enum ScaleUnit { 
     MILE("mile", 1609.344f), 
     NM("nm", 1852.0f), 
     KM("km", 1000.0f); 

     ScaleUnit(String unit, float ratio) { 
      this.unit = unit; 
      this.ratio = ratio; 
     } 

     String unit; 
     float ratio; 
    } 

    public ScaledMapview(@NonNull Context context) { 
     super(context); 
    } 

    public ScaledMapview(@NonNull Context context, @Nullable AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public ScaledMapview(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    public ScaledMapview(@NonNull Context context, @Nullable MapboxMapOptions options) { 
     super(context, options); 
    } 

    @Override 
    public void getMapAsync(OnMapReadyCallback callback) { 
     this.callback = callback; 
     super.getMapAsync(this); 
    } 

    /** 
    * To ensure this is called when the camera changes, either this ScaledMapview must be passed 
    * to mapboxMap.setOnCameraChangeListener() or whatever is listening must also call this method 
    * when it is called. 
    * 
    * @param position The CameraPosition at the end of the last camera change. 
    */ 
    @Override 
    public void onCameraChange(CameraPosition position) { 
     if (scaleText == null) { 
      ViewParent v = getParent(); 
      if (v instanceof FrameLayout) { 
       scaleText = (TextView)inflate(getContext(), R.layout.mapscale, null); 
       ((FrameLayout)v).addView(scaleText); 
      } 
     } 
     if (scaleText != null) { 
      // compute the horizontal span in metres of the bottom of the map 
      LatLngBounds latLngBounds = mapboxMap.getProjection().getVisibleRegion().latLngBounds; 
      float span[] = new float[1]; 
      Location.distanceBetween(latLngBounds.getLatSouth(), latLngBounds.getLonEast(), 
        latLngBounds.getLatSouth(), latLngBounds.getLonWest(), span); 

      float totalWidth = span[0]/scaleUnit.ratio; 
      // calculate an initial guess at step size 
      float tempStep = totalWidth * labelWidth; 

      // get the magnitude of the step size 
      float mag = (float)Math.floor(Math.log10(tempStep)); 
      float magPow = (float)Math.pow(10, mag); 

      // calculate most significant digit of the new step size 
      float magMsd = (int)(tempStep/magPow + 0.5); 

      // promote the MSD to either 1, 2, or 5 
      if (magMsd > 5.0f) 
       magMsd = 10.0f; 
      else if (magMsd > 2.0f) 
       magMsd = 5.0f; 
      else if (magMsd > 1.0f) 
       magMsd = 2.0f; 
      float length = magMsd * magPow; 
      if (length >= 1f) 
       scaleText.setText(String.format(Locale.US, "%.0f %s", length, scaleUnit.unit)); 
      else 
       scaleText.setText(String.format(Locale.US, "%.2f %s", length, scaleUnit.unit)); 
      // set the total width to the appropriate fraction of the display 
      int width = Math.round(getWidth() * length/totalWidth); 
      LayoutParams layoutParams = 
        new LayoutParams(width, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL); 
      layoutParams.bottomMargin = 4; 
      scaleText.setLayoutParams(layoutParams); 
     } 
    } 

    @Override 
    public void onMapReady(MapboxMap mapboxMap) { 
     this.mapboxMap = mapboxMap; 
     // if the owner of this view is listening for the map, pass it through. If not, we must 
     // listen for camera events ourselves. 
     if (callback != null) 
      callback.onMapReady(mapboxMap); 
     else 
      mapboxMap.setOnCameraChangeListener(this); 
     onCameraChange(null); 
    } 
} 

アクティビティー:

package com.controlj.test; 

import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 

import com.mapbox.mapboxsdk.MapboxAccountManager; 

public class MainActivity extends AppCompatActivity { 

    private static final String TAG = MainActivity.class.getSimpleName(); 
    ScaledMapview mapView; 

    @Override 
    protected void onStart() { 
     Log.d(TAG, "OnStart()"); 
     super.onStart(); 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Log.d(TAG, "OnCreate()"); 
     MapboxAccountManager.start(this, getString(R.string.mapbox_access_token)); 
     setContentView(R.layout.activity_main); 
     mapView = (ScaledMapview)findViewById(R.id.mapview); 
     mapView.onCreate(savedInstanceState); 
     mapView.getMapAsync(null); 
    } 
    @Override 
    public void onDestroy() { 
     Log.d(TAG, "OnDestroy()"); 
     super.onDestroy(); 
     mapView.onDestroy(); 

    } 

    @Override 
    public void onLowMemory() { 
     super.onLowMemory(); 
     mapView.onLowMemory(); 
    } 

    @Override 
    public void onPause() { 
     Log.d(TAG, "OnPause()"); 
     mapView.onPause(); 
     super.onPause(); 
    } 

    @Override 
    public void onResume() { 
     Log.d(TAG, "OnResume()"); 
     super.onResume(); 
     mapView.onResume(); 
    } 

    @Override 
    public void onSaveInstanceState(Bundle outState) { 
     Log.d(TAG, "OnSaveInstanceState()"); 
     super.onSaveInstanceState(outState); 
     mapView.onSaveInstanceState(outState); 
    } 
} 

活性レイアウト:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout 
    android:id="@+id/activity_main" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:mapbox="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.controlj.test.MainActivity"> 

     <com.controlj.test.ScaledMapview 
      android:id="@+id/mapview" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      mapbox:access_token="@string/mapbox_access_token" 
      mapbox:center_latitude="-31.42166667" 
      mapbox:center_longitude="152.75833333" 
      mapbox:style_url="@string/mapbox_style" 
      mapbox:zoom="4"/> 
</FrameLayout> 

とスケールウィジェット自体のレイアウト。イメージリソース@drawable/scaleは、9パッチイメージファイルです。

<?xml version="1.0" encoding="utf-8"?> 
<TextView 
    android:id="@+id/scale_text" 

    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center|bottom" 
    android:textAlignment="center" 
    android:background="@drawable/scale" 
    android:paddingBottom="2dp" 
    android:layout_marginBottom="6dp" 
    android:layout_marginTop="0dp" 
    android:paddingTop="0dp" 
    android:text="100km"/> 
+0

このタスクは保留になっていますので、とにかく多くのお返事ありがとうございます:) –

0

私は半径であなたが現在見える地図の距離を意味すると仮定しようとしていますか?これが当てはまる場合は、西と東の境界の間の絶対距離を度単位で取得できます。

LatLngBounds latLngBounds = mapboxMap.getProjection().getVisibleRegion().latLngBounds; 
latLngBounds.getLongitudeSpan(); 

これがあなたが探しているものでない場合は教えてください。

+0

:ok - 地図上のユーザーのズームイン、ズームアウトのアクションを検出するためにタッチリスナーを実装する方法について教えてください。 –

+0

更新されたカメラ位置を示す 'mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener()')を使うことができます。これで現在のズームを得ることができます。 – cammace