android谷歌地图开发

j623511810

贡献于2013-03-12

字数:10274 关键词: Android开发 移动开发

3.1.2 程序功能的概述 用户界面为地图模式下的地图图层,界面最上方标明实时卫星数据,包括用户当前所在位置的经度、纬度、海拔高度和用户的移动速度以及卫星的精度、数量等信息。界面正中央的小点则指明了用户当前所在的位置。 界面下方为Menu菜单,实现本程序的主要功能,包括图层分类,图层清除和程序退出等功能。图层分类可显示用户当前所在位置周边的娱乐、购物、交通等信息,使得用户对其周边有所了解,方便出行。点击Menu菜单的相应按钮,则会在地图图层上叠加出娱乐、购物、交通等图标。点击这些图标,则会弹出对话框显示详细信息以供用户查看。 当不再需要显示以上图层时,可选择清除图层按钮,则界面还原为初始的地图图层。点击退出程序按钮,程序将退出到Android主界面。 如图3-2所示,显示了软件的运行流程。 否 是 开始 显示地图图层 用户位置有无改变? 采集更新的位置信息 定位用户位置 侦听用户点击事件 判断命令类型 显示分类图层 图层清除 退出 结束 图3-2 软件运行流程图 3.2 功能模块实现的基本原理 3.2.1 GPS位置信息的获取 Android系统使应用程序可以利用android.location类来使用移动设备提供的GPS定位服务,获取位置的相关信息,包括如下四个类或接口: l LocationManager类 l LocationListener接口 l Location类 l LocationProvider类 其中LocationManager系统服务是GPS定位服务的中心组件,它提供了API来确定位置和方位。 GPS卫星数据的获取可通过如下代码实现: mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE); mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,mLocationListener) ; public LocationListener mLocationListener = new LocationListener() { public void onlocationChanged(Location location){ int lat,lon; lat = location.getLatitude(); lon = location.getLongitude(); } public void onProviderDisabled(String provider) { } public void onProviderEnabled(String provider) { } public void onStatusChanged(String provider, int status, Bundle extras) { } } 代码说明如下: 1.调用getSystemService(Context.LOCATION_SERVICE)方法可实例化一个LocationManager类对象。 2.调用requestLocationUpdates(String, long,float,LocatonListener)方法可以获取GPS地理位置的更新数据。其中,第1个参数是定位的方法,GPS定位或网络定位;第2个参数是产生位置改变事件的时间间隔,单位为微秒; 第3个参数是距离条件,单位是米;第4个参数是LocationListener接口,当GPS位置更新时,可通过此接口取得数据。 3.当GPS位置有所改变时,LocationListener接口用来接收来自Location- Manager的通知,同时调用onLocationChanged(Location location)方法,根据location类(getLatitude()、getLongitude()、getAccuracy()等)的参数可读出GPS位置详细信息。 4.onProviderDisabled()在用户禁用具有定位功能的硬件时被调用;onPro-viderEnabled()在用户启用具有定位功能的硬件时被调用;onStatusChang-ed()在提供定位功能的硬件的状态改变时被调用,如从不可获取位置信息状态到可以获取位置信息的状态,反之亦然。 5.为了使GPS定位功能生效,还需要在AndroidManifest.xml文件中加入用户许可,实现代码如下: 3.2.2 Google地图服务 获取Google地图服务首先要向Google申请一组经过验证的“地图密钥”(Map API Key),然后使用MapView(com.google.android.maps.MapView)就可以将Google地图嵌入到Android应用程序中,从而正常使用Google的地图服务。取得Maps API Key授权步骤: 1.产生keystore并取得认证指纹(MD5)码 利用keytool.exe读出MD5码,在C:\ProgramFiles\Java\jre1.5.0_06\bin目录下执行命令: >keytool –list –keystore ” C:\Documents and settings\adminstrator\.android\debug.keystore”,如图3-3,可得到认证指纹(MD5)码。 图3-3 取得认证指纹(MD5)码 2.经Google网站的签署取得Maps API Key授权码 进入“Android Maps API Key Signup”,网址为: http://code.google.com/intl/ja/android/maps-api-signup.html,在“My certificate’s MD5 fingerprint:”字段输入获取到的认证指纹(MD5)码,单击“Generate API Key”按钮后,弹出如图3-4的页面,显示得到的Maps API Key 。 图3-4 Map API Key 在/res/layout/main.xml文件内建立标签,并设置Maps API Key,如图3-5所示, 图3-5建立标签 由于获取Google地图是需要使用互联网的,所以在运行前还需要在Andro-idManifest.xml文件中,添加允许访问互联网的许可,即分别建立标签 标签 完成上述准备工作后,就可以从Google地图服务系统获得地图了。 3.2.3 地图叠层技术的基本原理 通过在地图上添加覆盖层,可以在指定的位置加添加注解、绘制图像或处理鼠标点击事件等。Google地图上可以加入多个覆盖层,所有覆盖层均都在地图图层之上,每个覆盖层均可以对用户的点击事件做出响应。 要实现地图上覆盖对象,首先要实现一个ItemizedOverlay类,它可以管理一套覆盖项目功能。以下是创建ItemizedOverlay类的基本代码: public class MyItemizedOverlay extends ItemizedOverlay { private ArrayList mOverlays = new ArrayList(); public MyItemizedOverlay(Drawable defaultMarker) { super(boundCenterBottom(defaultMarker)); // TODO Auto-generated constructor stub } public void addOverlay(OverlayItem overlay) { mOverlays.add(overlay); populate(); } @Override protected OverlayItem createItem(int i) { return mOverlays.get(i); } @Override public int size() { return mOverlays.size(); } } 代码说明如下: 1. 首行代码的作用为建立一个OverlayItem ArrayList数组,这个数组可以放置所有要贴在地图上的标记对象。 2. 为使Drawable标记可以贴上,必须界定它的范围。地图上的标记希望贴在地图底部中心点,使用boundCenterBottom()方法来处理。 3. addOverlay方法中的代码使得一个新的OverlayItem加入到ArratList数组上。每一次增加一个新的OverlayItem,一定要调用populate()方法,它会读出每一个OverlayItem并准备它可以被贴上。 4. 为了读出每一个OverlayItem会调用populate()方法,必须定义creatItem()请求,确认是从ArrayList数组读出。 5. 还需要一个覆盖size()方法,在处理size()方法的返回时加入如下代码: return mOverlays.size(); 以上为实现ItemizedOverlay类的基本程序。实现了一个ItemizedOverlay类后,就为后续的地图贴图工作打下了基础。 4 软件的详细分析与设计 4.1 地图图层的显示 按照3.2.2小结获得Maps API Key授权码,并对相关文件进行配制后,就可以使用Google的地图服务了,本节将论述产生地图图层的详尽方案。 以下代码实现了Google地图图层的显示, mapView = (MapView) findViewById(R.id.mv2); mapView.setSatellite(false); mapView.setTraffic(false); mapView.setBuiltInZoomControls(true); int maxZoom = mapView.getMaxZoomLevel(); int initZoom = (int)(0.90*(double)maxZoom); mapControl = mapView.getController(); mapControl.setZoom(initZoom); GeoPoint newPoint = new GeoPoint((int)(lat*1e6),(int)(lon*1e6)); mapControl.animateTo(newPoint); 说明如下: 1. MapView为地图的显示控件,可以设置不同的显示模式,例如卫星模式、街道模式或交通模式。本例通过mapView.setSatellite(false);mapView.setTr-affic(false);两条语句将所显示的图层设置为地图模式。 2. MapController则是MapView的控制器,可以控制MapView的显示中心和缩放级别等功能 。程序中的缩放级别为最大级别的0.9倍。 3. mapControl.animateTo(newPoint);使得地图以用户当前所在位置的经纬度为中心显示。 运行结果如图4-1所示: 图4-1 地图图层的显示 4.2 卫星数据的获取与显示 4.2.1获取卫星数据 当用户移动致使当前位置有所改变时,软件应能侦测到这一变化,并随时更新卫星数据。侦测这种变化的方法已在3.2.1小结中讨论过了,本节将研究侦测到变化后,如何读取更新的卫星数据。 当用户的位置改变时,函数onLocationChanged(Location location)会调用 centerOnLocation()函数,获取经度、纬度等卫星信息。 centerOnlocation()函数代码如下: private void centerOnLocation() { loc = locman.getLastKnownLocation(provider); if(loc != null){ lat = loc.getLatitude()-0.002; lon = loc.getLongitude()+0.003; GeoPoint newPoint = new GeoPoint((int)(lat*1e6),(int)(lon*1e6)); mapControl.animateTo(newPoint); getSatelliteData(); } if(displayOverlay != null){ displayOverlay.putSatStuff(lat, lon, satAccuracy, bearing, altitude, speed, currentProvider, numberSats); } } public void getSatelliteData(){ if(loc != null){ locBundle = loc.getExtras(); if(locBundle != null){ numberSats = locBundle.getInt("satellites",-1); } satAccuracy = loc.getAccuracy(); bearing = loc.getBearing(); altitude = loc.getAltitude(); speed = loc.getSpeed(); } } 说明如下: 1.getLastKnowLocation()方法可以获取当前的位置信息,在其返回的loc对象中包含了可以确定位置的信息,如经度、纬度等。需要说明的是,在手机上实 际测试时,会发现定位位置与实际位置将出现偏差,因此要对获取到的数据进行修正以消除这一偏差。 2. mapControl.animateTo(newPoint);语句以获取到的最新经纬度为中心,显示地图图层。 3.调用getSatelliteData()函数可以得到卫星精度、运动方位角,运动速度及海拔高度等信息。 4. displayOverlay.java程序的putSatStuff()函数用来接收获取到的卫星数据,以便将其显示在用户的手机屏幕上。 4.2.2 卫星数据的显示 取得到卫星数据后,接下来要解决的问题则是怎样将数据显示到手机屏幕上去。程序displayOverlay.java将完成此项功能,它通过使用Canvas(画布)类来显示当前位置信息。Canvas类主要实现屏幕的绘制过程,其中包含了很多实用的方法,比如绘制一条路径、区域、贴图、画点、画线、渲染文本等。 如前一小节所述,函数putSatStuff()用来接收得到的卫星数据,而显示这些数据则通过如下代码实现: public void draw(Canvas canvas, MapView mapview, boolean shadow) { super.draw(canvas, mapview, shadow); if(showData){ paint = new Paint(); paint.setAntiAlias(true); paint.setARGB(80,255,255,255); canvas.drawRect(0,0,350,33,paint); paint.setTextSize(11); paint.setARGB(180, 0, 0, 0); canvas.drawText("Lat = "+lat+" Long = "+lon+" Alt = "+(int)altitude+" m", 8, 14, paint); canvas.drawText("Sat = "+numberSats+" Accur = "+(int)satAccuracy+" m" +" speed = "+(int)speed+" m/s bearing = "+(int)bearing+" deg", 8, 27, paint); } } 代码说明如下: 1.首先通过paint = new Paint();语句实例化一个Paint类变量。 2.paint.setAntiAlias()函数设置了Paint类对象具有平滑锯齿状功能; paint.setARGB()函数设置了Paint对象的颜色; paint.setTextSize()函数设置字体大小。 3.canvas.drawRect()函数使得绘制区域为一矩形区域,并规定其范围(左上顶点与右下顶点的坐标),canvas.drawText()函数则将卫星数据显示于画布之上。 运行结果如图4-2所示,屏幕最上方显示了当前得到的卫星信息: 图4-2 卫星数据的显示 4.3 地图叠层技术的实现 4.3.1 用SQLite Databases处理地图信息 Android操作系统采用标准SQLite数据库,提供管理数据库相关的API。SQLite数据库与常用的PostgreSQL和MySQL一样,是属于RDBMS的一种,但不同的是SQLite数据库是可以用在本地应用程序的轻量级数据库,并不提供在服务器上使用。SQLite常用到以下几种类: l SQLiteOpenHelper类:负责创建与打开数据库和版本管理,建立此类时,同时需要建立三个回调(Call Back)方法,分别是创建onCreate(SQLiteData-base)、更新onUpgrade(SQLiteDatabase,int,int)和打开onOpen(SQLiteD-atabase)。 l SQLiteDataBase类:管理数据库本体,提供添加(Insert)、更新(Update)、删除(Delete)、检索(Query)、执行SQL指令和其他管理数据库的功能。在同一应用程序里数据库名称必须是唯一的。 l SQLiteCursor类:检索(Query)数据库时,指示查询结果的初始位置。 以下将详细介绍如何创建一个SQLite数据库并检索地图信息。 l ContentValues类:用来存储和保持表中的某行相关数据。 首先要定义一个接口MapSchema,包括数据库的表名称和字段名称, public interface MapSchema { String TABLE_NAME = "MapInfo"; String ID = "_id"; String TITLE = "Title"; String NAME = "name"; String LONGITUDE= "longitude"; String LATITUDE = "latitude"; String DETAILINFO1 = "detailinfo1"; String DETAILINFO2 = "detailinfo2"; } 接着通过SQLiteOpenHelper类来建立数据库MapInfoDB,并使用Call Back方法onCreate()函数来建立表MapInfo, public static class DBConnection extends SQLiteOpenHelper { private static final String DATABASE_NAME = "MapInfoDB"; private static final int DATABASE_VERSION = 1; private DBConnection(Context ctx) { super(ctx, DATABASE_NAME, null, DATABASE_VERSION); } public void onCreate(SQLiteDatabase db) { String sql = "CREATE TABLE " + MapSchema.TABLE_NAME + " (" + MapSchema.ID + " INTEGER primary key autoincrement, " + MapSchema. TITLE + " text not null, " + MapSchema.NAME + " text not null, " + MapSchema.LONGITUDE + " text not null, " + MapSchema.LATITUDE+ " text not null, " + MapSchema.DETAILINFO1+ " text not null, " + MapSchema.DETAILINFO2+ " text not null "+ ");"; db.execSQL(sql); } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } } 建立好数据库和表后,可通过定义SQLiteDataBase类变量db,来添加和检索地图信息。首先定义SQLiteDataBase类变量db,db数据库为可写入的, helper = new DBConnection(this); SQLiteDatabase db = helper.getWritableDatabase(); 插入一行数据到数据库中, db.insert(MapSchema.TABLE_NAME, null, values); 从数据库中检索一行数据, Cursor c = db.query(MapSchema.TABLE_NAME, FROM, null, null, null, null, null); 4.3.2 将分类图层覆盖于地图图层上 在3.2.3节通过程序MyItemizedOverlay.java实现了一个ItemizedOverlay类后,我们将研究怎样把贴图对象覆盖于地图图层上。 首先实例化一个List类对象mapOverlays作为地图图层,并从“/res/drawable”文件里取得图标knifefork_small.PNG, mapOverlays = mapView.getOverlays(); drawable = this.getResources().getDrawable(R.drawable.knifefork_small); 其次,实例化一个MyItemizedOverlay类对象itemizedOverlay来放置标记, itemizedOverlay = new MyItemizedOverlay(drawable,this,title); 实例化一个OverlayItem类对象overlayitem来存放贴图信息,并将贴图信息加入到itemizedOverlay对象上, OverlayItem overlayitem = new OverlayItem(new GeoPoint(Latitude,Longitude),name,text); itemizedOverlay.addOverlay(overlayitem); 最后,将贴图覆盖于地图图层上, mapOverlays.add(itemizedOverlay); 运行结果如图4-3所示, 图4-3 分类图层的实现 4.3.3 处理用户点击事件并显示地图信息 在MyItemizedOverlay.java程序中建立onTap()函数,用来实现对用户点击事件的处理并显示地图信息。代码如下: protected boolean onTap(int i){ GeoPoint gpoint = myOverlays.get(i).getPoint(); double lat = gpoint.getLatitudeE6()/1e6; double lon = gpoint.getLongitudeE6()/1e6; String text = "Title: "+myOverlays.get(i).getTitle(); text += "\nCoordinates: \nLat = "+lat+" Lon = "+lon+""; text += "\nText: "+myOverlays.get(i).getSnippet(); Builder builder = new Builder(context); builder.setTitle(title); builder.setMessage(text); builder.setPositiveButton("关闭", null); builder.show(); return(true); } 本例通过定义Builder类变量builder来创建弹出窗口,显示地图信息,实现效果如图4-4所示, 图4-4 地图信息的显示 5 软件的测试与运行 通过Android虚拟设备AVD可测试软件的运行情况,如图5-1为软件主界面, 图 5-1 软件主界面 界面上方显示出了用户当前的位置信息,包括经纬度、海拔高度、速度等。正中蓝点则标明了用户当前位置。Menu菜单对用户当前所在的周边作以分类,包括餐饮、购物、宾馆及出行等,此外还有清除图层及退出等功能。 选择Menu菜单上的分类,如餐饮,则程序将会查询用户周边的餐馆并标记在地图图层上,如图5-2所示, 图5-2显示贴图标记 点击贴图标签,则弹出相应的对话框,显示标记对象的具体信息,如图5-3所示, 图5-3 显示地图信息 在Menu菜单上选择清除图层,则贴图标签将被移除,如图5-4所示, 图5-4 清除图层 选择退出按钮,则程序将退至Android主界面,如图5-5所示, 图5-5 退出程序 通过以上测试表明,程序能够正常运行并实现了预期的目标。

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享文档获得金币 ]
0 人已下载

下载文档

相关文档