ウェブアプリケーション,インジェクション,コマンドインジェクション

Androidアプリ開発 アプリケーションでグーグルマップを使います

reverse Geocodingを使う

Finding a User-Friendly Address Using
Reverse GeoCoding, and Vice Versa

位置をタッチするだけで、マップの位置のアドレスを知りたい。
さらに、与えた位置の緯度、経度を見つけられる様にしたい。
そんな時に使える方法をここで示します。
一方、ユーザはGoogle Mapsを上下左右に動かすことで、
いろんな位置を画像的に見ることができ、
マップをタッチして、タッチされている位置のアドレスを
ユーザがわかりやすい形で得るのに役に立ちます。
これを動作させるためには、開発者は以下の段階を踏む必要があります。
1,タッチされている緯度、経度を取得します。
2,逆座標操作を行い、位置の緯度、経度をユーザにわかりやすい
アドレスの形に変換します。
以下のコードはGoogle Mapsのオーバレイを使ってそれらの操作を
動作させる方法を示します。

Getting the Location that was Touched

タッチされている位置情報を取得するには、
onTouchEvent()メソッドをOverlayクラスの中にオーバライド
(再定義)する必要があります。このメソッドはいつでもユーザが
マップを触ると停止されます。
onTouchEvent()は、MotionEventとMapViewの2つの引数を持ちます。
MotionEvent引数を使うと、getAction()メソッドを使って、
スクリーンからユーザの指が離れたかどうかを判断できます。
以下にあるコードは、Overlay基底クラスの拡張クラスを実行し、
そしてその拡張クラスのインスタンスをMapViewオブジェクトに
加えます。ユーザがスクリーンに触れ、そして指を話したときには、
触られた位置の緯度、経度が表示されます。

package net.learn2develop.maps;

import java.util.List;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class MainActivity extends MapActivity{
  MapView mapView;
  MapController mc;

  private class Mapoverlay extends Overlay{
   @Override
   public boolean onTouchEvent(MotionEvent event, MapView mapView){
    //---when user lifts his finger---
    if(event.getAction() == 1){
     GeoPoint p = mapView.getProjection().fromPixels(
      (int) event.getX();
      (int) event.gety();
      Toast.makeText(getBaseContext(),"Location: " +
       p.getLatitudeE6() / 1E6 + "," + p.getLongitudeE6(),
       Toast.LENGTH_SHORT).show();
    }
    return false;
   }
  }

  @Override
  public void onCreate(Bundle savedInstanceState){
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);

   mapView = (MapView) findViewById(R.id.mapView);
   mapView.setBuiltInZoomControls(true);

   mc = mapView.getController();

   MapOverlay mapOverlay = new MapOverlay();
   List<Overlay> listOfOverlays = mapView.getOverlays();
   listOfOverlays.add(mapOverlay);
  }

  @Override
  protected boolean isRouteDisplayed(){
   return false;
  }
}

getprojection()メソッドはスクリーンピクセル調整と緯度/経度調整を
変換している画像を返します。
fromPixels()メソッドはその時GeoPointオブジェクトでスクリーン調整に
変換されます。

Reverse Geocoding

もし位置の緯度、経度を知っていたら、reverse geocodingとして
知られる処理を使って、その位置のユーザに分かりやすいアドレスを
見つけ出すことができます。
AndroidデバイスのGoogle MapsはGeocoderクラスを使って
reverse geocodingをサポートしています。
以下のコードは、getFromLocation()メソッドを使って、
触れられた位置のアドレス情報を検索できる方法を示します。

