使用过百度地图的同学知道,它有个街景功能,可以看到许多地方的实景。这里就其街景内容的实现,进行下学习。

在百度地图SDK的官网上可以看到,百度对开发者提供了很多相干的内容,方便我们进行学习。关于SDK的使用方法,包括jar包导入,*.so 动态库的添加位置及AndroidManifest文件的配置不做为我们这里讨论的内容,官方文档已介绍的很详细,不做无聊的搬运工。

效果图

这里我们首先预览下,今天终究要实现的效果图

如图所示,我们这里的实现,就是两个页面的内容,1个是基础的地图MapView,1个是街景地图PanoView。接下来,就这两个页面(Activity)分别展开来讲。(由于GIF图片大小限制,效果不是很理想,文章结尾有源码地址,可以自己跑1下看1下效果先)

地图MapView实现

地图MapView的简单显示

布局文件

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:layout_width="match_parent"

android:layout_height="match_parent"

android:clickable="true" />

Application

1般情况下,我们的利用程序都会有1个继承自Application的类,用于实现1些初始化的方法,这里可以在Application里履行1些百度地图初始化的工作,这也是官方提倡的方式。

public void onCreate() {

super.onCreate();

mInstance = this; SDKInitializer.initialize(getApplicationContext());

}

Activity

在Activity的OnCreate方法中实现

setContentView(R.layout.activity_mapview);

mMapView = (MapView) findViewById(R.id.bmapView);

上面这样1段简单的代码,就能够在Activity中显示出1个MapView,也就是我们最熟习的地图页面,是否是很简单,就像我们显示1个TextView1样。

这里说明写1下,依照官方的API指点文档,使用MapView等百度地图SDK所提供的各种实现,是需要去申请相干的key的,申请的方法在官网有着详细的介绍,这里就不再粘贴复制了;很多同学在使用MapView的时候发现,程序运行后地图没有显示,显示的都是1些方格子,这常常是由于key没有申请,或申请的方式不当酿成的

MapView显示到当前位置

每次打开百度地图,都会自动定位到我们当前所在的位置,或是我们搜索某个特定的地方作为新的位置,全部地图所显现的区域都是新位置周边的环境。这里,关于地图的定位和搜索的相干实现内容,就不展开来讲,不当作此次的重点。

假定我们已通过定位(或是搜索),定位了到了1个位置

**

* 假定我们当前的位置在此

*/

private final double latitude = 39.963175;

private final double longitude = 116.400244;

这个位置依照新闻里常听到的说法就是,东经116.40度,北纬39.96度,位于北京市东城区旧鼓楼大街丙1号。

接下来,我们要做的就是将MapView的视图更新到我们“定位”的位置,这个位置周边的地图才是我们关心的。

mBaiduMap = mMapView.getMap();

//定义Maker坐标点

point = new LatLng(latitude, longitude);

//定义地图状态

final MapStatus mMapStatus = new MapStatus.Builder()

.target(point)

.zoom(18)

.build();

//定义MapStatusUpdate对象,以便描写地图状态将要产生的变化

MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);

//改变地图状态

mBaiduMap.setMapStatus(mMapStatusUpdate);

这里的mBaiduMap 是1个BaiduMap的实例,通过MapView的getMap方法便可取得。我们对地图的各种操作,设置属性都是基于这个实例进行。

通过上面的代码,我们就能够将MapView的视图更新到我们所想要的位置了。

添加View到MapView

添加Marker

依照百度地图API的说法,我们添加到地图上的小图标统1称为Marker。

//构建Marker图标

bitmap = BitmapDescriptorFactory

.fromResource(R.drawable.icon_markc);

//构建MarkerOption,用于在地图上添加Marker

option = new MarkerOptions()

.position(point)

.icon(bitmap);

//在地图上添加Marker,并显示

mBaiduMap.addOverlay(option);

通过上面的实现,我们就能够将1个小图标添加到地图层,作为标记。我们平常使用地图时,所搜周边后显现的1系列小圆点就是如此(以下图)

ShowInfoWindow使用

最后1步,实现显示街景缩略图的那个小弹框。

这里首先自定义1下我们要添加到地图层的View。

view = LayoutInflater.from(mContext).inflate(R.layout.pano_overlay, null);

pic = (ImageView) view.findViewById(R.id.panoImageView);

view.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new Intent(mContext, PanoDemoMain.class);

intent.putExtra("latitude", latitude);

intent.putExtra("longitude", longitude);

startActivity(intent);

}

});

这里pic这个ImageView用于显示我们要展现的街景缩略图。pano_overlay是全部弹框的布局,很简单,这里就不贴代码了。

