这段时间开发的时候用到了高德地图,对高德地图开发有心得体会,如今分享给大家。对我开发过百度地图的我来说,整体来说高德地图Demo,没有百度解说的具体
个人更偏向于使用百度地图,可是没办发,项目须要使用高德地图,我开发的是定位,更具经纬度加入标记。标记点击事件,以及路线规划废话不多说,上代代码
那么首先导入高德给的jar,包,我开发的是2d地图,
这个包结构图,高德题图api也提供了步骤,就不多说了
以下加入权限,设置key
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" />
package com.yakj.gaodedemo; import android.app.Activity; import android.graphics.Color; import android.location.Location; import android.os.Bundle; import android.view.View; import android.widget.RelativeLayout; import android.widget.Toast; import com.amap.api.location.AMapLocation; import com.amap.api.location.AMapLocationListener; import com.amap.api.location.LocationManagerProxy; import com.amap.api.location.LocationProviderProxy; import com.amap.api.maps2d.AMap; import com.amap.api.maps2d.AMap.OnMapClickListener; import com.amap.api.maps2d.AMap.OnMarkerClickListener; import com.amap.api.maps2d.CameraUpdateFactory; import com.amap.api.maps2d.LocationSource; import com.amap.api.maps2d.MapView; import com.amap.api.maps2d.model.BitmapDescriptor; import com.amap.api.maps2d.model.BitmapDescriptorFactory; import com.amap.api.maps2d.model.LatLng; import com.amap.api.maps2d.model.Marker; import com.amap.api.maps2d.model.MarkerOptions; import com.amap.api.maps2d.model.MyLocationStyle; import com.yakj.view.StationInfoPopupWindow; public class MainActivity extends Activity implements LocationSource, AMapLocationListener, OnMarkerClickListener, OnMapClickListener { /** * 基础地图 */ private MapView mapView; private AMap aMap; /** * 定位 */ private LocationManagerProxy mAMapLocationManager; /** * 定位监听 */ private OnLocationChangedListener mListener; /** * 加入的覆盖物标志 */ private Marker currentMarker; /** * 点击标记物弹出popWindow信息 */ private StationInfoPopupWindow popWindow; /** * 展示popWindow布局 */ private RelativeLayout mpop; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mapView = (MapView) findViewById(R.id.map); mapView.onCreate(savedInstanceState);// 必需要写 mpop = (RelativeLayout) findViewById(R.id.rent_map_pop); init(); } /** * 初始化AMap对象 */ private void init() { if (aMap == null) { aMap = mapView.getMap(); setUpMap(); } } /** * 设置地图样式 */ private void setUpMap() { // 自己定义系统定位蓝点 MyLocationStyle myLocationStyle = new MyLocationStyle(); // 自己定义定位蓝点图标 myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.location_marker)); // 自己定义精度范围的圆形边框颜色 myLocationStyle.strokeColor(Color.BLUE); myLocationStyle.radiusFillColor(Color.TRANSPARENT); // 自己定义精度范围的圆形边框宽度 myLocationStyle.strokeWidth(2); // 将自己定义的 myLocationStyle 对象加入到地图上 aMap.setMyLocationStyle(myLocationStyle); aMap.setLocationSource(this);// 设置定位监听 aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位button是否显示 aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false // 设置定位的类型为定位模式:定位(AMap.LOCATION_TYPE_LOCATE)、尾随(AMap.LOCATION_TYPE_MAP_FOLLOW) // 地图依据面向方向旋转(AMap.LOCATION_TYPE_MAP_ROTATE)三种模式 // aMap.setMyLocationType(AMap.MAP_TYPE_SATELLITE); // 设置地图可视缩放大小 aMap.moveCamera(CameraUpdateFactory.zoomTo(14)); aMap.getUiSettings().setCompassEnabled(true);// 设置指南针 aMap.getUiSettings().setScaleControlsEnabled(true);// 设置比例尺 LatLng latLng = new LatLng(31.383755, 118.438321); MarkerOptions otMarkerOptions = new MarkerOptions(); otMarkerOptions.position(latLng); otMarkerOptions.visible(true);//设置可见 otMarkerOptions.title("芜湖市").snippet("芜湖市:31.383755, 118.438321");//里面的内容自己定义 otMarkerOptions.draggable(true); //以下这个是标记上面这个经纬度在地图的位置是 // otMarkerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_mark)); //以下这个是自己定义的标记图标用法 otMarkerOptions.icon(ImageNormal(0)); aMap.addMarker(otMarkerOptions); aMap.setOnMarkerClickListener(this); aMap.setOnMapClickListener(this); } /** * 自己定义标记物的图片(未选中状态) * @param i * @return */ private BitmapDescriptor ImageNormal(int i) { //这个布局是自己定义的。这面的内容相同自己主动,在poi_view 这个xml文件中有一个有一张图片。有一个TextView //被我删除了,这个TextView,有需要的网友能够自己设置。这个TextView里面能够写数字。或者ABCD...更具需求 //各位自由发挥 View view = null; view = getLayoutInflater().inflate(R.layout.poi_view, null); RelativeLayout ly = (RelativeLayout) view.findViewById(R.id.view_mark); // TextView tv = (TextView) view.findViewById(R.id.poi_mark_img); // tv.setText(i + ""); // tv.setPadding(0, 0, 0, 25); // tv.setBackgroundResource(R.drawable.poi_mark_normal); BitmapDescriptor bitmap = BitmapDescriptorFactory.fromView(view); return bitmap; } /** * 自己定义标记物图片(选中状态) * @param i * @return */ private BitmapDescriptor ImagePress(int i) { //用法同上 View view = null; view = getLayoutInflater().inflate(R.layout.poi_view, null); // TextView tv = (TextView) view.findViewById(R.id.poi_mark_img); // tv.setText(i + ""); // tv.setPadding(0, 0, 0, 25); // tv.setBackgroundResource(R.drawable.poi_mark_press); BitmapDescriptor bitmap = BitmapDescriptorFactory.fromView(view); return bitmap; } /** * 方法必须重写 */ @Override protected void onResume() { super.onResume(); mapView.onResume(); } /** * 方法必须重写 */ @Override protected void onPause() { super.onPause(); mapView.onPause(); deactivate(); } /** * 方法必须重写 */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } /** * 方法必须重写 */ @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); if (popWindow != null) {//隐藏popwindow popWindow.dismiss(); } } /** * 激活定位 */ @Override public void activate(OnLocationChangedListener listener) { mListener = listener; if (mAMapLocationManager == null) { mAMapLocationManager = LocationManagerProxy.getInstance(this); // 此方法为每隔固定时间会发起一次定位请求。为了降低电量消耗或网络流量消耗, // 注意设置合适的定位时间的间隔,而且在合适时间调用removeUpdates()方法来取消定位请求 // 在定位结束后。在合适的生命周期调用destroy()方法 // 当中假设间隔时间为-1。则定位仅仅定一次 mAMapLocationManager.requestLocationData(LocationProviderProxy.AMapNetwork, 60 * 1000, 10, this); } } /** * 停止定位 */ @Override public void deactivate() { mListener = null; if (mAMapLocationManager != null) { mAMapLocationManager.removeUpdates(this); mAMapLocationManager.destroy(); } mAMapLocationManager = null; } @Override public void onLocationChanged(Location location) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } /** * 定位成功后回调函数 */ @Override public void onLocationChanged(AMapLocation amapLocation) { if (mListener != null && amapLocation != null) { if (amapLocation.getAMapException().getErrorCode() == 0) { mListener.onLocationChanged(amapLocation);// 显示系统小蓝点 } } } @Override public boolean onMarkerClick(Marker marker) { currentMarker = marker; Toast.makeText(this, "你点击了的是" + marker.getTitle(), 10000).show(); if(popWindow !=null){//先把原来的给隐藏起来 popWindow.dismiss(); } popWindow = new StationInfoPopupWindow(this); popWindow.showAsDropDown(mpop); return false; } /** * 点击地图其它地方时,隐藏InfoWindow,和popWindow弹出框 */ @Override public void onMapClick(LatLng latLng) { if (currentMarker != null) { currentMarker.hideInfoWindow();//隐藏InfoWindow框 popWindow.dismiss(); } } }
图上看到的那个就是我自己定义的图片,这个有些时候都是须要自定的,高德给的原生的不应符合我们的需求
当点击那个图上那个标记时就出现例如以下界面。
然后就是路劲规划了,点击到这里去button就跳转到路径规划的界面
以下吧popWidow代码贴出来
package com.yakj.view; import android.content.Context; import android.content.Intent; import android.graphics.drawable.BitmapDrawable; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.PopupWindow; import android.widget.PopupWindow.OnDismissListener; import com.yakj.gaodedemo.R; import com.yakj.gaodedemo.RouteActivity; public class StationInfoPopupWindow implements View.OnClickListener { private Context context; private PopupWindow popupWindow; //到这里去button private Button goBtn; public StationInfoPopupWindow(final Context context) { this.context = context; View view = LayoutInflater.from(context).inflate(R.layout.view_map_popup_window, null); popupWindow = new PopupWindow(view, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); // 这个是为了点击“返回Back”也能使其消失,而且并不会影响你的背景(非常奇妙的) popupWindow.setBackgroundDrawable(new BitmapDrawable(context.getResources())); goBtn = (Button) view.findViewById(R.id.go_to_hotel_btn); goBtn.setOnClickListener(this); } // 下拉式 弹出 pop菜单 parent 右下角 public void showAsDropDown(View parent) { // 保证尺寸是依据屏幕像素密度来的 popupWindow.showAtLocation(parent, Gravity.BOTTOM, 0, 0); // 使其聚集 popupWindow.setFocusable(false); // 设置同意在外点击消失 popupWindow.setOutsideTouchable(false); // 设置动画 popupWindow.setAnimationStyle(R.style.PopupWindowAnimStyle); // 刷新状态 popupWindow.update(); } public void setDismissListener(OnDismissListener onDismissListener) { popupWindow.setOnDismissListener(onDismissListener); } // 隐藏菜单 public void dismiss() { popupWindow.dismiss(); } // 是否显示 public boolean isShowing() { return popupWindow.isShowing(); } @Override public void onClick(View v) { if (v == goBtn) {
//这里跳转到路径规划界面 Intent intent = new Intent(context, RouteActivity.class); context.startActivity(intent); } } }
这里有些效果的图片贴不出来,我在博客最后会把我的Demo源代码给大家,希望对给位有所帮助
以下来说下路径规划
package com.yakj.gaodedemo; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageButton; import android.widget.Toast; import com.amap.api.maps2d.AMap; import com.amap.api.maps2d.CameraUpdateFactory; import com.amap.api.maps2d.MapView; import com.amap.api.maps2d.overlay.BusRouteOverlay; import com.amap.api.maps2d.overlay.DrivingRouteOverlay; import com.amap.api.maps2d.overlay.WalkRouteOverlay; import com.amap.api.services.core.LatLonPoint; import com.amap.api.services.route.BusPath; import com.amap.api.services.route.BusRouteResult; import com.amap.api.services.route.DrivePath; import com.amap.api.services.route.DriveRouteResult; import com.amap.api.services.route.RouteSearch; import com.amap.api.services.route.RouteSearch.BusRouteQuery; import com.amap.api.services.route.RouteSearch.DriveRouteQuery; import com.amap.api.services.route.RouteSearch.OnRouteSearchListener; import com.amap.api.services.route.RouteSearch.WalkRouteQuery; import com.amap.api.services.route.WalkPath; import com.amap.api.services.route.WalkRouteResult; /** * 路径规划 * * @author Administrator * */ public class RouteActivity extends Activity implements OnClickListener, OnRouteSearchListener { private AMap aMap; private MapView mapView; /** * 公交button,驾车button。步行button */ private ImageButton transitBtn, drivingBtn, walkBtn; private int busMode = RouteSearch.BusDefault;// 公交默认模式 private int drivingMode = RouteSearch.DrivingDefault;// 驾车默认模式 private int walkMode = RouteSearch.WalkDefault;// 步行默认模式 private RouteSearch routeSearch; private BusRouteResult busRouteResult;// 公交模式查询结果 private DriveRouteResult driveRouteResult;// 驾车模式查询结果 private WalkRouteResult walkRouteResult;// 步行模式查询结果 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_route); mapView = (MapView) findViewById(R.id.route_map); mapView.onCreate(savedInstanceState);// 此方法必须重写 transitBtn = (ImageButton) findViewById(R.id.imagebtn_roadsearch_tab_transit); drivingBtn = (ImageButton) findViewById(R.id.imagebtn_roadsearch_tab_driving); walkBtn = (ImageButton) findViewById(R.id.imagebtn_roadsearch_tab_walk); routeSearch = new RouteSearch(this); routeSearch.setRouteSearchListener(this); init(); } /** * 初始化AMap对象 */ private void init() { if (aMap == null) { aMap = mapView.getMap(); } transitBtn.setOnClickListener(this); drivingBtn.setOnClickListener(this); walkBtn.setOnClickListener(this); // 设置地图可视缩放大小 aMap.moveCamera(CameraUpdateFactory.zoomTo(12)); } /** * 方法必须重写 */ @Override protected void onResume() { super.onResume(); mapView.onResume(); } /** * 方法必须重写 */ @Override protected void onPause() { super.onPause(); mapView.onPause(); } /** * 方法必须重写 */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } /** * 方法必须重写 */ @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); } @Override public void onClick(View v) { // 这里是写死的两个位置 LatLonPoint startPoint = new LatLonPoint(31.383755, 118.438321); LatLonPoint endPoint = new LatLonPoint(31.339746, 118.381727); final RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(startPoint, endPoint); if (v == transitBtn) {// 公交 BusRouteQuery query = new BusRouteQuery(fromAndTo, busMode, "芜湖市", 1);// 第一个參数表示路径规划的起点和终点,第二个參数表示公交查询模式,第三个參数表示公交查询城市区号,第四个參数表示是否计算夜班车。0表示不计算 routeSearch.calculateBusRouteAsyn(query);// 异步路径规划公交模式查询 } else if (v == drivingBtn) {// 驾车 DriveRouteQuery query = new DriveRouteQuery(fromAndTo, drivingMode, null, null, "");// 第一个參数表示路径规划的起点和终点,第二个參数表示驾车模式,第三个參数表示途经点,第四个參数表示避让区域,第五个參数表示避让道路 routeSearch.calculateDriveRouteAsyn(query);// 异步路径规划驾车模式查询 } else if (v == walkBtn) {// 步行 WalkRouteQuery query = new WalkRouteQuery(fromAndTo, walkMode); routeSearch.calculateWalkRouteAsyn(query);// 异步路径规划步行模式查询 } } @Override public void onBusRouteSearched(BusRouteResult result, int rCode) { if (rCode == 0) { if (result != null && result.getPaths() != null && result.getPaths().size() > 0) { busRouteResult = result; BusPath busPath = busRouteResult.getPaths().get(0); aMap.clear();// 清理地图上的全部覆盖物 BusRouteOverlay routeOverlay = new BusRouteOverlay(this, aMap, busPath, busRouteResult.getStartPos(), busRouteResult.getTargetPos()); routeOverlay.removeFromMap(); routeOverlay.addToMap(); routeOverlay.zoomToSpan(); } else { showToast("对不起,没有搜索到相关数据!"); } } else if (rCode == 27) { showToast("搜索失败,请检查网络连接!"); } else if (rCode == 32) { showToast("key验证无效!"); } else { showToast("未知错误,请稍后重试!错误码为" + rCode); } } @Override public void onDriveRouteSearched(DriveRouteResult result, int rCode) { if (rCode == 0) { if (result != null && result.getPaths() != null && result.getPaths().size() > 0) { driveRouteResult = result; DrivePath drivePath = driveRouteResult.getPaths().get(0); aMap.clear();// 清理地图上的全部覆盖物 DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(this, aMap, drivePath, driveRouteResult.getStartPos(), driveRouteResult.getTargetPos()); drivingRouteOverlay.removeFromMap(); drivingRouteOverlay.addToMap(); drivingRouteOverlay.zoomToSpan(); } else { showToast("对不起,没有搜索到相关数据。"); } } else if (rCode == 27) { showToast("搜索失败,请检查网络连接!"); } else if (rCode == 32) { showToast("key验证无效!"); } else { showToast("未知错误,请稍后重试!错误码为" + rCode); } } @Override public void onWalkRouteSearched(WalkRouteResult result, int rCode) { if (rCode == 0) { if (result != null && result.getPaths() != null && result.getPaths().size() > 0) { walkRouteResult = result; WalkPath walkPath = walkRouteResult.getPaths().get(0); aMap.clear();// 清理地图上的全部覆盖物 WalkRouteOverlay walkRouteOverlay = new WalkRouteOverlay(this, aMap, walkPath, walkRouteResult.getStartPos(), walkRouteResult.getTargetPos()); walkRouteOverlay.removeFromMap(); walkRouteOverlay.addToMap(); walkRouteOverlay.zoomToSpan(); } else { showToast("对不起。没有搜索到相关数据!"); } } else if (rCode == 27) { showToast("搜索失败,请检查网络连接。"); } else if (rCode == 32) { showToast("key验证无效!"); } else { showToast("未知错误,请稍后重试!错误码为" + rCode); } } /** * toast封装 * * @param str */ private void showToast(String str) { Toast.makeText(this, str, Toast.LENGTH_SHORT).show(); ; } }
我这里路劲规划的界面没有定位,点击进去会是北京。然后你随便点击上面的一个路线规划button,就会有显示。如上图所看到的
以下我的把Demo路径。点击打开链接错这里啦
下载地址 :http://download.csdn.net/detail/shaozucheng/8799515