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()メソッドでアドレスが
返され、その時その位置がマップに表示されます。
|
ページ内メニュー
reverse Geocoding
Geocoding
【用語解説】
XML
HTMLと同じような言語ですが、
すべての型の複雑なデータ構造を
送信するための設計ができる
ファイル型式。
オブジェクト
ある手続きを持った
データアイテムで、
他の手続きと関連づけされるもの
metaタグ
ウェブページに与える
情報の宣言につかわれ
検索エンジン・ウェブアプリ
などにウェブページの内容を
伝える役目をする。
metaタグの内容は
ページ内に表示されない。
コンストラクタ
オブジェクト指向
プログラミングで使われ
新しいオブジェクトが
作られ時に呼び出される
メソッドのこと。
クラス
オブジェクト指向
プログラミングでの
オブジェクトの型
オブジェクト指向プログラミング
プログラミングの
方式のことで、
プログラマはデータ型を
定義できるだけでなく
自動的にデータ型と
メソッドを関連付け
できる
アクティビティ
Androidにおける
アクティビティは
Androidアプリの画面に
相当するもの
ボタンやウェブページ
など表示されている
すべてのもののこと。
view
Androidのアプリを開発する
上で使う部品のことで、
トリガボタン・イメージボタン
チェックボックスなどのこと。
UI
ユーザインターフェースのこと。
Bind(バインド)
シンボルとデータを
関連させるため
または、データの一片と
他のものを関連させること。
以下は例。
・変数に値を入れる。
(変数の初期化)
・特定のEthernetポートと
ネットワークプロトコルを
関連付けする。
・Javaの変数のセット上に
XML文書を配置すること。
または、ほかの
プログラミング言語でも。
|