package net.learn2develop.maps;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.location.Address;
import android.location.Geocoder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class MainActivity extends MapActivity{
  MapView mapView;
  MapController mc;

  /*
  private class MapOverlay extends Overlay{
   @Override
   public boolean onTouchEvent(MotionEvent event, MapView mapView){
    //---when user lifts his finget---
    if(event.getAction() == 1){
     GeoPoint p = mapView.getProjection().fromPixels(
      (int) event.getX();
      (int) event.getY();
      Toast.makeText(getVaseContext(), "Location: " +
       p.getLatitudeE6() / 1E6 + "," +
       p.getLongitudeE6() / 1E6,
       Toast.LENGTH_SHORT).show();
    }
    return false;
   }
  }
  */

  private class MapOverlay extends Overlay{
   private class DoBackgroundTask extends AsyncTask <GeoPoint, Void,
      List<Address>>{

    protected List<Address> doInBackground(GeoPoint... locations){
     Geocoder geoCodr = new Geocoder(getBaseContext(),
        Locale.getDefault());
     try{
      List<Address> addresses = geoCoer.getFromLocation(
         locations[0].getLatitudeE6 / 1E6,
         location[0].getLongitudeE6 / 1E6, 1);
      return addresses;
     }
     catch (IOException e){
       e.printStackTrace();
     }
     return null;
    }

    protected void onPostExecute(List<Address> addresses){
     String add = "";
     if(addresses.size() > 0){
       for (int i = 0; i < addresses.get(0).getMaxAddressLineIndex();
              i++)
        add += addresses.get(0).getAddressLine(i) + "\n";
      }
      Toast.makeText(getBaseContext(), add, Toast.LENGTH_SHORT).show();
    }
   }

   @Override
   public boolean onTouchEvent(MotionEvent event, MapView mapView){
    //---when user lifts his finger---
    if(event.getAction() == 1){
     GeoPoint p = mapView.getProjection().fromPixels(
           (int) event.getX();
           (int) event.getY();
     Toast.makeText(getBaseContext(), "Location: " +
            p.getLatitudeE6() / 1E6 + "," +
            p.getLongitudeE6() / 1E6 ,
            Toast.LENGTH_SHORT).show();

     //---reverse geocoding---
     new DoBackgroundTask().execute(p);
     return true;
    }
    return false;
   }
  }

  @Override
  public void onCreate(Bundle savedInstanceState){
   super.onCreate(savedInstanceState);
   setContentView(R.layout.ctivity_main);

   mapView = (MapView) findViewById(R.id.mapView);
   mapView.setBuiltInZoomControls(true);

   mc = mapView.getController();

   MapOverlay mapOverlay = new MapOverlay();
   List<Overlay> listOfOverlays = mapView.getOverlays();
   listOfOverlays.add(mapOverlay);
  }

  @Override
  protected boolean isRouteDisplayed(){
    return false;
  }
}

理由としてgetFromLocation()メソッドは呼び出しブロックされていて、
すぐにはリターンできません。
これは分離したスレッドからgetFromLocation()メソッドの呼び出すのに
重要です。上のコードはAsyncTaskクラスを使って
呼び出しが囲われています。

Geocoding

もしアドレスがわかっていて、そのアドレスの緯度、経度を
知りたい場合があれば、geocodingを使うことができます。
Geocoderクラスをこの目的に使うこともできます。
以下のコードは特定の場所の正確な場所をgetFromLocationName() メソッドを使って見つけることができる方法を示します。

@Override
public void onCreateZ(Bundle savedInstanceState){
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  mapView = (MapView) findViewById(R.id.mapView);
  mapView.setBuiltInZoomControls(true);

  mc = mapView.getController();

  MapOverlay mapOverlay = new MapOverlay();
  List<Overlay> listOfOverlays = mapView.getOverlays();
  listOfOverlays.add(mapOverlay);

  new DoBackgroundTask().execute(場所の名前を入れます);
}
  private class DoBackgroundTask etends AsyncTask <String, Void,
      List<Address>>{
   protected List<Address> doInBackground(String... locationNames){
    //---geo coding---
    Geocoder geoCoder = new Geocoder(getBaseContext(),
      Locale.getDefault());
    try{
     //---maximum 5 results---
     List<Address> addresses = geoCoder.getFromLocationName(
       locationNames[0],5);
     return addresses;
    }catch(IOException e){
     e.printStackTrace();
    }
    return null;
   }

   protected void onPostExecete(List<Address> addresses){
    if(address.size() > 0){
     GeoPoint p = new GeoPoint(
         (int) (addresses.get(0).getLatitude() * 1E6),
         (int) (addresses.get(0).getLongitude() * 1E6));
     mc.animateTo(p);
     mc.setZoom(20);
   }
  }
}

上のコードではまずgetFromLocationName()メソッドでアドレスが
返され、その時その位置がマップに表示されます。

ホーム
便利堂ロゴ
inserted by FC2 system