因项目需求,之前用的百度地图被pass,全部换位高德地图,经过不断的走坑,实现了地图的显示、定位蓝点、大头针显示、周围地理信息等
一、首先请各位要做高德的地图之前用心的去阅读下高德地图开放平台的技术文档,这个是最基本的准备,**
最重要的一点,如果想在地图界面调用相机、扫码等功能请集成3D地图,因为高德地底部是GLSurfaceView和TextureView
他俩都是地图容器,使用GLSurfaceView当你调用相机时会出现穿透或者冲突等问题,需要使用TextureView(存在于3D地图的SDK下)
本问基于3D地图SDK下:
1.显示地图:
1,进程第三方的SDK第一步注册账号、注册应用,获取appkey,如下:
2,获取到appkey 后,需要配置 AndroidManifest.xml:
//地图SDK(包含其搜索功能)需要的基础权限
然后,设置高德Key
在application标签中加入如下内容:
//开发者申请的key
3.向工程中添加地图开发包 (我做的是2D的不用添加so等文件,如果3D的需要放so文件等)
在Eclipse环境下:
步骤1:开发工程中新建“ libs ”文件夹,将地图包(2D或3D)、搜索包拷贝到 libs 的根目录下。若选择3D地图包,还需要将各库文件夹一起拷贝。拷贝完成后的工程目录(以3D V2.2.0为例)如图所示:
4,初始化地图容器;在你的布局文件中放入如下:
在Activity中绑定布局,并显示:
publicclassMainActivityextendsActivity{
MapView mMapView = null;
@Override
protectedvoidonCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);//获取地图控件引用
mMapView = (MapView) findViewById(R.id.map); //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
mMapView.onCreate(savedInstanceState);
}
@Override
protectedvoidonDestroy(){
super.onDestroy();//在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
mMapView.onDestroy();
}
@Override
protectedvoidonResume(){
super.onResume();//在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
mMapView.onResume();
}
@Override
protectedvoidonPause(){
super.onPause();//在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
mMapView.onPause();
}
@Override
protectedvoidonSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);//在activity执行onSaveInstanceState时执行
mMapView.onSaveInstanceState (outState),保存地图当前的状态
mMapView.onSaveInstanceState(outState); }
}
5.显示地图
//定义了一个地图
viewmapView = (MapView) findViewById(R.id.map);
mapView.onCreate(savedInstanceState);// 此方法须覆写,虚拟机需要在很多情况下保存地图绘制的当前状态。
//初始化地图控制器对象
AMap aMap;if (aMap == null) {
aMap = mapView.getMap();
}
即可完成地图的显示。
二、定位小蓝点显示
//设置成中文地图
aMap.setMapLanguage(AMap.CHINESE);
// 自定义系统定位小蓝点
MyLocationStyle myLocationStyle = new MyLocationStyle();
myLocationStyle.myLocationIcon(BitmapDescriptorFactory
.fromResource(R.drawable.local));// 设置小蓝点的图标
myLocationStyle.strokeColor(Color.BLACK);// 设置圆形的边框颜色
myLocationStyle.radiusFillColor(Color.argb(100, 0, 0, 180));// 设置圆形的填充颜色
// myLocationStyle.anchor(int,int)//设置小蓝点的锚点
myLocationStyle.strokeWidth(2.0f);// 设置圆形的边框粗细
aMap.setMyLocationStyle(myLocationStyle); // 将自定义的 myLocationStyle 对象添加到地图上
aMap.setLocationSource(this);// 设置定位监听 ,会实现两个方法activate()、 deactivate(),在两个方法中进行操作
// aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
// aMap.getUiSettings().setZoomControlsEnabled(false); //设置缩放按钮是否显示
// aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false
//aMap.setOnCameraChangeListener(this);// 对amap添加移动地图事件监听器
会回调此方法
@Override
public void activate(OnLocationChangedListener arg0) {
mListener = arg0;
if (mlocationClient == null) {
mlocationClient = new AMapLocationClient(this);
mLocationOption = new AMapLocationClientOption();
mLocationOption.setNeedAddress(true); //设置定位监听
mlocationClient.setLocationListener(this); //定位成功会回调onLocationChanged()方法
; //设置为高精度定位模式
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//设置定位参数
mlocationClient.setLocationOption(mLocationOption);
// 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
// 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求
// 在定位结束后,在合适的生命周期调用onDestroy()方法
// 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除
mlocationClient.startLocation();
}
}
@Override
public void deactivate() {
mListener = null;
if (mlocationClient != null) {
mlocationClient.stopLocation();
mlocationClient.onDestroy();
}
mlocationClient = null;
}
//定位成功回调此方法
@Override
public void onLocationChanged(AMapLocation amapLocation) {
if (mListener != null && amapLocation != null) {
if (amapLocation != null
&& amapLocation.getErrorCode() == 0) {
mListener.onLocationChanged(amapLocation);// 显示系统小蓝点
aMap.moveCamera(CameraUpdateFactory.zoomTo(15)); //设置显示级数//将视图中心点自动移动到次此置
aMap.moveCamera(CameraUpdateFactory.changeLatLng(new LatLng(amapLocation.getLatitude(), amapLocation.getLongitude()))); deactivate(); //我只定位了一次,所以成功之后就调用此方法,如果想一直重复定位不需要写此方法
Log.e("--Main--", localAddress);
} else {
String errText = "定位失败," + amapLocation.getErrorCode()+ ": " + amapLocation.getErrorInfo();
Log.e("AmapErr",errText);
}
}}
三、大头针显示,
1.获取当前位置的周边的大头针信息坐标,需要在上面已经定位成功的回调方法onLocationChanged()内调用doSearchQuery();方法,需要传城市名称,经度、纬度,如下;
private void doSearchQuery(String city,double latitude,double longitude){
//Log.e("--Main--","doSearchQuery()");
mCloudSearch = new CloudSearch(this);// 初始化查询类
mCloudSearch.setOnCloudSearchListener(this);// 设置回调函数 会回调两个方法onCloudItemDetailSearched()和onCloudSearched()一般在onCloudSearched中操作即可,
// 设置中心点及检索范围
SearchBound bound = new SearchBound(new LatLonPoint(latitude,longitude), 4000);
//设置查询条件,mTableID是将数据存储到数据管理台后获得。
try {
mQuery = new CloudSearch.Query("59141ef37bbf197dd1873504", "", bound);
mCloudSearch.searchCloudAsyn(mQuery);// 异步搜索
} catch (AMapException e) {
// TODO Auto-generated catch blocke.printStackTrace();
}
}
//回调的方法
@Override
public void onCloudItemDetailSearched(CloudItemDetail item, int rCode) {
}
//在此方法会获取到周边的数据,进行操作即可
@Override
public void onCloudSearched(CloudResult result, int rCode) {
mCloudItems = result.getClouds();
if (mCloudItems != null && mCloudItems.size() > 0) {
for (CloudItem item : mCloudItems) { //循环遍历获取数据//Log.e("--Main--", item.getTitle());
//Log.e("--Main--", "纬度为"+item.getLatLonPoint().getLatitude());
//Log.e("--Main--", "经度为"+item.getLatLonPoint().getLongitude());
//调用addMarker()方法添加大头针。
aMap.addMarker(new MarkerOptions().position(new LatLng(item.getLatLonPoint().getLatitude(),item.getLatLonPoint().getLongitude()))
.title(item.getTitle()).icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
.decodeResource(getResources(),R.drawable.danchepic))));
}
} else {
//
}
}
2、随着屏幕移动,获取指定位置的周围标识信息的坐标,首先需要在初始化地图时添加监听如下:
aMap.setOnCameraChangeListener(this);// 对amap添加移动地图事件监听器,会回调onCameraChange()和onCameraChangeFinish(),如下:
/*** 对正在移动地图事件回调*/
@Override
public void onCameraChange(CameraPosition cameraPosition) {}
/*** 对移动地图结束事件回调*
/@Override
public void onCameraChangeFinish(CameraPosition cameraPosition) {
LatLng latLng = cameraPosition.target;
//泥逆地理
geocoderSearch = new GeocodeSearch(this);
geocoderSearch.setOnGeocodeSearchListener(this);
// 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系
RegeocodeQuery query = new RegeocodeQuery(new LatLonPoint(latLng.latitude,latLng.longitude), 200,GeocodeSearch.AMAP);
geocoderSearch.getFromLocationAsyn(query);
//清除上一次的定位Marker
;aMap.clear();
aMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));/将定位图标移动到当前屏幕中心位置
aMap.addMarker(new MarkerOptions().position(cameraPosition.target).icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
.decodeResource(getResources(), R.drawable.icon_marka))));
//增加蓝色圆圈,可自定义
aMap.addCircle(new CircleOptions() .center(new LatLng(latLng.latitude, latLng.longitude))
.radius(300).strokeColor(// Color.argb(50, 1, 1, 1)Color.RED)
.fillColor(Color.argb(50, 1, 1, 1)).strokeWidth(5));
//执行搜索方法
doSearchQuery("北京",latLng.latitude,latLng.longitude);
}
四、周围的标志性建筑
首先两种需求,一种是当定位当前位置成功后获取当前位置周边的标志性建筑;另一种是随着屏幕滑动,想展示特点某个位置周边的标志性建筑
1、获取当前位置的周边的大头针薪资坐标,需要在上面已经定位成功的回调方法,onLocationChanged()内调用doSearchQuery();方法,写一个list作为每个标志性建筑的item展示,开始进行poi搜索
/**
* 开始进行poi搜索
*/
protected void doSearchQuery(String city,double latitude,double longitude) {
String mType="汽车服务|汽车销售|汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务|金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施";
query = new PoiSearch.Query("", mType, city);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国)
query.setPageSize(20);// 设置每页最多返回多少条poiitem
query.setPageNum(1);// 设置查第一页
poiSearch = new PoiSearch(this, query);
poiSearch.setOnPoiSearchListener(this);
//以当前定位的经纬度为准搜索周围5000米范围
// 设置搜索区域为以lp点为圆心,其周围5000米范围
poiSearch.setBound(new PoiSearch.SearchBound(new LatLonPoint(latitude,longitude), 1000, true));//
poiSearch.searchPOIAsyn();// 异步搜索
}
//回调的方法
@Override
public void onPoiItemSearched(PoiItem arg0, int arg1) {
}
@Override
public void onPoiSearched(PoiResult result, int arg1) {
// TODO Auto-generated method stub
if(arg1==1000){
if (result != null && result.getQuery() != null) {// 搜索poi的结果
if (result.getQuery().equals(query)) {// 是否是同一条
List poiItems = result.getPois();// 取得第一页的poiitem数据,页数从数字0开始
List tem=new ArrayList();
if (poiItems != null && poiItems.size() > 0) {
for (int i = 0; i < poiItems.size(); i++) {
PoiItem poiItem = poiItems.get(i); //写一个bean,作为数据存储
PoiBean bean=new PoiBean();
bean.setTitleName(poiItem.getTitle());
bean.setCityName(poiItem.getCityName());
bean.setAd(poiItem.getAdName());
bean.setSnippet(poiItem.getSnippet());
bean.setPoint(poiItem.getLatLonPoint());
Log.e("yufs",""+poiItem.getTitle()+","+poiItem.getProvinceName()+","
+poiItem.getCityName()+","
+poiItem.getAdName()+","//区
+poiItem.getSnippet()+","
+poiItem.getLatLonPoint()+"\n");
tem.add(bean);
}
poiData.addAll(tem);
mAdapter.notifyDataSetChanged(); //解析成功更新list布局
}
}
}
}
}
2.随着屏幕移动,获取指定位置的周围标志性建筑,和上面的大头针一样,也是在移动地图结束后调用doSearchQuery()方法,进行poi检索,就不意义叙述了
最后效果图如下:
以上就是吧基本功能显示完成了,有一些细节东西没有全部写出来,希望这些对初次集成地图的童鞋有帮助,如果发现问题请联系我qq:2145228494,欢迎指教。