zoukankan      html  css  js  c++  java
  • Android高德地图开发具体解释

    这段时间开发的时候用到了高德地图,对高德地图开发有心得体会,如今分享给大家。对我开发过百度地图的我来说,整体来说高德地图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








  • 相关阅读:
    Django框架(二十三)-- Django rest_framework-视图组件
    Django框架 --序列化组件(serializer)
    Django框架(十六)-- 中间件、CSRF跨站请求伪造
    leetcode 之 两数之和
    vue中webpack相关的配置
    vue-cli3 初始化创建项目
    vue之模块化开发
    vue基础之常用方法
    凯哥带你用python撸算法之雪花算法
    docker数据卷之持久化操作
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5095803.html
Copyright © 2011-2022 走看看