同时,我们为这个自定义View设置点击事件,方便我们跳转到PanoView街景地图页面,并且将当前位置传递过去。

由于祖国地大物博,所以街景的覆盖并不是百分之百,所以说,不是每一个地方都有街景可以显示,有些鸟不拉屎的地方是看不到的。那我们怎样知道甚么地方有街景呢?API为我们提供了很好的检测方法

new Thread(new Runnable() {

@Override

public void run() {

PanoramaRequest request = PanoramaRequest.getInstance(mContext);

BaiduPanoData locationPanoData = request.getPanoramaInfoByLatLon(longitude, latitude);

//开发者可以判断是不是有外景(街景)

if (locationPanoData.hasStreetPano()) {

String url = baseUrl + locationPanoData.getPid();

Message message = new Message();

message.what = 0x01;

message.obj = url;

handler.sendMessage(message);

}

}

}).start();

这样,我们就能够根据当前位置,先检测1下是不是有街景可以显示。这里,如果当前位置有街景,我们就通过Handler通知主线程去更新UI

private class myHandler extends Handler {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

if (msg.what == 0x01) {

String url = (String) msg.obj;

Glide.with(mContext).load(url).into(pic);

InfoWindow mInfoWindow = new InfoWindow(view, point, -57);

//显示InfoWindow

mBaiduMap.showInfoWindow(mInfoWindow);

}

}

}

这里看1下,InfoWindow的说明及其构造函数

public class InfoWindow extends java.lang.Object

在地图中显示1个信息窗口,可以设置1个View作为该窗口的内容,也能够设置1个 BitmapDescriptor 作为该窗口的内容。

public InfoWindow(View view, LatLng position, int yOffset)

/**

通过传入的 view 构造1个 InfoWindow, 此时只是利用该view

生成1个Bitmap绘制在地图中,监听事件由开发者实现。

Parameters:

view - InfoWindow 展现的 view

position - InfoWindow 显示的地理位置

yOffset - InfoWindow Y 轴偏移量

*/

在Handler的handleMessage方法中,我们通过返回的url加载图片,并将自定义的弹框View显示到之前1步添加的marker偏上1点的地方(这就是InfoWindow的构造函数中⑸7的意义)

关于这个加载图片的URL,可以参考这里静态图API。

这样,就实现了MapView页面所有的内容。通过点击InfoWindow,就能够跳转到PanoView所在的界面去查看街景地图。

接下来,我们将介绍PanoView街景地图的实现。

街景地图PanoViewActivity实现

街景地图PanoView基础

街景地图PanoView的显示和基础地图MapView10分类似

首先是在布局文件中定义view

android:id="@+id/panorama"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:clickable="true"

android:visibility="visible" />

在Activity的OnCreate方法中

PanoDemoApplication app = (PanoDemoApplication) this.getApplication();

if (app.mBMapManager == null) {

app.mBMapManager = new BMapManager(app);

app.mBMapManager.init(new PanoDemoApplication.MyGeneralListener());

}

mPanoView = (PanoramaView) findViewById(R.id.panorama);

mPanoView.setPanorama(longitude, latitude);

这里一样需要的是在Application类中做1些初始化工作;对我们所使用key的有效性进行检测。

public void initEngineManager(Context context) {

if (mBMapManager == null) {

mBMapManager = new BMapManager(context);

}

if (!mBMapManager.init(new MyGeneralListener())) {

Toast.makeText(PanoDemoApplication.getInstance().getApplicationContext(), "BMapManager 初始化毛病!",

Toast.LENGTH_LONG).show();

}

}

// 经常使用事件监听,用来处理通常的网络毛病,授权验证毛病等

static class MyGeneralListener implements MKGeneralListener {

@Override

public void onGetPermissionState(int iError) {

// 非零值表示key验证未通过

if (iError != 0) {

// 授权Key毛病:

Toast.makeText(PanoDemoApplication.getInstance().getApplicationContext(),

"请在AndoridManifest.xml中输入正确的授权Key,并检查您的网络连接是不是正常!error: " + iError, Toast.LENGTH_LONG).show();

} else {

Toast.makeText(PanoDemoApplication.getInstance().getApplicationContext(), "key认证成功", Toast.LENGTH_LONG)

.show();

}

}

}

同时在Activity里也需要做1些初始化的工作,最后就是通过PanoView的setPanorama()方法实现街景的显示。

关于这里用到的setPanorama(),根据API我们可以看到

public void setPanorama(java.lang.String pid)

//根据全景pid值切换全景场景

public void setPanorama(int x,int y)

//根据百度墨卡托投影坐标切换全景场景

public void setPanorama(double longitude,double latitude)

//根据百度经纬度坐标切换全景场景

public void setPanoramaByUid(java.lang.String uid,

int panoType)

//根据uid值切换全景场景

也就是说,不但通过经纬度,而且可以通过别的方式实现街景地图的功能。这里我们就使用了大家最熟习的经纬度,对别的实现方式有兴趣的同学,可以自己去探索1下。

将地图MapView展现在街景PanoView上面

如图所示,将1个MapView显示在PanoView之上;很自然的我们会写出下面的布局方式:

android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/panorama"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:clickable="true"

android:visibility="visible" />

android:layout_width="60dp"

android:layout_height="60dp"

android:layout_alignParentBottom="true"

android:layout_alignParentLeft="true"

android:layout_marginBottom="8dp"

android:layout_marginLeft="8dp"

android:background="#00ffffff">

android:id="@+id/bmapView"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:clickable="true"

android:padding="20dp" />

这样,我们在全部PanoView的左下角定义1个60x60大小的view用于显示1个MapView。

实现对街景视图操作的监听

街景SDK为我们提供了PanoramaViewListener这个接口,可以实现对从街景视图开始绘制到完成绘制,对街景地图的操作(如点击,旋转)的监听。

这里我们重点看1下onMessage(String msgName, int msgType)这个回调方法。

public void onMessage(String msgName, int msgType) {

Log.e(LTAG, "msgName--->" + msgName + ", msgType--->" + msgType);

switch (msgType) {

case 8213:

//旋转

Log.e(PanoViewActivity.class.getSimpleName(), "now,the heading is " + mPanoView.getPanoramaHeading());

Message message = new Message();

message.what = ACTION_DRAG;

message.arg1 = (int) mPanoView.getPanoramaHeading();

handler.sendMessage(message);

break;

case 12302:

//点击

Log.e(PanoViewActivity.class.getSimpleName(), "clicked");

Message msg = new Message();

msg.what = ACTION_CLICK;

handler.sendMessage(msg);

break;

default:

break;

}

}

这里不能不吐槽1下,官方所提供的API文档,对这个onMessage回调方法中的参数竟然没有任何有价值的解释。这里的8213及12302完全是通过打印日志自己总结出的规律。

这样,我们对不同的操作,就能够通过Handler实现不同的UI效果。我们看1下handler的实现:

private class MyHandler extends Handler {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

switch (msg.what) {

case ACTION_CLICK:

if (titleVisible) {

titleVisible = false;

textTitle.startAnimation(animationHide);

textTitle.setVisibility(View.GONE);

sv.setVisibility(View.GONE);

} else {

titleVisible = true;

textTitle.startAnimation(animationShow);

textTitle.setVisibility(View.VISIBLE);

sv.setVisibility(View.VISIBLE);

}

break;

case ACTION_DRAG:

float heading = (float) msg.arg1;

mBaiduMap.clear();

//构建MarkerOption,用于在地图上添加Marker

option = new MarkerOptions()

.position(point)

.rotate(360-heading)

.icon(bitmap);

//在地图上添加Marker,并显示

mBaiduMap.addOverlay(option);

break;

default:

break;

}

}

}

这里的处理就分两种情况:

点击事件

我们仿照百度地图的样式,实现标题栏及MapView的隐藏,并添加动画,这样可以方便用户全屏更清晰的视察街景内容。

旋转事件

上面我们说过对MapView添加Marker的方法,这里就派上用处了。随着我们对PanoView的不断拖拽旋转,通过其getPanoramaHeading() 可以得到当前视角的偏航角。

在UI线程中,我们可以通过不断移除和添加Marker,并设置不同的marker的偏转角度,从而实现1种在左下方小地图上显现我们当前视角的效果。

好了,这样就简单模仿了1下百度地图街景的部份实现功能,由于UI资源所限制,部份效果并不是完全1致,这里只是学习下而已。

代码已上传至github,点这里便可查看。

