【转】构建Android平台Google Map应用
http://www.moandroid.com/?p=1360
Android 的新版本提供了的功能,通過這段視頻,大家可以先簡單了解下:
 
Android 提供的地圖(Map)功能可能是廣大開發者非常關心的一個部分。到目前為止,開發內嵌式地圖應用的軟件是相當的困難,而且往往還需要支付很高的地圖廠商的版權費
用,加之手機上GPS功能的不完善,導致很多可以基于當前位置來開發功能的軟件少之又少。就算是幾個比較著名的LBS(Location-Based Service)軟件,使用者也是寥寥。Android的出現打破這一格局,提供給普通開發者非常靈活的地圖展示與控制功能。本文根據AndroidAPI 以及筆者親身體驗,給讀者簡單介紹下Android里面的MapView和MapActivity,通過簡單的代碼例子,期望給大家有所啟示及探討。
MapView是個展示地圖的視圖。它可以獲取鍵盤事件(onKeyDown 和onKeyUp) 來支持地圖移動(東南西北)和縮放功能。它還支持多層Overlay,可以在地圖上面畫坐標,寫地名,畫圖片等等。MapView只能通過MapActivity來建立。因為MapView需要在后臺使用文件系統和網絡,所有這些線程需要在Activity的生命周期中被控制。
Android 是通過布局(layout)來定義UI(用戶界面)的。一般視圖(View)可以直接在布局的xml 里面申明。但MapView不行,不知道是Google 故意的,還是當前API 沒有實現。不過可以以自定義類來申明來實現:
<view id=”@+id/mapview”
class=”com.google.android.maps.MapView”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:layout_weight=”1″ />
這樣你可以添加你自己需要的其他視圖,比如一個工具欄,或者一個EditText 來輸入地址。基于MapView展示地圖的視圖
在詳細進入coding 之前, 我們先介紹下經緯度(geocode)。
經度是地球上一個地點離一根被稱為本初子午線的南北方向走線以東或以西的度數。本初子午線的經度是0°,地球上其它地點的經度是向東到180°或向西到180°緯度是指某點與地球球心的連線和地球赤道面所成的線面角,其數值在0至90度之間。位于赤道以北的點的緯度叫北緯,記為N,位于赤道以南的點的緯度稱南緯,記為S。基于緯度 phi (φ) 和經度 lambda (λ)的地圖模型
使用geocode,地球上任何一個地點都可以用精度+維度來代表。當然,geocode涉及的范圍很廣,本身就是一個很大的課題,以后有機會我們再講。
回到Android,com.google.android.maps.Point 這個類代表了一個地點的經緯度:Point(int latitudeE6, int longitudeE6),E6 是微度(microdegrees),就是度數再乘以1000000。目前如果要指定地圖地點,一定要傳遞一個Point的類到地圖中:
// 紐約帝國大廈的經度和緯度
Point p = new Point(40.748356*1000000,-73.984621*1000000);
// 獲取當前地圖的控制器
MapController mc = mapview.getController();
// 地圖中心移動到指定的點上
mc.animateTo(p);
// 放大到21級(level),level范圍1-21
mc.zoomTo(21);
以拉斐特廣場為例的地圖效果
你也可以使用zoomTo(int)來縮放到你需要的級別,比如獲取當前縮放等級并再縮放一級(zoom out 1 morelevel):mc.zoomTo(mapview.getZoomLevel()-1)
經過縮放以后的地圖效果
mapview還提供了衛星圖、路況圖、街道圖的功能:<
- 獲取衛星地圖:mapview.setSatellite(true);
- 實時路況衛星圖:mapview.setTraffic(true);
- 獲取街道圖片:mapview.setStreetView(true);
大家可以清楚的看到,使用Android 的地圖功能是非常的簡單然后又很強大。那如何拿到一個地址的經度和緯度呢?有很多在線的服務可以使用。筆者比較喜歡Yahoo的Geo API :http://developer.yahoo.com/maps/rest/V1/geocode.html。Yahoo 的用戶可以去免費申請一個appid,就可以使用所有Yahoo 提供的服務了。最簡單的獲取geocode的請求就是提供location的值:
http://local.yahooapis.com/MapsService/V1/geocode?appid你的appid&location=350+5th+Ave,+New+York,+NY+10118
在返回的XML中,我們只關心Latitude和Longitude的值:
<Latitude>40.748396</Latitude>
<Longitude>-73.984703</Longitude>
在Android 中,可以通過包里面org.xml.sax 包來分析xml,也可以通過substring來做。如果你需要在地圖上畫地標、坐標、圖片等等,那就需要定義你自己的Overlay 類:
public class MyOverlay extends Overlay {
// com.google.android.maps.Overlay
然后override draw(Canvas canvas, PixelCalculatorcalculator, boolean shadow)這個方法。比如你想畫個圖標在當前的點上:
super.draw(canvas, calculator, shadow)
// 下面兩行把當前的點轉換成地圖上的xy坐標
int[] xyCoordinates = new int[2];
calculator.getPointXY(p, xyCoordinates);
// 在坐標這點畫圖(bitmap是Bitmap類,可以讀取圖片資源
//(drawable resources)來生成)
canvas.drawBitmap(bitmap, xyCoordinates[0],xyCoordinates[1], new Paint());
// 在mapview中獲得OverlayController:
OverlayController oc = myMapView.createOverlayController();
MyOverlay mo = new MyOverlay();
// 加入到Overlay控制器就可以了
oc.add(om, true);
當然,你也可以在draw里面寫字,畫幾何圖形等等,這里就不一一敘述。
最后,我們看看如何獲取鍵盤事件:
public boolean onKeyDown(View v, int keyCode,KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_I)
{
// 放大
mapview.getController().zoomTo(myMapView.getZoomLevel() + 1);
return true;
}
else if (keyCode == KeyEvent.KEYCODE_O)
{
// 縮小
mapview.getController().zoomTo(myMapView.getZoomLevel() – 1);
return true;
}
else if (keyCode == KeyEvent.KEYCODE_S)
{
// 轉換到衛星地圖
mapview.toggleSatellite();
return true;
}
else if (keyCode == KeyEvent.KEYCODE_T)
{
// 轉換到路況圖
mapview.toggleTraffic();
return true;
}
return false;
}
有興趣的讀者,可以去andoridcn 看看筆者發表的minigoogle map(包含所有source)。如果有機會,可以繼續深入關于GPS的操作,如何在沒有GPS硬件的情況下估計當前GPS位置,以及使用kml,nmea來模擬GPS路線等等。
總結和技術展望
Android本身設計和系統的實現是一個極其復雜的工作。就發稿時的m3-rc22a 版來看,系統還有需要充實的地方,相信在明年全面發布,真機發布之時,Android會變得更加強壯和易用。感謝Androidcn 社區的 lordhong( 吳宏) 和 風雷( 李錕) 對本文成稿的貢獻。
閱讀后記
更多關于Android 中如何使用Google Map的文章,請閱讀Maps External Library。
轉載于:https://www.cnblogs.com/justinprc/archive/2010/10/12/1848973.html
總結
以上是生活随笔為你收集整理的【转】构建Android平台Google Map应用的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 不断电系统的容量如何计算?
- 下一篇: 二叉查找树转换成有序的双向链表
