让我们接着上一篇继续下去研究研究地图,上一篇中主要是对配置环境,基础使用作了一些介绍,稍微说了下Marker的使用与监听,今天将来重点研究下地图上覆盖物。
在百度地图中对于所有的在地图上的标注,路线等都称之为覆盖物。最常见就是各种标记,起点终点啊,之类的,不过还有一些不常见的,通过官方的文档我们可以了解到所有的地图覆盖物的种类。
可以看到Overlay的子类有好多,其中Marker之前见过,剩下的从前到后分别是弧形,圆形,点,范围,标记,多边形,折线,文字。当然了,我们平时在使用的时候都是使用对应的Options类来设置这些对象的,看了OverlayOptions。可以看到overlay的每一个子类都是与之对应的options选型类。接下来用代码来试试都是什么样子的。具体的每个选型类里面都有什么方法我就不贴了,官方文档的类参考中都有说明。主要是看一下使用。
//创建三个点
LatLng latLng1=new LatLng(39.914114,116.403022);
LatLng latLng2=new LatLng(39.910114,116.443022);
LatLng latLng3=new LatLng(39.918114,116.403022);
//创建点的集合
List latLngs=new ArrayList<>();
latLngs.add(latLng1);
latLngs.add(latLng2);
latLngs.add(latLng3);
//创建颜色集合
List colors = new ArrayList<>();
colors.add(Color.BLUE);
colors.add(Color.YELLOW);
//创建一个圆弧覆盖物
ArcOptions arc=new ArcOptions()
.color(Color.BLACK)
.points(latLng1,latLng2,latLng3)
.width(5);
//创建点覆盖物
DotOptions dot1=new DotOptions()
.color(Color.BLUE)
.center(latLng1)
.radius(10);
DotOptions dot2=new DotOptions()
.color(Color.RED)
.center(latLng2)
.radius(10);
DotOptions dot3=new DotOptions()
.color(Color.GREEN)
.center(latLng3)
.radius(10);
//创建圆形覆盖物
CircleOptions circleStock=new CircleOptions()
.center(new LatLng(39.9102,116.42))
.stroke(new Stroke(10,Color.RED))
.fillColor(Color.BLUE)
.radius(300);
//创建地形图覆盖物
GroundOverlayOptions ground=new GroundOverlayOptions()
.dimensions(200,200)
.image(BitmapDescriptorFactory.fromResource(R.drawable.emoji001))
.position(latLng1)
.transparency(0.8f);
//创建多边形覆盖物
PolygonOptions gon=new PolygonOptions()
.fillColor(Color.BLUE)
.stroke(new Stroke(10,Color.RED))
.points(latLngs);
//创建折线覆盖物
PolylineOptions lin=new PolylineOptions()
.points(latLngs)
.zIndex(10)
.colorsValues(colors)
.width(5);
//创建文本覆盖物
OverlayOptions textOption = new TextOptions()
.bgColor(0xAAFFFF00)
.fontSize(34)
.fontColor(0xFFFF00FF)
.text("北京找工作!!")
.rotate(+30)
.position(latLng2);
List optionses=new ArrayList<>();
optionses.add(arc);
optionses.add(dot1);
optionses.add(dot2);
optionses.add(dot3);
optionses.add(circleStock);
optionses.add(ground);
optionses.add(gon);
optionses.add(lin);
optionses.add(textOption);
baiduMap.addOverlays(optionses);
以上是所有的覆盖物(除了Marker,昨天写过了)的基本使用方法,都很简单,通过选型对象来确定要设置样式,然后我都添加到一个集合中,整体的添加到地图上,其中需要注意的有。。。好像也没什么需要注意啊。看下效果。
最外面的圆是弧,三个点,分别是起点,中点,终点,中间是圆,还有个Emoj在蓝点的下面,三角形是多边形,文本在红点上面。还有两条折线,连接绿红,红蓝。就这么多吧。接下来在研究Marker。
Marker其实跟其他的覆盖物一样,也是由MarkerOptions来设置样式,之通过baiduMap.addOverlays()添加到地图上,不同的地方是它有监听,还有动画,再就我们经常用的就是Marker。昨天简单使用了一下,今天在加上InfoWindow来玩一玩。
先看一下基础的动画设置,有两种方式实现动画,一个是采用官方给的生长和下落来表现出现的时候的动画,之后就可以采用帧动画的形式来让Marker不断切换显示的图标,使用起来也不难。
ArrayList bitmaps=new ArrayList<>();
bitmaps.add(BitmapDescriptorFactory.fromResource(R.drawable.icon_locate));
bitmaps.add(BitmapDescriptorFactory.fromResource(R.drawable.map_start));
bitmaps.add(BitmapDescriptorFactory.fromResource(R.drawable.pin_end));
MarkerOptions markerOptions=new MarkerOptions()
.alpha(0.8f)
.draggable(true)
.position(latLng1)
.icons(bitmaps)
.period(20)
.animateType(MarkerOptions.MarkerAnimateType.grow);
baiduMap.addOverlay(markerOptions);
这就是一个简单的动画实现,包括生长和一个帧动画。
一个点击事件加InfoWindow。
View view=View.inflate(this,R.layout.info,null);
Button btn= (Button) view.findViewById(R.id.button2);
final TextView tv= (TextView) view.findViewById(R.id.textView);
final ImageView im= (ImageView) view.findViewById(R.id.imageView);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tv.setText("别点我");
im.setImageResource(R.drawable.icon_pay_success);
}
});
final InfoWindow info=new InfoWindow(view,latLng1,-30);
baiduMap.addOverlay(markerOptions);
baiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
baiduMap.showInfoWindow(info);
return true;
}
});
效果: infoWindow中的事件如果是用view对象传入的话,由View对象自己去实现,如果使用BitmapDescriptor对象的话可以使用这个方法
在监听器的回调的实现业务就可以。还有个问题就是应该都看出来了,就是textView中的内容没有被刷掉,不知道为什么,我尝试下别的方法没有实现,如果有知道问题在哪的,麻烦告诉一下,不胜感激。
infoWindow的内容就这么多也没别的关于marker还有些更多的使用,比如一次显示多个标记点。这些可以去看下文档就可以。
地图的基本功能使用的差不多了,接下来研究研究定位功能,平时我们点开地图的时候都是以自己为中心的,有个标记,或者是以某个想要去的商家为中心,这就需要定位功能。
//创建两个成员变量
mLocationClient=new LocationClient(getApplicationContext());
initLocation();
mMylisterner=new MyLocationListener();
mLocationClient.registerLocationListener(mMylisterner);
mLocationClient.start();
}
//设置定位参数
private void initLocation() {
LocationClientOption option=new LocationClientOption();
option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系
option.setScanSpan(0);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
option.setOpenGps(true);//可选,默认false,设置是否使用gps
option.setLocationNotify(true);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
option.setIgnoreKillProcess(true);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集
option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤gps仿真结果,默认需要
mLocationClient.setLocOption(option);
}
//创建监听器的实现类
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
//Receive Location
StringBuffer sb = new StringBuffer(256);
sb.append("time : ");
sb.append(location.getTime());
sb.append("\nerror code : ");
sb.append(location.getLocType());
sb.append("\nlatitude : ");
sb.append(location.getLatitude());
sb.append("\nlontitude : ");
sb.append(location.getLongitude());
sb.append("\nradius : ");
sb.append(location.getRadius());
if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
sb.append("\nspeed : ");
sb.append(location.getSpeed());// 单位:公里每小时
sb.append("\nsatellite : ");
sb.append(location.getSatelliteNumber());
sb.append("\nheight : ");
sb.append(location.getAltitude());// 单位:米
sb.append("\ndirection : ");
sb.append(location.getDirection());// 单位度
sb.append("\naddr : ");
sb.append(location.getAddrStr());
sb.append("\ndescribe : ");
sb.append("gps定位成功");
} else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
sb.append("\naddr : ");
sb.append(location.getAddrStr());
//运营商信息
sb.append("\noperationers : ");
sb.append(location.getOperators());
sb.append("\ndescribe : ");
sb.append("网络定位成功");
} else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
sb.append("\ndescribe : ");
sb.append("离线定位成功,离线定位结果也是有效的");
} else if (location.getLocType() == BDLocation.TypeServerError) {
sb.append("\ndescribe : ");
sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到[email protected],会有人追查原因");
} else if (location.getLocType() == BDLocation.TypeNetWorkException) {
sb.append("\ndescribe : ");
sb.append("网络不同导致定位失败,请检查网络是否通畅");
} else if (location.getLocType() == BDLocation.TypeCriteriaException) {
sb.append("\ndescribe : ");
sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
}
sb.append("\nlocationdescribe : ");
sb.append(location.getLocationDescribe());// 位置语义化信息
List list = location.getPoiList();// POI数据
if (list != null) {
sb.append("\npoilist size = : ");
sb.append(list.size());
for (Poi p : list) {
sb.append("\npoi= : ");
sb.append(p.getId() + " " + p.getName() + " " + p.getRank());
}
}
Log.i("BaiduLocationApiDem", sb.toString());
//图标
MarkerOptions overlay = new MarkerOptions();
overlay.icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_locate));
LatLng arg0 = new LatLng(location.getLatitude(), location.getLongitude());
overlay.position(arg0);
baiduMap.addOverlay(overlay);
//中心点设置
MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(arg0);
baiduMap.animateMapStatus(msu);
//信息窗
TextView view = new TextView(getApplicationContext());
view.setText("我在这");
view.setBackgroundColor(Color.RED);
view.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
view.setPadding(5, 5, 5, 5);
view.setGravity(Gravity.CENTER);
InfoWindow window = new InfoWindow(view, arg0, -30);
baiduMap.showInfoWindow(window);
//设置比例尺
baiduMap.setMaxAndMinZoomLevel(20, 15);
//定位成功停止发送定位请求
if (mLocationClient.isStarted()) {
mLocationClient.stop();
mLocationClient.unRegisterLocationListener(mMylisterner);
}
}
}
其实写了这么多关于百度地图的东西,应该能够发现一点,在百度地图中大部分的逻辑:创建对象,创建监听器,设置参数发起请求,这三步。上面的代码中就是这样的实现的而且百度地图中大部分的请求都可以用这种套路去实现。上面的代码大部分来自于官方文档,注释都解释的很清楚可以根据自己的需求去选择不同的定位参数,在监听的最后我设置一个标记,显示个Info,把地图中心定位到当前位置。其中需要关注的就是定位请求的刷新,在一些需要不断请求定位的业务中需要把setScanSpan()中设定定位间隔,要求大于1秒。通常用于跑步啊,追踪啊之类的,不需要重复定位,只定位一次的话就设为0,或者也可以根据业务来取消定位。关于定位的就介绍这么多,之后会介绍一些周边搜索和交通查询功能。
这篇博客就这么多。
最后还得打广告,目前在找工作。。。。。