Android 百度地图搜索框实现,仿百度地图街景实现相关推荐

  1. android 仿百度地图,仿百度地图街景实现

    使用过百度地图的同学知道,它有个街景功能,可以看到许多地方的实景.这里就其街景内容的实现,进行下学习. 在百度地图SDK的官网上可以看到,百度对开发者提供了很多相关的内容,方便我们进行学习.关于SDK ...

  2. 仿百度地图 android,仿百度地图街景实现

    使用过百度地图的同学知道,它有个街景功能,可以看到许多地方的实景.这里就其街景内容的实现,进行下学习. 在百度地图SDK的官网上可以看到,百度对开发者提供了很多相关的内容,方便我们进行学习.关于SDK ...

  3. 百度地图(二) - 模仿百度地图搜索框

    百度地图(二) - 模仿百度地图搜索框 1 模仿百度地图搜索框 1 在activity_Main在添加 TextView <TextView android:id="@+id/tvSe ...

  4. Android 高仿百度地图的LBS服务——离线地图篇 Part 2 (v 3.1.1)

    一.前言 转载请标明出处:http://blog.csdn.net/wlwlwlwl015/article/details/41492031 这一篇blog写的真心不容易,我只想说我这种菜鸟去高仿百度 ...

  5. 解决百度地图搜索框在底层显示不出来

    /*解决百度地图搜索框在底层显示不出来*/ 官方出的补丁,把这个放在html顶端即可 <style type="text/css"> .tangram-suggesti ...

  6. 百度地图街景实现,看这篇就够了

    点击上方蓝字关注码个蛋 一招一式,看遍天下 作者:IAM四十二 博客:http://www.jianshu.com/u/c6f7cfa366d9 文章目录 前言 效果图 地图MapView实现 地图M ...

  7. Android 高仿百度地图的LBS服务——基础地图篇(v 3.1.1)

    一.前言 转载请标明出处:http://blog.csdn.net/wlwlwlwl015/article/details/41076537 因为项目需要集成地图功能,所以交给我负责研究并继续完善百度 ...

  8. android 布局中绘制语音曲线,Android仿百度地图小度语音助手的贝塞尔曲线动画

    本文为大家分享了Android仿小度语音助手的贝塞尔曲线动画,供大家参考,具体内容如下 废话不多说,看下面的动图,和百度的还是有点点差别,我也不修改了,很简单,我实在是没有多余的时间,还要学习其他的东 ...

  9. android仿百度地图悬浮式窗口,百度地图(bMap)实现浮动层、按钮等的方法及代码...

    本帖最后由 流浪男 于 2015-10-20 16:34 编辑 利用openFame的方法我们可以在百度地图模块(bMap)上添加任何想要的浮动层,比如 一.添加按钮 二.在中间添加固定图标,拖动地图 ...

  10. Android 起调第三方导航,百度地图,高德地图,腾讯地图。起调高德地图导航

    主要工具类 /*** Created by meixi on 2018/6/29.* 使用第三方导航:高德.百度..........*/ public class AmapUtil {public s ...

最新文章

  1. 如果三十年前有这些AI技术,可可西里的悲剧不会发生
  2. 使用组策略禁用注册表编辑工具
  3. 文巾解题 881. 救生艇
  4. Dell R710服务器磁盘恢复数据库一例(记录)
  5. win7系统的右键菜单只显示一个白色框不显示菜单项 解决办法
  6. 武汉纺织大学C语言试题,武汉纺织大学10年C语言试题.doc
  7. CSharp_DevExpress_DXperience_Universal_11.1.6 下载+源码+编译
  8. win10内存占用率高达95%解决方法
  9. 平板电脑怎么打开HTML,为什么平板电脑和笔记本电脑打开网页不一样,感觉平板电脑就是手机?...
  10. 鼠标右键转圈圈_了解原理并解决鼠标右键转圈圈
  11. 判断字符长度,区分中英文(中文两个字符,英文一个字符)
  12. ZUCC高级程序设计实验01
  13. [转载]【实拍】:绿色灾难中的我们|浒苔带来的启示
  14. 三步集成美图软件背景虚化景深效果【iOS篇】
  15. 一文带你看懂JAVA IO流,史上最全面的IO教学啦(附送JAVA IO脑图
  16. pygame.surface.blit()方法4个参数的使用方法
  17. redis持久化(万一redis突然宕机了咋办?数据会丢失吗?)
  18. 4、微信小程序-项目配置
  19. BUUCTF msic 专题(59)[SWPU2019]伟大的侦探
  20. 实变函数笔记-勒贝格积分

热门文章

  1. 毕设题目:Matlab飞行器
  2. 【滤波器】基于matlab GUI高通+低通+带通+带阻FIR滤波器设计【含Matlab源码 092期】
  3. 开通CSDN年度会员,免费赠送代码
  4. 【TSP】基于matlab禁忌搜索算法求解31城市旅行商问题【含Matlab源码 1143期】
  5. 【细胞分割】基于matlab GUI生物细胞计数【含Matlab源码 758期】
  6. 【车间调度】基于matlab遗传算法求解多目标流水车间调度问题【含Matlab源码 443期】
  7. html让一行文字在两行,css单行两行文本自适应问题
  8. ai驱动数据安全治理_利用AI驱动的自动协调器实时停止有毒信息
  9. 深度学习分类pytorch_立即学习AI:02 —使用PyTorch进行分类问题简介
  10. 内置函数的数据聚合NumpyPandas