到位的主要特色是地图加LBS功能,搜索周边的服务和帮忙,既然是地图,我们就站在百度的肩膀来开车吧:
首先你得有个KEY,在百度地图API上注册为开发者后,你就可以创建一个应用,记得选Android类型,因为默认是服务器类型。
之后在AndroidManifest上加上下面这些(网络、定位权限的就不需要列出了吧),最后在APPlication中初始化SDKInitializer.initialize(this);,这样你的的MapView就可以跑起来啦!
<service
android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote" />
<meta-data
android:name="api_key"
android:value="CirU5l4MGVbE59tOduYDCO6TDX27CPzV" />
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="CirU5l4MGVbE59tOduYDCO6TDX27CPzV" />
虽然用的是MapView,但是实际上操作的,是MapView里面的BaiduMap。
下方长♂代码走起,流程是:比例尺;不要倾角;不要旋转;设置最大和最小的缩放层级;初始化聚合管理器(后面都是他的事情);Marker(地图上对应的item)管理器;设置显示位置的图标; 初始化我们需要的搜索Model(经纬度,半径,表id)用与保存搜索状态。是不是很简单,哇塞,我有一个地图了。
mBaiduMap = mBaiduMapView.getMap();
// 比例尺控件
mBaiduMapView.showScaleControl(true);
// 缩放控件
mBaiduMapView.showZoomControls(false);
// 百度地图LoGo -> 正式版切记不能这么做,本人只是觉得logo丑了
mBaiduMapView.removeViewAt(1);
//不倾斜
mBaiduMap.getUiSettings().setOverlookingGesturesEnabled(false);
//不旋转
mBaiduMap.getUiSettings().setRotateGesturesEnabled(false);
//设置缩放层级
mBaiduMap.setMaxAndMinZoomLevel(19, 12);
//图标管理器
mMarkerManager = new MarkerManager(mBaiduMap);
//聚合与渲染管理器
mClusterManager = new ClusterManager<>(this, mBaiduMap, mMarkerManager);
mBaiduMap.setOnMapStatusChangeListener(mClusterManager);
mBaiduMap.setOnMapLoadedCallback(this);
mBaiduMap.setMyLocationEnabled(true);
Bitmap bitmap = CommonUtil.getImageFromAssetsFile(DemoApplication.getApplication(), "current_location.png");
//调整位置图片,类似百度地图的小蓝点
float scale = 0.80f;
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
mCLBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(mCLBitmap);
MyLocationConfiguration myLocationConfiguration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, false, bitmapDescriptor);
mBaiduMap.setMyLocationConfigeration(myLocationConfiguration);
//显示位置图标的builder
MyLocationData locData = new MyLocationData.Builder()
.accuracy(0)
.direction(0).latitude(llat)
.longitude(llng).build();
//显示位置图标-珠海
mBaiduMap.setMyLocationData(locData);
//显示等级-转换:初始化为mDefaultRadius半径的层级用于显示
float level = LocationLevelUtils.returnCurZoom(mDefaultRadius);
//当前地图状态
mCurrentMapStatus = new MapStatus.Builder().target(new LatLng(llat, llng)).zoom(level).build();
mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(mCurrentMapStatus));
//初始化数据搜索model
mSearchModel = new SearchModel();
mSearchModel.setGps(llng + "," + llat);
mSearchModel.setRadius(mDefaultRadius);
mSearchModel.setLevel(level);
mSearchModel.setTableId(DemoApplication.TABLE_ID());
初始化好地图,那么我们需要的是,在地图上显示图标,并且将临近的点聚合起来。百度地图的DEMO已经实现了这一点,但是还不够我们的需求,这是时候我们要修改Demo下,clusterutil路径下的类,针对聚合与Marker的显示做自定义处理。
1)、ClusterItem
这个接口代表着地图上一个item,但是的百度Demo还不够,所以在里面加入新接口,用于显示我们的自定图标,然后实现ClusterBaiduItem继承ClusterItem,将需要显示的经纬度和图标信息,保存在Item里。
/**
* 网络的单个marker的实例
*/
BitmapDescriptor getUrlMarkerIconBitmapDescriptor(boolean select);
/**
* 网络的单个marker的icon路径
*/
String getUrlLocalMarkerIconPath();
/**
* 网络的单个聚合的icon路径
*/
String getUrlClusterIconPath();
2)、ClusterManager
这是聚合marker的管理器,内部有渲染类,将ICON渲染到地图上,同时也包含了地图状态变化的接口,这里我们把地图的状态变化接口回调出来,方便我们监听地图的移动和缩放。
同时对渲染类DefaultClusterRenderer也增加get接口,因为后面我们需要,在外部动态改变Marker的图标。地图上渲染出来的Marker在Render渲染类中,会以ClusterItem为KEY,缓存在MAP中。
//add myself 修改了地图状态变化的回调
public BaiduMap.OnMapStatusChangeListener onMapStatusChangeListener;
/**
* add myself
*/
public DefaultClusterRenderer<T> getDefaultClusterRenderer() {
return (DefaultClusterRenderer) mRenderer;
}
3)、NonHierarchicalDistanceBasedAlgorithm
这个类主要关注MAX_DISTANCE_AT_ZOOM,它代表着多远的距离可以聚合,这里个人修改为200,反正我就不喜欢堆在一起╮(╯_╰)╭。
4)、DefaultClusterRenderer
这是大头,很大的头,默认渲染类,当然你可以自己实现,但是秉承着快速(懒)开发的原则,我是直接在上面修改的:
显示Marker的修改,是将原本只显示drawable的功能,扩展到支持加载本地图标的支持,后面我们只需要,把对应的Marker的图标下载下来,就可以显示不同的网络ICON啦。下方继续长长长代码(。・・)ノ。
//聚合背景修改为我们要的效果
private LayerDrawable makeClusterBackground() {
//读取聚合图标
InputStream inputStream;
inputStream = context.getResources().openRawResource(R.raw.cluster);
BitmapDrawable drawable = new BitmapDrawable(inputStream);
mColoredCircleBackground = drawable;
//将外部的圈圈去掉
ShapeDrawable outline = new ShapeDrawable(new RoundRectShape(mOuterCircle, mInsertCircle, null));
outline.getPaint().setColor(0x00000000);
LayerDrawable background = new LayerDrawable(new Drawable[]{outline, mColoredCircleBackground});
//修改padding
int strokeWidth = (int) (mDensity * 3);
background.setLayerInset(1, strokeWidth, strokeWidth, strokeWidth, strokeWidth);
return background;
}
/**
* 设置文本的样式,修改为使用了TextView,不用百度的SquareTextView
*/
private TextView makeSquareTextView(Context context) {
TextView squareTextView =
new TextView(context);
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams((int) (54 * mDensity), (int) (54 * mDensity));
squareTextView.setLayoutParams(layoutParams);
squareTextView.setId(R.id.text);
squareTextView.setGravity(Gravity.CENTER);
return squareTextView;
}
/**
* 设置文本的数字显示
*/
protected String getClusterText(int bucket) {
if (bucket < BUCKETS[0]) {
return String.valueOf(bucket);
}
if (bucket > 999) {
bucket = 999;
return String.valueOf(bucket) + "+";
}
return String.valueOf(bucket);
}
//显示渲染图标,修改注释部分代码
private void perform(MarkerModifier markerModifier) {
if (!shouldRenderAsCluster(cluster)) {
/**如果此处没有需要聚合的**/
for (T item : cluster.getItems()) {
Marker marker = mMarkerCache.get(item);
MarkerWithPosition markerWithPosition;
if (marker == null) {
MarkerOptions markerOptions = new MarkerOptions();
//markerOptions.animateType(MarkerOptions.MarkerAnimateType.grow);
/**
* 下面就是marker的显示
*/
BitmapDescriptor bitmapDescriptor;
//如果有需要显示的url icon的话,就显示已下载的url Icon
if (!TextUtils.isEmpty(item.getUrlLocalMarkerIconPath()) && new File(item.getUrlLocalMarkerIconPath()).exists()) {
bitmapDescriptor = item.getUrlMarkerIconBitmapDescriptor(false);
if (bitmapDescriptor == null) {
bitmapDescriptor = item.getBitmapDescriptor();
}
} else {
bitmapDescriptor = item.getBitmapDescriptor();
}
···
onBeforeClusterItemRendered(item, markerOptions);
marker = mClusterManager.getMarkerCollection().addMarker(markerOptions);
markerWithPosition = new MarkerWithPosition(marker);
//根据 item 缓存marker
mMarkerCache.put(item, marker);
···
/**显示聚合之前完善图片信息**/
onBeforeClusterRendered(cluster, markerOptions);
····
}
5)、IconGenerator
这个类主要是对应聚合Marker的,这里修改了聚合图标的大小,背景,文本样式等等。其中setTextAppearance配置文本的样式,如颜色,大小等,目前百度自带Bubble.TextAppearance.Light和Bubble.TextAppearance.Dark,你也可以自己配置你需要的。
首先,你还是得有个女朋·····我呸,得是有个KEY,同样是在百度地图API,这次选择的是服务端,创建应用后,最底部可以选择sn加密或者的ip白名单。
既然叫服务端,一般这种工作都是服务器去做的,客户端只需要从服务端拿数据就好。但是有时候服务端没空理你(没错,就是不被理会的我),你就需要直接从百度服务器扣了。
这里采用的是sn加密,就是根据url,通过申请到的ak和sk,还有各种请求参数,进行utf8转化和md5加密,具体有兴趣可以看看DEMO,虽然在客户端这样加密是没有意义的。
那么那我们就开始请求数据啦:
http://api.map.baidu.com/geosearch/v3/nearby?ak=r3sHA6uyjCwDvE838WGfvnPSpghTxi93&geotable_id=158714&page_index=1&page_size=20&location=113.583087,22.276012&radius=5000&sn=7e1dd255849414916373e9fe9856d555
上方式一次请求中完整的url,其中:
其他的还有 有关键字q,标签tag,排序sort,过滤等:
还有其他的就在百度官网了,再说下去真的就废话了。
请求到数据后,lbs对应返回我们需要的json,我们映射成需要的model,组装ClusterBaiduItem并设置图标,用于ClusterManager渲染。
但是!!!百度地图Marker不支持url!这就尴尬了,所以我们还是乖乖自己下载吧┑( ̄Д  ̄)┍。
下载逻辑具体可看demo中的 ICONJob(真的好懒),主要的逻辑是:
这里主要是动态更新Marker的图标逻辑:
根据下载成功的ICON对应的id,找到对应的ClusterBaiduItem,通过ClusterBaiduItem,在ClusterManager的DefaultClusterRenderer中拿到marker,修改marker的图标,为我们下载成功的图片,对应的一一更新,哇塞,好简单。
for (ClusterBaiduItem clusterBaiduItem : mClusterBaiduItems) {
LBSModel lbsModel = clusterBaiduItem.getLBAModel();
//此处根据id设置对应的图片
if (lbsModel.getUid() == e.geteId()) {
BitmapDescriptor bitmapDescriptor;
if (!TextUtils.isEmpty(clusterBaiduItem.getUrlLocalMarkerIconPath()) &&
new File(clusterBaiduItem.getUrlLocalMarkerIconPath()).exists()) {
bitmapDescriptor = clusterBaiduItem.getUrlMarkerIconBitmapDescriptor(false);
if (bitmapDescriptor == null) {
bitmapDescriptor = clusterBaiduItem.getBitmapDescriptor();
}
} else {
bitmapDescriptor = clusterBaiduItem.getBitmapDescriptor();
}
//从聚合管理器里面拿到marker,动态改变它
Marker marker = mClusterManager.getDefaultClusterRenderer().getMarker(clusterBaiduItem);
if (marker != null) {
marker.setIcon(bitmapDescriptor);
}
//刷新
mClusterManager.cluster();
return;
}
}
在地图移动和缩放的时候,因为地理信息改变了,需要更新数据,这时候可以通过setOnMapStatusChangeListener来监听地图的变化。
mClusterManager.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
//记住变化前的上一个状态
private MapStatus mFrontMapStatus;
@Override
public void onMapStatusChangeStart(MapStatus mapStatus) {
if (mFrontMapStatus == null) {
mFrontMapStatus = mapStatus;
}
}
@Override
public void onMapStatusChangeFinish(MapStatus mapStatus) {
//此处需要注意,如果是进入的时候重新定位了地址,或者进入后在改变地图状态,可能也会进入这里
if (mHadRequest) {
if (StatusChangeLogic(mFrontMapStatus, mapStatus)) {//处理移动与放大
mFrontMapStatus = null;
}
}
mCurrentMapStatus = mapStatus;
}
});
/**
* 地图因为操作而发生了状态改变
*/
private boolean StatusChangeLogic(MapStatus frontMapStatus, MapStatus mapStatus) {
//重新确定搜索半径的中心图标
mSearchModel.setGps(mapStatus.bound.getCenter().longitude + "," + mapStatus.bound.getCenter().latitude);
//重新确定层
本站资源仅限于学习研究,严禁从事商业或者非法活动!
源码搜藏网所有源码来自互联网转载与用户上传分享,如果侵犯了您的权益请与我们联系,我们将在24小时内删除!谢谢!
热门源码
源码站
html5网站
小区物业管理系统
后台
安卓源码下载
网页模版
asp网站建设
php问答系统下载
oa系统下载
个人网站模板下载
中国源码
门户网站源码
源码分享
论坛源代码
网页模板免费下载
php教程下载
源码网站
免费源码下载
导航菜单代码
网站后台模板
编程电子书
.net源码
网页下载
源代码下载
flash动画素材网
学校网站模板
建站源码
帝国网站管理系统
超级群
个人博客模板
模板之家
html模板
论坛源码
网站源码下载
网站模板
个人主页模板
个人主页源码
源码大全
主页模板
html网页模板
源码下载
php 源码
企业网站程序
免费论坛
个人网页设计模板
php论坛
asp文件
第三方支付源码
站长下载
商城源码
Copyright ©
2025版权所有 本站资源均来自互联网或会员发布,如果侵犯了您的权益请与我们联系,我们将在24小时内删除!谢谢!