高德地图添加marker及反地理编码获取POI
项目中集成百度、高德、腾讯地图已是司空见惯的事情,今天我总结了一下项目中用到的高德地图常用的功能:
1.展示高德地图并定位显示定位图标;
2.添加实时大头针;
3.反地理编码获取周围兴趣点
效果如下:
现在开始展示集成流程
一.显示地图
1.申请key
至于如何申请高德地图开发者账号,请自行百度。在高德开放平台->控制台->创建新应用 ->添加新Key
需提前获取 SHA1: keytool -v -list -keystore keystore 文件绝对路径或者先定位到keystore 文件所在路径后,后面只写keystone文件名
2.配置AndroidManifest.xml
1)添加权限
//地图SDK(包含其搜索功能)需要的基础权限
1 <!--允许程序打开网络套接字--> 2 <uses-permission android:name="android.permission.INTERNET" /> 3 <!--允许程序设置内置sd卡的写权限--> 4 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 5 <!--允许程序获取网络状态--> 6 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 7 <!--允许程序访问WiFi网络信息--> 8 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 9 <!--允许程序读写手机状态和身份--> 10 <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 11 <!--允许程序访问CellID或WiFi热点来获取粗略的位置--> 12 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
2)配置key
1 <meta-data android:name="com.amap.api.v2.apikey" android:value="开发者申请的key "/>
3.下载jar包(若选择3D地图包,还需要下载so文件)
地图SDK:http://lbs.amap.com/api/android-sdk/download
定位sdk:http://lbs.amap.com/api/android-location-sdk/download
4.将jar包放入libs目录下
对于每个jar文件,右键-选择Add As Library,导入到工程中。
或者使用菜单栏 选择 File ->Project Structure->Modules-> Dependencies。点击绿色的加号选择File dependency. 然后选择要添加的jar包即可,此时build.gradle中会自动生成如下信息(以地图、定位为例)
5.初始化地图容器
布局xml文件中添加地图控件(以地图2D):
1 <com.amap.api.maps2d.MapView 2 android:id="@+id/map" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent"/>
管理地图生命周期
1 @Override 2 protected void onCreate(Bundle savedInstanceState) { 3 super.onCreate(savedInstanceState); 4 。。。。 5 //获取地图控件引用 6 mMapView = (MapView) findViewById(R.id.map); 7 //在activity创建地图 8 aMapView.onCreate(savedInstanceState); 9 //初始化地图控制器对象 10 if (aMap == null) { 11 aMap = mapView.getMap(); 12 } 13 } 14 @Override 15 protected void onDestroy() { 16 super.onDestroy(); 17 //在activity销毁地图 18 aMapView.onDestroy(); 19 //销毁定位对象 20 if (null != mlocationClient) { 21 mlocationClient.onDestroy();//销毁定位客户端,同时销毁本地定位服务。 22 } 23 } 24 @Override 25 protected void onResume() { 26 super.onResume(); 27 //在activity重新绘制加载地图 28 aMapView.onResume(); 29 } 30 @Override 31 protected void onPause() { 32 super.onPause(); 33 //在activity暂停地图的绘制 34 mMapView.onPause(); 35 } 36 @Override 37 protected void onSaveInstanceState(Bundle outState) { 38 super.onSaveInstanceState(outState); 39 //在activity保存地图当前的状态 40 mMapView.onSaveInstanceState(outState); 41 }
二.显示定位小蓝点及反地理编码检索
地图 SDK 5.0.0版本之前
1.配置AndroidManifest.xml
请在application标签中声明service组件
1 <service android:name="com.amap.api.location.APSService"></service>
声明权限
1 <!--用于获取wifi的获取权限,wifi信息会用来进行网络定位--> 2 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission> 3 <!--用于访问GPS定位--> 4 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 5 <!--用于申请调用A-GPS模块--> 6 <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
设置一些amap的属性
1 private void setUpMap() { 2 // 自定义系统定位小蓝点 3 MyLocationStyle myLocationStyle = new MyLocationStyle(); 4 myLocationStyle.myLocationIcon(BitmapDescriptorFactory 5 .fromResource(R.drawable.location_marker));// 设置小蓝点的图标 6 myLocationStyle.strokeColor(Color.BLACK);// 设置圆形的边框颜色 7 myLocationStyle.radiusFillColor(Color.argb(100, 0, 0, 180));// 设置圆形的填充颜色 8 // myLocationStyle.anchor(int,int)//设置小蓝点的锚点 9 myLocationStyle.strokeWidth(1.0f);// 设置圆形的边框粗细 10 aMap.setMyLocationStyle(myLocationStyle); 11 aMap.setLocationSource(this);// 设置定位监听 12 aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示 13 aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。 14 // 触摸监听 15 aMap.setOnCameraChangeListener(cameraChangeListener); 16 }
2.初始化定位
在aMap.setLocationSource(this)中包含两个回调:在activate()中设置定位初始化及启动定位,在deactivate()中写停止定位的相关调用。
1 /** 2 * 激活定位 3 */ 4 @Override 5 public void activate(OnLocationChangedListener listener) { 6 mListener = listener; 7 if (mlocationClient == null) { 8 //初始化定位 需要传Context类型的参数。推荐用getApplicationConext()方法 9 mlocationClient = new AMapLocationClient(this); 10 //初始化定位参数 11 mLocationOption = new AMapLocationClientOption(); 12 //设置定位回调监听 13 mlocationClient.setLocationListener(this); 14 //设置单次定位 该方法默认为false。 15 mLocationOption.setOnceLocation(true); 16 //选择定位模式 SDK默认选择使用高精度定位模式。 17 // 高精度定位模式:Hight_Accuracy 同时使用网络定位和GPS定位 18 //低功耗定位模式:Battery_Saving 不会使用GPS和其他传感器,只会使用网络定位(Wi-Fi和基站定位) 19 //仅用设备定位模式:Device_Sensors 不需要连接网络,只使用GPS进行定位,这种模式下不支持室内环境的定位,自 v2.9.0 版本支持返回地址描述信息 mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); 20 //设置定位间隔,单位毫秒,默认为2000ms 最低1000ms 21 mLocationOption.setInterval(5000); 22 //设置是否返回地址信息(默认返回地址信息) 23 mLocationOption.setNeedAddress(true); 24 //设置是否强制刷新WIFI,默认为true,强制刷新,会增加电量消耗。 25 mLocationOption.setWifiActiveScan(true); 26 // 设置定位请求超时时间,单位是毫秒,默认30000毫秒,建议超时时间不要低于8000毫秒。 27 mLocationOption.setHttpTimeOut(30000); 28 //设置是否开启定位缓存机制 缓存机制默认开启true 网络定位结果均会生成本地缓存, 29 // 不区分单次定位还是连续定位。GPS定位结果不会被缓存 30 mLocationOption.setLocationCacheEnable(true); 31 //设置定位参数 32 mlocationClient.setLocationOption(mLocationOption); 33 // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗, 34 // 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求 35 // 在定位结束后,在合适的生命周期调用onDestroy()方法 36 // 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除 37 mlocationClient.startLocation();//启动定位 38 } 39 } 40 /** 41 * 停止定位 42 */ 43 @Override 44 public void deactivate() { 45 mListener = null; 46 if (mlocationClient != null) { 47 mlocationClient.stopLocation();//停止定位后,本地定位服务并不会被销毁 48 } 49 mlocationClient = null; 50 }
3.定位回调中设置显示大头针
mlocationClient.setLocationListener(this);后,重写onLocationChanged回调
1 /** 2 * 定位成功后回调函数 3 */ 4 @Override 5 public void onLocationChanged(AMapLocation amapLocation) { 6 if (mListener != null&&amapLocation != null) { 7 if (amapLocation.getErrorCode() == 0) { 8 mListener.onLocationChanged(amapLocation);// 显示系统小蓝点 9 //定位成功回调信息,设置相关消息 10 amapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见定位类型表 11 amapLocation.getLatitude();//获取纬度 12 amapLocation.getLongitude();//获取经度 13 amapLocation.getAccuracy();//获取精度信息 14 amapLocation.getAddress();//地址,如果option中设置isNeedAddress为false,则没有此结果,网络定位结果中会有地址信息,GPS定位不返回地址信息。 15 amapLocation.getCountry();//国家信息 16 amapLocation.getProvince();//省信息 17 amapLocation.getCity();//城市信息 18 amapLocation.getDistrict();//城区信息 19 amapLocation.getStreet();//街道信息 20 amapLocation.getStreetNum();//街道门牌号信息 21 amapLocation.getCityCode();//城市编码 22 amapLocation.getAdCode();//地区编码 23 amapLocation.getAoiName();//获取当前定位点的AOI信息 24 amapLocation.getBuildingId();//获取当前室内定位的建筑物Id 25 amapLocation.getFloor();//获取当前室内定位的楼层 26 amapLocation.getGpsAccuracyStatus();//获取GPS的当前状态 27 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 28 Date date = new Date(amapLocation.getTime()); 29 df.format(date);//定位时间 30 addMarker(locationLatLng, desc);//添加大头针 desc可为null 31 //根据locationLatLng地图移至中心位置
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(locationLatLng, 15)); 32 //反地理编码搜索 33 regeocodeSearch(latitude, longitude, 3000); 34 } else { 35 String errText = "定位失败," + amapLocation.getErrorCode()+ ": " + amapLocation.getErrorInfo(); 36 Log.e("AmapErr",errText); 37 } 38 } 39 } 40 /** 41 * 定位成功后往地图上添加marker 42 * 此处设置两个marker,来实现大头针下添加小原点 43 * @param latLng 44 */ 45 private void addMarker(LatLng latLng, String desc) { 46 MarkerOptions markerOptions = new MarkerOptions(); 47 markerOptions.position(latLng); markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_fixed_location));//大头针图标 48 MarkerOptions options = new MarkerOptions(); 49 options.position(latLng); options.icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_location));//大头针下原点 50 options.anchor(0.5f,0.5f);//保证小蓝点的中心对应经纬度位置 51 //markerOptions.icon(BitmapDescriptorFactory.defaultMarker()); 52 marker = aMap.addMarker(options);//先添加的在底层 53 locationMarker = aMap.addMarker(markerOptions); 54 } 55 注意:需要在系统 onDestroy() 方法中销毁定位对象 56 @Override 57 protected void onDestroy() { 58 super.onDestroy(); 59 //在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图 60 mMapView.onDestroy(); 61 // 销毁定位对象 62 if(null != mlocationClient){ 63 mlocationClient.onDestroy();//销毁定位客户端,同时销毁本地定位服务。 64 } 65 }
4.滑动地图事件或调用aMap.moveCamera后回调
1 AMap.OnCameraChangeListener cameraChangeListener = new AMap.OnCameraChangeListener() { 2 /*设置定位图标位置*/ 3 @Override 4 public void onCameraChange(CameraPosition cameraPosition) { 5 LatLng latLng = cameraPosition.target; 6 if (locationMarker != null) { 7 locationMarker.setPosition(latLng); 8 } 9 if (null != marker) 10 marker.setPosition(latLng); 11 } 12 /*更新地址列表*/ 13 @Override 14 public void onCameraChangeFinish(CameraPosition position) { 15 final LatLng latLng = position.target; 16 if (null != marker && !marker.isVisible()) 17 marker.setVisible(true);//设置可见性 18 //marker.setVisible(false); 19 adapter.index = 0; 20 regeocodeSearch(latLng.latitude, latLng.longitude, 3000); 21 } 22 };
5.反地理编码设置
1 private void regeocodeSearch(double lat, double lng, float radius) { 2 LatLonPoint point = new LatLonPoint(lat, lng); 3 GeocodeSearch geocodeSearch = new GeocodeSearch(this); 4 geocodeSearch.setOnGeocodeSearchListener(this); 5 // 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系 6 RegeocodeQuery regeocodeQuery = new RegeocodeQuery(point, radius, GeocodeSearch.AMAP); 7 geocodeSearch.getFromLocationAsyn(regeocodeQuery); 8 } 9 @Override 10 public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int rCode) { 11 String preAdd = "";//地址前缀 12 if (1000 == rCode) { 13 RegeocodeAddress address = regeocodeResult.getRegeocodeAddress(); 14 StringBuffer stringBuffer = new StringBuffer(); 15 String area = address.getProvince();//省或直辖市 16 String loc = address.getCity();//地级市或直辖市 17 String subLoc = address.getDistrict();//区或县或县级市 18 String ts = address.getTownship();//乡镇 19 String thf = null;//道路 20 List<RegeocodeRoad> regeocodeRoads = address.getRoads();//道路列表 21 if (regeocodeRoads != null && regeocodeRoads.size() > 0) { 22 RegeocodeRoad regeocodeRoad = regeocodeRoads.get(0); 23 if (regeocodeRoad != null) { 24 thf = regeocodeRoad.getName(); 25 } 26 } 27 String subthf = null;//门牌号 28 StreetNumber streetNumber = address.getStreetNumber(); 29 if (streetNumber != null) { 30 subthf = streetNumber.getNumber(); 31 } 32 String fn = address.getBuilding();//标志性建筑,当道路为null时显示 33 if (area != null) { 34 stringBuffer.append(area); 35 preAdd += area; 36 } 37 if (loc != null && !area.equals(loc)) { 38 stringBuffer.append(loc); 39 preAdd += loc; 40 } 41 if (subLoc != null) { 42 stringBuffer.append(subLoc); 43 preAdd += subLoc; 44 } 45 if (ts != null) 46 stringBuffer.append(ts); 47 if (thf != null) 48 stringBuffer.append(thf); 49 if (subthf != null) 50 stringBuffer.append(subthf); 51 if ((thf == null && subthf == null) && fn != null && !subLoc.equals(fn)) 52 stringBuffer.append(fn + "附近"); 53 String ps = "poi"; 54 List<PoiItem> pois = address.getPois();//获取周围兴趣点 55 if (pois != null && pois.size() > 0) { 56 for (int i = 0; i < pois.size(); i++) { 57 String title = pois.get(i).getTitle(); 58 String adName = pois.get(i).getAdName(); 59 String snippet = pois.get(i).getSnippet(); 60 LatLonPoint latLonPoint = pois.get(i).getLatLonPoint(); 61 double latitude = latLonPoint.getLatitude(); 62 double longitude = latLonPoint.getLongitude(); 63 ps = ps + ",title=" + title + ",adName=" + adName + ",snippet=" + snippet; 64 } 65 Log.e("PoiItem" + "pois.size=" ,pois.size() + "----" + ps); 66 } 67 } 68 }
本文为博主原创文章,请尊重版权,未经博主允许不得转载,转载请注明出处:http://www.cnblogs.com/details-666/p/AMap.html
另附定位类型对照表: