高德地图添加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

另附定位类型对照表:
 
posted @ 2017-06-30 10:46  CoddingMan  阅读(7640)  评论(3编辑  收藏  举报