MapView 和 MapActivity 负责显示和操作地图的主要工作
1.基本对象
a.GeoPoint类:表示一对经度和纬度值
GeoPoint geoPoint = new GeoPoint((int)(1*1E6),(int)(-1*1E6));//纬度经度 geoPoint.getLongitudeE6();//经度 geoPoint.getLatitudeE6();//纬度 geoPoint.toString();//显示经纬度信息字符,例如:28418971,-81581436
b.mapView类:主要用于显示map
mapView.setBuiltInZoomControls(true); // getZoomControls() deprecated mapView.getController().zoomIn();//放大一层 mapView.getController().zoomOut();//缩小一层 mapView.setSatellite(true);//卫星模式 mapView.setTraffic(true);//交通模式 mapView.setSatellite(false);//关闭其他模式就是normal模式 mapView.setTraffic(false); mapView.postInvalidateDelayed(2000);//mapView内部使用线程获取数据来显示交通线,这里是设置线程延时 mapView.setClickable(false);//这样就不能左右移动地图
mapView.getOverlays().add(Overlays);//添加图层
mapView.postInvalidate();//显示图层
c.自定义ItemizedOverlay类:主要用于绘制和管理一系列OverlayItem在地图添加层Overlay上
class InterestingLocations extends ItemizedOverlay {
//代表地图上标记的对象数组
private ArrayList<OverlayItem> locations = new ArrayList<OverlayItem>();
//构造函数传入默认图片
public InterestingLocations(Drawable marker){
super(marker);
populate();//此方法用于缓存locations数组中的OverlayItem }
//shadow是设置阴影
public void draw(Canvas canvas, MapView mapview, boolean shadow){super.draw(canvas, mapview, Shadow);}
//返回地图对应的OverlayItem项
protected OverlayItem createItem(int i){return overlayItem;}
//告诉地图数据size
public int size(){return size;}
//点击事件响应
public boolean onTap(GeoPoint arg0, MapView arg1){return super.onTap(arg0, arg1);}
protected boolean onTap(int index){return super.onTap(index);}
}
d.OverlayItem类:表示地图上的单个标记信息
getPoint()//以GeoPoint的方式返回这个overlay的经纬度 getSnippet()//返回这个overlay的文字片段 getTitle()//返回这个overlay的标题文本
e.自定义MyLocationOverlay类:主要用于更新和显示设备位置
public class MyCustomLocationOverlay extends MyLocationOverlay { MapView mMapView = null; public MyCustomLocationOverlay(Context ctx, MapView mapView) { super(ctx, mapView); mMapView = mapView; } //更新位置时调用 public void onLocationChanged(Location loc) { super.onLocationChanged(loc); GeoPoint newPt = new GeoPoint((int) (loc.getLatitude()*1E6), (int) (loc.getLongitude()*1E6)); Log.v("MyCustomLocationOverlay", "Got new location: " + newPt); mMapView.getController().animateTo(newPt); } }
MyCustomLocationOverlay whereAmI = new MyCustomLocationOverlay(MapActivity.this,mapView);
whereAmI.enableMyLocation();//打开定位whereAmI.disableMyLocation();//关闭定位whereAmI.runOnFirstFix(new Runnable(){public void run(){
//拥有位置信息后立即运行}
});whereAmI.isMyLocationEnabled();//是否在地图上显示了位置
2.基本使用
a.配置google maps库与相关权限
<?xml version="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.androidbook.mapview" android:versionCode="1" android:versionName="1.0"> <applicationandroid:icon="@drawable/icon"android:label="@string/app_name"> <uses-libraryandroid:name="com.google.android.maps" />//需要引用google地图库 <activity android:name=".MapViewDemoActivity" android:label="@string/app_name"> <intent-filter> <actionandroid:name="android.intent.action.MAIN" /> <categoryandroid:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permissionandroid:name="android.permission.INTERNET"/> //由于基础数据来自 google maps 所以需要添加访问英特网权限 <uses-sdk android:minSdkVersion="3" /> </manifest>
b.在布局文件中添加MapView
<?xml version="1.0"encoding="utf-8"?> <!-- This fileis /res/layout/mapview.xml --> <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.google.android.maps.MapViewandroid:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="wrap_content" android:clickable="true" android:apiKey="0orhFMieGnXevh9ejBKQbeFVGBhShvCGoL1O4yQ" //your map api keygoes here //about get mapapi key /> </RelativeLayout>
c.MapActivity
package com.androidbook.mapview;
import android.os.Bundle;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
public class MapViewDemoActivity extends MapActivity
{
private MapView mapView;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.mapview); mapView = (MapView)findViewById(R.id.mapview); /*启用默认地图缩放控件*/ mapView.setBuiltInZoomControls(true); // getZoomControls() deprecated
mapView.getController().zoomIn();//放大一层
mapView.getController().zoomOut();//缩小一层
mapView.setSatellite(true);//卫星模式
mapView.setTraffic(true);//交通模式
mapView.setSatellite(false);//关闭其他模式就是normal模式
mapView.setTraffic(false);
mapView.postInvalidateDelayed(2000);//mapView内部使用线程获取数据来显示交通线,这里是设置线程延时
mapView.setClickable(false);//这样就不能左右移动地图
} /** * @function 向地图服务器表明是否显示了任何路线信息,For accounting purposes * */ @Override protected boolean isRouteDisplayed() { return false; } /** * @function 向地图服务器表明是否显示了当前设备的位置,For accounting purposes * */ @Override protected boolean isLocationDisplayed() { // TODO Auto-generated method stub return super.isLocationDisplayed(); } }
d.使用覆盖图添加标记
//扩展ItemziedOverlay,ItemizedOverlay扩展了Overlay
//Overlay定义了覆盖图的契约
//ItemizedOverlay简化了一组标记位置显示的过程
class InterestingLocations extends ItemizedOverlay { private ArrayList<OverlayItem> locations = new ArrayList<OverlayItem>(); private GeoPoint center = null; Drawable drawable = null; public InterestingLocations(Drawable marker,Drawable marker2) { super(marker); //map api 需要知道原点位于Drawable的何处 drawable = boundCenter(marker2);//将图片的原点放在中心 drawable = boundCenterBottom(marker2);//将图片的原点放在底边中心 // create locations of interest GeoPoint disneyMagicKingdom = new GeoPoint((int)(28.418971*1000000),(int)(-81.581436*1000000)); GeoPoint disneySevenLagoon = new GeoPoint((int)(28.410067*1000000),(int)(-81.583699*1000000)); locations.add(new OverlayItem(disneySevenLagoon, "Seven Seas Lagoon", "Seven Seas Lagoon")); locations.add(new OverlayItem(disneyMagicKingdom, "Magic Kingdom", "Magic Kingdom")); populate(); //此方法用于缓存locations数组中的OverlayItem //通过size方法获取数组数量 //通过createItem方法访问自定义的locations数组返回OverlayItem对象缓存起来 } // We added this method to find the middle point of the cluster // Start each edge on its opposite side and move across with each point. // The top of the world is +90, the bottom -90, // the west edge is -180, the east +180
// 获取最大东西经和南北纬,计算所有经纬点的中点 public GeoPoint getCenterPt() { if(center == null) { int northEdge = -90000000; // i.e., -90E6 microdegrees int southEdge = 90000000; int eastEdge = -180000000; int westEdge = 180000000; Iterator<OverlayItem> iter = locations.iterator(); while(iter.hasNext()) { GeoPoint pt = iter.next().getPoint(); if(pt.getLatitudeE6() > northEdge) northEdge = pt.getLatitudeE6(); if(pt.getLatitudeE6() < southEdge) southEdge = pt.getLatitudeE6(); if(pt.getLongitudeE6() > eastEdge) eastEdge = pt.getLongitudeE6(); if(pt.getLongitudeE6() < westEdge) westEdge = pt.getLongitudeE6(); } center = new GeoPoint((int)((northEdge + southEdge)/2), (int)((westEdge + eastEdge)/2)); } return center; } boolean Shadow = false;//是否显示标记的影子 @Override public void draw(Canvas canvas, MapView mapview, boolean shadow) { // Here is where we can eliminate shadows by setting to false super.draw(canvas, mapview, this.Shadow); } /** * @function InterestingLocations通过此方法返回locations数组的元素 * */ @Override protected OverlayItem createItem(int i) { OverlayItem overlayItem = locations.get(i); if(i == 0)overlayItem.setMarker(drawable); return overlayItem; } /** * @function InterestingLocations通过此方法确定locations数组的元素数量 * */ @Override public int size() { return locations.size(); } }