天天看點

Android地圖開發中的地理編碼與地理反編碼

地理編碼(Geocoding)與地理反編碼(Reverse Geocoding)是地圖操作中的常見操作,前者表示通過街道位址請求空間坐标,後者表示通過空間坐标請求街道位址。通俗的說,二者就是街道位址與經緯度的轉換。舉例來說,前者就是輸入查詢"上海市楊浦區四平路1239号"得到(31.285207060526762, 121.50546412914991),而後者則表示這個反過程。

在實際的移動開發過程中,地圖相關的操作對于地理編碼與地理反編碼的使用都是十分普遍。幸運的是,Android的MapView控件中對于這兩者都進行了封裝,是以可以友善的利用Google Map Service進行二者查詢。下面将對開發過程做一個簡單介紹。

首先必須進行MapKey的申請,任何地圖的顯示都需要申請一個MapKey。具體的申請步驟可見

http://code.google.com/intl/zh-CN/android/maps-api-signup.html

然後可以建立一個基于Google APIs的程式,并且在AndroidManifest.xml中加入地圖API的支援。

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="net.learn2develop.GoogleMaps"

android:versionCode="1"

android:versionName="1.0.0">

<application android:icon="@drawable/icon" android:label="@string/app_name">

<uses-library android:name="com.google.android.maps" />

<activity android:name=".MapsActivity"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

<uses-permission android:name="android.permission.INTERNET" />

</manifest>

</xml> 

接着可以在主Layout檔案中加入對于地圖的顯示,這裡需要加入剛才申請的MapKey,否則地圖将無法正常顯示。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<com.google.android.maps.MapView

android:id="@+id/mapView"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:enabled="true"

android:clickable="true"

android:apiKey="MapKey"

/>

</RelativeLayout>

接着在主Activity的JAVA檔案進行修改,支援地圖顯示。

import com.google.android.maps.MapActivity;

import com.google.android.maps.MapView;

import android.os.Bundle;

public class MapsActivity extends MapActivity

{

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

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

mapView.setBuiltInZoomControls(true);

}

此時運作程式,地圖應該就可以正常顯示了,見下圖。

Android地圖開發中的地理編碼與地理反編碼

此時我們再向程式中加入地理編碼與地理反編碼的功能,其參考代碼如下。 

地理編碼:

Geocoder geoCoder = new Geocoder(this, Locale.getDefault());

try {

List<Address> addresses = geoCoder.getFromLocationName(

"上海市楊浦區四平路1239号", 5);

String add = "";

if (addresses.size() > 0) {

p = new GeoPoint(

(int) (addresses.get(0).getLatitude() * 1E6),

(int) (addresses.get(0).getLongitude() * 1E6));

mc.animateTo(p);

mapView.invalidate();

}

} catch (IOException e) {

e.printStackTrace();

}

地理反編碼,其中MapOverlay為地圖圖層上的疊加圖層,用于辨別的顯示以及點選事件的捕捉。

 class MapOverlay extends com.google.android.maps.Overlay

{

@Override

public boolean draw(Canvas canvas, MapView mapView,

boolean shadow, long when)

{

//...

}

@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());

Geocoder geoCoder = new Geocoder(

getBaseContext(), Locale.getDefault());

try {

List<Address> addresses = geoCoder.getFromLocation(

p.getLatitudeE6() / 1E6,

p.getLongitudeE6() / 1E6, 1);

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();

}

catch (IOException e) {

e.printStackTrace();

}

return true;

}

else

return false;

}

}

 最終實作結果如下圖所示,地理編碼,查詢“上海市楊浦區四平路1239号”,結果其實略有偏差。中國的位址與郵編比較混亂,是以結果有些地方無法做到完全準确。

Android地圖開發中的地理編碼與地理反編碼

地理反編碼

Android地圖開發中的地理編碼與地理反編碼

本文系“首屆 Google 暑期大學生部落格分享大賽——2010 Andriod 篇”參賽文章

繼續閱讀